diff --git a/CleanArchitecture.Api/Controllers/UserController.cs b/CleanArchitecture.Api/Controllers/UserController.cs index 3f28f6a..a31a158 100644 --- a/CleanArchitecture.Api/Controllers/UserController.cs +++ b/CleanArchitecture.Api/Controllers/UserController.cs @@ -38,8 +38,8 @@ public class UserController : ApiController [HttpPost] public async Task CreateUserAsync([FromBody] CreateUserViewModel viewModel) { - await _userService.CreateUserAsync(viewModel); - return Response(); + var userId = await _userService.CreateUserAsync(viewModel); + return Response(userId); } [HttpDelete("{id}")] diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs index 0d0d27f..ef02fbf 100644 --- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs +++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs @@ -16,12 +16,10 @@ public sealed class GetAllUsersTestFixture : QueryHandlerBaseFixture { UserRepository = new(); - SetupUserRepositoryGetAllAsync(); - Handler = new(UserRepository.Object); } - private void SetupUserRepositoryGetAllAsync() + public void SetupUserAsync() { var user = new Mock(() => new User( diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs index 45bc4dd..0671991 100644 --- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs +++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs @@ -16,12 +16,10 @@ public sealed class GetUserByIdTestFixture : QueryHandlerBaseFixture { UserRepository = new(); - SetupUserRepositoryGetAllAsync(); - Handler = new(UserRepository.Object, Bus.Object); } - private void SetupUserRepositoryGetAllAsync() + public void SetupUserAsync() { var user = new Mock(() => new User( diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs index 18e44eb..a625aa0 100644 --- a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs +++ b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs @@ -11,6 +11,8 @@ public sealed class GetAllUsersQueryHandlerTests [Fact] public async Task Should_Get_All_Users() { + _fixture.SetupUserAsync(); + var result = await _fixture.Handler.Handle( new(), default); @@ -21,4 +23,6 @@ public sealed class GetAllUsersQueryHandlerTests result.Should().ContainSingle(); result.FirstOrDefault()!.Id.Should().Be(_fixture.ExistingUserId); } + + // Add Test for deleted user } \ No newline at end of file diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs index c26ab85..f24ece9 100644 --- a/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs +++ b/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs @@ -13,6 +13,8 @@ public sealed class GetUserByIdQueryHandlerTests [Fact] public async Task Should_Get_Existing_User() { + _fixture.SetupUserAsync(); + var result = await _fixture.Handler.Handle( new(_fixture.ExistingUserId), default); @@ -26,6 +28,8 @@ public sealed class GetUserByIdQueryHandlerTests [Fact] public async Task Should_Raise_Notification_For_No_User() { + _fixture.SetupUserAsync(); + var request = new GetUserByIdQuery(Guid.NewGuid()); var result = await _fixture.Handler.Handle( request, @@ -38,4 +42,6 @@ public sealed class GetUserByIdQueryHandlerTests result.Should().BeNull(); } + + // Add Test for deleted user } \ No newline at end of file diff --git a/CleanArchitecture.Application/Interfaces/IUserService.cs b/CleanArchitecture.Application/Interfaces/IUserService.cs index ea7ad9c..650a50f 100644 --- a/CleanArchitecture.Application/Interfaces/IUserService.cs +++ b/CleanArchitecture.Application/Interfaces/IUserService.cs @@ -9,7 +9,7 @@ public interface IUserService { public Task GetUserByUserIdAsync(Guid userId); public Task> GetAllUsersAsync(); - public Task CreateUserAsync(CreateUserViewModel user); + public Task CreateUserAsync(CreateUserViewModel user); public Task UpdateUserAsync(UpdateUserViewModel user); public Task DeleteUserAsync(Guid userId); } \ 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 3ae90cd..bcb4aad 100644 --- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs +++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQueryHandler.cs @@ -24,6 +24,7 @@ public sealed class GetAllUsersQueryHandler : { return await _userRepository .GetAllNoTracking() + .Where(x => !x.Deleted) .Select(x => UserViewModel.FromUser(x)) .ToListAsync(cancellationToken); } diff --git a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs index af9a258..1109d00 100644 --- a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs +++ b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs @@ -27,7 +27,7 @@ public sealed class GetUserByIdQueryHandler : { var user = _userRepository .GetAllNoTracking() - .FirstOrDefault(x => x.Id == request.UserId); + .FirstOrDefault(x => x.Id == request.UserId && !x.Deleted); if (user == null) { diff --git a/CleanArchitecture.Application/Services/UserService.cs b/CleanArchitecture.Application/Services/UserService.cs index a6e1a04..bd99d42 100644 --- a/CleanArchitecture.Application/Services/UserService.cs +++ b/CleanArchitecture.Application/Services/UserService.cs @@ -31,13 +31,17 @@ public sealed class UserService : IUserService return await _bus.QueryAsync(new GetAllUsersQuery()); } - public async Task CreateUserAsync(CreateUserViewModel user) + public async Task CreateUserAsync(CreateUserViewModel user) { + var userId = Guid.NewGuid(); + await _bus.SendCommandAsync(new CreateUserCommand( - Guid.NewGuid(), + userId, user.Email, user.Surname, user.GivenName)); + + return userId; } public async Task UpdateUserAsync(UpdateUserViewModel user) diff --git a/CleanArchitecture.Domain/Entities/User.cs b/CleanArchitecture.Domain/Entities/User.cs index 731a8f9..e2c56e9 100644 --- a/CleanArchitecture.Domain/Entities/User.cs +++ b/CleanArchitecture.Domain/Entities/User.cs @@ -14,8 +14,8 @@ public class User : Entity public User( Guid id, string email, - string givenName, - string surname) : base(id) + string surname, + string givenName) : base(id) { Email = email; GivenName = givenName; diff --git a/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs b/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs new file mode 100644 index 0000000..a03f826 --- /dev/null +++ b/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs @@ -0,0 +1,63 @@ +using CleanArchitecture.Domain.Notifications; +using FluentAssertions; +using Xunit; + +namespace CleanArchitecture.Infrastructure.Tests; + +public sealed class DomainNotificationHandlerTests +{ + [Fact] + public void Should_Create_DomainNotificationHandler_Instance() + { + var domainNotificationHandler = new DomainNotificationHandler(); + domainNotificationHandler.GetNotifications().Should().BeEmpty(); + } + + [Fact] + public void Should_Handle_DomainNotification() + { + string key = "Key"; + string value = "Value"; + string code = "Code"; + + var domainNotification = new DomainNotification(key, value, code); + var domainNotificationHandler = new DomainNotificationHandler(); + domainNotificationHandler.Handle(domainNotification); + domainNotificationHandler.GetNotifications().Should().HaveCount(1); + } + + [Fact] + public void Should_Handle_DomainNotification_Overload() + { + string key = "Key"; + string value = "Value"; + string code = "Code"; + + var domainNotification = new DomainNotification(key, value, code); + var domainNotificationHandler = new DomainNotificationHandler(); + domainNotificationHandler.Handle(domainNotification, default); + domainNotificationHandler.GetNotifications().Should().HaveCount(1); + } + + [Fact] + public void DomainNotification_HasNotifications_After_Handling_One() + { + string key = "Key"; + string value = "Value"; + string code = "Code"; + + var domainNotification = new DomainNotification(key, value, code); + var domainNotificationHandler = new DomainNotificationHandler(); + domainNotificationHandler.Handle(domainNotification); + + domainNotificationHandler.HasNotifications().Should().BeTrue(); + } + + [Fact] + public void DomainNotification_HasNotifications_False_Not_Handling_One() + { + var domainNotificationHandler = new DomainNotificationHandler(); + + domainNotificationHandler.HasNotifications().Should().BeFalse(); + } +} diff --git a/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs b/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs new file mode 100644 index 0000000..913dd4d --- /dev/null +++ b/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs @@ -0,0 +1,40 @@ +using CleanArchitecture.Domain.Notifications; +using FluentAssertions; +using Xunit; + +namespace CleanArchitecture.Infrastructure.Tests; + +public sealed class DomainNotificationTests +{ + [Fact] + public void Should_Create_DomainNotification_Instance() + { + string key = "Key"; + string value = "Value"; + string code = "Code"; + + var domainNotification = new DomainNotification( + key, value, code); + + domainNotification.Key.Should().Be(key); + domainNotification.Value.Should().Be(value); + domainNotification.Should().NotBe(default(Guid)); + domainNotification.Code.Should().Be(code); + } + + [Fact] + public void Should_Create_DomainNotification_Overload_Instance() + { + string key = "Key"; + string value = "Value"; + string code = "Code"; + + var domainNotification = new DomainNotification( + key, value, code); + + domainNotification.Key.Should().Be(key); + domainNotification.Value.Should().Be(value); + domainNotification.Code.Should().Be(code); + domainNotification.Should().NotBe(default(Guid)); + } +} diff --git a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj index e3e890e..255c2cf 100644 --- a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj +++ b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj @@ -9,16 +9,31 @@ - - + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all + + + + + + + + + diff --git a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs new file mode 100644 index 0000000..de56e73 --- /dev/null +++ b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs @@ -0,0 +1,164 @@ +using System.Net; +using CleanArchitecture.Application.ViewModels.Users; +using CleanArchitecture.IntegrationTests.Extensions; +using CleanArchitecture.IntegrationTests.Fixtures; +using FluentAssertions; +using Xunit; +using Xunit.Priority; + +namespace CleanArchitecture.IntegrationTests.Controller; + +[Collection("Integrationtests")] +[TestCaseOrderer(PriorityOrderer.Name, PriorityOrderer.Assembly)] +public sealed class UserControllerTests : IClassFixture +{ + private readonly UserTestFixture _fixture; + + public UserControllerTests(UserTestFixture fixture) + { + _fixture = fixture; + } + + [Fact, Priority(0)] + public async Task Should_Get_No_User() + { + var response = await _fixture.ServerClient.GetAsync("user"); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync>(); + + message?.Data.Should().NotBeNull(); + + var content = message!.Data!; + + content.Should().BeNullOrEmpty(); + } + + [Fact, Priority(5)] + public async Task Should_Create_User() + { + var user = new CreateUserViewModel("test@email.com", "Test", "Email"); + + var response = await _fixture.ServerClient.PostAsJsonAsync("user", user); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync(); + + message?.Data.Should().NotBeEmpty(); + + _fixture.CreatedUserId = message!.Data; + } + + [Fact, Priority(10)] + public async Task Should_Get_Created_Users() + { + var response = await _fixture.ServerClient.GetAsync("user/" + _fixture.CreatedUserId); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync(); + + message?.Data.Should().NotBeNull(); + + var content = message!.Data!; + + content.Id.Should().Be(_fixture.CreatedUserId); + content.Email.Should().Be("test@email.com"); + content.Surname.Should().Be("Test"); + content.GivenName.Should().Be("Email"); + } + + [Fact, Priority(15)] + public async Task Should_Update_User() + { + var user = new UpdateUserViewModel( + _fixture.CreatedUserId, + "newtest@email.com", + "NewTest", + "NewEmail"); + + var response = await _fixture.ServerClient.PutAsJsonAsync("user", user); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync(); + + message?.Data.Should().NotBeNull(); + + var content = message!.Data; + + content.Should().BeEquivalentTo(user); + } + + [Fact, Priority(20)] + public async Task Should_Get_Updated_Users() + { + var response = await _fixture.ServerClient.GetAsync("user/" + _fixture.CreatedUserId); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync(); + + message?.Data.Should().NotBeNull(); + + var content = message!.Data!; + + content.Id.Should().Be(_fixture.CreatedUserId); + content.Email.Should().Be("newtest@email.com"); + content.Surname.Should().Be("NewTest"); + content.GivenName.Should().Be("NewEmail"); + } + + [Fact, Priority(25)] + public async Task Should_Get_One_User() + { + var response = await _fixture.ServerClient.GetAsync("user"); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync>(); + + message?.Data.Should().NotBeNull(); + + var content = message!.Data!; + + content.Should().ContainSingle(); + content.First().Id.Should().Be(_fixture.CreatedUserId); + content.First().Email.Should().Be("newtest@email.com"); + content.First().Surname.Should().Be("NewTest"); + content.First().GivenName.Should().Be("NewEmail"); + } + + [Fact, Priority(30)] + public async Task Should_Delete_User() + { + var response = await _fixture.ServerClient.DeleteAsync("user/" + _fixture.CreatedUserId); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync(); + + message?.Data.Should().NotBeEmpty(); + + var content = message!.Data!; + content.Should().Be(_fixture.CreatedUserId); + } + + [Fact, Priority(35)] + public async Task Should_Get_No_User_Again() + { + var response = await _fixture.ServerClient.GetAsync("user"); + + response.StatusCode.Should().Be(HttpStatusCode.OK); + + var message = await response.Content.ReadAsJsonAsync>(); + + message?.Data.Should().NotBeNull(); + + var content = message!.Data!; + + content.Should().BeNullOrEmpty(); + } +} diff --git a/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs b/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs new file mode 100644 index 0000000..7179db1 --- /dev/null +++ b/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs @@ -0,0 +1,42 @@ +using System.Data.Common; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.EntityFrameworkCore.Diagnostics; + +namespace CleanArchitecture.IntegrationTests.Extensions; + +public static class FunctionalTestsServiceCollectionExtensions +{ + public static IServiceCollection SetupTestDatabase(this IServiceCollection services, DbConnection connection) where TContext : DbContext + { + var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions)); + if (descriptor != null) + services.Remove(descriptor); + + services.AddScoped(p => + DbContextOptionsFactory( + p, + (sp, options) => options + .ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning)) + .UseLazyLoadingProxies() + .UseSqlite(connection))); + + return services; + } + + private static DbContextOptions DbContextOptionsFactory( + IServiceProvider applicationServiceProvider, + Action optionsAction) + where TContext : DbContext + { + var builder = new DbContextOptionsBuilder( + new DbContextOptions(new Dictionary())); + + builder.UseApplicationServiceProvider(applicationServiceProvider); + + optionsAction?.Invoke(applicationServiceProvider, builder); + + return builder.Options; + } +} diff --git a/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs b/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs new file mode 100644 index 0000000..45ace89 --- /dev/null +++ b/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs @@ -0,0 +1,56 @@ +using System.Text; +using System.Text.Json; +using CleanArchitecture.Api.Models; + +namespace CleanArchitecture.IntegrationTests.Extensions; + +public static class HttpExensions +{ + public static JsonSerializerOptions JsonSerializerOptions = new() + { + PropertyNameCaseInsensitive = true, + }; + + private static T? Deserialize(string json) + { + if (string.IsNullOrWhiteSpace(json)) + { + return default; + } + + return JsonSerializer.Deserialize(json, JsonSerializerOptions); + } + + private static string Serialize(T data) + { + return JsonSerializer.Serialize(data, JsonSerializerOptions); + } + + public static async Task?> ReadAsJsonAsync(this HttpContent httpContent) + { + var stringContent = await httpContent.ReadAsStringAsync(); + + return Deserialize>(stringContent); + } + + public static Task PatchAsJsonAsync(this HttpClient httpClient, string url, T data) + { + var content = new StringContent(Serialize(data), Encoding.UTF8, "application/json"); + + return httpClient.PatchAsync(url, content); + } + + public static Task PostAsJsonAsync(this HttpClient httpClient, string url, T data) + { + var content = new StringContent(Serialize(data), Encoding.UTF8, "application/json"); + + return httpClient.PostAsync(url, content); + } + + public static Task PutAsJsonAsync(this HttpClient httpClient, string url, T data) + { + var content = new StringContent(Serialize(data), Encoding.UTF8, "application/json"); + + return httpClient.PutAsync(url, content); + } +} diff --git a/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs b/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs new file mode 100644 index 0000000..afaa3d1 --- /dev/null +++ b/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs @@ -0,0 +1,35 @@ +using CleanArchitecture.Infrastructure.Database; +using CleanArchitecture.IntegrationTests.Infrastructure; +using Microsoft.Extensions.DependencyInjection; + +namespace CleanArchitecture.IntegrationTests.Fixtures; + +public class TestFixtureBase +{ + public HttpClient ServerClient { get; } + + public TestFixtureBase() + { + var projectDir = Directory.GetCurrentDirectory(); + var configPath = Path.Combine(projectDir, "appsettings.Integration.json"); + + var factory = new CleanArchitectureWebApplicationFactory( + SeedTestData, + RegisterCustomServicesHandler, + configPath); + + ServerClient = factory.CreateClient(); + ServerClient.Timeout = TimeSpan.FromMinutes(5); + } + + protected virtual void SeedTestData(ApplicationDbContext context) + { + } + + protected virtual void RegisterCustomServicesHandler( + IServiceCollection services, + ServiceProvider serviceProvider, + IServiceProvider scopedServices) + { + } +} diff --git a/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs b/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs new file mode 100644 index 0000000..24bd329 --- /dev/null +++ b/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs @@ -0,0 +1,6 @@ +namespace CleanArchitecture.IntegrationTests.Fixtures; + +public sealed class UserTestFixture : TestFixtureBase +{ + public Guid CreatedUserId { get; set; } +} diff --git a/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs b/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs new file mode 100644 index 0000000..3a1dd7c --- /dev/null +++ b/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs @@ -0,0 +1,64 @@ +using CleanArchitecture.Infrastructure.Database; +using CleanArchitecture.Infrastructure.Extensions; +using CleanArchitecture.IntegrationTests.Extensions; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Data.Sqlite; +using Microsoft.Extensions.DependencyInjection; + +namespace CleanArchitecture.IntegrationTests.Infrastructure; + +public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFactory +{ + public delegate void AddCustomSeedDataHandler(ApplicationDbContext context); + + public delegate void RegisterCustomServicesHandler( + IServiceCollection services, + ServiceProvider serviceProvider, + IServiceProvider scopedServices); + + private readonly SqliteConnection _connection = new($"DataSource=:memory:"); + + private readonly AddCustomSeedDataHandler? _addCustomSeedDataHandler; + private readonly RegisterCustomServicesHandler? _registerCustomServicesHandler; + private readonly string? _environment; + + public CleanArchitectureWebApplicationFactory( + AddCustomSeedDataHandler? addCustomSeedDataHandler, + RegisterCustomServicesHandler? registerCustomServicesHandler, + string? environment = null) + { + _addCustomSeedDataHandler = addCustomSeedDataHandler; + _registerCustomServicesHandler = registerCustomServicesHandler; + _environment = environment; + } + + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + if (!string.IsNullOrWhiteSpace(_environment)) + { + builder.UseEnvironment(_environment); + } + + base.ConfigureWebHost(builder); + + _connection.Open(); + + builder.ConfigureServices(services => + { + services.SetupTestDatabase(_connection); + + var sp = services.BuildServiceProvider(); + + using IServiceScope scope = sp.CreateScope(); + var scopedServices = scope.ServiceProvider; + + var applicationDbContext = scopedServices.GetRequiredService(); + + applicationDbContext.EnsureMigrationsApplied(); + + _addCustomSeedDataHandler?.Invoke(applicationDbContext); + _registerCustomServicesHandler?.Invoke(services, sp, scopedServices); + }); + } +} diff --git a/CleanArchitecture.IntegrationTests/UnitTest1.cs b/CleanArchitecture.IntegrationTests/UnitTest1.cs deleted file mode 100644 index e159791..0000000 --- a/CleanArchitecture.IntegrationTests/UnitTest1.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace CleanArchitecture.IntegrationTests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - } -} \ No newline at end of file diff --git a/CleanArchitecture.IntegrationTests/Usings.cs b/CleanArchitecture.IntegrationTests/Usings.cs deleted file mode 100644 index 8c927eb..0000000 --- a/CleanArchitecture.IntegrationTests/Usings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; \ No newline at end of file