From ee3547a01311144fd5ca106663d2cc97e76c40c7 Mon Sep 17 00:00:00 2001 From: GuillaumeM <86654731+GuillaumeM-2ISA@users.noreply.github.com> Date: Wed, 15 Feb 2023 16:18:39 +0100 Subject: [PATCH] enable search on concentrator page (#1755) * enable search on concentrator page * update unit tests ConcentratorSearch component * update unit tests services + list page * update Lorawan Concentrator Service * update concentrator list page --- .../Services/ILoRaWANConcentratorService.cs | 3 +- .../Concentrators/ConcentratorSearch.razor | 76 ++++++++++++++++ .../Models/ConcentratorSearchInfo.cs | 12 +++ .../Concentrator/ConcentratorListPage.razor | 26 ++++-- .../LoRaWAN/LoRaWANConcentratorsController.cs | 17 ++-- .../Services/LoRaWANConcentratorService.cs | 25 +++++- .../Models/v1.0/Filters/ConcentratorFilter.cs | 15 ++++ .../Concentrators/ConcentratorSearchTests.cs | 87 +++++++++++++++++++ .../Concentrator/ConcentratorListPageTests.cs | 63 ++++++++++++-- .../LoRaWANConcentratorsControllerTest.cs | 5 +- .../LoRaWANConcentratorServiceTests.cs | 48 +++++++++- src/AzureIoTHub.Portal.sln | 2 +- 12 files changed, 346 insertions(+), 33 deletions(-) create mode 100644 src/AzureIoTHub.Portal.Client/Components/Concentrators/ConcentratorSearch.razor create mode 100644 src/AzureIoTHub.Portal.Client/Models/ConcentratorSearchInfo.cs create mode 100644 src/AzureIoTHub.Portal.Shared/Models/v1.0/Filters/ConcentratorFilter.cs create mode 100644 src/AzureIoTHub.Portal.Tests.Unit/Client/Components/Concentrators/ConcentratorSearchTests.cs diff --git a/src/AzureIoTHub.Portal.Application/Services/ILoRaWANConcentratorService.cs b/src/AzureIoTHub.Portal.Application/Services/ILoRaWANConcentratorService.cs index 35f1c733f..f2eb896d9 100644 --- a/src/AzureIoTHub.Portal.Application/Services/ILoRaWANConcentratorService.cs +++ b/src/AzureIoTHub.Portal.Application/Services/ILoRaWANConcentratorService.cs @@ -6,10 +6,11 @@ namespace AzureIoTHub.Portal.Application.Services using System.Threading.Tasks; using AzureIoTHub.Portal.Models.v10.LoRaWAN; using AzureIoTHub.Portal.Shared.Models.v1._0; + using AzureIoTHub.Portal.Shared.Models.v10.Filters; public interface ILoRaWANConcentratorService { - Task> GetAllDeviceConcentrator(int pageSize = 10, int pageNumber = 0, string[] orderBy = null); + Task> GetAllDeviceConcentrator(ConcentratorFilter concentratorFilter); Task GetConcentrator(string deviceId); Task CreateDeviceAsync(ConcentratorDto concentrator); Task UpdateDeviceAsync(ConcentratorDto concentrator); diff --git a/src/AzureIoTHub.Portal.Client/Components/Concentrators/ConcentratorSearch.razor b/src/AzureIoTHub.Portal.Client/Components/Concentrators/ConcentratorSearch.razor new file mode 100644 index 000000000..a9da950e5 --- /dev/null +++ b/src/AzureIoTHub.Portal.Client/Components/Concentrators/ConcentratorSearch.razor @@ -0,0 +1,76 @@ + + + + + + + + + Status + + + Enabled + + + Disabled + + + All + + + + + + Connection state + + + Connected + + + Disconnected + + + All + + + + + + + Search + Reset + + + + + + + +@code { + [Parameter] + public EventCallback OnSearch { get; set; } + + private string? searchKeyword = string.Empty; + private string? searchStatus = string.Empty; + private string? searchState = string.Empty; + + private async Task Search() + { + var searchInfo = new ConcentratorSearchInfo + { + SearchKeyword = searchKeyword, + SearchStatus = searchStatus, + SearchState = searchState + }; + await OnSearch.InvokeAsync(searchInfo); + } + + private async Task Reset() + { + searchKeyword = string.Empty; + searchStatus = string.Empty; + searchState = string.Empty; + + await Search(); + } +} diff --git a/src/AzureIoTHub.Portal.Client/Models/ConcentratorSearchInfo.cs b/src/AzureIoTHub.Portal.Client/Models/ConcentratorSearchInfo.cs new file mode 100644 index 000000000..af831ee78 --- /dev/null +++ b/src/AzureIoTHub.Portal.Client/Models/ConcentratorSearchInfo.cs @@ -0,0 +1,12 @@ +// Copyright (c) CGI France. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace AzureIoTHub.Portal.Client.Models +{ + public class ConcentratorSearchInfo + { + public string? SearchKeyword { get; set; } + public string? SearchStatus { get; set; } + public string? SearchState { get; set; } + } +} diff --git a/src/AzureIoTHub.Portal.Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor b/src/AzureIoTHub.Portal.Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor index 8dc3530d1..b2c403694 100644 --- a/src/AzureIoTHub.Portal.Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor +++ b/src/AzureIoTHub.Portal.Client/Pages/LoRaWAN/Concentrator/ConcentratorListPage.razor @@ -1,5 +1,6 @@ @page "/lorawan/concentrators" @using AzureIoTHub.Portal +@using AzureIoTHub.Portal.Client.Components.Concentrators @using AzureIoTHub.Portal.Models.v10.LoRaWAN @attribute [Authorize] @@ -8,7 +9,9 @@ @inject ILoRaWanConcentratorClientService LoRaWanConcentratorsClientService - + + await Search(args)) /> + @@ -96,13 +99,15 @@ @code { [CascadingParameter] public Error Error {get; set;} - + private MudTable table; private readonly Dictionary pages = new(); private bool IsLoading { get; set; } = true; + private ConcentratorSearchInfo concentratorSearchInfo = new(); + private async Task> LoadItems(TableState state) { try @@ -119,7 +124,7 @@ break; } - var uri = $"api/lorawan/concentrators?pageNumber={state.Page}&pageSize={state.PageSize}&orderBy={orderBy}"; + var uri = $"api/lorawan/concentrators?pageNumber={state.Page}&pageSize={state.PageSize}&orderBy={orderBy}&keyword={this.concentratorSearchInfo.SearchKeyword}&status={this.concentratorSearchInfo.SearchStatus}&state={this.concentratorSearchInfo.SearchState}"; var result = await LoRaWanConcentratorsClientService.GetConcentrators(uri); @@ -148,7 +153,7 @@ private async Task DeleteDevice(ConcentratorDto device) { var parameters = new DialogParameters {{"deviceId", device.DeviceId}}; - + var result = await DialogService.Show("Confirm Deletion", parameters).Result; if (result.Cancelled) @@ -157,12 +162,19 @@ } // Update the list of devices after the deletion - Search(); + await Search(); } - private void Search() + private async Task Search(ConcentratorSearchInfo concentratorSearchInfo = null) { - pages.Clear(); + if (concentratorSearchInfo == null) + { + this.concentratorSearchInfo = new(); + } + else + { + this.concentratorSearchInfo = concentratorSearchInfo; + } table.ReloadServerData(); } diff --git a/src/AzureIoTHub.Portal.Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsController.cs b/src/AzureIoTHub.Portal.Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsController.cs index ebe6af3a2..4e00c1645 100644 --- a/src/AzureIoTHub.Portal.Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsController.cs +++ b/src/AzureIoTHub.Portal.Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsController.cs @@ -7,6 +7,7 @@ namespace AzureIoTHub.Portal.Server.Controllers.V10.LoRaWAN using System.Threading.Tasks; using AzureIoTHub.Portal.Application.Services; using AzureIoTHub.Portal.Models.v10.LoRaWAN; + using AzureIoTHub.Portal.Shared.Models.v10.Filters; using Filters; using Hellang.Middleware.ProblemDetails; using Microsoft.AspNetCore.Authorization; @@ -51,15 +52,9 @@ public LoRaWANConcentratorsController( /// [HttpGet(Name = "GET LoRaWAN Concentrator list")] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task>> GetAllDeviceConcentrator( - int pageSize = 10, - int pageNumber = 0, - [FromQuery] string[] orderBy = null) + public async Task>> GetAllDeviceConcentrator([FromQuery] ConcentratorFilter concentratorFilter) { - var paginatedDevices = await this.loRaWANConcentratorService.GetAllDeviceConcentrator( - pageSize, - pageNumber, - orderBy); + var paginatedDevices = await this.loRaWANConcentratorService.GetAllDeviceConcentrator(concentratorFilter); var nextPage = string.Empty; @@ -70,9 +65,9 @@ public async Task>> GetAllDeviceC RouteName = "GET LoRaWAN Concentrator list", Values = new { - pageSize, - pageNumber = pageNumber + 1, - orderBy + concentratorFilter.PageSize, + pageNumber = concentratorFilter.PageNumber + 1, + concentratorFilter.OrderBy } }); } diff --git a/src/AzureIoTHub.Portal.Server/Services/LoRaWANConcentratorService.cs b/src/AzureIoTHub.Portal.Server/Services/LoRaWANConcentratorService.cs index c6a9f3fc0..2a5587cb5 100644 --- a/src/AzureIoTHub.Portal.Server/Services/LoRaWANConcentratorService.cs +++ b/src/AzureIoTHub.Portal.Server/Services/LoRaWANConcentratorService.cs @@ -7,6 +7,8 @@ namespace AzureIoTHub.Portal.Server.Services using AutoMapper; using AzureIoTHub.Portal.Application.Mappers; using AzureIoTHub.Portal.Application.Services; + using AzureIoTHub.Portal.Infrastructure.Repositories; + using AzureIoTHub.Portal.Shared.Models.v10.Filters; using Domain; using Domain.Entities; using Domain.Exceptions; @@ -55,11 +57,26 @@ IConcentratorRepository concentratorRepository } public async Task> GetAllDeviceConcentrator( - int pageSize = 10, - int pageNumber = 0, - string[] orderBy = null) + ConcentratorFilter concentratorFilter) { - var paginatedConcentrator = await this.concentratorRepository.GetPaginatedListAsync(pageNumber, pageSize, orderBy); + var concentratorPredicate = PredicateBuilder.True(); + + if (!string.IsNullOrWhiteSpace(concentratorFilter.Keyword)) + { + concentratorPredicate = concentratorPredicate.And(concentrator => concentrator.Id.ToLower().Contains(concentratorFilter.Keyword) || concentrator.Name.ToLower().Contains(concentratorFilter.Keyword)); + } + + if (concentratorFilter.Status != null) + { + concentratorPredicate = concentratorPredicate.And(concentrator => concentrator.IsEnabled == concentratorFilter.Status); + } + + if (concentratorFilter.State != null) + { + concentratorPredicate = concentratorPredicate.And(concentrator => concentrator.IsConnected == concentratorFilter.State); + } + + var paginatedConcentrator = await this.concentratorRepository.GetPaginatedListAsync(concentratorFilter.PageNumber, concentratorFilter.PageSize, concentratorFilter.OrderBy, concentratorPredicate); return this.mapper.Map>(paginatedConcentrator); } diff --git a/src/AzureIoTHub.Portal.Shared/Models/v1.0/Filters/ConcentratorFilter.cs b/src/AzureIoTHub.Portal.Shared/Models/v1.0/Filters/ConcentratorFilter.cs new file mode 100644 index 000000000..f98ff761f --- /dev/null +++ b/src/AzureIoTHub.Portal.Shared/Models/v1.0/Filters/ConcentratorFilter.cs @@ -0,0 +1,15 @@ +// Copyright (c) CGI France. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace AzureIoTHub.Portal.Shared.Models.v10.Filters +{ + + public class ConcentratorFilter : PaginationFilter + { + public string Keyword { get; set; } + + public bool? Status { get; set; } + + public bool? State { get; set; } + } +} diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Components/Concentrators/ConcentratorSearchTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Components/Concentrators/ConcentratorSearchTests.cs new file mode 100644 index 000000000..789cdc96c --- /dev/null +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Components/Concentrators/ConcentratorSearchTests.cs @@ -0,0 +1,87 @@ +// Copyright (c) CGI France. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace AzureIoTHub.Portal.Tests.Unit.Client.Components.Concentrators +{ + using AutoFixture; + using System.Collections.Generic; + using AzureIoTHub.Portal.Tests.Unit.UnitTests.Bases; + using Bunit; + using NUnit.Framework; + using AzureIoTHub.Portal.Client.Components.Concentrators; + using FluentAssertions; + using System.Linq; + using AzureIoTHub.Portal.Client.Models; + + [TestFixture] + public class ConcentratorSearchTests : BlazorUnitTest + { + public override void Setup() + { + base.Setup(); + } + + [Test] + public void SearchConcentrators_ClickOnSearch_SearchIsFired() + { + // Arrange + var searchKeyword = Fixture.Create(); + var receivedEvents = new List(); + var expectedConcentratorSearchInfo = new ConcentratorSearchInfo + { + SearchKeyword = searchKeyword, + SearchState = string.Empty, + SearchStatus = string.Empty + }; + + var cut = RenderComponent(parameters => parameters.Add(p => p.OnSearch, (searchInfo) => + { + receivedEvents.Add(searchInfo); + })); + + cut.WaitForElement("#searchKeyword").Change(searchKeyword); + cut.WaitForElement("#searchStatusAll").Click(); + cut.WaitForElement("#searchStateAll").Click(); + + // Act + cut.WaitForElement("#searchButton").Click(); + + // Assert + cut.WaitForAssertion(() => receivedEvents.Count.Should().Be(1)); + _ = receivedEvents.First().Should().BeEquivalentTo(expectedConcentratorSearchInfo); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + + [Test] + public void SearchConcentrators_ClickOnReset_SearchKeyworkIsSetToEmptyAndSearchIsFired() + { + // Arrange + var searchKeyword = Fixture.Create(); + var receivedEvents = new List(); + var expectedConcentratorSearchInfo = new ConcentratorSearchInfo + { + SearchKeyword = string.Empty, + SearchState = string.Empty, + SearchStatus = string.Empty + }; + + var cut = RenderComponent(parameters => parameters.Add(p => p.OnSearch, (searchInfo) => + { + receivedEvents.Add(searchInfo); + })); + + cut.WaitForElement("#searchKeyword").Input(searchKeyword); + cut.WaitForElement("#searchStatusAll").Click(); + cut.WaitForElement("#searchStateAll").Click(); + + // Act + cut.WaitForElement("#resetSearch").Click(); + + // Assert + cut.WaitForAssertion(() => receivedEvents.Count.Should().Be(1)); + _ = receivedEvents.First().Should().BeEquivalentTo(expectedConcentratorSearchInfo); + _ = cut.Find("#searchKeyword").TextContent.Should().Be(string.Empty); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } + } +} diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/LoRaWan/Concentrator/ConcentratorListPageTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/LoRaWan/Concentrator/ConcentratorListPageTests.cs index 8552a44f7..6334f8395 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/LoRaWan/Concentrator/ConcentratorListPageTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/LoRaWan/Concentrator/ConcentratorListPageTests.cs @@ -19,6 +19,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Client.Pages.LoRaWan.Concentrator using Moq; using MudBlazor; using NUnit.Framework; + using AutoFixture; [TestFixture] public class ConcentratorListPageTests : BlazorUnitTest @@ -46,7 +47,7 @@ public override void Setup() public void ConcentratorListPageShouldLoadAndShowConcentrators() { // Arrange - var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy="; + var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword=&status=&state="; _ = this.mockLoRaWanConcentratorClientService.Setup(service => service.GetConcentrators(It.Is(s => expectedUri.Equals(s, StringComparison.Ordinal)))) @@ -74,7 +75,7 @@ public void ConcentratorListPageShouldLoadAndShowConcentrators() public void ConcentratorListPageShouldProcessProblemDetailsExceptionWhenIssueOccursOnLoadingConcentrators() { // Arrange - var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy="; + var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword=&status=&state="; _ = this.mockLoRaWanConcentratorClientService.Setup(service => service.GetConcentrators(It.Is(s => expectedUri.Equals(s, StringComparison.Ordinal)))) @@ -96,7 +97,7 @@ public void ClickToItemShouldRedirectToConcentratorDetailsPage() { // Arrange var deviceId = Guid.NewGuid().ToString(); - var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy="; + var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword=&status=&state="; _ = this.mockLoRaWanConcentratorClientService.Setup(service => service.GetConcentrators(It.Is(s => expectedUri.Equals(s, StringComparison.Ordinal)))) @@ -126,7 +127,7 @@ public void ClickToItemShouldRedirectToConcentratorDetailsPage() public void ClickOnAddNewDeviceShouldNavigateToNewDevicePage() { // Arrange - const string expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy="; + const string expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword=&status=&state="; _ = this.mockLoRaWanConcentratorClientService.Setup(service => service.GetConcentrators(It.Is(s => expectedUri.Equals(s, StringComparison.Ordinal)))) @@ -155,7 +156,7 @@ public void ClickOnAddNewDeviceShouldNavigateToNewDevicePage() public void ClickOnRefreshShouldReloadConcentrators() { // Arrange - var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy="; + var expectedUri = "api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword=&status=&state="; _ = this.mockLoRaWanConcentratorClientService.Setup(service => service.GetConcentrators(It.Is(s => expectedUri.Equals(s, StringComparison.Ordinal)))) @@ -172,5 +173,57 @@ public void ClickOnRefreshShouldReloadConcentrators() // Assert cut.WaitForAssertion(() => MockRepository.VerifyAll()); } + + [Test] + public void ClickOnSearchShouldSearchConcentrators() + { + // Arrange + var searchKeyword = Fixture.Create(); + var concentratorSearchInfo = new ConcentratorSearchInfo + { + SearchKeyword = searchKeyword, + SearchState = string.Empty, + SearchStatus = string.Empty + }; + var expectedUri = $"api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword=&status=&state="; + + _ = this.mockLoRaWanConcentratorClientService.Setup(service => + service.GetConcentrators(It.Is(s => expectedUri.Equals(s, StringComparison.Ordinal)))) + .ReturnsAsync(new PaginationResult + { + Items = new List() + { + new (), + new (), + new (), + } + }); + + var expectedUriWithFilter = $"api/lorawan/concentrators?pageNumber=0&pageSize=10&orderBy=&keyword={concentratorSearchInfo.SearchKeyword}&status={concentratorSearchInfo.SearchStatus}&state={concentratorSearchInfo.SearchState}"; + + _ = this.mockLoRaWanConcentratorClientService.Setup(service => + service.GetConcentrators(It.Is(s => expectedUriWithFilter.Equals(s, StringComparison.Ordinal)))) + .ReturnsAsync(new PaginationResult + { + Items = new List() + { + new () + } + }); + + var cut = RenderComponent(); + + cut.WaitForAssertion(() => cut.Markup.Should().NotContain("Loading...")); + cut.WaitForAssertion(() => cut.FindAll("table tbody tr").Count.Should().Be(3)); + cut.WaitForElement("#searchKeyword").Change(searchKeyword); + + // Act + cut.WaitForElement("#searchButton").Click(); + + // Assert + cut.WaitForAssertion(() => cut.Markup.Should().NotContain("Loading...")); + cut.WaitForAssertion(() => cut.FindAll("table tbody tr").Count.Should().Be(1)); + cut.WaitForAssertion(() => MockRepository.VerifyAll()); + } } } diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsControllerTest.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsControllerTest.cs index f48b3e267..e2f6d1678 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsControllerTest.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/LoRaWAN/LoRaWANConcentratorsControllerTest.cs @@ -11,6 +11,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Controllers.v1._0.LoRaWAN using AzureIoTHub.Portal.Models.v10.LoRaWAN; using AzureIoTHub.Portal.Server.Controllers.V10.LoRaWAN; using AzureIoTHub.Portal.Shared.Models.v1._0; + using AzureIoTHub.Portal.Shared.Models.v10.Filters; using AzureIoTHub.Portal.Tests.Unit.UnitTests.Bases; using FluentAssertions; using Hellang.Middleware.ProblemDetails; @@ -73,7 +74,7 @@ public async Task GetAllDeviceConcentratorShouldReturnList() }; _ = this.mockLoRaWANConcentratorService.Setup(service => service.GetAllDeviceConcentrator( - It.IsAny(), It.IsAny(), It.IsAny())) + It.IsAny())) .ReturnsAsync(expectedPaginatedConcentrator); var locationUrl = "http://location/concentrators"; @@ -83,7 +84,7 @@ public async Task GetAllDeviceConcentratorShouldReturnList() .Returns(locationUrl); // Act - var result = await concentratorsController.GetAllDeviceConcentrator().ConfigureAwait(false); + var result = await concentratorsController.GetAllDeviceConcentrator(new ConcentratorFilter()).ConfigureAwait(false); // Assert diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/LoRaWANConcentratorServiceTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/LoRaWANConcentratorServiceTests.cs index 0af8f4f56..e28fdd1e1 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/LoRaWANConcentratorServiceTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/LoRaWANConcentratorServiceTests.cs @@ -3,7 +3,9 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Services { + using System; using System.Linq; + using System.Linq.Expressions; using System.Threading.Tasks; using AutoFixture; using AutoMapper; @@ -13,9 +15,11 @@ namespace AzureIoTHub.Portal.Tests.Unit.Server.Services using AzureIoTHub.Portal.Domain.Entities; using AzureIoTHub.Portal.Domain.Exceptions; using AzureIoTHub.Portal.Domain.Repositories; + using AzureIoTHub.Portal.Infrastructure.Repositories; using AzureIoTHub.Portal.Models.v10.LoRaWAN; using AzureIoTHub.Portal.Server.Services; using AzureIoTHub.Portal.Shared.Models.v1._0; + using AzureIoTHub.Portal.Shared.Models.v10.Filters; using AzureIoTHub.Portal.Tests.Unit.UnitTests.Bases; using EntityFramework.Exceptions.Common; using FluentAssertions; @@ -77,7 +81,7 @@ public async Task GetAllDeviceConcentratorDefaultParametersShouldReturnConcentra await DbContext.AddRangeAsync(expectedDevices); _ = await DbContext.SaveChangesAsync(); - _ = this.mockConcentratorRepository.Setup(x => x.GetPaginatedListAsync(It.IsAny(), It.IsAny(), It.IsAny(), null, default)) + _ = this.mockConcentratorRepository.Setup(x => x.GetPaginatedListAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>>(), default)) .ReturnsAsync(new PaginatedResult { Data = expectedDevices.Skip(expectedCurrentPage * expectedPageSize).Take(expectedPageSize).ToList(), @@ -87,7 +91,47 @@ public async Task GetAllDeviceConcentratorDefaultParametersShouldReturnConcentra }); // Act - var result = await this.concentratorService.GetAllDeviceConcentrator(); + var result = await this.concentratorService.GetAllDeviceConcentrator(new ConcentratorFilter()); + + // Assert + Assert.IsAssignableFrom>(result); + _ = result.Data.Count.Should().Be(expectedPageSize); + _ = result.TotalCount.Should().Be(expectedTotalDevicesCount); + _ = result.PageSize.Should().Be(expectedPageSize); + _ = result.CurrentPage.Should().Be(expectedCurrentPage); + MockRepository.VerifyAll(); + } + + [Test] + public async Task GetAllDeviceConcentratorWithPredicateShouldReturnConcentratorsList() + { + // Arrange + var expectedTotalDevicesCount = 50; + var expectedPageSize = 10; + var expectedCurrentPage = 0; + var expectedDevices = Fixture.CreateMany(expectedTotalDevicesCount).ToList(); + + await DbContext.AddRangeAsync(expectedDevices); + _ = await DbContext.SaveChangesAsync(); + + _ = this.mockConcentratorRepository.Setup(x => x.GetPaginatedListAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>>(), default)) + .ReturnsAsync(new PaginatedResult + { + Data = expectedDevices.Skip(expectedCurrentPage * expectedPageSize).Take(expectedPageSize).ToList(), + PageSize = expectedPageSize, + CurrentPage = expectedCurrentPage, + TotalCount = expectedTotalDevicesCount + }); + + var concentratorFilter = new ConcentratorFilter + { + Keyword = "keyword", + Status = true, + State = false + }; + + // Act + var result = await this.concentratorService.GetAllDeviceConcentrator(concentratorFilter); // Assert Assert.IsAssignableFrom>(result); diff --git a/src/AzureIoTHub.Portal.sln b/src/AzureIoTHub.Portal.sln index a7a30f321..c33ced6e4 100644 --- a/src/AzureIoTHub.Portal.sln +++ b/src/AzureIoTHub.Portal.sln @@ -67,7 +67,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Client", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Application", "AzureIoTHub.Portal.Application\AzureIoTHub.Portal.Application.csproj", "{81FA39E5-DBBF-40DB-B888-F50EE0C363B7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AzureIoTHub.Portal.Crosscutting", "AzureIoTHub.Portal.Crosscutting\AzureIoTHub.Portal.Crosscutting.csproj", "{3523EAFD-81F3-4FC3-BC49-65D3ECE94E4D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AzureIoTHub.Portal.Crosscutting", "AzureIoTHub.Portal.Crosscutting\AzureIoTHub.Portal.Crosscutting.csproj", "{3523EAFD-81F3-4FC3-BC49-65D3ECE94E4D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution