This commit is contained in:
2026-10-27 12:09:25 +08:00
parent 105c7825b4
commit 493fa7c2e9
2 changed files with 65 additions and 5 deletions
+37
View File
@@ -43,6 +43,43 @@ function page(dependencies = {}) {
}
const proof = (command, version = 1) => ({ dispatchNo: command.dispatchNo, action: command.action, idempotencyKey: command.body.idempotencyKey, recordVersion: version, stage: command.action === 'LOADING_COMPLETE' ? 'AFTER_LOADING' : 'LOADING', result: { confirmed: true } })
test('pallet scan notice reports the current pickable quantity and closes after three seconds without submitting', t => {
t.mock.timers.enable({ apis: ['setTimeout'] })
storage(); let writes = 0, sounds = 0
const state = page({ pickDispatchItem: async () => { writes++ }, playSuccessSound: () => { sounds++ } })
state.current = task({ items: [item({ scheduledPackages: 12, pickedPackages: 4, positions: [{ positionId: 'position-1', availablePackages: 6, allocatedPackages: 0, pickedPackages: 0 }] })] })
state.handleScan('PALLET-1')
assert.deepEqual(state.scanNotice, { palletNo: 'PALLET-1', packages: 6 })
assert.equal(sounds, 1)
t.mock.timers.tick(2999); assert.ok(state.scanNotice)
t.mock.timers.tick(1); assert.equal(state.scanNotice, null)
assert.equal(writes, 0); assert.equal(state.packages, 6)
})
test('consecutive pallet scans replace the notice and restart its full display time', t => {
t.mock.timers.enable({ apis: ['setTimeout'] })
storage(); const state = page()
state.current = task({ items: [item(), item({ dispatchItemId: 'item-2', sourceKey: 'source-2', palletNo: 'PALLET-2', scheduledPackages: 1 })] })
state.handleScan('PALLET-1'); t.mock.timers.tick(2000)
state.handleScan('PALLET-2')
assert.deepEqual(state.scanNotice, { palletNo: 'PALLET-2', packages: 1 })
t.mock.timers.tick(1000); assert.ok(state.scanNotice)
t.mock.timers.tick(2000); assert.equal(state.scanNotice, null)
})
test('scan errors, carton scans and switching tabs cannot retain a stale pallet notice', t => {
t.mock.timers.enable({ apis: ['setTimeout'] })
storage(); const state = page()
state.handleScan('PALLET-1'); state.handleScan('UNKNOWN')
assert.equal(state.scanNotice, null); assert.ok(state.error)
state.handleScan('PALLET-1'); state.selectTab('photos')
assert.equal(state.scanNotice, null)
state.selectTab('picking'); state.handleScan('PALLET-1')
state.current = task({ items: [item({ returnCartons: [{ returnCartonId: 'rc-1', cartonMark: 'RC-1', status: 'OUTBOUND_PENDING', productQuantity: 5 }] })] })
state.handleScan('RC-1'); assert.equal(state.scanNotice, null)
t.mock.timers.tick(3000); assert.equal(state.scanNotice, null)
})
test('real picking requires the native gate, physical source and current stage; empty or merely counted tasks cannot complete loading', async () => {
storage(); const state = page(); state.selectPallet(state.current.items[0]); assert.equal(state.canPick, true)
for (const allowed of [false, 'true', undefined]) { state.current.actions.PICK.allowed = allowed; assert.equal(state.canPick, false) }