Files
docs/悦/PDA(海外)/tests/pallet-order-tabs.runtime.test.js
T
2026-08-24 19:10:22 +08:00

150 lines
6.3 KiB
JavaScript

const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const html = fs.readFileSync(path.join(__dirname, '..', 'index.html'), 'utf8');
const match = html.match(/<script>([\s\S]*?)<\/script>/);
assert.ok(match, 'inline application script is missing');
const applicationSource = match[1].replace(/\s*render\(\);\s*$/, '');
const tests = [];
const runtimeTests = String.raw`
render=()=>{};
showModal=(message,onConfirm)=>{globalThis.__lastModal={message,onConfirm}};
closeModal=()=>{};
toast=()=>{};
function test(name,fn){tests.push({name,fn})}
test('consolidation ignores dropship pallet lookup and clears type inputs',()=>{
state.palletOrderType='dropship';
state.fbaPalletLabels=['D4444-TC-001'];
state.dropshipPalletLabel='D2222-TC-001';
state.palletTypeMessage={type:'error',text:'stale'};
state.fbaPalletMessage={type:'error',text:'stale'};
state.dropshipScanMessage={type:'error',text:'stale'};
startConsolidation();
assert.deepEqual(state.fbaPalletLabels,[]);
assert.equal(state.dropshipPalletLabel,'');
assert.equal(state.palletTypeMessage,null);
assert.equal(state.fbaPalletMessage,null);
assert.equal(state.dropshipScanMessage,null);
state.pallet={id:'DRAFT',mode:'consolidate',planId:null,targetPallets:null,destinationCode:'',destinationAddress:'',items:[]};
document.__input='D2222-TC-001';
handlePalletScan();
assert.equal(state.pallet.items.length,0,'consolidation must not import an existing pallet');
assert.equal(state.dropshipPalletLabel,'');
});
test('starting and selecting jobs reset type-specific inputs',()=>{
state.palletMode='palletize';
state.selectedPlanId='INB-260819-026';
state.fbaPalletLabels=['D4444-TC-001'];
state.dropshipPalletLabel='D2222-TC-001';
state.fbaPalletMessage={type:'error',text:'stale'};
state.dropshipScanMessage={type:'error',text:'stale'};
startPallet();
assert.deepEqual(state.fbaPalletLabels,[]);
assert.equal(state.dropshipPalletLabel,'');
assert.equal(state.fbaPalletMessage,null);
assert.equal(state.dropshipScanMessage,null);
state.fbaPalletLabels=['D4444-TC-002'];
state.dropshipPalletLabel='D2222-TC-001';
selectPallet('D4444-TC-003','INB-260819-026');
assert.deepEqual(state.fbaPalletLabels,[]);
assert.equal(state.dropshipPalletLabel,'');
state.fbaPalletLabels=['D4444-TC-004'];
state.dropshipPalletLabel='D2222-TC-001';
document.__input='BX-88401-01';
handlePalletTopScan();
assert.deepEqual(state.fbaPalletLabels,[]);
assert.equal(state.dropshipPalletLabel,'');
state.fbaPalletLabels=['D4444-TC-005'];
state.dropshipPalletLabel='D2222-TC-001';
startNewConsolidation();
assert.deepEqual(state.fbaPalletLabels,[]);
assert.equal(state.dropshipPalletLabel,'');
state.fbaPalletLabels=['D4444-TC-006'];
state.dropshipPalletLabel='D2222-TC-001';
reconsolidatePallet('D2222-TC-019');
assert.deepEqual(state.fbaPalletLabels,[]);
assert.equal(state.dropshipPalletLabel,'');
});
test('FBA selector disables occupied labels and every label for persisted pallets',()=>{
state.palletOrderType='fba';
state.pallet={id:'',mode:'palletize',planId:'INB-260819-018',items:[],persisted:false};
let markup=fbaPalletLabelSelector(plans[0]);
assert.match(markup,/D2222-TC-001[\s\S]*?<\/button>/);
const occupiedButton=markup.match(/<button[^>]*>[\s\S]*?D2222-TC-001[\s\S]*?<\/button>/)?.[0]||'';
assert.match(occupiedButton,/disabled/);
state.pallet.persisted=true;
markup=fbaPalletLabelSelector(plans[0]);
const buttons=[...markup.matchAll(/<button[^>]*class="fba-pallet-choice[^>]*>/g)].map(match=>match[0]);
assert.ok(buttons.length>1);
assert.ok(buttons.every(button=>button.includes('disabled')));
});
test('FBA and dropship validation messages render in their owning modules',()=>{
state.palletMode='palletize';
state.selectedPlanId='INB-260819-026';
state.pallet={id:'',mode:'palletize',planId:'INB-260819-026',destinationCode:'',destinationAddress:'',items:[]};
state.fbaPalletMessage={type:'error',text:'FBA_MESSAGE'};
const selector=fbaPalletLabelSelector(plans[2]);
assert.match(selector,/fba-pallet-selector[\s\S]*FBA_MESSAGE/);
state.palletOrderType='dropship';
state.fbaPalletMessage=null;
state.dropshipScanMessage={type:'error',text:'DROPSHIP_MESSAGE'};
const view=palletView();
const scanStart=view.indexOf('pallet-type-scan');
const scanEnd=view.indexOf('</section>',scanStart);
assert.ok(scanStart>=0 && view.slice(scanStart,scanEnd).includes('DROPSHIP_MESSAGE'));
});
test('FBA submission materializes every available selected label exactly once',()=>{
const plan=plans[2];
const originalPallets=state.pallets.map(pallet=>JSON.parse(JSON.stringify(pallet)));
const originalReceived=plan.receivedPallets;
const source=cargo.find(item=>item.id==='C-004');
source.palletNo='';
state.pallets=originalPallets;
state.selectedPlanId=plan.id;
state.palletMode='palletize';
state.palletOrderType='fba';
state.fbaPalletLabels=['D4444-TC-001','D4444-TC-002'];
state.pallet={id:'',mode:'palletize',planId:plan.id,targetPallets:plan.expectedPallets,destinationCode:source.destinationCode,destinationAddress:source.destinationAddress,items:[{...source}]};
submitPallet();
const created=state.pallets.filter(pallet=>['D4444-TC-001','D4444-TC-002'].includes(pallet.id));
assert.equal(created.length,2);
assert.equal(new Set(created.map(pallet=>pallet.id)).size,2);
assert.equal(created.reduce((count,pallet)=>count+pallet.items.length,0),1,'cargo must be linked once across the selected pallets');
assert.equal(source.palletNo,'D4444-TC-001');
assert.equal(plan.receivedPallets,Math.min(plan.expectedPallets,originalReceived+2));
});
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 documentStub = {
__input: '',
getElementById(id) {
if (id === 'pallet-scan' || id === 'pallet-top-scan') return { value: this.__input };
return null;
}
};
const run = new Function('assert', 'tests', 'localStorage', 'document', 'window', applicationSource + '\n' + runtimeTests);
run(assert, tests, { getItem: () => null, setItem: () => {} }, documentStub, { scrollTo: () => {} });