14 lines
4.8 KiB
JavaScript
14 lines
4.8 KiB
JavaScript
import test from 'node:test';import assert from 'node:assert/strict';import fs from 'node:fs';
|
|
import {buildProjectDossierRows} from '../../resources/js/lib/project-dossier.ts';
|
|
import {proactiveInvestmentRows} from '../../resources/js/lib/proactive-investment-report.ts';
|
|
const source=(id,need)=>({key:'opportunity:'+id,title:'SYNTHETIC QA '+id,version:3,analysis:{proactive:{version:1,group:'ideas',state:'hypothesis',need,proposal:'Solução '+id,basis:'Fixture pública sintética',limitations:'Não comprova procura real.',next_action:'Confirmar dados reais.',evidence:[{statement:'QA facto '+id,source:'QA exemplar',locator:'Fixture linha1',period:'2026',scope:'Piloto',coverage:'Sintética',verified_on:'2026-10-27'}]}}});
|
|
test('absent proactivity is a no-op for accepted dossiers',()=>{assert.deepEqual(proactiveInvestmentRows({}),[]);assert.deepEqual(proactiveInvestmentRows({context_applicability_snapshot:'{"version":1,"opportunity_choices":[]}'}),[]);assert.deepEqual(proactiveInvestmentRows({context_opportunity_snapshot:'unreadable-original-preserved'}),[]);});
|
|
test('each idea retains origin,source,need,limits without summing or inventing economic values',()=>{const choices=[{opportunity:source(1,'A')},{opportunity:source(2,'B')}],d={context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:choices})},r=proactiveInvestmentRows(d);assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,2);assert.match(JSON.stringify(r),/opportunity:1/);assert.match(JSON.stringify(r),/opportunity:2/);assert.match(JSON.stringify(r),/Hipótese analítica/);assert.match(JSON.stringify(r),/não é zero/);assert.equal(d.context_applicability_snapshot,JSON.stringify({version:1,opportunity_choices:choices}));});
|
|
test('consumer selection only reports its idea even when other source contexts are present',()=>{const choices=[{opportunity:source(1,'A')},{opportunity:source(2,'B')}],r=proactiveInvestmentRows({context_opportunity:'opportunity:2',context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:choices})});assert.doesNotMatch(JSON.stringify(r),/opportunity:1/);assert.match(JSON.stringify(r),/opportunity:2/);});
|
|
test('explicit consumer snapshot is retained and repeat references do not duplicate report rows',()=>{const a=source(1,'A');let r=proactiveInvestmentRows({context_opportunity_snapshot:JSON.stringify({choice:{opportunity:a}})});assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,1);r=proactiveInvestmentRows({context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:[{opportunity:a},{opportunity:a}]})});assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,1);});
|
|
test('portable API consumer snapshot produces an independently scoped report',()=>{const d=JSON.parse(fs.readFileSync(new URL('./fixtures/proactive-api-consumers.json',import.meta.url),'utf8'));const before=JSON.stringify(d);const perConsumer=d.consumer_contexts.map(c=>proactiveInvestmentRows(c.prefill.simulator));for(const rows of perConsumer)assert.equal(rows.filter(x=>x[1]==='Origem da análise e ideia').length,1);const r=perConsumer.flat();assert.equal(r.filter(x=>x[1]==='Origem da análise e ideia').length,2);assert.match(JSON.stringify(perConsumer[0]),/opportunity:399/);assert.doesNotMatch(JSON.stringify(perConsumer[0]),/opportunity:400/);assert.match(JSON.stringify(perConsumer[1]),/opportunity:400/);assert.doesNotMatch(JSON.stringify(perConsumer[1]),/opportunity:399/);assert.doesNotMatch(JSON.stringify(r),/PRIVATE-QA-/);assert.equal(JSON.stringify(d),before);});
|
|
|
|
test('resources,assumptions and selected relationships are retained in the existing dossier report',()=>{const a=source(7,'A');Object.assign(a.analysis.proactive,{resources:'QA recurso declarado',assumptions:'QA pressuposto explícito',conditions:'QA condição',relations:[{kind:'project',target_id:'QA-reference',label:'QA projecto existente',relationship:'hypothesis',basis:'QA fundamento público'}]});const draft={context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:[{opportunity:a}]})},rows=buildProjectDossierRows(draft);assert.match(JSON.stringify(rows),/QA pressuposto explícito/);assert.match(JSON.stringify(rows),/QA projecto existente/);assert.match(JSON.stringify(rows),/sem contrato, acesso ou participação presumidos/);});
|
|
|
|
test('existing facts hide unrelated need and idea rows without deleting previous preparation',()=>{const a=source(8,'Old need');a.analysis.proactive.group='exists';a.analysis.proactive.proposal='Old idea';const d={context_applicability_snapshot:JSON.stringify({version:1,opportunity_choices:[{opportunity:a}]})},before=d.context_applicability_snapshot,r=proactiveInvestmentRows(d);assert.equal(r.some(x=>x[1]==='Estado da necessidade'||x[1]==='Proposta de investimento'),false);assert.equal(d.context_applicability_snapshot,before);assert.match(JSON.stringify(r),/QA facto 8/);});
|