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 React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import ts from 'typescript'; const require = createRequire(import.meta.url); function load(path, mocks = {}) { const source = fs.readFileSync(new URL(path, import.meta.url), 'utf8'); const output = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, jsx: ts.JsxEmit.ReactJSX, }, }).outputText; const module = { exports: {} }; compileFunction(output, ['require', 'module', 'exports'])( (name) => mocks[name] ?? require(name), module, module.exports, ); return module.exports.default; } const Coverage = load( '../../resources/js/components/investment-map-coverage.tsx', ); const flat = (node) => !node || typeof node !== 'object' ? [] : [node, ...React.Children.toArray(node.props.children).flatMap(flat)]; const data = { features: [ { geometry: { coordinates: [35, -20] }, properties: { id: 1, title: 'Synthetic point', url: '/synthetic/1', source_reference: 'Synthetic source', source_date: '2026-10-29', }, }, { geometry: { coordinates: [36, -21] }, properties: { id: 1, title: 'Synthetic unknown', url: '/synthetic/2', source_reference: ' ', source_date: null, }, }, ], areas: [ { title: 'Synthetic area', geometry: { type: 'Polygon', coordinates: [] }, url: '/synthetic/area', source_reference: 'Synthetic area source', source_date: '', }, ], unlocated: [{ id: 3, title: 'Synthetic unlocated', url: '/synthetic/3' }], truncated: true, matched_count: 8, }; void test('map coverage distinguishes returned counts, missing provenance and truncated coverage without changing data', () => { const before = JSON.stringify(data); const html = renderToStaticMarkup( React.createElement(Coverage, { points: data.features, areas: data.areas, unlocated: data.unlocated.length, truncated: true, }), ); assert.match( html, /as contagens abaixo não representam o total do cadastro/, ); assert.match( html, /Marcadores de investimento<\/th>2<\/td>1<\/td>1<\/td>/, ); assert.match( html, /Áreas e limites<\/th>1<\/td>0<\/td>1<\/td>/, ); assert.match( html, /Investimentos sem ponto público utilizável nesta consulta: 1/, ); assert.match(html, /Investimentos com ponto nesta resposta: 1/); assert.match( html, /Ausência de registos não significa ausência de investimento/, ); assert.equal(JSON.stringify(data), before); const empty = renderToStaticMarkup( React.createElement(Coverage, { points: [], areas: [], unlocated: 0, truncated: false, }), ); assert.doesNotMatch(empty, /As fichas continuam disponíveis abaixo/); assert.doesNotMatch(empty, /Resultados limitados/); }); void test('one layered map preserves records, coverage, unlocated links and applied filters without a duplicate map or nonadministrative inference', async () => { const previousFetch = globalThis.fetch; let resolve; const requests = []; globalThis.fetch = (url, options) => { requests.push({ url, options }); return new Promise((done) => { resolve = done; }); }; const memory = []; let cursor = 0; const effects = []; const hooks = { ...React, useState(initial) { const index = cursor++; if (!(index in memory)) memory[index] = initial; return [ memory[index], (value) => { memory[index] = typeof value === 'function' ? value(memory[index]) : value; }, ]; }, useEffect(callback) { effects.push(callback); }, }; const MapView = () => null; const SearchState = () => null; const Panel = load( '../../resources/js/components/investment-map-panel.tsx', { react: hooks, '@/components/search-state': { default: SearchState }, './catalogue-investment-map': { default: MapView }, './interactive-investment-map': { default: MapView }, './investment-map-coverage': { default: Coverage }, }, ); const render = () => { cursor = 0; effects.length = 0; return Panel({ filters: { province_id: 'synthetic-province' } }); }; let cleanup; try { assert.equal( flat(render()).some((node) => node.type === Coverage), false, ); cleanup = effects[0](); resolve({ ok: true, json: async () => data }); await new Promise((done) => setImmediate(done)); let tree = render(); assert.equal( flat(tree).find((node) => node.type === SearchState).props.error, '', ); assert.equal( flat(tree).find((node) => node.type === SearchState).props.total, 8, ); const map = () => flat(tree).find((node) => node.type === MapView); assert.equal(map().props.points.length, 2); assert.equal(map().props.areas.length, 1); assert.equal( flat(tree).filter((node) => node.type === MapView).length, 1, ); assert.equal( flat(tree).filter((node) => node.type === 'input').length, 0, ); assert.equal(map().props.territoryId, 'synthetic-province'); const html = renderToStaticMarkup(tree); assert.match(html, /incluindo camadas ocultas/); assert.match(html, /href="\/synthetic\/3"/); assert.match( html, /Marcadores de investimento<\/th>2<\/td>/, ); tree = render(); assert.equal(map().props.points, data.features); assert.equal(map().props.areas, data.areas); assert.equal(requests.length, 1); assert.match(requests[0].url, /province_id=synthetic-province/); cursor = 0; const changed = Panel({ filters: { geo_location_id: 'synthetic-park' }, }); const changedMap = flat(changed).find((node) => node.type === MapView); assert.equal(changedMap.props.territoryId, undefined); assert.equal(changedMap.props.points, null); assert.deepEqual(changedMap.props.areas, []); assert(!flat(changed).some((node) => node.type === Coverage)); } finally { cleanup?.(); globalThis.fetch = previousFetch; } });