import { afterEach, describe, expect, it, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import type { components } from '$lib/generated/api'; import Page from './+page.svelte'; type User = components['schemas']['AppUser']; afterEach(cleanup); vi.mock('$app/navigation', () => ({ goto: vi.fn(), invalidateAll: vi.fn() })); const baseUser: User = { id: 'u1', email: 'max@example.com', firstName: 'Max', lastName: '', groups: [], enabled: true, createdAt: '2024-01-01T00:00:00Z' }; const baseData = { user: baseUser, isReader: false as const, canWrite: true, canAnnotate: false, canBlogWrite: false, resumeDoc: null, pulse: null, activityFeed: [], stats: null, segmentationDocs: [], transcriptionDocs: [], readyDocs: [], weeklyStats: null, incompleteDocs: [], incompleteTotal: 0, error: null }; const readerData = { user: baseUser, isReader: true as const, canWrite: false, canAnnotate: false, canBlogWrite: false, readerStats: { totalPersons: 12, totalDocuments: 34, totalStories: 5 }, topPersons: [], recentDocs: [], recentStories: [], drafts: [], error: null }; // ─── Dashboard layout ───────────────────────────────────────────────────────── describe('Home page – dashboard layout', () => { it('does not render a search input', async () => { render(Page, { data: baseData }); const input = page.getByPlaceholder('Titel, Personen, Tags durchsuchen…'); await expect.element(input).not.toBeInTheDocument(); }); it('renders a greeting for the logged-in user', async () => { render(Page, { data: baseData }); await expect.element(page.getByRole('heading', { level: 1 })).toBeInTheDocument(); }); it('renders resume strip empty state when resumeDoc is null', async () => { render(Page, { data: baseData }); const empty = page.getByTestId('resume-strip-empty'); await expect.element(empty).toBeInTheDocument(); }); it('renders resume card when resumeDoc is provided', async () => { const resume = { documentId: 'doc-1', title: 'Geburtsurkunde', caption: 'Max · 1920', excerpt: 'Hiermit…', totalBlocks: 3, pct: 33, collaborators: [] }; render(Page, { data: { ...baseData, resumeDoc: resume } }); const strip = page.getByTestId('resume-strip'); await expect.element(strip).toBeInTheDocument(); }); it('shows drop zone when canWrite is true', async () => { render(Page, { data: { ...baseData, canWrite: true } }); await expect.element(page.getByText(/Dateien auf einmal hochladen/i)).toBeInTheDocument(); }); it('hides drop zone when canWrite is false', async () => { render(Page, { data: { ...baseData, canWrite: false } }); await expect.element(page.getByText(/Dateien auf einmal hochladen/i)).not.toBeInTheDocument(); }); }); // ─── Reader dashboard layout ────────────────────────────────────────────────── describe('Home page – reader dashboard layout', () => { it('renders reader header-bar totals when isReader is true', async () => { render(Page, { data: readerData }); await expect.element(page.getByText('34')).toBeInTheDocument(); await expect.element(page.getByText('12')).toBeInTheDocument(); await expect.element(page.getByText('5')).toBeInTheDocument(); }); it('reader branch does not render h1 heading', async () => { render(Page, { data: readerData }); const h1 = page.getByRole('heading', { level: 1 }); await expect.element(h1).not.toBeInTheDocument(); }); it('renders the recent-docs heading when isReader is true', async () => { render(Page, { data: readerData }); await expect.element(page.getByText('Zuletzt aktualisiert')).toBeInTheDocument(); }); it('hides the contributor mission control caption when isReader is true', async () => { render(Page, { data: readerData }); await expect.element(page.getByText('Offene Aufgaben')).not.toBeInTheDocument(); }); it('renders the drafts module when canBlogWrite is true', async () => { render(Page, { data: { ...readerData, canBlogWrite: true } }); await expect.element(page.getByText('Meine Entwürfe')).toBeInTheDocument(); }); it('hides the drafts module when canBlogWrite is false', async () => { render(Page, { data: readerData }); await expect.element(page.getByText('Meine Entwürfe')).not.toBeInTheDocument(); }); });