132 lines
4.3 KiB
JavaScript
132 lines
4.3 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import { compileFunction } from 'node:vm';
|
|
import { createRequire } from 'node:module';
|
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
import ts from 'typescript';
|
|
const require = createRequire(import.meta.url);
|
|
function load(file, mocks = {}) {
|
|
const code = ts.transpileModule(
|
|
fs.readFileSync(new URL(file, import.meta.url), 'utf8'),
|
|
{
|
|
compilerOptions: {
|
|
module: ts.ModuleKind.CommonJS,
|
|
target: ts.ScriptTarget.ES2022,
|
|
jsx: ts.JsxEmit.ReactJSX,
|
|
},
|
|
},
|
|
).outputText;
|
|
const module = { exports: {} };
|
|
compileFunction(code, ['require', 'module', 'exports'])(
|
|
(key) => mocks[key] ?? require(key),
|
|
module,
|
|
module.exports,
|
|
);
|
|
return module.exports;
|
|
}
|
|
const lib = load('../../resources/js/lib/product-usage.ts');
|
|
const searchComponent = load(
|
|
'../../resources/js/components/search-usage-report.tsx',
|
|
{
|
|
'@/lib/product-usage': lib,
|
|
'@/pages/investment/shared': { card: '' },
|
|
},
|
|
);
|
|
const report = {
|
|
definition_version: 'SYNTHETIC-v1',
|
|
generated_at: '2026-11-03T12:00:00Z',
|
|
observed_before: '2026-11-03T00:00:00Z',
|
|
timezone: 'UTC',
|
|
filters: { from: '2026-11-02', to: '2026-11-02', service_code: null },
|
|
services: [{ code: 'test', title: 'SYNTHETIC <service>', version: 1 }],
|
|
coverage: {
|
|
cohort_requests: 2,
|
|
complete_histories: 1,
|
|
unknown_histories: 1,
|
|
},
|
|
metrics: [
|
|
{
|
|
id: 'rate',
|
|
title: 'SYNTHETIC rate',
|
|
value: null,
|
|
unit: '%',
|
|
numerator: 0,
|
|
denominator: 1,
|
|
state: 'partial',
|
|
source: 'SYNTHETIC source',
|
|
limits: 'SYNTHETIC unknown',
|
|
},
|
|
{
|
|
id: 'count',
|
|
title: 'SYNTHETIC count',
|
|
value: 0,
|
|
unit: 'pedidos',
|
|
numerator: null,
|
|
denominator: null,
|
|
state: 'observed',
|
|
source: 'SYNTHETIC count source',
|
|
limits: 'SYNTHETIC count limit',
|
|
},
|
|
],
|
|
unmeasured: [
|
|
{
|
|
id: 'investment',
|
|
title: 'Investimento confirmado',
|
|
reason: 'Sem fonte canónica',
|
|
},
|
|
],
|
|
limits: ['Não somar pessoas e pedidos'],
|
|
fingerprint: 'a'.repeat(64),
|
|
read_consistency: 'repeatable_read',
|
|
};
|
|
const component = load(
|
|
'../../resources/js/pages/management/product-usage.tsx',
|
|
{
|
|
'@inertiajs/react': {
|
|
Link: 'a',
|
|
usePage: () => ({ props: { errors: {} } }),
|
|
},
|
|
'@/pages/investment/shared': {
|
|
Frame: 'main',
|
|
card: '',
|
|
input: '',
|
|
button: '',
|
|
},
|
|
'@/lib/product-usage': lib,
|
|
'@/components/search-usage-report': searchComponent,
|
|
},
|
|
);
|
|
test('unknown values remain distinct from measured zero and rates retain numerator and denominator', () => {
|
|
assert.equal(lib.usageValue(null, '%'), 'Sem medição');
|
|
assert.equal(lib.usageValue(0, '%'), '0 %');
|
|
const html = renderToStaticMarkup(component.default({ report }));
|
|
assert.match(html, /Cobertura parcial/);
|
|
assert.match(html, /Numerador:.*0/);
|
|
assert.match(html, /Denominador:.*1/);
|
|
assert.match(html, /Sem medição/);
|
|
assert.match(html, /0 pedidos/);
|
|
assert.match(html, /Investimento confirmado/);
|
|
assert.doesNotMatch(html, />0 %</);
|
|
});
|
|
test('filters and export use the applied report with no new telemetry or private request parameters', () => {
|
|
const html = renderToStaticMarkup(component.default({ report }));
|
|
assert.match(html, /action="\/management\/product-usage" method="get"/);
|
|
assert.match(html, /name="from"[^>]*value="2026-11-02"/);
|
|
assert.match(html, /SYNTHETIC <service>/);
|
|
assert.match(html, /Período aplicado/);
|
|
assert.match(html, /Observações anteriores a/);
|
|
assert.deepEqual(JSON.parse(lib.usageExport(report)), report);
|
|
const src = fs.readFileSync(
|
|
new URL(
|
|
'../../resources/js/pages/management/product-usage.tsx',
|
|
import.meta.url,
|
|
),
|
|
'utf8',
|
|
);
|
|
assert.doesNotMatch(
|
|
src,
|
|
/fetch\(|document\.cookie|localStorage|sessionStorage/,
|
|
);
|
|
});
|