-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathTestFixture.cs
138 lines (120 loc) · 5.4 KB
/
TestFixture.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
namespace PeakLims.IntegrationTests;
using System.Security.Claims;
using Amazon.S3;
using PeakLims.Extensions.Services;
using PeakLims.Databases;
using PeakLims.Resources;
using PeakLims.SharedTestHelpers.Utilities;
using FluentAssertions;
using FluentAssertions.Extensions;
using Hangfire;
using HeimGuard;
using NSubstitute;
using Testcontainers.PostgreSql;
using Testcontainers.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using SharedTestHelpers.Fakes.PeakOrganization;
using Testcontainers.LocalStack;
using static Resources.PeakLimsOptions;
[CollectionDefinition(nameof(TestFixture))]
public class TestFixtureCollection : ICollectionFixture<TestFixture> {}
public class TestFixture : IAsyncLifetime
{
public static IServiceScopeFactory BaseScopeFactory;
private PostgreSqlContainer _dbContainer;
private RabbitMqContainer _rmqContainer;
private LocalStackContainer _localStackContainer;
public async Task InitializeAsync()
{
var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
EnvironmentName = Consts.Testing.IntegrationTestingEnvName
});
_dbContainer = new PostgreSqlBuilder().Build();
await _dbContainer.StartAsync();
builder.Configuration.GetSection(ConnectionStringOptions.SectionName)[ConnectionStringOptions.PeakLimsKey] = _dbContainer.GetConnectionString();
await RunMigration(_dbContainer.GetConnectionString());
var freePort = DockerUtilities.GetFreePort();
_rmqContainer = new RabbitMqBuilder()
.WithPortBinding(freePort, 5672)
.Build();
await _rmqContainer.StartAsync();
builder.Configuration.GetSection(RabbitMqOptions.SectionName)[RabbitMqOptions.HostKey] = "localhost";
builder.Configuration.GetSection(RabbitMqOptions.SectionName)[RabbitMqOptions.VirtualHostKey] = "/";
builder.Configuration.GetSection(RabbitMqOptions.SectionName)[RabbitMqOptions.UsernameKey] = "guest";
builder.Configuration.GetSection(RabbitMqOptions.SectionName)[RabbitMqOptions.PasswordKey] = "guest";
builder.Configuration.GetSection(RabbitMqOptions.SectionName)[RabbitMqOptions.PortKey] = _rmqContainer.GetConnectionString();
var localstackPort = DockerUtilities.GetFreePort();
builder.Configuration["PeakLims:LocalstackPort"] = localstackPort.ToString();
_localStackContainer = new LocalStackBuilder()
.WithPortBinding(localstackPort, 4566)
.Build();
await _localStackContainer.StartAsync();
await AddS3Buckets(localstackPort);
builder.ConfigureServices();
var services = builder.Services;
// add any mock services here
services.ReplaceServiceWithSingletonMock<IHttpContextAccessor>();
services.ReplaceServiceWithSingletonMock<IHeimGuardClient>();
services.ReplaceServiceWithSingletonMock<IBackgroundJobClient>();
var provider = services.BuildServiceProvider();
BaseScopeFactory = provider.GetService<IServiceScopeFactory>();
var dbContext = provider.GetService<PeakLimsDbContext>();
var testingOrganization = new FakePeakOrganizationBuilder().Build();
testingOrganization.OverrideId(TestingConsts.DefaultTestingOrganizationId);
await dbContext.PeakOrganizations.AddAsync(testingOrganization);
await dbContext.SaveChangesAsync();
SetupDateAssertions();
}
private static async Task RunMigration(string connectionString)
{
var options = new DbContextOptionsBuilder<PeakLimsDbContext>()
.UseNpgsql(connectionString)
.Options;
var context = new PeakLimsDbContext(options, null, null, null);
await context?.Database?.MigrateAsync();
}
private static async Task AddS3Buckets(int localstackPort)
{
var config = new AmazonS3Config { ForcePathStyle = true, ServiceURL = $"http://localhost:{localstackPort}" };
var client = new AmazonS3Client("test", "test", config);
foreach (var bucket in Consts.S3Buckets.List())
{
await client.PutBucketAsync(bucket);
}
}
public async Task DisposeAsync()
{
await _dbContainer.DisposeAsync();
await _rmqContainer.DisposeAsync();
await _localStackContainer.DisposeAsync();
}
private static void SetupDateAssertions()
{
// close to equivalency required to reconcile precision differences between EF and Postgres
AssertionOptions.AssertEquivalencyUsing(options =>
{
options.Using<DateTime>(ctx => ctx.Subject
.Should()
.BeCloseTo(ctx.Expectation, 1.Seconds())).WhenTypeIs<DateTime>();
options.Using<DateTimeOffset>(ctx => ctx.Subject
.Should()
.BeCloseTo(ctx.Expectation, 1.Seconds())).WhenTypeIs<DateTimeOffset>();
return options;
});
}
}
public static class ServiceCollectionServiceExtensions
{
public static IServiceCollection ReplaceServiceWithSingletonMock<TService>(this IServiceCollection services)
where TService : class
{
services.RemoveAll(typeof(TService));
services.AddSingleton(_ => Substitute.For<TService>());
return services;
}
}