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 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-02 19:39:11 +02:00
committed by marcel
parent 30f450b0d1
commit 782a34e34b

View File

@@ -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<string, unknown> };
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<void> }) => Promise<void>
): { 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' };
});