Files
Investidor-V2/tests/frontend/investor-guidance.test.mjs
T
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

156 lines
5.1 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
guidanceFinance,
guidanceFinancialTools,
} from '../../resources/js/lib/investor-guidance-finance.ts';
import { buildProjectDossierRows } from '../../resources/js/lib/project-dossier.ts';
import { serializeFinancialToolsSnapshot } from '../../resources/js/lib/financial-calculators.ts';
import {
forecastBusinessPlan,
serializeBusinessPlanSnapshot,
compareBusinessScenarios,
} from '../../resources/js/lib/business-financial-plan.ts';
const assumptions = {
currency: 'MZN',
openingCash: '0',
products: [
{
label: 'Serviço',
monthlyUnits: '100',
unitPrice: '1000',
unitVariableCost: '400',
},
],
monthlyCollections: '90000',
salesCollectionLagMonths: null,
salesCollectionPercent: '100',
salesRecoverySchedule: [],
monthlyVariableCostPayments: '42000',
monthlyVariableCostPaymentsByPeriod: null,
monthlyInventoryPurchases: '40000',
inventoryPurchaseLeadMonths: 0,
inventoryPurchaseSchedule: null,
useInventoryPurchaseSchedule: false,
useProductInventorySchedule: false,
useSupplierPaymentTerms: false,
monthlyOperatingExpenses: '20000',
monthlyOperatingPayments: '18000',
monthlyPayrollExpense: '15000',
monthlyPayrollPayments: '15000',
assetInvestment: '100000',
inventory: '20000',
receivables: '10000',
openingReceivablesCollectionMonth: null,
openingReceivablesCollectionPercent: '100',
openingReceivablesInstallments: [],
openingPayablesInstallments: [],
payables: '5000',
equity: '80000',
shareholderLoans: '0',
bankLoanProceeds: '50000',
grants: '0',
assetDepreciation: '100000',
depreciationLifeMonths: 60,
monthlyInterestExpense: '1200',
monthlyInterestPayment: '1000',
monthlyPrincipalRepayment: '5000',
periods: 12,
};
void test('guidance reuses the dossier calculator report and preserves partial indeterminacy', () => {
const source = {
budgetPeriod: 'Mensal',
loan: {
principal: '',
rate: '',
months: '',
rateType: 'nominal',
periodMonths: '',
gracePeriods: '',
upfrontFee: '',
recurringFee: '',
},
breakEven: { fixed: '', price: '', variable: '' },
funding: { total: '1000', secured: '400' },
incomes: [{ label: 'Receita QA', amount: '300' }],
expenses: [{ label: 'Custo QA', amount: '200' }],
};
const draft = {
financial_tools_snapshot: serializeFinancialToolsSnapshot(source),
currency: 'MZN',
};
const result = guidanceFinancialTools(draft);
assert.deepEqual(
result.rows,
buildProjectDossierRows(draft).filter(
(row) => row[0] === 'Plano financeiro',
),
);
assert.deepEqual(result.assumptions, source);
assert.equal(
guidanceFinancialTools({ financial_tools_snapshot: '{"version":999}' }),
null,
);
assert.equal(guidanceFinancialTools(null), null);
});
void test('guidance keeps missing, malformed and unsupported financial snapshots indeterminate', () => {
for (const snapshot of [
undefined,
'',
'{}',
'{invalid',
'{"version":999,"plan":{}}',
]) {
const view = guidanceFinance(
snapshot ? { business_plan_snapshot: snapshot } : null,
);
assert.equal(view.status, 'indeterminate');
assert.equal(view.result, null);
}
});
void test('guidance uses exact deterministic outputs and preserves negative cash and original assumptions', () => {
const plan = { ...assumptions, monthlyCollections: '0' };
const snapshot = serializeBusinessPlanSnapshot(plan);
const view = guidanceFinance({ business_plan_snapshot: snapshot });
assert.equal(view.status, 'calculated');
assert.deepEqual(view.result, forecastBusinessPlan(view.assumptions));
assert.equal(view.result.endingCash.startsWith('-'), true);
assert.equal(view.tax, 'indeterminate');
assert.equal(view.scenarios, null);
assert.equal(snapshot, serializeBusinessPlanSnapshot(plan));
});
void test('guidance scenarios are the existing deterministic scenario tool without success probabilities', () => {
const scenario = {
...assumptions,
scenarioAdjustments: {
favorable: {
unitVolumePercent: '10',
unitPricePercent: '5',
unitCostPercent: '0',
operatingCostsPercent: '0',
cashCollectionsPercent: '10',
},
unfavorable: {
unitVolumePercent: '-10',
unitPricePercent: '-5',
unitCostPercent: '10',
operatingCostsPercent: '10',
cashCollectionsPercent: '-10',
},
},
};
const view = guidanceFinance({
business_plan_snapshot: serializeBusinessPlanSnapshot(scenario),
});
assert.deepEqual(
view.scenarios,
compareBusinessScenarios(view.assumptions),
);
assert.equal('success_probability' in view, false);
});