using System.Net; using System.Net.Http.Headers; using Azaion.Missions.E2E.Fixtures; using Azaion.Missions.E2E.Helpers; using Xunit; namespace Azaion.Missions.E2E.Tests.Waypoints; /// /// FT-P-18 — waypoint cascade delete is scoped to one waypoint; the sibling /// waypoint's chain remains intact. Owns its own xUnit collection because /// the F4 fixture is destructive. /// Traces: AC-4.5. /// [Collection("CascadeF4")] [Trait("Category", "Blackbox")] [Trait("db_access", "seed-or-assert-only")] public sealed class CascadeF4Tests : TestBase, IClassFixture { public CascadeF4Tests(CascadeF4Fixture _) { /* fixture seeds the DB. */ } [Fact] [Trait("Traces", "AC-4.5")] [Trait("max_ms", "10000")] public async Task FT_P_18_waypoint_cascade_scoped_to_one_waypoint_sibling_intact() { // Arrange — refresh the F4 fixture into a deterministic state. DbResetFixture.ResetDatabase(TestEnvironment.DbSideChannel); StubSchema.EnsureCreated(); Seeds.Apply(FixtureSql.Load("fixture_cascade_F4")); // Pre-state safety check (cascade_F4_walk.json // expected_per_table_pre_state_for_safety_check). Assert.Equal(2, DbAssertions.TableRowCount("waypoints")); Assert.Equal(2, DbAssertions.TableRowCount("media")); Assert.Equal(2, DbAssertions.TableRowCount("annotations")); Assert.Equal(2, DbAssertions.TableRowCount("detection")); var token = await Tokens.MintDefaultAsync(); // Act using var http = new HttpRequestMessage( HttpMethod.Delete, $"/missions/{CascadeF4Fixture.MissionId}/waypoints/{CascadeF4Fixture.TargetWaypointId}"); http.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.Jwt); using var response = await Missions.SendAsync(http); // Assert — target chain gone. await HttpAssertions.AssertStatusAsync(response, HttpStatusCode.NoContent); Assert.Equal(0L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM waypoints WHERE id = @id", ("id", CascadeF4Fixture.TargetWaypointId))); Assert.Equal(0L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM media WHERE id = @id", ("id", CascadeF4Fixture.TargetMediaId))); Assert.Equal(0L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM annotations WHERE id = @id", ("id", CascadeF4Fixture.TargetAnnotationId))); Assert.Equal(0L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM detection WHERE annotation_id = @id", ("id", CascadeF4Fixture.TargetAnnotationId))); // Sibling chain intact. Assert.Equal(1L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM waypoints WHERE id = @id", ("id", CascadeF4Fixture.SiblingWaypointId))); Assert.Equal(1L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM media WHERE id = @id", ("id", CascadeF4Fixture.SiblingMediaId))); Assert.Equal(1L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM annotations WHERE id = @id", ("id", CascadeF4Fixture.SiblingAnnotationId))); Assert.Equal(1L, DbAssertions.ScalarCount( "SELECT COUNT(*) FROM detection WHERE annotation_id = @id", ("id", CascadeF4Fixture.SiblingAnnotationId))); } }