Files
familienarchiv/frontend/src/lib/components/DateInput.svelte.spec.ts
Marcel 46eb908ff4
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 1m46s
CI / Backend Unit Tests (pull_request) Failing after 2m37s
CI / E2E Tests (pull_request) Failing after 1h48m16s
fix(DateInput): fire onchange when field is cleared
Clearing the input set value='' but did not call onchange, so the
korrespondenz filter strip never re-fetched. Added onchange?.() in the
empty-display branch and added a test that confirms the callback fires.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 21:22:43 +02:00

211 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import DateInput from './DateInput.svelte';
afterEach(() => cleanup());
// ─── Rendering ────────────────────────────────────────────────────────────────
describe('DateInput rendering', () => {
it('renders a text input with inputmode=numeric and maxlength=10', async () => {
render(DateInput, {});
const input = page.getByRole('textbox');
await expect.element(input).toBeInTheDocument();
await expect.element(input).toHaveAttribute('inputmode', 'numeric');
await expect.element(input).toHaveAttribute('maxlength', '10');
});
it('has default placeholder from paraglide', async () => {
render(DateInput, {});
const input = page.getByRole('textbox');
await expect.element(input).toHaveAttribute('placeholder', 'TT.MM.JJJJ');
});
it('accepts a custom placeholder', async () => {
render(DateInput, { placeholder: 'Geburtsdatum' });
const input = page.getByRole('textbox');
await expect.element(input).toHaveAttribute('placeholder', 'Geburtsdatum');
});
it('passes id prop to the input', async () => {
render(DateInput, { id: 'my-date' });
const input = page.getByRole('textbox');
await expect.element(input).toHaveAttribute('id', 'my-date');
});
});
// ─── Init from value ──────────────────────────────────────────────────────────
describe('DateInput init from value', () => {
it('displays ISO value in German format on mount', async () => {
render(DateInput, { value: '2024-12-20' });
const input = page.getByRole('textbox');
await expect.element(input).toHaveValue('20.12.2024');
});
it('starts empty and error-free when no value is given', async () => {
let errorMessage: string | null = null;
render(DateInput, {
get errorMessage() {
return errorMessage;
},
set errorMessage(v) {
errorMessage = v;
}
});
const input = page.getByRole('textbox');
await expect.element(input).toHaveValue('');
expect(errorMessage).toBeNull();
});
});
// ─── Typing valid date ────────────────────────────────────────────────────────
describe('DateInput typing a valid date', () => {
it('auto-formats to DD.MM.YYYY and updates value to ISO', async () => {
let value = '';
let errorMessage: string | null = null;
render(DateInput, {
get value() {
return value;
},
set value(v) {
value = v;
},
get errorMessage() {
return errorMessage;
},
set errorMessage(v) {
errorMessage = v;
}
});
const input = page.getByRole('textbox');
await input.fill('20122024');
await expect.element(input).toHaveValue('20.12.2024');
expect(value).toBe('2024-12-20');
expect(errorMessage).toBeNull();
});
});
// ─── Typing invalid month ─────────────────────────────────────────────────────
describe('DateInput typing a date with invalid month', () => {
it('sets errorMessage and clears value when month > 12', async () => {
let value = '';
let errorMessage: string | null = null;
render(DateInput, {
get value() {
return value;
},
set value(v) {
value = v;
},
get errorMessage() {
return errorMessage;
},
set errorMessage(v) {
errorMessage = v;
}
});
const input = page.getByRole('textbox');
await input.fill('22222222');
await expect.element(input).toHaveValue('22.22.2222');
expect(value).toBe('');
expect(errorMessage).not.toBeNull();
});
});
// ─── Typing partial date ──────────────────────────────────────────────────────
describe('DateInput typing a partial date', () => {
it('sets errorMessage and clears value when date is incomplete', async () => {
let value = '';
let errorMessage: string | null = null;
render(DateInput, {
get value() {
return value;
},
set value(v) {
value = v;
},
get errorMessage() {
return errorMessage;
},
set errorMessage(v) {
errorMessage = v;
}
});
const input = page.getByRole('textbox');
await input.fill('2212');
await expect.element(input).toHaveValue('22.12');
expect(value).toBe('');
expect(errorMessage).not.toBeNull();
});
});
// ─── Clearing date ────────────────────────────────────────────────────────────
describe('DateInput clearing the date', () => {
it('resets value and errorMessage to null when cleared', async () => {
let value = '';
let errorMessage: string | null = null;
render(DateInput, {
get value() {
return value;
},
set value(v) {
value = v;
},
get errorMessage() {
return errorMessage;
},
set errorMessage(v) {
errorMessage = v;
}
});
const input = page.getByRole('textbox');
// Type a valid date first
await input.fill('20122024');
expect(value).toBe('2024-12-20');
// Now clear
await input.fill('');
expect(value).toBe('');
expect(errorMessage).toBeNull();
});
it('fires onchange when the field is cleared', async () => {
let called = 0;
render(DateInput, { value: '2024-12-20', onchange: () => called++ });
const input = page.getByRole('textbox');
await input.fill('');
expect(called).toBeGreaterThan(0);
});
});
// ─── Hidden input ─────────────────────────────────────────────────────────────
describe('DateInput hidden input for form submission', () => {
it('renders a hidden input with the given name when name prop is set', async () => {
render(DateInput, { name: 'documentDate' });
const hidden = document.querySelector('input[type="hidden"][name="documentDate"]');
expect(hidden).not.toBeNull();
});
it('does not render a hidden input when name prop is absent', async () => {
render(DateInput, {});
const hidden = document.querySelector('input[type="hidden"]');
expect(hidden).toBeNull();
});
it('hidden input value reflects the ISO value', async () => {
render(DateInput, { name: 'documentDate', value: '' });
const input = page.getByRole('textbox');
await input.fill('20122024');
const hidden = document.querySelector<HTMLInputElement>(
'input[type="hidden"][name="documentDate"]'
);
await expect.poll(() => hidden?.value).toBe('2024-12-20');
});
});