88 lines
7.3 KiB
JavaScript
88 lines
7.3 KiB
JavaScript
|
|
// Run with NODE_PATH pointing to a jsdom installation (no application dependency).
|
||
|
|
const {JSDOM} = require('jsdom');
|
||
|
|
const fs = require('node:fs');
|
||
|
|
const assert = require('node:assert/strict');
|
||
|
|
const source = fs.readFileSync('app/modules/sag/templates/create.html','utf8');
|
||
|
|
const script = source.match(/<script>([\s\S]*?)<\/script>/)[1];
|
||
|
|
const html = source.split('{% block content %}')[1].split('<script>')[0]
|
||
|
|
.replace(/\{% for user[\s\S]*?\{% endfor %\}/, '<option value="7">Test bruger</option>')
|
||
|
|
.replace(/\{% for group[\s\S]*?\{% endfor %\}/, '<option value="2">Support</option>');
|
||
|
|
const extension = fs.readFileSync('static/js/case-create.js','utf8');
|
||
|
|
const delay = ms => new Promise(r=>setTimeout(r,ms));
|
||
|
|
async function page(storage, userId=7, search='') {
|
||
|
|
const dom = new JSDOM(html,{url:`http://localhost:8001/sag/new${search}`,runScripts:'outside-only'});
|
||
|
|
const w=dom.window;
|
||
|
|
await new Promise(r=>w.addEventListener('DOMContentLoaded',r));
|
||
|
|
w.CSS = {escape:s=>s}; w.confirm=()=>true; w.alert=()=>{};
|
||
|
|
w.setTagPickerContext=()=>{}; w.tagPicker={showSelection:cb=>cb({id:9,name:'Hardware',color:'#112233'})};
|
||
|
|
w.bootstrap={Modal:class {show(){} hide(){}}};
|
||
|
|
w.fetch=async url=>({ok:true,json:async()=>{
|
||
|
|
if(url.includes('/settings/case_types'))return {value:'["ticket","pipeline","ordre","opgave","service","abonnement"]'};
|
||
|
|
if(url.includes('/auth/me/profile'))return {default_case_type:'ticket'};
|
||
|
|
if(url.includes('/auth/me'))return {id:userId};
|
||
|
|
if(url.includes('/pipeline/stages'))return [{id:1,name:'Tilbud'}];
|
||
|
|
if(url.includes('/case-create/workload'))return {total:0,items:[]};
|
||
|
|
if(url.includes('/case-create/contacts-open-cases'))return {5:{total:2,items:[{id:44,titel:'Eksisterende routerfejl',status:'åben',ansvarlig_navn:'Test bruger',deadline:null}]}};
|
||
|
|
if(url.includes('/case-create/templates'))return [{id:1,name:'Test',values:{type:'pipeline',titel:'Tilbud',beskrivelse:'Tekst',status:'åben',tag_ids:[9]}}];
|
||
|
|
if(url.includes('/tags?'))return [{id:9,name:'Hardware'},{id:10,name:'Router',type:'brand',catch_words:['router'],color:'#112233'}];
|
||
|
|
return [];
|
||
|
|
}});
|
||
|
|
if(storage)for(const [k,v] of Object.entries(storage))w.localStorage.setItem(k,v);
|
||
|
|
w.eval(script + '\n' + extension + '\nwindow.testSetCustomer = () => { selectedCustomer={id:11,name:"Firma"}; selectedContacts={}; renderSelections(); }; window.testSetContact = () => { selectedContacts={5:{id:5,name:"Ada"}}; renderSelections(); window.caseCreateUI.contactsChanged(); };'); w.document.dispatchEvent(new w.Event('DOMContentLoaded'));
|
||
|
|
await delay(60);
|
||
|
|
return dom;
|
||
|
|
}
|
||
|
|
(async()=>{
|
||
|
|
const dom=await page(),w=dom.window,d=w.document;
|
||
|
|
assert.equal(d.querySelectorAll('#cc-types > button[data-case-type]').length,4);
|
||
|
|
assert.equal(d.querySelectorAll('#cc-types > button[data-case-message]').length,1);
|
||
|
|
assert.equal(d.querySelectorAll('.cc-panel').length,6);
|
||
|
|
assert.equal(d.querySelectorAll('form#createForm').length,1);
|
||
|
|
for(const id of ['customerSearch','titel','beskrivelse','status','deadline','submitBtn'])assert.ok(d.getElementById(id).closest('#createForm'),id);
|
||
|
|
assert.match(d.getElementById('cc-workload').textContent,/0 åbne sager/);
|
||
|
|
assert.equal(w.caseCreateUI.validate(),false);
|
||
|
|
assert.equal(d.getElementById('cc-relations').open,true);
|
||
|
|
w.testSetCustomer();
|
||
|
|
await w.loadSelectedCustomerContacts(11);
|
||
|
|
const search=d.getElementById('contactSearch'), results=d.getElementById('contactResults');
|
||
|
|
assert.ok(results.classList.contains('d-none'),'Selecting company must not open contact results');
|
||
|
|
search.focus();assert.ok(results.classList.contains('d-none'),'Empty focus must not open results');
|
||
|
|
search.value='Fi';search.dispatchEvent(new w.Event('input',{bubbles:true}));assert.ok(!results.classList.contains('d-none'),'Explicit search opens results');
|
||
|
|
search.value='';search.dispatchEvent(new w.Event('input',{bubbles:true}));assert.ok(results.classList.contains('d-none'),'Clearing closes results');
|
||
|
|
w.testSetContact(); await delay(30);
|
||
|
|
assert.match(d.getElementById('cc-contact-cases').textContent,/Eksisterende routerfejl/);
|
||
|
|
assert.match(d.getElementById('cc-contact-cases').innerHTML,/\/sag\/44\/v3/);
|
||
|
|
d.getElementById('titel').value='Test oprettelse';
|
||
|
|
d.getElementById('beskrivelse').value='Router mister forbindelsen';d.getElementById('beskrivelse').dispatchEvent(new w.Event('input',{bubbles:true}));await delay(400);
|
||
|
|
assert.match(d.getElementById('cc-tag-suggestions').textContent,/Router/);
|
||
|
|
d.getElementById('pipeline_amount').value='123';
|
||
|
|
d.querySelector('[data-case-type="ordre"]').click();
|
||
|
|
w.addOrderLine('sale');d.querySelector('.order-description').value='Router';d.querySelector('.order-amount').value='50';
|
||
|
|
d.querySelector('[data-case-type="ticket"]').click();
|
||
|
|
assert.equal(d.getElementById('pipeline_amount').value,'123');
|
||
|
|
assert.equal(w.caseCreateUI.validate(),true);
|
||
|
|
w.confirm=()=>false;
|
||
|
|
d.getElementById('cc-template').value='1';d.getElementById('cc-template').dispatchEvent(new w.Event('change',{bubbles:true}));await delay(30);
|
||
|
|
assert.equal(d.getElementById('titel').value,'Test oprettelse');
|
||
|
|
w.confirm=()=>true;
|
||
|
|
d.getElementById('cc-tag-add').click();
|
||
|
|
d.getElementById('titel').dispatchEvent(new w.Event('input',{bubbles:true}));
|
||
|
|
await delay(650);
|
||
|
|
const key=Object.keys(w.localStorage)[0];assert.ok(key?.startsWith('bmc:case-draft:v1:7:'), d.getElementById('cc-save').textContent);
|
||
|
|
const draft=JSON.parse(w.localStorage.getItem(key));assert.equal(draft.orders.length,1);assert.equal(draft.tags[0].id,9);
|
||
|
|
const saved={[key]:w.localStorage.getItem(key)};
|
||
|
|
const restored=await page(saved);restored.window.document.getElementById('cc-restore').click();await delay(80);
|
||
|
|
assert.equal(restored.window.document.getElementById('titel').value,'Test oprettelse');
|
||
|
|
assert.equal(restored.window.document.querySelector('.order-description').value,'Router');
|
||
|
|
assert.deepEqual(Array.from(restored.window.caseCreateUI.relations().tag_ids),[9]);
|
||
|
|
restored.window.caseCreateUI.created({id:99});await delay(600);assert.equal(restored.window.localStorage.getItem(key),null);
|
||
|
|
const other=await page(saved,8);assert.equal(other.window.document.getElementById('cc-restore'),null);
|
||
|
|
const prefill=await page(saved,7,'?title=Other');assert.equal(prefill.window.document.getElementById('cc-restore'),null);
|
||
|
|
const expired=await page({[key]:JSON.stringify({...draft,savedAt:Date.now()-8*86400000})});assert.equal(expired.window.document.getElementById('cc-restore'),null);
|
||
|
|
const td=expired.window.document;td.getElementById('cc-template').value='1';td.getElementById('cc-template').dispatchEvent(new expired.window.Event('change',{bubbles:true}));await delay(40);
|
||
|
|
assert.equal(td.getElementById('titel').value,'Tilbud');assert.equal(td.getElementById('type').value,'pipeline');assert.deepEqual(Array.from(expired.window.caseCreateUI.relations().tag_ids),[9]);
|
||
|
|
assert.equal(new Set(Array.from(d.querySelectorAll('[id]')).map(el=>el.id)).size,d.querySelectorAll('[id]').length,'IDs must remain unique');
|
||
|
|
[dom,restored,other,prefill,expired].forEach(x=>x.window.close());
|
||
|
|
console.log('PASS: panel structure, type switching, validation, tags, autosave, restore, user/prefill isolation, expiration, successful cleanup');
|
||
|
|
})().catch(e=>{console.error(e);process.exit(1);});
|