import assert from 'node:assert/strict'; import test from 'node:test'; import fs from 'node:fs'; import {createRequire} from 'node:module'; import React from 'react'; import ts from 'typescript'; // Exercise the real component's event/state contract; this is not browser visual QA. const require=createRequire(import.meta.url); const source=fs.readFileSync(new URL('../../resources/js/components/territory-search-select.tsx',import.meta.url),'utf8'); const compiled=ts.transpileModule(source,{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022,jsx:ts.JsxEmit.ReactJSX}}).outputText; function harness(overrides={}){ const memory=[];let cursor=0;const chosen=[]; const hooks={...React,useState(initial){const i=cursor++;if(!(i in memory))memory[i]=initial;return[memory[i],value=>{memory[i]=typeof value==='function'?value(memory[i]):value;}];},useRef:()=>({current:null}),useEffect:()=>{}}; const module={exports:{}}; new Function('require','module','exports',compiled)(name=>name==='react'?hooks:require(name),module,module.exports); const options=[{id:'province-a',name:'Nampula'},{id:'province-b',name:'Maputo Província'}]; const props={id:'territory',label:'Província',search:'',options,onSearch(query){props.search=query;},onChange(option){chosen.push(option);props.selected=option;},...overrides}; let tree; const flat=node=>!node||typeof node!=='object'?[]:[node,...React.Children.toArray(node.props?.children).flatMap(flat)]; const render=()=>{cursor=0;tree=module.exports.default(props);return tree;}; const find=predicate=>flat(tree).find(predicate); const input=()=>find(node=>node.type==='input'); const key=value=>input().props.onKeyDown({key:value,preventDefault(){}}); render();return{props,chosen,render,find,input,key,options}; } test('one search input owns the dropdown; the separate select is absent',()=>{ const h=harness();assert.equal(h.find(node=>node.type==='select'),undefined); assert.equal(h.input().props.role,'combobox');assert.equal(h.input().props['aria-expanded'],false); h.input().props.onFocus();h.render(); assert.equal(h.input().props['aria-expanded'],true); assert.ok(h.find(node=>node.props?.role==='listbox')); h.find(node=>node.props?.role==='option'&&node.props.id==='territory-options-1').props.onClick();h.render(); assert.deepEqual(h.chosen,[h.options[1]]);assert.equal(h.input().props.value,'Maputo Província'); assert.equal(h.input().props['aria-expanded'],false); }); test('typing and Escape preserve the existing selection until an option is explicitly chosen',()=>{ const selected={id:'saved',name:'Selecção guardada fora desta página'};const h=harness({selected}); h.input().props.onFocus();h.render();h.input().props.onChange({target:{value:'Map'}});h.render(); assert.equal(h.props.search,'Map');assert.deepEqual(h.chosen,[]); h.key('Escape');h.render();assert.equal(h.input().props.value,selected.name);assert.deepEqual(h.chosen,[]); }); test('arrow keys and Enter choose from the list; loading cannot commit an old result',()=>{ const h=harness();h.input().props.onFocus();h.render();h.key('ArrowDown');h.render();h.key('ArrowDown');h.render(); assert.equal(h.input().props['aria-activedescendant'],'territory-options-1'); h.key('Enter');h.render();assert.deepEqual(h.chosen,[h.options[1]]); const busy=harness({loading:true});busy.input().props.onFocus();busy.render();busy.key('Enter'); assert.deepEqual(busy.chosen,[]); }); test('clear is explicit; disabled dependent levels cannot expose the dropdown',()=>{ const h=harness({selected:{id:'saved',name:'Nampula'}}); h.find(node=>node.props?.['aria-label']==='Limpar Província').props.onClick();h.render(); assert.deepEqual(h.chosen,[undefined]);assert.equal(h.input().props.value,''); const disabled=harness({disabled:true});assert.equal(disabled.input().props.disabled,true); assert.equal(disabled.find(node=>node.props?.role==='listbox'),undefined); });