From e712477d2b2a9dd9b4053ffd3027beae50aa69b8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 12 Jun 2026 19:31:39 +0200 Subject: [PATCH] fix(person): block submit while a life-date input is partial 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 --- .../src/lib/person/PersonLifeDateField.svelte | 34 +++++----- .../person/PersonLifeDateField.svelte.spec.ts | 64 +++++++++++++++++++ .../lib/shared/primitives/DateInput.svelte | 13 +++- .../[id]/edit/PersonEditForm.svelte.test.ts | 14 +++- 4 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 frontend/src/lib/person/PersonLifeDateField.svelte.spec.ts diff --git a/frontend/src/lib/person/PersonLifeDateField.svelte b/frontend/src/lib/person/PersonLifeDateField.svelte index 53a8e04f..0d56f36a 100644 --- a/frontend/src/lib/person/PersonLifeDateField.svelte +++ b/frontend/src/lib/person/PersonLifeDateField.svelte @@ -1,7 +1,7 @@ { const select = (await page.getByLabelText(/^generation$/i).element()) as HTMLSelectElement; expect(select.value).toBe(''); }); + + // ─── partial-date guard (#812 review) ──────────────────────────────────────── + + it('blocks submission while a stored birth date is partially edited (no silent clear)', async () => { + render(PersonEditForm, { props: { person: personPersonal } }); + + await userEvent.fill(page.getByLabelText(/^geburtsdatum$/i), '14.03.'); + + const birthInput = (await page.getByLabelText(/^geburtsdatum$/i).element()) as HTMLInputElement; + expect(birthInput.checkValidity()).toBe(false); + await expect.element(page.getByText(/Bitte im Format TT\.MM\.JJJJ/)).toBeVisible(); + }); });