136 lines
5.6 KiB
JavaScript
136 lines
5.6 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const applicationSource = fs.readFileSync(path.join(__dirname, '..', 'assets', 'app.js'), 'utf8')
|
|
.replace(/\s*bootstrap\(\);\s*$/, '');
|
|
const tests = [];
|
|
const runtimeTests = String.raw`
|
|
render=()=>{};
|
|
toast=()=>{};
|
|
|
|
function test(name,fn){tests.push({name,fn})}
|
|
|
|
test('inbound workbench exposes express sign-in entry',()=>{
|
|
const markup=workbenchView();
|
|
assert.match(markup,/快递签收/);
|
|
assert.match(markup,/navigate\('express-signin'\)/);
|
|
});
|
|
|
|
test('express sign-in view exposes purchase and return tabs with order fields',()=>{
|
|
state.page='express-signin';
|
|
state.expressOrderType='purchase';
|
|
const markup=expressSignInView();
|
|
for(const label of ['采购','退货','客户简码','SKU','箱数/件数','承运商','快递号','签收']) assert.match(markup,new RegExp(label));
|
|
assert.match(markup,/setExpressOrderType\('return'\)/);
|
|
});
|
|
|
|
test('each express order uses exactly two rows without an off-screen table',()=>{
|
|
state.expressOrderType='purchase';
|
|
const markup=expressSignInView();
|
|
const cards=markup.match(/<article class="express-order-card">/g)||[];
|
|
const rows=markup.match(/<div class="express-order-row">/g)||[];
|
|
assert.equal(cards.length,2);
|
|
assert.equal(rows.length,cards.length*2);
|
|
assert.doesNotMatch(markup,/<table|express-signin-table/);
|
|
});
|
|
|
|
test('signing an express order marks it received and prevents duplicate action',()=>{
|
|
const order=expressOrders.find(item=>item.type==='purchase');
|
|
order.signedIn=false;
|
|
state.expressOrderType='purchase';
|
|
openExpressSignIn(order.id);
|
|
state.expressScan={kind:'sku',value:order.sku,quantity:1};
|
|
state.expressWaybillPhotos[order.id]='data:image/png;base64,test';
|
|
completeExpressSignIn();
|
|
assert.equal(order.signedIn,true);
|
|
assert.equal(state.page,'express-signin');
|
|
const markup=expressSignInView();
|
|
assert.match(markup,/已签收/);
|
|
});
|
|
|
|
test('sign action opens a dedicated scan and waybill photo page',()=>{
|
|
const order=expressOrders.find(item=>item.type==='purchase'&&!item.signedIn);
|
|
state.expressOrderType='purchase';
|
|
openExpressSignIn(order.id);
|
|
assert.equal(state.page,'express-signin-detail');
|
|
assert.equal(state.selectedExpressOrderId,order.id);
|
|
const markup=expressSignInDetailView();
|
|
assert.match(markup,/扫描箱唛或SKU/);
|
|
assert.match(markup,/照片信息/);
|
|
assert.match(markup,/面单/);
|
|
assert.match(markup,/express-waybill-photo-input/);
|
|
assert.match(markup,/签收完成/);
|
|
assert.match(markup,new RegExp(order.carrier));
|
|
assert.match(markup,new RegExp(order.trackingNo.replace(/ /g,'\\s')));
|
|
assert.match(markup,/aria-label="扫描箱唛或SKU"/);
|
|
});
|
|
|
|
test('scanning a carton mark exposes the carton count input',()=>{
|
|
const order=expressOrders.find(item=>item.type==='purchase'&&!item.signedIn);
|
|
openExpressSignIn(order.id);
|
|
document.getElementById=()=>({value:order.boxMark});
|
|
handleExpressScan();
|
|
assert.deepEqual(state.expressScan,{kind:'carton',value:order.boxMark,quantity:order.cartons});
|
|
const markup=expressSignInDetailView();
|
|
assert.match(markup,/箱数/);
|
|
assert.match(markup,/id="express-quantity"/);
|
|
assert.doesNotMatch(markup,/>个数</);
|
|
});
|
|
|
|
test('scanning an SKU exposes the piece count input',()=>{
|
|
const order=expressOrders.find(item=>item.type==='purchase'&&!item.signedIn);
|
|
openExpressSignIn(order.id);
|
|
document.getElementById=()=>({value:order.sku});
|
|
handleExpressScan();
|
|
assert.deepEqual(state.expressScan,{kind:'sku',value:order.sku,quantity:order.pieces});
|
|
const markup=expressSignInDetailView();
|
|
assert.match(markup,/>个数</);
|
|
assert.match(markup,/id="express-quantity"/);
|
|
});
|
|
|
|
test('express sign-in cannot complete before a scan and waybill photo',()=>{
|
|
const order=expressOrders.find(item=>item.type==='return');
|
|
order.signedIn=false;
|
|
openExpressSignIn(order.id);
|
|
state.expressScan=null;
|
|
delete state.expressWaybillPhotos[order.id];
|
|
completeExpressSignIn();
|
|
assert.equal(order.signedIn,false);
|
|
assert.equal(state.page,'express-signin-detail');
|
|
});
|
|
|
|
test('correcting an invalid quantity immediately refreshes completion readiness',()=>{
|
|
const order=expressOrders.find(item=>item.type==='return');
|
|
openExpressSignIn(order.id);
|
|
state.expressScan={kind:'sku',value:order.sku,quantity:order.pieces};
|
|
state.expressWaybillPhotos[order.id]='data:image/png;base64,test';
|
|
const completionButton={disabled:false};
|
|
document.getElementById=id=>id==='express-complete'?completionButton:null;
|
|
setExpressQuantity('0');
|
|
assert.equal(completionButton.disabled,true);
|
|
setExpressQuantity('2');
|
|
assert.equal(completionButton.disabled,false);
|
|
});
|
|
|
|
test('express sign-in rejects fractional quantities',()=>{
|
|
const order=expressOrders.find(item=>item.type==='return');
|
|
order.signedIn=false;
|
|
openExpressSignIn(order.id);
|
|
state.expressScan={kind:'sku',value:order.sku,quantity:'1.5'};
|
|
state.expressWaybillPhotos[order.id]='data:image/png;base64,test';
|
|
completeExpressSignIn();
|
|
assert.equal(order.signedIn,false);
|
|
assert.equal(state.page,'express-signin-detail');
|
|
});
|
|
|
|
for(const entry of tests){
|
|
try{entry.fn();process.stdout.write('PASS: '+entry.name+'\n')}
|
|
catch(error){process.stderr.write('FAIL: '+entry.name+'\n'+error.stack+'\n');globalThis.__failed=(globalThis.__failed||0)+1}
|
|
}
|
|
if(globalThis.__failed)throw new Error(globalThis.__failed+' runtime behavior test(s) failed');
|
|
`;
|
|
|
|
const run = new Function('assert', 'tests', 'localStorage', 'document', 'window', applicationSource + '\n' + runtimeTests);
|
|
run(assert, tests, { getItem: () => null, setItem: () => {} }, { getElementById: () => null }, { scrollTo: () => {} });
|