feat(search): render title highlights and transcription snippets in DocumentList

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-15 18:34:14 +02:00
committed by marcel
parent 6cffd36b22
commit 60dc73ba04
2 changed files with 100 additions and 3 deletions

View File

@@ -12,11 +12,16 @@ const baseProps = {
canWrite: false,
error: null,
total: 0,
q: ''
q: '',
matchData: {} as Record<
string,
import('$lib/generated/api').components['schemas']['SearchMatchData']
>
};
type DocOverrides = {
id?: string;
title?: string;
documentDate?: string | null;
sender?: { firstName?: string | null; lastName: string; displayName: string } | null;
receivers?: { firstName?: string | null; lastName: string; displayName: string }[];
@@ -115,3 +120,74 @@ describe('DocumentList group headers', () => {
await expect.element(links.nth(1)).toBeInTheDocument();
});
});
// ─── Match data: snippet and title highlighting ───────────────────────────────
describe('DocumentList match snippets and highlights', () => {
it('shows transcription snippet when matchData has one for the document', async () => {
const doc = makeDoc({ id: 'doc1' });
render(DocumentList, {
...baseProps,
documents: [doc],
total: 1,
matchData: {
doc1: {
transcriptionSnippet: 'Er schrieb einen langen Brief',
titleOffsets: [],
senderMatched: false,
matchedReceiverIds: [],
matchedTagIds: []
}
}
});
await expect.element(page.getByText('Er schrieb einen langen Brief')).toBeInTheDocument();
});
it('does not show snippet section when matchData has no entry for the document', async () => {
const doc = makeDoc({ id: 'doc1' });
render(DocumentList, { ...baseProps, documents: [doc], total: 1, matchData: {} });
await expect.element(page.getByTestId('search-snippet')).not.toBeInTheDocument();
});
it('renders a <mark> element when titleOffsets are present', async () => {
const doc = makeDoc({ id: 'doc1', title: 'Brief an Anna' });
render(DocumentList, {
...baseProps,
documents: [doc],
total: 1,
matchData: {
doc1: {
transcriptionSnippet: undefined,
titleOffsets: [{ start: 0, length: 5 }], // "Brief"
senderMatched: false,
matchedReceiverIds: [],
matchedTagIds: []
}
}
});
// The word "Brief" should be inside a <mark> element
const mark = page.getByRole('mark');
await expect.element(mark).toBeInTheDocument();
await expect.element(mark).toHaveTextContent('Brief');
});
it('renders title as plain text when titleOffsets is empty', async () => {
const doc = makeDoc({ id: 'doc1', title: 'Brief an Anna' });
render(DocumentList, {
...baseProps,
documents: [doc],
total: 1,
matchData: {
doc1: {
transcriptionSnippet: undefined,
titleOffsets: [],
senderMatched: false,
matchedReceiverIds: [],
matchedTagIds: []
}
}
});
await expect.element(page.getByRole('mark')).not.toBeInTheDocument();
await expect.element(page.getByText('Brief an Anna')).toBeInTheDocument();
});
});