namespace GmRelay.Bot.Tests.Web; public sealed class PublicationModeTests { [Fact] public void PublicationMode_ShouldHaveFourValues() { var values = Enum.GetValues(); Assert.Equal(4, values.Length); Assert.Contains(GmRelay.Shared.Domain.PublicationMode.None, values); Assert.Contains(GmRelay.Shared.Domain.PublicationMode.Catalog, values); Assert.Contains(GmRelay.Shared.Domain.PublicationMode.ClubOnly, values); Assert.Contains(GmRelay.Shared.Domain.PublicationMode.Both, values); } [Fact] public async Task MigrationV030_ShouldAddClubMembershipsTable() { var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V030__add_club_memberships_and_publication_mode.sql"); Assert.Contains("CREATE TABLE club_memberships", migration, StringComparison.Ordinal); Assert.Contains("status", migration, StringComparison.Ordinal); Assert.Contains("role", migration, StringComparison.Ordinal); Assert.Contains("Pending", migration, StringComparison.Ordinal); Assert.Contains("Active", migration, StringComparison.Ordinal); Assert.Contains("Rejected", migration, StringComparison.Ordinal); Assert.Contains("Left", migration, StringComparison.Ordinal); Assert.Contains("ux_club_memberships_one_active", migration, StringComparison.Ordinal); Assert.Contains("Member", migration, StringComparison.Ordinal); } [Fact] public async Task MigrationV030_ShouldReplaceIsPublicWithPublicationModeEnum() { var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V030__add_club_memberships_and_publication_mode.sql"); Assert.Contains("ADD COLUMN publication_mode", migration, StringComparison.Ordinal); Assert.Contains("ck_sessions_publication_mode", migration, StringComparison.Ordinal); Assert.Contains("'None', 'Catalog', 'ClubOnly', 'Both'", migration, StringComparison.Ordinal); Assert.Contains("UPDATE sessions SET publication_mode = 'Both' WHERE is_public = true", migration, StringComparison.Ordinal); Assert.Contains("UPDATE sessions SET publication_mode = 'None' WHERE is_public = false", migration, StringComparison.Ordinal); Assert.Contains("DROP COLUMN is_public", migration, StringComparison.Ordinal); } [Fact] public async Task MigrationV030_ShouldRecreatePartialIndexUsingPublicationMode() { var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V030__add_club_memberships_and_publication_mode.sql"); Assert.Contains("ix_sessions_public_schedule", migration, StringComparison.Ordinal); Assert.Contains("publication_mode IN ('Catalog', 'Both')", migration, StringComparison.Ordinal); } [Fact] public async Task MigrationV030_ShouldAddPortfolioPublicationModeColumn() { var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V030__add_club_memberships_and_publication_mode.sql"); Assert.Contains("portfolio_games", migration, StringComparison.Ordinal); Assert.Contains("ix_portfolio_games_showcase", migration, StringComparison.Ordinal); } private static async Task ReadRepositoryFileAsync(string relativePath) { var directory = new DirectoryInfo(AppContext.BaseDirectory); while (directory is not null) { var candidate = Path.Combine(directory.FullName, relativePath); if (File.Exists(candidate)) { return await File.ReadAllTextAsync(candidate); } directory = directory.Parent; } throw new FileNotFoundException($"Could not locate repository file '{relativePath}'."); } }