50 lines
4.6 KiB
JavaScript
50 lines
4.6 KiB
JavaScript
import fs from 'node:fs';
|
|
import assert from 'node:assert/strict';
|
|
import crypto from 'node:crypto';
|
|
const legacy=process.argv.includes('--previous');
|
|
const privateData=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-2576427d1939/private/development.json','utf8'));
|
|
assert.deepEqual([privateData.tenant_id,privateData.company_id,privateData.unit_id],[1,1,1]);
|
|
const checks=[];
|
|
for(const profile of privateData.profiles){
|
|
const jar=new Map();let csrf='',token='';
|
|
const api=async(path,method='GET',body,status=200,overrides={})=>{
|
|
const response=await fetch('http://127.0.0.1:8039'+path,{method,headers:{Accept:'application/json','Content-Type':'application/json',Cookie:[...jar].map(([k,v])=>k+'='+v).join('; '),'X-CSRF-TOKEN':csrf,'X-SGF-Context':token,'X-Purchasing-Context':'procurement.internal','Idempotency-Key':crypto.randomUUID(),...overrides},...(body===undefined?{}:{body:JSON.stringify(body)})});
|
|
for(const cookie of response.headers.getSetCookie()){const pair=cookie.split(';')[0],at=pair.indexOf('=');jar.set(pair.slice(0,at),pair.slice(at+1));}
|
|
const text=await response.text();let d;try{d=JSON.parse(text);}catch{d={};}
|
|
assert((Array.isArray(status)?status:[status]).includes(response.status),`${profile.role} ${path}: expected ${status}, got ${response.status}: ${d.message??''}`);
|
|
if(d.csrf)csrf=d.csrf;if(d.context?.token)token=d.context.token;
|
|
return d;
|
|
};
|
|
await api('/api/session');await api('/api/login','POST',{email:profile.email,password:privateData.password});
|
|
await api('/api/context','POST',{tenant_id:1,company_id:1,unit_id:1,module_id:'purchasing'});
|
|
const list=await api('/api/internal-requisitions');
|
|
if(legacy&&profile.role==='consulta'){
|
|
assert(!list.records.some(r=>r.id===1));await api('/api/internal-requisitions/1','GET',undefined,404);
|
|
checks.push('Previous version reproduces missing read-only listing/detail');continue;
|
|
}
|
|
assert(list.records.some(r=>r.id===1),'Existing request must be listed');
|
|
const detail=await api('/api/internal-requisitions/1');
|
|
assert.equal(detail.record.id,1);assert.equal(detail.record.version,3);assert.equal(detail.record.status,'approved');assert.equal(detail.record.total_minor,10000);
|
|
assert.equal(detail.history.length,3);
|
|
checks.push(`${profile.role}: existing request 1 listed, detail and three-event history readable`);
|
|
if(profile.role==='consulta'){
|
|
assert.equal(list.permissions.prepare,false);assert.equal(list.permissions.configure,false);assert.deepEqual(detail.record.allowed_actions,[]);
|
|
await api('/api/internal-requisitions/save','POST',{operation_key:crypto.randomUUID()},403);
|
|
for(const action of ['save','submit','decide'])await api('/api/internal-requisitions/1/'+action,'POST',{operation_key:crypto.randomUUID(),version:3,...(action==='decide'?{decision:'approved'}:{})},[403,404]);
|
|
await api('/api/internal-requisitions/policy','POST',{version:1,reason:'Denied read-only configuration verification.',enabled:true,budget_required:true,first_limit_minor:1000000,second_limit_minor:2000000,approval_includes_tax:true,centres:[{id:1,department_ref:'OPER'}],members:[{user_id:1,department_ref:'OPER'},{user_id:2,department_ref:'OPER'}]},403);
|
|
await api('/api/internal-requisitions/centres','POST',{operation_key:crypto.randomUUID(),code:'REFUSED',reason:'Read-only denial check.'},403);
|
|
await api('/api/purchasing-budget/approve','POST',{budget_id:1},403);
|
|
await api('/api/accesses','GET',undefined,403);
|
|
checks.push('Consulta: no allowed actions; creation, save, submission, decision, policy, centre, budget approval and administration refused');
|
|
await api('/api/internal-requisitions/1','GET',undefined,409,{'X-SGF-Context':'invalid'});
|
|
await api('/api/internal-requisitions/1','GET',undefined,403,{'X-Purchasing-Context':'procurement.third_party'});
|
|
await api('/api/internal-requisitions/999999999','GET',undefined,404);
|
|
await api('/api/context','POST',{tenant_id:1,company_id:1,unit_id:2,module_id:'purchasing'},403);
|
|
await api('/api/context','POST',{tenant_id:1,company_id:2,unit_id:3,module_id:'purchasing'},403);
|
|
checks.push('Consulta: forged context, wrong option, missing record and unauthorised company/unit refused');
|
|
}
|
|
}
|
|
const report={passed:true,mode:legacy?'previous-version-recovery':'corrected-version',url:'http://127.0.0.1:8039',scope:'1:1:1',request_id:1,request_recreated:false,reservation_commands_executed:false,rights_changed:false,checks,checked_at:new Date().toISOString(),visual_review:false};
|
|
fs.writeFileSync('C:/laragon/www/compras/docs/proofs/sgf-read-8039-'+(legacy?'rollback':'http')+'.json',JSON.stringify(report,null,2));
|
|
console.log(JSON.stringify(report));
|