mirror of
https://github.com/azaion/missions.git
synced 2026-06-21 21:21:08 +00:00
6b2c2d998e
Adds 26 blackbox tests (FT-P-01..18, FT-N-01..08) covering full AC
matrices for Vehicles/Missions/Waypoints/Health/Errors. Three
spec-vs-code carry-forwards documented in batch_02_report.md and
pinned with [Trait("carry_forward", ...)].
Shared scaffolding: ApiDtos.cs, AssertProblemEnvelopeAsync helper,
Seeds.cs, StubSchema.cs, CascadeF3/F4 fixtures, PostgresStopStart
fixture (gated by COMPOSE_RESTART_ENABLED). Removes the 4 placeholder
Sanity.cs files (now superseded). docker-compose.test.yml gains the
expected_results volume mount + FIXTURE_SQL_DIR for the consumer.
Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
3.0 KiB
C#
83 lines
3.0 KiB
C#
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text.Json;
|
|
using Azaion.Missions.E2E.Fixtures;
|
|
using Azaion.Missions.E2E.Helpers;
|
|
using Xunit;
|
|
|
|
namespace Azaion.Missions.E2E.Tests.Health;
|
|
|
|
/// <summary>
|
|
/// FT-P-16 (anonymous 200) and FT-P-17 (200 with PG stopped). FT-P-17 is a
|
|
/// SkippableFact: it runs only when COMPOSE_RESTART_ENABLED=1 and the e2e
|
|
/// container has docker CLI access; otherwise it skips with a clear reason.
|
|
/// Traces: AC-7.1, AC-7.2, AC-7.3.
|
|
/// </summary>
|
|
[Collection("Health")]
|
|
[Trait("Category", "Blackbox")]
|
|
public sealed class HealthTests : TestBase, IClassFixture<PostgresStopStartFixture>
|
|
{
|
|
private readonly PostgresStopStartFixture _pg;
|
|
|
|
public HealthTests(PostgresStopStartFixture pg) => _pg = pg;
|
|
|
|
[Fact]
|
|
[Trait("Traces", "AC-7.1")]
|
|
[Trait("max_ms", "2000")]
|
|
public async Task FT_P_16_health_returns_200_anonymous_with_lowercase_status_key()
|
|
{
|
|
// Arrange
|
|
using var http = new HttpRequestMessage(HttpMethod.Get, "/health");
|
|
// Explicitly NO Authorization header — health is anonymous.
|
|
|
|
// Act
|
|
using var response = await Missions.SendAsync(http);
|
|
|
|
// Assert
|
|
await HttpAssertions.AssertStatusAsync(response, HttpStatusCode.OK);
|
|
var raw = await response.Content.ReadAsStringAsync();
|
|
using var doc = JsonDocument.Parse(raw);
|
|
var root = doc.RootElement;
|
|
// The anonymous-object literal in Program.cs declares the key as
|
|
// lowercase "status"; assert that exact contract — a future global
|
|
// PascalCase shift would break consumers.
|
|
Assert.True(root.TryGetProperty("status", out var statusEl), $"missing 'status' key: {raw}");
|
|
Assert.Equal("healthy", statusEl.GetString());
|
|
// Reject any extra keys to pin the envelope.
|
|
var extras = root.EnumerateObject().Select(p => p.Name)
|
|
.Where(n => n != "status").ToArray();
|
|
Assert.True(extras.Length == 0,
|
|
$"unexpected extra keys in /health body: {string.Join(",", extras)}");
|
|
}
|
|
|
|
[SkippableFact]
|
|
[Trait("Traces", "AC-7.2,AC-7.3")]
|
|
[Trait("max_ms", "5000")]
|
|
public async Task FT_P_17_health_returns_200_with_postgres_stopped_proves_no_db_ping()
|
|
{
|
|
Skip.IfNot(_pg.Enabled,
|
|
"PostgresStopStartFixture disabled (COMPOSE_RESTART_ENABLED!=1). " +
|
|
"Enable in CI; locally this scenario requires docker socket access.");
|
|
|
|
// Arrange
|
|
_pg.Stop();
|
|
try
|
|
{
|
|
using var http = new HttpRequestMessage(HttpMethod.Get, "/health");
|
|
|
|
// Act
|
|
using var response = await Missions.SendAsync(http);
|
|
|
|
// Assert
|
|
await HttpAssertions.AssertStatusAsync(response, HttpStatusCode.OK);
|
|
var raw = await response.Content.ReadAsStringAsync();
|
|
using var doc = JsonDocument.Parse(raw);
|
|
Assert.Equal("healthy", doc.RootElement.GetProperty("status").GetString());
|
|
}
|
|
finally
|
|
{
|
|
_pg.Start();
|
|
}
|
|
}
|
|
}
|