using ItWorx.KnowledgeHub.Domain.Identity; using ItWorx.KnowledgeHub.Domain.Sources; using ItWorx.KnowledgeHub.Infrastructure.Persistence; using ItWorx.KnowledgeHub.IntegrationTests.Infrastructure; using ItWorx.KnowledgeHub.IntegrationTests.Operations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Migrations; namespace ItWorx.KnowledgeHub.IntegrationTests.Platform; [Collection(PostgresTestGroup.Name)] public sealed class PlatformMigrationTests(PostgresContainerFixture postgres) { [Fact] public async Task Platform_upgrade_preserves_existing_workspace_and_supports_pre_use_schema_rollback() { // Only this disposable, freshly created database is ever downgraded. An // operator rollback after platform use must restore a pre-upgrade backup. await using var target = await RestoreTargetDatabase.CreateAsync(postgres); var options = new DbContextOptionsBuilder() .UseNpgsql(target.ConnectionString) .UseSnakeCaseNamingConvention().Options; await using var db = new KnowledgeHubDbContext(options); var migrator = db.GetService(); const string previousSchema = "20260924182209_AddProjectIcons"; await migrator.MigrateAsync(previousSchema); var workspace = Workspace.Create(WorkspaceName.Create("Bestaande werkruimte"), DateTimeOffset.UtcNow); db.Workspaces.Add(workspace); await db.SaveChangesAsync(); await migrator.MigrateAsync(); db.ChangeTracker.Clear(); Assert.Equal("Bestaande werkruimte", (await db.Workspaces.SingleAsync()).Name); Assert.Empty(await db.Database.GetPendingMigrationsAsync()); Assert.Empty(await db.Set().ToListAsync()); Assert.Empty(await db.UserPreferences.ToListAsync()); Assert.Empty(await db.PlatformSettings.ToListAsync()); Assert.Empty(await db.BackgroundJobs.ToListAsync()); await migrator.MigrateAsync(previousSchema); Assert.Equal(workspace.Id, (await db.Workspaces.AsNoTracking().SingleAsync()).Id); await migrator.MigrateAsync(); Assert.Empty(await db.Database.GetPendingMigrationsAsync()); Assert.Equal(workspace.Id, (await db.Workspaces.AsNoTracking().SingleAsync()).Id); } }