Files
baiyue-firstleg/scripts/admin-test-env-modules/fleet-fee-coverage-acceptance-contract.test.mjs
T
2026-10-21 14:30:41 +08:00

40 lines
3.8 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { verifyFleetFeeCoverage } from './fleet-fee-coverage-acceptance.mjs'
const BASE = '/api/platform/v1/last-leg/dispatches'
function fixture(fault = '') {
const cases = ['FULL','PARTIAL'].map((mode,i)=>({marker:'RUN',mode,dispatchNo:`DS-${i}`,customerId:'C'}))
const trips = cases.map(c=>({dispatchNo:c.dispatchNo,tripNo:`TR-${c.mode}`,warehouseId:'92',loadingCommand:{body:{idempotencyKey:`KEY-${c.mode}`},result:{action:'LOADING_COMPLETE',dispatchNo:c.dispatchNo,stage:'DELIVERING',result:{loadingCompletionHash:'HASH'}}}}))
const items = cases.map((c,i)=>[{customerId:'C',warehousePalletId:fault==='overlap'?'PAL':`PAL-${i}`,sourceKey:`SOURCE-${i}`,destination:{key:'FBA:A'},pickedPackages:2,scheduledPackages:2}])
const docs = i=>({outbounds:[{customerId:'C',outboundNo:`OUT-${i}`,status:'OUTBOUNDED'}],deliveries:[{customerId:'C',outboundNo:`OUT-${i}`,deliveryNo:`DEL-${i}`,destination:{key:'FBA:A'},status:'DELIVERING',packageCount:2}]})
const detail = i=>({dispatchNo:`DS-${i}`,recordVersion:7,status:'ACTIVE',stage:'DELIVERING',pickingReconciled:true,counts:{packageCount:2,pickedPackageCount:2,shippedPackageCount:2},documents:fault==='missing-docs'?{}:docs(i)})
const calls=[]
const context={marker:'RUN',createdResources:{fleetFeeCoverageCases:cases,fleetTrips:trips},checkpoint:async()=>{},assert(_m,label,_r,ok){assert.ok(ok,label)},apiSuccess(_m,_l,r){return r.body.data},async request(method,raw){
calls.push({method,raw});assert.equal(method,'GET')
const url=new URL(raw,'https://offline.invalid'),path=url.pathname
let data
if(path===BASE){const i=Number(url.searchParams.get('dispatchNo').slice(-1));data={records:[{...detail(i),warehouseId:'92'}]}}
else if(path.includes('/delivery-orders/')){const i=Number(path.slice(-1));assert.equal(url.searchParams.get('customerId'),'C');data={order:{dispatchNo:`DS-${i}`,deliveryNo:`DEL-${i}`,outboundNo:`OUT-${i}`,customerId:fault==='foreign-customer'?'OTHER':'C',packageCount:2,status:'DELIVERING'},fees:fault==='duplicate-fee'?[{id:'F'},{id:'F'}]:[],feeCoverage:null}}
else{const i=Number(path.split('/dispatches/')[1][3]);data=path.endsWith('/items')?{...detail(i),items:items[i]}:detail(i)}
return {http:200,body:{code:'200',data},requestId:'REQ',traceId:'TRACE'}
}}
return {context,cases,trips,calls}
}
for(const index of [0,1])test(`automatic delivery reads authoritative documents for fixture ${index}`,async()=>{
const f=fixture(),proof=await verifyFleetFeeCoverage(f.context,'automatic',f.cases[index])
assert.equal(proof.status,'VERIFIED');assert.deepEqual(proof.deliveryNos,[`DEL-${index}`])
assert.equal(proof.feeCoverageSelection,'NOT_APPLICABLE_AUTOMATIC_DELIVERY')
assert.equal(Object.hasOwn(proof,'newReceivable'),false)
assert.deepEqual(proof.confirmationRequest,f.trips[index].loadingCommand.body)
assert.ok(f.calls.every(c=>c.method==='GET'))
assert.equal((await verifyFleetFeeCoverage(f.context,'automatic',f.cases[index],{reconcilePersisted:true})).status,'VERIFIED')
await assert.rejects(verifyFleetFeeCoverage(f.context,'automatic',f.cases[index]),/未执行/)
})
for(const fault of ['overlap','missing-docs','foreign-customer','duplicate-fee'])test(`automatic proof rejects ${fault}`,async()=>{
const f=fixture(fault);await assert.rejects(verifyFleetFeeCoverage(f.context,'automatic',f.cases[0]));assert.notEqual(f.cases[0].proof.status,'VERIFIED')
})
test('requires original current-run loading completion receipt and registered disjoint fixtures',async()=>{
const f=fixture();delete f.trips[0].loadingCommand;await assert.rejects(verifyFleetFeeCoverage(f.context,'automatic',f.cases[0]))
const missing=fixture();missing.cases.pop();await assert.rejects(verifyFleetFeeCoverage(missing.context,'automatic',missing.cases[0]));assert.equal(missing.calls.length,0)
})