A partial date (e.g. "14.03.") left the hidden ISO input empty, so saving the edit form silently cleared a stored date. PersonLifeDateField now delegates to the shared DateInput primitive (inline format error, calendar validation) and sets a custom validity while the error is present, so the browser blocks native submission for both person forms. A full clear stays submittable - that is the intentional clear path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import { describe, it, expect, afterEach } from 'vitest';
|
|
import { cleanup, render } from 'vitest-browser-svelte';
|
|
import { page, userEvent } from 'vitest/browser';
|
|
import PersonLifeDateField from './PersonLifeDateField.svelte';
|
|
import { m } from '$lib/paraglide/messages.js';
|
|
|
|
afterEach(cleanup);
|
|
|
|
const baseProps = {
|
|
name: 'birthDate',
|
|
legend: 'Geburtsdatum',
|
|
precisionLabel: 'Genauigkeit'
|
|
};
|
|
|
|
const visibleInput = () => page.getByLabelText('Geburtsdatum', { exact: true });
|
|
const hiddenIso = () => document.querySelector<HTMLInputElement>('input[name="birthDate"]');
|
|
|
|
describe('PersonLifeDateField', () => {
|
|
it('shows the format error and flags the input invalid for a partial date', async () => {
|
|
render(PersonLifeDateField, { props: baseProps });
|
|
|
|
await userEvent.fill(visibleInput(), '14.03.');
|
|
|
|
await expect.element(page.getByText(m.form_date_error())).toBeVisible();
|
|
const input = (await visibleInput().element()) as HTMLInputElement;
|
|
expect(input.checkValidity()).toBe(false);
|
|
expect(hiddenIso()?.value).toBe('');
|
|
});
|
|
|
|
it('clears error and custom validity when the input is fully emptied', async () => {
|
|
render(PersonLifeDateField, { props: { ...baseProps, initialIso: '1899-03-14' } });
|
|
|
|
await userEvent.fill(visibleInput(), '');
|
|
|
|
await expect.element(page.getByText(m.form_date_error())).not.toBeInTheDocument();
|
|
const input = (await visibleInput().element()) as HTMLInputElement;
|
|
expect(input.checkValidity()).toBe(true);
|
|
// Empty hidden ISO is the intentional clear path — the server action omits the pair.
|
|
expect(hiddenIso()?.value).toBe('');
|
|
});
|
|
|
|
it('keeps a stored date submittable when untouched', async () => {
|
|
render(PersonLifeDateField, {
|
|
props: { ...baseProps, initialIso: '1899-03-14', initialPrecision: 'DAY' }
|
|
});
|
|
|
|
await expect.element(visibleInput()).toHaveValue('14.03.1899');
|
|
const input = (await visibleInput().element()) as HTMLInputElement;
|
|
expect(input.checkValidity()).toBe(true);
|
|
expect(hiddenIso()?.value).toBe('1899-03-14');
|
|
});
|
|
|
|
it('becomes valid again once the partial date is completed', async () => {
|
|
render(PersonLifeDateField, { props: baseProps });
|
|
|
|
await userEvent.fill(visibleInput(), '14.03.');
|
|
await userEvent.fill(visibleInput(), '14.03.1899');
|
|
|
|
await expect.element(page.getByText(m.form_date_error())).not.toBeInTheDocument();
|
|
const input = (await visibleInput().element()) as HTMLInputElement;
|
|
expect(input.checkValidity()).toBe(true);
|
|
expect(hiddenIso()?.value).toBe('1899-03-14');
|
|
});
|
|
});
|