2026-10-22 14:37:59 +08:00
import test from 'node:test'
import assert from 'node:assert/strict'
import { prepareLooseboardPool } from './looseboard-pool-preparation.mjs'
// 模拟原车资源及容量版本;记录所有写入以验证不会创建主档或自动补发。
function fixture ( fault = '' , validPlan = false ) {
const tripProof = { marker : 'fixture' , preparation : 'VERIFIED' , tripNo : 'TR-1' , dispatchNo : 'DP-1' , warehouseId : '42' , vehicleId : '11' , driverId : '12' }
const demand = { marker : 'fixture' , finalStatus : 'PENDING_ACCEPTANCE' }
const trip = { ... tripProof , status : 'PLANNED' , recordVersion : 1 ,
stops : [{ destinationKey : 'ORIGIN' }, { destinationKey : 'FBA:TEST' }] }
const plan = { planValid : validPlan , recordVersion : 1 , manifestHash : 'a' . repeat ( 64 ), availableSegments : [{}],
cargo : [{ dispatchNo : 'DP-1' , warehousePalletId : '71' , palletNo : 'P-1' , destinationKey : 'FBA:TEST' }] }
const offer = { offerNo : 'OF-1' , tripNo : 'TR-1' , status : 'DRAFT' , recordVersion : 0 , tripRecordVersion : 1 }
const calls = [], checkpoints = []; let creates = 0 , publishes = 0 , bindCalls = 0
const context = { marker : 'fixture' , createdResources : { fleetTrips : [ tripProof ], phase4OverseasBusiness : { looseboard : demand } },
assert ( _m , name , _r , passed ) { assert . ok ( passed , name ) }, apiSuccess () {},
async checkpoint () { if ( fault === 'disk' ) throw Error ( 'disk' ); checkpoints . push ( structuredClone ( tripProof . looseboardOffer )) },
async request ( method , path , body ) {
calls . push ({ method , path , body })
let data
if ( path . endsWith ( '/dispatches/DP-1' )) data = { dispatchNo : 'DP-1' , status : 'ACTIVE' , stage : 'LOADING' ,
counts : { pickedPackageCount : fault === 'picked' ? 1 : 0 , shippedPackageCount : 0 } }
else if ( path . endsWith ( '/trips/TR-1' )) data = { trip : { ... trip , driverId : fault === 'driver' ? '13' : '12' }, dispatches : [{ dispatchNo : 'DP-1' }] }
else if ( path . endsWith ( '/capacity-plan' )) {
if ( method === 'POST' ) {
assert . equal ( body . pallets [ 0 ]. warehousePalletId , '71' )
assert . equal ( body . pallets [ 0 ]. deliveryIndex , 1 )
plan . planValid = true
}
data = structuredClone ( plan )
if ( fault === 'foreign cargo' ) data . cargo [ 0 ]. dispatchNo = 'OTHER'
} else if ( path . endsWith ( '/loading' )) data = { confirmedLoad : fault === 'loaded' ? {} : null }
else if ( path . endsWith ( '/capacity-offers' ) && method === 'POST' ) {
creates += 1
if ( fault === 'network' ) return { http : 0 }
data = { offer : { ... offer }, replayed : creates > 1 }
if ( fault === 'draft replay' && creates > 1 ) data . offer . offerNo = 'OF-2'
} else if ( path . endsWith ( '/OF-1/publish' )) {
publishes += 1
data = { offer : { ... offer , status : 'OPEN' , capacityKnown : true , canCreateInquiry : true , canConfirm : true }, replayed : publishes > 1 }
if ( fault === 'publish replay' && publishes > 1 ) data . offer . recordVersion = 9
} else throw Error ( `Unexpected ${ method } ${ path } ` )
return { http : 200 , body : { code : '200' , data : structuredClone ( data ) }, requestId : 'request' , traceId : 'trace' }
} }
const bind = async ( ctx , args ) => {
bindCalls += 1
assert . equal ( ctx , context ); assert . equal ( args . demand , demand ); assert . equal ( args . tripProof , tripProof )
assert . equal ( args . offerNo , 'OF-1' ); assert . equal ( args . destinationKey , 'FBA:TEST' )
assert . equal ( tripProof . looseboardOffer . status , 'OPEN' )
return { status : 'CONFIRMED_ORIGINAL_ORDER' , tripNo : 'TR-1' , offerNo : 'OF-1' }
}
return { context , args : { demand , tripProof , destinationKey : 'FBA:TEST' , unitPrice : 25 }, bind , calls , checkpoints , counts : () => ({ creates , publishes , bindCalls }) }
}
for ( const valid of [ false , true ]) test ( `prepare owned pool and pass original demand to binding; existing plan= ${ valid } ` , async () => {
const f = fixture ( '' , valid )
await prepareLooseboardPool ( f . context , f . args , f . bind )
assert . deepEqual ( f . counts (), { creates : 2 , publishes : 2 , bindCalls : 1 })
assert . equal ( f . calls . filter ( c => c . method === 'POST' && c . path . endsWith ( '/capacity-plan' )). length , valid ? 0 : 1 )
assert . equal ( f . args . tripProof . looseboardOffer . status , 'BOUND_ORIGINAL_DEMAND' )
await assert . rejects ( prepareLooseboardPool ( f . context , f . args , f . bind ))
assert . equal ( f . calls . some ( c => / \ / vehicles | \ / drivers | \ / iam / . test ( c . path )), false )
})
2026-10-23 04:48:02 +08:00
for ( const encoded of [ '0' , '12' , '' , null , '01' , '-1' , '9007199254740992' ]) test ( `pool source version uses bounded native Long encoding: ${ String ( encoded ) } ` , async () => {
const f = fixture ( '' , true )
const request = f . context . request
f . context . request = async ( method , path , body ) => {
const response = await request ( method , path , body )
if ( path . endsWith ( '/capacity-plan' )) response . body . data . recordVersion = encoded
return response
}
if ([ '0' , '12' ]. includes ( encoded )) await prepareLooseboardPool ( f . context , f . args , f . bind )
else {
await assert . rejects ( prepareLooseboardPool ( f . context , f . args , f . bind ), /容量依据/ )
assert . equal ( f . counts (). creates , 0 )
}
})
2026-10-22 14:37:59 +08:00
for ( const fault of [ 'picked' , 'driver' , 'foreign cargo' , 'loaded' , 'network' , 'draft replay' , 'publish replay' , 'disk' ]) {
test ( `pool preparation fails closed on ${ fault } ` , async () => {
const f = fixture ( fault )
await assert . rejects ( prepareLooseboardPool ( f . context , f . args , f . bind ))
assert . equal ( f . args . tripProof . looseboardOffer . status , 'FAILED' )
assert . equal ( f . counts (). bindCalls , 0 )
if ( fault === 'network' ) assert . equal ( f . counts (). creates , 1 )
if ( fault === 'disk' ) assert . equal ( f . calls . length , 0 )
assert . equal ( f . calls . some ( c => / cancel | close | delete /.test(c.path)), false)
})
}