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
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
138 lines
4.4 KiB
TypeScript
138 lines
4.4 KiB
TypeScript
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();
|
||
});
|
||
});
|