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
{
-
+
CheckedChanged(context)">
}
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();
}