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) })