Files
Trent 5c28516412
CI / backend (push) Successful in 9m19s
CI / frontend (push) Successful in 1m43s
Fix most recent fix for ci test
2026-08-10 15:24:47 +08:00

107 lines
5.0 KiB
C#

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using StackExchange.Redis;
public class GatewayApiFixture : WebApplicationFactory<Program>, IAsyncLifetime
{
// Prefer CI/env overrides; fall back to ward-gateway compose profile ports.
public static string TestConnectionString { get; } =
Environment.GetEnvironmentVariable("ConnectionStrings__GatewayDb")
?? "Host=localhost;Port=5437;Database=vigilcare_ward_test;Username=postgres;Password=password";
// Never fall back to the API Redis__* env — that points at a different instance/DB index.
public static string RedisConnection { get; } =
Environment.GetEnvironmentVariable("Gateway__Redis__ConnectionString")
?? "localhost:6383,defaultDatabase=2,allowAdmin=true";
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Testing");
builder.ConfigureAppConfiguration((_, config) =>
{
config.AddInMemoryCollection(new Dictionary<string, string?>
{
["ConnectionStrings:GatewayDb"] = TestConnectionString,
["Redis:ConnectionString"] = RedisConnection,
["RabbitMq:Host"] = Environment.GetEnvironmentVariable("Gateway__RabbitMq__Host")
?? Environment.GetEnvironmentVariable("RabbitMq__Host")
?? "localhost",
// Do not fall back to RabbitMq__Port (API uses 5674); gateway broker is 5675.
["RabbitMq:Port"] = Environment.GetEnvironmentVariable("Gateway__RabbitMq__Port")
?? "5675",
["RabbitMq:Username"] = Environment.GetEnvironmentVariable("RabbitMq__Username") ?? "guest",
["RabbitMq:Password"] = Environment.GetEnvironmentVariable("RabbitMq__Password") ?? "guest",
["RabbitMq:PagingAckTimeoutMs"] = "5000",
// Neutralize appsettings.Production.json if the process env was Production.
["RabbitMq:UseSsl"] = "false",
["CentralApi:BaseUrl"] = "http://127.0.0.1:1",
["Gateway:GatewayId"] = "22222222-2222-2222-2222-222222222222",
["Gateway:SiteId"] = "11111111-1111-1111-1111-111111111111",
["Gateway:Department"] = "ICU",
["Gateway:EncounterSyncIntervalMinutes"] = "60",
["Gateway:CentralReachabilityIntervalSeconds"] = "1",
["Gateway:HeartbeatIntervalSeconds"] = "1",
["Gateway:SyncBatchSize"] = "500",
["Gateway:AutoMigrate"] = "false",
["ApiKey:Gateway"] = "dev-gateway-key-change-in-production",
["Jwt:SigningKey"] = "dev-signing-key-minimum-32-bytes-long!!",
["Jwt:Issuer"] = "vigilcare-gateway",
["Jwt:Audience"] = "vigilcare-dashboard",
});
});
builder.ConfigureServices(services =>
{
services.Configure<HostOptions>(o =>
o.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = TestingAuthHandler.SchemeName;
options.DefaultChallengeScheme = TestingAuthHandler.SchemeName;
})
.AddScheme<AuthenticationSchemeOptions, TestingAuthHandler>(
TestingAuthHandler.SchemeName, _ => { });
});
}
public async Task InitializeAsync()
{
var options = new DbContextOptionsBuilder<GatewayDbContext>()
.UseNpgsql(TestConnectionString)
.Options;
await using (var migrateDb = new GatewayDbContext(options))
{
await migrateDb.Database.MigrateAsync();
await GatewayDbResetHelper.ResetAsync(migrateDb);
}
// Flush only the gateway test DB index — do not FlushAll (would wipe API test DB 1).
// Must run before Services is touched: host startup saturates the thread pool and
// causes StackExchange.Redis TimeoutException on FLUSHDB under CI load.
var dbIndex = 2;
var cfg = RedisConnection.Split(',').FirstOrDefault(p => p.StartsWith("defaultDatabase=", StringComparison.OrdinalIgnoreCase));
if (cfg is not null && int.TryParse(cfg.Split('=')[1], out var parsed))
dbIndex = parsed;
await using (var redis = await ConnectionMultiplexer.ConnectAsync(RedisConnection))
{
var server = redis.GetServer(redis.GetEndPoints().First());
await server.FlushDatabaseAsync(dbIndex);
}
}
protected override void ConfigureClient(HttpClient client)
{
base.ConfigureClient(client);
client.AsNurse();
}
public new async Task DisposeAsync() => await base.DisposeAsync();
}