From a08d537fd6f73d0cac797f2f3b03efc075a6da7f Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 10 May 2026 02:11:38 +0200 Subject: [PATCH] test(dashboard): cover ReaderPersonChips branches Section landmark with aria-label, empty placeholder, per-person chip with link to detail, document-count chip visibility branch, displayName vs lastName fallback, all-persons footer link. 7 tests, ~16 branches. Refs #496. Co-Authored-By: Claude Sonnet 4.6 --- .../ReaderPersonChips.svelte.test.ts | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.test.ts diff --git a/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.test.ts b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.test.ts new file mode 100644 index 00000000..246c9831 --- /dev/null +++ b/frontend/src/lib/shared/dashboard/ReaderPersonChips.svelte.test.ts @@ -0,0 +1,80 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; +import ReaderPersonChips from './ReaderPersonChips.svelte'; + +afterEach(cleanup); + +const makePerson = (overrides: Record = {}) => ({ + id: 'p1', + displayName: 'Anna Schmidt', + lastName: 'Schmidt', + documentCount: 5, + ...overrides +}); + +describe('ReaderPersonChips', () => { + it('renders the section with the persons heading via aria-label', async () => { + render(ReaderPersonChips, { props: { persons: [] } }); + + await expect.element(page.getByRole('region', { name: /personen/i })).toBeVisible(); + }); + + it('renders the no-persons placeholder when persons is empty', async () => { + render(ReaderPersonChips, { props: { persons: [] } }); + + await expect.element(page.getByText('Noch keine Personen im Archiv.')).toBeVisible(); + }); + + it('renders one chip per person with link to person detail', async () => { + render(ReaderPersonChips, { + props: { + persons: [ + makePerson({ id: 'p1', displayName: 'Anna Schmidt' }), + makePerson({ id: 'p2', displayName: 'Bert Meier' }) + ] + } + }); + + await expect + .element(page.getByRole('link', { name: /anna schmidt/i })) + .toHaveAttribute('href', '/persons/p1'); + await expect + .element(page.getByRole('link', { name: /bert meier/i })) + .toHaveAttribute('href', '/persons/p2'); + }); + + it('renders document count chip when documentCount > 0', async () => { + render(ReaderPersonChips, { + props: { persons: [makePerson({ documentCount: 7 })] } + }); + + await expect.element(page.getByText('7')).toBeVisible(); + }); + + it('omits document count chip when documentCount is 0', async () => { + render(ReaderPersonChips, { + props: { persons: [makePerson({ documentCount: 0 })] } + }); + + await expect.element(page.getByText('0')).not.toBeInTheDocument(); + }); + + it('falls back to lastName when displayName is missing', async () => { + render(ReaderPersonChips, { + props: { + persons: [makePerson({ displayName: null, lastName: 'Schmidt' })] + } + }); + + await expect.element(page.getByRole('link', { name: /schmidt/i })).toBeVisible(); + }); + + it('renders the all-persons footer link', async () => { + render(ReaderPersonChips, { props: { persons: [makePerson()] } }); + + await expect + .element(page.getByRole('link', { name: /alle personen/i })) + .toHaveAttribute('href', '/persons'); + }); +});