/* Exercise report rendering and CSV export using the production script. */ const assert=require('node:assert/strict'),fs=require('node:fs'),vm=require('node:vm'); const elements=new Map(),requests=[]; function element(id){if(!elements.has(id))elements.set(id,{innerHTML:'',textContent:'',hidden:false,disabled:false,dataset:{},value:'',insertAdjacentHTML(_,html){this.innerHTML+=html;}});return elements.get(id);} const form=element('absenceFilters');form.elements={start_date:element('absenceFrom'),end_date:element('absenceTo'),user_id:element('absenceEmployee')}; const item={id:1,kind:'vacation',name:'=Private spreadsheet formula',kind_label:'Ferie',starts_at:'2026-10-15T06:00:00Z',ends_at:'2026-10-16T14:00:00Z',norm_configured:true,planned_minutes:900,planned_days:2,actual_minutes:450,registered:true}; const result={employees:[{id:1,name:'One'}],summary:[{user_id:1,name:'One',norm_configured:true,planned_minutes:900,planned_days:2,actual_minutes:450}],items:[item],total:1,totals:{planned_minutes:900,planned_days:2,actual_minutes:450}}; result.type_summary=[{kind:'vacation',kind_label:'Ferie',periods:1,norm_configured:true,planned_minutes:900,planned_days:2,actual_minutes:450,employees:result.summary}]; let download=null; const context={window:{},Intl,Date,Number,String,Promise,URLSearchParams,Blob, FormData:class{constructor(form){this.values=Object.entries(form.elements).map(([key,input])=>[key,input.value]);}[Symbol.iterator](){return this.values[Symbol.iterator]();}}, document:{getElementById:element,createElement:()=>({click(){}})}, fetch:async path=>{requests.push(path);return{ok:true,json:async()=>result};}, URL:{createObjectURL:blob=>{download=blob;return 'blob:report';},revokeObjectURL(){}},setTimeout:()=>{}, }; vm.createContext(context);vm.runInContext(fs.readFileSync('static/js/absence-report.js','utf8'),context); (async()=>{ await new Promise(resolve=>setImmediate(resolve)); assert.match(element('absenceRows').innerHTML,/Tid registreret/); assert.match(element('absenceRows').innerHTML,/scope="rowgroup" colspan="8">Ferie/); assert.match(element('absenceSummary').innerHTML,/Ferie/); assert.match(element('absenceSummary').innerHTML,/One/); assert.equal(new URLSearchParams(requests[0].split('?')[1]).get('group_by'),'type'); assert.match(element('absenceTotals').innerHTML,/15 t/); assert.match(element('absenceTotals').innerHTML,/7,5 t/); assert.match(element('absenceRows').innerHTML,/