// @requirements REQ-PRODUCT-CONTRACT-ACTIONS REQ-PRODUCT-DEMO-WORKSPACE REQ-PRODUCT-A11Y REQ-PRODUCT-MOBILE import {test} from 'node:test'; import assert from 'node:assert/strict'; import {readFile} from 'node:fs/promises'; import {JSDOM} from 'jsdom'; import * as contracts from 'notabenda/contracts'; import {serveHost} from '../host.mjs'; import {DemoWorkspace} from '../worker.mjs'; import {createSyntheticStorage} from '../../packages/notabenda-cf/examples/synthetic.mjs'; import data from '../dist/server-data.json' with {type:'json'}; const request=(path,init={})=>new Request('https://demo.example.test'+path,init); function environment(){ const objects=new Map(),env={ADMIN_KEY:'b'.repeat(64),DEMO_PROVISION_LIMITER:{limit:async()=>({success:true})},WORKSPACE:{idFromName(){throw Error('Operational storage selected');}},ASSETS:{async fetch(req){let path=new URL(req.url).pathname;if(!path.endsWith('.json'))path=path.replace(/\/$/u,'')+'/index.html';try{return new Response(await readFile(new URL('../dist/public'+path,import.meta.url)),{headers:{'Content-Type':path.endsWith('.json')?'application/json':'text/html'}});}catch{return new Response('Not found',{status:404});}}}}; env.DEMO_WORKSPACES={idFromName:name=>name,get(name){if(!objects.has(name)){const storage=createSyntheticStorage([]);storage.setAlarm=async()=>{};storage.deleteAll=async()=>{for(const key of (await storage.list({prefix:'',limit:10000})).keys())await storage.delete(key);};objects.set(name,{storage,workspace:new DemoWorkspace({storage,blockConcurrencyWhile:fn=>fn()},env)});}return {fetch:req=>objects.get(name).workspace.fetch(req)};}};return {env,objects}; } async function session(env,route='withdrawal'){const response=await serveHost(request('/contract-actions/'+route),env);assert.equal(response.status,200);const dom=new JSDOM(await response.text()),cookie=response.headers.get('Set-Cookie').split(';')[0],generation=dom.window.document.querySelector('meta[name=notabenda-demo-generation]').content,operation=dom.window.document.querySelector('meta[name=notabenda-contract-operation]').content;dom.window.close();return {cookie,generation,operation};} const headers=s=>({Cookie:s.cookie,'X-Notabenda-Demo-Generation':s.generation}); const body=route=>({schemaVersion:1,definitionId:data.contractActions.definitions[route].definitionId,requestId:crypto.randomUUID(),clientAt:new Date().toISOString(),fields:{name:'Morgan Pine',contract:'Sample order JN-25001',email:'morgan@example.test',...(route==='cancellation'?{cancellation:{kind:'ordinary',reason:'',ending:''}}:{})}}); const post=(env,s,route,value,extra={})=>serveHost(request('/demo/contracts/'+route,{method:'POST',headers:{...headers(s),Origin:'https://demo.example.test','Content-Type':'application/json','X-Notabenda-Demo':'1',...extra},body:JSON.stringify(value)}),env); test('contract pages use the shared light/midnight design, exact public references and no automatic cookie/terms acceptance',async()=>{ for(const prefix of ['','dark/'])for(const route of ['withdrawal','cancellation']){const html=await readFile(new URL('../dist/public/'+prefix+'contract-actions/'+route+'/index.html',import.meta.url),'utf8'),dom=new JSDOM(html);assert.match(html,/nb-demo-contracts/);assert.ok(dom.window.document.querySelector('script[src="/assets/contract-actions.mjs"]'));assert.equal(dom.window.document.querySelectorAll('input[type=checkbox]').length,0);assert.match(html,/example.test/);assert.doesNotMatch(html,/href="\/backoffice/);dom.window.close();} for(const kind of ['privacy','cookies','terms'])assert.doesNotMatch(await readFile(new URL('../dist/public/contract-actions/'+kind+'/index.html',import.meta.url),'utf8'),/