Files
Investidor-V2/tests/frontend/irpc-pec-obligation-ui.test.mjs
T
2026-11-11 10:55:53 +02:00

122 lines
4.7 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 React from 'react';
import ts from 'typescript';
import * as annual from '../../resources/js/lib/irpc-annual-settlement.ts';
import * as investment from '../../resources/js/lib/irpc-pec-obligation.ts';
import * as rational from '../../resources/js/lib/fiscal-rational.ts';
import { renderToStaticMarkup } from 'react-dom/server';
import { plan } from './helpers/irpc-pec-obligation-case.mjs';
import { investmentCase } from './helpers/irpc-investment-case.mjs';
const require = createRequire(import.meta.url),
module = { exports: {} };
const source = fs.readFileSync(
new URL(
'../../resources/js/components/simulation-irpc-pec-obligation.tsx',
import.meta.url,
),
'utf8',
);
const output = ts.transpileModule(source, {
compilerOptions: {
module: ts.ModuleKind.CommonJS,
target: ts.ScriptTarget.ES2022,
jsx: ts.JsxEmit.ReactJSX,
},
}).outputText;
compileFunction(output, ['require', 'module', 'exports'])(
(name) =>
name === './simulation-irpc-pec-correction' ? {SimulationIrpcPecCorrection:()=>null} : name === './simulation-irpc-pec-plan'
? {SimulationIrpcPecPlan:()=>null}
: name === '@/lib/irpc-annual-settlement'
? annual
: name === '@/lib/irpc-pec-obligation'
? investment
: name === '@/lib/fiscal-rational'
? rational
: name === './simulation-irpc-special'
? { QualificationFields: () => null }
: name === './fiscal-proof-parcel'
? { FiscalProofParcelFields: () => null }
: require(name),
module,
module.exports,
);
const Component = module.exports.SimulationIrpcPecObligation;
const text = (node) =>
typeof node === 'string' || typeof node === 'number'
? String(node)
: React.isValidElement(node)
? React.Children.toArray(node.props.children).map(text).join('')
: '';
const all = (node) =>
React.isValidElement(node)
? [node, ...React.Children.toArray(node.props.children).flatMap(all)]
: [];
function harness(c) {
let b = c.b;
return {
book: () => b,
render: () =>
Component({
draft: c.d,
book: b,
onChange: (next) => {
b = { ...b, pecObligation: next };
},
}),
click(label) {
const button = all(this.render()).find(
(n) => n.type === 'button' && text(n) === label,
);
assert.ok(button, label);
button.props.onClick();
},
change(label, value) {
const input = all(this.render()).find(
(n) => n.props['aria-label'] === label,
);
assert.ok(input, label);
input.props.onChange({ target: { value } });
},
};
}
test('actual PEC form reuses context, preserves hidden edits and explains first-year exception', () => {
const c = investmentCase(),
h = harness(c);
h.click('Simular PEC');
assert.equal(h.book().pecObligation.subjectNuit, c.b.subjectNuit);
assert.equal(h.book().pecObligation.previousTurnover, '');
h.change('Enquadramento PEC', 'ordinary_resident');
h.change('Ano de início efectivo da actividade — PEC', '2020');
h.change('Fonte do início de actividade — PEC', 'SYNTHETIC activity');
h.change('Exercício anterior — PEC', '2025');
h.change('Volume de negócios anterior — MZN', '10000000');
h.change('Fonte do volume de negócios — PEC', 'SYNTHETIC volume');
h.change('PPC efectivamente pagos no ano anterior — MZN', '10000');
h.change('Fonte dos PPC anteriores — PEC', 'SYNTHETIC actual PPC');
assert.match(text(h.render()), /40000/);
assert.match(text(h.render()), /2026-06/);
assert.deepEqual(h.book().pecPayments, c.b.pecPayments);
h.change('Ano de início efectivo da actividade — PEC', '2026');
assert.match(text(h.render()), /Não aplicável/);
assert.equal(h.book().pecObligation.previousTurnover, '10000000');
h.change('Ano de início efectivo da actividade — PEC', '2020');
assert.match(text(h.render()), /40000/);
const html = renderToStaticMarkup(
Component({
book: {
...c.b,
pecObligation: { ...plan(), subjectNuit: c.b.subjectNuit },
},
onChange: () => {},
}),
);
assert.match(html, /2026-10/);
assert.match(html, /Fonte e limites PEC/);
});