import { describe, it, expect, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import PersonDocumentList from './PersonDocumentList.svelte'; afterEach(cleanup); const makeDoc = (overrides: Record = {}) => ({ id: 'd1', title: 'Brief an Helene', originalFilename: 'brief.pdf', documentDate: '1923-04-15', location: 'Berlin', status: 'UPLOADED' as string, contentType: 'application/pdf', thumbnailUrl: '', ...overrides }); describe('PersonDocumentList', () => { it('renders the heading and a count badge', async () => { render(PersonDocumentList, { props: { documents: [makeDoc()], heading: 'Gesendet', emptyMessage: 'Keine Dokumente' } }); await expect.element(page.getByRole('heading', { name: /gesendet/i })).toBeVisible(); await expect.element(page.getByText('1', { exact: true })).toBeVisible(); }); it('renders the empty message when documents is an empty array', async () => { render(PersonDocumentList, { props: { documents: [], heading: 'Empfangen', emptyMessage: 'Es liegen keine Dokumente vor.' } }); await expect.element(page.getByText('Es liegen keine Dokumente vor.')).toBeVisible(); }); it('hides the year range when no document has a date', async () => { render(PersonDocumentList, { props: { documents: [makeDoc({ documentDate: null })], heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByText(/^\d{4}\s*–\s*\d{4}$/)).not.toBeInTheDocument(); }); it('shows a single year when all documents fall in the same year', async () => { render(PersonDocumentList, { props: { documents: [ makeDoc({ documentDate: '1923-01-01' }), makeDoc({ id: 'd2', documentDate: '1923-12-30' }) ], heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByText('1923', { exact: true })).toBeVisible(); }); it('shows a min–max range when documents span multiple years', async () => { render(PersonDocumentList, { props: { documents: [ makeDoc({ id: 'd1', documentDate: '1899-01-01' }), makeDoc({ id: 'd2', documentDate: '1923-12-31' }) ], heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByText('1899 – 1923')).toBeVisible(); }); it('does not render the sort toggle when only one document is present', async () => { render(PersonDocumentList, { props: { documents: [makeDoc()], heading: 'X', emptyMessage: 'X' } }); await expect .element(page.getByRole('button', { name: /neueste zuerst|älteste zuerst/i })) .not.toBeInTheDocument(); }); it('renders the sort toggle when at least two documents are present', async () => { render(PersonDocumentList, { props: { documents: [makeDoc({ id: 'd1' }), makeDoc({ id: 'd2', documentDate: '1900-01-01' })], heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByRole('button', { name: /neueste zuerst/i })).toBeVisible(); }); it('toggles the sort direction label when the sort button is clicked', async () => { render(PersonDocumentList, { props: { documents: [makeDoc({ id: 'd1' }), makeDoc({ id: 'd2', documentDate: '1900-01-01' })], heading: 'X', emptyMessage: 'X' } }); await page.getByRole('button', { name: /neueste zuerst/i }).click(); await expect.element(page.getByRole('button', { name: /älteste zuerst/i })).toBeVisible(); }); it('caps the visible documents at the preview limit and exposes a "show more" button', async () => { const docs = Array.from({ length: 8 }, (_, i) => makeDoc({ id: `d${i}`, title: `Brief ${i + 1}` }) ); render(PersonDocumentList, { props: { documents: docs, heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByText('Brief 1')).toBeVisible(); await expect.element(page.getByText('Brief 6')).not.toBeInTheDocument(); await expect.element(page.getByRole('button', { name: /weitere anzeigen/i })).toBeVisible(); }); it('expands the list to all documents when the "show more" button is clicked', async () => { const docs = Array.from({ length: 8 }, (_, i) => makeDoc({ id: `d${i}`, title: `Brief ${i + 1}` }) ); render(PersonDocumentList, { props: { documents: docs, heading: 'X', emptyMessage: 'X' } }); await page.getByRole('button', { name: /weitere anzeigen/i }).click(); await expect.element(page.getByText('Brief 6')).toBeVisible(); }); it('falls back to the originalFilename when title is missing', async () => { render(PersonDocumentList, { props: { documents: [makeDoc({ title: null, originalFilename: 'untitled.pdf' })], heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByText('untitled.pdf')).toBeVisible(); }); it('renders "Kein Datum" when documentDate is missing', async () => { render(PersonDocumentList, { props: { documents: [makeDoc({ documentDate: null })], heading: 'X', emptyMessage: 'X' } }); await expect.element(page.getByText('Kein Datum')).toBeVisible(); }); it('omits the location separator when location is null', async () => { render(PersonDocumentList, { props: { documents: [makeDoc({ location: null })], heading: 'X', emptyMessage: 'X' } }); const meta = document.querySelector('.font-sans.text-\\[11px\\]'); expect(meta?.textContent ?? '').not.toMatch(/·/); }); });