Files
baiyue-firstleg/scripts/admin-test-env-modules/warehouse-transfer-outbound-contract.test.mjs

68 lines
4.3 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { outboundWarehouseTransfer } from './warehouse-transfer-outbound.mjs'
// 替身返回独立的单据与库存证据,验证错误流水不能被成功状态掩盖。
function fixture(fault = '') {
const allocation = { inventoryPositionId: '301', palletId: '401', palletNo: 'P-1', packageCount: 1, skuCode: 'NEW', inboundCode: 'IN-1', status: 'RESERVED' }
const proof = { marker: 'BATCH', customerId: '101', warehouseId: '201', transferNo: 'WT-1', relabelNo: 'RL-1', relabelApplicationId: '501', inboundCode: 'IN-1',
status: 'ALLOCATED', outboundAllocations: [allocation], relabelFulfillment: { execution: { status: 'HTTP_VERIFIED_READY_FOR_TRANSFER_OUTBOUND' } } }
const calls = [], snapshots = []
let shipped = false, writes = 0
const context = { marker: 'BATCH', context: { merchantQualificationFixture: { tenantId: '101' } },
createdResources: { phase4OverseasClientServices: { transferFulfillment: proof } }, assert() {},
async request(method, path, body) {
calls.push({ method, path, body })
let data
if (method === 'POST') {
writes++
if (fault === 'network') throw Error('connection lost')
shipped = true
}
if (path.includes('/ledger?')) {
const rows = shipped || fault === 'existing shipment' ? [{ id: '601', palletNo: fault === 'wrong pallet' ? 'P-OTHER' : 'P-1', customerId: fault === 'foreign customer' ? '999' : '101',
overseasWarehouseId: '201', skuCode: fault === 'old sku' ? 'OLD' : 'NEW', inboundCode: 'IN-1', businessType: 'SHIP', businessOrderNo: 'WT-1', deltaPackages: -1 }] : []
if (fault === 'double shipment' && shipped) rows.push({ ...rows[0], id: '602' })
if (fault === 'replay ledger' && writes === 2) rows[0].id = '699'
data = { total: rows.length, records: rows }
} else if (path.includes('/relabel-applications/')) data = { application: { relabelNo: 'RL-1', customerOrderNo: 'WT-1', status: 'READY_FOR_OUTBOUND', fulfillmentStatus: fault === 'wrong relabel' ? 'COMPLETED' : 'OUTBOUNDED' } }
else data = { transferNo: 'WT-1', status: shipped ? 'OUTBOUNDED' : 'ALLOCATED', relabelNo: 'RL-1', relabelApplicationId: '501', operatingWarehouseId: '201',
packageCount: 1, fbaWarehouseCode: 'FBA-1', actualShipAt: shipped && fault !== 'missing shipment time' ? '2026-10-22T12:00:00' : null,
allocations: [{ ...allocation, status: shipped ? 'SHIPPED' : 'RESERVED' }] }
return { http: 200, body: { code: '200', data } }
} }
const options = { proof, merchantToken: 'secret', checkpoint: async () => { snapshots.push(structuredClone(proof)); if (fault === 'disk') throw Error('disk full') } }
return { context, options, proof, calls, snapshots }
}
test('原转运出库验证同单新SKU扣库及重放唯一性', async () => {
const f = fixture()
await outboundWarehouseTransfer(f.context, f.options)
assert.equal(f.proof.status, 'OUTBOUNDED')
assert.equal(f.proof.outbound.status, 'OUTBOUNDED_HTTP_VERIFIED')
assert.equal(f.calls.filter(c => c.method === 'POST').length, 2)
assert.equal(JSON.stringify(f.snapshots).includes('secret'), false)
const count = f.calls.length
await assert.rejects(outboundWarehouseTransfer(f.context, f.options))
assert.equal(f.calls.length, count)
})
for (const fault of ['network', 'existing shipment', 'foreign customer', 'wrong pallet', 'old sku', 'double shipment', 'replay ledger', 'wrong relabel', 'missing shipment time', 'disk']) {
test(`原转运出库拒绝 ${fault}`, async () => {
const f = fixture(fault)
await assert.rejects(outboundWarehouseTransfer(f.context, f.options))
assert.equal(f.proof.outbound.status, 'FAILED')
assert.equal(f.proof.status, 'ALLOCATED')
const writes = f.calls.filter(c => c.method === 'POST').length
assert.equal(writes, ['disk', 'existing shipment'].includes(fault) ? 0 : ['replay ledger', 'wrong relabel'].includes(fault) ? 2 : 1)
if (fault === 'network') assert.equal(f.proof.outbound.requests.at(-1).status, 'UNKNOWN_RESULT')
})
}
test('原转运未完成换标不得发出请求', async () => {
const f = fixture()
f.proof.relabelFulfillment.execution.status = 'FAILED'
await assert.rejects(outboundWarehouseTransfer(f.context, f.options))
assert.equal(f.calls.length, 0)
})