Files
Investidor-V2/tests/frontend/irpc-investment-carry-ui.test.mjs
T
2026-11-10 16:17:48 +02:00

122 lines
4.9 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-investment-credit.ts';
import { investmentCase } from './helpers/irpc-investment-case.mjs';
import { investmentCarryCase } from './helpers/irpc-investment-carry-case.mjs';
const require = createRequire(import.meta.url),
module = { exports: {} };
const source = fs.readFileSync(
new URL(
'../../resources/js/components/simulation-irpc-investment.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 === '@/lib/irpc-annual-settlement'
? annual
: name === '@/lib/irpc-investment-credit'
? investment
: name === './simulation-irpc-special'
? { QualificationFields: () => null }
: name === './fiscal-proof-parcel'
? { FiscalProofParcelFields: () => null }
: require(name),
module,
module.exports,
);
const Component = module.exports.SimulationIrpcInvestment;
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,
save: (next) => {
b = 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 } });
},
};
}
void test('actual form prepares carry without inventing qualification or erasing current assets', () => {
const c = investmentCase(),
before = structuredClone(c.b.investmentCredit.assets),
h = harness(c);
h.click('Preparar transporte de crédito de anos anteriores');
assert.equal(h.book().version, 3);
assert.equal(h.book().investmentCredit.version, 2);
assert.deepEqual(h.book().investmentCredit.assets, before);
assert.equal(h.book().investmentCredit.carryForward.useReconciled, '');
h.click('Acrescentar activo de origem anterior');
assert.equal(h.book().investmentCredit.assets.length, 2);
assert.equal(h.book().investmentCredit.assets[1].originYear, '');
assert.equal(annual.calculateAnnual(c.d, h.book()).arithmeticBalance, null);
});
void test('actual origin and use controls invalidate inconsistent credit and recover when reconciled', () => {
const c = investmentCarryCase(),
h = harness(c);
assert.deepEqual(annual.calculateAnnual(c.d, h.book()).pending, []);
h.change('CBF15 origem 1 — NUIT do contribuinte de origem', '999999999');
assert.equal(annual.calculateAnnual(c.d, h.book()).arithmeticBalance, null);
h.change(
'CBF15 origem 1 — NUIT do contribuinte de origem',
c.b.subjectNuit,
);
h.change('CBF15 origem 1 — Referência do projecto de origem', 'OTHER');
assert.equal(annual.calculateAnnual(c.d, h.book()).arithmeticBalance, null);
h.change(
'CBF15 origem 1 — Referência do projecto de origem',
c.b.investmentCredit.projectReference,
);
h.change('CBF15 origem 1 — Taxa original documentada — 5 ou 10', '10');
assert.equal(annual.calculateAnnual(c.d, h.book()).arithmeticBalance, null);
h.change('CBF15 origem 1 — Taxa original documentada — 5 ou 10', '5');
h.change('CBF15 — Montante de uso anterior', '600');
assert.equal(annual.calculateAnnual(c.d, h.book()).arithmeticBalance, null);
h.change('CBF15 — Montante de uso anterior', '100');
assert.deepEqual(annual.calculateAnnual(c.d, h.book()).pending, []);
h.change('CBF15 transporte — Reconciliação do uso', '');
assert.equal(annual.calculateAnnual(c.d, h.book()).arithmeticBalance, null);
assert.equal(h.book().investmentCredit.assets[0].originYear, '2025');
});