From bd175321188610980bb71b24449001e77f9fe1a7 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 28 Apr 2026 20:31:09 +0200 Subject: [PATCH] =?UTF-8?q?test(transcription):=20orphaned-sidecar=20guard?= =?UTF-8?q?=20=E2=80=94=20no-op=20when=20personId=20is=20gone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A block with a sidecar entry pointing at a personId no longer in the persons table receives a rename event for that ghost id. The listener detects via PersonService.existsById that the entity is gone and exits without touching block.text or the sidecar. Defends against any future async refactor where an event could outlive the entity, or against malformed events injected by tests / migrations. Refs #362 Co-Authored-By: Claude Opus 4.7 --- .../PersonMentionPropagationListenerTest.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/backend/src/test/java/org/raddatz/familienarchiv/service/PersonMentionPropagationListenerTest.java b/backend/src/test/java/org/raddatz/familienarchiv/service/PersonMentionPropagationListenerTest.java index 38568cc1..3cd98ea2 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/service/PersonMentionPropagationListenerTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/service/PersonMentionPropagationListenerTest.java @@ -143,6 +143,28 @@ class PersonMentionPropagationListenerTest { .containsExactly("Augusta Raddatz"); } + @Test + void noOps_whenPersonIdNoLongerExists_orphanedSidecarGuard() { + UUID orphanId = UUID.randomUUID(); + when(personService.existsById(orphanId)).thenReturn(false); + + TranscriptionBlock saved = saveBlock( + "Stale reference to @Ghost Name should not be rewritten.", + List.of(new PersonMention(orphanId, "Ghost Name"))); + em.clear(); + + listener.onPersonDisplayNameChanged( + new PersonDisplayNameChangedEvent(orphanId, "Ghost Name", "Resurrected Name")); + blockRepository.flush(); + em.clear(); + + TranscriptionBlock reloaded = blockRepository.findById(saved.getId()).orElseThrow(); + assertThat(reloaded.getText()).isEqualTo("Stale reference to @Ghost Name should not be rewritten."); + assertThat(reloaded.getMentionedPersons()) + .extracting(PersonMention::getDisplayName) + .containsExactly("Ghost Name"); + } + @Test void leavesUnrelatedBlockUntouched_whenNoSidecarReferencesPerson() { UUID personId = savedPersonId("Auguste", "Raddatz");