Skip to content

Commit

Permalink
CDMS-200 adding decision integration tests & refactoring ApplicationF…
Browse files Browse the repository at this point in the history
…actory
  • Loading branch information
craigedmunds committed Dec 24, 2024
1 parent 1863b79 commit e30d145
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 29 deletions.
4 changes: 2 additions & 2 deletions Btms.Backend.IntegrationTests/AnalyticsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
namespace Btms.Backend.IntegrationTests;

[Trait("Category", "Integration")]
public class AnalyticsTests(IntegrationTestsApplicationFactory factory, ITestOutputHelper testOutputHelper)
: BaseApiTests(factory, testOutputHelper), IClassFixture<IntegrationTestsApplicationFactory>
public class AnalyticsTests(ApplicationFactory factory, ITestOutputHelper testOutputHelper)
: BaseApiTests(factory, testOutputHelper), IClassFixture<ApplicationFactory>
{

// private static void ShouldNotBeNull<T>([DoesNotReturnIf(true), NotNull] T? value)
Expand Down
9 changes: 7 additions & 2 deletions Btms.Backend.IntegrationTests/BaseApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ namespace Btms.Backend.IntegrationTests;
public abstract class BaseApiTests
{
protected readonly HttpClient Client;
protected readonly IntegrationTestsApplicationFactory Factory;
internal readonly IIntegrationTestsApplicationFactory Factory;
// protected readonly IntegrationTestsApplicationFactory Factory;

protected BaseApiTests(IntegrationTestsApplicationFactory factory, ITestOutputHelper testOutputHelper)
protected async Task ClearDb()
{
await Factory.ClearDb(Client);
}
protected BaseApiTests(IIntegrationTestsApplicationFactory factory, ITestOutputHelper testOutputHelper)
{
Factory = factory;
Factory.TestOutputHelper = testOutputHelper;
Expand Down
46 changes: 46 additions & 0 deletions Btms.Backend.IntegrationTests/DecisionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Diagnostics.CodeAnalysis;
using Btms.Common.Extensions;
using Btms.Model;
using Btms.SyncJob;
using Btms.Backend.IntegrationTests.JsonApiClient;
using FluentAssertions;
using System.Net;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using Btms.Backend.IntegrationTests.Extensions;
using Btms.Backend.IntegrationTests.Helpers;
using Json.More;
using Xunit;
using Xunit.Abstractions;

namespace Btms.Backend.IntegrationTests;

[Trait("Category", "Integration")]
public class DecsionTests(ScenarioApplicationFactory factory, ITestOutputHelper testOutputHelper)
: BaseApiTests(factory, testOutputHelper), IClassFixture<ScenarioApplicationFactory>
{

[Fact]
public async Task SimpleChedPScenario()
{
// Arrange
await factory.ClearDb(Client);

// Act
// await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
// {
// SyncPeriod = SyncPeriod.All, RootFolder = "SmokeTest"
// });

// Assert
var jsonClientResponse = Client.AsJsonApiClient().Get("api/movements");
jsonClientResponse.Data
.Where(x => x.Relationships is not null)
.SelectMany(x => x.Relationships!)
.Any(x => x.Value is { Links: not null })
.Should().Be(false);
}
}
18 changes: 10 additions & 8 deletions Btms.Backend.IntegrationTests/GmrTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,27 @@ namespace Btms.Backend.IntegrationTests;

[Trait("Category", "Integration")]
public class GmrTests :
IClassFixture<IntegrationTestsApplicationFactory>, IAsyncLifetime
IClassFixture<ApplicationFactory>, IAsyncLifetime
{
private readonly HttpClient client;
private readonly HttpClient _client;
private IIntegrationTestsApplicationFactory _factory;

public GmrTests(IntegrationTestsApplicationFactory factory, ITestOutputHelper testOutputHelper)
public GmrTests(ApplicationFactory factory, ITestOutputHelper testOutputHelper)
{
factory.TestOutputHelper = testOutputHelper;
factory.DatabaseName = "GmrTests";
client = factory.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
_client = factory.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
var credentials = "IntTest:Password";
var credentialsAsBytes = Encoding.UTF8.GetBytes(credentials.ToCharArray());
var encodedCredentials = Convert.ToBase64String(credentialsAsBytes);
client.DefaultRequestHeaders.Authorization =
_client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(BasicAuthenticationDefaults.AuthenticationScheme, encodedCredentials);
_factory = factory;
}

public async Task InitializeAsync()
{
await IntegrationTestsApplicationFactory.ClearDb(client);
await _factory.ClearDb(_client);

await MakeSyncGmrsRequest(new SyncGmrsCommand
{
Expand All @@ -48,7 +50,7 @@ await MakeSyncGmrsRequest(new SyncGmrsCommand
public void FetchSingleGmrTest()
{
//Act
var jsonClientResponse = client.AsJsonApiClient().GetById("GMRAPOQSPDUG", "api/gmrs");
var jsonClientResponse = _client.AsJsonApiClient().GetById("GMRAPOQSPDUG", "api/gmrs");

// Assert
jsonClientResponse.Data.Relationships?["customs"]?.Links?.Self.Should().Be("/api/gmr/:id/relationships/import-notifications");
Expand All @@ -68,7 +70,7 @@ private Task<HttpResponseMessage> PostCommand<T>(T command, string uri)
var jsonData = JsonSerializer.Serialize(command);
HttpContent content = new StringContent(jsonData, Encoding.UTF8, "application/json");

return client.PostAsync(uri, content);
return _client.PostAsync(uri, content);
}

public Task DisposeAsync()
Expand Down
93 changes: 93 additions & 0 deletions Btms.Backend.IntegrationTests/Helpers/ApplicationFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using Btms.Backend.Data;
using Btms.BlobService;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Driver;
using Xunit.Abstractions;

namespace Btms.Backend.IntegrationTests.Helpers;

public interface IIntegrationTestsApplicationFactory
{
ITestOutputHelper TestOutputHelper { get; set; }
string DatabaseName { get; set; }

HttpClient CreateClient(WebApplicationFactoryClientOptions options);
HttpClient CreateClient();
IMongoDbContext GetDbContext();
Task ClearDb(HttpClient client);
}

public class ApplicationFactory : WebApplicationFactory<Program>, IIntegrationTestsApplicationFactory
{
// protected override Bef
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
// Any integration test overrides could be added here
// And we don't want to load the backend ini file
var configurationValues = new Dictionary<string, string>
{
{ "DisableLoadIniFile", "true" },
{ "BlobServiceOptions:CachePath", "../../../Fixtures" },
{ "BlobServiceOptions:CacheReadEnabled", "true" },
{ "AuthKeyStore:Credentials:IntTest", "Password" }
};

var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(configurationValues!)
.Build();

builder
.UseConfiguration(configuration)
.ConfigureServices(services =>
{
var mongoDatabaseDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IMongoDatabase))!;
services.Remove(mongoDatabaseDescriptor);

var blobOptionsValidatorDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IValidateOptions<BlobServiceOptions>))!;
services.Remove(blobOptionsValidatorDescriptor);

services.AddSingleton(sp =>
{
var options = sp.GetService<IOptions<MongoDbOptions>>()!;
var settings = MongoClientSettings.FromConnectionString(options.Value.DatabaseUri);
var client = new MongoClient(settings);

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
// convention must be registered before initialising collection
ConventionRegistry.Register("CamelCase", camelCaseConvention, _ => true);

var dbName = string.IsNullOrEmpty(DatabaseName) ? Random.Shared.Next().ToString() : DatabaseName;
return client.GetDatabase($"Btms_MongoDb_{dbName}_Test");
});

services.AddLogging(lb => lb.AddXUnit(TestOutputHelper));
});

builder.UseEnvironment("Development");
}

public ITestOutputHelper TestOutputHelper { get; set; } = null!;

public string DatabaseName { get; set; } = null!;

public IMongoDbContext GetDbContext()
{
return Services.CreateScope().ServiceProvider.GetRequiredService<IMongoDbContext>();
}

// public new HttpClient CreateClient()
// {
// throw new NotImplementedException();
// }

public async Task ClearDb(HttpClient client)
{
await client.GetAsync("mgmt/collections/drop");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Btms.Backend.IntegrationTests.Helpers;

public class IntegrationTestsApplicationFactory : WebApplicationFactory<Program>
public class ScenarioApplicationFactory : WebApplicationFactory<Program>, IIntegrationTestsApplicationFactory
{
// protected override Bef
protected override void ConfigureWebHost(IWebHostBuilder builder)
Expand Down Expand Up @@ -61,16 +61,16 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
builder.UseEnvironment("Development");
}

internal ITestOutputHelper TestOutputHelper { get; set; } = null!;
public ITestOutputHelper TestOutputHelper { get; set; } = null!;

internal string DatabaseName { get; set; } = null!;
public string DatabaseName { get; set; } = null!;

public IMongoDbContext GetDbContext()
{
return Services.CreateScope().ServiceProvider.GetRequiredService<IMongoDbContext>();
}

public static async Task ClearDb(HttpClient client)
public async Task ClearDb(HttpClient client)
{
await client.GetAsync("mgmt/collections/drop");
}
Expand Down
12 changes: 6 additions & 6 deletions Btms.Backend.IntegrationTests/LinkingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
namespace Btms.Backend.IntegrationTests;

[Trait("Category", "Integration")]
public class LinkingTests(IntegrationTestsApplicationFactory factory, ITestOutputHelper testOutputHelper)
: BaseApiTests(factory, testOutputHelper), IClassFixture<IntegrationTestsApplicationFactory>
public class LinkingTests(ApplicationFactory factory, ITestOutputHelper testOutputHelper)
: BaseApiTests(factory, testOutputHelper), IClassFixture<ApplicationFactory>
{
[Fact]
public async Task SyncClearanceRequests_WithNoReferencedNotifications_ShouldNotLink()
{
// Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await Factory.ClearDb(Client);

// Act
await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
Expand All @@ -36,7 +36,7 @@ await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
public async Task SyncClearanceRequests_WithReferencedNotifications_ShouldLink()
{
// Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();

// Act
await MakeSyncNotificationsRequest(new SyncNotificationsCommand
Expand All @@ -61,7 +61,7 @@ await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
public async Task SyncNotifications_WithNoReferencedMovements_ShouldNotLink()
{
// Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();

// Act
await MakeSyncNotificationsRequest(new SyncNotificationsCommand
Expand All @@ -82,7 +82,7 @@ await MakeSyncNotificationsRequest(new SyncNotificationsCommand
public async Task SyncNotifications_WithReferencedMovements_ShouldLink()
{
// Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();

// Act
await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
Expand Down
14 changes: 7 additions & 7 deletions Btms.Backend.IntegrationTests/SmokeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
namespace Btms.Backend.IntegrationTests;

[Trait("Category", "Integration")]
public class SmokeTests : BaseApiTests, IClassFixture<IntegrationTestsApplicationFactory>
public class SmokeTests : BaseApiTests, IClassFixture<ApplicationFactory>
{
private readonly JsonSerializerOptions jsonOptions;

public SmokeTests(IntegrationTestsApplicationFactory factory, ITestOutputHelper testOutputHelper) :base(factory, testOutputHelper)
public SmokeTests(ApplicationFactory factory, ITestOutputHelper testOutputHelper) :base(factory, testOutputHelper)
{
jsonOptions = new JsonSerializerOptions();
jsonOptions.Converters.Add(new JsonStringEnumConverter());
Expand All @@ -30,7 +30,7 @@ public SmokeTests(IntegrationTestsApplicationFactory factory, ITestOutputHelper
public async Task CancelSyncJob()
{
//Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();
var jobId = await StartJob(new SyncNotificationsCommand
{
SyncPeriod = SyncPeriod.All,
Expand All @@ -56,7 +56,7 @@ public async Task CancelSyncJob()
public async Task SyncNotifications()
{
//Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();
await MakeSyncNotificationsRequest(new SyncNotificationsCommand
{
SyncPeriod = SyncPeriod.All,
Expand All @@ -76,7 +76,7 @@ await MakeSyncNotificationsRequest(new SyncNotificationsCommand
public async Task SyncDecisions()
{
//Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();
await SyncClearanceRequests();
await MakeSyncDecisionsRequest(new SyncDecisionsCommand
{
Expand Down Expand Up @@ -106,7 +106,7 @@ await MakeSyncDecisionsRequest(new SyncDecisionsCommand
public async Task SyncClearanceRequests()
{
//Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();

//Act
await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
Expand All @@ -127,7 +127,7 @@ await MakeSyncClearanceRequest(new SyncClearanceRequestsCommand
public async Task SyncGmrs()
{
//Arrange
await IntegrationTestsApplicationFactory.ClearDb(Client);
await base.ClearDb();

//Act
await MakeSyncGmrsRequest(new SyncGmrsCommand
Expand Down

0 comments on commit e30d145

Please sign in to comment.