using Microsoft.EntityFrameworkCore; using Testcontainers.PostgreSql; using w4c_workflows.Data; using Xunit; namespace w4c_workflows.Tests; [CollectionDefinition("WorkflowsPostgres")] public class WorkflowsPostgresCollection : ICollectionFixture { } /// /// One Postgres 17 container per collection; applies the EF Core migration once /// and hands out fresh (scoped-like) DbContext instances per test. /// public sealed class WorkflowsPostgresFixture : IAsyncLifetime { private PostgreSqlContainer? _container; private string _connectionString = ""; public async Task InitializeAsync() { _container = new PostgreSqlBuilder() .WithImage("postgres:17-alpine") .WithDatabase("w4c_workflows_test") .WithUsername("w4c") .WithPassword("w4c_test_pw") .Build(); await _container.StartAsync(); _connectionString = _container.GetConnectionString() + ";Timezone=UTC"; await using var context = CreateContext(); await context.Database.MigrateAsync(); // Mirror the production startup ordering (Program.cs): the add-on columns for // W7 (ArchivedAt) and S8 (Server) are applied by idempotent raw SQL AFTER the // EF migrations — no new EF migration is introduced (the project's house style). await context.Database.ExecuteSqlRawAsync( "ALTER TABLE workflows.\"Tasks\" ADD COLUMN IF NOT EXISTS \"ArchivedAt\" timestamptz NULL;"); await context.Database.ExecuteSqlRawAsync( "ALTER TABLE workflows.\"Tasks\" ADD COLUMN IF NOT EXISTS \"Server\" text NULL;"); // Workflow repo scoping: the repo name column + per-tenant repo setting table. await context.Database.ExecuteSqlRawAsync( "ALTER TABLE workflows.\"Workflows\" ADD COLUMN IF NOT EXISTS \"Repo\" text NOT NULL DEFAULT 'workflows';"); await context.Database.ExecuteSqlRawAsync( "CREATE TABLE IF NOT EXISTS workflows.\"WorkflowRepos\" (" + "\"TenantId\" text NOT NULL, \"RepoName\" text NOT NULL, \"UpdatedAt\" timestamptz NULL, " + "CONSTRAINT \"PK_WorkflowRepos\" PRIMARY KEY (\"TenantId\"));"); } public async Task DisposeAsync() { if (_container is not null) await _container.DisposeAsync(); } public WorkflowsDbContext CreateContext() { var options = new DbContextOptionsBuilder() .UseNpgsql(_connectionString) .Options; return new WorkflowsDbContext(options); } }