import { afterEach, describe, expect, it, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page, userEvent } from 'vitest/browser'; import { m } from '$lib/paraglide/messages.js'; import { getErrorMessage } from '$lib/shared/errors'; vi.mock('$app/navigation', () => ({ goto: vi.fn() })); const { default: JourneyCreate } = await import('./JourneyCreate.svelte'); afterEach(() => { cleanup(); vi.unstubAllGlobals(); }); describe('JourneyCreate — failure path', () => { it('renders the mapped error message when POST /api/geschichten fails with a code', async () => { vi.stubGlobal( 'fetch', vi.fn().mockResolvedValue({ ok: false, json: vi.fn().mockResolvedValue({ code: 'VALIDATION_ERROR' }) }) ); render(JourneyCreate, {}); await userEvent.fill( page.getByRole('textbox', { name: m.journey_title_aria_label() }), 'Meine Lesereise' ); await userEvent.click(page.getByRole('button', { name: m.journey_create_submit() })); const alert = page.getByRole('alert'); await expect.element(alert).toBeInTheDocument(); await expect.element(alert).toHaveTextContent(getErrorMessage('VALIDATION_ERROR')); }); it('navigates to the edit page on success', async () => { const { goto } = await import('$app/navigation'); vi.mocked(goto).mockClear(); vi.stubGlobal( 'fetch', vi.fn().mockResolvedValue({ ok: true, json: vi.fn().mockResolvedValue({ id: 'g-new' }) }) ); render(JourneyCreate, {}); await userEvent.fill( page.getByRole('textbox', { name: m.journey_title_aria_label() }), 'Meine Lesereise' ); await userEvent.click(page.getByRole('button', { name: m.journey_create_submit() })); await vi.waitFor(() => { expect(goto).toHaveBeenCalledWith('/geschichten/g-new/edit'); }); }); it('shows an error alert when the network request rejects (no crash)', async () => { vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new TypeError('network down'))); const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}); render(JourneyCreate, {}); await userEvent.fill( page.getByRole('textbox', { name: m.journey_title_aria_label() }), 'Meine Lesereise' ); await userEvent.click(page.getByRole('button', { name: m.journey_create_submit() })); await expect.element(page.getByRole('alert')).toBeInTheDocument(); consoleError.mockRestore(); }); it('has an accessible label on the title input', async () => { vi.stubGlobal('fetch', vi.fn()); render(JourneyCreate, {}); await expect .element(page.getByRole('textbox', { name: m.journey_title_aria_label() })) .toBeInTheDocument(); }); });