56 lines
4.0 KiB
JavaScript
56 lines
4.0 KiB
JavaScript
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/);
|
|
});
|