test: sequence terminal drayage around unloading

This commit is contained in:
2026-09-11 01:50:46 +08:00
parent abbacc683e
commit fe278f2ba6
6 changed files with 86 additions and 48 deletions
@@ -3,7 +3,7 @@ import { readFile } from 'node:fs/promises'
import test from 'node:test'
import { fileURLToPath } from 'node:url'
import { normalizeModuleOrder } from '../admin-test-env-acceptance.mjs'
import { run } from './phase5-terminal-drayage.mjs'
import { prepareTerminalDrayage, run } from './phase5-terminal-drayage.mjs'
const source = await readFile(fileURLToPath(new URL('./phase5-terminal-drayage.mjs', import.meta.url)), 'utf8')
@@ -19,11 +19,12 @@ test('four real command payloads mutate contract fields and preserve remarks and
let conflicts = 0
let replays = 0
const response = (data, code = '200') => ({ http: 200, body: { code, data }, requestId: 'offline-request', traceId: 'offline-trace' })
const producer = { containerBookingId, containerNo, shippingReady: true,
carrierScheduleQueryId: '9223372036854775805', carrierLatestActualAt: '2026-09-09T01:00:00' }
const context = {
marker, token: 'offline-only',
createdResources: {
phase4InboundProducerFixtures: { marker, containers: [{ containerBookingId, containerNo,
shippingReady: true, carrierScheduleQueryId: '9223372036854775805', carrierLatestActualAt: '2026-09-09T01:00:00' }] },
phase4InboundProducerFixtures: { marker, containers: [producer] },
phase4OverseasPda: { marker, finalStatus: 'COMPLETED', completedContainerFacts: [{ containerBookingId, containerNo }] },
},
apiSuccess(_module, name, result) { assert.equal(result.body.code, '200', name); return result.body.data },
@@ -58,13 +59,15 @@ test('four real command payloads mutate contract fields and preserve remarks and
state = { ...state, version: state.version + 1 }
if (index === 0) Object.assign(state, { fleetSupplierId: body.fleetSupplierId, fleetSupplierName: body.fleetSupplierName, allowedActions: ['SCHEDULE_PICKUP'] })
if (index === 1) state.pickupAppointmentAt = body.pickupAppointmentAt
if (index === 2) Object.assign(state, { status: 'UNLOADED', actualPickupAt: body.actualAt, unloadingCompletedAt: '2026-09-09T04:00:00', allowedActions: ['RECORD_EMPTY_RETURN'] })
if (index === 2) Object.assign(state, { status: 'PICKED_UP', actualPickupAt: body.actualAt, allowedActions: [] })
if (index === 3) Object.assign(state, { status: 'EMPTY_RETURNED', actualEmptyReturnAt: body.actualAt, allowedActions: [], emptyReturnWarning: { status: 'RESOLVED' } })
history.push({ action: actions[index], fromVersion: index, toVersion: index + 1, reason: body[field] })
commands.set(key, { body: structuredClone(body), state: structuredClone(state) })
return response(state)
},
}
await prepareTerminalDrayage(context, producer)
state = { ...state, status: 'UNLOADED', unloadingCompletedAt: '2026-09-09T04:00:00', allowedActions: ['RECORD_EMPTY_RETURN'] }
await run(context)
assert.equal(commands.size, 4)
assert.equal(replays, 4)
@@ -73,7 +76,7 @@ test('four real command payloads mutate contract fields and preserve remarks and
assert.equal(context.createdResources.phase5TerminalDrayage.finalStatus, 'EMPTY_RETURNED')
})
test('terminal drayage runs after pickup-ready and overseas unloading but before final carrier validation', () => {
test('terminal drayage prepares pickup before unloading and finalizes return before carrier validation', () => {
const modules = normalizeModuleOrder(['phase4-carrier-nodes'])
const pickup = modules.indexOf('phase4-carrier-pickup-ready')
const pda = modules.indexOf('phase4-overseas-pda')
@@ -106,12 +109,10 @@ test('all four commands cover idempotent replay hash conflict and lifecycle sema
test('target is strictly current-marker pickup and completed-PDA container', () => {
assert.match(source, /matrix\?\.marker !== context\.marker/)
assert.match(source, /pda\?\.marker !== context\.marker/)
assert.match(source, /prepared\?\.marker !== context\.marker/)
assert.match(source, /pda\?\.finalStatus !== 'COMPLETED'/)
assert.match(source, /completedContainerFacts/)
assert.match(source, /item\?\.shippingReady === true/)
assert.match(source, /carrierScheduleQueryId/)
assert.match(source, /carrierLatestActualAt/)
assert.match(source, /producer\?\.shippingReady !== true/)
assert.match(source, /phase4CarrierPickupReady =/)
assert.match(source, /禁止借历史货柜/)
})