import test from 'node:test'; import assert from 'node:assert/strict'; import { getProjectReadiness, readPlannedRiskResponses, serializePlannedRiskResponses, } from '../../resources/js/lib/project-readiness.ts'; import { getSimulationSections } from '../../resources/js/lib/simulation-form.ts'; import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts'; void test('idea journey reuses one dossier and exposes the six requested stages', () => { const sections = getSimulationSections({ purpose: 'simulate_only', journey_type: 'small_business', }); assert.deepEqual( sections.map((section) => section.title), [ 'Ideia e objectivos', 'Clientes e mercado', 'Localização e recursos', 'Equipa e execução', 'Investimento e financiamento', 'Resultados, riscos e plano', ], ); }); void test('missing customer details remain visible even if the answer says yes', () => { const items = getProjectReadiness({ purpose: 'simulate_only', journey_type: 'small_business', customer_validation_status: 'yes', }); assert.ok( items.some( (item) => item.id === 'customers' && item.kind === 'missing', ), ); assert.ok( items.every( (item) => !('probability' in item) && !('severity' in item), ), ); }); void test('not applicable suppresses only the matching readiness prompts', () => { const items = getProjectReadiness({ target_customers: '', customer_validation_status: 'not_applicable', cost_estimate_status: 'not_applicable', location_assessment_status: 'not_applicable', funding_status: 'not_applicable', project_team_snapshot: '[]', }); assert.equal( items.some((item) => ['customers', 'costs', 'location', 'funding'].includes(item.id), ), false, ); }); void test('planned responses round-trip and invalid data is ignored', () => { const source = [ { risk_id: 'customers', action: 'Falar com clientes', owner: 'Equipa', estimated_cost: '20', due_date: '2026-11-10', }, ]; assert.deepEqual( readPlannedRiskResponses({ project_risk_responses_snapshot: serializePlannedRiskResponses(source), }), source, ); assert.deepEqual( readPlannedRiskResponses({ project_risk_responses_snapshot: 'invalid', }), [], ); }); void test('dossier report includes generated gaps and user response plans without inventing summary data', () => { const draft = { project_title: 'Projecto de teste', project_questionnaire_version: 'investmoz-project-dossier-2026-10-05.1', project_risk_responses_snapshot: JSON.stringify([ { risk_id: 'customers', action: 'Fazer entrevistas', owner: 'Equipa', estimated_cost: '', due_date: '', }, ]), }; const report = createProjectDossierReport(draft, { selectedSections: new Set(['summary', 'risk']), version: '1', }); const summary = report.sections.find((section) => section.id === 'summary'); const risk = report.sections.find((section) => section.id === 'risk'); assert.match(summary.paragraphs.join(' '), /Projecto de teste/); assert.match( risk.rows.map((row) => `${row.field}: ${row.value}`).join(' '), /Clientes ainda pouco definidos/, ); assert.match( risk.rows.map((row) => row.value).join(' '), /Fazer entrevistas/, ); assert.match( risk.rows.map((row) => row.value).join(' '), /Resposta planeada/, ); });