import { describe, it, expect, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import GeschichtenCard from './GeschichtenCard.svelte'; afterEach(cleanup); const makeGeschichte = (overrides: Record = {}) => ({ id: 'g1', title: 'Reise nach Berlin', body: '

Brief text

', publishedAt: '2026-04-15T10:00:00Z', author: { firstName: 'Anna', lastName: 'Schmidt', email: 'a@b' } as unknown, ...overrides }); const baseProps = (overrides: Record = {}) => ({ geschichten: [] as ReturnType[], personId: 'p-1', personName: 'Anna Schmidt', canWrite: false, ...overrides }); describe('GeschichtenCard', () => { it('renders nothing when geschichten is empty', async () => { render(GeschichtenCard, { props: baseProps() }); expect(document.querySelector('section')).toBeNull(); }); it('renders the section when at least one geschichte is present', async () => { render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()] }) }); await expect.element(page.getByRole('heading', { name: /geschichten/i })).toBeVisible(); }); it('shows the write-action link when canWrite is true', async () => { render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()], canWrite: true }) }); await expect .element(page.getByRole('link', { name: /geschichte schreiben/i })) .toHaveAttribute('href', '/geschichten/new?personId=p-1'); }); it('hides the write-action link when canWrite is false', async () => { render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()] }) }); await expect .element(page.getByRole('link', { name: /geschichte schreiben/i })) .not.toBeInTheDocument(); }); it('limits visible geschichten to 3', async () => { const geschichten = Array.from({ length: 5 }, (_, i) => makeGeschichte({ id: `g${i}`, title: `Geschichte ${i + 1}` }) ); render(GeschichtenCard, { props: baseProps({ geschichten }) }); await expect.element(page.getByText('Geschichte 1')).toBeVisible(); await expect.element(page.getByText('Geschichte 3')).toBeVisible(); await expect.element(page.getByText('Geschichte 4')).not.toBeInTheDocument(); }); it('renders the show-all link in the footer when there are 3 or more', async () => { const geschichten = Array.from({ length: 3 }, (_, i) => makeGeschichte({ id: `g${i}`, title: `g${i}` }) ); render(GeschichtenCard, { props: baseProps({ geschichten }) }); await expect .element(page.getByRole('link', { name: /alle geschichten zu anna schmidt/i })) .toHaveAttribute('href', '/geschichten?personId=p-1'); }); it('hides the show-all footer when fewer than 3 geschichten', async () => { render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte({ id: 'g1' }), makeGeschichte({ id: 'g2', title: 'Two' })] }) }); await expect .element(page.getByRole('link', { name: /alle geschichten zu/i })) .not.toBeInTheDocument(); }); it('renders the author full name when both first and last names are set', async () => { render(GeschichtenCard, { props: baseProps({ geschichten: [makeGeschichte()] }) }); await expect.element(page.getByText(/Anna Schmidt/)).toBeVisible(); }); it('falls back to author email when no name', async () => { render(GeschichtenCard, { props: baseProps({ geschichten: [ makeGeschichte({ author: { firstName: undefined, lastName: undefined, email: 'fallback@x' } }) ] }) }); await expect.element(page.getByText(/fallback@x/)).toBeVisible(); }); });