import { afterEach, describe, expect, it, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import Page from './+page.svelte'; vi.mock('$app/navigation', () => ({ goto: vi.fn() })); afterEach(cleanup); // ─── Test data ──────────────────────────────────────────────────────────────── const baseData = { user: undefined, canWrite: true, canAnnotate: false, documents: [], initialValues: { senderName: '', receiverName: '' }, filters: { senderId: '', receiverId: '', from: '', to: '', dir: 'DESC' as const } }; const withPersons = { ...baseData, filters: { ...baseData.filters, senderId: 'p1', receiverId: 'p2' } }; const makeDoc = (overrides: Record = {}) => ({ id: 'd1', title: 'Testbrief', originalFilename: 'testbrief.pdf', status: 'UPLOADED' as const, documentDate: '1923-04-12', location: 'Berlin', sender: { id: 'p1', firstName: 'Hans', lastName: 'Müller' }, receivers: [{ id: 'p2', firstName: 'Anna', lastName: 'Schmidt' }], tags: [], transcription: undefined, filePath: undefined, createdAt: '1923-04-12T00:00:00Z', updatedAt: '1923-04-12T00:00:00Z', ...overrides }); const withDocs = { ...withPersons, documents: [makeDoc()] }; // ─── Empty state ────────────────────────────────────────────────────────────── describe('Conversations page – empty state', () => { it('shows the "select two persons" prompt when no persons are selected', async () => { render(Page, { data: baseData }); await expect.element(page.getByText(/Wählen Sie zwei Personen aus/i)).toBeInTheDocument(); }); it('hides the swap button when no persons are selected', async () => { render(Page, { data: baseData }); // Button is always in the DOM (holds grid column width on desktop) but made invisible await expect.element(page.getByTestId('conv-swap-btn')).toHaveClass('invisible'); }); it('does not show the new document link when no persons are selected', async () => { render(Page, { data: baseData }); await expect.element(page.getByTestId('conv-new-doc-link')).not.toBeInTheDocument(); }); }); // ─── No results ─────────────────────────────────────────────────────────────── describe('Conversations page – no results', () => { it('shows "no documents found" when both persons are selected but there are no documents', async () => { render(Page, { data: withPersons }); await expect.element(page.getByText(/Keine Dokumente gefunden/i)).toBeInTheDocument(); }); }); // ─── Swap button ────────────────────────────────────────────────────────────── describe('Conversations page – swap button', () => { it('shows the swap button when both persons are selected', async () => { render(Page, { data: withPersons }); await expect.element(page.getByTestId('conv-swap-btn')).not.toHaveClass('invisible'); }); it('calls goto with swapped sender and receiver when clicked', async () => { const { goto } = await import('$app/navigation'); vi.mocked(goto).mockClear(); render(Page, { data: withPersons }); document.querySelector('[data-testid="conv-swap-btn"]')!.click(); expect(goto).toHaveBeenCalledWith(expect.stringContaining('senderId=p2'), expect.anything()); expect(goto).toHaveBeenCalledWith(expect.stringContaining('receiverId=p1'), expect.anything()); }); }); // ─── Summary ────────────────────────────────────────────────────────────────── describe('Conversations page – summary', () => { it('shows document count and year range when documents are loaded', async () => { const data = { ...withPersons, documents: [ makeDoc({ documentDate: '1923-04-12' }), makeDoc({ id: 'd2', documentDate: '1965-08-03' }) ] }; render(Page, { data }); const summary = page.getByTestId('conv-summary'); await expect.element(summary).toHaveTextContent('2'); await expect.element(summary).toHaveTextContent('1923'); await expect.element(summary).toHaveTextContent('1965'); }); }); // ─── Year dividers ──────────────────────────────────────────────────────────── describe('Conversations page – year dividers', () => { it('renders a year divider for the first document', async () => { render(Page, { data: withDocs }); await expect.element(page.getByTestId('year-divider').first()).toHaveTextContent('1923'); }); it('renders a divider for each new year in the document list', async () => { const data = { ...withPersons, documents: [ makeDoc({ documentDate: '1923-04-12' }), makeDoc({ id: 'd2', documentDate: '1965-08-03' }) ] }; render(Page, { data }); await expect.element(page.getByTestId('year-divider').first()).toHaveTextContent('1923'); await expect.element(page.getByTestId('year-divider').nth(1)).toHaveTextContent('1965'); }); it('does not render a second divider for documents from the same year', async () => { const data = { ...withPersons, documents: [ makeDoc({ documentDate: '1923-04-12' }), makeDoc({ id: 'd2', documentDate: '1923-09-01' }) ] }; render(Page, { data }); // Only one divider for 1923; 1965 divider should not appear await expect.element(page.getByTestId('year-divider').first()).toHaveTextContent('1923'); await expect.element(page.getByTestId('year-divider').nth(1)).not.toBeInTheDocument(); }); }); // ─── New document link ──────────────────────────────────────────────────────── describe('Conversations page – new document link', () => { it('shows the link with correct href for a write user', async () => { render(Page, { data: { ...withDocs, canWrite: true } }); const link = page.getByTestId('conv-new-doc-link'); await expect.element(link).toBeInTheDocument(); await expect.element(link).toHaveAttribute('href', '/documents/new?senderId=p1&receiverId=p2'); }); it('hides the link for a read-only user', async () => { render(Page, { data: { ...withDocs, canWrite: false } }); await expect.element(page.getByTestId('conv-new-doc-link')).not.toBeInTheDocument(); }); });