59 lines
3.3 KiB
JavaScript
59 lines
3.3 KiB
JavaScript
|
|
const {test} = require('node:test');
|
||
|
|
const assert = require('node:assert/strict');
|
||
|
|
const vm = require('node:vm');
|
||
|
|
const fs = require('node:fs');
|
||
|
|
function setup(responses = [{ok:true}], confirm = true) {
|
||
|
|
const handlers = {}, calls = [], messages = [];
|
||
|
|
let reloads = 0;
|
||
|
|
const card = {dataset:{moveId:'8',version:'4',start:'2026-10-20T08:00:00',end:'2026-10-20T09:00:00',segmentStart:'2026-10-20T08:00:00'},classList:{add(){},remove(){}},getBoundingClientRect:()=>({top:196})};
|
||
|
|
const day = {dataset:{date:'2026-10-21'},classList:{add(){},remove(){}},getBoundingClientRect:()=>({top:100})};
|
||
|
|
const host = {dataset:{firstHour:'7'},addEventListener:(name,fn)=>{handlers[name]=fn;},querySelectorAll:()=>[]};
|
||
|
|
vm.runInNewContext(fs.readFileSync('static/js/case-slot-move.js','utf8'),{
|
||
|
|
document:{getElementById:()=>host},
|
||
|
|
window:{confirm:()=>confirm,showCaseFeedback:message=>messages.push(message),loadEmbeddedCasePlanner:async()=>{reloads++;}},
|
||
|
|
fetch:async(url,options)=>{calls.push({url,body:JSON.parse(options.body)});const r=responses.shift();return {...r,json:async()=>r.body||{}};},
|
||
|
|
});
|
||
|
|
const event = (target,y) => ({target:{closest:selector=>selector==='.case-slot-resize'?null:target},clientY:y,preventDefault(){},stopPropagation(){},dataTransfer:{setData(){}}});
|
||
|
|
return {handlers,calls,messages,card,day,event,reloads:()=>reloads};
|
||
|
|
}
|
||
|
|
test('move to another day and time preserves duration and version',async()=>{
|
||
|
|
const s=setup();
|
||
|
|
s.handlers.dragstart(s.event(s.card,208)); // Grab 7.5 minutes below start.
|
||
|
|
await s.handlers.drop(s.event(s.day,400));
|
||
|
|
assert.equal(s.calls[0].url,'/api/v1/planner/allocations/8');
|
||
|
|
assert.equal(s.calls[0].body.version,4);
|
||
|
|
const start=new Date(s.calls[0].body.starts_at),end=new Date(s.calls[0].body.ends_at);
|
||
|
|
assert.equal(start.getDate(),21);
|
||
|
|
assert.equal(start.getHours(),10);
|
||
|
|
assert.equal(start.getMinutes(),0);
|
||
|
|
assert.equal(end-start,3600000);
|
||
|
|
assert.equal(s.reloads(),1);
|
||
|
|
});
|
||
|
|
test('cancelled drag and unrelated drops do not write',async()=>{
|
||
|
|
const s=setup();
|
||
|
|
s.handlers.dragstart(s.event(s.card,196));
|
||
|
|
s.handlers.dragend();
|
||
|
|
await s.handlers.drop(s.event(s.day,400));
|
||
|
|
assert.equal(s.calls.length,0);
|
||
|
|
});
|
||
|
|
test('overlap can be confirmed; stale version is never forced',async()=>{
|
||
|
|
const s=setup([{ok:false,status:409,body:{detail:{message:'Overlap',conflict_status:'overlap'}}},{ok:true}]);
|
||
|
|
s.handlers.dragstart(s.event(s.card,196));
|
||
|
|
await s.handlers.drop(s.event(s.day,400));
|
||
|
|
assert.equal(s.calls.length,2);
|
||
|
|
assert.equal(s.calls[1].body.confirm_conflicts,true);
|
||
|
|
const stale=setup([{ok:false,status:409,body:{detail:{message:'Ændret af anden bruger',current:{version:5}}}}]);
|
||
|
|
stale.handlers.dragstart(stale.event(stale.card,196));
|
||
|
|
await stale.handlers.drop(stale.event(stale.day,400));
|
||
|
|
assert.equal(stale.calls.length,1);
|
||
|
|
assert.equal(stale.messages[0],'Ændret af anden bruger');
|
||
|
|
});
|
||
|
|
test('declining overlap restores server state',async()=>{
|
||
|
|
const s=setup([{ok:false,status:409,body:{detail:{message:'Overlap',conflict_status:'overlap'}}}],false);
|
||
|
|
s.handlers.dragstart(s.event(s.card,196));
|
||
|
|
await s.handlers.drop(s.event(s.day,400));
|
||
|
|
assert.equal(s.calls.length,1);
|
||
|
|
assert.equal(s.reloads(),1);
|
||
|
|
assert.equal(s.messages[0],'Overlap');
|
||
|
|
});
|