178 lines
6.0 KiB
JavaScript
178 lines
6.0 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import { createRequire } from 'node:module';
|
|
import { compileFunction } from 'node:vm';
|
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
import ts from 'typescript';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
function load(file, mocks) {
|
|
const output = ts.transpileModule(
|
|
fs.readFileSync(new URL(file, import.meta.url), 'utf8'),
|
|
{
|
|
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;
|
|
}
|
|
const proximity = load('../../resources/js/components/similar-businesses.tsx', {
|
|
'@inertiajs/react': { Link: 'a' },
|
|
'@/lib/portal-api': {},
|
|
});
|
|
function nodes(tree) {
|
|
if (!tree || typeof tree !== 'object') return [];
|
|
if (Array.isArray(tree)) return tree.flatMap(nodes);
|
|
return [tree, ...nodes(tree.props?.children)];
|
|
}
|
|
const coverage = {
|
|
origin_id: 'qa-public-reference',
|
|
origin_title: '<Public reference>',
|
|
radius_km: 25,
|
|
origin_recorded_at: null,
|
|
with_public_point: 1,
|
|
without_public_point: 3,
|
|
source: 'Published register',
|
|
method: 'Geodesic, not road',
|
|
};
|
|
|
|
await test('catalogue preserves applied radius in detail links while edits affect only the next search, and clearing removes both proximity fields', () => {
|
|
let cursor = 0,
|
|
sent;
|
|
const state = [];
|
|
const Page = load(
|
|
'../../resources/js/pages/investment/business-marketplace.tsx',
|
|
{
|
|
react: {
|
|
useState(initial) {
|
|
const index = cursor++;
|
|
if (!(index in state))
|
|
state[index] =
|
|
typeof initial === 'function' ? initial() : initial;
|
|
return [
|
|
state[index],
|
|
(value) => {
|
|
state[index] =
|
|
typeof value === 'function'
|
|
? value(state[index])
|
|
: value;
|
|
},
|
|
];
|
|
},
|
|
},
|
|
'@inertiajs/react': {
|
|
Link: 'a',
|
|
router: {
|
|
get: (...args) => {
|
|
sent = args;
|
|
},
|
|
},
|
|
},
|
|
'./shared': {
|
|
Frame: 'div',
|
|
button: 'button',
|
|
card: 'card',
|
|
input: 'input',
|
|
},
|
|
'./business-types': {
|
|
businessModalities: { company_sale: 'Company sale' },
|
|
},
|
|
'@/components/investment-territory': {
|
|
TerritoryFields: () => null,
|
|
},
|
|
'@/components/opportunity-classification': {
|
|
ClassificationSummary: () => null,
|
|
},
|
|
'@/components/similar-businesses': proximity,
|
|
},
|
|
).default;
|
|
const props = {
|
|
filters: {
|
|
near_business: 'qa-public-reference',
|
|
radius_km: '25',
|
|
sector: '4',
|
|
},
|
|
geographicCoverage: coverage,
|
|
results: {
|
|
data: [
|
|
{
|
|
id: 'qa-near',
|
|
slug: 'qa-near',
|
|
title: 'Nearby',
|
|
modality: 'company_sale',
|
|
distance_km: 1.2,
|
|
location_recorded_at: '2026-10-02T10:00:00Z',
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const render = () => {
|
|
cursor = 0;
|
|
return Page(props);
|
|
};
|
|
let tree = render();
|
|
let html = renderToStaticMarkup(tree);
|
|
assert.match(html, /1 com ponto utilizável; 3 sem ponto público/);
|
|
assert.match(html, /<Public reference>/);
|
|
assert.match(html, /data não indicada/);
|
|
assert.match(html, /Distância aproximada em linha recta/);
|
|
nodes(tree)
|
|
.find((node) => node.type === 'input' && node.props.type === 'number')
|
|
.props.onChange({ target: { value: '10.5' } });
|
|
nodes(tree)
|
|
.find(
|
|
(node) =>
|
|
node.type === 'input' && node.props.id === 'business-search',
|
|
)
|
|
.props.onChange({ target: { value: 'next search' } });
|
|
tree = render();
|
|
html = renderToStaticMarkup(tree);
|
|
assert.match(
|
|
html,
|
|
/\/negocios\/qa-near\?near_business=qa-public-reference&radius_km=25&sector=4/,
|
|
);
|
|
assert.doesNotMatch(html, /qa-near\?[^"]*radius_km=10/);
|
|
nodes(tree)
|
|
.find((node) => node.type === 'form')
|
|
.props.onSubmit({ preventDefault() {} });
|
|
assert.equal(sent[1].radius_km, '10.5');
|
|
assert.equal(sent[1].near_business, 'qa-public-reference');
|
|
assert.equal(sent[1].sector, '4');
|
|
assert.equal(sent[1].q, 'next search');
|
|
nodes(tree)
|
|
.find((node) => node.type === 'input' && node.props.type === 'number')
|
|
.props.onChange({ target: { value: '' } });
|
|
tree = render();
|
|
nodes(tree)
|
|
.find((node) => node.type === 'form')
|
|
.props.onSubmit({ preventDefault() {} });
|
|
assert.equal('radius_km' in sent[1], false);
|
|
assert.equal('near_business' in sent[1], false);
|
|
assert.equal(sent[1].sector, '4');
|
|
});
|
|
|
|
await test('distance rendering rejects unknown or malformed values and keeps unknown source dates explicit', () => {
|
|
for (const distance of [null, undefined, -1, Infinity, NaN, '2'])
|
|
assert.equal(
|
|
proximity.BusinessDistance({ record: { distance_km: distance } }),
|
|
null,
|
|
);
|
|
const html = renderToStaticMarkup(
|
|
proximity.BusinessDistance({
|
|
record: { distance_km: 0, location_recorded_at: 'not-a-date' },
|
|
}),
|
|
);
|
|
assert.match(html, /0 km/);
|
|
assert.match(html, /data não indicada/);
|
|
});
|