import { describe, it, expect, vi, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; vi.mock('$app/navigation', () => ({ beforeNavigate: () => {}, afterNavigate: () => {}, goto: vi.fn(), invalidate: vi.fn(), invalidateAll: vi.fn(), preloadCode: vi.fn(), preloadData: vi.fn(), pushState: vi.fn(), replaceState: vi.fn(), disableScrollHandling: vi.fn(), onNavigate: () => () => {} })); const { default: AdminGroupNewPage } = await import('./+page.svelte'); afterEach(cleanup); describe('admin/groups/new page', () => { it('renders the page heading', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); await expect.element(page.getByRole('heading', { name: /neue gruppe anlegen/i })).toBeVisible(); }); it('renders all four standard permission checkboxes', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const standardPerms = ['READ_ALL', 'ANNOTATE_ALL', 'WRITE_ALL', 'BLOG_WRITE']; for (const perm of standardPerms) { const checkbox = document.querySelector(`input[name="permissions"][value="${perm}"]`); expect(checkbox).not.toBeNull(); } }); it('renders all four administrative permission checkboxes', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const adminPerms = ['ADMIN', 'ADMIN_USER', 'ADMIN_TAG', 'ADMIN_PERMISSION']; for (const perm of adminPerms) { const checkbox = document.querySelector(`input[name="permissions"][value="${perm}"]`); expect(checkbox).not.toBeNull(); } }); it('shows the form error banner when form.error is set', async () => { render(AdminGroupNewPage, { props: { form: { error: 'Name is required' } } }); await expect.element(page.getByText('Name is required')).toBeVisible(); }); it('does not show the form error banner when form is undefined', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); await expect.element(page.getByText(/^Name is required$/)).not.toBeInTheDocument(); }); it('renders cancel link to /admin/groups', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const cancelLink = document.querySelector('a[href="/admin/groups"]'); expect(cancelLink).not.toBeNull(); }); it('renders the submit button labelled "Erstellen" tied to the form via the form attribute', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const submit = (await page .getByRole('button', { name: /erstellen/i }) .element()) as HTMLButtonElement; expect(submit.getAttribute('form')).toBe('new-group-form'); }); it('renders the name input with placeholder text', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const nameInput = document.querySelector('input[name="name"]') as HTMLInputElement; expect(nameInput.placeholder).not.toBe(''); expect(nameInput.required).toBe(true); }); it('does not show the unsaved-warning banner before any input', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); // The unsaved warning specifically contains the German phrase expect(document.body.textContent).not.toMatch(/ungespeicherte/i); }); it('keeps the form mounted after an input event (oninput handler does not unmount)', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const form = document.querySelector('form') as HTMLFormElement; expect(form).not.toBeNull(); form.dispatchEvent(new Event('input', { bubbles: true })); expect(document.querySelector('form')).not.toBeNull(); }); it('hides the form error banner when form is undefined (already covered, branch 2)', async () => { render(AdminGroupNewPage, { props: { form: undefined } }); const banner = document.querySelector('.bg-red-50'); expect(banner).toBeNull(); }); });