Permitir consulta pública dos ecrãs reais com dados privados protegidos
tests / ci (push) Canceled after 0s

This commit is contained in:
2026-10-30 20:14:24 +02:00
parent c6373365bf
commit 2134aa084b
83 changed files with 3894 additions and 3127 deletions
+79 -29
View File
@@ -1,39 +1,89 @@
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
const cookies = new Map(), base = 'http://127.0.0.1:8005';
const cookies = new Map(),
base = 'http://127.0.0.1:8005';
async function request(path, method = 'GET', body) {
const r = await fetch(base + path, {method, redirect:'manual', headers:{Accept:'application/json',
Cookie:[...cookies].map(([k,v])=>`${k}=${v}`).join('; '),
...(body?{'Content-Type':'application/x-www-form-urlencoded'}:{})},
...(body?{body:new URLSearchParams(body)}:{})});
for(const c of r.headers.getSetCookie()) {const p=c.split(';',1)[0],i=p.indexOf('=');cookies.set(p.slice(0,i),p.slice(i+1));}
return {status:r.status,text:await r.text()};
const r = await fetch(base + path, {
method,
redirect: 'manual',
headers: {
Accept: 'application/json',
Cookie: [...cookies].map(([k, v]) => `${k}=${v}`).join('; '),
...(body
? { 'Content-Type': 'application/x-www-form-urlencoded' }
: {}),
},
...(body ? { body: new URLSearchParams(body) } : {}),
});
for (const c of r.headers.getSetCookie()) {
const p = c.split(';', 1)[0],
i = p.indexOf('=');
cookies.set(p.slice(0, i), p.slice(i + 1));
}
return { status: r.status, text: await r.text() };
}
const landing=await request('/avaliar');
const csrf=landing.text.match(/name="_token" value="([^"]+)"/)[1];
assert.equal((await request('/avaliar/entrar','POST',{role:'admin',_token:csrf})).status,302);
const before=JSON.parse((await request('/api/supplier-payables')).text);
const landing = await request('/avaliar');
const csrf = landing.text.match(/name="_token" value="([^"]+)"/)[1];
assert.equal(
(await request('/avaliar/entrar', 'POST', { role: 'admin', _token: csrf }))
.status,
302,
);
const before = JSON.parse((await request('/api/supplier-payables')).text);
assert(before.documents.length);
for(const doc of before.documents) {
const filtered=await request('/api/supplier-payables?invoice='+doc.local_id);
assert.equal(filtered.status,200);
const data=JSON.parse(filtered.text);
assert.deepEqual(data.documents,[doc]);
const page=await request('/obrigacoes-fornecedores?invoice='+doc.local_id);
assert.equal(page.status,200);
for (const doc of before.documents) {
const filtered = await request(
'/api/supplier-payables?invoice=' + doc.local_id,
);
assert.equal(filtered.status, 200);
const data = JSON.parse(filtered.text);
assert.deepEqual(data.documents, [doc]);
const page = await request(
'/obrigacoes-fornecedores?invoice=' + doc.local_id,
);
assert.equal(page.status, 200);
assert(page.text.includes('href="/facturas"'));
assert(page.text.includes('Voltar às facturas'));
assert(page.text.includes(doc.number));
}
for(const query of ['0','-1','abc','1.5']) {
assert.equal((await request('/api/supplier-payables?invoice='+query)).status,422);
assert.equal((await request('/obrigacoes-fornecedores?invoice='+query)).status,422);
for (const query of ['0', '-1', 'abc', '1.5']) {
assert.equal(
(await request('/api/supplier-payables?invoice=' + query)).status,
422,
);
assert.equal(
(await request('/obrigacoes-fornecedores?invoice=' + query)).status,
422,
);
}
assert.equal((await request('/api/supplier-payables?invoice=2147483647')).status,404);
const after=JSON.parse((await request('/api/supplier-payables')).text);
assert.deepEqual(after,before,'Read-only navigation must preserve all documents and histories');
await fs.writeFile('docs/proofs/invoice-payable-link.json',JSON.stringify({checked_at:new Date().toISOString(),
documents_checked:before.documents.length,per_invoice_entry:true,return_to_invoices:true,
invalid_identifiers_refused:true,unknown_invoice_refused:true,full_listing_unchanged:true,business_commands:0,
visual_review:false},null,2)+'\n');
console.log('Per-invoice payable navigation, invalid/unknown identifiers and unchanged history passed.');
assert.equal(
(await request('/api/supplier-payables?invoice=2147483647')).status,
404,
);
const after = JSON.parse((await request('/api/supplier-payables')).text);
assert.deepEqual(
after,
before,
'Read-only navigation must preserve all documents and histories',
);
await fs.writeFile(
'docs/proofs/invoice-payable-link.json',
JSON.stringify(
{
checked_at: new Date().toISOString(),
documents_checked: before.documents.length,
per_invoice_entry: true,
return_to_invoices: true,
invalid_identifiers_refused: true,
unknown_invoice_refused: true,
full_listing_unchanged: true,
business_commands: 0,
visual_review: false,
},
null,
2,
) + '\n',
);
console.log(
'Per-invoice payable navigation, invalid/unknown identifiers and unchanged history passed.',
);