import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { createRequire } from 'node:module'; import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import ts from 'typescript'; const require = createRequire(import.meta.url); let states = [], formData; const mockReact = { ...React, useState: initial => [states.length ? states.shift() : initial, () => {}], useEffect() {} }; function load(file, appended = '') { const code = ts.transpileModule(fs.readFileSync(new URL('../../resources/js/pages/' + file, import.meta.url), 'utf8') + appended, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, jsx: ts.JsxEmit.ReactJSX } }).outputText; const module = { exports: {} }; new Function('require', 'module', 'exports', code)(name => { if (name === 'react') return mockReact; if (name === 'react/jsx-runtime') return require(name); if (name === '@inertiajs/react') return { useForm: data => { formData = data; return {data, errors: {}, processing: false, setData() {}, post() {}}; } }; if (name === './shared') return { Field: ({label, children}) => React.createElement('label', null, label, children), button: '', control: '', input: '', card: '' }; return {}; }, module, module.exports); return module.exports; } const { ZoneReview, ZoneHistory } = load('investment/zone.tsx', '\nexport { ZoneReview, ZoneHistory };'); const SubjectForm = load('management/editorial-subject-form.tsx').default; const zone = { id: 'synthetic-zone', version_no: 8, editorial_workflow: { state: 'in_review', content_version: 3, fresh: true, can_approve: true } }; const renderReview = (patch = {}, dirty = false) => { states = ['Documentary review reason']; return renderToStaticMarkup(React.createElement(ZoneReview, {zone: {...zone, editorial_workflow: {...zone.editorial_workflow, ...patch}}, busy: false, dirty, action() {}})); }; test('zone review separates approval from publication and hides unauthorised approval', () => { const html = renderReview(); assert.match(html, /Aprovar esta edição/); assert.doesNotMatch(html, />Publicar/); assert.doesNotMatch(renderReview({can_approve: false}), /Aprovar esta edição/); }); test('changed sources and unsaved edits disable decisions without hiding the history', () => { for (const html of [renderReview({fresh: false}), renderReview({}, true)]) assert.match(html, /disabled=""[^>]*>Aprovar esta edição/); assert.match(renderReview({fresh: false}), /fonte ou anexos mudaram/); }); test('history displays exact observation and source without applying it', () => { states = [{version_no: 4, fields: {name: 'Historical zone', description: 'Preserved description'}, observations: [{label: 'Investment', value: '9007199254740.25', unit: 'MZN', scope: 'Synthetic zone', source_reference: 'Report page 2'}]}, '', false]; const html = renderToStaticMarkup(React.createElement(ZoneHistory, {id: 'synthetic-zone', revisions: [{version_no: 4, action: 'profile_prepared', created_at: '2026-11-14'}]})); assert.match(html, /9007199254740.25/); assert.match(html, /Report page 2/); assert.match(html, /preserva a versão actual/); assert.doesNotMatch(html, /Restaurar|Publicar/); }); test('structural form preserves revision and selected values and opens progressively', () => { const props = {base: '/management/editorial/subjects/projects/synthetic', revision: 7, fields: [{name: 'name', label: 'Designação', type: 'text', options: []}], initial: {name: 'Deliberate edit'}}; states = [false]; assert.doesNotMatch(renderToStaticMarkup(React.createElement(SubjectForm, props)), /textarea/); states = [true]; const html = renderToStaticMarkup(React.createElement(SubjectForm, props)); assert.equal(formData.expected_revision, 7); assert.equal(formData.fields.name, 'Deliberate edit'); assert.match(html, /Deliberate edit/); assert.match(html, /publicação expressa da decisão/); });