import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { createRequire } from 'node:module'; import { compileFunction } from 'node:vm'; 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, jsx: ts.JsxEmit.ReactJSX, target: ts.ScriptTarget.ES2022, }, }, ).outputText; const module = { exports: {} }; compileFunction(code, ['require', 'module', 'exports'])( (name) => mocks[name] ?? require(name), module, module.exports, ); return module.exports; } function nodes(tree) { if (Array.isArray(tree)) return tree.flatMap(nodes); if (!tree || typeof tree !== 'object') return []; return [tree, ...nodes(tree.props?.children)]; } const text = (tree) => typeof tree === 'string' ? tree : Array.isArray(tree) ? tree.map(text).join('') : tree?.props ? text(tree.props.children) : typeof tree === 'number' ? String(tree) : ''; const document = { id: 'link-one', document_id: 'original-one', file_name: 'SYNTHETIC proof.txt', version_no: 3, source_reference: 'SYNTHETIC document source', status: 'active', malware_scan_status: 'clean', }; const payment = { id: 'payment-one', reference: 'SYNTHETIC reference', amount: '25.50', currency: 'MZN', source_reference: 'SYNTHETIC amount purpose', document_id: null, version: 1, status: 'pending', verified_by: null, reason: null, }; const shared = { card: '', input: '', button: '' }; function formsHarness(file, defaults, pickerMock = {}) { const forms = [], calls = []; let cursor = 0, serial = 0, tree, props = defaults; const loaded = load(file, { '@inertiajs/react': { useForm(initial) { const i = cursor++; forms[i] ??= { data: { ...initial }, errors: {}, processing: false, setData(key, value) { this.data[key] = value; }, transform(callback) { this.transformer = callback; }, reset(...keys) { for (const key of keys) this.data[key] = initial[key]; }, put(url, options) { calls.push({ url, method: 'PUT', data: { ...this.data }, options, }); }, post(url, options) { calls.push({ url, method: 'POST', data: this.transformer ? this.transformer(this.data) : { ...this.data }, options, }); }, }; return forms[i]; }, }, '@/lib/operation-key': { createOperationKey: () => `synthetic-key-${++serial}`, }, '@/pages/investment/shared': shared, './desk-payment-document-form': pickerMock, }); const Component = loaded.default ?? loaded.RequestOperations; function render(patch = {}) { props = { ...props, ...patch }; cursor = 0; tree = Component(props); } render(); return { forms, calls, render, all: () => nodes(tree), text: () => text(tree), find: (type, label) => nodes(tree).find( (n) => n.type === type && (!label || text(n).includes(label)), ), submit() { nodes(tree) .find((n) => n.type === 'form') .props.onSubmit({ preventDefault() {} }); }, }; } const proofHarness = () => formsHarness( '../../resources/js/components/desk-payment-document-form.tsx', { requestId: 'request-one', payment, documents: [document] }, ); test('adding proof to a pending payment sends only new documentary facts and conserves financial declaration', () => { const h = proofHarness(); h.find('select').props.onChange({ target: { value: document.id } }); h.render(); h.find('textarea').props.onChange({ target: { value: 'SYNTHETIC reason' }, }); h.render(); h.find('input').props.onChange({ target: { checked: true } }); h.render(); h.submit(); assert.match(h.calls[0].url, /pagamentos\/payment-one\/comprovativo$/); assert.equal(h.calls[0].method, 'PUT'); assert.deepEqual( Object.keys(h.calls[0].data).sort(), [ 'version', 'document_link_id', 'reason', 'consent', 'client_key', ].sort(), ); assert.equal(h.calls[0].data.document_link_id, document.id); assert.equal(h.calls[0].data.version, 1); assert.equal(h.calls[0].data.consent, true); assert.match( h.text(), /referência, o valor e a moeda já registados são conservados/, ); assert.equal(h.all().filter((n) => n.type === 'input').length, 1); }); test('failed retry keeps payload and operation key while editing deliberately starts a new operation', () => { const h = proofHarness(); h.forms[0].setData('document_link_id', document.id); h.forms[0].setData('reason', 'SYNTHETIC original reason'); h.forms[0].setData('consent', true); h.submit(); h.submit(); assert.deepEqual(h.calls[0].data, h.calls[1].data); const original = h.forms[0].data.client_key; h.find('textarea').props.onChange({ target: { value: 'SYNTHETIC edited reason' }, }); h.render(); assert.notEqual(h.forms[0].data.client_key, original); assert.equal(h.forms[0].data.consent, false); assert.equal(h.forms[0].data.document_link_id, document.id); h.forms[0].setData('consent', true); h.submit(); const key = h.forms[0].data.client_key; h.calls.at(-1).options.onSuccess(); h.render({ payment: { ...payment, version: 2 } }); assert.equal(h.forms[0].data.version, 2); assert.equal(h.forms[0].data.reason, ''); assert.equal(h.forms[0].data.document_link_id, ''); assert.notEqual(h.forms[0].data.client_key, key); }); test('new server version requires deliberate adoption and does not erase reason or selected proof', () => { const h = proofHarness(); h.forms[0].setData('document_link_id', document.id); h.forms[0].setData('reason', 'SYNTHETIC unsaved reason'); h.forms[0].setData('consent', true); h.render({ payment: { ...payment, version: 3 } }); assert.equal(h.find('button', 'Guardar comprovativo').props.disabled, true); h.submit(); assert.equal(h.calls.length, 0); h.find('button', 'Usar versão actual').props.onClick(); h.render(); assert.equal(h.forms[0].data.version, 3); assert.equal(h.forms[0].data.document_link_id, document.id); assert.equal(h.forms[0].data.reason, 'SYNTHETIC unsaved reason'); assert.equal(h.forms[0].data.consent, false); }); test('read-only operations preserve payment history without offering manual business forms', () => { const Proof = () => null; const h = formsHarness( '../../resources/js/components/desk-internal-operations.tsx', { requestId: 'request-one', owner: false, reviewer: false, documents: [document], payments: [payment], }, { default: Proof }, ); assert.match(h.text(), /SYNTHETIC reference/); assert.match(h.text(), /Comprovativo ainda não associado/); assert.equal(h.all().filter((n) => n.type === 'form').length, 0); assert.equal(h.all().filter((n) => n.type === Proof).length, 0); h.render({ payments: [{ ...payment, document_id: document.document_id }] }); assert.match(h.text(), /metadados da associação não capturados à época/); }); test('only pending or disputed payment offers proof correction and creation uses exact link without copying amount provenance', () => { const Proof = () => null; const h = formsHarness( '../../resources/js/components/desk-internal-operations.tsx', { requestId: 'request-one', owner: true, reviewer: false, documents: [document], payments: [ payment, { ...payment, id: 'verified', status: 'internal_verified' }, { ...payment, id: 'issue', status: 'internal_issue' }, ], }, { default: Proof }, ); assert.equal(h.all().filter((n) => n.type === Proof).length, 2); const selector = h .all() .find( (n) => n.type === 'select' && n.props.value === h.forms[0].data.document_link_id, ); assert.ok( nodes(selector).some( (n) => n.type === 'option' && n.props.value === document.id, ), ); selector.props.onChange({ target: { value: document.id } }); h.render(); assert.equal(h.forms[0].data.document_link_id, document.id); assert.equal(h.forms[0].data.source_reference, ''); assert.equal(h.forms[0].data.amount, ''); }); test('historical evidence shows the frozen file version and separates documentary reference from amount purpose', () => { const h = formsHarness( '../../resources/js/components/desk-internal-operations.tsx', { requestId: 'request-one', owner: false, reviewer: false, documents: [], payments: [ { ...payment, document_id: document.document_id, document_evidence: { link_id: document.id, file_name: document.file_name, document_version: 3, source_reference: document.source_reference, valid_until: '2028-01-02', }, }, ], }, { default: () => null }, ); assert.match(h.text(), /Fonte do valor: SYNTHETIC amount purpose/); assert.match( h.text(), /SYNTHETIC proof.txt.*versão 3.*SYNTHETIC document source.*2028-01-02/, ); });