import { describe, it, expect, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import PersonsNewPage from './+page.svelte'; afterEach(cleanup); describe('persons/new page', () => { it('renders the heading and details section by default', async () => { render(PersonsNewPage, { props: { form: undefined } }); await expect.element(page.getByRole('heading', { name: /neue person/i })).toBeVisible(); await expect.element(page.getByRole('heading', { name: /angaben zur person/i })).toBeVisible(); }); it('renders the firstName field for the default PERSON type', async () => { render(PersonsNewPage, { props: { form: undefined } }); await expect.element(page.getByLabelText(/vorname/i)).toBeVisible(); }); it('renders alias and life-year fields for the PERSON type', async () => { render(PersonsNewPage, { props: { form: undefined } }); await expect.element(page.getByLabelText(/rufname/i)).toBeVisible(); }); it('hides firstName, alias, and life-year fields for the INSTITUTION type', async () => { render(PersonsNewPage, { props: { form: { personType: 'INSTITUTION' } } }); await expect.element(page.getByLabelText(/vorname/i)).not.toBeInTheDocument(); await expect.element(page.getByLabelText(/rufname/i)).not.toBeInTheDocument(); }); it('changes the lastName label to "Name" for non-PERSON types', async () => { render(PersonsNewPage, { props: { form: { personType: 'GROUP' } } }); await expect.element(page.getByLabelText(/^name \*$/i)).toBeVisible(); }); it('uses "Nachname" as the lastName label for PERSON type', async () => { render(PersonsNewPage, { props: { form: undefined } }); await expect.element(page.getByLabelText(/nachname \*/i)).toBeVisible(); }); it('renders the form error banner when form.error is set', async () => { render(PersonsNewPage, { props: { form: { error: 'Last name is required' } } }); await expect.element(page.getByText('Last name is required')).toBeVisible(); }); it('does not render the form error banner when form is undefined', async () => { render(PersonsNewPage, { props: { form: undefined } }); await expect.element(page.getByText('Last name is required')).not.toBeInTheDocument(); }); it('hydrates lastName and firstName from prior form values', async () => { render(PersonsNewPage, { props: { form: { lastName: 'Müller', firstName: 'Anna', alias: 'Anni' } } }); const lastName = (await page.getByLabelText(/nachname/i).element()) as HTMLInputElement; const firstName = (await page.getByLabelText(/vorname/i).element()) as HTMLInputElement; const alias = (await page.getByLabelText(/rufname/i).element()) as HTMLInputElement; expect(lastName.value).toBe('Müller'); expect(firstName.value).toBe('Anna'); expect(alias.value).toBe('Anni'); }); it('renders cancel link pointing to /persons and a submit button', async () => { render(PersonsNewPage, { props: { form: undefined } }); await expect .element(page.getByRole('link', { name: /abbrechen/i })) .toHaveAttribute('href', '/persons'); await expect.element(page.getByRole('button', { name: /erstellen/i })).toBeVisible(); }); it('falls back to PERSON when an unknown personType is supplied', async () => { render(PersonsNewPage, { props: { form: { personType: 'NOT_A_REAL_TYPE' } } }); await expect.element(page.getByLabelText(/vorname/i)).toBeVisible(); }); });