test(fleet): isolate pick commands per customer dispatch

This commit is contained in:
2026-10-07 17:21:58 +08:00
parent 27c0fe80f6
commit dbdd7bb066
2 changed files with 75 additions and 5 deletions
+53 -1
View File
@@ -1,7 +1,7 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import { parsePoolArguments, poolPlan, runPoolAcceptance, assertPoolRemaining, assertSingleCommercial,
shrinkingVehicleRequest, expiryWaitMs, poolLocalDateTime, POOL_COVERAGE, POOL_REMAINING } from './fleet-capacity-pool-test-env.mjs'
shrinkingVehicleRequest, expiryWaitMs, poolLocalDateTime, poolPickScope, pickPoolDispatch, POOL_COVERAGE, POOL_REMAINING } from './fleet-capacity-pool-test-env.mjs'
test('default and explicit plans make no network requests or invoke the mutating runner', async () => {
const original = globalThis.fetch
@@ -106,3 +106,55 @@ test('LocalDateTime transport time keeps actual local wall clock while Instant d
assert.equal(new LosAngelesDate(instant).toISOString(), instant)
assert.throws(() => poolLocalDateTime(new Date('invalid')), /VALID_LOCAL_DATE_REQUIRED/)
})
test('PDA namespace belongs to the exact run, customer and dispatch while parent evidence stays shared', () => {
const context = { marker: 'ORIGINAL-RUN', steps: [], createdResources: {} }, first = { customerId: '9', dispatchNo: 'DS-A' }
const a = poolPickScope(context, first), replay = poolPickScope(context, first)
assert.equal(a.marker, replay.marker)
assert.notEqual(a.marker, poolPickScope(context, { ...first, dispatchNo: 'DS-B' }).marker)
assert.notEqual(a.marker, poolPickScope(context, { ...first, customerId: '10' }).marker)
assert.notEqual(a.marker, poolPickScope({ ...context, marker: 'OTHER-RUN' }, first).marker)
assert.equal(a.steps, context.steps)
assert.equal(a.createdResources, context.createdResources)
assert.equal(context.marker, 'ORIGINAL-RUN')
assert.throws(() => poolPickScope(context, { dispatchNo: 'DS-A' }), /PICK_SCOPE_REQUIRED/)
})
test('real pickAll helper handles two same-customer dispatches with separate pick/complete keys and exact replays', async () => {
const operations = new Map(), requests = [], steps = [], picked = new Map()
const dispatches = ['DS-A', 'DS-B']
const context = {
marker: 'SAME-CUSTOMER-RUN', steps, createdResources: {},
addStep(_module, _name, _response, passed) { steps.push(passed) },
assert(_module, _name, _response, passed) { assert.equal(Boolean(passed), true) },
addCoverageGap() { assert.fail('unexpected coverage gap') },
async request(method, path, body) {
const dispatchNo = path.split('/dispatches/')[1].split('/')[0], index = dispatches.indexOf(dispatchNo)
assert.ok(index >= 0)
const response = data => ({ http: 200, body: { code: '200', data }, requestId: 'test', traceId: 'test' })
if (method === 'GET') return response({ items: [{ dispatchItemId: `${index + 1}`, scheduledPackages: 1,
pickedPackages: picked.get(dispatchNo) || 0, positions: [{ id: `${index + 100}`, availablePackages: 1 }] }] })
requests.push({ method, path, body: structuredClone(body) })
const prior = operations.get(body.idempotencyKey), payload = JSON.stringify([path, body])
if (prior) {
if (prior.payload !== payload) return { http: 200, body: { code: 'A0409', message: 'Idempotency key was reused with a different request' } }
return response({ ...prior.result, replayed: true })
}
let result
if (path.endsWith('/pick')) { picked.set(dispatchNo, 1); result = { pickedPackages: 1 } }
else result = { status: 'READY_TO_DEPART', plannedPackages: 1, pickedPackages: 1, remainingPackages: 0, replayed: false }
operations.set(body.idempotencyKey, { payload, result })
return response(result)
},
}
for (const dispatchNo of dispatches) await pickPoolDispatch(context, 'test-pda', { customerId: '9', dispatchNo })
assert.equal(operations.size, 4)
assert.equal(requests.length, 8)
assert.ok(steps.every(Boolean))
for (let index = 0; index < requests.length; index += 2) assert.deepEqual(requests[index], requests[index + 1])
})
test('failed helper result stops the pool stage immediately instead of appending a misleading generic failure', async () => {
const context = { marker: 'R', steps: [] }
await assert.rejects(pickPoolDispatch(context, 'test', { customerId: '9', dispatchNo: 'DS-A' }, async () => false), /PDA_PICK_FAILED:DS-A/)
})