import { describe, it, expect, vi, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; vi.mock('$lib/shared/services/confirm.svelte', () => ({ getConfirmService: () => ({ confirm: async () => false }) })); const { default: AdminGroupEditPage } = await import('./+page.svelte'); afterEach(cleanup); const baseGroup = (overrides: Record = {}) => ({ id: 'g1', name: 'Familie', permissions: ['READ_ALL'] as string[], ...overrides }); describe('admin/groups/[id] page', () => { it('renders the edit heading with the group name', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } }); await expect.element(page.getByRole('heading', { name: /familie/i })).toBeVisible(); }); it('hydrates the name input from data.group.name', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup({ name: 'Admins' }) }, form: undefined } }); const input = document.querySelector('input[name="name"]') as HTMLInputElement; expect(input.value).toBe('Admins'); }); it('checks the permission checkboxes that are in data.group.permissions', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup({ permissions: ['READ_ALL', 'ADMIN_TAG'] }) }, form: undefined } }); const readAll = document.querySelector( 'input[name="permissions"][value="READ_ALL"]' ) as HTMLInputElement; const adminTag = document.querySelector( 'input[name="permissions"][value="ADMIN_TAG"]' ) as HTMLInputElement; const writeAll = document.querySelector( 'input[name="permissions"][value="WRITE_ALL"]' ) as HTMLInputElement; expect(readAll.checked).toBe(true); expect(adminTag.checked).toBe(true); expect(writeAll.checked).toBe(false); }); it('shows the success banner when form.success is true', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: { success: true } } }); await expect.element(page.getByText('Gruppe gespeichert.')).toBeVisible(); }); it('shows the error banner when form.error is set', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: { error: 'Name darf nicht leer sein.' } } }); await expect.element(page.getByText('Name darf nicht leer sein.')).toBeVisible(); }); it('renders the cancel link to /admin/groups', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } }); const links = document.querySelectorAll('a[href="/admin/groups"]'); expect(links.length).toBeGreaterThan(0); }); it('renders the delete and save buttons', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } }); await expect.element(page.getByRole('button', { name: /löschen/i })).toBeVisible(); await expect.element(page.getByRole('button', { name: /speichern/i })).toBeVisible(); }); it('does not render success banner when form is undefined', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } }); const banner = document.querySelector('.bg-green-50'); expect(banner).toBeNull(); }); it('does not render error-banner div when form.success is true (success path only)', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: { success: true } } }); // Error banner is the
with bg-red-50 — the delete button is also red but is a button const errorBanner = document.querySelector('div.bg-red-50'); expect(errorBanner).toBeNull(); }); it('renders all 8 permission checkboxes (4 standard + 4 admin)', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup() }, form: undefined } }); const checkboxes = document.querySelectorAll('input[name="permissions"]'); expect(checkboxes.length).toBe(8); }); it('handles a group with empty permissions array', async () => { render(AdminGroupEditPage, { props: { data: { group: baseGroup({ permissions: [] }) }, form: undefined } }); const checkboxes = Array.from( document.querySelectorAll('input[name="permissions"]') ) as HTMLInputElement[]; expect(checkboxes.every((c) => !c.checked)).toBe(true); }); });