test(DateInput): add Vitest specs for DateInput component and date utils
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 4m3s
CI / Backend Unit Tests (pull_request) Failing after 2m24s
CI / E2E Tests (pull_request) Failing after 1h46m24s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-03-30 18:20:07 +02:00
parent 56d79c919e
commit 9d6c7b8605
2 changed files with 315 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
import { describe, expect, it, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import { page } from 'vitest/browser';
import DateInput from './DateInput.svelte';
/** Wait one macrotask so Svelte can flush reactive DOM updates. */
const domFlush = () => new Promise<void>((r) => setTimeout(r, 50));
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();
});
});
// ─── 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');
await domFlush();
const hidden = document.querySelector<HTMLInputElement>(
'input[type="hidden"][name="documentDate"]'
);
expect(hidden?.value).toBe('2024-12-20');
});
});