From 4877a63a3b603225cf572483f9dc8cdb21f0c790 Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Tue, 7 Jul 2026 12:22:28 -0700 Subject: [PATCH] site-builder: pin non-relay byte-identity on the realistic (non-empty fields) case [PR #2 review] --- .../components/forms/ContactForm.toHtml.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/craft/src/components/forms/ContactForm.toHtml.test.ts b/craft/src/components/forms/ContactForm.toHtml.test.ts index 99b9598..36e48f3 100644 --- a/craft/src/components/forms/ContactForm.toHtml.test.ts +++ b/craft/src/components/forms/ContactForm.toHtml.test.ts @@ -23,4 +23,21 @@ describe('ContactForm.toHtml relay wiring', () => { // Backward-compat: ensure non-relay output is byte-identical (no extra blank lines from honeypot) expect(html).not.toMatch(/]*>\n\s*\n/); }); + + test('without recipientEmail + real fields: byte-clean legacy output (realistic case)', () => { + // The empty-fields case is NOT byte-identical to the old code (the old + // template emitted a stray whitespace line when fields was empty; the new + // ternary drops it). Real forms always have fields, so pin THAT scenario: + // no marker, no honeypot, and no whitespace-only line between
and + // the first field. + const fields = [{ type: 'text', label: 'Name', name: 'name', placeholder: 'Your name', required: true }]; + const { html } = toHtml({ formAction: '/legacy', fields }, ''); + expect(html).not.toContain('WHP-FORM'); + expect(html).not.toContain('_gotcha'); + expect(html).toContain('action="/legacy"'); + expect(html).not.toMatch(/]*>\n\s*\n/); + // First field renders directly after the form tag (no stray blank line). + expect(html).toMatch(/]*>\n\s*