bmc_hub/tests/test_hardware_intake_ui.js

71 lines
3.8 KiB
JavaScript

const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
const nodes = {};
const get = id => nodes[id] ||= {value:'', hidden:false, className:'', innerHTML:'',textContent:'',focus(){},closest(){return this;}};
const requests=[];
let replies=[];
const ctx = {crypto:{randomUUID:()=> '11111111-1111-4111-8111-111111111111'},
document:{getElementById:get},URLSearchParams,
fetch:async url=>{requests.push(url); return {ok:true,json:async()=>replies.shift()};}};
vm.createContext(ctx);
vm.runInContext(fs.readFileSync('static/js/hardware-intake.js','utf8'),ctx);
(async()=>{
vm.runInContext("hardwareIntake.mode='invoice'",ctx);
ctx.showHardwareInvoicePreview({preview_id:'p',header:{invoice_number:'F123',currency:'DKK'},created_units:{'7':[10]},
lines:[{key:'7',quantity:'3',unit_price:'0',description:'PC <safe>'}]});
ctx.chooseHardwareInvoiceLine(0);
assert.equal(get('intake-count').value,2);
assert.equal(get('intake-unit-cost').value,'0');
assert.equal(get('model').value,'PC <safe>');
assert.equal(get('intake-serials-group').hidden,false);
get('intake-serials').value='SNA\nSNB';
get('intake-currency').value='DKK';
const payload=ctx.hardwareIntakePayload({asset_type:'pc'});
assert.equal(payload.preview_id,'p');
assert.equal(payload.count,2);
assert.deepEqual(Array.from(payload.serial_numbers),['SNA','SNB']);
assert(get('intake-invoice-lines').innerHTML.includes('PC &lt;safe&gt;'));
ctx.setHardwareIntakeMode('manual');
assert.equal(ctx.hardwareIntakePayload({asset_type:'pc'}).preview_id,null);
vm.runInContext("hardwareIntake.mode='barcode'",ctx);
get('intake-code').value='0012345678901';
replies=[[],{products:[{name:'Test PC',sku:'SKU',ean:'0012345678901',manufacturer:'Maker',price:100,currency:'DKK'}]}];
await ctx.lookupHardwareCode();
assert(requests[0].includes('0012345678901'));
assert(requests[1].includes('/apigateway/search'));
ctx.chooseHardwareProduct(0);
assert.equal(get('brand').value,'Maker');
assert.equal(get('model').value,'Test PC');
assert.equal(ctx.hardwareIntakePayload({asset_type:'pc'}).code,'0012345678901');
assert.equal(get('serial_number').value,'');
// Selected machine data and serial are retained until another source is selected.
vm.runInContext("hardwareIntake.inventoryItems=[{name:'Mac <12>',brand:'Apple',model:'Mac mini',serial_number:'SN12',hardware_specs:{gateway_inventory:{id:12}}}]",ctx);
ctx.chooseHardwareInventory(0);
assert.equal(get('serial_number').value,'SN12');
get('intake-currency').value='DKK';
vm.runInContext("hardwareIntake.mode='manual'",ctx);
assert.equal(ctx.hardwareIntakePayload({asset_type:'pc'}).hardware.hardware_specs.gateway_inventory.id,12);
ctx.setHardwareIntakeMode('manual');
assert.equal(ctx.hardwareIntakePayload({asset_type:'pc'}).hardware.hardware_specs,undefined);
vm.runInContext("hardwareIntake.pairHardwareId=4;hardwareIntake.inventoryItems=[{id:12,name:'PC12'}]",ctx);
let reloaded = false;
ctx.window = {location:{reload(){reloaded=true;}}};
const writes = [];
ctx.fetch = async (url, options) => {writes.push({url,options});return {ok:true,json:async()=>({hardware_id:4})};};
await ctx.chooseHardwareInventory(0);
assert.equal(writes[0].url,'/api/v1/hardware-intake/inventory/4/pair');
assert.equal(JSON.parse(writes[0].options.body).inventory_id,12);
assert.equal(reloaded,true);
await ctx.unpairHardwareInventory();
assert.equal(writes[1].options.method,'DELETE');
ctx.fetch = async () => ({ok:false,json:async()=>({detail:'Gateway utilgængelig'})});
reloaded = false;
await ctx.chooseHardwareInventory(0);
assert.equal(reloaded,false);
assert.equal(get('intake-message').textContent,'Gateway utilgængelig');
console.log('Hardware intake UI OK: invoice quantities, serials, source reset, code lookup and EAN preservation');
})().catch(error=>{console.error(error);process.exitCode=1;});