import { describe, it, expect, vi, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; vi.mock('$app/navigation', () => ({ beforeNavigate: () => {}, afterNavigate: () => {}, goto: vi.fn(), invalidate: vi.fn(), invalidateAll: vi.fn(), preloadCode: vi.fn(), preloadData: vi.fn(), pushState: vi.fn(), replaceState: vi.fn(), disableScrollHandling: vi.fn(), onNavigate: () => () => {} })); const { default: GeschichtenNewPage } = await import('./+page.svelte'); afterEach(cleanup); const baseData = (overrides: Record = {}) => ({ initialPersons: [] as { id: string; displayName: string }[], selectedType: 'STORY' as 'STORY' | 'JOURNEY' | null, ...overrides }); describe('geschichten/new page', () => { it('renders the page heading', async () => { render(GeschichtenNewPage, { props: { data: baseData() } }); await expect.element(page.getByRole('heading', { level: 1 })).toBeVisible(); }); it('renders a button (BackButton component)', async () => { render(GeschichtenNewPage, { props: { data: baseData() } }); const buttons = document.querySelectorAll('button'); expect(buttons.length).toBeGreaterThan(0); }); it('does not render an error banner by default', async () => { render(GeschichtenNewPage, { props: { data: baseData() } }); expect(document.querySelector('[role="alert"]')).toBeNull(); }); it('renders the GeschichteEditor when selectedType is STORY', async () => { render(GeschichtenNewPage, { props: { data: baseData({ selectedType: 'STORY' }) } }); // Editor renders inputs/textarea — verify at least one form input is present const inputs = document.querySelectorAll('input, textarea'); expect(inputs.length).toBeGreaterThan(0); }); it('passes initialPersons through to the editor', async () => { render(GeschichtenNewPage, { props: { data: baseData({ selectedType: 'STORY', initialPersons: [{ id: 'p1', displayName: 'Anna Schmidt' }] }) } }); await expect.element(page.getByText('Anna Schmidt')).toBeVisible(); }); it('shows TypeSelector radiogroup when selectedType is null', async () => { render(GeschichtenNewPage, { props: { data: baseData({ selectedType: null }) } }); await expect.element(page.getByRole('radiogroup')).toBeVisible(); }); it('shows JourneyCreate form when selectedType is JOURNEY', async () => { render(GeschichtenNewPage, { props: { data: baseData({ selectedType: 'JOURNEY' }) } }); await expect.element(page.getByRole('button', { name: /Lesereise erstellen/i })).toBeVisible(); }); it('JOURNEY create form offers a return-to-selection link', async () => { render(GeschichtenNewPage, { props: { data: baseData({ selectedType: 'JOURNEY' }) } }); const backLink = page.getByRole('link', { name: /andere Auswahl/i }); await expect.element(backLink).toBeVisible(); await expect.element(backLink).toHaveAttribute('href', '/geschichten/new'); }); it('TypeSelector Weiter calls goto with ?type=STORY on STORY selection', async () => { const { goto } = await import('$app/navigation'); vi.mocked(goto).mockClear(); render(GeschichtenNewPage, { props: { data: baseData({ selectedType: null }) } }); // Select STORY const storyCard = page.getByRole('radio', { name: /Geschichte/i }); await storyCard.click(); // Click Weiter const weiter = page.getByRole('button', { name: /Weiter/i }); await weiter.click(); expect(goto).toHaveBeenCalledWith('/geschichten/new?type=STORY'); }); });