From 782a34e34b83a2a94aa08a876c82ff470356cf41 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 2 Jun 2026 19:39:11 +0200 Subject: [PATCH] test(mocks): add shared $app/forms interceptor mock body Single home for the non-trivial form-interceptor enhance() shared by the four complex consumers: it intercepts submit, invokes the SubmitFunction, and fires the returned callback with a configurable result. setFormResult() drives the success/failure branch; an embedded beforeEach resets it before every test so isolation is structural. Consumed via vi.mock('$app/forms', () => ({ ...formsMock })) through the $mocks alias. Part of #560. Co-Authored-By: Claude Opus 4.8 --- frontend/src/__mocks__/$app/forms.ts | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 frontend/src/__mocks__/$app/forms.ts diff --git a/frontend/src/__mocks__/$app/forms.ts b/frontend/src/__mocks__/$app/forms.ts new file mode 100644 index 00000000..2c8915dc --- /dev/null +++ b/frontend/src/__mocks__/$app/forms.ts @@ -0,0 +1,43 @@ +// Shared browser-test mock body for the SvelteKit `$app/forms` virtual module. +// +// Imported into a sync vi.mock factory via the $mocks alias: +// import * as formsMock from '$mocks/$app/forms'; +// vi.mock('$app/forms', () => ({ ...formsMock })); +// +// `enhance` intercepts the form's submit event, invokes the component's +// SubmitFunction, and — when that returns a post-submit callback — calls it +// with the configurable `_formResult`. Tests drive the success/failure branch +// with `setFormResult({ type: 'failure' })`. The embedded `beforeEach` resets +// the result before every test, so isolation is structural, not per-spec. +// See ADR-012. + +import { beforeEach } from 'vitest'; + +export type FormEnhanceResult = { type: string; data?: Record }; + +let _formResult: FormEnhanceResult = { type: 'success' }; + +export function setFormResult(result: FormEnhanceResult): void { + _formResult = result; +} + +export function enhance( + node: HTMLFormElement, + submit?: (opts: { + formData: FormData; + }) => (opts: { result: FormEnhanceResult; update: () => Promise }) => Promise +): { destroy: () => void } { + const handler = async (e: Event) => { + e.preventDefault(); + const callback = submit?.({ formData: new FormData(node) } as never); + if (typeof callback === 'function') { + await callback({ result: _formResult, update: async () => {} }); + } + }; + node.addEventListener('submit', handler); + return { destroy: () => node.removeEventListener('submit', handler) }; +} + +beforeEach(() => { + _formResult = { type: 'success' }; +});