Files
GmRelayBot/tests/GmRelay.Bot.Tests/Web/PortfolioSchemaGateSourceTests.cs
T

92 lines
3.4 KiB
C#

namespace GmRelay.Bot.Tests.Web;
public sealed class PortfolioSchemaGateSourceTests
{
[Fact]
public async Task Compose_ShouldStartDiscordAndWebOnlyAfterBotMigrationsAreHealthy()
{
var compose = await ReadRepositoryFileAsync("compose.yaml");
AssertServiceDependsOnHealthyBot(compose, "discord");
AssertServiceDependsOnHealthyBot(compose, "web");
}
[Fact]
public async Task Aspire_ShouldStartDiscordAndWebOnlyAfterBotMigrationsAreHealthy()
{
var appHost = NormalizeSource(await ReadRepositoryFileAsync("src/GmRelay.AppHost/Program.cs"));
Assert.Contains(
"var bot = builder.AddProject<Projects.GmRelay_Bot>(\"bot\") .WithReference(postgres) .WaitFor(postgres) .WithHttpEndpoint(port: 8081, targetPort: 8081, name: \"health\", isProxied: false) .WithHttpHealthCheck(\"/health\", endpointName: \"health\");",
appHost,
StringComparison.Ordinal);
Assert.Contains(
"builder.AddProject<Projects.GmRelay_DiscordBot>(\"discord\") .WithReference(postgres) .WaitFor(postgres) .WaitFor(bot);",
appHost,
StringComparison.Ordinal);
Assert.Contains(
"builder.AddProject<Projects.GmRelay_Web>(\"web\") .WithReference(postgres) .WaitFor(postgres) .WaitFor(bot);",
appHost,
StringComparison.Ordinal);
}
[Fact]
public async Task Aspire_ShouldUseApplicationDatabaseConnectionStringName()
{
var appHost = NormalizeSource(await ReadRepositoryFileAsync("src/GmRelay.AppHost/Program.cs"));
Assert.Contains(".AddDatabase(\"gmrelaydb\");", appHost, StringComparison.Ordinal);
}
private static void AssertServiceDependsOnHealthyBot(string compose, string serviceName)
{
var serviceBlock = GetServiceBlock(compose, serviceName);
Assert.Contains(
"""
bot:
condition: service_healthy
""",
serviceBlock,
StringComparison.Ordinal);
}
private static string GetServiceBlock(string compose, string serviceName)
{
var lines = compose.Split('\n');
var start = Array.FindIndex(lines, line => line.TrimEnd('\r') == $" {serviceName}:");
Assert.True(start >= 0, $"compose.yaml should contain service '{serviceName}'.");
var end = Array.FindIndex(
lines,
start + 1,
line => line.StartsWith(" ", StringComparison.Ordinal)
&& !line.StartsWith(" ", StringComparison.Ordinal)
&& line.TrimEnd('\r').EndsWith(':'));
return string.Join('\n', lines[start..(end < 0 ? lines.Length : end)]);
}
private static string NormalizeSource(string source)
{
return string.Join(' ', source.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries));
}
private static async Task<string> 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}'.");
}
}