mirror of
https://github.com/azaion/missions.git
synced 2026-06-22 21:51:06 +00:00
[AZ-577] [AZ-578] [AZ-579] [AZ-580] Implement E2E test batch 2
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>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user