16 lines
3.5 KiB
JavaScript
16 lines
3.5 KiB
JavaScript
import fs from 'node:fs';import path from 'node:path';import assert from 'node:assert/strict';
|
|
const read=p=>JSON.parse(fs.readFileSync(p,'utf8')),state=read('C:/laragon/data/sgf-tempo/run/modular-regression-current.json'),tag=process.argv[2];if(state.port!==55439||!/^[a-f0-9]{12}$/.test(tag??''))throw Error('Owned sales demo required');
|
|
const root=path.join(state.root,'private/ledger-'+tag),demo=read(path.join(root,'sales-demo.json')),g=read(path.join(root,'sales-fixture.json')),output=path.join(root,'sales-demo-http.json');if(fs.existsSync(output))throw Error('Completed readiness preserved');const base=new URL(demo.url).origin;let checks=0;const check=(v,s)=>{checks++;assert(v,s);};let result=await fetch(demo.url);check(result.status===200&&(await result.text()).includes('data-sales-demo="'+tag+'"'),'Persistent sales demo ready');
|
|
for(const role of ['prepare','validate','read']){
|
|
const jar=new Map();let auth;const req=async url=>{const r=await fetch(base+url,{headers:{Accept:'application/json',Cookie:[...jar].map(([k,v])=>k+'='+v).join('; '),'X-SGF-Context':auth?.context??''},redirect:'manual'});for(const c of r.headers.getSetCookie()){const p=c.split(';')[0],at=p.indexOf('=');jar.set(p.slice(0,at),p.slice(at+1));}const text=await r.text();let data;try{data=JSON.parse(text);}catch{}return{status:r.status,data,text};};
|
|
let r=await req('/qa/sales-enter/'+role);check(r.status===200,'Own role '+role);auth=r.data;check(jar.has(demo.cookie)&&!jar.has('XSRF-TOKEN'),'Dedicated cookie does not overwrite demos');
|
|
r=await req('/api/general-ledger/sales?invoice_id='+g.invoice_id);check(r.status===200&&r.data.commercial.position===null&&!r.data.book.journals.length&&!r.data.commercial.records.length&&!r.data.commercial.effects.length,'Actual invoice but no financial or ledger effects in team fixture');check(r.data.commercial.invoice.snapshot.calculation.total_document_proposed==='1000.00','Approved documentary total1000 preserved');
|
|
r=await req('/general-ledger/sales?invoice_id='+g.invoice_id);check(r.status===200&&(role==='prepare'?r.text.includes('data-finance="propose"'):!r.text.includes('data-finance=')),'Role-specific initial financial interface');check(r.text.includes("fetch('/api/session'")&&r.text.includes('snapshot.context?.token!==context'),'UI checks old generation before compound module transitions');
|
|
if(role==='prepare')fs.writeFileSync(path.join(root,'sales-demo-preparer.html'),r.text);
|
|
r=await req('/general-ledger');check(r.status===200&&r.text.includes('/general-ledger/sales')&&!r.text.includes('name="obligation_id" type="number"'),'Accounting navigation exposes Sales and no unauthorised supplier preparation');
|
|
r=await req('/');check(r.status===200&&r.text.includes('/build/assets/'),'Existing SGF app/navigation uses private assets');
|
|
const m=read(path.join(root,'storage/public/build/manifest.json')),asset=Object.values(m).find(x=>x.isEntry)?.file;check(Boolean(asset)&&(await req('/build/'+asset)).status===200,'Private app build reachable');
|
|
}
|
|
const access=read(path.join(root,'sales-demo-access.json'));check(access.unlisted_users_with_grants===0,'Only declared synthetic actors retain access');
|
|
fs.writeFileSync(output,JSON.stringify({passed:true,checks,url:demo.url,three_roles:true,one_actual_test_invoice:true,financial_records:0,financial_effects:0,journals:0,no_business_commands:true,private_build:true,module_generation_checked_by_ui:true,unlisted_users_with_grants:0,visual_review:false,browser_automation:false},null,2)+'\n');console.log(JSON.stringify({passed:true,checks,url:demo.url}));
|