Files
compras/scripts/invoice-payable-link-check.mjs
2026-10-30 20:14:24 +02:00

90 lines
2.9 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
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 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);
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,
);
}
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.',
);