+ Camadas ocultas. Active uma camada para voltar a consultar
+ os registos no mapa.
+
+ )}
+ 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('map layer choices preserve received records, coverage, unlocated links and filters without another request', 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 },
+ './territory-geometry-preview': { default: () => null },
+ './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);
+ flat(tree)
+ .filter((node) => node.type === 'input')[0]
+ .props.onChange({ target: { checked: false } });
+ tree = render();
+ assert.deepEqual(map().props.points, []);
+ assert.equal(map().props.areas.length, 1);
+ flat(tree)
+ .filter((node) => node.type === 'input')[1]
+ .props.onChange({ target: { checked: false } });
+ tree = render();
+ assert.deepEqual(map().props.areas, []);
+ const html = renderToStaticMarkup(tree);
+ assert.match(html, /Camadas ocultas/);
+ assert.match(html, /incluindo camadas ocultas/);
+ assert.match(html, /href="\/synthetic\/3"/);
+ assert.match(
+ html,
+ / | Marcadores de investimento<\/th> | 2<\/td>/,
+ );
+ for (const checkbox of flat(tree).filter(
+ (node) => node.type === 'input',
+ ))
+ checkbox.props.onChange({ target: { checked: true } });
+ 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/);
+ } finally {
+ cleanup?.();
+ globalThis.fetch = previousFetch;
+ }
+});
|