Completes Phase 2a: geschichten/[id], persons/[id]/edit and admin/tags/[id] page specs now provide a real createConfirmService() via render context instead of mocking confirm.svelte. Zero confirm.svelte vi.mocks remain across the client suite (AC#4). Part of #560. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
171 lines
5.5 KiB
TypeScript
171 lines
5.5 KiB
TypeScript
import { describe, it, expect, afterEach } from 'vitest';
|
|
import { cleanup, render } from 'vitest-browser-svelte';
|
|
import { page } from 'vitest/browser';
|
|
|
|
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
|
|
|
|
const { default: GeschichtePage } = await import('./+page.svelte');
|
|
|
|
afterEach(cleanup);
|
|
|
|
const baseGeschichte = (overrides: Record<string, unknown> = {}) => ({
|
|
id: 'g1',
|
|
title: 'Die Reise nach Berlin',
|
|
body: '<p>Im Jahr 1923 fuhr Helene...</p>',
|
|
publishedAt: '2026-04-15T10:00:00Z' as string | null,
|
|
author: { firstName: 'Anna', lastName: 'Schmidt', email: 'anna@example.com' } as {
|
|
firstName?: string;
|
|
lastName?: string;
|
|
email: string;
|
|
} | null,
|
|
persons: [] as { id: string; displayName: string }[],
|
|
documents: [] as { id: string; title: string; documentDate?: string | null }[],
|
|
...overrides
|
|
});
|
|
|
|
const baseData = (overrides: Record<string, unknown> = {}) => ({
|
|
geschichte: baseGeschichte(),
|
|
canBlogWrite: false,
|
|
...overrides
|
|
});
|
|
|
|
describe('geschichten/[id] page', () => {
|
|
it('renders the geschichte title as the level-1 heading', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData() }
|
|
});
|
|
|
|
await expect
|
|
.element(page.getByRole('heading', { level: 1, name: /reise nach berlin/i }))
|
|
.toBeVisible();
|
|
});
|
|
|
|
it('renders the author full name from firstName + lastName', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData() }
|
|
});
|
|
|
|
await expect.element(page.getByText(/Anna Schmidt/)).toBeVisible();
|
|
});
|
|
|
|
it('falls back to author email when no name is set', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: {
|
|
data: baseData({
|
|
geschichte: baseGeschichte({
|
|
author: { firstName: undefined, lastName: undefined, email: 'fallback@example.com' }
|
|
})
|
|
})
|
|
}
|
|
});
|
|
|
|
await expect.element(page.getByText(/fallback@example.com/)).toBeVisible();
|
|
});
|
|
|
|
it('renders an empty author when author is null', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData({ geschichte: baseGeschichte({ author: null }) }) }
|
|
});
|
|
|
|
await expect.element(page.getByRole('heading', { level: 1 })).toBeVisible();
|
|
});
|
|
|
|
it('renders the publishedAt date suffix when publishedAt is set', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData() }
|
|
});
|
|
|
|
await expect.element(page.getByText(/veröffentlicht am/i)).toBeVisible();
|
|
});
|
|
|
|
it('omits the publishedAt suffix when publishedAt is null', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData({ geschichte: baseGeschichte({ publishedAt: null }) }) }
|
|
});
|
|
|
|
await expect.element(page.getByText(/veröffentlicht am/i)).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('omits the persons section when there are no linked persons', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData() }
|
|
});
|
|
|
|
await expect.element(page.getByText(/Personen in dieser Geschichte/i)).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('renders the persons section when there are linked persons', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: {
|
|
data: baseData({
|
|
geschichte: baseGeschichte({
|
|
persons: [
|
|
{ id: 'p1', displayName: 'Helene Schmidt' },
|
|
{ id: 'p2', displayName: 'Karl Müller' }
|
|
]
|
|
})
|
|
})
|
|
}
|
|
});
|
|
|
|
await expect.element(page.getByText('Personen in dieser Geschichte')).toBeVisible();
|
|
await expect.element(page.getByText('Helene Schmidt')).toBeVisible();
|
|
await expect.element(page.getByText('Karl Müller')).toBeVisible();
|
|
});
|
|
|
|
it('omits the documents section when there are no linked documents', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData() }
|
|
});
|
|
|
|
await expect.element(page.getByText('Erwähnte Dokumente')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('renders the documents section when there are linked documents', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: {
|
|
data: baseData({
|
|
geschichte: baseGeschichte({
|
|
documents: [{ id: 'd1', title: 'Brief 1923', documentDate: '1923-04-15' }]
|
|
})
|
|
})
|
|
}
|
|
});
|
|
|
|
await expect.element(page.getByText('Erwähnte Dokumente')).toBeVisible();
|
|
await expect.element(page.getByText('Brief 1923')).toBeVisible();
|
|
});
|
|
|
|
it('renders edit and delete actions when canBlogWrite is true', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData({ canBlogWrite: true }) }
|
|
});
|
|
|
|
await expect
|
|
.element(page.getByRole('link', { name: /bearbeiten/i }))
|
|
.toHaveAttribute('href', '/geschichten/g1/edit');
|
|
await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible();
|
|
});
|
|
|
|
it('hides edit and delete actions when canBlogWrite is false', async () => {
|
|
render(GeschichtePage, {
|
|
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
|
|
props: { data: baseData({ canBlogWrite: false }) }
|
|
});
|
|
|
|
await expect.element(page.getByRole('link', { name: /bearbeiten/i })).not.toBeInTheDocument();
|
|
await expect.element(page.getByRole('button', { name: /löschen/i })).not.toBeInTheDocument();
|
|
});
|
|
});
|