const test=require('node:test'),assert=require('node:assert/strict'); const {CommandRun,init}=require('../../static/js/case-create-commands.js'); const parser=require('../../static/js/case-commands.js'); const completion=require('../../static/js/case-command-suggestions.js'); test('creation commands target the new case and retry with the same UUID and payload',async()=>{ const calls=[];let fail=true; const run=new CommandRun(async(url,body)=>{calls.push({url,body:JSON.stringify(body)});if(fail){fail=false;throw new Error('offline');}return {};},()=> 'same-uuid'); const parsed=parser.parse('Sagens beskrivelse\n/undersag "Router"\n//tildel ct "Opsæt router"\n//tid 30m support "Opsætning"'); assert.equal(parsed.comment,'Sagens beskrivelse');assert.equal(parsed.errors.length,0); run.attach(198,parsed.commands); await assert.rejects(run.execute(),/offline/);assert.equal(run.pending.caseId,198); await run.execute();assert.equal(run.pending,null);assert.deepEqual(calls[0],calls[1]); assert.equal(calls[0].url,'/api/v1/sag/198/command-execute'); }); class Element { constructor(){this.children=[];this.listeners={};this.value='';this.selectionStart=0;this.selectionEnd=0;this.classList={toggle(){}};} append(...nodes){this.children.push(...nodes);}after(){}replaceChildren(){this.children=[];}setAttribute(){} addEventListener(type,fn){this.listeners[type]=fn;}focus(){} setSelectionRange(start,end){this.selectionStart=start;this.selectionEnd=end;} setRangeText(text,start,end){this.value=this.value.slice(0,start)+text+this.value.slice(end);this.setSelectionRange(start+text.length,start+text.length);} dispatchEvent(event){this.listeners[event.type]?.(event);} } async function fixture(handler){ const nodes=[],input=new Element(),button=new Element(); const root={document:{getElementById:id=>id==='beskrivelse'?input:id==='submitBtn'?button:{textContent:'{"users":[{"user_id":3,"username":"ct","full_name":"Christian Thomas"}],"groups":[]}'},createElement:()=>{const node=new Element();nodes.push(node);return node;},createTextNode:text=>({textContent:text})},CaseCommands:parser,CaseCommandSuggestions:completion,Event:class{constructor(type){this.type=type;}},crypto:{randomUUID:(()=>{let n=0;return ()=>`uuid-${++n}`;})()},sessionStorage:{getItem(){return null;},setItem(){},removeItem(){}},fetch:async(url,options)=>options&&handler?handler(url,JSON.parse(options.body)):({ok:true,json:async()=>({id:17})})}; init(root);await root.caseCreateCommands.ready; const type=text=>{input.value=text;input.setSelectionRange(text.length,text.length);input.dispatchEvent(new root.Event('input'));}; const press=key=>input.listeners.keydown({key,preventDefault(){}}); return {root,input,nodes,type,press}; } test('new case supports first-suggestion Enter, initials and automatic description quotes',async()=>{ const f=await fixture();f.type('Beskrivelse\n/ti');f.press('Enter');assert.equal(f.input.value,'Beskrivelse\n/tid '); f.type('Beskrivelse\n/tid 30m support ');assert.equal(f.input.value,'Beskrivelse\n/tid 30m support ""'); f.type('Beskrivelse\n/undersag "Router"\n//tildel ct');f.press('Enter'); assert.equal(f.input.value,'Beskrivelse\n/undersag "Router"\n//tildel ct ""'); }); test('Enter preserves closing quotes and prose stays separate from commands',async()=>{ const f=await fixture();f.type('Beskrivelse\n/todo "Opgave"');f.input.setSelectionRange(f.input.value.length-1,f.input.value.length-1);f.press('Enter'); assert.equal(f.input.value,'Beskrivelse\n/todo "Opgave"\n'); const parsed=f.root.caseCreateCommands.prepare();assert.equal(parsed.comment,'Beskrivelse');assert.equal(parsed.commands[0].title,'Opgave'); f.type('Beskrivelse\n/ukendt');assert.throws(()=>f.root.caseCreateCommands.prepare(),/Ukendt kommando/); }); test('a rejected command can be corrected on the same created case',async()=>{ const calls=[];let reject=true; const f=await fixture(async(url,body)=>{calls.push({url,body});return reject?{ok:false,status:400,json:async()=>({detail:'Initialerne er tvetydige'})}:{ok:true,json:async()=>({results:[]})};}); f.type('Beskrivelse\n/tildel ct "Overdrag"');f.root.caseCreateCommands.prepare(); await assert.rejects(f.root.caseCreateCommands.created({id:99}),/Sag #99 er oprettet/); assert.equal(f.input.readOnly,false);assert.equal(f.root.caseCreateCommands.pendingCaseId(),99); reject=false;f.type('Beskrivelse\n/tildel carlt "Overdrag"');await f.root.caseCreateCommands.retry(); assert.equal(calls[1].url,'/api/v1/sag/99/command-execute'); assert.equal(calls[1].body.commands[0].assignee,'carlt'); assert.notEqual(calls[0].body.request_id,calls[1].body.request_id); assert.equal(f.root.caseCreateCommands.hasPending(),false); });