import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts'; import assert from 'node:assert/strict'; void test('legacy draft without a compatible source keeps its shape and identity', () => { const legacy = { activity_id: 'legacy-activity', infrastructure_needs: ['energia'], }; assert.equal(inheritSimulatorFields(legacy), legacy); assert.equal( Object.hasOwn( inheritSimulatorFields(legacy), 'compatible_fields_snapshot', ), false, ); }); import test from 'node:test'; import { inheritCompatibleFields, inheritSimulatorFields, reusedInvestmentValue, } from '../../resources/js/lib/context-inheritance.ts'; import { serializeBusinessPlanSnapshot } from '../../resources/js/lib/business-financial-plan.ts'; import { monthlySalesFromDraft } from '../../resources/js/lib/monthly-iva.ts'; import { restoreSimulationDraft, partitionSimulationDraft, } from '../../resources/js/lib/simulation-form.ts'; void test('known investment questions become editable summaries after save/recovery, while missing and deliberate edits remain questions', () => { const scope = 'dossier:A:simulator'; const source = { project_title: 'Florestas — Beira', project_summary: 'Preparar investimento florestal', province_id: 'p1', province_id_label: 'Sofala', sector_id: '3', sector_id_label: 'Agronegócio', }; const reused = inheritCompatibleFields(scope, {}, source, null); const draft = { ...reused.patch, context_reuse: reused.metadata, purpose: 'simulate_only', journey_type: 'investor', }; const saved = partitionSimulationDraft(draft); const recovered = restoreSimulationDraft( saved.personal_snapshot, saved.economic_snapshot, ); assert.equal( reusedInvestmentValue(scope, 'project_title', recovered), source.project_title, ); assert.equal( reusedInvestmentValue(scope, 'province_id', recovered), 'Sofala', ); assert.equal( reusedInvestmentValue(scope, 'sector_id', recovered), 'Agronegócio', ); assert.equal(reusedInvestmentValue(scope, 'district_id', recovered), null); assert.equal( reusedInvestmentValue( 'dossier:B:simulator', 'project_title', recovered, ), null, ); assert.equal( reusedInvestmentValue(scope, 'project_title', { ...recovered, project_title: 'Edição deliberada', }), null, ); assert.equal( reusedInvestmentValue(scope, 'project_title', { ...recovered, project_title: '', }), null, ); assert.equal( reusedInvestmentValue(scope, 'province_id', { ...recovered, province_id_label: '', }), null, ); assert.equal( reusedInvestmentValue(scope, 'currency', { ...recovered, currency: 'MZN', }), null, ); assert.equal( reusedInvestmentValue(scope, 'project_title', { ...recovered, context_reuse: 'invalid', }), null, ); }); void test('local geography and sector keep their labels when the dossier proposes different identifiers', () => { const scope = 'dossier:A:simulator'; const source = { province_id: 'p1', province_id_label: 'Sofala', district_id: 'd1', district_id_label: 'Dondo', sector_id: '3', sector_id_label: 'Agronegócio', }; const local = { province_id: 'p2', province_id_label: 'Gaza', district_id: 'd2', district_id_label: 'Outro distrito', sector_id: '4', sector_id_label: 'Turismo', }; const reconciliation = inheritCompatibleFields(scope, local, source, null); assert.deepEqual(reconciliation.patch, {}); assert.ok(reconciliation.conflicts.includes('province_id')); const first = inheritCompatibleFields(scope, {}, source, null); const changed = inheritCompatibleFields( scope, { ...first.patch, context_reuse: first.metadata }, { ...source, province_id: 'p3', province_id_label: 'Manica', district_id: '', district_id_label: '', }, first.metadata, ); assert.equal(changed.patch.province_id, 'p3'); assert.equal(changed.patch.province_id_label, 'Manica'); assert.equal(changed.patch.district_id, ''); assert.equal(changed.patch.district_id_label, ''); const stale = inheritCompatibleFields( scope, { province_id_label: 'Nome antigo' }, source, null, ); assert.equal(stale.patch.province_id, 'p1'); assert.equal(stale.patch.province_id_label, 'Sofala'); }); void test('investment entry selects the existing simulation route without replacing an earlier deliberate purpose', () => { const scope = 'dossier:A:simulator'; const source = { journey_type: 'investor', journey_type_label: 'Avaliar o meu investimento', purpose: 'simulate_only', purpose_label: 'Apenas simular', }; const first = inheritCompatibleFields(scope, {}, source, null); const values = { ...first.patch, context_reuse: first.metadata }; assert.equal( reusedInvestmentValue(scope, 'journey_type', values), 'Avaliar o meu investimento', ); assert.equal( reusedInvestmentValue(scope, 'purpose', values), 'Apenas simular', ); const old = inheritCompatibleFields( scope, { journey_type: 'small_business', purpose: 'seek_partner' }, source, null, ); assert.deepEqual(old.patch, {}); assert.equal( reusedInvestmentValue(scope, 'purpose', { purpose: 'seek_partner', context_reuse: old.metadata, }), null, ); }); void test('inherited source updates follow through recovery while local edits and deliberate clears survive', () => { const first = inheritCompatibleFields( 'dossier:A:simulator', {}, { currency: 'MZN', project_title: 'A' }, null, ); const saved = { ...first.patch, context_reuse: first.metadata }; const changed = inheritCompatibleFields( 'dossier:A:simulator', saved, { currency: 'USD', project_title: 'A2' }, saved.context_reuse, ); assert.deepEqual(changed.patch, { currency: 'USD', project_title: 'A2' }); const edited = inheritCompatibleFields( 'dossier:A:simulator', { ...saved, currency: 'EUR', project_title: '' }, { currency: 'USD', project_title: 'A2' }, saved.context_reuse, ); assert.deepEqual(edited.patch, {}); assert.deepEqual(edited.conflicts, ['currency', 'project_title']); const recovered = JSON.parse( JSON.stringify({ ...saved, currency: 'EUR', project_title: '' }), ); assert.deepEqual( inheritCompatibleFields( 'dossier:A:simulator', recovered, { currency: 'USD', project_title: 'A2' }, recovered.context_reuse, ).patch, {}, ); assert.ok(!first.metadata.includes('MZN')); assert.ok(!first.metadata.includes('project_title":"A')); }); void test('a different dossier cannot take ownership of existing values using another dossier metadata', () => { const first = inheritCompatibleFields( 'dossier:A:simulator', {}, { currency: 'MZN' }, null, ); const second = inheritCompatibleFields( 'dossier:B:simulator', first.patch, { currency: 'USD' }, first.metadata, ); assert.deepEqual(second.patch, {}); assert.deepEqual(second.conflicts, ['currency']); }); void test('a local geographic override protects the entire hierarchy', () => { const first = inheritCompatibleFields( 'A', {}, { province_id: 'p1', district_id: 'd1' }, null, ); const update = inheritCompatibleFields( 'A', { ...first.patch, province_id: 'p-local' }, { province_id: 'p2', district_id: 'd2' }, first.metadata, ); assert.deepEqual(update.patch, {}); }); void test('compatible currency and date reuse survives backend partition and new session recovery without invented tax scope', () => { const initial = inheritSimulatorFields({ currency: 'USD', expected_start_date: '2026-03-01', purpose: 'simulate_only', }); assert.equal(initial.fiscal_currency, 'USD'); assert.equal(initial.published_iva_currency, 'USD'); assert.equal(initial.opportunity_currency, 'USD'); assert.equal(JSON.parse(initial.monthly_iva_settings).start, '2026-03'); assert.equal(JSON.parse(initial.monthly_iva_settings).declared, false); assert.equal(initial.published_iva_date, undefined); assert.equal( inheritSimulatorFields({ expected_start_date: '2026-01-01', monthly_iva_settings: '[invalid stored input', }).monthly_iva_settings, '[invalid stored input', ); const saved = partitionSimulationDraft(initial, true); const recovered = restoreSimulationDraft( saved.economic_snapshot, saved.personal_snapshot, ); assert.equal(recovered.published_iva_currency, 'USD'); assert.strictEqual(inheritSimulatorFields(recovered), recovered); const changed = inheritSimulatorFields({ ...recovered, currency: 'EUR' }); assert.equal(changed.fiscal_currency, 'EUR'); const override = inheritSimulatorFields({ ...changed, fiscal_currency: 'MZN', published_iva_currency: '', }); assert.equal(override.fiscal_currency, 'MZN'); assert.equal(override.published_iva_currency, ''); }); void test('land consumer reuses geography inside an empty parcel and preserves all other parcel data', () => { const first = inheritCompatibleFields( 'land', { parcels: [ { area: '12', province_id: '' }, { area: '20', province_id: 'other' }, ], }, { parcels: [{ province_id: 'P', district_id: 'D' }] }, null, ); assert.equal(first.patch.parcels[0].area, '12'); assert.equal(first.patch.parcels[0].district_id, 'D'); assert.equal(first.patch.parcels[1].province_id, 'other'); const changed = inheritCompatibleFields( 'land', { parcels: [ { ...first.patch.parcels[0], area: '13' }, first.patch.parcels[1], ], }, { parcels: [{ province_id: 'P2' }] }, first.metadata, ); assert.equal(changed.patch.parcels[0].area, '13'); assert.equal(changed.patch.parcels[0].district_id, ''); }); void test('clearing an inherited zone reference clears only the inherited value, preserving a deliberate override', () => { const first = inheritCompatibleFields( 'A', {}, { special_zone_id: 'zone' }, null, ); assert.equal( inheritCompatibleFields( 'A', first.patch, { special_zone_id: '' }, first.metadata, ).patch.special_zone_id, '', ); assert.deepEqual( inheritCompatibleFields( 'A', { special_zone_id: 'local' }, { special_zone_id: '' }, first.metadata, ).patch, {}, ); }); void test('conflicting saved sales currency is explained instead of relabelled or converted', () => { const fields = [ 'openingCash', 'monthlyCollections', 'monthlyVariableCostPayments', 'monthlyInventoryPurchases', 'monthlyOperatingExpenses', 'monthlyOperatingPayments', 'monthlyPayrollExpense', 'monthlyPayrollPayments', 'assetInvestment', 'inventory', 'receivables', 'payables', 'equity', 'shareholderLoans', 'bankLoanProceeds', 'grants', 'assetDepreciation', 'monthlyInterestExpense', 'monthlyInterestPayment', 'monthlyPrincipalRepayment', ]; const plan = { ...Object.fromEntries(fields.map((key) => [key, '0'])), currency: 'MZN', periods: 4, depreciationLifeMonths: 60, products: [ { label: 'QA', monthlyUnits: '1', unitPrice: '100', unitVariableCost: '0', }, ], }; assert.throws( () => monthlySalesFromDraft({ currency: 'USD', business_plan_snapshot: serializeBusinessPlanSnapshot(plan), }), /projecção de vendas está em MZN.*projecto está em USD/, ); }); void test('report preserves consulted zone version and makes unsupported benefit explicit without inventing a fiscal result', () => { const context = { version: 1, context_revision: 3, zone: { title: 'Referência QA', version: 7, href: '/zonas/qa' }, fields: { currency: 'USD' }, }; const draft = { project_title: 'QA', currency: 'USD', context_applicability_snapshot: JSON.stringify(context), }; const saved = JSON.stringify(draft); const report = createProjectDossierReport(draft, { selectedSections: new Set(['sources']), }); assert.match(JSON.stringify(report), /Referência QA, versão 7/); assert.match( JSON.stringify(report), /Benefício fiscal da zona indeterminado/, ); assert.equal(JSON.stringify(draft), saved); });