优化
This commit is contained in:
@@ -80,7 +80,7 @@ test('missing user-visible relationships use explicit empty labels instead of ID
|
||||
read('../src/components/ReceivingSessionSummary.vue'),
|
||||
read('../src/pages/pallet/pallet.vue')
|
||||
])
|
||||
assert.match(summary, /overseasWarehouseName \|\| '—'/)
|
||||
assert.match(summary, /overseasWarehouseCode[\s\S]*overseasWarehouseName/)
|
||||
assert.match(summary, /unique\.length \? unique : \['—'\]/)
|
||||
assert.match(pallet, /inboundCode \|\| '无入仓码'/)
|
||||
assert.match(pallet, /locationCode \|\| '未绑定库位'/)
|
||||
|
||||
@@ -2,7 +2,7 @@ import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
|
||||
import { normalizeReceivingCandidate, normalizeReceivingSession } from '../src/api/receiving-adapter.js'
|
||||
import { assertReceivingWarehouse, normalizeReceivingCandidate, normalizeReceivingSession, normalizeReceivingWarehouseProfile } from '../src/api/receiving-adapter.js'
|
||||
import { receiving, receivingPhase, receivingProgress, resetReceivingSession, setCurrentReceiving } from '../src/stores/receiving.js'
|
||||
|
||||
const read = (path) => readFile(new URL(path, import.meta.url), 'utf8')
|
||||
@@ -21,6 +21,7 @@ const inbounds = Array.from({ length: 15 }, (_, index) => ({
|
||||
test('one container candidate aggregates fifteen independent one-inbound plans', () => {
|
||||
const candidate = normalizeReceivingCandidate({
|
||||
sourceContainerBookingId: '2093166483653849089', containerNo: 'C10000000', status: 'WAIT_SIGN',
|
||||
overseasWarehouseCode: 'US-LAX-RCV', overseasWarehouseName: '洛杉矶接柜仓',
|
||||
plannedArrivalAt: '2026-08-29T09:30:00', totalOrderCount: 15, planCount: 15, inboundCodeCount: 15,
|
||||
missingInboundCodeCount: 0, plannedInboundCodeCount: 15, pendingPlanCount: 0, allPlansReady: true, operable: true, blockReason: '',
|
||||
destinationCodes: ['ABE3', 'US-LAX-01'], plannedPalletCount: 15,
|
||||
@@ -28,6 +29,7 @@ test('one container candidate aggregates fifteen independent one-inbound plans',
|
||||
})
|
||||
assert.deepEqual(candidate, {
|
||||
sourceContainerBookingId: '2093166483653849089', containerNo: 'C10000000', status: 'WAIT_SIGN',
|
||||
overseasWarehouseCode: 'US-LAX-RCV', overseasWarehouseName: '洛杉矶接柜仓',
|
||||
plannedArrivalAt: '2026-08-29T09:30:00', totalOrderCount: 15, planCount: 15, inboundCodeCount: 15,
|
||||
missingInboundCodeCount: 0, plannedInboundCodeCount: 15, pendingPlanCount: 0, allPlansReady: true, operable: true, blockReason: '',
|
||||
destinationCodes: ['ABE3', 'US-LAX-01'], plannedPalletCount: 15,
|
||||
@@ -37,6 +39,21 @@ test('one container candidate aggregates fifteen independent one-inbound plans',
|
||||
assert.equal(candidate.sourceContainerBookingId, '2093166483653849089')
|
||||
})
|
||||
|
||||
test('receiving warehouse facts are explicit and fail closed when absent or assigned elsewhere', () => {
|
||||
const profile = normalizeReceivingWarehouseProfile({ warehouseId: '900', warehouseCode: 'US-LAX-RCV', warehouseName: '洛杉矶接柜仓' })
|
||||
const assigned = normalizeReceivingCandidate({ containerNo: 'C10000002', overseasWarehouseCode: 'US-LAX-RCV', overseasWarehouseName: '洛杉矶接柜仓' })
|
||||
assert.equal(assertReceivingWarehouse(assigned, profile, '柜号 C10000002'), assigned)
|
||||
assert.throws(() => assertReceivingWarehouse(normalizeReceivingCandidate({ containerNo: 'C10000003' }), profile), (error) => {
|
||||
assert.equal(error.code, 'RECEIVING_WAREHOUSE_CONTRACT_INVALID')
|
||||
return /缺少已分配海外接柜仓/.test(error.message)
|
||||
})
|
||||
assert.throws(() => assertReceivingWarehouse(normalizeReceivingCandidate({ containerNo: 'C10000004', overseasWarehouseCode: 'US-NYC-RCV', overseasWarehouseName: '纽约接柜仓' }), profile), (error) => {
|
||||
assert.equal(error.code, 'RECEIVING_WAREHOUSE_MISMATCH')
|
||||
return /已分配至其他海外接柜仓/.test(error.message)
|
||||
})
|
||||
assert.throws(() => normalizeReceivingWarehouseProfile({ warehouseId: '900', warehouseName: '洛杉矶接柜仓' }), /绑定仓信息不完整/)
|
||||
})
|
||||
|
||||
test('incomplete containers remain visible but fail closed from server readiness facts', () => {
|
||||
const candidate = normalizeReceivingCandidate({
|
||||
sourceContainerBookingId: '2093166483653849099', containerNo: 'C10000001',
|
||||
@@ -60,7 +77,7 @@ test('incomplete containers remain visible but fail closed from server readiness
|
||||
|
||||
test('current recovery retains all independent-plan inbound facts while progress remains container-level', () => {
|
||||
const session = normalizeReceivingSession({
|
||||
containerNo: 'C10000000', status: 'RECEIVING', totalPackages: 60,
|
||||
containerNo: 'C10000000', overseasWarehouseCode: 'US-LAX-RCV', overseasWarehouseName: '洛杉矶接柜仓', status: 'RECEIVING', totalPackages: 60,
|
||||
receivedPackages: 4, pendingPackages: 56, photos: [], inbounds
|
||||
})
|
||||
setCurrentReceiving(session)
|
||||
@@ -90,6 +107,10 @@ test('container UI locks and signs once across independent plans, then renders o
|
||||
assert.match(inboundApi, /current\('\/sign'\)/)
|
||||
assert.match(operation, /prepareReceivingContainer\(this\.selected\.containerNo, \{ idempotencyKey: key\.value \}\)/)
|
||||
assert.match(operation, /getCurrentReceiving\(\)[\s\S]*applyCurrentReceiving\(current\)/)
|
||||
assert.match(operation, /applyWarehouseProfile\(await getCurrentWarehouseProfile\(\)\)/)
|
||||
assert.match(operation, /values\.map\(\(item\) => this\.validateReceivingWarehouse/)
|
||||
assert.match(operation, /prepareReceivingContainer[\s\S]*validateReceivingWarehouse/)
|
||||
assert.match(summary, /overseasWarehouseCode[\s\S]*overseasWarehouseName/)
|
||||
for (const forbidden of ['customerId', 'planNo', 'allocationId', 'warehouseId', 'locationId']) {
|
||||
assert.doesNotMatch(inboundApi, new RegExp(forbidden))
|
||||
}
|
||||
@@ -108,7 +129,7 @@ test('PDA does not infer container eligibility from partial plan workflow states
|
||||
assert.match(adapter, /operable: value\.operable === true/)
|
||||
assert.match(operation, /if \(!candidate\.operable\) \{ receiving\.selected = candidate; this\.detailOpen = true; return \}/)
|
||||
assert.match(operation, /if \(!this\.selected\?\.containerNo \|\| !this\.selected\?\.allPlansReady \|\| !this\.selected\?\.operable/)
|
||||
assert.match(operation, /catch \(error\) \{ await this\.recoverCurrentAfterConflict\(error, true\) \}/)
|
||||
assert.match(operation, /recoverCurrentAfterConflict\(error, true\)/)
|
||||
assert.match(operation, /preserveEvidence \? error : null[\s\S]*this\.candidateError = preserveEvidence \? error : null/)
|
||||
assert.doesNotMatch(inbound, /sort\(/)
|
||||
})
|
||||
|
||||
@@ -178,10 +178,11 @@ test('business and network errors retain diagnostics without refreshing or clear
|
||||
prepareSession(); let refreshCount = 0
|
||||
globalThis.uni.request = (options) => {
|
||||
if (options.url.endsWith('/auth/refresh')) refreshCount += 1
|
||||
options.success({ statusCode: 200, data: { code: 'A0409', message: 'locked', requestId: 'business-request', traceId: 'business-trace' }, header: {} })
|
||||
options.success({ statusCode: 200, data: { code: 'A0409', message: '当前柜已分配至其他海外接柜仓,无法在本仓操作', requestId: 'business-request', traceId: 'business-trace' }, header: {} })
|
||||
}
|
||||
await assert.rejects(overseasRequest('POST', '/pda/locked'), (error) => {
|
||||
assert.equal(error.code, 'A0409')
|
||||
assert.equal(error.message, '当前柜已分配至其他海外接柜仓,无法在本仓操作')
|
||||
assert.equal(error.requestId, 'business-request')
|
||||
assert.equal(error.traceId, 'business-trace')
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user