// -----------------------------------------------------------------------------
// ProofChainTestFixture.cs
// Sprint: SPRINT_3500_0004_0003_integration_tests_corpus
// Task: T1 - Proof Chain Integration Tests
// Description: Test fixture for proof chain integration tests with PostgreSQL
// -----------------------------------------------------------------------------
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Testcontainers.PostgreSql;
namespace StellaOps.Integration.ProofChain;
///
/// Test fixture for proof chain integration tests.
/// Provides a fully configured Scanner WebService with PostgreSQL backing store.
///
public sealed class ProofChainTestFixture : IAsyncLifetime
{
private PostgreSqlContainer? _postgresContainer;
private WebApplicationFactory? _factory;
private bool _initialized;
///
/// Initializes the test fixture, starting PostgreSQL container.
///
public async Task InitializeAsync()
{
if (_initialized)
return;
// Start PostgreSQL container
_postgresContainer = new PostgreSqlBuilder()
.WithImage("postgres:16-alpine")
.WithDatabase("stellaops_test")
.WithUsername("test_user")
.WithPassword("test_password")
.WithPortBinding(5432, true)
.Build();
await _postgresContainer.StartAsync();
// Create the test web application factory
_factory = new WebApplicationFactory()
.WithWebHostBuilder(builder =>
{
builder.ConfigureAppConfiguration((context, config) =>
{
// Override connection string with test container
config.AddInMemoryCollection(new Dictionary
{
["ConnectionStrings:ScannerDb"] = _postgresContainer.GetConnectionString(),
["Scanner:Authority:Enabled"] = "false",
["Scanner:AllowAnonymous"] = "true",
["Scanner:ProofChain:Enabled"] = "true",
["Scanner:ProofChain:SigningKeyId"] = "test-key",
["Scanner:ProofChain:AutoSign"] = "true",
["Logging:LogLevel:Default"] = "Warning"
});
});
builder.ConfigureServices(services =>
{
// Add test-specific service overrides if needed
services.AddLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Warning);
});
});
});
_initialized = true;
}
///
/// Creates an HTTP client for the test application.
///
public async Task CreateClientAsync()
{
if (!_initialized)
{
await InitializeAsync();
}
return _factory!.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false
});
}
///
/// Disposes of the test fixture resources.
///
public async Task DisposeAsync()
{
_factory?.Dispose();
if (_postgresContainer is not null)
{
await _postgresContainer.DisposeAsync();
}
}
}
///
/// Placeholder for Program class detection.
/// The actual Program class is from Scanner.WebService.
///
#pragma warning disable CA1050 // Declare types in namespaces
public partial class Program { }
#pragma warning restore CA1050