fix(pda): enforce sealed pallet contract and deduplicate activation refresh

This commit is contained in:
2026-09-09 12:35:03 +08:00
parent b19cecb54f
commit b03d5e1561
5 changed files with 56 additions and 6 deletions
+36
View File
@@ -4,6 +4,42 @@ import { readFile } from 'node:fs/promises'
const read = (path) => readFile(new URL(path, import.meta.url), 'utf8')
test('duplicate onShow shares one load chain while background return refreshes again', async () => {
const page = await read('../pages/picking/picking.vue')
const show = page.match(/async onShow\(\) \{[\s\S]*?\r?\n\t\t\},/)?.[0]
const hide = page.match(/onHide\(\) \{[\s\S]*?\r?\n\t\t\},/)?.[0]
assert.ok(show && hide)
const hooks = new Function('requireSession', 'session', `return ({${show}${hide}})`)(() => true, { currentUser: { id: '7' } })
const calls = []
let release
const pending = new Promise((resolve) => { release = resolve })
const context = { startHardwareScanner() {}, stopHardwareScanner() {}, async refreshAvailableBoxes() { calls.push('pending'); await pending }, async syncRemoteTask() { calls.push('detail+evidence') } }
const first = hooks.onShow.call(context)
const duplicate = hooks.onShow.call(context)
assert.deepEqual(calls, ['pending'])
release()
await Promise.all([first, duplicate])
assert.deepEqual(calls, ['pending', 'detail+evidence'])
await hooks.onShow.call(context)
assert.equal(calls.length, 2)
hooks.onHide.call(context)
await hooks.onShow.call(context)
assert.deepEqual(calls, ['pending', 'detail+evidence', 'pending', 'detail+evidence'])
const onLoad = page.match(/onLoad\(options = \{\}\) \{[\s\S]*?\r?\n\t\t\},/)?.[0]
assert.doesNotMatch(onLoad, /refreshAvailableBoxes|syncRemoteTask/)
})
test('camera and evidence preview resume still avoid unnecessary refreshes', async () => {
const page = await read('../pages/picking/picking.vue')
const show = page.match(/async onShow\(\) \{[\s\S]*?\r?\n\t\t\},/)?.[0]
const hooks = new Function('requireSession', 'session', `return ({${show}})`)(() => true, { currentUser: {} })
for (const flag of ['cameraPicking', 'evidencePreviewReturning']) {
const context = { [flag]: true, startHardwareScanner() {}, debugEvidence() {}, refreshAvailableBoxes() { throw new Error('unexpected refresh') } }
await hooks.onShow.call(context)
assert.equal(context._pageVisible, true)
}
})
test('direct H5 refresh restores the page user before rendering picking content', async () => {
const page = await read('../pages/picking/picking.vue')
+8 -2
View File
@@ -8,14 +8,20 @@ const state = await import(`data:text/javascript;base64,${Buffer.from(source).to
const items = [{ id: 1 }, { id: 2 }, { id: 3 }]
test('sealed pallet matches its DP code and never accepts an individual carton', () => {
const pallet = { id: '1', unitType: 'PALLET', indivisible: true, palletNo: 'DP-260909-0143', boxCodes: ['IN#2-1', 'IN#2-2'], qty: 2 }
const pallet = { id: '1', unitType: 'SEALED_PALLET', indivisible: true, palletNo: 'DP-260909-0143', boxCodes: ['IN#2-1', 'IN#2-2'], qty: 2 }
assert.equal(state.classifyScan([pallet], {}, 'IN#2-1').type, 'unknown')
assert.equal(state.classifyScan([pallet], {}, pallet.palletNo).type, 'pending')
assert.equal(state.classifyScan([pallet], { 1: state.ITEM_STATUS.PICKED }, pallet.palletNo).type, 'processed')
})
test('only the authoritative sealed-pallet unit type selects pallet behavior', () => {
assert.equal(state.isPalletItem({ unitType: 'SEALED_PALLET', indivisible: true }), true)
assert.equal(state.isPalletItem({ unitType: 'PALLET', indivisible: true }), false)
assert.equal(state.isPalletItem({ unitType: 'PACKAGE', indivisible: true }), false)
})
test('mixed task keeps package scanning separate from sealed pallet scanning', () => {
const mixed = [{ id: '1', unitType: 'PALLET', palletNo: 'DP-260909-0001', boxCodes: ['BOX-1'] }, { id: '2', unitType: 'PACKAGE', boxCodes: ['BOX-2'] }]
const mixed = [{ id: '1', unitType: 'SEALED_PALLET', palletNo: 'DP-260909-0001', boxCodes: ['BOX-1'] }, { id: '2', unitType: 'PACKAGE', boxCodes: ['BOX-2'] }]
assert.equal(state.classifyScan(mixed, {}, 'BOX-2').item.id, '2')
assert.equal(state.classifyScan(mixed, {}, 'DP-260909-0001').item.id, '1')
assert.equal(state.classifyScan(mixed, {}, 'BOX-1').type, 'unknown')