116 lines
10 KiB
JavaScript
116 lines
10 KiB
JavaScript
import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
|
|
import assert from 'node:assert/strict';
|
|
|
|
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';
|
|
|
|
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);
|
|
});
|
|
|
|
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');
|
|
});
|
|
|
|
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);
|
|
});
|
|
|
|
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'));
|
|
});
|
|
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']);
|
|
});
|
|
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,{});
|
|
});
|
|
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,'');
|
|
});
|
|
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,'');
|
|
});
|
|
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,{});
|
|
});
|
|
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/);
|
|
});
|
|
|
|
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);
|
|
});
|