From 620f33919659b2b59e7b78fe87bbb438006f4165 Mon Sep 17 00:00:00 2001 From: hocine hacherouf Date: Wed, 7 Sep 2022 13:03:00 +0200 Subject: [PATCH] Add unit tests on device create/detail pages about save and duplicate feature #1001 (#1163) * Add unit tests on DeviceToDuplicateSelector #1001 * Add unit tests on create device page about save and new/duplicate #1001 * Add unit test on device details page about duplicate device #1001 --- .../Pages/Devices/CreateDevicePageTests.cs | 152 ++++++++++++++++ .../Pages/Devices/DeviceDetailPageTests.cs | 73 +++++++- .../Devices/DeviceToDuplicateSelectorTests.cs | 166 ++++++++++++++++++ .../Devices/DeviceToDuplicateSelector.razor | 4 +- 4 files changed, 392 insertions(+), 3 deletions(-) diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/CreateDevicePageTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/CreateDevicePageTests.cs index d87becae4..91f652791 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/CreateDevicePageTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/CreateDevicePageTests.cs @@ -318,5 +318,157 @@ public async Task ChangeModelShouldProcessProblemDetailsExceptionWhenIssueOccurs // Assert cut.WaitForAssertion(() => MockRepository.VerifyAll()); } + + [Test] + public async Task ClickOnSaveAndAddNewShouldCreateDeviceAndResetCreateDevicePage() + { + var mockDeviceModel = new DeviceModel + { + ModelId = Guid.NewGuid().ToString(), + Description = Guid.NewGuid().ToString(), + SupportLoRaFeatures = false, + Name = Guid.NewGuid().ToString() + }; + + var expectedDeviceDetails = new DeviceDetails + { + DeviceName = Guid.NewGuid().ToString(), + ModelId = mockDeviceModel.ModelId, + DeviceID = Guid.NewGuid().ToString(), + }; + + _ = this.mockDeviceClientService.Setup(service => service.CreateDevice(It.Is(details => expectedDeviceDetails.DeviceID.Equals(details.DeviceID, StringComparison.Ordinal)))) + .Returns(Task.CompletedTask); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModels()) + .ReturnsAsync(new List + { + mockDeviceModel + }); + + _ = this.mockDeviceTagSettingsClientService.Setup(service => service.GetDeviceTags()) + .ReturnsAsync(new List + { + new() + { + Label = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString(), + Required = false, + Searchable = false + } + }); + + _ = this.mockDeviceModelsClientService + .Setup(service => service.GetDeviceModelModelProperties(mockDeviceModel.ModelId)) + .ReturnsAsync(new List()); + + _ = this.mockDeviceClientService + .Setup(service => service.SetDeviceProperties(expectedDeviceDetails.DeviceID, It.IsAny>())) + .Returns(Task.CompletedTask); + + var popoverProvider = RenderComponent(); + var cut = RenderComponent(); + var saveButton = cut.WaitForElement("#SaveButton"); + + cut.WaitForElement($"#{nameof(DeviceDetails.DeviceName)}").Change(expectedDeviceDetails.DeviceName); + cut.WaitForElement($"#{nameof(DeviceDetails.DeviceID)}").Change(expectedDeviceDetails.DeviceID); + await cut.Instance.ChangeModel(mockDeviceModel); + + var mudButtonGroup = cut.FindComponent(); + + mudButtonGroup.Find(".mud-menu button").Click(); + + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(3)); + + var items = popoverProvider.FindAll("div.mud-list-item"); + + // Click on Save and New + items[1].Click(); + + // Act + saveButton.Click(); + + // Assert + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + cut.WaitForAssertion(() => cut.Find($"#{nameof(DeviceDetails.DeviceName)}").TextContent.Should().BeEmpty()); + cut.WaitForAssertion(() => cut.Find($"#{nameof(DeviceDetails.DeviceID)}").TextContent.Should().BeEmpty()); + cut.WaitForAssertion(() => this.mockNavigationManager.Uri.Should().NotEndWith("/devices")); + } + + [Test] + public async Task ClickOnSaveAndDuplicateShouldCreateDeviceAndDuplicateDeviceDetailsInCreateDevicePage() + { + var mockDeviceModel = new DeviceModel + { + ModelId = Guid.NewGuid().ToString(), + Description = Guid.NewGuid().ToString(), + SupportLoRaFeatures = false, + Name = Guid.NewGuid().ToString() + }; + + var expectedDeviceDetails = new DeviceDetails + { + DeviceName = Guid.NewGuid().ToString(), + ModelId = mockDeviceModel.ModelId, + DeviceID = Guid.NewGuid().ToString(), + }; + + _ = this.mockDeviceClientService.Setup(service => service.CreateDevice(It.Is(details => expectedDeviceDetails.DeviceID.Equals(details.DeviceID, StringComparison.Ordinal)))) + .Returns(Task.CompletedTask); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModels()) + .ReturnsAsync(new List + { + mockDeviceModel + }); + + _ = this.mockDeviceTagSettingsClientService.Setup(service => service.GetDeviceTags()) + .ReturnsAsync(new List + { + new() + { + Label = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString(), + Required = false, + Searchable = false + } + }); + + _ = this.mockDeviceModelsClientService + .Setup(service => service.GetDeviceModelModelProperties(mockDeviceModel.ModelId)) + .ReturnsAsync(new List()); + + _ = this.mockDeviceClientService + .Setup(service => service.SetDeviceProperties(expectedDeviceDetails.DeviceID, It.IsAny>())) + .Returns(Task.CompletedTask); + + var popoverProvider = RenderComponent(); + var cut = RenderComponent(); + var saveButton = cut.WaitForElement("#SaveButton"); + + cut.WaitForElement($"#{nameof(DeviceDetails.DeviceName)}").Change(expectedDeviceDetails.DeviceName); + cut.WaitForElement($"#{nameof(DeviceDetails.DeviceID)}").Change(expectedDeviceDetails.DeviceID); + await cut.Instance.ChangeModel(mockDeviceModel); + + var mudButtonGroup = cut.FindComponent(); + + mudButtonGroup.Find(".mud-menu button").Click(); + + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(3)); + + var items = popoverProvider.FindAll("div.mud-list-item"); + + // Click on Save and Duplicate + items[2].Click(); + + // Act + saveButton.Click(); + + // Assert + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + cut.WaitForAssertion(() => cut.Find($"#{nameof(DeviceDetails.DeviceName)}").TextContent.Should().BeEmpty()); + cut.WaitForAssertion(() => cut.Find($"#{nameof(DeviceDetails.DeviceID)}").TextContent.Should().BeEmpty()); + cut.WaitForAssertion(() => this.mockNavigationManager.Uri.Should().NotEndWith("/devices")); + } } } diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceDetailPageTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceDetailPageTests.cs index 5ec2e0baf..af69c54d1 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceDetailPageTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceDetailPageTests.cs @@ -22,7 +22,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Client.Pages.Devices using MudBlazor.Services; using NUnit.Framework; using UnitTests.Mocks; - using AzureIoTHub.Portal.Models.v10.LoRaWAN; + using Models.v10.LoRaWAN; using AzureIoTHub.Portal.Client.Pages.DeviceModels; [TestFixture] @@ -533,5 +533,76 @@ public void ClickOnDeleteShouldDisplayConfirmationDialogAndRedirectIfConfirmed() cut.WaitForState(() => this.mockNavigationManager.Uri.EndsWith("/devices", StringComparison.OrdinalIgnoreCase)); cut.WaitForAssertion(() => MockRepository.VerifyAll()); } + + [Test] + public void ClickOnDuplicateShouldDuplicateDeviceDetailAndRedirectToCreateDevicePage() + { + var mockDeviceModel = new DeviceModel + { + ModelId = Guid.NewGuid().ToString(), + Description = Guid.NewGuid().ToString(), + SupportLoRaFeatures = false, + Name = Guid.NewGuid().ToString() + }; + + var mockTag = new DeviceTag + { + Label = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString(), + Required = false, + Searchable = false + }; + + var mockDeviceDetails = new DeviceDetails + { + DeviceName = Guid.NewGuid().ToString(), + ModelId = mockDeviceModel.ModelId, + DeviceID = Guid.NewGuid().ToString(), + Tags = new Dictionary() + { + {mockTag.Name,Guid.NewGuid().ToString()} + } + }; + + _ = this.mockDeviceClientService + .Setup(service => service.GetDevice(mockDeviceDetails.DeviceID)) + .ReturnsAsync(mockDeviceDetails); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModel(mockDeviceDetails.ModelId)) + .ReturnsAsync(mockDeviceModel); + + _ = this.mockDeviceTagSettingsClientService.Setup(service => service.GetDeviceTags()) + .ReturnsAsync(new List + { + mockTag + }); + + _ = this.mockDeviceClientService + .Setup(service => service.GetDeviceProperties(mockDeviceDetails.DeviceID)) + .ReturnsAsync(new List()); + + var popoverProvider = RenderComponent(); + var cut = RenderComponent(ComponentParameter.CreateParameter("DeviceID", mockDeviceDetails.DeviceID)); + cut.WaitForAssertion(() => cut.Find($"#{nameof(DeviceModel.Name)}").InnerHtml.Should().NotBeEmpty()); + + var saveButton = cut.WaitForElement("#saveButton"); + + var mudButtonGroup = cut.FindComponent(); + + mudButtonGroup.Find(".mud-menu button").Click(); + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(2)); + + var items = popoverProvider.FindAll("div.mud-list-item"); + + // Click on Duplicate + items[1].Click(); + + // Act + saveButton.Click(); + + // Assert + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + cut.WaitForAssertion(() => this.mockNavigationManager.Uri.Should().EndWith("/devices/new")); + } } } diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceToDuplicateSelectorTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceToDuplicateSelectorTests.cs index 9fd7a5c49..803bede5b 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceToDuplicateSelectorTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/DeviceToDuplicateSelectorTests.cs @@ -15,6 +15,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Client.Pages.Devices using Bunit; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; + using Models.v10.LoRaWAN; using Moq; using MudBlazor; using NUnit.Framework; @@ -74,6 +75,7 @@ public void TypingOnMudAutocompleteShouldTriggerSearch() } }); + var popoverProvider = RenderComponent(); var cut = RenderComponent(); var autocompleteComponent = cut.FindComponent>(); @@ -82,10 +84,174 @@ public void TypingOnMudAutocompleteShouldTriggerSearch() autocompleteComponent.Find(TagNames.Input).Input(query); // Assert + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(1)); cut.WaitForAssertion(() => autocompleteComponent.Instance.IsOpen.Should().BeTrue()); cut.WaitForAssertion(() => MockRepository.VerifyAll()); } + [Test] + public void SelectDeviceShouldDuplicateDeviceAndItsModel() + { + // Arrange + var query = Fixture.Create(); + + var expectedDeviceModel = new DeviceModel + { + ModelId = Fixture.Create() + }; + + var expectedDevice = new DeviceDetails + { + DeviceID = Fixture.Create(), + ModelId = expectedDeviceModel.ModelId + }; + + var expectedDeviceItem = new DeviceListItem + { + DeviceID = expectedDevice.DeviceID, + }; + + var url = $"api/devices?pageSize=10&searchText={query}"; + _ = this.mockDeviceClientService.Setup(service => service.GetDevices(url)) + .ReturnsAsync(new PaginationResult() + { + Items = new List + { + expectedDeviceItem + } + }); + + _ = this.mockDeviceClientService.Setup(service => service.GetDevice(expectedDevice.DeviceID)) + .ReturnsAsync(expectedDevice); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModel(expectedDevice.ModelId)) + .ReturnsAsync(expectedDeviceModel); + + var popoverProvider = RenderComponent(); + var cut = RenderComponent(); + + var autocompleteComponent = cut.FindComponent>(); + autocompleteComponent.Find(TagNames.Input).Click(); + autocompleteComponent.Find(TagNames.Input).Input(query); + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(1)); + + // Act + var item = popoverProvider.Find("div.mud-list-item"); + item.Click(); + + // Assert + cut.WaitForAssertion(() => autocompleteComponent.Instance.IsOpen.Should().BeFalse()); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + [Test] + public void SelectDeviceShouldProcessProblemDetailsExceptionWhenGettingDeviceDetails() + { + // Arrange + var query = Fixture.Create(); + + var expectedDeviceModel = new DeviceModel + { + ModelId = Fixture.Create() + }; + + var expectedDevice = new DeviceDetails + { + DeviceID = Fixture.Create(), + ModelId = expectedDeviceModel.ModelId + }; + + var expectedDeviceItem = new DeviceListItem + { + DeviceID = expectedDevice.DeviceID, + }; + + var url = $"api/devices?pageSize=10&searchText={query}"; + _ = this.mockDeviceClientService.Setup(service => service.GetDevices(url)) + .ReturnsAsync(new PaginationResult() + { + Items = new List + { + expectedDeviceItem + } + }); + + _ = this.mockDeviceClientService.Setup(service => service.GetDevice(expectedDevice.DeviceID)) + .ThrowsAsync(new ProblemDetailsException(new ProblemDetailsWithExceptionDetails())); + + var popoverProvider = RenderComponent(); + var cut = RenderComponent(); + + var autocompleteComponent = cut.FindComponent>(); + autocompleteComponent.Find(TagNames.Input).Click(); + autocompleteComponent.Find(TagNames.Input).Input(query); + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(1)); + + // Act + var item = popoverProvider.Find("div.mud-list-item"); + item.Click(); + + // Assert + cut.WaitForAssertion(() => autocompleteComponent.Instance.IsOpen.Should().BeFalse()); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + [Test] + public void SelectLoraDeviceShouldDuplicateLoraDeviceAndItsLoraModel() + { + // Arrange + var query = Fixture.Create(); + + var expectedDeviceModel = new LoRaDeviceModel + { + ModelId = Fixture.Create() + }; + + var expectedDevice = new LoRaDeviceDetails + { + DeviceID = Fixture.Create(), + ModelId = expectedDeviceModel.ModelId + }; + + var expectedDeviceItem = new DeviceListItem + { + DeviceID = expectedDevice.DeviceID, + SupportLoRaFeatures = true + }; + + var url = $"api/devices?pageSize=10&searchText={query}"; + _ = this.mockDeviceClientService.Setup(service => service.GetDevices(url)) + .ReturnsAsync(new PaginationResult() + { + Items = new List + { + expectedDeviceItem + } + }); + + _ = this.mockLoRaWanDeviceClientService.Setup(service => service.GetDevice(expectedDevice.DeviceID)) + .ReturnsAsync(expectedDevice); + + _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModel(expectedDevice.ModelId)) + .ReturnsAsync(expectedDeviceModel); + + var popoverProvider = RenderComponent(); + var cut = RenderComponent(); + + var autocompleteComponent = cut.FindComponent>(); + autocompleteComponent.Find(TagNames.Input).Click(); + autocompleteComponent.Find(TagNames.Input).Input(query); + popoverProvider.WaitForAssertion(() => popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(1)); + + // Act + var item = popoverProvider.Find("div.mud-list-item"); + item.Click(); + + // Assert + cut.WaitForAssertion(() => autocompleteComponent.Instance.IsOpen.Should().BeFalse()); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + [Test] public void TypingOnMudAutocompleteShouldProcessProblemDetailsExceptionWhenTriggerSearch() { diff --git a/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceToDuplicateSelector.razor b/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceToDuplicateSelector.razor index 942141c9c..162fe38e1 100644 --- a/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceToDuplicateSelector.razor +++ b/src/AzureIoTHub.Portal/Client/Pages/Devices/DeviceToDuplicateSelector.razor @@ -78,8 +78,8 @@ device = await DeviceClientService.GetDevice(deviceToDuplicate.DeviceID); deviceModel = await DeviceModelsClientService.GetDeviceModel(device.ModelId); } - DeviceLayoutService.DuplicateSharedDevice(device as DeviceDetails); - DeviceLayoutService.DuplicateSharedDeviceModel(deviceModel as DeviceModel); + DeviceLayoutService.DuplicateSharedDevice(device); + DeviceLayoutService.DuplicateSharedDeviceModel(deviceModel); DeviceLayoutService.RefreshDevice(); } catch (ProblemDetailsException exception)