- Move api.server.ts, errors.ts, types.ts, utils.ts, relativeTime.ts to lib/shared/ - Move person relationship components to lib/person/relationship/ - Move Stammbaum components to lib/person/genealogy/ - Move HelpPopover to lib/shared/primitives/ - Update all import paths across routes, specs, and lib files - Update vi.mock() paths in server-project test files - Remove now-empty legacy directories (components/, hooks/, server/, etc.) - Update vite.config.ts coverage include paths for new structure - Update frontend/CLAUDE.md to reflect domain-based lib/ layout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.9 KiB
TypeScript
66 lines
2.9 KiB
TypeScript
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
import { cleanup, render } from 'vitest-browser-svelte';
|
|
import { page } from 'vitest/browser';
|
|
import AddRelationshipForm from './AddRelationshipForm.svelte';
|
|
|
|
vi.mock('$app/forms', () => ({ enhance: () => () => {} }));
|
|
vi.mock('$lib/person/PersonTypeahead.svelte', () => ({ default: () => null }));
|
|
|
|
afterEach(cleanup);
|
|
|
|
describe('AddRelationshipForm', () => {
|
|
it('shows add-relationship button initially and no form', async () => {
|
|
render(AddRelationshipForm, { personId: 'person-1' });
|
|
await expect.element(page.getByRole('button')).toBeInTheDocument();
|
|
await expect.element(page.getByRole('combobox')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('shows relationType select when add button is clicked', async () => {
|
|
render(AddRelationshipForm, { personId: 'person-1' });
|
|
document.querySelector<HTMLButtonElement>('button')!.click();
|
|
await expect.element(page.getByRole('combobox')).toBeInTheDocument();
|
|
});
|
|
|
|
it('hides form and shows button when cancel is clicked', async () => {
|
|
render(AddRelationshipForm, { personId: 'person-1' });
|
|
document.querySelector<HTMLButtonElement>('button')!.click();
|
|
await expect.element(page.getByRole('combobox')).toBeInTheDocument();
|
|
const cancelBtn = [...document.querySelectorAll<HTMLButtonElement>('button')].find(
|
|
(b) => b.type === 'button' && /abbrechen/i.test(b.textContent ?? '')
|
|
);
|
|
cancelBtn!.click();
|
|
await expect.element(page.getByRole('combobox')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('submit is disabled when no person is selected', async () => {
|
|
render(AddRelationshipForm, { personId: 'person-1' });
|
|
document.querySelector<HTMLButtonElement>('button')!.click();
|
|
await expect.element(page.getByRole('button', { name: /^Hinzufügen$/i })).toBeDisabled();
|
|
});
|
|
|
|
it('form has no server action when onSubmit prop is provided', async () => {
|
|
const onSubmit = vi.fn().mockResolvedValue(undefined);
|
|
render(AddRelationshipForm, { personId: 'person-1', onSubmit });
|
|
document.querySelector<HTMLButtonElement>('button')!.click();
|
|
await expect.element(page.getByRole('combobox')).toBeInTheDocument();
|
|
const form = document.querySelector('form');
|
|
expect(form?.hasAttribute('action')).toBe(false);
|
|
});
|
|
|
|
it('shows year-range error when toYear is before fromYear', async () => {
|
|
render(AddRelationshipForm, { personId: 'person-1' });
|
|
document.querySelector<HTMLButtonElement>('button')!.click();
|
|
await expect.element(page.getByRole('combobox')).toBeInTheDocument();
|
|
|
|
const fromInput = document.querySelector<HTMLInputElement>('input[name="fromYear"]')!;
|
|
fromInput.value = '1935';
|
|
fromInput.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
|
|
const toInput = document.querySelector<HTMLInputElement>('input[name="toYear"]')!;
|
|
toInput.value = '1920';
|
|
toInput.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
|
|
|
await expect.element(page.getByRole('alert')).toBeVisible();
|
|
});
|
|
});
|