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

272 lines
9.2 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/editorial-edition.tsx',
import.meta.url,
),
'utf8',
);
const code = ts.transpileModule(source, {
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 === '../portfolio/shared')
return { labels: { description: 'Visão e proposta de valor' } };
if (name === '@inertiajs/react')
return {
Link: ({ href, children, ...rest }) =>
React.createElement('a', { href, ...rest }, children),
useForm: (data) => ({
data,
errors: {},
processing: false,
setData() {},
transform() {},
post() {},
}),
};
if (name === './shared')
return {
Management: ({ children }) =>
React.createElement('main', null, children),
Field: ({ label, children }) =>
React.createElement('label', null, label, children),
control: '',
button: '',
};
if (name === './editorial-workflow')
return {
states: {
draft: 'Rascunho',
approved: 'Aprovado',
in_review: 'Em revisão',
},
};
return require(name);
},
module,
module.exports,
);
const Page = module.exports.default;
const props = {
resource: {
id: 91,
title: 'Artigo QA',
published: true,
public_edition_no: 1,
},
manager: true,
legalReviewer: true,
current: true,
canApprove: true,
independentRequired: true,
history: [],
editions: [{ id: 'qa-edition', revision_no: 2, state: 'draft' }],
reviewers: [{ id: 5, name: 'Equipa de revisão' }],
edition: {
id: 'qa-edition',
revision_no: 2,
version: 1,
state: 'draft',
content_hash: 'a'.repeat(64),
fresh: true,
legal_required: false,
approval: null,
legal_validation: null,
payload: {
resource: {
title: 'Novo título',
editorial_content: JSON.stringify({
body: '<script>não executar</script>',
}),
},
files: [
{
id: 'qa-file',
file_name: 'anexo.pdf',
version_no: 2,
sha256: 'b'.repeat(64),
},
],
},
},
};
const render = (changes = {}) =>
renderToStaticMarkup(React.createElement(Page, { ...props, ...changes }));
test('draft preserves public version and offers submission without approval or publication', () => {
const html = render();
assert.match(html, /Versão pública: edição 1/);
assert.match(html, /value="submit"/);
assert.doesNotMatch(html, /value="(?:approve|publish)"/);
assert.match(
html,
/href="\/management\/editorial\/resources\/91\/editions\/qa-edition\/files\/qa-file" target="_blank" rel="noopener noreferrer"/,
);
assert.match(html, /&lt;script&gt;/);
assert.doesNotMatch(html, /<script>/);
});
test('approved edition offers explicit publication; stale files and historical versions cannot be published', () => {
assert.match(
render({
edition: { ...props.edition, state: 'approved', approval: '{}' },
}),
/value="publish"/,
);
const stale = render({
edition: { ...props.edition, state: 'approved', fresh: false },
});
assert.match(stale, /Os anexos mudaram/);
assert.doesNotMatch(stale, /value="publish"/);
const staleReview = render({
edition: { ...props.edition, state: 'in_review', fresh: false },
});
assert.match(staleReview, /value="return"/);
assert.doesNotMatch(staleReview, /value="approve"/);
const historical = render({ current: false });
assert.match(historical, /Versão histórica para consulta/);
assert.doesNotMatch(historical, /<form/);
assert.match(historical, /edition=qa-edition/);
});
test('contributor does not see independent approval or legal-validation actions', () => {
const html = render({
canApprove: false,
edition: { ...props.edition, state: 'in_review' },
});
assert.doesNotMatch(html, /value="(?:approve|legal_validate)"/);
assert.match(html, /responsável independente/);
});
test('portfolio edition reuses review screen with its own context, history and edit routes', () => {
const html = render({
subject: 'portfolio',
resource: { ...props.resource, id: 'qa-dossier' },
edition: {
...props.edition,
payload: {
...props.edition.payload,
resource: {
title: 'Ficha privada',
source: 'Fonte QA',
content: { description: '<script>não executar</script>' },
},
files: [],
links: [
{
target_type: 'projects',
target_key: 'qa-project',
context: { name: 'Projecto QA', code: 'QA-1' },
},
],
},
},
});
assert.match(html, /href="\/management\/portfolio\/qa-dossier"/);
assert.match(
html,
/\/management\/editorial\/portfolio\/qa-dossier\?edition=qa-edition/,
);
assert.match(html, /Visão e proposta de valor/);
assert.match(html, /Contexto: Projecto QA/);
assert.doesNotMatch(html, /Alterar artigo|Alterar metadados\/documento/);
assert.match(html, /&lt;script&gt;/);
});
test('portfolio contributor cannot select publication of an approved edition', () => {
assert.doesNotMatch(
render({
subject: 'portfolio',
canApprove: false,
edition: { ...props.edition, state: 'approved' },
}),
/value="publish"/,
);
assert.match(
render({
subject: 'portfolio',
canApprove: true,
edition: { ...props.edition, state: 'approved' },
}),
/value="publish"/,
);
});
test('portfolio review presents proposed base data and territory without applying them', () => {
const html = render({
subject: 'portfolio',
edition: {
...props.edition,
payload: {
...props.edition.payload,
resource: {
title: 'Ficha existente',
_structure: {
fields: {
name: 'Nome proposto',
budget_amount: '999999999999999999.99',
primary_territory_id: 'qa-district',
territory_version: 1,
},
territory_context: [
{ id: 'qa-district', name: 'Distrito sintético' },
],
},
},
files: [],
},
},
});
assert.match(html, /Alterações propostas nos dados-base/);
assert.match(html, /Nome proposto/);
assert.match(html, /999999999999999999.99/);
assert.match(html, /Localização proposta: Distrito sintético/);
assert.doesNotMatch(html, /qa-district|territory_version/);
});
test('demographic edition presents provenance, warnings and protected original with a separate publication step', () => {
const html = render({
subject: 'demography',
resource: { ...props.resource, id: 'qa-batch', published: false },
edition: {
...props.edition,
state: 'approved',
payload: {
...props.edition.payload,
resource: {
title: 'Exemplar sintético',
source: 'Fonte QA',
publication_version: 'Edição não indicada no original',
observations: 10,
sha256: 'a'.repeat(64),
dataset_hash: 'b'.repeat(64),
report: { issue_counts: { unit_not_supplied: 2 } },
},
files: [],
},
},
});
assert.match(html, /10 observações conferidas/);
assert.match(html, /Edição não indicada no original/);
assert.match(html, /unit_not_supplied: 2 advertências conservadas/);
assert.match(
html,
/href="\/management\/editorial\/demography\/qa-batch\/original"/,
);
assert.match(html, /value="publish"/);
assert.doesNotMatch(html, /Alterar artigo|Alterar ficha da carteira/);
});