import {normalizeConsentNotice} from 'notabenda'; import {mountAstroConsent} from 'notabenda/astro/client'; import {ConsentProvider,PreferencesButton} from 'notabenda/react/consent'; import {compileAuthoredDocuments} from 'notabenda-authoring'; import {renderServiceDirectory} from 'notabenda/services'; // @requirements REQ-PRODUCT-LOCALIZATION REQ-PRODUCT-DOCUMENTS REQ-PRODUCT-CONSENT-EVIDENCE REQ-PRODUCT-A11Y import {test} from 'node:test'; import assert from 'node:assert/strict'; import {readFile} from 'node:fs/promises'; import {JSDOM} from 'jsdom'; import {renderToStaticMarkup} from 'react-dom/server'; import {createElement} from 'react'; import {validateSiteConfig,renderLegalDocument,renderLegalPage,createConsent,mountControls,defaultConsentWording} from 'notabenda'; import {LegalDocument} from 'notabenda/react/documents'; import {compileLegalDocuments,compileConsentRuntimeConfig,createConsentNotice,canonicalJson,sha256,createTermsOffer,createCollectionNotice} from 'notabenda/content'; import {recordLegalRelease,registerConsentNotice,setActiveConsentNotice,recordConsentChoice,getConsentHead,createConsentEvidenceStore} from 'notabenda-cf'; import {createSyntheticStorage} from '../../notabenda-cf/examples/synthetic.mjs'; import {localizedExampleConfig} from '../../../examples/localization/config.mjs'; import {consentProfiles} from './consent-profiles.mjs'; import {fixture} from './helpers.mjs'; const instant='2026-10-19T12:00:00.000Z'; async function config(){const c=localizedExampleConfig(await fixture());c.localization.reviewStatus='reviewed';for(const d of Object.values(c.documents))d.review.status='reviewed';return c;} const env=values=>({storage:{getItem:k=>values.get(k)??null,setItem:(k,v)=>values.set(k,v),removeItem:k=>values.delete(k)},now:()=>Date.parse(instant),schedule:()=>()=>{}}); const rehash=n=>{const {noticeId:_,...body}=n;return {...n,noticeId:sha256(canonicalJson(body))};}; test('complete selected dictionaries are bounded plain text, have exact placeholders and require review in production',async()=>{ const c=await config();assert.equal(validateSiteConfig(c,{mode:'production'}).valid,true); for(const change of [c=>delete c.localization.consent.stale,c=>c.localization.consent.extra='Unused',c=>c.localization.consent.services='Serviços',c=>c.localization.consent.services='{unknown}',c=>c.localization.consent.services='{services}',c=>c.localization.consent.services='{services} {',c=>c.localization.consent.title='💬'.repeat(600),c=>c.localization.consent.acceptLabel='a'.repeat(121),c=>c.localization.locale='pt-br',c=>c.localization.direction='auto',c=>c.localization.revision='',c=>delete c.localization.documents.contents,c=>delete c.localization.generatedDocuments.storageCaption,c=>delete c.localization.generatedDocuments]){ const changed=structuredClone(c);change(changed);assert.equal(validateSiteConfig(changed,{mode:'production'}).valid,false,change.toString()); } const draft=structuredClone(c);draft.localization.reviewStatus='draft';assert.equal(validateSiteConfig(draft,{mode:'production'}).valid,false);assert.equal(validateSiteConfig(draft,{mode:'preview'}).valid,true); const supplied=structuredClone(c);delete supplied.localization.generatedDocuments;for(const d of Object.values(supplied.documents)){d.source='supplied';d.sections=[{id:'one',heading:'Informações',paragraphs:['Texto revisado pelo responsável.']}];}assert.equal(validateSiteConfig(supplied,{mode:'production'}).valid,true);assert.match(renderLegalPage(supplied,'privacy'),/Texto revisado/u); const malicious=structuredClone(c);Object.defineProperty(malicious.localization.consent,'title',{enumerable:true,get(){throw Error('Do not invoke translation getters');}});assert.equal(validateSiteConfig(malicious).valid,false); }); test('native and React legal documents share localized text, language, direction and escaped declared facts',async()=>{ const c=await config();c.site.name='Juniper & leitura';c.purposes[0].description=''; for(const kind of ['privacy','cookies','terms']){ const html=renderLegalPage(c,kind),fragment=renderLegalDocument(c,kind),react=renderToStaticMarkup(createElement(LegalDocument,{config:c,kind})); assert.ok(react.includes(fragment));assert.match(html,//u);assert.match(fragment,/lang="pt-BR" dir="ltr"/u);assert.match(html,/Ir para o conteúdo/u);assert.match(fragment,/Nesta página/u);assert.doesNotMatch(html,/Who is responsible|Declared storage|On this page|Skip to content|>Version |Effective