test(transcription): orphaned-sidecar guard — no-op when personId is gone

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 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-28 20:31:09 +02:00
parent e021261300
commit bd17532118

View File

@@ -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");