const assert = require('node:assert/strict'); const fs = require('node:fs'); const vm = require('node:vm'); const source = fs.readFileSync('app/modules/hardware/templates/detail.html','utf8'); const script = source.slice(source.indexOf(' let quickRentCaseGeneration'),source.indexOf(' async function submitQuickRent()')).replaceAll('{{ hardware.id }}','1'); const nodes = {}; const get = id => nodes[id] ||= {value:'',disabled:false,hidden:false,textContent:'',options:[],add(option){this.options.push(option);}}; let calls = [], refreshes = 0; const context = {document:{getElementById:get},Option:function(text,value){this.text=text;this.value=value;},encodeURIComponent,refreshQuickRentPlan(){refreshes++;},intakeFetch:async(url,options)=>{calls.push({url,options});return {cases:[{id:9,titel:'PC',status:'Ny'}],has_more:false};}}; vm.createContext(context); vm.runInContext(script,context); (async()=>{ await context.loadQuickRentCases(); assert.equal(calls.length,0); assert.equal(get('quickRentSagId').disabled,true); get('quickRentCustomerId').value='12'; get('quickRentCaseSearch').value='PC'; await context.loadQuickRentCases(); assert(calls[0].url.includes('customer_id=12&q=PC')); assert.equal(get('quickRentSagId').options[0].value,9); assert.equal(get('quickRentSagId').disabled,false); get('quickRentNewCaseTitle').value='Ny udlejning'; context.intakeFetch=async(url,options)=>{calls.push({url,options});return {id:10,titel:'Ny udlejning'};}; await context.createQuickRentCase(); const body=JSON.parse(calls.at(-1).options.body); assert.equal(body.customer_id,12); assert.deepEqual(body.hardware_ids,[1]); assert.equal(get('quickRentSagId').value,'10'); assert.equal(get('quickRentNewCasePanel').hidden,true); let finish; context.intakeFetch=()=>new Promise(resolve=>{finish=resolve;}); const pending=context.loadQuickRentCases(); get('quickRentCustomerId').value=''; await context.loadQuickRentCases(); finish({cases:[{id:99}],has_more:false}); await pending; assert.equal(get('quickRentSagId').disabled,true); console.log('Rental case picker OK: customer lookup, asset-linked creation, customer-change race'); })().catch(error=>{console.error(error);process.exitCode=1;});