test: inject real ConfirmService via context (batch 2/2)

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>
This commit is contained in:
Marcel
2026-06-02 20:01:28 +02:00
committed by marcel
parent b1b8505b93
commit 29015ee864
3 changed files with 78 additions and 26 deletions

View File

@@ -10,9 +10,7 @@ vi.mock('$app/state', () => ({
}
}));
vi.mock('$lib/shared/services/confirm.svelte', () => ({
getConfirmService: () => ({ confirm: async () => false })
}));
import { createConfirmService, CONFIRM_KEY } from '$lib/shared/services/confirm.svelte.js';
vi.mock('$app/navigation', () => ({
beforeNavigate: () => {},
@@ -49,13 +47,17 @@ const baseData = (overrides: Record<string, unknown> = {}) => ({
describe('admin/tags/[id] page', () => {
it('renders the edit heading with the tag name', async () => {
render(AdminTagEditPage, { props: { data: baseData(), form: undefined } });
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData(), form: undefined }
});
await expect.element(page.getByRole('heading', { name: /personen/i })).toBeVisible();
});
it('hydrates the name input from data.tag.name', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData({ tag: baseTag({ name: 'Reisen' }) }), form: undefined }
});
@@ -64,14 +66,20 @@ describe('admin/tags/[id] page', () => {
});
it('renders the color picker for top-level tags (no parentId)', async () => {
render(AdminTagEditPage, { props: { data: baseData(), form: undefined } });
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData(), form: undefined }
});
const colorPicker = document.querySelector('[data-testid="color-picker"]');
expect(colorPicker).not.toBeNull();
});
it('renders one color swatch per palette entry', async () => {
render(AdminTagEditPage, { props: { data: baseData(), form: undefined } });
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData(), form: undefined }
});
const swatches = document.querySelectorAll('[data-testid^="color-swatch-"]');
expect(swatches.length).toBeGreaterThanOrEqual(10);
@@ -79,6 +87,7 @@ describe('admin/tags/[id] page', () => {
it('marks the active color swatch as aria-pressed', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData({ tag: baseTag({ color: 'amber' }) }), form: undefined }
});
@@ -88,6 +97,7 @@ describe('admin/tags/[id] page', () => {
it('shows the form-success banner when form.success is true', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData(), form: { success: true } }
});
@@ -97,6 +107,7 @@ describe('admin/tags/[id] page', () => {
it('shows the form-error banner when form.error is set', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData(), form: { error: 'Tag name already in use' } }
});
@@ -106,6 +117,7 @@ describe('admin/tags/[id] page', () => {
it('shows the merge-success banner when data.mergeSuccess is set', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData({ mergeSuccess: 'old-id' }), form: undefined }
});
@@ -115,6 +127,7 @@ describe('admin/tags/[id] page', () => {
it('hides the color picker for child tags (parentId set)', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: {
data: baseData({ tag: baseTag({ parentId: 't-parent' }) }),
form: undefined
@@ -126,7 +139,10 @@ describe('admin/tags/[id] page', () => {
});
it('does not show form-success banner when form is undefined', async () => {
render(AdminTagEditPage, { props: { data: baseData(), form: undefined } });
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData(), form: undefined }
});
const banners = document.querySelectorAll('.bg-green-50');
// Some other green elements may exist, but the form-success specifically
@@ -139,6 +155,7 @@ describe('admin/tags/[id] page', () => {
it('hides the merge-success banner when mergeSuccess is null', async () => {
render(AdminTagEditPage, {
context: new Map([[CONFIRM_KEY, createConfirmService()]]),
props: { data: baseData({ mergeSuccess: null }), form: undefined }
});