test: extend eight-business acceptance flows and offline contracts

This commit is contained in:
2026-10-22 15:41:50 +08:00
parent 86889d7e0e
commit 080ca600e6
33 changed files with 1285 additions and 101 deletions
@@ -4,7 +4,7 @@ import { verifyCargoDiscardFulfillment } from './cargo-discard-fulfillment.mjs'
function harness(fault = '') {
const calls = [], persisted = []
let discarded = false, confirmed = false, repeats = 0
let discarded = false, confirmed = false, repeats = 0, invalidPhotoRejected = false
const proof = { approvedNo: 'CD202610220001', customerId: '101', warehouseId: '201', inboundCode: 'RK-TEST', skuCode: 'SKU-TEST',
status: 'APPROVAL_HTTP_VERIFIED_CARTON_SQL_PENDING' }
const task = { discardNo: proof.approvedNo, customerId: '101', overseasWarehouseId: '201', palletNo: 'PALLET-TEST',
@@ -20,6 +20,11 @@ function harness(fault = '') {
else if (path.endsWith('/resolve')) data = task
else if (path.endsWith('/confirm-completion')) { confirmed = true; data = {} }
else if (path.endsWith('/confirm')) {
if (body.photoFileIds.length === 2) {
invalidPhotoRejected = true
return { http: 200, requestId: 'request-test', traceId: fault === 'photo missing trace' ? null : 'trace-test',
body: { code: fault === 'photo accepted' ? '200' : fault === 'photo wrong code' ? 'A0400' : 'A0409', data: null } }
}
if (fault === 'unknown confirm') throw new Error('network unknown')
if (discarded) repeats++
discarded = true
@@ -42,12 +47,19 @@ function harness(fault = '') {
async snapshot() {
const quantity = discarded ? fault === 'no deduction' ? 4 : fault === 'replay deduction' && repeats ? 2 : 3 : 4
const ledger = discarded ? [{ businessOrderNo: proof.approvedNo, businessType: 'DISCARD', deltaPackages: -1,
id: '501', customerId: proof.customerId, overseasWarehouseId: proof.warehouseId, palletNo: task.palletNo,
beforePackages: 4, afterPackages: 3,
skuCode: proof.skuCode, inboundCode: proof.inboundCode }] : []
if (discarded && fault === 'duplicate ledger') ledger.push({ ...ledger[0] })
if (discarded && fault === 'ledger customer') ledger[0].customerId = '999'
if (discarded && fault === 'ledger warehouse') ledger[0].overseasWarehouseId = '999'
if (discarded && fault === 'ledger pallet') ledger[0].palletNo = 'OTHER-PALLET'
if (discarded && fault === 'ledger identity') delete ledger[0].id
if (discarded && fault === 'ledger arithmetic') ledger[0].afterPackages = 4
return { balances: [{ inboundCode: proof.inboundCode, skuCode: proof.skuCode, totalPackages: quantity, availablePackages: quantity }],
ledger, detail: { summary: { discardNo: proof.approvedNo, customerId: proof.customerId, overseasWarehouseId: proof.warehouseId,
status: confirmed ? 'COMPLETED' : discarded ? 'PDA_COMPLETED' : 'APPROVED', totalPackages: 1,
actualPackages: discarded ? 1 : null, customerConfirmedAt: confirmed ? '2026-10-22T12:00:00' : null } } }
actualPackages: discarded || invalidPhotoRejected && fault === 'photo drift' ? 1 : null, customerConfirmedAt: confirmed ? '2026-10-22T12:00:00' : null } } }
} }
return { context, inputs, calls, persisted }
}
@@ -57,7 +69,7 @@ test('discard executes same application through PDA and customer completion with
const result = await verifyCargoDiscardFulfillment(h.context, h.inputs)
assert.equal(result.status, 'HTTP_VERIFIED')
assert.equal(h.inputs.proof.status, 'COMPLETED_HTTP_VERIFIED_CARTON_SQL_PENDING')
assert.equal(h.calls.filter(call => call.path.endsWith('/confirm')).length, 3)
assert.equal(h.calls.filter(call => call.path.endsWith('/confirm')).length, 4)
assert.equal(h.calls.filter(call => call.path.endsWith('/confirm-completion')).length, 2)
assert.equal(h.calls.filter(call => call.path.endsWith('/photos/files')).length, 1)
assert.ok(!JSON.stringify(h.persisted).includes('client-secret'))
@@ -65,7 +77,9 @@ test('discard executes same application through PDA and customer completion with
await assert.rejects(verifyCargoDiscardFulfillment(h.context, h.inputs), /已批准申请|不自动重跑/)
})
for (const fault of ['wrong customer', 'no deduction', 'duplicate ledger', 'replay deduction', 'unknown confirm', 'disk']) {
for (const fault of ['wrong customer', 'no deduction', 'duplicate ledger', 'replay deduction', 'unknown confirm', 'disk',
'ledger customer', 'ledger warehouse', 'ledger pallet', 'ledger identity', 'ledger arithmetic',
'photo accepted', 'photo wrong code', 'photo missing trace', 'photo drift']) {
test(`discard stops on ${fault}`, async () => {
const h = harness(fault)
await assert.rejects(verifyCargoDiscardFulfillment(h.context, h.inputs))
@@ -74,7 +88,7 @@ for (const fault of ['wrong customer', 'no deduction', 'duplicate ledger', 'repl
if (fault === 'wrong customer') assert.equal(h.calls.length, 1)
if (fault === 'disk') assert.equal(h.calls.length, 0)
if (fault === 'unknown confirm') {
assert.equal(h.calls.filter(call => call.path.endsWith('/confirm')).length, 1)
assert.equal(h.calls.filter(call => call.path.endsWith('/confirm')).length, 2)
assert.equal(h.inputs.proof.fulfillment.requests.at(-1).status, 'UNKNOWN_RESULT')
}
})