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 === './editorial-subject-form') return { default: () => null }; 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 === '@/lib/editorial-states') 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: '', }), }, 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, /<script>/); assert.doesNotMatch(html, /' }, }, 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, /<script>/); }); 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/); });