From 9cba179c59b69318e53deecc3d16620d4d27168a Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 23 Oct 2026 08:48:14 +0000 Subject: [PATCH] Test that deleting an entity cascades through referrers Covers the recursive MarkDeleted call in SnapshotWorker: deleting a word deletes its definition via RemoveReference, which must in turn delete the definition's example. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017iyZdteks1z5KpAsAAVMNt --- src/SIL.Harmony.Tests/SnapshotWorkerTests.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/SIL.Harmony.Tests/SnapshotWorkerTests.cs b/src/SIL.Harmony.Tests/SnapshotWorkerTests.cs index c45a634..c3c4590 100644 --- a/src/SIL.Harmony.Tests/SnapshotWorkerTests.cs +++ b/src/SIL.Harmony.Tests/SnapshotWorkerTests.cs @@ -109,6 +109,22 @@ public async Task DeletingAnEntityDropsReferencesToItFromBaselineEntities() WordFrom(wordSnapshot).AntonymId.Should().BeNull(); } + [Fact] + public async Task DeletingAnEntityCascadesThroughReferrersThatRemovingTheReferenceDeletes() + { + var word = new Word { Id = Guid.NewGuid(), Text = "hello" }; + var definition = new Definition { Id = Guid.NewGuid(), Text = "a greeting", Order = 0, PartOfSpeech = "noun", WordId = word.Id }; + var example = new Example { Id = Guid.NewGuid(), DefinitionId = definition.Id }; + var baseline = Baseline(word, definition, example); + var delete = NextCommit(DeleteWord(word.Id)); + + var (snapshots, _) = await SnapshotWorker.ComputeNewSnapshotsAndCheckpoints(baseline, [delete], SampleConfig); + + //the example only references the definition, so it's deleted by the recursive MarkDeleted + snapshots.Should().HaveCount(3).And.OnlyContain(s => s.EntityIsDeleted && s.CommitId == delete.Id); + snapshots.Select(s => s.EntityId).Should().BeEquivalentTo([word.Id, definition.Id, example.Id]); + } + [Fact] public async Task ADeletedEntityIsRevivedByACreateChange() {