import test from 'node:test'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { compileFunction } from 'node:vm'; import { createRequire } from 'node:module'; import { renderToStaticMarkup } from 'react-dom/server'; import ts from 'typescript'; const require = createRequire(import.meta.url); const root = new URL('../../', import.meta.url); const source = JSON.parse(fs.readFileSync(new URL('database/data/mining-reference-20261111.json', root))); // Public data follows exactly the service projection, while native QA verifies the route itself. const begin = source.risks.findIndex(x => x.startsWith('Riscos e pontos')); const end = source.risks.findIndex(x => x.startsWith('Próximos passos')); const data = { ...source, sector_slug:'mineracao', title:'Mineração e cadeias de valor', introduction:'Explore recursos minerais por localização.', group_label:'Grupo mineral', resource_heading:'Recursos e localização', resource_notice:'Conservar o âmbito territorial da fonte.', background:[], risks: source.risks.slice(begin + 1, end) }; data.groups=source.minerals.map(({province_names,...group})=>({...group,location_labels:province_names})); data.indicators=source.indicators.map(({mineral,value,source})=>({value,source,label:mineral})); delete data.original_paragraphs; data.areas = data.areas.map(({source_fields: _sourceFields,province_names,mineral_ids, ...area}) => ({...area,location_labels:province_names,group_ids:mineral_ids})); function load(file, mocks) { const code = ts.transpileModule(fs.readFileSync(new URL(file, root), 'utf8'), { compilerOptions: {module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022,jsx:ts.JsxEmit.ReactJSX}, }).outputText; const mod = {exports:{}}; compileFunction(code,['require','module','exports'])(key => mocks[key] ?? require(key),mod,mod.exports); return mod.exports.default; } function nodes(tree) { if (!tree || typeof tree !== 'object') return []; if (Array.isArray(tree)) return tree.flatMap(nodes); return [tree,...nodes(tree.props?.children)]; } const Link = ({children, ...props}) => require('react').createElement('a',props,children); function mount(url = '/sectores/mineracao', content = data) { const state = []; let cursor = 0; const Component = load('resources/js/components/sector-resource-reference.tsx', { react:{useState(initial) {const n=cursor++; if (!(n in state)) state[n]=initial; return [state[n],value=>state[n]=value];}}, '@inertiajs/react':{Link,usePage:()=>({url})}, }); return () => {cursor=0;return Component({data:content});}; } test('mineral and province filters keep value-chain selection in the existing investment route',()=>{ const render=mount(); let tree=render(); nodes(tree).find(n=>n.props?.['aria-label']==='Localização sectorial').props.onChange({target:{value:'Cabo Delgado'}}); tree=render(); nodes(tree).find(n=>n.props?.['aria-label']==='Grupo mineral').props.onChange({target:{value:'MINERAL-04'}}); tree=render(); const links=nodes(tree).filter(n=>n.type===Link); assert.equal(links.length,1); const url=new URL(links[0].props.href,'https://qa.invalid'); assert.equal(url.pathname,'/investimentos/a-partir-do-setor/mineracao'); assert.equal(url.searchParams.get('resource_area'),'MIN-02'); assert.equal(url.searchParams.get('resource_location'),'Cabo Delgado'); assert.equal(url.searchParams.get('resource_group'),'MINERAL-04'); assert.equal(url.searchParams.get('resource_source'),source.source_sha256); const html=renderToStaticMarkup(tree); assert.match(html,/Beneficiamento/); if (process.env.INVESTMOZ_MINING_QA_ARTIFACTS === '1') { const view=JSON.parse(fs.readFileSync(new URL('outputs/mining-reference-20261111/public-view.json',root))); for (const key of ['source_sha256','reference_date','groups','areas','projects','indicators','sources','risks']) assert.deepEqual(view[key],data[key]); fs.writeFileSync(new URL('outputs/mining-reference-20261111/Cabo-Delgado-Grafite.html',root),html); } }); test('return link filters and source uncertainty survive without invented map pins or publishing instructions',()=>{ const render=mount('/sectores/mineracao?resource_area=MIN-06&resource_location=Maputo'); const html=renderToStaticMarkup(render()); assert.match(html,/Maputo — província\/cidade a precisar/); assert.match(html,/Minerais industriais/); assert.doesNotMatch(html,/Próximos passos|documento gerador|seis requisitos|latitude|longitude/); const clear=nodes(render()).find(n=>n.type==='button');clear.props.onClick(); assert.ok(nodes(render()).filter(n=>n.type===Link).length>=1); }); test('selected mining context reaches both new and existing dossier actions',()=>{ let initial; const posted=[]; const selection={sector_slug:'mineracao',area_id:'MIN-02',group_id:'MINERAL-04',location_label:'Cabo Delgado',source_sha256:source.source_sha256,title:data.areas[1].title,value_chain:data.areas[1].value_chain}; const Component=load('resources/js/pages/investor-path/index.tsx',{ react:{useState:fn=>[typeof fn==='function'?fn():fn,()=>{}]}, '@/lib/operation-key':{createOperationKey:()=> 'SYNTHETIC-key'}, '@/lib/company-comparison':{}, '@/lib/investment-guides':{}, '@inertiajs/react':{Head:()=>null,Link,router:{post:(...args)=>posted.push(args)},useForm:data=>{initial=data;return {data,errors:{},processing:false,setData:()=>{},post:url=>posted.push([url,data])};}}, }); const tree=Component({contexts:[{id:'SYNTHETIC-case',version:3,title:'Synthetic dossier',updated_at:'2026-11-11'}],sectorSource:{slug:'mineracao',name:'Mineração',href:'/sectores/mineracao'},resourceSource:selection}); assert.deepEqual(initial.sector_reference,{area_id:selection.area_id,group_id:selection.group_id,source_sha256:selection.source_sha256,location_label:selection.location_label}); const button=nodes(tree).find(n=>n.type==='button' && n.props.onClick); button.props.onClick(); assert.equal(posted[0][0],'/investimentos/SYNTHETIC-case/sectores'); assert.deepEqual(posted[0][1].sector_reference,initial.sector_reference); nodes(tree).find(n=>n.type==='form').props.onSubmit({preventDefault(){}}); assert.equal(posted[1][0],'/investimentos'); assert.deepEqual(posted[1][1].sector_reference,initial.sector_reference); }); const energySource=JSON.parse(fs.readFileSync(new URL('database/data/energy-reference-20261111.json',root))); const energyData={...energySource,sector_slug:'energia-especifica',title:'Energia e cadeias de valor',introduction:'Prepare o investimento energético.',group_label:'Segmento energético',resource_heading:'Segmentos e âmbito territorial',resource_notice:'Conservar bacias,corredores e localidades.'}; test('energy solar selection preserves Niassa, batteries and the correct sector route',()=>{ const render=mount('/sectores/energia-especifica',energyData);let tree=render(); nodes(tree).find(n=>n.props?.['aria-label']==='Localização sectorial').props.onChange({target:{value:'Niassa'}}); tree=render();nodes(tree).find(n=>n.props?.['aria-label']==='Segmento energético').props.onChange({target:{value:'EN-SOLAR'}}); tree=render();const links=nodes(tree).filter(n=>n.type===Link);assert.equal(links.length,1); const url=new URL(links[0].props.href,'https://qa.invalid'); assert.equal(url.pathname,'/investimentos/a-partir-do-setor/energia-especifica'); assert.equal(url.searchParams.get('resource_area'),'ENE-07'); assert.equal(url.searchParams.get('resource_location'),'Niassa'); assert.equal(url.searchParams.get('resource_group'),'EN-SOLAR'); const html=renderToStaticMarkup(tree); assert.match(html,/baterias|armazenamento/);assert.match(html,/47,3 milhões EUR/);assert.match(html,/56 milhões USD/); assert.doesNotMatch(html,/Produção e recursos por período/); if(process.env.INVESTMOZ_MINING_QA_ARTIFACTS==='1'){ const view=JSON.parse(fs.readFileSync(new URL('outputs/energy-reference-20261111/public-view.json',root))); for(const key of ['groups','areas','projects','sources','risks','background'])assert.deepEqual(view[key],energyData[key]); fs.writeFileSync(new URL('outputs/energy-reference-20261111/Niassa-Solar.html',root),html); } }); test('energy studies without a named location stay selectable without assigning national coverage',()=>{ const tree=mount('/sectores/energia-especifica?resource_area=ENE-09',energyData)(); const links=nodes(tree).filter(n=>n.type===Link);assert.equal(links.length,1); const url=new URL(links[0].props.href,'https://qa.invalid'); assert.equal(url.searchParams.get('resource_location'),null); assert.equal(url.searchParams.get('resource_area'),'ENE-09'); const html=renderToStaticMarkup(tree);assert.match(html,/Sem implantação concreta/);assert.doesNotMatch(html,/latitude|longitude/); });