test(admin): keep phase3 producer fixtures aligned
This commit is contained in:
@@ -67,11 +67,25 @@ async function detail(context, caseId) {
|
||||
return { response, data }
|
||||
}
|
||||
|
||||
export function selectCustomsFlow(createdResources) {
|
||||
const fixtures = [
|
||||
createdResources?.orchestrationFixtures?.inboundMeasurement,
|
||||
createdResources?.orchestrationFixtures?.phase3Container,
|
||||
].filter(Boolean)
|
||||
const containers = [
|
||||
createdResources?.phase3Loading,
|
||||
createdResources?.phase3ContainerLoading,
|
||||
].filter(Boolean)
|
||||
for (const container of containers) {
|
||||
const fixture = fixtures.find((candidate) => id(candidate?.tenantId) === id(container?.tenantId)
|
||||
&& id(candidate?.inboundId) === id(container?.inboundId))
|
||||
if (fixture) return { fixture, container }
|
||||
}
|
||||
return { fixture: null, container: null }
|
||||
}
|
||||
|
||||
export async function run(context) {
|
||||
const fixture = context.createdResources?.orchestrationFixtures?.inboundMeasurement
|
||||
|| context.createdResources?.orchestrationFixtures?.phase3Container
|
||||
const container = context.createdResources?.phase3Loading
|
||||
|| context.createdResources?.phase3ContainerLoading
|
||||
const { fixture, container } = selectCustomsFlow(context.createdResources)
|
||||
const tenantId = id(fixture?.tenantId)
|
||||
const parentOrderId = id(fixture?.orderId)
|
||||
const inboundId = id(fixture?.inboundId)
|
||||
|
||||
@@ -2,6 +2,23 @@ const MODULE = 'phase3-loading-finalize'
|
||||
const OPTIONS = { scenario: 'phase3-loading-hard-gate-finalize', deploymentBlocker: true }
|
||||
|
||||
function id(value) { return value == null ? '' : String(value) }
|
||||
function codeOf(response) { return response?.body?.code == null ? 'missing' : String(response.body.code) }
|
||||
|
||||
export function buildFinalizeResource(fixture, finalData, completeResponse) {
|
||||
const observedStatus = finalData?.summary?.processStatus || fixture?.inboundStatus || 'UNKNOWN'
|
||||
const observedVersion = Number(finalData?.summary?.version)
|
||||
const loaded = observedStatus === 'LOADED'
|
||||
const version = Number.isInteger(observedVersion) ? observedVersion : fixture?.inboundVersion
|
||||
return {
|
||||
...fixture,
|
||||
...(Number.isInteger(version) ? { inboundVersion: version } : {}),
|
||||
inboundStatus: observedStatus,
|
||||
finalStatus: observedStatus,
|
||||
finalizeSucceeded: loaded,
|
||||
notCleanedReason: loaded ? null
|
||||
: `装柜完成未成功,保留真实状态 ${observedStatus};completeCode=${codeOf(completeResponse)}`,
|
||||
}
|
||||
}
|
||||
|
||||
async function request(context, method, path, body, headers = {}) {
|
||||
try {
|
||||
@@ -69,7 +86,5 @@ export async function run(context) {
|
||||
&& item.operatorName && item.fromStatus === 'LOADING' && item.toStatus === 'LOADED'),
|
||||
`status=${finalData?.summary?.processStatus || 'missing'}, version=${finalData?.summary?.version ?? 'missing'}, histories=${finalData?.statusHistory?.length ?? 'n/a'}`, OPTIONS)
|
||||
|
||||
context.createdResources.phase3Loading = {
|
||||
...fixture, inboundVersion: Number(finalData?.summary?.version), inboundStatus: 'LOADED', finalStatus: 'LOADED',
|
||||
}
|
||||
context.createdResources.phase3Loading = buildFinalizeResource(fixture, finalData, completeResponse)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
|
||||
import { selectCustomsFlow } from './phase3-customs.mjs'
|
||||
import { buildFinalizeResource } from './phase3-loading-finalize.mjs'
|
||||
|
||||
test('pairs customs source fixture with the matching loading container', () => {
|
||||
const resources = {
|
||||
orchestrationFixtures: {
|
||||
inboundMeasurement: { tenantId: 10001, orderId: 101, inboundId: 201 },
|
||||
phase3Container: { tenantId: 10001, orderId: 102, inboundId: 202 },
|
||||
},
|
||||
phase3Loading: { tenantId: 10001, inboundId: 201, containerBookingId: 301 },
|
||||
phase3ContainerLoading: { tenantId: 10001, inboundId: 202, containerBookingId: 302 },
|
||||
}
|
||||
const selected = selectCustomsFlow(resources)
|
||||
assert.equal(selected.fixture.orderId, 101)
|
||||
assert.equal(selected.container.containerBookingId, 301)
|
||||
})
|
||||
|
||||
test('falls back to the matching container fixture without crossing source identities', () => {
|
||||
const resources = {
|
||||
orchestrationFixtures: { phase3Container: { tenantId: 10001, orderId: 102, inboundId: 202 } },
|
||||
phase3Loading: { tenantId: 10001, inboundId: 201, containerBookingId: 301 },
|
||||
phase3ContainerLoading: { tenantId: 10001, inboundId: 202, containerBookingId: 302 },
|
||||
}
|
||||
const selected = selectCustomsFlow(resources)
|
||||
assert.equal(selected.fixture.orderId, 102)
|
||||
assert.equal(selected.container.containerBookingId, 302)
|
||||
})
|
||||
|
||||
test('records LOADING and a cleanup reason when finalize returns S0500', () => {
|
||||
const result = buildFinalizeResource(
|
||||
{ inboundStatus: 'LOADING', inboundVersion: 5, finalStatus: 'COMPLETED' },
|
||||
{ summary: { processStatus: 'LOADING', version: 5 } },
|
||||
{ http: 200, body: { code: 'S0500' } },
|
||||
)
|
||||
assert.equal(result.finalStatus, 'LOADING')
|
||||
assert.equal(result.finalizeSucceeded, false)
|
||||
assert.match(result.notCleanedReason, /S0500/)
|
||||
})
|
||||
|
||||
test('records LOADED and clears the reason only after a real LOADED reread', () => {
|
||||
const result = buildFinalizeResource(
|
||||
{ inboundStatus: 'LOADING', inboundVersion: 5, finalStatus: 'COMPLETED' },
|
||||
{ summary: { processStatus: 'LOADED', version: 6 } },
|
||||
{ http: 200, body: { code: '200' } },
|
||||
)
|
||||
assert.equal(result.finalStatus, 'LOADED')
|
||||
assert.equal(result.finalizeSucceeded, true)
|
||||
assert.equal(result.notCleanedReason, null)
|
||||
})
|
||||
Reference in New Issue
Block a user