From 52fb94677ad1bc827ed37da39c6afaffd5ee0e23 Mon Sep 17 00:00:00 2001 From: alex289 Date: Thu, 31 Aug 2023 19:28:25 +0200 Subject: [PATCH] feat: Add pagination --- .../Controllers/TenantController.cs | 12 ++++-- .../Controllers/UserController.cs | 12 ++++-- .../Queries/Users/GetAllUsersTestFixture.cs | 4 +- .../Tenants/GetAllTenantsQueryHandlerTests.cs | 29 ++++++++++++-- .../Users/GetAllUsersQueryHandlerTests.cs | 31 ++++++++++++--- .../Extensions/ServiceCollectionExtension.cs | 6 +-- .../Interfaces/ITenantService.cs | 3 +- .../Interfaces/IUserService.cs | 3 +- .../Tenants/GetAll/GetAllTenantsQuery.cs | 5 ++- .../GetAll/GetAllTenantsQueryHandler.cs | 27 ++++++++++--- .../Queries/Users/GetAll/GetAllUsersQuery.cs | 5 ++- .../Users/GetAll/GetAllUsersQueryHandler.cs | 31 ++++++++++++--- .../Services/TenantService.cs | 5 ++- .../Services/UserService.cs | 5 ++- .../ViewModels/PageQuery.cs | 20 ++++++++++ .../ViewModels/PagedResult.cs | 39 +++++++++++++++++++ .../Controller/TenantControllerTests.cs | 13 ++++--- .../Controller/UserControllerTests.cs | 6 +-- 18 files changed, 204 insertions(+), 52 deletions(-) create mode 100644 CleanArchitecture.Application/ViewModels/PageQuery.cs create mode 100644 CleanArchitecture.Application/ViewModels/PagedResult.cs diff --git a/CleanArchitecture.Api/Controllers/TenantController.cs b/CleanArchitecture.Api/Controllers/TenantController.cs index 0576122..01853a3 100644 --- a/CleanArchitecture.Api/Controllers/TenantController.cs +++ b/CleanArchitecture.Api/Controllers/TenantController.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using CleanArchitecture.Api.Models; using CleanArchitecture.Application.Interfaces; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; using CleanArchitecture.Domain.Notifications; using MediatR; @@ -28,10 +28,14 @@ public sealed class TenantController : ApiController [HttpGet] [SwaggerOperation("Get a list of all tenants")] - [SwaggerResponse(200, "Request successful", typeof(ResponseMessage>))] - public async Task GetAllTenantsAsync() + [SwaggerResponse(200, "Request successful", typeof(ResponseMessage>))] + public async Task GetAllTenantsAsync( + [FromQuery] PageQuery query, + [FromQuery] string searchTerm = "") { - var tenants = await _tenantService.GetAllTenantsAsync(); + var tenants = await _tenantService.GetAllTenantsAsync( + query, + searchTerm); return Response(tenants); } diff --git a/CleanArchitecture.Api/Controllers/UserController.cs b/CleanArchitecture.Api/Controllers/UserController.cs index 3aac047..34d9ad2 100644 --- a/CleanArchitecture.Api/Controllers/UserController.cs +++ b/CleanArchitecture.Api/Controllers/UserController.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; using CleanArchitecture.Api.Models; using CleanArchitecture.Application.Interfaces; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Users; using CleanArchitecture.Domain.Notifications; using MediatR; @@ -28,10 +28,14 @@ public sealed class UserController : ApiController [HttpGet] [SwaggerOperation("Get a list of all users")] - [SwaggerResponse(200, "Request successful", typeof(ResponseMessage>))] - public async Task GetAllUsersAsync() + [SwaggerResponse(200, "Request successful", typeof(ResponseMessage>))] + public async Task GetAllUsersAsync( + [FromQuery] PageQuery query, + [FromQuery] string searchTerm = "") { - var users = await _userService.GetAllUsersAsync(); + var users = await _userService.GetAllUsersAsync( + query, + searchTerm); return Response(users); } diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs index 61b70d7..9d745f6 100644 --- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs +++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs @@ -21,7 +21,7 @@ public sealed class GetAllUsersTestFixture : QueryHandlerBaseFixture Handler = new GetAllUsersQueryHandler(UserRepository); } - public void SetupUserAsync() + public User SetupUserAsync() { var user = new User( ExistingUserId, @@ -35,6 +35,8 @@ public sealed class GetAllUsersTestFixture : QueryHandlerBaseFixture var query = new[] { user }.BuildMock(); UserRepository.GetAllNoTracking().Returns(query); + + return user; } public void SetupDeletedUserAsync() diff --git a/CleanArchitecture.Application.Tests/Queries/Tenants/GetAllTenantsQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Tenants/GetAllTenantsQueryHandlerTests.cs index 6940687..061cf4b 100644 --- a/CleanArchitecture.Application.Tests/Queries/Tenants/GetAllTenantsQueryHandlerTests.cs +++ b/CleanArchitecture.Application.Tests/Queries/Tenants/GetAllTenantsQueryHandlerTests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using CleanArchitecture.Application.Queries.Tenants.GetAll; using CleanArchitecture.Application.Tests.Fixtures.Queries.Tenants; +using CleanArchitecture.Application.ViewModels; using FluentAssertions; using Xunit; @@ -16,24 +17,44 @@ public sealed class GetAllTenantsQueryHandlerTests { var tenant = _fixture.SetupTenant(); + var query = new PageQuery + { + PageSize = 10, + Page = 1 + }; + var result = await _fixture.QueryHandler.Handle( - new GetAllTenantsQuery(), + new GetAllTenantsQuery(query), default); _fixture.VerifyNoDomainNotification(); - tenant.Should().BeEquivalentTo(result.First()); + result.PageSize.Should().Be(query.PageSize); + result.Page.Should().Be(query.Page); + result.Count.Should().Be(1); + + tenant.Should().BeEquivalentTo(result.Items.First()); } [Fact] public async Task Should_Not_Get_Deleted_Tenant() { _fixture.SetupTenant(true); + + var query = new PageQuery + { + PageSize = 10, + Page = 1 + }; var result = await _fixture.QueryHandler.Handle( - new GetAllTenantsQuery(), + new GetAllTenantsQuery(query), default); + + result.PageSize.Should().Be(query.PageSize); + result.Page.Should().Be(query.Page); + result.Count.Should().Be(0); - result.Should().HaveCount(0); + result.Items.Should().HaveCount(0); } } \ No newline at end of file diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs index 816c374..60ccfc0 100644 --- a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs +++ b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using CleanArchitecture.Application.Queries.Users.GetAll; using CleanArchitecture.Application.Tests.Fixtures.Queries.Users; +using CleanArchitecture.Application.ViewModels; using FluentAssertions; using Xunit; @@ -14,15 +15,25 @@ public sealed class GetAllUsersQueryHandlerTests [Fact] public async Task Should_Get_All_Users() { - _fixture.SetupUserAsync(); + var user = _fixture.SetupUserAsync(); + + var query = new PageQuery + { + PageSize = 1, + Page = 1 + }; var result = await _fixture.Handler.Handle( - new GetAllUsersQuery(), + new GetAllUsersQuery(query, user.Email), default); _fixture.VerifyNoDomainNotification(); + + result.PageSize.Should().Be(query.PageSize); + result.Page.Should().Be(query.Page); + result.Count.Should().Be(1); - var userViewModels = result.ToArray(); + var userViewModels = result.Items.ToArray(); userViewModels.Should().NotBeNull(); userViewModels.Should().ContainSingle(); userViewModels.FirstOrDefault()!.Id.Should().Be(_fixture.ExistingUserId); @@ -32,13 +43,23 @@ public sealed class GetAllUsersQueryHandlerTests public async Task Should_Not_Get_Deleted_Users() { _fixture.SetupDeletedUserAsync(); + + var query = new PageQuery + { + PageSize = 10, + Page = 1 + }; var result = await _fixture.Handler.Handle( - new GetAllUsersQuery(), + new GetAllUsersQuery(query), default); _fixture.VerifyNoDomainNotification(); + + result.PageSize.Should().Be(query.PageSize); + result.Page.Should().Be(query.Page); + result.Count.Should().Be(0); - result.Should().BeEmpty(); + result.Items.Should().BeEmpty(); } } \ No newline at end of file diff --git a/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs b/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs index 9da4c3b..c8e282c 100644 --- a/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs +++ b/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs @@ -1,10 +1,10 @@ -using System.Collections.Generic; using CleanArchitecture.Application.Interfaces; using CleanArchitecture.Application.Queries.Tenants.GetAll; using CleanArchitecture.Application.Queries.Tenants.GetTenantById; using CleanArchitecture.Application.Queries.Users.GetAll; using CleanArchitecture.Application.Queries.Users.GetUserById; using CleanArchitecture.Application.Services; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; using CleanArchitecture.Application.ViewModels.Users; using MediatR; @@ -26,12 +26,12 @@ public static class ServiceCollectionExtension { // User services.AddScoped, GetUserByIdQueryHandler>(); - services.AddScoped>, GetAllUsersQueryHandler>(); + services.AddScoped>, GetAllUsersQueryHandler>(); // Tenant services.AddScoped, GetTenantByIdQueryHandler>(); services - .AddScoped>, GetAllTenantsQueryHandler>(); + .AddScoped>, GetAllTenantsQueryHandler>(); return services; } diff --git a/CleanArchitecture.Application/Interfaces/ITenantService.cs b/CleanArchitecture.Application/Interfaces/ITenantService.cs index fbf4332..fb47918 100644 --- a/CleanArchitecture.Application/Interfaces/ITenantService.cs +++ b/CleanArchitecture.Application/Interfaces/ITenantService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; namespace CleanArchitecture.Application.Interfaces; @@ -11,5 +12,5 @@ public interface ITenantService public Task UpdateTenantAsync(UpdateTenantViewModel tenant); public Task DeleteTenantAsync(Guid tenantId); public Task GetTenantByIdAsync(Guid tenantId, bool deleted); - public Task> GetAllTenantsAsync(); + public Task> GetAllTenantsAsync(PageQuery query, string searchTerm = ""); } \ No newline at end of file diff --git a/CleanArchitecture.Application/Interfaces/IUserService.cs b/CleanArchitecture.Application/Interfaces/IUserService.cs index 1fbca3e..1d2116b 100644 --- a/CleanArchitecture.Application/Interfaces/IUserService.cs +++ b/CleanArchitecture.Application/Interfaces/IUserService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Users; namespace CleanArchitecture.Application.Interfaces; @@ -9,7 +10,7 @@ public interface IUserService { public Task GetUserByUserIdAsync(Guid userId, bool isDeleted); public Task GetCurrentUserAsync(); - public Task> GetAllUsersAsync(); + public Task> GetAllUsersAsync(PageQuery query, string searchTerm = ""); public Task CreateUserAsync(CreateUserViewModel user); public Task UpdateUserAsync(UpdateUserViewModel user); public Task DeleteUserAsync(Guid userId); diff --git a/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQuery.cs b/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQuery.cs index e87ddec..6144730 100644 --- a/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQuery.cs +++ b/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQuery.cs @@ -1,7 +1,8 @@ -using System.Collections.Generic; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; using MediatR; namespace CleanArchitecture.Application.Queries.Tenants.GetAll; -public sealed record GetAllTenantsQuery : IRequest>; \ No newline at end of file +public sealed record GetAllTenantsQuery(PageQuery Query, string SearchTerm = "") : + IRequest>; \ No newline at end of file diff --git a/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs b/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs index 844a5f4..839b4ef 100644 --- a/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs +++ b/CleanArchitecture.Application/Queries/Tenants/GetAll/GetAllTenantsQueryHandler.cs @@ -1,7 +1,7 @@ -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; using CleanArchitecture.Domain.Interfaces.Repositories; using MediatR; @@ -10,7 +10,7 @@ using Microsoft.EntityFrameworkCore; namespace CleanArchitecture.Application.Queries.Tenants.GetAll; public sealed class GetAllTenantsQueryHandler : - IRequestHandler> + IRequestHandler> { private readonly ITenantRepository _tenantRepository; @@ -19,15 +19,30 @@ public sealed class GetAllTenantsQueryHandler : _tenantRepository = tenantRepository; } - public async Task> Handle( + public async Task> Handle( GetAllTenantsQuery request, CancellationToken cancellationToken) { - return await _tenantRepository + var tenantsQuery = _tenantRepository .GetAllNoTracking() .Include(x => x.Users) - .Where(x => !x.Deleted) - .Select(x => TenantViewModel.FromTenant(x)) + .Where(x => !x.Deleted); + + if (!string.IsNullOrWhiteSpace(request.SearchTerm)) + { + tenantsQuery = tenantsQuery.Where(tenant => + tenant.Name.Contains(request.SearchTerm)); + } + + var totalCount = await tenantsQuery.CountAsync(cancellationToken); + + var tenants = await tenantsQuery + .Skip((request.Query.Page - 1) * request.Query.PageSize) + .Take(request.Query.PageSize) + .Select(tenant => TenantViewModel.FromTenant(tenant)) .ToListAsync(cancellationToken); + + return new PagedResult( + totalCount, tenants, request.Query.Page, request.Query.PageSize); } } \ No newline at end of file diff --git a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs index 9e59d7f..5e0361e 100644 --- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs +++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs @@ -1,7 +1,8 @@ -using System.Collections.Generic; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Users; using MediatR; namespace CleanArchitecture.Application.Queries.Users.GetAll; -public sealed record GetAllUsersQuery : IRequest>; \ No newline at end of file +public sealed record GetAllUsersQuery(PageQuery Query, string SearchTerm = "") : + IRequest>; \ No newline at end of file diff --git a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs index c43bad2..dcdd952 100644 --- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs +++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs @@ -1,7 +1,7 @@ -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Users; using CleanArchitecture.Domain.Interfaces.Repositories; using MediatR; @@ -10,7 +10,7 @@ using Microsoft.EntityFrameworkCore; namespace CleanArchitecture.Application.Queries.Users.GetAll; public sealed class GetAllUsersQueryHandler : - IRequestHandler> + IRequestHandler> { private readonly IUserRepository _userRepository; @@ -19,12 +19,31 @@ public sealed class GetAllUsersQueryHandler : _userRepository = userRepository; } - public async Task> Handle(GetAllUsersQuery request, CancellationToken cancellationToken) + public async Task> Handle( + GetAllUsersQuery request, + CancellationToken cancellationToken) { - return await _userRepository + var usersQuery = _userRepository .GetAllNoTracking() - .Where(x => !x.Deleted) - .Select(x => UserViewModel.FromUser(x)) + .Where(x => !x.Deleted); + + if (!string.IsNullOrWhiteSpace(request.SearchTerm)) + { + usersQuery = usersQuery.Where(user => + user.Email.Contains(request.SearchTerm) || + user.FirstName.Contains(request.SearchTerm) || + user.LastName.Contains(request.SearchTerm)); + } + + var totalCount = await usersQuery.CountAsync(cancellationToken); + + var users = await usersQuery + .Skip((request.Query.Page - 1) * request.Query.PageSize) + .Take(request.Query.PageSize) + .Select(user => UserViewModel.FromUser(user)) .ToListAsync(cancellationToken); + + return new PagedResult( + totalCount, users, request.Query.Page, request.Query.PageSize); } } \ No newline at end of file diff --git a/CleanArchitecture.Application/Services/TenantService.cs b/CleanArchitecture.Application/Services/TenantService.cs index c10fe20..0b77343 100644 --- a/CleanArchitecture.Application/Services/TenantService.cs +++ b/CleanArchitecture.Application/Services/TenantService.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using CleanArchitecture.Application.Interfaces; using CleanArchitecture.Application.Queries.Tenants.GetAll; using CleanArchitecture.Application.Queries.Tenants.GetTenantById; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; using CleanArchitecture.Domain.Commands.Tenants.CreateTenant; using CleanArchitecture.Domain.Commands.Tenants.DeleteTenant; @@ -49,8 +50,8 @@ public sealed class TenantService : ITenantService return await _bus.QueryAsync(new GetTenantByIdQuery(tenantId, deleted)); } - public async Task> GetAllTenantsAsync() + public async Task> GetAllTenantsAsync(PageQuery query, string searchTerm = "") { - return await _bus.QueryAsync(new GetAllTenantsQuery()); + return await _bus.QueryAsync(new GetAllTenantsQuery(query, searchTerm)); } } \ No newline at end of file diff --git a/CleanArchitecture.Application/Services/UserService.cs b/CleanArchitecture.Application/Services/UserService.cs index f6181f7..eb90bed 100644 --- a/CleanArchitecture.Application/Services/UserService.cs +++ b/CleanArchitecture.Application/Services/UserService.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using CleanArchitecture.Application.Interfaces; using CleanArchitecture.Application.Queries.Users.GetAll; using CleanArchitecture.Application.Queries.Users.GetUserById; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Users; using CleanArchitecture.Domain.Commands.Users.ChangePassword; using CleanArchitecture.Domain.Commands.Users.CreateUser; @@ -35,9 +36,9 @@ public sealed class UserService : IUserService return await _bus.QueryAsync(new GetUserByIdQuery(_user.GetUserId(), false)); } - public async Task> GetAllUsersAsync() + public async Task> GetAllUsersAsync(PageQuery query, string searchTerm = "") { - return await _bus.QueryAsync(new GetAllUsersQuery()); + return await _bus.QueryAsync(new GetAllUsersQuery(query, searchTerm)); } public async Task CreateUserAsync(CreateUserViewModel user) diff --git a/CleanArchitecture.Application/ViewModels/PageQuery.cs b/CleanArchitecture.Application/ViewModels/PageQuery.cs new file mode 100644 index 0000000..89fd16f --- /dev/null +++ b/CleanArchitecture.Application/ViewModels/PageQuery.cs @@ -0,0 +1,20 @@ +using System; + +namespace CleanArchitecture.Application.ViewModels; + +public sealed class PageQuery +{ + private int _pageSize = 10; + public int PageSize + { + get => _pageSize; + set => _pageSize = Math.Max(0, value); + } + + private int _page = 1; + public int Page + { + get => _page; + set => _page = Math.Max(1, value); + } +} \ No newline at end of file diff --git a/CleanArchitecture.Application/ViewModels/PagedResult.cs b/CleanArchitecture.Application/ViewModels/PagedResult.cs new file mode 100644 index 0000000..09fac7d --- /dev/null +++ b/CleanArchitecture.Application/ViewModels/PagedResult.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace CleanArchitecture.Application.ViewModels; + +public sealed class PagedResult +{ + public int Count { get; init; } + + public IList Items { get; init; } = Array.Empty(); + + public int Page { get; init; } + public int PageSize { get; init; } + + public PagedResult(int count, IList items, int page, int pageSize) + { + Count = count; + Items = items; + Page = page; + PageSize = pageSize; + } + + // used by json deserializer + private PagedResult() + { + + } + + public static PagedResult Empty() + { + return new PagedResult + { + Count = 0, + Items = Array.Empty(), + Page = 1, + PageSize = 10 + }; + } +} \ No newline at end of file diff --git a/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs b/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs index 9e7f49f..d765819 100644 --- a/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs +++ b/CleanArchitecture.IntegrationTests/Controller/TenantControllerTests.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Tenants; using CleanArchitecture.IntegrationTests.Extensions; using CleanArchitecture.IntegrationTests.Fixtures; @@ -43,15 +43,16 @@ public sealed class TenantControllerTests : IClassFixture [Priority(5)] public async Task Should_Get_All_Tenants() { - var response = await _fixture.ServerClient.GetAsync("api/v1/Tenant"); + var response = await _fixture.ServerClient.GetAsync( + "api/v1/Tenant?searchTerm=Test&pageSize=5&page=1"); response.StatusCode.Should().Be(HttpStatusCode.OK); - var message = await response.Content.ReadAsJsonAsync>(); + var message = await response.Content.ReadAsJsonAsync>(); - message?.Data.Should().NotBeEmpty(); - message!.Data.Should().HaveCountGreaterOrEqualTo(2); - message.Data! + message?.Data!.Items.Should().NotBeEmpty(); + message!.Data!.Items.Should().HaveCount(1); + message.Data!.Items .FirstOrDefault(x => x.Id == _fixture.CreatedTenantId) .Should().NotBeNull(); } diff --git a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs index 45dd1f4..5d4b3d7 100644 --- a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs +++ b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; +using CleanArchitecture.Application.ViewModels; using CleanArchitecture.Application.ViewModels.Users; using CleanArchitecture.Domain.Constants; using CleanArchitecture.Domain.Enums; @@ -34,11 +34,11 @@ public sealed class UserControllerTests : IClassFixture response.StatusCode.Should().Be(HttpStatusCode.OK); - var message = await response.Content.ReadAsJsonAsync>(); + var message = await response.Content.ReadAsJsonAsync>(); message?.Data.Should().NotBeNull(); - var content = message!.Data!.ToList(); + var content = message!.Data!.Items.ToList(); content.Count.Should().Be(2);