import test from 'node:test' import assert from 'node:assert/strict' import { verifyCargoDiscardFulfillment } from './cargo-discard-fulfillment.mjs' function harness(fault = '') { const calls = [], persisted = [] let discarded = false, confirmed = false, repeats = 0 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', status: 'PENDING', skus: [{ itemId: '301', skuCode: proof.skuCode, quantityUnit: '箱', plannedPackages: 1 }], cartonMarks: ['BOX-TEST'] } const context = { marker: 'DISCARD-TEST', context: { merchantQualificationFixture: { tenantId: '101' } }, createdResources: { phase4OverseasClientServices: { marker: 'DISCARD-TEST' } }, assert(_module, name, _response, passed) { assert.ok(passed, name) }, async request(method, path, body, token) { calls.push({ method, path, body, token }) assert.equal(persisted.at(-1)?.requests.at(-1)?.status, 'SENDING') let data if (method === 'GET') data = [{ ...task, customerId: fault === 'wrong customer' ? '999' : '101' }] else if (path.endsWith('/resolve')) data = task else if (path.endsWith('/confirm-completion')) { confirmed = true; data = {} } else if (path.endsWith('/confirm')) { if (fault === 'unknown confirm') throw new Error('network unknown') if (discarded) repeats++ discarded = true data = { ...task, status: 'COMPLETED', skus: [{ ...task.skus[0], actualPackages: 1 }] } } else throw new Error(`unexpected ${path}`) return { http: 200, body: { code: '200', data } } }, async requestMultipart(method, path, form, token) { calls.push({ method, path, token }) assert.ok(form.get('file')) assert.equal(persisted.at(-1)?.requests.at(-1)?.status, 'SENDING') return { http: 200, body: { code: '200', data: { fileId: '401', palletNo: task.palletNo } } } }, } const inputs = { proof, merchantToken: 'client-secret', pdaToken: 'pda-secret', async checkpoint() { if (fault === 'disk') throw new Error('disk full') persisted.push(structuredClone(proof.fulfillment)) }, 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, skuCode: proof.skuCode, inboundCode: proof.inboundCode }] : [] if (discarded && fault === 'duplicate ledger') ledger.push({ ...ledger[0] }) 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 } } } } } return { context, inputs, calls, persisted } } test('discard executes same application through PDA and customer completion with zero-drift replays', async () => { const h = harness() 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-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')) assert.ok(!JSON.stringify(h.persisted).includes('pda-secret')) await assert.rejects(verifyCargoDiscardFulfillment(h.context, h.inputs), /已批准申请|不自动重跑/) }) for (const fault of ['wrong customer', 'no deduction', 'duplicate ledger', 'replay deduction', 'unknown confirm', 'disk']) { test(`discard stops on ${fault}`, async () => { const h = harness(fault) await assert.rejects(verifyCargoDiscardFulfillment(h.context, h.inputs)) assert.equal(h.inputs.proof.fulfillment.status, 'FAILED') assert.equal(h.calls.some(call => call.path.endsWith('/confirm-completion')), false) 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.inputs.proof.fulfillment.requests.at(-1).status, 'UNKNOWN_RESULT') } }) } test('foreign batch or customer fails before HTTP or checkpoint', async () => { const h = harness() h.inputs.proof.customerId = '999' await assert.rejects(verifyCargoDiscardFulfillment(h.context, h.inputs), /本轮已批准申请/) assert.equal(h.calls.length, 0) assert.equal(h.persisted.length, 0) })