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.default; } 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) : ''; function harness(file, initial, extra = {}) { const forms = [], cells = [], calls = []; let formCursor = 0, cursor = 0, serial = 0, tree, props = initial; const Empty = () => null; const Component = load(file, { react: { useState(initial) { const i = cursor++; if (!(i in cells)) cells[i] = initial; return [ cells[i], (value) => { cells[i] = value; }, ]; }, useRef(initial) { const i = cursor++; cells[i] ??= { current: initial }; return cells[i]; }, }, '@inertiajs/react': { Link: 'a', router: { reload() {} }, usePage: () => ({ url: '/synthetic', props: { auth: { user: { id: 1 } } }, }), useForm(initial) { const i = formCursor++; forms[i] ??= { data: { ...initial }, errors: {}, processing: false, setData(key, value) { this.data[key] = value; }, reset(...keys) { for (const key of keys) this.data[key] = initial[key]; }, put(url, options) { calls.push({ url, options, data: { ...this.data } }); }, }; return forms[i]; }, }, '@/lib/operation-key': { createOperationKey: () => `SYNTHETIC-${++serial}`, }, '@/pages/investment/shared': { Frame: 'main', card: '', input: '', button: '', }, '@/components/investor-guidance': { InvestorGuidance: Empty }, '@/components/desk-internal-operations': { DocumentReview: Empty }, '@/components/desk-document-picker': { default: Empty }, ...extra, }); function render(patch = {}) { props = { ...props, ...patch }; cursor = 0; formCursor = 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 dossier = { id: 'case-one', version: 1, closed_at: null }; const activity = { open_requests: 2, open_tasks: 1, pending_payments: 3 }; const state = (extra) => harness('../../resources/js/components/desk-case-state-form.tsx', { dossier, activity, ...extra, }); test('owner can explicitly close with recorded pending items and sends only state decision data', () => { const h = state(); h.find('textarea').props.onChange({ target: { value: 'SYNTHETIC owner reason' }, }); h.render(); h.submit(); assert.match(h.calls[0].url, /dossiers\/case-one\/estado$/); assert.deepEqual( Object.keys(h.calls[0].data).sort(), ['version', 'state', 'reason', 'client_key'].sort(), ); assert.equal(h.calls[0].data.state, 'closed'); assert.equal(h.calls[0].data.version, 1); assert.match( h.text(), /Pedidos em curso: 2.*tarefas em curso: 1.*comprovativos por conferir: 3/, ); }); test('success adopts actual server state and version for reopening and calls parent cleanup only for the same dossier', () => { let changed = 0; const h = state({ onChanged() { changed++; }, }); h.find('textarea').props.onChange({ target: { value: 'SYNTHETIC close reason' }, }); h.render(); h.submit(); const key = h.forms[0].data.client_key; h.calls[0].options.onSuccess({ props: { case: { ...dossier, version: 2, closed_at: '2026-11-03' } }, }); h.render({ dossier: { ...dossier, version: 2, closed_at: '2026-11-03' } }); assert.equal(h.forms[0].data.state, 'open'); assert.equal(h.forms[0].data.version, 2); assert.equal(h.forms[0].data.reason, ''); assert.notEqual(h.forms[0].data.client_key, key); assert.equal(changed, 1); h.calls[0].options.onSuccess({ props: { case: { id: 'other-case', version: 9 } }, }); assert.equal(changed, 1); assert.ok(h.find('button', 'Confirmar reabertura')); }); test('failed retry keeps operation identity and reason while editing or explicitly adopting new state starts a new intent', () => { const h = state(); h.find('textarea').props.onChange({ target: { value: 'SYNTHETIC deliberate reason' }, }); h.render(); h.submit(); h.submit(); assert.deepEqual(h.calls[0].data, h.calls[1].data); const key = h.forms[0].data.client_key; h.render({ dossier: { ...dossier, version: 3, closed_at: '2026-11-03' } }); assert.equal(h.find('button', 'Confirmar reabertura').props.disabled, true); h.submit(); assert.equal(h.calls.length, 2); h.find('button', 'Usar estado actual').props.onClick(); h.render(); assert.equal(h.forms[0].data.version, 3); assert.equal(h.forms[0].data.state, 'open'); assert.equal(h.forms[0].data.reason, 'SYNTHETIC deliberate reason'); assert.notEqual(h.forms[0].data.client_key, key); }); test('unknown optional counts remain unknown and in-flight business work disables the decision', () => { const h = state({ activity: { open_requests: 0, open_tasks: null, pending_payments: null, }, disabled: true, }); assert.match( h.text(), /Pedidos em curso: 0.*tarefas em curso: por confirmar.*comprovativos por conferir: por confirmar/, ); assert.equal( h.find('button', 'Confirmar encerramento').props.disabled, true, ); h.submit(); assert.equal(h.calls.length, 0); }); test('case exposes owner control separately from ordinary writing and clears unassociated file consent after success', () => { const State = () => null; const base = { case: { ...dossier, closed_at: '2026-11-03', title: 'SYNTHETIC owner dossier', workflow: {}, }, canWrite: false, canChangeState: true, activity, manager: false, requests: [], services: [], documents: [], workflow: {}, stepStates: {}, states: {}, guidance: null, events: [], links: [], legacyRequest: null, }; const h = harness('../../resources/js/pages/desk/case.tsx', base, { '@/components/desk-case-state-form': { default: State }, }); let widget = h.all().find((n) => n.type === State); assert.ok(widget); h.forms[2].setData('file', { name: 'SYNTHETIC unsent file' }); h.forms[2].setData('consent', true); widget.props.onChanged(); assert.equal(h.forms[2].data.file, null); assert.equal(h.forms[2].data.consent, false); h.forms[2].processing = true; h.render(); widget = h.all().find((n) => n.type === State); assert.equal(widget.props.disabled, true); h.render({ canChangeState: false, canWrite: true, manager: true }); assert.equal( h.all().some((n) => n.type === State), false, ); });