From c80c66a5e1650a9602c54a12a3382216fc59c889 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sat, 9 May 2026 21:07:12 +0200 Subject: [PATCH] test: cover geschichten/new and geschichten/[id]/edit page renders Both pages embed GeschichteEditor (TipTap-based). The tests assert heading, BackButton presence, no-error default, editor inputs render, and prop pass-through (initialPersons / initialDocuments). $app/navigation is mocked because GeschichteEditor pulls beforeNavigate transitively. Refs #496. Co-Authored-By: Claude Sonnet 4.6 --- .../geschichten/[id]/edit/page.svelte.test.ts | 63 +++++++++++++++++ .../geschichten/new/page.svelte.test.ts | 70 +++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 frontend/src/routes/geschichten/[id]/edit/page.svelte.test.ts create mode 100644 frontend/src/routes/geschichten/new/page.svelte.test.ts diff --git a/frontend/src/routes/geschichten/[id]/edit/page.svelte.test.ts b/frontend/src/routes/geschichten/[id]/edit/page.svelte.test.ts new file mode 100644 index 00000000..5376edb6 --- /dev/null +++ b/frontend/src/routes/geschichten/[id]/edit/page.svelte.test.ts @@ -0,0 +1,63 @@ +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: GeschichtenEditPage } = await import('./+page.svelte'); + +afterEach(cleanup); + +const baseData = (overrides: Record = {}) => ({ + geschichte: { + id: 'g1', + title: 'Die Reise nach Berlin', + body: '

Im Jahr 1923...

', + status: 'PUBLISHED' as 'DRAFT' | 'PUBLISHED', + persons: [], + documents: [] + }, + ...overrides +}); + +describe('geschichten/[id]/edit page', () => { + it('renders the geschichte title in the heading', async () => { + render(GeschichtenEditPage, { props: { data: baseData() } }); + + await expect + .element(page.getByRole('heading', { level: 1, name: /reise nach berlin/i })) + .toBeVisible(); + }); + + it('renders a button (BackButton component)', async () => { + render(GeschichtenEditPage, { props: { data: baseData() } }); + + const buttons = document.querySelectorAll('button'); + expect(buttons.length).toBeGreaterThan(0); + }); + + it('does not render an error alert by default', async () => { + render(GeschichtenEditPage, { props: { data: baseData() } }); + + expect(document.querySelector('[role="alert"]')).toBeNull(); + }); + + it('renders the GeschichteEditor with form inputs', async () => { + render(GeschichtenEditPage, { props: { data: baseData() } }); + + const inputs = document.querySelectorAll('input, textarea, [contenteditable]'); + expect(inputs.length).toBeGreaterThan(0); + }); +}); diff --git a/frontend/src/routes/geschichten/new/page.svelte.test.ts b/frontend/src/routes/geschichten/new/page.svelte.test.ts new file mode 100644 index 00000000..7e10a727 --- /dev/null +++ b/frontend/src/routes/geschichten/new/page.svelte.test.ts @@ -0,0 +1,70 @@ +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 = { + initialPersons: [] as { id: string; displayName: string }[], + initialDocuments: [] as { id: string; title: string }[] +}; + +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 child component', async () => { + render(GeschichtenNewPage, { props: { data: baseData } }); + + // 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 and initialDocuments through to the editor', async () => { + render(GeschichtenNewPage, { + props: { + data: { + initialPersons: [{ id: 'p1', displayName: 'Anna Schmidt' }], + initialDocuments: [{ id: 'd1', title: 'Brief 1923' }] + } + } + }); + + // Both should appear somewhere in the rendered editor + await expect.element(page.getByText('Anna Schmidt')).toBeVisible(); + await expect.element(page.getByText('Brief 1923')).toBeVisible(); + }); +});