120 lines
8.8 KiB
JavaScript
120 lines
8.8 KiB
JavaScript
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/);
|
|
});
|