95 lines
3.7 KiB
JavaScript
95 lines
3.7 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
import JSZip from 'jszip';
|
|
import {
|
|
calculateBudget,
|
|
calculateBreakEven,
|
|
restoreFinancialToolsSnapshot,
|
|
} from '../../resources/js/lib/financial-calculators.ts';
|
|
import { createInvestorDossierReport } from '../../resources/js/lib/investor-dossier-report.ts';
|
|
import {
|
|
createProjectDossierPrintHtml,
|
|
generateProjectDossierDocx,
|
|
} from '../../resources/js/lib/project-dossier-report.ts';
|
|
|
|
await test('persisted synthetic offer crosses the dossier boundary into location assumptions, calculation and private report', async () => {
|
|
// Produced by the guarded PHP integration test, never by an operational export.
|
|
const directory = new URL(
|
|
'../../outputs/offers-investment-continuity-20261114/',
|
|
import.meta.url,
|
|
);
|
|
const { path, saved } = JSON.parse(
|
|
readFileSync(
|
|
new URL('integrated-report-input.json', directory),
|
|
'utf8',
|
|
),
|
|
);
|
|
assert.equal(path.case.title, 'Synthetic acquisition acceptance');
|
|
assert.equal(
|
|
path.investment_context.fields.project_summary,
|
|
saved.project_summary,
|
|
);
|
|
assert.equal(path.investment_context.fields.province_id, saved.province_id);
|
|
const data = restoreFinancialToolsSnapshot(
|
|
path.results[0].financial_snapshot,
|
|
);
|
|
assert.ok(data);
|
|
assert.deepEqual(
|
|
data,
|
|
restoreFinancialToolsSnapshot(saved.financial_tools_snapshot),
|
|
);
|
|
const budget = calculateBudget(
|
|
data.incomes.map((row) => row.amount),
|
|
data.expenses.map((row) => row.amount),
|
|
);
|
|
const breakEven = calculateBreakEven(
|
|
data.breakEven.fixed,
|
|
data.breakEven.price,
|
|
data.breakEven.variable,
|
|
);
|
|
assert.equal(budget.operatingBalance, '7000.00');
|
|
assert.equal(breakEven.breakEvenUnits, '60');
|
|
// An explicit alternative location-cost assumption, not an inferred provincial tariff.
|
|
const alternative = calculateBudget(
|
|
data.incomes.map((row) => row.amount),
|
|
['5000', '3000'],
|
|
);
|
|
assert.equal(alternative.operatingBalance, '2000.00');
|
|
assert.deepEqual(
|
|
data.expenses.map((row) => row.amount),
|
|
['2000', '1000'],
|
|
);
|
|
const report = createInvestorDossierReport(path, '2026-11-14T12:00:00Z');
|
|
const html = await createProjectDossierPrintHtml(report, [], false);
|
|
assert.ok(html.includes(saved.project_summary));
|
|
assert.ok(html.includes('Synthetic province'));
|
|
assert.ok(!html.includes('60000.00'));
|
|
assert.ok(!html.includes('Synthetic private contact'));
|
|
const docx = await generateProjectDossierDocx(report, [], false);
|
|
const bytes = Buffer.from(await docx.arrayBuffer());
|
|
const zip = await JSZip.loadAsync(bytes);
|
|
const xml = await zip.file('word/document.xml').async('string');
|
|
assert.ok(xml.includes(saved.project_summary));
|
|
assert.ok(xml.includes('Synthetic province'));
|
|
assert.ok(!xml.includes('60000.00'));
|
|
writeFileSync(new URL('private-integrated-report.html', directory), html);
|
|
writeFileSync(new URL('private-integrated-report.docx', directory), bytes);
|
|
writeFileSync(
|
|
new URL('location-analysis.json', directory),
|
|
JSON.stringify(
|
|
{
|
|
scope: 'Synthetic investor-declared costs at the selected location; no automatic profitability or fiscal entitlement',
|
|
province_id: saved.province_id,
|
|
budget,
|
|
breakEven,
|
|
alternative,
|
|
source_offer: path.investment_context.selection.opportunity.key,
|
|
case_id: path.case.id,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
});
|