110 lines
4.0 KiB
JavaScript
110 lines
4.0 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import JSZip from 'jszip';
|
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
import {
|
|
createProjectDossierReport,
|
|
createProjectDossierPrintHtml,
|
|
generateProjectDossierDocx,
|
|
generateProjectDossierPackage,
|
|
} from '../../resources/js/lib/project-dossier-report.ts';
|
|
import { inheritCompatibleFields } from '../../resources/js/lib/context-inheritance.ts';
|
|
|
|
void test('selected second opportunity survives actual Word and ZIP generation and the native print document', async () => {
|
|
const snapshot = JSON.stringify({
|
|
version: 1,
|
|
context_revision: 12,
|
|
consumer_opportunity: 'opportunity:309',
|
|
zone: { title: 'Parque Manica', version: 3, href: '/parques/manica' },
|
|
opportunity_choices: [
|
|
{
|
|
opportunity: {
|
|
key: 'opportunity:309',
|
|
title: 'Segunda oportunidade Manica',
|
|
},
|
|
},
|
|
],
|
|
land_preparation: { need: 'yes' },
|
|
path: {
|
|
steps: [
|
|
{
|
|
code: 'S10',
|
|
title: 'Terra Manica',
|
|
applicability: 'applicable',
|
|
state: 'preparing',
|
|
},
|
|
{
|
|
code: 'S13',
|
|
title: 'Financiamento',
|
|
applicability: 'not_needed_for_preparation',
|
|
reason: 'Sem financiamento externo neste ambito',
|
|
},
|
|
],
|
|
},
|
|
});
|
|
const report = createProjectDossierReport(
|
|
{
|
|
project_title: 'QA segunda oportunidade',
|
|
context_applicability_snapshot: snapshot,
|
|
},
|
|
{ selectedSections: new Set(['sources']) },
|
|
);
|
|
const html = await createProjectDossierPrintHtml(report, [], false);
|
|
assert.match(html, /Terra Manica/);
|
|
assert.match(html, /Sem financiamento externo neste ambito/);
|
|
assert.match(html, /opportunity:309/);
|
|
assert.match(html, /Segunda oportunidade Manica/);
|
|
assert.match(html, /Parque Manica/);
|
|
assert.doesNotMatch(html, /Sofala/);
|
|
const docx = await generateProjectDossierDocx(report, [], true);
|
|
const bytes = await docx.arrayBuffer();
|
|
const word = await JSZip.loadAsync(bytes);
|
|
const xml = await word.file('word/document.xml').async('string');
|
|
assert.match(xml, /opportunity:309/);
|
|
assert.match(xml, /Parque Manica/);
|
|
assert.doesNotMatch(xml, /Sofala/);
|
|
const bundle = await generateProjectDossierPackage(docx, [], true);
|
|
const zip = await JSZip.loadAsync(await bundle.arrayBuffer());
|
|
const inner = Object.keys(zip.files).find((name) => name.endsWith('.docx'));
|
|
assert.ok(inner);
|
|
assert.deepEqual(
|
|
await zip.file(inner).async('uint8array'),
|
|
new Uint8Array(bytes),
|
|
);
|
|
await mkdir('outputs/multi-opportunity-fix-20261023/treatment-exports', {
|
|
recursive: true,
|
|
});
|
|
await writeFile(
|
|
'outputs/multi-opportunity-fix-20261023/treatment-exports/second.docx',
|
|
new Uint8Array(bytes),
|
|
);
|
|
await writeFile(
|
|
'outputs/multi-opportunity-fix-20261023/treatment-exports/second.zip',
|
|
new Uint8Array(await bundle.arrayBuffer()),
|
|
);
|
|
await writeFile(
|
|
'outputs/multi-opportunity-fix-20261023/treatment-exports/second-print.html',
|
|
html,
|
|
);
|
|
});
|
|
|
|
void test('new common contact reuse preserves a deliberate contact and follows inherited contact only', () => {
|
|
const source = { email: 'qa@example.invalid', phone: '+258840001234' };
|
|
const a = inheritCompatibleFields(
|
|
'dossier:qa:land',
|
|
{ email: 'edited@example.invalid' },
|
|
source,
|
|
'',
|
|
);
|
|
assert.equal(a.patch.phone, source.phone);
|
|
assert.equal(a.patch.email, undefined);
|
|
const b = inheritCompatibleFields(
|
|
'dossier:qa:land',
|
|
{ email: 'edited@example.invalid', phone: source.phone },
|
|
{ ...source, phone: '+258840005678' },
|
|
a.metadata,
|
|
);
|
|
assert.equal(b.patch.phone, '+258840005678');
|
|
assert.equal(b.patch.email, undefined);
|
|
});
|