Files
aia-website/www/tools/jotform-form-a.test.mjs

135 lines
8.1 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import test from 'node:test';
import { buildFormAIframeUrl, formAIframeId, formAIframeOrigin, formAIframePlacements,
formModeForRuntime, resolveFormAIframe, resolveFormMode } from '../src/utils/form-integration.ts';
const expected = [
['/contact', 'en', 'contact'], ['/es/contact', 'es', 'contact'],
...['aba-therapy','aba-insurance','aba-ahcccs','aba-private-pay','early-intervention'].map(s => ['/lp/' + s, 'en', 'landing']),
['/client-consultation', 'en', 'consultation'], ['/es/client-consultation', 'es', 'consultation'], ['/schedule-consultation', 'en', 'consultation'],
...['en','es'].flatMap(lang => ['aba-therapy','autism-evaluations','learner-social-club'].map(s => [(lang === 'es' ? '/es/' : '/') + s, lang, 'consultation'])),
];
test('default and explicit live enable exactly sixteen fixed route/locale/context placements', () => {
assert.equal(formAIframeOrigin, 'https://form.jotform.com');
assert.equal(formAIframeId, '262946078314059');
assert.deepEqual(formAIframePlacements.map(p => [p.route,p.locale,p.context]), expected);
assert.equal(new Set(formAIframePlacements.map(p => p.route)).size, 16);
for (const rawMode of [undefined, '', ' ', 'live', 'LIVE']) for (const [route, locale, context] of expected) {
const config = resolveFormAIframe({ rawMode, route, locale });
assert.equal(config.enabled, true, route);
assert.equal(config.context, context);
assert.equal(config.mode, 'live');
assert.equal(config.url, `https://form.jotform.com/262946078314059?formContext=${context}&language=${locale}`);
assert.equal(formModeForRuntime(resolveFormMode(rawMode)), 'off', 'native surfaces remain inactive');
}
});
test('invalid and obsolete mode values fail clearly instead of silently disabling forms', () => {
for (const rawMode of ['isolated-test', 'production', 'invalid', 'false']) {
assert.throws(() => resolveFormMode(rawMode), /PUBLIC_AIA_FORMS_MODE.*Remove.*live, off, or mock/);
assert.throws(() => resolveFormAIframe({ rawMode, route: '/contact', locale: 'en' }), /PUBLIC_AIA_FORMS_MODE/);
}
});
test('off and mock reject real frames on every approved placement', () => {
for (const rawMode of ['off', 'mock']) for (const [route, locale] of expected) {
const config = resolveFormAIframe({ rawMode, route, locale });
assert.equal(config.enabled, false);
assert.equal(config.url, undefined);
}
});
test('registry rejects unknown routes, mismatched locales and arbitrary URL parameters', () => {
for (const route of ['/referrals', '/tour', '/ar/contact', '/contact/', '/contact?formContext=landing', 'https://evil.invalid']) {
assert.equal(resolveFormAIframe({ rawMode: undefined, route, locale: 'en' }).reason, 'route-not-authorized');
}
for (const [route, locale] of expected) {
assert.equal(resolveFormAIframe({ rawMode: undefined, route, locale: locale === 'en' ? 'es' : 'en' }).reason, 'locale-not-authorized');
}
assert.throws(() => buildFormAIframeUrl('ar', 'contact'), /Unsupported/);
assert.throws(() => buildFormAIframeUrl('en', 'untrusted'), /Unsupported/);
});
test('EN/ES consultation and contact titles/fallbacks remain localized', () => {
const en = resolveFormAIframe({ rawMode: undefined, route: '/client-consultation', locale: 'en' });
const es = resolveFormAIframe({ rawMode: undefined, route: '/es/client-consultation', locale: 'es' });
assert.equal(en.title, 'AIA consultation form');
assert.equal(es.title, 'Formulario de consulta de AIA');
assert.equal(es.fallbackLinkText, 'abra el formulario de consulta en una pestaña nueva.');
assert.equal(resolveFormAIframe({rawMode: undefined,route:'/es/contact',locale:'es'}).fallbackText,'Si el formulario integrado no se carga,');
});
test('the shared adapter preserves layout, bilingual drawers, sandbox, fallback and dimensions', () => {
const contact = fs.readFileSync('src/components/pages/ContactPage.astro', 'utf8');
const adapter = fs.readFileSync('src/components/JotformIframe.astro', 'utf8');
const shell = fs.readFileSync('src/components/FormShell.astro', 'utf8');
const drawer = fs.readFileSync('src/components/ServiceInquiryDrawer.astro', 'utf8');
const layout = fs.readFileSync('src/layouts/PageLayout.astro', 'utf8');
const campaign = fs.readFileSync('src/components/campaign/ConsultationForm.astro', 'utf8');
const earlyIntervention = fs.readFileSync('src/components/campaign/EarlyInterventionPage.astro', 'utf8');
assert.match(contact, /resolveFormAIframe/);
assert.match(contact, /route = lang === 'es' \? '\/es\/contact' : '\/contact'/);
assert.match(contact, /JotformIframe/);
assert.match(campaign, /resolveFormAIframe/);
assert.match(campaign, /JotformIframe/);
assert.match(campaign, /variant="embedded"/);
assert.match(campaign, /\/lp\/aba-therapy/);
assert.match(campaign, /const iframeDescription = 'Use this form to request a conversation\. An AIA team member can explain the next steps for your family\.'/);
assert.match(campaign, /description=\{iframeDescription\}/);
assert.doesNotMatch(campaign, /description=\{intro\}/);
assert.match(earlyIntervention, /resolveFormAIframe/);
assert.match(earlyIntervention, /route: '\/lp\/early-intervention'/);
assert.match(earlyIntervention, /JotformIframe/);
assert.match(shell, /resolveFormAIframe/);
assert.match(shell, /JotformIframe/);
assert.match(drawer, /lang: SupportedLocale/);
assert.match(drawer, /data-consultation-enabled/);
assert.match(drawer, /serviceCopy.heading/);
assert.match(drawer, /deferUntilActivated/);
assert.match(fs.readFileSync('src/scripts/service-inquiry.ts', 'utf8'), /aia:jotform-activate/);
assert.match(drawer, /Cerrar el formulario de consulta/);
assert.doesNotMatch(drawer, /No WAITLIST!|guarantee your child|now open for enrollment/i);
assert.match(layout, /entry\.data\.lang === 'en' \|\| entry\.data\.lang === 'es'/);
assert.match(adapter, /referrerpolicy="no-referrer"/);
assert.match(adapter, /sandbox="allow-forms allow-scripts allow-same-origin"/);
assert.match(adapter, /data-form-mode=\{config\.mode\}/);
assert.match(adapter, /data-jotform-iframe-frame/);
assert.match(adapter, /data-jotform-iframe-url/);
assert.match(adapter, /data-jotform-deferred/);
assert.match(adapter, /data-jotform-iframe-fallback hidden aria-live="polite" role="status"/);
assert.match(adapter, /<noscript>/);
assert.match(adapter, /fallbackTimeoutMs = 15_000/);
assert.match(adapter, /frame\.addEventListener\('load', onLoad, \{ once: true \}\)/);
assert.match(adapter, /document\.addEventListener\('astro:before-swap', dispose, \{ once: true \}\)/);
assert.match(adapter, /container\.addEventListener\('aia:jotform-activate'/);
assert.doesNotMatch(adapter, /set:html=|fallbackMarkup|escapeHtml\(/);
assert.match(adapter, /target="_blank" rel="noopener noreferrer"/);
assert.match(adapter, /--jotform-frame-height: 60rem/);
assert.match(adapter, /max-width: none;/);
assert.match(adapter, /width: 100%;/);
assert.match(adapter, /\.jotform-iframe--embedded \{\s*--jotform-frame-height: 42rem/);
assert.match(adapter, /\.jotform-iframe__frame \{\s*height: 68rem/);
assert.match(adapter, /\.jotform-iframe--embedded \.jotform-iframe__frame \{\s*height: 50rem/);
assert.match(adapter, /\.jotform-iframe--drawer \{\s*--jotform-frame-height: 72rem/);
assert.match(adapter, /\.jotform-iframe--drawer \.jotform-iframe__frame \{\s*height: 82rem/);
assert.doesNotMatch(adapter, /for-form-embed-handler|jotformEmbedHandler|onload=|postMessage|fetch\(|form\.submit|analytics|googletag/i);
assert.doesNotMatch(campaign, /262946078314059/);
});
test('Jotform Builder CSS retains the owner-reconciled theme overrides without external assets', () => {
const css = fs.readFileSync('integrations/jotform/aia-form-a.css', 'utf8');
for (const declaration of [
'background: #fcf9f5 !important',
'border: 1px solid #edeef3 !important',
'background: #ffbd59 !important',
'border: 2px solid #ffbd59 !important',
'border-color: #ff914d !important',
'color: #254080 !important',
]) assert.match(css, new RegExp(declaration.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
assert.match(css, /:focus-visible/);
assert.doesNotMatch(css, /https?:\/\/|@import|url\(/i);
});