From f0a2365e119a5709fc84a56c43729291d53dc715 Mon Sep 17 00:00:00 2001 From: E068097 Date: Fri, 22 Nov 2024 14:32:01 +0100 Subject: [PATCH] Unit tests --- .../Components/Planning/EditPlanning.razor | 6 +- .../Planning/DeletePlanningDialog.razor | 1 - .../Startup/AWSServiceCollectionExtension.cs | 17 +- .../Components/Planning/EditPlanningTest.cs | 511 ++++++++++++------ .../Layer/LinkDeviceLayerDialogTest.cs | 177 ++++++ .../Planning/DeletePlanningDialogTest.cs | 58 ++ .../Pages/Planning/PlanningListPageTest.cs | 32 ++ .../DevelopmentConfigHandlerTests.cs | 10 + .../ProductionAWSConfigHandlerTests.cs | 10 + .../ProductionAzureConfigHandlerTests.cs | 10 + .../IoTHub.Portal.Tests.Unit.csproj | 1 - .../Server/Managers/ExportManagerTests.cs | 6 +- 12 files changed, 670 insertions(+), 169 deletions(-) create mode 100644 src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Layer/LinkDeviceLayerDialogTest.cs create mode 100644 src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Planning/DeletePlanningDialogTest.cs diff --git a/src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor b/src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor index f52901c8f..a61ff3fe1 100644 --- a/src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor +++ b/src/IoTHub.Portal.Client/Components/Planning/EditPlanning.razor @@ -77,7 +77,7 @@ - + @@ -176,7 +176,7 @@ - + @@ -194,7 +194,7 @@ } else { - + } diff --git a/src/IoTHub.Portal.Client/Dialogs/Planning/DeletePlanningDialog.razor b/src/IoTHub.Portal.Client/Dialogs/Planning/DeletePlanningDialog.razor index 80675b852..39973d46c 100644 --- a/src/IoTHub.Portal.Client/Dialogs/Planning/DeletePlanningDialog.razor +++ b/src/IoTHub.Portal.Client/Dialogs/Planning/DeletePlanningDialog.razor @@ -1,7 +1,6 @@ @inject ISnackbar Snackbar @inject IPlanningClientService PlanningClientService @inject ILayerClientService LayerClientService -@inject IScheduleClientService ScheduleClientService diff --git a/src/IoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs b/src/IoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs index 93c0d9217..0be446cef 100644 --- a/src/IoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs +++ b/src/IoTHub.Portal.Infrastructure/Startup/AWSServiceCollectionExtension.cs @@ -11,7 +11,8 @@ public static IServiceCollection AddAWSInfrastructureLayer(this IServiceCollecti .ConfigureAWSClient(configuration).Result .ConfigureAWSServices() .ConfigureAWSDeviceModelImages() - .ConfigureAWSSyncJobs(configuration); + .ConfigureAWSSyncJobs(configuration) + .ConfigureAWSSendingCommands(configuration); } private static async Task ConfigureAWSClient(this IServiceCollection services, ConfigHandler configuration) { @@ -110,5 +111,19 @@ private static IServiceCollection ConfigureAWSSyncJobs(this IServiceCollection s }); } + private static IServiceCollection ConfigureAWSSendingCommands(this IServiceCollection services, ConfigHandler configuration) + { + return services.AddQuartz(q => + { + _ = q.AddJob(j => j.WithIdentity(nameof(SendPlanningCommandJob))) + .AddTrigger(t => t + .WithIdentity($"{nameof(SendPlanningCommandJob)}") + .ForJob(nameof(SendPlanningCommandJob)) + .WithSimpleSchedule(s => s + .WithIntervalInMinutes(configuration.SendCommandsToDevicesIntervalInMinutes) + .RepeatForever())); + }); + } + } } diff --git a/src/IoTHub.Portal.Tests.Unit/Client/Components/Planning/EditPlanningTest.cs b/src/IoTHub.Portal.Tests.Unit/Client/Components/Planning/EditPlanningTest.cs index e68f52f24..36149c547 100644 --- a/src/IoTHub.Portal.Tests.Unit/Client/Components/Planning/EditPlanningTest.cs +++ b/src/IoTHub.Portal.Tests.Unit/Client/Components/Planning/EditPlanningTest.cs @@ -3,6 +3,11 @@ namespace IoTHub.Portal.Tests.Unit.Client.Components.Planning { + using Bunit; + using IoTHub.Portal.Client.Dialogs.Planning; + using Moq; + using MudBlazor; + internal class EditPlanningTest : BlazorUnitTest { private Mock mockPlanningClientService; @@ -10,6 +15,8 @@ internal class EditPlanningTest : BlazorUnitTest private Mock mockLayerClientService; private Mock mockDeviceModelsClientService; private Mock mockLoRaWanDeviceModelsClientService; + private Mock mockDialogService; + private FakeNavigationManager mockNavigationManager; public override void Setup() { @@ -20,6 +27,7 @@ public override void Setup() this.mockLayerClientService = MockRepository.Create(); this.mockDeviceModelsClientService = MockRepository.Create(); this.mockLoRaWanDeviceModelsClientService = MockRepository.Create(); + this.mockDialogService = MockRepository.Create(); _ = Services.AddSingleton(this.mockScheduleClientService.Object); _ = Services.AddSingleton(this.mockPlanningClientService.Object); @@ -27,204 +35,208 @@ public override void Setup() _ = Services.AddSingleton(this.mockDeviceModelsClientService.Object); _ = Services.AddSingleton(this.mockLoRaWanDeviceModelsClientService.Object); _ = Services.AddSingleton(new PortalSettings { IsLoRaSupported = true }); + _ = Services.AddSingleton(this.mockDialogService.Object); + + this.mockNavigationManager = Services.GetRequiredService(); } - // TODO: To fix - //[Test] - //public void EditPlanningInit() - //{ - // var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); + [Test] + public void EditPlanningInit() + { + var expectedDeviceModelDto = Fixture.Create(); + var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); - // var planning = new PlanningDto - // { - // DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, - // CommandId = expectedDeviceModelCommandDto[0].Id - // }; - // var firstSchedule = new ScheduleDto - // { - // Start = "00:00" - // }; + var planning = new PlanningDto + { + DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, + CommandId = expectedDeviceModelCommandDto[0].Id + }; + var firstSchedule = new ScheduleDto + { + Start = "00:00" + }; - // var scheduleList = new List - // { - // firstSchedule - // }; + var scheduleList = new List + { + firstSchedule + }; - // _ = this.mockLayerClientService.Setup(service => service.GetLayers()) - // .ReturnsAsync(new List()); + _ = this.mockLayerClientService.Setup(service => service.GetLayers()) + .ReturnsAsync(new List()); - // _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModels(It.IsAny())) - // .ReturnsAsync(new PaginationResult - // { - // Items = new List() - // }); + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List { expectedDeviceModelDto } + }); - // // Act - // var cut = RenderComponent( - // ComponentParameter.CreateParameter("mode", "New"), - // ComponentParameter.CreateParameter("planning", planning), - // ComponentParameter.CreateParameter("scheduleList", scheduleList ) - // ); + _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) + .ReturnsAsync(expectedDeviceModelCommandDto); - // Assert.AreEqual(DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, cut.Instance.planning.DayOff); - // Assert.AreEqual("00:00", cut.Instance.scheduleList[0].Start); - // cut.WaitForAssertion(() => MockRepository.VerifyAll()); - //} + // Act + var cut = RenderComponent( + ComponentParameter.CreateParameter("mode", "New"), + ComponentParameter.CreateParameter("planning", planning), + ComponentParameter.CreateParameter("scheduleList", scheduleList), + ComponentParameter.CreateParameter("SelectedModel", expectedDeviceModelDto.Name) + ); - // TODO: To fix - //[Test] - //public void EditPlanningInit_AddScheduleShouldNotWork() - //{ - // var expectedLayers = Fixture.CreateMany(1).ToList(); - // var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); + Assert.AreEqual(DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, cut.Instance.planning.DayOff); + Assert.AreEqual("00:00", cut.Instance.scheduleList[0].Start); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } - // var planning = new PlanningDto - // { - // DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, - // CommandId = expectedDeviceModelCommandDto[0].Id - // }; - // var firstSchedule = new ScheduleDto - // { - // Start = "00:00" - // }; + [Test] + public void EditPlanningInit_AddScheduleShouldNotWork() + { + var expectedDeviceModelDto = Fixture.CreateMany(1).ToList(); + var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); - // var scheduleList = new List - // { - // firstSchedule - // }; + var planning = new PlanningDto + { + DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, + CommandId = expectedDeviceModelCommandDto[0].Id + }; + var firstSchedule = new ScheduleDto + { + Start = "00:00" + }; - // _ = this.mockLayerClientService.Setup(service => service.GetLayers()) - // .ReturnsAsync(new List()); + var scheduleList = new List + { + firstSchedule + }; - // _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModels(It.IsAny())) - // .ReturnsAsync(new PaginationResult - // { - // Items = expectedLayers - // }); + _ = this.mockLayerClientService.Setup(service => service.GetLayers()) + .ReturnsAsync(new List()); - // _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) - // .ReturnsAsync(expectedDeviceModelCommandDto); + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = expectedDeviceModelDto + }); - // // Act - // var cut = RenderComponent( - // ComponentParameter.CreateParameter("mode", "New"), - // ComponentParameter.CreateParameter("planning", planning), - // ComponentParameter.CreateParameter("scheduleList", scheduleList ) - // ); + _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) + .ReturnsAsync(expectedDeviceModelCommandDto); - // var editPlanningAddLayers = cut.WaitForElement("#editPlanningAddLayers"); - // editPlanningAddLayers.Click(); + // Act + var cut = RenderComponent( + ComponentParameter.CreateParameter("mode", "New"), + ComponentParameter.CreateParameter("planning", planning), + ComponentParameter.CreateParameter("scheduleList", scheduleList ) + ); - // Assert.AreEqual(1, cut.Instance.scheduleList.Count); - // cut.WaitForAssertion(() => MockRepository.VerifyAll()); - //} + var editPlanningAddSchedule = cut.WaitForElement("#addScheduleButton"); + editPlanningAddSchedule.Click(); - // TODO: To fix - //[Test] - //public async Task EditPlanningInit_AddSchedule() - //{ - // var expectedLayers = Fixture.CreateMany(1).ToList(); - // var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); + Assert.AreEqual(1, cut.Instance.scheduleList.Count); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } - // var planning = new PlanningDto - // { - // DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, - // CommandId = expectedDeviceModelCommandDto[0].Id - // }; - // var firstSchedule = new ScheduleDto - // { - // Start = "00:00", - // CommandId = expectedDeviceModelCommandDto[0].Id - // }; + [Test] + public async Task EditPlanningInit_AddSchedule() + { + var expectedDeviceModelDto = Fixture.CreateMany(1).ToList(); + var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); - // var scheduleList = new List - // { - // firstSchedule - // }; + var planning = new PlanningDto + { + DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, + CommandId = expectedDeviceModelCommandDto[0].Id + }; + var firstSchedule = new ScheduleDto + { + Start = "00:00", + CommandId = expectedDeviceModelCommandDto[0].Id + }; - // _ = this.mockLayerClientService.Setup(service => service.GetLayers()) - // .ReturnsAsync(new List()); + var scheduleList = new List + { + firstSchedule + }; - // _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModels(It.IsAny())) - // .ReturnsAsync(new PaginationResult - // { - // Items = expectedLayers - // }); + _ = this.mockLayerClientService.Setup(service => service.GetLayers()) + .ReturnsAsync(new List()); - // _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) - // .ReturnsAsync(expectedDeviceModelCommandDto); + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = expectedDeviceModelDto + }); - // // Act - // var cut = RenderComponent( - // ComponentParameter.CreateParameter("mode", "New"), - // ComponentParameter.CreateParameter("planning", planning), - // ComponentParameter.CreateParameter("scheduleList", scheduleList ) - // ); + _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) + .ReturnsAsync(expectedDeviceModelCommandDto); - // var endField = cut.FindComponents>()[2]; - // await cut.InvokeAsync(() => endField.Instance.SetText("23:59")); + // Act + var cut = RenderComponent( + ComponentParameter.CreateParameter("mode", "New"), + ComponentParameter.CreateParameter("planning", planning), + ComponentParameter.CreateParameter("scheduleList", scheduleList ) + ); - // var editPlanningAddLayers = cut.WaitForElement("#editPlanningAddLayers"); - // editPlanningAddLayers.Click(); + var endField = cut.FindComponents>()[2]; + await cut.InvokeAsync(() => endField.Instance.SetText("23:59")); - // Assert.AreEqual(2, cut.Instance.scheduleList.Count); - // cut.WaitForAssertion(() => MockRepository.VerifyAll()); - //} + var editPlanningAddSchedule = cut.WaitForElement("#addScheduleButton"); + editPlanningAddSchedule.Click(); - // TODO: To fix - //[Test] - //public async Task EditPlanningInit_DeleteSchedule() - //{ - // var expectedLayers = Fixture.CreateMany(1).ToList(); - // var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); + Assert.AreEqual(2, cut.Instance.scheduleList.Count); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } - // var planning = new PlanningDto - // { - // DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, - // CommandId = expectedDeviceModelCommandDto[0].Id - // }; - // var firstSchedule = new ScheduleDto - // { - // Start = "00:00", - // CommandId = expectedDeviceModelCommandDto[0].Id - // }; + [Test] + public async Task EditPlanningInit_DeleteSchedule() + { + var expectedDeviceModelDto = Fixture.CreateMany(1).ToList(); + var expectedDeviceModelCommandDto = Fixture.CreateMany(3).ToList(); - // var scheduleList = new List - // { - // firstSchedule - // }; + var planning = new PlanningDto + { + DayOff = DaysEnumFlag.DaysOfWeek.Saturday | DaysEnumFlag.DaysOfWeek.Sunday, + CommandId = expectedDeviceModelCommandDto[0].Id + }; + var firstSchedule = new ScheduleDto + { + Start = "00:00", + CommandId = expectedDeviceModelCommandDto[0].Id + }; - // _ = this.mockLayerClientService.Setup(service => service.GetLayers()) - // .ReturnsAsync(new List()); + var scheduleList = new List + { + firstSchedule + }; - // _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModels(It.IsAny())) - // .ReturnsAsync(new PaginationResult - // { - // Items = expectedLayers - // }); + _ = this.mockLayerClientService.Setup(service => service.GetLayers()) + .ReturnsAsync(new List()); - // _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) - // .ReturnsAsync(expectedDeviceModelCommandDto); + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = expectedDeviceModelDto + }); - // // Act - // var cut = RenderComponent( - // ComponentParameter.CreateParameter("mode", "New"), - // ComponentParameter.CreateParameter("planning", planning), - // ComponentParameter.CreateParameter("scheduleList", scheduleList ) - // ); + _ = this.mockLoRaWanDeviceModelsClientService.Setup(service => service.GetDeviceModelCommands(It.IsAny())) + .ReturnsAsync(expectedDeviceModelCommandDto); + + // Act + var cut = RenderComponent( + ComponentParameter.CreateParameter("mode", "New"), + ComponentParameter.CreateParameter("planning", planning), + ComponentParameter.CreateParameter("scheduleList", scheduleList ) + ); - // var endField = cut.FindComponents>()[2]; - // await cut.InvokeAsync(() => endField.Instance.SetText("23:59")); + var endField = cut.FindComponents>()[2]; + await cut.InvokeAsync(() => endField.Instance.SetText("23:59")); - // var editPlanningAddLayers = cut.WaitForElement("#editPlanningAddLayers"); - // editPlanningAddLayers.Click(); + var editPlanningAddSchedule = cut.WaitForElement("#addScheduleButton"); + editPlanningAddSchedule.Click(); - // var editPlanningDeleteLayers = cut.FindAll("#editPlanningDeleteLayers")[1]; - // editPlanningDeleteLayers.Click(); + var editPlanningDeleteSchedule = cut.FindAll("#deleteScheduleButton")[1]; + editPlanningDeleteSchedule.Click(); - // Assert.AreEqual(1, cut.Instance.scheduleList.Count); - // cut.WaitForAssertion(() => MockRepository.VerifyAll()); - //} + Assert.AreEqual(1, cut.Instance.scheduleList.Count); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } [Test] public void EditPlanningInit_ProblemDetailsException() @@ -479,5 +491,184 @@ public void EditPlanningInit_ChangeOffDay() // cut.WaitForAssertion(() => MockRepository.VerifyAll()); //} + + [Test] + public void ClickOnDeleteShouldDisplayConfirmationDialogAndReturnIfAborted() + { + var mockPlanning = new PlanningDto + { + Id = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + var mockDeviceModel = new DeviceModelDto + { + ModelId = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + var mockScheduleList = Fixture.CreateMany(2).ToList(); + + _ = this.mockLayerClientService.Setup(service => + service.GetLayers()) + .ReturnsAsync(new List + { + new LayerDto { Id = Guid.NewGuid().ToString(), Name = Guid.NewGuid().ToString() } + }); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List() + }); + + var mockDialogReference = MockRepository.Create(); + _ = mockDialogReference.Setup(c => c.Result).ReturnsAsync(DialogResult.Cancel); + _ = this.mockDialogService.Setup(c => c.Show(It.IsAny(), It.IsAny())) + .Returns(mockDialogReference.Object); + + var cut = RenderComponent(parameters => parameters.Add(p => p.mode, "Edit") + .Add(p => p.planning, mockPlanning) + .Add(p => p.scheduleList, mockScheduleList) + .Add(p => p.initScheduleList, new List(mockScheduleList)) + .Add(p => p.SelectedModel, mockDeviceModel.Name)); + + var deleteButton = cut.WaitForElement("#deleteButton"); + deleteButton.Click(); + + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + + [Test] + public void ClickOnDeleteShouldDisplayConfirmationDialogAndRedirectIfConfirmed() + { + var mockPlanning = new PlanningDto + { + Id = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + var mockDeviceModel = new List + { + new DeviceModelDto + { + ModelId = Guid.NewGuid().ToString(), Name = Guid.NewGuid().ToString() + }, + new DeviceModelDto + { + ModelId = Guid.NewGuid().ToString(), Name = Guid.NewGuid().ToString() + } + }; + + var mockScheduleList = Fixture.CreateMany(2).ToList(); + + var deviceModels = Fixture.CreateMany(2).ToList(); + + var expectedPaginatedDeviceModels = new PaginationResult() + { + Items = mockDeviceModel.ToList(), + TotalItems = mockDeviceModel.Count + }; + + _ = this.mockLayerClientService.Setup(service => + service.GetLayers()) + .ReturnsAsync(new List + { + new LayerDto { Id = Guid.NewGuid().ToString(), Name = Guid.NewGuid().ToString() } + }); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List() + }); + + var mockDialogReference = MockRepository.Create(); + _ = mockDialogReference.Setup(c => c.Result).ReturnsAsync(DialogResult.Ok("Ok")); + _ = this.mockDialogService.Setup(c => c.Show(It.IsAny(), It.IsAny())) + .Returns(mockDialogReference.Object); + + var cut = RenderComponent(parameters => parameters.Add(p => p.mode, "Edit") + .Add(p => p.planning, mockPlanning) + .Add(p => p.scheduleList, mockScheduleList) + .Add(p => p.initScheduleList, new List(mockScheduleList)) + .Add(p => p.SelectedModel, mockDeviceModel[0].Name)); + + var deleteButton = cut.WaitForElement("#deleteButton"); + deleteButton.Click(); + + cut.WaitForState(() => this.mockNavigationManager.Uri.EndsWith("/planning", StringComparison.OrdinalIgnoreCase)); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + [Test] + public async Task DisplayLayersRenderCorrectly() + { + var mockPlanning = new PlanningDto + { + Id = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + var mockDeviceModel = new DeviceModelDto + { + ModelId = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + var mockScheduleList = Fixture.CreateMany(2).ToList(); + + var mockPrincipalLayer = new LayerDto + { + Id = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString(), + Planning = null, + Father = null + }; + + var mockSubLayer1 = new LayerDto + { + Id = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString(), + Planning = mockPlanning.Id, + Father = mockPrincipalLayer.Id + }; + + var mockSubLayer2 = new LayerDto + { + Id = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString(), + Planning = Guid.NewGuid().ToString(), + Father = mockPrincipalLayer.Id + }; + + _ = this.mockLayerClientService.Setup(service => + service.GetLayers()) + .ReturnsAsync(new List + { + mockPrincipalLayer, + mockSubLayer1, + mockSubLayer2 + }); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List() + }); + + var cut = RenderComponent(parameters => parameters.Add(p => p.mode, "Edit") + .Add(p => p.planning, mockPlanning) + .Add(p => p.scheduleList, mockScheduleList) + .Add(p => p.initScheduleList, new List(mockScheduleList)) + .Add(p => p.SelectedModel, mockDeviceModel.Name)); + + var tooltips = cut.FindComponents(); + _ = tooltips[0].Instance.Text.Should().Be("Add layer"); + _ = tooltips[1].Instance.Text.Should().Be("Already registered"); + _ = tooltips[2].Instance.Text.Should().Be("Registered on other planning"); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } } } diff --git a/src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Layer/LinkDeviceLayerDialogTest.cs b/src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Layer/LinkDeviceLayerDialogTest.cs new file mode 100644 index 000000000..eb3ba89a3 --- /dev/null +++ b/src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Layer/LinkDeviceLayerDialogTest.cs @@ -0,0 +1,177 @@ +// Copyright (c) CGI France. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace IoTHub.Portal.Tests.Unit.Client.Dialogs.Layer +{ + using System.Collections.Generic; + using System.Linq; + using System.Threading.Tasks; + using IoTHub.Portal.Client.Dialogs.Layer; + + public class LinkDeviceLayerDialogTest : BlazorUnitTest + { + private Mock mockDeviceClientService; + private Mock mockLayerClientService; + private Mock mockDeviceModelsClientService; + + private readonly string apiBaseUrl = "api/devices"; + + public override void Setup() + { + base.Setup(); + + this.mockDeviceClientService = MockRepository.Create(); + this.mockLayerClientService = MockRepository.Create(); + this.mockDeviceModelsClientService = MockRepository.Create(); + + _ = Services.AddSingleton(this.mockDeviceClientService.Object); + _ = Services.AddSingleton(this.mockLayerClientService.Object); + _ = Services.AddSingleton(this.mockDeviceModelsClientService.Object); + } + + [Test] + public async Task LinkDeviceLayerDialog_Search_RendersCorrectlyAsync() + { + // Arrange + var searchedDevices = Fixture.CreateMany>(3).ToList(); + var expectedLayerDto = Fixture.Create(); + + _ = this.mockDeviceClientService.Setup(service => + service.GetDevices($"{this.apiBaseUrl}?pageNumber=0&pageSize=5&searchText=")) + .ReturnsAsync(new PaginationResult + { + Items = new[] { new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true }, + new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true }} + }); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List() + }); + + // Act + var cut = RenderComponent(); + var service = Services.GetService() as DialogService; + + var parameters = new DialogParameters + { + {"InitLayer", expectedLayerDto}, + {"LayerList", new HashSet()} + }; + + _ = await cut.InvokeAsync(() => service?.Show(string.Empty, parameters)); + + // Assert + cut.WaitForAssertion(() => cut.FindAll("table tbody tr").Count.Should().Be(2)); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + [Test] + public async Task LinkDeviceLayerDialog_Search_ShouldDisplayDevicesAsync() + { + // Arrange + var searchedDevices = Fixture.CreateMany>(3).ToList(); + var expectedLayerDto = Fixture.Create(); + + var mockDeviceModel = new DeviceModelDto + { + ModelId = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + + _ = this.mockDeviceClientService.Setup(service => + service.GetDevices($"{this.apiBaseUrl}?pageNumber=0&pageSize=5&searchText=")) + .ReturnsAsync(new PaginationResult + { + Items = new[] { new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true, DeviceModelId = mockDeviceModel.ModelId }, + new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true, DeviceModelId = Guid.NewGuid().ToString() }} + }); + + _ = this.mockDeviceClientService.Setup(service => + service.GetDevices($"{this.apiBaseUrl}?pageNumber=0&pageSize=5&searchText=&modelId={mockDeviceModel.ModelId}")) + .ReturnsAsync(new PaginationResult + { + Items = new[] { new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true, DeviceModelId = mockDeviceModel.ModelId } } + }); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List + { + mockDeviceModel + } + }); + + // Act + var cut = RenderComponent(); + var service = Services.GetService() as DialogService; + + var parameters = new DialogParameters + { + {"InitLayer", expectedLayerDto}, + {"LayerList", new HashSet()} + }; + + _ = await cut.InvokeAsync(() => service?.Show(string.Empty, parameters)); + cut.WaitForElement("#saveButton").Click(); + + // Assert + cut.WaitForAssertion(() => cut.FindAll("table tbody tr").Count.Should().Be(1)); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + [Test] + public async Task LinkDeviceLayerDialog_Save_UpdatesDevices() + { + // Arrange + var searchedDevices = Fixture.CreateMany>(3).ToList(); + var expectedLayerDto = Fixture.Create(); + + var mockDeviceModel = new DeviceModelDto + { + ModelId = Guid.NewGuid().ToString(), + Name = Guid.NewGuid().ToString() + }; + + + _ = this.mockDeviceClientService.Setup(service => + service.GetDevices($"{this.apiBaseUrl}?pageNumber=0&pageSize=5&searchText=")) + .ReturnsAsync(new PaginationResult + { + Items = new[] { new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true, DeviceModelId = mockDeviceModel.ModelId }, + new DeviceListItem { DeviceID = Guid.NewGuid().ToString(), IsEnabled = true, IsConnected = true, DeviceModelId = Guid.NewGuid().ToString() }} + }); + + _ = this.mockDeviceModelsClientService.Setup(service => service.GetDeviceModelsAsync(It.IsAny())) + .ReturnsAsync(new PaginationResult + { + Items = new List + { + mockDeviceModel + } + }); + + _ = this.mockLayerClientService.Setup(service => service.UpdateLayer(expectedLayerDto)) + .Returns(Task.CompletedTask); + + // Act + var cut = RenderComponent(); + var service = Services.GetService() as DialogService; + + var parameters = new DialogParameters + { + {"InitLayer", expectedLayerDto}, + {"LayerList", new HashSet()} + }; + + _ = await cut.InvokeAsync(() => service?.Show(string.Empty, parameters)); + cut.WaitForElement("#save").Click(); + + // Assert + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + } +} diff --git a/src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Planning/DeletePlanningDialogTest.cs b/src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Planning/DeletePlanningDialogTest.cs new file mode 100644 index 000000000..cd54c36f3 --- /dev/null +++ b/src/IoTHub.Portal.Tests.Unit/Client/Dialogs/Planning/DeletePlanningDialogTest.cs @@ -0,0 +1,58 @@ +// Copyright (c) CGI France. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace IoTHub.Portal.Tests.Unit.Client.Dialogs.Planning +{ + using System; + using System.Collections.Generic; + using System.Threading.Tasks; + using IoTHub.Portal.Client.Dialogs.Planning; + + [TestFixture] + public class DeletePlanningDialogTest : BlazorUnitTest + { + private Mock mockPlanningClientService; + private Mock mockLayerClientService; + + public override void Setup() + { + base.Setup(); + + this.mockPlanningClientService = MockRepository.Create(); + this.mockLayerClientService = MockRepository.Create(); + + _ = Services.AddSingleton(this.mockPlanningClientService.Object); + _ = Services.AddSingleton(this.mockLayerClientService.Object); + } + + [Test] + public async Task DeletePlanning_PlanningDeleted() + { + // Arrange + var planningId = Guid.NewGuid().ToString(); + var planningName = Guid.NewGuid().ToString(); + + _ = this.mockLayerClientService.Setup(service => service.GetLayers()) + .ReturnsAsync(new List()); + + _ = this.mockPlanningClientService.Setup(service => service.DeletePlanning(planningId)) + .Returns(Task.CompletedTask); + + var cut = RenderComponent(); + var service = Services.GetService() as DialogService; + + var parameters = new DialogParameters + { + {"planningID", planningId}, + {"planningName", planningName} + }; + + // Act + _ = await cut.InvokeAsync(() => service?.Show(string.Empty, parameters)); + cut.WaitForElement("#delete-planning").Click(); + + // Assert + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + } +} diff --git a/src/IoTHub.Portal.Tests.Unit/Client/Pages/Planning/PlanningListPageTest.cs b/src/IoTHub.Portal.Tests.Unit/Client/Pages/Planning/PlanningListPageTest.cs index 5e4dae410..7bb4d644b 100644 --- a/src/IoTHub.Portal.Tests.Unit/Client/Pages/Planning/PlanningListPageTest.cs +++ b/src/IoTHub.Portal.Tests.Unit/Client/Pages/Planning/PlanningListPageTest.cs @@ -3,19 +3,24 @@ namespace IoTHub.Portal.Tests.Unit.Client.Pages.Planning { + using IoTHub.Portal.Client.Dialogs.Planning; + [TestFixture] internal class PlanningListPageTest : BlazorUnitTest { private Mock mockPlanningClientService; private FakeNavigationManager mockNavigationManager; + private Mock mockDialogService; public override void Setup() { base.Setup(); this.mockPlanningClientService = MockRepository.Create(); + this.mockDialogService = MockRepository.Create(); _ = Services.AddSingleton(this.mockPlanningClientService.Object); _ = Services.AddSingleton(new PortalSettings { IsLoRaSupported = true }); + _ = Services.AddSingleton(this.mockDialogService.Object); this.mockNavigationManager = Services.GetRequiredService(); } @@ -90,5 +95,32 @@ public void OnInitializedAsync_ListDetailPlanningPage() cut.WaitForAssertion(() => this.mockNavigationManager.Uri.Should().EndWith($"/planning/{expectedPlannings[0].Id}")); cut.WaitForAssertion(() => MockRepository.VerifyAll()); } + + [Test] + public void DeletePlanning_Clicked_DeletePlanningDialogIsShown() + { + // Arrange + var planningId = Guid.NewGuid().ToString(); + + _ = this.mockPlanningClientService.Setup(service => + service.GetPlannings()).ReturnsAsync(new List + { + new PlanningDto() { Id = planningId, Name = Guid.NewGuid().ToString() } + }); + + var mockDialogReference = MockRepository.Create(); + _ = mockDialogReference.Setup(c => c.Result).ReturnsAsync(DialogResult.Ok("Ok")); + _ = this.mockDialogService.Setup(c => c.Show(It.IsAny(), It.IsAny())) + .Returns(mockDialogReference.Object); + + var cut = RenderComponent(); + cut.WaitForAssertion(() => cut.Markup.Should().NotContain("Loading...")); + + // Act + cut.WaitForElement($"#delete-planning-{planningId}").Click(); + + // Assert + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } } } diff --git a/src/IoTHub.Portal.Tests.Unit/Infrastructure/DevelopmentConfigHandlerTests.cs b/src/IoTHub.Portal.Tests.Unit/Infrastructure/DevelopmentConfigHandlerTests.cs index 337702b63..b8de5c89d 100644 --- a/src/IoTHub.Portal.Tests.Unit/Infrastructure/DevelopmentConfigHandlerTests.cs +++ b/src/IoTHub.Portal.Tests.Unit/Infrastructure/DevelopmentConfigHandlerTests.cs @@ -299,5 +299,15 @@ public void DbProviderKeyShouldBeExpectedDefaultValue() // Assert _ = developmentConfigHandler.DbProvider.Should().Be(DbProviders.PostgreSQL); } + + [Test] + public void SendCommandsToDevicesIntervalInMinutesConfigMustHaveDefaultValue() + { + // Arrange + var developmentConfigHandler = new DevelopmentConfigHandler(new ConfigurationManager()); + + // Assert + _ = developmentConfigHandler.SendCommandsToDevicesIntervalInMinutes.Should().Be(10); + } } } diff --git a/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAWSConfigHandlerTests.cs b/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAWSConfigHandlerTests.cs index 520ab0732..c276523ae 100644 --- a/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAWSConfigHandlerTests.cs +++ b/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAWSConfigHandlerTests.cs @@ -314,5 +314,15 @@ public void DbProviderKeyShouldBeExpectedDefaultValue() // Assert _ = productionAWSConfigHandler.DbProvider.Should().Be(DbProviders.PostgreSQL); } + + [Test] + public void SendCommandsToDevicesIntervalInMinutesConfigMustHaveDefaultValue() + { + // Arrange + var productionAWSConfigHandler = new ProductionAWSConfigHandler(new ConfigurationManager()); + + // Assert + _ = productionAWSConfigHandler.SendCommandsToDevicesIntervalInMinutes.Should().Be(10); + } } } diff --git a/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAzureConfigHandlerTests.cs b/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAzureConfigHandlerTests.cs index e575c2bce..b97e4216d 100644 --- a/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAzureConfigHandlerTests.cs +++ b/src/IoTHub.Portal.Tests.Unit/Infrastructure/ProductionAzureConfigHandlerTests.cs @@ -300,5 +300,15 @@ public void DbProviderKeyShouldBeExpectedDefaultValue() // Assert _ = productionConfigHandler.DbProvider.Should().Be(DbProviders.PostgreSQL); } + + [Test] + public void SendCommandsToDevicesIntervalInMinutesConfigMustHaveDefaultValue() + { + // Arrange + var productionConfigHandler = new ProductionAzureConfigHandler(new ConfigurationManager()); + + // Assert + _ = productionConfigHandler.SendCommandsToDevicesIntervalInMinutes.Should().Be(10); + } } } diff --git a/src/IoTHub.Portal.Tests.Unit/IoTHub.Portal.Tests.Unit.csproj b/src/IoTHub.Portal.Tests.Unit/IoTHub.Portal.Tests.Unit.csproj index e2c5ce67f..7b019d5ca 100644 --- a/src/IoTHub.Portal.Tests.Unit/IoTHub.Portal.Tests.Unit.csproj +++ b/src/IoTHub.Portal.Tests.Unit/IoTHub.Portal.Tests.Unit.csproj @@ -46,7 +46,6 @@ - diff --git a/src/IoTHub.Portal.Tests.Unit/Server/Managers/ExportManagerTests.cs b/src/IoTHub.Portal.Tests.Unit/Server/Managers/ExportManagerTests.cs index 662d484ee..b7dfb9de2 100644 --- a/src/IoTHub.Portal.Tests.Unit/Server/Managers/ExportManagerTests.cs +++ b/src/IoTHub.Portal.Tests.Unit/Server/Managers/ExportManagerTests.cs @@ -117,7 +117,7 @@ public void ExportDeviceListLoRaEnabledShouldWriteStreamAndDisplayLoRaSpecificFi using var reader = new StreamReader(fileStream); var header = reader.ReadLine(); - _ = header.Split(",").Length.Should().Be(28); + _ = header.Split(",").Length.Should().Be(14); var content = reader.ReadToEnd(); _ = content.TrimEnd().Split("\r\n").Length.Should().Be(2); @@ -151,7 +151,7 @@ public void ExportTemplateFileLoRaDisabledShouldWriteStream() using var reader = new StreamReader(fileStream); var content = reader.ReadToEnd(); _ = content.TrimEnd().Split("\r\n").Length.Should().Be(1); - _ = content.Split(",").Length.Should().Be(7); + _ = content.Split(",").Length.Should().Be(8); } [Test] @@ -181,7 +181,7 @@ public void ExportTemplateFileLoRaEnabledShouldWriteStreamAndDisplayLoRaSpecific using var reader = new StreamReader(fileStream); var content = reader.ReadToEnd(); _ = content.TrimEnd().Split("\r\n").Length.Should().Be(1); - _ = content.Split(",").Length.Should().Be(27); + _ = content.Split(",").Length.Should().Be(14); MockRepository.VerifyAll(); }