Files
pda-uniapp/tests/dropship-palletizing-page.test.mjs
T

74 lines
4.7 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { readFile } from 'node:fs/promises'
const read = (path) => readFile(new URL(path, import.meta.url), 'utf8')
test('system pallet action binds through one request and keeps the same operation on retry', async () => {
const page = await read('../pages/dropship-palletizing/dropship-palletizing.vue')
const method = page.slice(page.indexOf('async createPallet()'), page.indexOf('statusLabel(status)'))
const requests = []
const { stableOperationId } = await import('../utils/idempotency.js')
const methods = new Function('createAndBindDropshipPallet', 'stableOperationId', 'playSuccessSound', 'playErrorSound', 'formatApiError', `return ({${method}})`)(async (taskId, payload) => {
requests.push({ taskId, payload })
if (requests.length === 1) throw new Error('network timeout')
return { taskStatus: 'CLAIMED', unbound: [], pallets: [{ palletNo: 'DP-260909-0001', cartons: [{ cartonId: '9007199254740993' }] }] }
}, stableOperationId, () => {}, () => {}, (error) => error.message)
const context = { busy: false, online: true, task: { taskStatus: 'CLAIMED' }, taskId: '10', warehouseId: '100', user: { id: '7' }, unboundCartons: [{ cartonId: '9007199254740993' }], scanState: {}, persistDraft() {}, get pallets() { return this.task.pallets || [] } }
await methods.createPallet.call(context)
assert.equal(context.error, 'network timeout')
assert.equal(context.busy, false)
await methods.createPallet.call(context)
assert.deepEqual(requests[0], requests[1])
assert.equal(context.activePalletNo, 'DP-260909-0001')
assert.equal(context.scanState.activePalletNo, context.activePalletNo)
context.unboundCartons = []
await methods.createPallet.call(context)
assert.equal(requests.length, 2)
assert.match(page, /新建托盘并绑定/)
})
test('dropship palletizing route and workbench entry are registered', async () => {
const [pages, data, home, modulePage] = await Promise.all([read('../pages.json'), read('../data/demo-data.js'), read('../pages/home/home.vue'), read('../pages/module/module.vue')])
assert.match(pages, /pages\/dropship-palletizing\/tasks/)
assert.match(pages, /pages\/dropship-palletizing\/dropship-palletizing/)
assert.match(data, /一件代发清点组托[\s\S]*?route: '\/pages\/dropship-palletizing\/tasks'/)
assert.match(home, /operation\.route \|\| '\/pages\/operation\/operation'/)
assert.match(modulePage, /operation\.route \|\| '\/pages\/operation\/operation'/)
})
test('page exposes both scan orders, receiving confirmation, pending boxes, pallet changes, and sealing guards', async () => {
const page = await read('../pages/dropship-palletizing/dropship-palletizing.vue')
for (const text of ['先扫托盘', '先扫多箱', '确认本箱实收', '待绑托箱', '移回待绑托', '封托']) assert.match(page, new RegExp(text))
assert.match(page, /startScanBroadcast/)
assert.match(page, /watchNetwork/)
assert.match(page, /saveDropshipPalletizingDraft/)
assert.match(page, /restoreDropshipPalletizingDraft/)
assert.match(page, /resolveDropshipCarton/)
assert.match(page, /countDropshipCarton/)
assert.match(page, /bindPendingDropshipCartons/)
assert.match(page, /moveDropshipCarton/)
assert.match(page, /sealDropshipPallet/)
assert.match(page, /pallet\.cartons \|\| \[\]/)
assert.match(page, /carton\.canCount === false[\s\S]*?carton\.blockReason/)
assert.doesNotMatch(page, /\(pallet\.items \|\| \[\]\)\.filter/)
assert.match(page, /:disabled="busy \|\| !online \|\| !canSeal"/)
assert.doesNotMatch(page, /warehouseId:\s*Number\(this\.warehouseId\)/)
assert.doesNotMatch(page, /模拟成功|DEMO_|palletStatus/)
})
test('390px work layout uses bounded grids and touch-sized primary actions', async () => {
const page = await read('../pages/dropship-palletizing/dropship-palletizing.vue')
assert.match(page, /\.dropship-page\{min-width:0;overflow:hidden;/)
assert.match(page, /\.summary-grid\{[^}]*grid-template-columns:repeat\(3,minmax\(0,1fr\)\);/)
assert.match(page, /\.primary-button,\.secondary-button\{[^}]*width:100%;min-height:48px;/)
assert.match(page, /\.quantity-control\{[^}]*grid-template-columns:52px minmax\(0,1fr\) 52px/)
})
test('dropship API uses only the frozen cartons/count contract', async () => {
const api = await read('../api/pda-dropship.js')
for (const path of ['tasks/pending', 'cartons/resolve', 'cartons/count', 'pallets/bind-pending', '/move', '/seal']) assert.match(api, new RegExp(path.replace('/', '\\/')))
for (const field of ['actualSkuQuantity', 'discrepancyAction', 'discrepancyRemark', 'palletNo', 'operationId', 'expectedVersion']) assert.match(api, new RegExp(field))
assert.doesNotMatch(api, /pallets\/open|pallets\/\$\{encodeURIComponent\(palletId\)\}\/scan|palletStatus/)
})