Files
Investidor-V2/tests/frontend/territorial-editorial.test.mjs
T

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/);
});