Files
familienarchiv/frontend/src/routes/page.svelte.spec.ts
Marcel 43d36c898c
Some checks failed
CI / Unit & Component Tests (push) Failing after 4m46s
CI / OCR Service Tests (push) Successful in 52s
CI / Backend Unit Tests (push) Failing after 3m32s
CI / Unit & Component Tests (pull_request) Failing after 4m0s
CI / OCR Service Tests (pull_request) Successful in 43s
CI / Backend Unit Tests (pull_request) Failing after 3m32s
feat(dashboard): wire ReaderHeaderBar, grid content row, delete ReaderStatsStrip (#483)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 17:13:00 +02:00

138 lines
4.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();
});
});