Files
SGF/scripts/receipt-selection-race-check.mjs
2026-11-04 09:37:20 +02:00

6 lines
2.4 KiB
JavaScript

import fs from 'node:fs';import vm from 'node:vm';import assert from 'node:assert/strict';
const html=fs.readFileSync('resources/views/accounting/receipt-recovery.blade.php','utf8'),script=html.match(/<script>([\s\S]*)<\/script>/)[1].replace(/@json\(session\('company_context.token'\)\)/g,'"qa-context"'),events={},form={elements:{command_key:{value:'11111111-1111-1111-1111-111111111111'},domain:{value:'ledger'}},querySelector:()=>button,addEventListener:(e,fn)=>events[e]=fn},button={},status={},result={},requests=[];let checks=0;const ok=(v,m)=>{checks++;assert(v,m);};
const sandbox={AbortController,document:{getElementById:id=>({'receipt-lookup':form,'receipt-status':status,'receipt-result':result}[id])},fetch:(url,options)=>new Promise(resolve=>requests.push({url,options,resolve}))};vm.createContext(sandbox);vm.runInContext(script,sandbox);const submit=()=>form.onsubmit({preventDefault(){}}),reply=(n,body,ok=true)=>requests[n].resolve({ok,json:async()=>body});
const old=submit();form.elements.domain.value='settlement';events.change();ok(requests[0].options.signal.aborted&&!button.disabled&&result.textContent==='','Changing domain cancels and clears selection');const fresh=submit();reply(0,{result:'OLD'});await old;ok(result.textContent===''&&button.disabled,'Late old response cannot paint or unlock new request');reply(1,{result:'CURRENT'});await fresh;ok(result.textContent.includes('CURRENT')&&!button.disabled,'Current response displayed');const third=submit();form.elements.command_key.value='22222222-2222-2222-2222-222222222222';events.input();reply(2,{result:'WRONG-KEY'});await third;ok(result.textContent===''&&!button.disabled,'Changed key invalidates response');const fourth=submit(),fifth=submit();reply(3,{result:'OLDER'});await fourth;ok(result.textContent===''&&button.disabled,'Repeated submit keeps latest request in control');reply(4,{message:'Denied'},false);await fifth;ok(status.textContent.includes('Denied')&&result.textContent===''&&!button.disabled&&requests.every(r=>!r.options.method&&!r.options.body),'Current refusal recovers without executing');
const output=process.argv[2];if(!output||fs.existsSync(output))throw Error('Fresh explicit proof output required');fs.writeFileSync(output,JSON.stringify({passed:true,checks,node_vm_only:true,actual_browser:false,late_domain_and_key_responses_rejected:true,read_only_get:true},null,2));console.log(JSON.stringify({passed:true,checks}));