merge release test changes and preserve local frontend updates

This commit is contained in:
2026-09-20 15:24:04 +08:00
parent ca05994986
commit c24f8739e8
10 changed files with 288 additions and 87 deletions
+46 -9
View File
@@ -2,6 +2,7 @@ import test from 'node:test'
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
const source = await readFile(new URL('../src/components/RelabelPalletWork.vue', import.meta.url), 'utf8')
const template = source.split('</template>')[0]
const script = source.split('<script>')[1].split('</script>')[0].replace(/^import .*$/gm, '').replace('export default', 'return')
const component = new Function('ScanTargetInput', script)({})
function context() {
@@ -13,7 +14,7 @@ function context() {
] } }
for (const [key, method] of Object.entries(component.methods)) value[key] = method.bind(value)
for (const [key, method] of Object.entries(component.computed)) Object.defineProperty(value, key, { get: method.bind(value) })
value.selectSource({ positionId: '1', palletCode: 'SOURCE', movablePackages: 2, cartonMarks: ['A', 'B', 'C'] })
value.selectSource({ positionId: '1', palletId: '20', palletCode: 'SOURCE', movablePackages: 2, cartonMarks: ['A', 'B', 'C'] })
return value
}
test('quantity batch only includes completed boxes from same inbound and destination', () => {
@@ -24,22 +25,58 @@ test('quantity batch only includes completed boxes from same inbound and destina
value.selectedDestination = 'JFK8'; value.quantity = '1'; value.fillBatch(); assert.deepEqual(value.marks, ['B'])
})
test('submission requires exact count and scanned distinct source and target pallets', () => {
test('submission uses pallet identity instead of scanned presentation text', () => {
const value = context(); value.quantity = '1'; value.fillBatch()
value.source = { palletCode: 'SOURCE' }; value.sourceCode = 'source'
value.target = { palletCode: 'TARGET' }; value.targetCode = 'TARGET'
value.source = { palletId: '20', palletCode: 'SOURCE' }; value.sourceCode = ' source\n'
value.target = { palletId: '30', palletCode: 'TARGET' }; value.targetCode = 'target-alias'
assert.equal(value.readyToBind, true)
value.toggleMark('A'); assert.equal(value.readyToBind, false)
value.toggleMark('A'); value.sourceCode = 'OTHER'; assert.equal(value.readyToBind, false)
value.sourceCode = 'SOURCE'; value.target = { palletCode: 'SOURCE' }; value.targetCode = 'SOURCE'
value.toggleMark('A'); value.source = { palletId: '21', palletCode: 'OTHER' }; assert.equal(value.readyToBind, false)
value.source = { palletId: '20', palletCode: 'SOURCE' }; value.target = { palletId: '20', palletCode: 'TARGET-ALIAS' }
assert.equal(value.readyToBind, false)
})
test('pallet comparison tolerates mixed API versions and canonical code formatting', () => {
const value = context()
assert.equal(value.samePallet(
{ palletCode: ' plt-us-lax-01-1 ' },
{ palletCode: 'PLT-US-LAX-01-1' }
), true)
assert.equal(value.samePallet(
{ palletId: '20', palletCode: 'SOURCE' },
{ palletId: '21', palletCode: 'OTHER' }
), false)
assert.equal(value.samePallet(
{ palletId: '20', palletCode: 'SOURCE' },
{ palletId: '21', palletCode: ' source ' }
), true)
assert.equal(value.samePallet(
{ palletId: 2100203890682015700, palletCode: 'PLT-US-LAX-01-20260916-2100203890682015746' },
{ palletId: '2100203890682015746', palletCode: ' plt-us-lax-01-20260916-2100203890682015746 ' }
), true)
})
test('quantity disassembly has no extra carton scanner', () => {
assert.doesNotMatch(source, /relabel-move-carton/)
assert.match(source, /actualSource:/)
assert.match(source, /仍归属/)
})
test('source pallet list is concise and hides rows with no movable packages', () => {
const value = context()
value.sourceRows = [
{ palletCode: 'PALLET-1', inboundCode: 'IN-1', stockPackages: 12, movablePackages: 2 },
{ palletCode: 'PALLET-2', inboundCode: 'IN-2', stockPackages: 10, movablePackages: 0 }
]
assert.deepEqual(value.operableSourceRows.map(row => row.palletCode), ['PALLET-1'])
assert.match(source, />托盘</)
assert.match(source, />刷新</)
assert.match(source, /托盘号:\{\{ row\.palletCode \}\} · 入仓码:\{\{ row\.inboundCode \}\}/)
assert.match(source, /可拆\{\{ isReturnBulk \? '件数' : '箱数' \}\}:\{\{ row\.movablePackages \}\}/)
assert.doesNotMatch(template, /刷新来源托盘/)
assert.doesNotMatch(template, /按原入仓单拆托/)
assert.doesNotMatch(template, /确认后直接提交本批拆托合托/)
})
test('latest current-round binding is used for rebind source', () => {
const value = context()
value.task.history = ['OLD', 'NEW'].map(pallet => ({ action: 'PALLET_BIND', detail: JSON.stringify({ round: 'INITIAL', cartonMarks: ['A'], targetPallets: [pallet] }) }))
@@ -61,9 +98,9 @@ test('rescan same bound pallet does not call stock movement', async () => {
test('target confirmation submits binding directly, with no second submit button', async () => {
const value = context(); value.quantity = '1'; value.fillBatch()
value.source = { palletCode: 'SOURCE' }; value.sourceCode = 'SOURCE'; value.targetCode = 'TARGET'
value.source = { palletId: '20', palletCode: 'SOURCE' }; value.sourceCode = 'SOURCE'; value.targetCode = 'TARGET'
let binds = 0
value.resolve = async kind => { assert.equal(kind, 'target'); value.target = { palletCode: 'TARGET' } }
value.resolve = async kind => { assert.equal(kind, 'target'); value.target = { palletId: '30', palletCode: 'TARGET' } }
value.bind = async () => { binds++ }
await value.confirmTargetAndBind()
assert.equal(binds, 1)
@@ -83,7 +120,7 @@ test('missing source scan shows modal and never submits a binding', async () =>
test('target lookup failure cannot submit binding or report success', async () => {
const value = context(); value.quantity = '1'; value.fillBatch()
value.source = { palletCode: 'SOURCE' }; value.sourceCode = 'SOURCE'; value.targetCode = 'TARGET'
value.source = { palletId: '20', palletCode: 'SOURCE' }; value.sourceCode = 'SOURCE'; value.targetCode = 'TARGET'
value.resolve = async () => { value.error = '目标托盘不可用' }
let title = ''
value.showBindingMessage = heading => { title = heading }