diff --git a/Api.Integration.Tests/Api.Integration.Tests.csproj b/Api.Integration.Tests/Api.Integration.Tests.csproj index 18fc11d0..e210b8bf 100644 --- a/Api.Integration.Tests/Api.Integration.Tests.csproj +++ b/Api.Integration.Tests/Api.Integration.Tests.csproj @@ -26,6 +26,7 @@ + diff --git a/Api.Integration.Tests/ClientFactory.cs b/Api.Integration.Tests/ClientFactory.cs index 6e101dad..404aa257 100644 --- a/Api.Integration.Tests/ClientFactory.cs +++ b/Api.Integration.Tests/ClientFactory.cs @@ -1,20 +1,17 @@ using System; using System.Linq; -using Microsoft.AspNetCore.Mvc.Testing; using System.Net.Http; using System.Net.Http.Headers; -using Api.Integration.Tests; using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.DependencyInjection; -using NUnit.Framework; using NRZMyk.Server; using NRZMyk.Services.Data; -using NRZMyk.Services.Data.Entities; -namespace PublicApiIntegrationTests +namespace Api.Integration.Tests { public static class ClientFactory { diff --git a/Api.Integration.Tests/Organizations/ListTest.cs b/Api.Integration.Tests/Organizations/ListTest.cs index a05cc4ce..679b359f 100644 --- a/Api.Integration.Tests/Organizations/ListTest.cs +++ b/Api.Integration.Tests/Organizations/ListTest.cs @@ -7,7 +7,6 @@ using NRZMyk.Services.Data.Entities; using NRZMyk.Services.Interfaces; using NUnit.Framework; -using PublicApiIntegrationTests; using Organization = NRZMyk.Services.Data.Entities.Organization; namespace Api.Integration.Tests.Organizations @@ -17,7 +16,7 @@ public class ListTest [OneTimeSetUp] protected void SeedData() { - using (var scope = ClientFactory.ServiceProvider.CreateScope()) + using (var scope = TestcontainerDbClientFactory.ServiceProvider.CreateScope()) { var db = scope.ServiceProvider.GetService(); db.Organizations.Add(new Organization @@ -29,7 +28,7 @@ protected void SeedData() [Test] public async Task WhenCreatingValidSentinelEntry_RespondsWithCreate() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var organizations = await client.GetFromJsonAsync>("api/organizations").ConfigureAwait(true); diff --git a/Api.Integration.Tests/SentinelEntries/CreateTests.cs b/Api.Integration.Tests/SentinelEntries/CreateTests.cs index 7025f00c..71d9f478 100644 --- a/Api.Integration.Tests/SentinelEntries/CreateTests.cs +++ b/Api.Integration.Tests/SentinelEntries/CreateTests.cs @@ -8,7 +8,6 @@ using NRZMyk.Services.Data.Entities; using NRZMyk.Services.Services; using NUnit.Framework; -using PublicApiIntegrationTests; using Tynamix.ObjectFiller; namespace Api.Integration.Tests.SentinelEntries @@ -18,7 +17,7 @@ public class CreateTests [Test] public async Task WhenCreatingValidSentinelEntry_RespondsWithCreate() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var request = CreateValidRequest(); var createdEntry = await CreateValidEntry(client, request).ConfigureAwait(true); @@ -30,7 +29,7 @@ public async Task WhenCreatingValidSentinelEntry_RespondsWithCreate() [Test] public async Task WhenCreatingWithValidPredecessorEntry_RespondsWithCreate() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var predecessor = CreateValidRequest(); var predecessorEntry = await CreateValidEntry(client, predecessor).ConfigureAwait(true); @@ -47,7 +46,7 @@ public async Task WhenCreatingWithValidPredecessorEntry_RespondsWithCreate() [Test] public async Task WhenCreatingPredecessorCircle_RespondsWithCreate() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var predecessorRequest = CreateValidRequest(); // Arrange: Create entry with follow-up @@ -74,7 +73,7 @@ public async Task WhenCreatingPredecessorCircle_RespondsWithCreate() [Test] public async Task WhenCreatingUnknownPredecessorEntry_RespondsWithBadRequest() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var request = CreateValidRequest(); request.PredecessorLaboratoryNumber = "SN-4242-0042"; @@ -89,7 +88,7 @@ public async Task WhenCreatingUnknownPredecessorEntry_RespondsWithBadRequest() [Test] public async Task WhenCreatingWithMissingSamplingDate_RespondsWithBadRequest() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var request = CreateValidRequest(); request.SamplingDate = null; @@ -103,7 +102,7 @@ public async Task WhenCreatingWithMissingSamplingDate_RespondsWithBadRequest() [Test] public async Task WhenCreatingWithInvalidDepartmentCombination_RespondsWithBadRequest() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var request = CreateValidRequest(); request.InternalHospitalDepartmentType = InternalHospitalDepartmentType.Angiological; @@ -117,7 +116,7 @@ public async Task WhenCreatingWithInvalidDepartmentCombination_RespondsWithBadRe [Test] public async Task WhenCreatingWithFutureSamplingDate_RespondsWithBadRequest() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var request = CreateValidRequest(); request.SamplingDate = DateTime.Now.AddDays(1); @@ -151,6 +150,8 @@ private static SentinelEntryRequest CreateValidRequest() request.SamplingDate = DateTime.Now.AddDays(-3); request.PredecessorLaboratoryNumber = string.Empty; request.HasPredecessor = YesNo.No; + request.AntimicrobialSensitivityTests = null; + request.Id = 0; return request; } } diff --git a/Api.Integration.Tests/Swagger/SwaggerTest.cs b/Api.Integration.Tests/Swagger/SwaggerTest.cs index 0563498f..b5ecce4f 100644 --- a/Api.Integration.Tests/Swagger/SwaggerTest.cs +++ b/Api.Integration.Tests/Swagger/SwaggerTest.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using FluentAssertions; using NUnit.Framework; -using PublicApiIntegrationTests; namespace Api.Integration.Tests.Swagger { @@ -11,7 +10,7 @@ public class SwaggerTests [Test] public async Task WhenAccessingIndex_ReturnsPage() { - var client = ClientFactory.CreateClient(); + var client = TestcontainerDbClientFactory.CreateClient(); var response = await client.GetAsync("swagger/index.html").ConfigureAwait(true); diff --git a/Api.Integration.Tests/TestcontainerDbClientFactory.cs b/Api.Integration.Tests/TestcontainerDbClientFactory.cs new file mode 100644 index 00000000..5248f345 --- /dev/null +++ b/Api.Integration.Tests/TestcontainerDbClientFactory.cs @@ -0,0 +1,97 @@ +using System; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using FluentAssertions.Common; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NRZMyk.Server; +using NRZMyk.Services.Configuration; +using NRZMyk.Services.Data; +using Testcontainers.MsSql; + +namespace Api.Integration.Tests +{ + public static class TestcontainerDbClientFactory + { + private static readonly WebApplicationFactory _factory; + public static IServiceProvider ServiceProvider => _factory.Services; + + private static readonly MsSqlContainer _dbContainer = new MsSqlBuilder() + .WithImage("mcr.microsoft.com/mssql/server:2022-latest") + .WithPassword("Strong_password_123!") + .Build(); + + static TestcontainerDbClientFactory() + { + _dbContainer.StartAsync().Wait(); + + _factory = new WebApplicationFactory().WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => + { + services.AddAuthentication(TestAuthHandler.AuthenticationScheme) + .AddScheme( + TestAuthHandler.AuthenticationScheme, _ => { }); + + var descriptor = services.SingleOrDefault( + d => d.ServiceType == + typeof(DbContextOptions)); + if (descriptor != null) + { + services.Remove(descriptor); + } + + services.AddDbContext(options => + { + options.UseSqlServer(_dbContainer.GetConnectionString()); + }); + }); + }); + + using (var scope = _factory.Services.CreateScope()) + { + var services = scope.ServiceProvider; + var loggerFactory = services.GetRequiredService(); + var configuration = services.GetRequiredService(); + var seedSettings = configuration.Get(); + + try + { + var catalogContext = services.GetRequiredService(); + ApplicationDbContextSeed.SeedAsync(catalogContext, loggerFactory, seedSettings.DatabaseSeed).Wait(); + } + catch (Exception ex) + { + var logger = loggerFactory.CreateLogger(); + logger.LogError(ex, "An error occurred seeding the DB."); + } + } + + AppDomain.CurrentDomain.ProcessExit += Dispose; + } + + private static void Dispose(object? sender, EventArgs e) { + var disposeContainerTask = _dbContainer.DisposeAsync().AsTask(); + disposeContainerTask.Wait(); + _factory.Dispose(); + } + + public static HttpClient CreateClient() + { + var client = _factory.CreateClient(new WebApplicationFactoryClientOptions + { + AllowAutoRedirect = false, + }); + + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(TestAuthHandler.AuthenticationScheme); + return client; + } + } +} diff --git a/NRZMyk.Services.Tests/Services/ReminderServiceTests.cs b/NRZMyk.Services.Tests/Services/ReminderServiceTests.cs index 3d805f71..3702f316 100644 --- a/NRZMyk.Services.Tests/Services/ReminderServiceTests.cs +++ b/NRZMyk.Services.Tests/Services/ReminderServiceTests.cs @@ -34,7 +34,6 @@ public void WhenExpectedNextSendingIsThisMonth_HumanReadableExpectedNextSendingS [TestCase(8, 6, "vor 6 Monaten")] [TestCase(19, 6, "vor einem Jahr")] [TestCase(43, 6, "vor 3 Jahren")] - [TestCase(10, 2, "in einem Monat")] public void WhenExpectedNextSendingIsChecked_HumanReadableExpectedNextSendingShowsValidInformation(int monthSinceLatestStrainArrival, int monthUntilNextArrival, string expectedNextSending) { var sut = CreateSut();