Files
compras/scripts/supplier-improvement-report-check.mjs
nala 48347e2d3a
tests / ci (push) Canceled after 0s
commit5
2026-10-30 10:55:18 +02:00

223 lines
7.6 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
const base = 'http://127.0.0.1:8005';
function client() {
const cookies = new Map();
let csrf;
let version;
async function request(path, method = 'GET', data, inertia = true) {
const response = await fetch(base + path, {
method,
redirect: 'manual',
headers: {
Accept: inertia ? 'application/json' : 'text/html',
Cookie: [...cookies].map(([k, v]) => `${k}=${v}`).join('; '),
...(inertia
? {
'X-Inertia': 'true',
'X-Inertia-Version': version ?? '',
}
: {}),
...(data
? {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': csrf,
}
: {}),
},
...(data ? { body: JSON.stringify(data) } : {}),
});
for (const cookie of response.headers.getSetCookie()) {
const pair = cookie.split(';', 1)[0],
i = pair.indexOf('=');
cookies.set(pair.slice(0, i), pair.slice(i + 1));
}
const text = await response.text();
return {
status: response.status,
location: response.headers.get('location'),
text,
page: response.headers
.get('content-type')
?.includes('application/json')
? JSON.parse(text)
: null,
};
}
return {
request,
async enter(role) {
let page = await request('/avaliar', 'GET', undefined, false);
assert.equal(page.status, 200);
csrf = page.text.match(/name="_token" value="([^"]+)"/)[1];
assert.equal(
(await request('/avaliar/entrar', 'POST', { role }, false))
.status,
302,
);
page = await request('/avaliar', 'GET', undefined, false);
csrf = page.text.match(/name="_token" value="([^"]+)"/)[1];
const dashboard = await request(
'/dashboard',
'GET',
undefined,
false,
);
const encoded = dashboard.text.match(
/<script data-page="app" type="application\/json">([\s\S]*?)<\/script>/,
);
assert.ok(encoded, 'Expected Inertia bootstrap data');
version = JSON.parse(encoded[1]).version;
},
};
}
function csvRows(text) {
const rows = [];
let row = [],
value = '',
quoted = false;
for (let i = 0; i < text.length; i++) {
const c = text[i];
if (c === '"') {
if (quoted && text[i + 1] === '"') {
value += '"';
i++;
} else quoted = !quoted;
} else if (c === ';' && !quoted) {
row.push(value);
value = '';
} else if (c === '\n' && !quoted) {
row.push(value.replace(/\r$/, ''));
rows.push(row);
row = [];
value = '';
} else value += c;
}
if (value || row.length) {
row.push(value);
rows.push(row);
}
return rows;
}
const path = '/relatorios/medidas-fornecedores';
const readers = ['admin', 'procurement', 'finance', 'department_head'];
let example;
for (const role of [...readers, 'requester', 'warehouse']) {
const c = client();
await c.enter(role);
const report = await c.request(path);
if (readers.includes(role)) {
assert.equal(report.status, 200, role);
assert.equal(report.page.component, 'reports/supplier-improvements');
const csv = await c.request(path + '.csv', 'GET', undefined, false);
assert.equal(csv.status, 200, role);
const rows = csvRows(csv.text);
assert.equal(rows.length, report.page.props.records.total + 3, role);
assert.equal(
Object.values(report.page.props.counts).reduce((a, b) => a + b, 0),
report.page.props.records.total,
);
if (role === 'admin') {
assert.ok(
report.page.props.records.total >= 1,
'Existing explicit QA improvement required',
);
const supplier = report.page.props.suppliers[0],
responsible = report.page.props.responsibles[0];
const filters = new URLSearchParams({
supplier_id: String(supplier.id),
responsible_id: String(responsible.id),
status: 'closed',
from: '2026-11-15',
to: '2026-11-15',
});
const filtered = await c.request(path + '?' + filters);
assert.equal(filtered.status, 200);
assert.ok(filtered.page.props.records.total >= 1);
assert.ok(
filtered.page.props.records.data.every(
(m) =>
m.status === 'closed' &&
m.due_on === '2026-11-15' &&
m.overdue === false,
),
);
const exported = await c.request(
path + '.csv?' + filters + '&page=2',
'GET',
undefined,
false,
);
assert.equal(exported.status, 200);
assert.equal(
csvRows(exported.text).length,
filtered.page.props.records.total + 3,
);
const overdue = await c.request(path + '?overdue=1&status=closed');
assert.equal(overdue.page.props.records.total, 0);
const invalid = await c.request(
path + '?from=2026-11-15&to=2026-01-01',
);
assert.equal(invalid.status, 422);
const first = report.page.props.records.data[0];
assert.equal(
(
await c.request(
'/fornecedores/avaliacoes/' + first.evaluation_id,
)
).status,
200,
);
assert.equal(
(
await c.request(
'/fornecedores/avaliacoes/' +
first.evaluation_id +
'/relatorio',
)
).status,
200,
);
example = {
total: report.page.props.records.total,
filtered_total: filtered.page.props.records.total,
};
}
} else {
assert.equal(report.status, 403, role);
assert.equal(
(await c.request(path + '.csv', 'GET', undefined, false)).status,
403,
role,
);
}
assert.equal((await c.request('/logout', 'POST', {}, false)).status, 302);
}
await fs.writeFile(
'docs/proofs/supplier-improvement-report-http.json',
JSON.stringify(
{
checked_at: new Date().toISOString(),
base,
path,
readers,
denied: ['requester', 'warehouse'],
...example,
filters_and_csv_match: true,
csv_ignores_page: true,
closed_not_overdue: true,
invalid_range_refused: true,
linked_evaluation_and_report: true,
business_commands: 0,
visual_review: false,
},
null,
2,
) + '\n',
);
console.log(
'Consolidated improvement report: six profiles, filters, counts, CSV and evaluation links passed.',
);