Files
Investidor-V2/tests/frontend/quick-opportunity-search.test.mjs
T
paulomassigue 705dc69d68
tests / ci (push) Canceled after 0s
pesquisa intelignte
2026-11-04 15:52:55 +02:00

134 lines
4.6 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.default;
}
function nodes(tree) {
if (!tree || typeof tree !== 'object') return [];
if (Array.isArray(tree)) return tree.flatMap(nodes);
return [tree, ...nodes(tree.props?.children)];
}
await test('the quick search has a native GET destination and submits the actual input value even after browser autofill', () => {
let sent, edited;
const Hero = load('../../resources/js/components/portal-hero.tsx', {
react: { useState: (initial) => [initial, () => {}], useEffect() {} },
'@inertiajs/react': {
Link: 'a',
router: {
get: (url, data) => {
sent = { url, data };
},
},
},
'lucide-react': { ArrowRight: () => null, Search: () => null },
});
const tree = Hero({
query: 'stale rendered value',
setQuery: (value) => {
edited = value;
},
});
const form = nodes(tree).find((node) => node.type === 'form');
const input = nodes(tree).find(
(node) => node.type === 'input' && node.props.name === 'q',
);
assert.equal(form.props.action, '/pesquisa');
assert.equal(form.props.method, 'get');
assert.equal(input.props.maxLength, 120);
input.props.onChange({ target: { value: 'plantio de algodao' } });
assert.equal(edited, 'plantio de algodao');
const original = globalThis.FormData;
try {
globalThis.FormData = class {
constructor(element) {
this.element = element;
}
get(key) {
assert.equal(key, 'q');
return this.element.value;
}
};
let prevented = false;
form.props.onSubmit({
preventDefault() {
prevented = true;
},
currentTarget: { value: ' plantio de algodao ' },
});
assert.equal(prevented, true);
assert.deepEqual(sent, {
url: '/pesquisa',
data: { q: 'plantio de algodao' },
});
} finally {
globalThis.FormData = original;
}
const html = renderToStaticMarkup(tree);
assert.ok(html.includes('Pesquisa rápida no InvesteMoz'));
assert.ok(html.includes('action="/pesquisa"'));
assert.ok(html.includes('Pesquisar'));
});
await test('related processing fiches are explicitly distinct from the requested cultivation and disappear during pending or failed searches', () => {
const Related = load(
'../../resources/js/components/opportunity-related-results.tsx',
{ '@inertiajs/react': { Link: 'a' } },
);
const related = {
query: 'plantio de algodao',
subject: 'algodao',
href: '/oportunidades?sector=qa&q=algodao',
items: [
{
id: 1,
slug: 'synthetic-processing',
title: 'Synthetic processing',
summary: 'Descaroçamento e transformação de algodão.',
},
],
};
const props = { related, loading: false, error: '', total: 0 };
const html = renderToStaticMarkup(Related(props));
assert.ok(
html.includes('não correspond') ||
html.includes(
'Não encontrámos fichas que correspondam a todos os termos',
),
);
assert.ok(html.includes('outras etapas da cadeia'));
assert.ok(html.includes('Descaroçamento e transformação de algodão'));
assert.ok(html.includes('q=plantio+de+algodao'));
assert.ok(html.includes('Ver a pesquisa relacionada'));
for (const state of [
{ loading: true },
{ error: 'failure' },
{ total: 1 },
{ related: null },
]) {
assert.equal(Related({ ...props, ...state }), null);
}
});