using System; using System.IO; namespace GmRelay.Bot.Tests.Discord; public sealed class DiscordStartupTests { private static string GetRepoRoot() { var dir = AppContext.BaseDirectory; while (!string.IsNullOrEmpty(dir) && !File.Exists(Path.Combine(dir, "Directory.Build.props"))) { dir = Directory.GetParent(dir)?.FullName; } return dir ?? throw new InvalidOperationException("Could not find repo root"); } [Fact] public void Program_ShouldValidateDiscordTokenBeforeRunning() { var program = ReadProgram(); Assert.Contains("GetRequiredSection(\"Discord\")", program); Assert.Contains("DiscordOptions", program); Assert.Contains(".Validate()", program); } [Fact] public void Program_ShouldRegisterServiceDefaultsAndPostgresDataSource() { var program = ReadProgram(); Assert.Contains("builder.AddServiceDefaults()", program); Assert.Contains("ConnectionStrings:gmrelaydb is required", program); Assert.Contains("NpgsqlDataSource", program); Assert.Contains("SecretRedactor.RedactConnectionString", program); } [Fact] public void Program_ShouldRegisterNetCordGatewayApplicationCommandsAndComponents() { var program = ReadProgram(); Assert.Contains(".AddDiscordGateway", program); Assert.Contains(".AddApplicationCommands", program); Assert.Contains(".AddComponentInteractions", program); Assert.Contains(".AddGatewayHandlers", program); Assert.Contains("AddSlashCommand", program); } [Fact] public void LifecycleLogger_ShouldLogGatewayLifecycleEventsWithoutTokenValues() { var repoRoot = GetRepoRoot(); var loggerPath = Path.Combine( repoRoot, "src", "GmRelay.DiscordBot", "Infrastructure", "Logging", "DiscordGatewayLifecycleLogger.cs"); Assert.True(File.Exists(loggerPath), "Discord gateway lifecycle logger should exist."); var logger = File.ReadAllText(loggerPath); Assert.Contains("IReadyGatewayHandler", logger); Assert.Contains("IDisconnectGatewayHandler", logger); Assert.Contains("IResumeGatewayHandler", logger); Assert.Contains("LogInformation", logger); Assert.DoesNotContain("Token", logger); } private static string ReadProgram() { var repoRoot = GetRepoRoot(); return File.ReadAllText(Path.Combine(repoRoot, "src", "GmRelay.DiscordBot", "Program.cs")); } }