using System.Net; using System.Net.Sockets; using System.Text.Json; using FinalFactory.Rendezvous.Server.Diagnostics; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace FinalFactory.Rendezvous.Tests.Diagnostics; public sealed class DiagnosticDashboardTests { [Fact] public void ConfigurationRequiresBoundedUniqueAllowListedScopes() { Assert.Empty(ValidOptions().Validate()); Assert.Empty(new DiagnosticDashboardOptions().Validate()); DiagnosticDashboardOptions invalid = ValidOptions() with { PollIntervalSeconds = 1, MaximumRenderedSessions = 501, Scopes = [ new DiagnosticDashboardScope { GameId = "INVALID", EnvironmentId = "smoke", ProtocolVersions = [0, 0], Regions = ["INVALID", "INVALID"], }, new DiagnosticDashboardScope { GameId = "INVALID", EnvironmentId = "smoke", ProtocolVersions = [1], Regions = ["local"], }, ], }; IReadOnlyList errors = invalid.Validate(); Assert.Contains(errors, error => error.Contains("PollIntervalSeconds", StringComparison.Ordinal)); Assert.Contains(errors, error => error.Contains("MaximumRenderedSessions", StringComparison.Ordinal)); Assert.Contains(errors, error => error.Contains("invalid game", StringComparison.Ordinal)); Assert.Contains(errors, error => error.Contains("protocol versions", StringComparison.Ordinal)); Assert.Contains(errors, error => error.Contains("regions", StringComparison.Ordinal)); Assert.Contains(errors, error => error.Contains("duplicate", StringComparison.Ordinal)); DiagnosticDashboardOptions nullBound = ValidOptions() with { Scopes = null!, }; Assert.Contains( nullBound.Validate(), error => error.Contains("Scopes must contain", StringComparison.Ordinal)); DiagnosticDashboardOptions nullScope = ValidOptions() with { Scopes = [null!], }; Assert.Contains( nullScope.Validate(), error => error.Contains("null entries", StringComparison.Ordinal)); DiagnosticDashboardOptions nullCollections = ValidOptions() with { Scopes = [ new DiagnosticDashboardScope { GameId = null!, EnvironmentId = null!, ProtocolVersions = null!, Regions = null!, }, ], }; Assert.True(nullCollections.Validate().Count >= 3); } [Fact] public async Task DisabledDashboardHasNoPublicAssetOrConfigurationSurface() { await using DashboardHost host = await DashboardHost.StartAsync(new()); Assert.Equal(HttpStatusCode.NotFound, (await host.Client.GetAsync("diagnostics/")).StatusCode); Assert.Equal(HttpStatusCode.NotFound, (await host.Client.GetAsync("diagnostics/app.mjs")).StatusCode); Assert.Equal(HttpStatusCode.NotFound, (await host.Client.GetAsync("diagnostics/config.json")).StatusCode); } [Fact] public async Task EnabledDashboardServesOnlyHardenedSameOriginReadOnlyAssets() { await using DashboardHost host = await DashboardHost.StartAsync(ValidOptions()); using HttpRequestMessage request = new(HttpMethod.Get, "diagnostics/"); request.Headers.Add("Origin", "https://hostile.example"); using HttpResponseMessage response = await host.Client.SendAsync(request); string html = await response.Content.ReadAsStringAsync(); Assert.True(response.IsSuccessStatusCode, html); Assert.Equal("text/html", response.Content.Headers.ContentType?.MediaType); Assert.Equal("DENY", Header(response, "X-Frame-Options")); Assert.Equal("nosniff", Header(response, "X-Content-Type-Options")); Assert.Equal("no-referrer", Header(response, "Referrer-Policy")); Assert.Contains("default-src 'none'", Header(response, "Content-Security-Policy"), StringComparison.Ordinal); Assert.Contains("connect-src 'self'", Header(response, "Content-Security-Policy"), StringComparison.Ordinal); Assert.Contains("frame-ancestors 'none'", Header(response, "Content-Security-Policy"), StringComparison.Ordinal); Assert.False(response.Headers.Contains("Access-Control-Allow-Origin")); Assert.Contains("", html, StringComparison.Ordinal); Assert.Contains("href=\"#main-content\"", html, StringComparison.Ordinal); Assert.Contains("aria-live=\"polite\"", html, StringComparison.Ordinal); Assert.Contains("type=\"module\" src=\"/diagnostics/app.mjs\"", html, StringComparison.Ordinal); Assert.DoesNotContain("