test(mention): lock deleted-person graceful-degradation contract (#684)

Strengthen one renderTranscriptionBody case into the AC-6 contract: a
@DisplayName with an empty mentionedPersons array (the deleted-person case
V71 produces) must render as plain readable text with no <a>, person-mention
class, data-person-id, or href. Guards against a future renderer refactor
silently reintroducing the dead-link-on-deleted-person degradation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-06 11:49:48 +02:00
parent 82e86ed110
commit 149d23a5e6

View File

@@ -307,9 +307,21 @@ describe('renderTranscriptionBody', () => {
expect(result).not.toMatch(/>O"Brien<\/a>/);
});
it('renders nothing when mentionedPersons is undefined-empty and no @ triggers', () => {
const result = renderTranscriptionBody('Plain old transcription text.', []);
expect(result).toBe('Plain old transcription text.');
it('renders a deleted-person @mention as plain text with no dead link (graceful degradation)', () => {
// AC-6 (#684): when a mentioned person is deleted, V71's ON DELETE CASCADE removes the
// sidecar row, so the displayName reaches the renderer with an empty mentionedPersons
// array. The reader must still see the name as plain text — never a dead <a>, a
// person-mention class, a data-person-id, or an href. This locks the degradation
// contract so a future renderer refactor cannot silently reintroduce a dead link.
const result = renderTranscriptionBody('Brief an @Auguste Raddatz vom Mai', []);
// (a) the reader still sees the readable name and the surrounding sentence verbatim
expect(result).toContain('Auguste Raddatz');
expect(result).toBe('Brief an @Auguste Raddatz vom Mai');
// (b) none of the anchor artifacts leak through
expect(result).not.toContain('<a');
expect(result).not.toContain('person-mention');
expect(result).not.toContain('data-person-id');
expect(result).not.toContain('href');
});
it('skips substitution when personId is not a UUID (defense in depth)', () => {