149 lines
4.4 KiB
JavaScript
149 lines
4.4 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);
|
|
const source = fs.readFileSync(
|
|
new URL(
|
|
'../../resources/js/pages/management/territorial-editorial.tsx',
|
|
import.meta.url,
|
|
),
|
|
'utf8',
|
|
);
|
|
const code = ts.transpileModule(source, {
|
|
compilerOptions: {
|
|
module: ts.ModuleKind.CommonJS,
|
|
target: ts.ScriptTarget.ES2022,
|
|
jsx: ts.JsxEmit.ReactJSX,
|
|
},
|
|
}).outputText;
|
|
let states = [],
|
|
index = 0;
|
|
const module = { exports: {} };
|
|
new Function('require', 'module', 'exports', code)(
|
|
(name) => {
|
|
if (name === 'react')
|
|
return {
|
|
...React,
|
|
useState: () => [states[index++], () => {}],
|
|
useEffect: () => {},
|
|
};
|
|
if (name === '@inertiajs/react')
|
|
return {
|
|
Link: ({ href, children }) =>
|
|
React.createElement('a', { href }, children),
|
|
};
|
|
if (name === '@/lib/portal-api')
|
|
return {
|
|
portalRequest: () => {
|
|
throw new Error('No SSR writes');
|
|
},
|
|
PortalApiError: Error,
|
|
};
|
|
if (name === './shared')
|
|
return {
|
|
Management: ({ children }) =>
|
|
React.createElement('main', null, children),
|
|
Field: ({ label, children }) =>
|
|
React.createElement('label', null, label, children),
|
|
button: '',
|
|
control: '',
|
|
};
|
|
return require(name);
|
|
},
|
|
module,
|
|
module.exports,
|
|
);
|
|
const state = {
|
|
location: {
|
|
id: 'qa',
|
|
name: 'Proposta privada',
|
|
code: 'QA',
|
|
location_type: 'country',
|
|
parent_id: null,
|
|
version_no: 5,
|
|
},
|
|
profile: {
|
|
source_id: 'qa-source',
|
|
valid_from: '2020-01-01',
|
|
valid_to: null,
|
|
status: 'approved',
|
|
editor_id: 1,
|
|
reviewer_id: 2,
|
|
},
|
|
public_version_no: 1,
|
|
fresh: true,
|
|
baseline_changed: false,
|
|
_editorial: { private: true, contributors: [1] },
|
|
};
|
|
function render({
|
|
roles = ['publishers'],
|
|
actorId = 3,
|
|
changes = {},
|
|
dirty = false,
|
|
} = {}) {
|
|
const working = { ...state, ...changes };
|
|
const form = {
|
|
name: dirty ? 'Alteração por guardar' : working.location.name,
|
|
code: 'QA',
|
|
source_id: 'qa-source',
|
|
valid_from: '2020-01-01',
|
|
valid_to: '',
|
|
reason: 'Decisão sintética QA',
|
|
confirm_baseline_change: false,
|
|
};
|
|
states = [
|
|
[],
|
|
null,
|
|
{
|
|
working,
|
|
public: {
|
|
...state,
|
|
location: {
|
|
...state.location,
|
|
name: 'Designação pública original',
|
|
},
|
|
profile: { ...state.profile, status: 'published' },
|
|
},
|
|
history: [],
|
|
},
|
|
form,
|
|
[],
|
|
false,
|
|
'',
|
|
{},
|
|
];
|
|
index = 0;
|
|
return renderToStaticMarkup(
|
|
React.createElement(module.exports.default, { roles, actorId }),
|
|
);
|
|
}
|
|
test('territorial approval keeps the public reference and requires a separate publisher', () => {
|
|
const html = render();
|
|
assert.match(html, /Designação pública original/);
|
|
assert.match(html, /Publicar versão aprovada/);
|
|
assert.match(html, /Versão pública: 1/);
|
|
assert.doesNotMatch(render({ actorId: 2 }), /Publicar versão aprovada/);
|
|
assert.doesNotMatch(render({ actorId: 1 }), /Publicar versão aprovada/);
|
|
assert.doesNotMatch(
|
|
render({ roles: ['editors'], actorId: 1 }),
|
|
/Retirar publicação actual/,
|
|
);
|
|
});
|
|
test('stale context and unsaved edits cannot silently enter a publication decision', () => {
|
|
assert.doesNotMatch(
|
|
render({ changes: { fresh: false } }),
|
|
/Publicar versão aprovada/,
|
|
);
|
|
const dirty = render({ roles: ['editors', 'publishers'], dirty: true });
|
|
assert.match(
|
|
dirty,
|
|
/<button[^>]*disabled=""[^>]*>Publicar versão aprovada<\/button>/,
|
|
);
|
|
assert.match(dirty, /Guarde as alterações antes/);
|
|
assert.match(dirty, /Guardar proposta privada/);
|
|
});
|