import { describe, test, expect } from 'vitest'; import { SubscribeForm } from './SubscribeForm'; const toHtml = (SubscribeForm as any).toHtml; describe('SubscribeForm.toHtml hardcoded attributes stay hardcoded (no raw prop breakout)', () => { test('form method is always POST regardless of any injected props', () => { const { html } = toHtml({ heading: 'Join us', method: 'GET">' } as any, ''); expect(html).toMatch(/
{ const { html } = toHtml({ type: 'text">' } as any, ''); expect(html).toContain(' { const { html: inlineHtml } = toHtml({ layout: 'inline' }, ''); const { html: stackedHtml } = toHtml({ layout: 'stacked' }, ''); expect(inlineHtml).toContain('flex-direction:row'); expect(stackedHtml).toContain('flex-direction:column'); }); test('malicious layout value cannot inject raw CSS/attribute breakout (falls through the isInline boolean check to the stacked literal)', () => { const { html } = toHtml({ layout: '">' as any }, ''); expect(html).not.toContain(' { const { html } = toHtml({ heading: 'Subscribe', placeholder: 'you@example.com', buttonText: 'Go' }, ''); expect(html).toContain('Subscribe'); expect(html).toContain('placeholder="you@example.com"'); expect(html).toContain('>Go<'); }); }); // F1: SubscribeForm previously emitted `` with no action // at all -- a published subscribe form silently did nothing on submit. // Wired through the same relay contract as ContactForm/FormContainer // (utils/form-relay-wiring.ts) so setting a recipient makes it functional. describe('SubscribeForm.toHtml is functional (not a dead POST)', () => { test('without a recipient: still has a real (non-empty) action -- "#" fallback, not a bare method="POST"', () => { const { html } = toHtml({}, ''); expect(html).toMatch(/ { const { html } = toHtml({ recipientEmail: 'news@example.com', thankYouUrl: '/thanks' }, '', 'node-sub1'); expect(html).toMatch(//); expect(html).toMatch(/action="__WHP_FORM_ACTION__F_[0-9a-z]+__"/); expect(html).toContain('name="_gotcha"'); const mid = html.match(/id="(F_[0-9a-z]+)"/)![1]; expect(html).toContain(`__WHP_FORM_ACTION__${mid}__`); }); test('the email input keeps its name="email" so the relay receives it', () => { const { html } = toHtml({ recipientEmail: 'news@example.com' }, '', 'node-sub2'); expect(html).toContain('name="email"'); }); }); describe('SubscribeForm.toHtml box-model style passthrough', () => { test('margin/border/box-shadow/opacity flow through via the style prop', () => { const { html } = toHtml({ style: { marginTop: '16px', border: '1px solid #ddd', boxShadow: '0 2px 6px rgba(0,0,0,.15)', opacity: '0.85' } }, ''); expect(html).toContain('margin-top:16px'); expect(html).toContain('border:1px solid #ddd'); expect(html).toContain('opacity:0.85'); }); }); describe('SubscribeForm.craft.props includes animation/visibility defaults', () => { test('has blank/false defaults', () => { expect(SubscribeForm.craft!.props).toMatchObject({ animation: '', animationDelay: '', hideOnDesktop: false, hideOnTablet: false, hideOnMobile: false, }); }); });