From e2d1bc6a6601c6e2c360ddc9f1dd5d1c41dacbba Mon Sep 17 00:00:00 2001 From: Nick Warms Date: Fri, 26 Apr 2024 14:40:53 +0100 Subject: [PATCH] Switch api tests to running the web application properly using the web application factory --- .../Api/IdentifiersEndpointTests.cs | 103 ++++++------------ Dfe.Identifiers.Api.Test/ApiTestFixture.cs | 75 +++++++++---- 2 files changed, 86 insertions(+), 92 deletions(-) diff --git a/Dfe.Identifiers.Api.Test/Api/IdentifiersEndpointTests.cs b/Dfe.Identifiers.Api.Test/Api/IdentifiersEndpointTests.cs index 9f87945..c99d178 100644 --- a/Dfe.Identifiers.Api.Test/Api/IdentifiersEndpointTests.cs +++ b/Dfe.Identifiers.Api.Test/Api/IdentifiersEndpointTests.cs @@ -1,4 +1,5 @@ using System.Net; +using System.Net.Http.Json; using Dfe.Identifiers.Api.Controllers; using Dfe.Identifiers.Api.Test.Constants; using Dfe.Identifiers.Api.Test.Extensions; @@ -18,16 +19,14 @@ namespace Dfe.Identifiers.Api.Test.Api; public class IdentifiersEndpointTests : IClassFixture { private ApiTestFixture Fixture { get; } - private IdentifiersController Sut { get; } + + private readonly HttpClient _client; + private const string ApiUrlPrefix = "/api/identifier"; public IdentifiersEndpointTests(ApiTestFixture fixture) { Fixture = fixture; - var logger = new Mock>(); - var mstrContext = fixture.GetMstrContext(); - var academistationContext = fixture.GetAcademisationContext(); - Sut = new IdentifiersController(logger.Object, new IdentifiersQuery(new TrustRepository(mstrContext), - new EstablishmentRepository(mstrContext), new ProjectsRepository(academistationContext))); + _client = fixture.Client; } // TRUSTS @@ -52,14 +51,10 @@ public async Task Get_TrustIdentifiers_AndTrustExists_Returns_Ok(TrustIdTypes tr _ => throw new ArgumentOutOfRangeException(nameof(trustIdType), trustIdType, null) }; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier!, cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var trusts = content!.Trusts; trusts.Length.Should().Be(1); @@ -84,14 +79,10 @@ public async Task Get_TrustIdentifiers_AndDuplicateTrustsExists_Returns_Ok(Trust _ => throw new ArgumentOutOfRangeException(nameof(trustIdType), trustIdType, null) }; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier, cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var trusts = content!.Trusts; trusts.Length.Should().Be(3); @@ -117,15 +108,11 @@ public async Task Get_TrustIdentifiers_AndNoOtherIdentifiersExist_Returns_Ok(Tru TrustIdTypes.GroupUID => selectedTrust.GroupUID, _ => throw new ArgumentOutOfRangeException(nameof(trustIdType), trustIdType, null) }; + + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier!, cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); - - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var trusts = content!.Trusts; trusts.Length.Should().Be(1); @@ -139,14 +126,10 @@ public async Task Get_TrustIdentifiers_AndTrustDoesNotExist_Returns_EmptyList() await DatabaseModelBuilder.BuildTrustSet(context); - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers("NoTrustExists", cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); + var response = await _client.GetAsync($"{ApiUrlPrefix}/noIdentifier"); - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var trusts = content!.Trusts; trusts.Length.Should().Be(0); @@ -174,14 +157,10 @@ public async Task Get_EstablishmentIdentifiers_AndEstablishmentExists_Returns_Ok _ => throw new ArgumentOutOfRangeException(nameof(idType), idType, null) }; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier!, cancellationToken); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); - - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var establishments = content!.Establishments; establishments.Length.Should().Be(1); @@ -199,14 +178,10 @@ public async Task Get_Identifiers_AndEstablishmentAndTrustExists_Returns_Ok() var selectedEstablishment = mixedData.Establishments.First(); var selectedTrust = mixedData.Trust; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(IdentifierConstants.MixedSameUkprn, cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{IdentifierConstants.MixedSameUkprn}"); - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var establishments = content!.Establishments; establishments.Length.Should().Be(1); @@ -237,14 +212,10 @@ public async Task Get_ConversionProjectIdentifier_AndProjectExistsExists_Returns _ => throw new ArgumentOutOfRangeException(nameof(idType), idType, null) }; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier!, cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var conversionProjects = content!.ConversionProjects; conversionProjects.Length.Should().Be(1); @@ -261,14 +232,10 @@ public async Task Get_TransferProjectIdentifier_AndProjectExistsExists_Returns_O var selectedProject = projectData.First(); var identifier = selectedProject.ProjectReference; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier!, cancellationToken); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); - - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var transferProjects = content!.TransferProjects; transferProjects.Length.Should().Be(1); @@ -292,14 +259,10 @@ public async Task Get_FormAMatProjectIdentifier_AndProjectExistsExists_Returns_O _ => throw new ArgumentOutOfRangeException(nameof(idType), idType, null) }; - var cancellationToken = new CancellationToken(); - var response = await Sut.GetIdentifiers(identifier!, cancellationToken); - - response.Result.Should().NotBeNull(); - response.Result.Should().BeOfType(typeof(OkObjectResult)); - response.GetStatusCode().Should().Be((int)HttpStatusCode.OK); + var response = await _client.GetAsync($"{ApiUrlPrefix}/{identifier}"); - var content = response.GetIdentifiers(); + response.StatusCode.Should().Be(HttpStatusCode.OK); + var content = await response.Content.ReadFromJsonAsync(); content.Should().NotBeNull(); var formAMatProjects = content!.FormAMatProjects; formAMatProjects.Length.Should().Be(1); diff --git a/Dfe.Identifiers.Api.Test/ApiTestFixture.cs b/Dfe.Identifiers.Api.Test/ApiTestFixture.cs index 636e895..387cf5e 100644 --- a/Dfe.Identifiers.Api.Test/ApiTestFixture.cs +++ b/Dfe.Identifiers.Api.Test/ApiTestFixture.cs @@ -1,4 +1,6 @@ -using Dfe.Identifiers.Infrastructure.Context; +using System.Net.Mime; +using Dfe.Identifiers.Infrastructure.Context; +using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -8,38 +10,67 @@ public class ApiTestFixture : IDisposable { private const string connectionStringKey = "ConnectionStrings:DefaultConnection"; private DbContextOptions _mstrContextOptions { get; init; } - private DbContextOptions _academisationContextOptions { get; init; } + private static readonly object _lock = new(); + private static bool isInitalised = false; + public HttpClient Client { get; init; } + + private readonly WebApplicationFactory _application; public ApiTestFixture() { - var builder = new ConfigurationBuilder() - .AddJsonFile("appsettings.json") - .AddEnvironmentVariables() - .AddUserSecrets(); - - Configuration = builder.Build(); - _mstrContextOptions = new DbContextOptionsBuilder() - .UseSqlServer(Configuration[connectionStringKey]) - .Options; - _academisationContextOptions = new DbContextOptionsBuilder() - .UseSqlServer(Configuration[connectionStringKey]) - .Options; - using var mstrContext = GetMstrContext(); - using var academisationContext = GetAcademisationContext(); - mstrContext.Database.EnsureDeleted(); - academisationContext.Database.EnsureDeleted(); - mstrContext.Database.Migrate(); - academisationContext.Database.Migrate(); + lock (_lock) + { + if (!isInitalised) + { + string? connectionString = null; + _application = new WebApplicationFactory() + .WithWebHostBuilder(builder => + { + builder.ConfigureAppConfiguration((context, config) => + { + config.AddJsonFile("appsettings.json") + .AddEnvironmentVariables() + .AddUserSecrets(); + var configuration = config.Build(); + connectionString = configuration[connectionStringKey]; + }); + }); + + Client = _application.CreateClient(); + Client.DefaultRequestHeaders.Add("ApiKey", "app-key"); + Client.DefaultRequestHeaders.Add("ContentType", MediaTypeNames.Application.Json); + Client.BaseAddress = new Uri("https://identifiers-api.com"); + + _mstrContextOptions = new DbContextOptionsBuilder() + .UseSqlServer(connectionString) + .EnableSensitiveDataLogging() + .Options; + _academisationContextOptions = new DbContextOptionsBuilder() + .UseSqlServer(connectionString) + .EnableSensitiveDataLogging() + .Options; + } + SetupDatabase(); + } + } - private IConfigurationRoot Configuration { get; init; } - public MstrContext GetMstrContext() => new(_mstrContextOptions); public AcademisationContext GetAcademisationContext() => new(_academisationContextOptions); public void Dispose() { } + + private void SetupDatabase() + { + using var mstrContext = GetMstrContext(); + using var academisationContext = GetAcademisationContext(); + mstrContext.Database.EnsureDeleted(); + academisationContext.Database.EnsureDeleted(); + mstrContext.Database.Migrate(); + academisationContext.Database.Migrate(); + } } } \ No newline at end of file