test(admin): complete phase3 producer fixtures
This commit is contained in:
@@ -39,7 +39,8 @@ export async function run(context) {
|
||||
context.apiSuccess(MODULE, '创建隔离海运订舱', createResponse, `key=${key}`, OPTIONS)
|
||||
context.assert(MODULE, '订舱 DTO 字段、DRAFT 和9类关联字段完整', createResponse, Boolean(bookingId) && detail?.oceanBooking?.status === 'DRAFT' && detail?.parties?.length === 3 && detail?.containerRequirements?.length === 1, `bookingId=${bookingId || 'missing'}, parties=${detail?.parties?.length ?? 'n/a'}, requirements=${detail?.containerRequirements?.length ?? 'n/a'}`, OPTIONS)
|
||||
if (!bookingId) return
|
||||
context.createdResources.oceanBooking = { id: bookingId, customerId: '10001', marker: context.marker, finalStatus: 'RELEASED' }
|
||||
context.createdResources.oceanBooking = { id: bookingId, customerId: '10001', marker: context.marker,
|
||||
containerBookingId: null, loadingPlanId: null, finalStatus: 'DRAFT' }
|
||||
const replay = await createBooking(context, suffix, key)
|
||||
context.assert(MODULE, '创建 Idempotency-Key 重放返回同一订舱', replay, String(data(replay)?.oceanBooking?.id) === bookingId, `first=${bookingId}, replay=${id(data(replay)?.oceanBooking?.id)}`, OPTIONS)
|
||||
const path = `${BASE}/${bookingId}`
|
||||
@@ -84,6 +85,12 @@ export async function run(context) {
|
||||
fd?.oceanBooking?.status === 'RELEASED' && fd.histories?.length >= 5 && fd.histories.every((h) => h.operatorName)
|
||||
&& (!containerFlow || fd?.containerAllocations?.some?.((item) => id(item?.containerBookingId) === id(containerFlow.containerBookingId))),
|
||||
`status=${fd?.oceanBooking?.status || 'missing'}, histories=${fd?.histories?.length ?? 'n/a'}, allocations=${fd?.containerAllocations?.length ?? 'n/a'}`, OPTIONS)
|
||||
context.createdResources.oceanBooking = {
|
||||
id: bookingId, customerId: id(fd?.oceanBooking?.customerId), marker: context.marker,
|
||||
containerBookingId: containerFlow ? id(containerFlow.containerBookingId) : null,
|
||||
loadingPlanId: containerFlow ? id(containerFlow.loadingPlanId) : null,
|
||||
finalStatus: fd?.oceanBooking?.status || null,
|
||||
}
|
||||
const missingDetail = await request(context, 'GET', `${BASE}/999999999999999999`)
|
||||
step(context, '不存在订舱详情安全失败', missingDetail, failure(missingDetail), `HTTP=${missingDetail.http}, code=${codeOf(missingDetail)}`)
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ async function detail(context, caseId) {
|
||||
|
||||
export function selectCustomsFlow(createdResources) {
|
||||
const fixtures = [
|
||||
createdResources?.orders,
|
||||
createdResources?.orchestrationFixtures?.inboundMeasurement,
|
||||
createdResources?.orchestrationFixtures?.phase3Container,
|
||||
].filter(Boolean)
|
||||
@@ -84,6 +85,43 @@ export function selectCustomsFlow(createdResources) {
|
||||
return { fixture: null, container: null }
|
||||
}
|
||||
|
||||
async function ensureServiceCenterFlow(context, container) {
|
||||
const containerBookingId = id(container?.containerBookingId)
|
||||
const loadingPlanId = id(container?.loadingPlanId)
|
||||
let ocean = context.createdResources?.oceanBooking
|
||||
if (ocean?.finalStatus !== 'RELEASED'
|
||||
|| id(ocean?.containerBookingId) !== containerBookingId
|
||||
|| id(ocean?.loadingPlanId) !== loadingPlanId) {
|
||||
const oceanBookings = await import(new URL('./ocean-bookings.mjs', import.meta.url))
|
||||
await oceanBookings.run(context)
|
||||
ocean = context.createdResources?.oceanBooking
|
||||
}
|
||||
if (ocean?.finalStatus !== 'RELEASED'
|
||||
|| id(ocean?.containerBookingId) !== containerBookingId
|
||||
|| id(ocean?.loadingPlanId) !== loadingPlanId) {
|
||||
context.addStep(MODULE, '报关前订舱已放舱并绑定实际装柜柜次', null, false,
|
||||
`oceanStatus=${ocean?.finalStatus || 'missing'}, oceanContainer=${id(ocean?.containerBookingId) || 'missing'}, containerBookingId=${containerBookingId || 'missing'}`, OPTIONS)
|
||||
return false
|
||||
}
|
||||
|
||||
let truck = context.createdResources?.serviceCenterFlow
|
||||
if (truck?.finalStatus !== 'COMPLETED'
|
||||
|| id(truck?.oceanBookingId) !== id(ocean.id)
|
||||
|| id(truck?.containerBookingId) !== containerBookingId
|
||||
|| id(truck?.loadingPlanId) !== loadingPlanId) {
|
||||
const serviceCenter = await import(new URL('./service-center-flow.mjs', import.meta.url))
|
||||
await serviceCenter.run(context)
|
||||
truck = context.createdResources?.serviceCenterFlow
|
||||
}
|
||||
const ready = truck?.finalStatus === 'COMPLETED'
|
||||
&& id(truck?.oceanBookingId) === id(ocean.id)
|
||||
&& id(truck?.containerBookingId) === containerBookingId
|
||||
&& id(truck?.loadingPlanId) === loadingPlanId
|
||||
context.addStep(MODULE, '报关前拖车已完成并绑定实际装柜柜次', null, ready,
|
||||
`truckStatus=${truck?.finalStatus || 'missing'}, truckContainer=${id(truck?.containerBookingId) || 'missing'}, containerBookingId=${containerBookingId || 'missing'}`, OPTIONS)
|
||||
return ready
|
||||
}
|
||||
|
||||
export async function run(context) {
|
||||
const { fixture, container } = selectCustomsFlow(context.createdResources)
|
||||
const tenantId = id(fixture?.tenantId)
|
||||
@@ -97,6 +135,7 @@ export async function run(context) {
|
||||
`tenantId=${tenantId || 'missing'}, parentOrderId=${parentOrderId || 'missing'}, inboundId=${inboundId || 'missing'}, containerBookingId=${containerBookingId || 'missing'}, loadingPlanId=${loadingPlanId || 'missing'}, containerStatus=${container?.finalStatus || 'missing'}`, OPTIONS)
|
||||
return
|
||||
}
|
||||
if (!await ensureServiceCenterFlow(context, container)) return
|
||||
|
||||
const slicesPath = `/api/platform/v1/orders/container-bookings/${encodeURIComponent(containerBookingId)}/fulfillment-slices?tenantId=${encodeURIComponent(tenantId)}`
|
||||
const slicesResponse = await context.request('GET', slicesPath)
|
||||
|
||||
@@ -20,8 +20,8 @@ function assertOrder(value, snippets) {
|
||||
|
||||
test('pairs customs source fixture with the matching loading container', () => {
|
||||
const resources = {
|
||||
orders: { tenantId: 10001, orderId: 101, inboundId: 201 },
|
||||
orchestrationFixtures: {
|
||||
inboundMeasurement: { tenantId: 10001, orderId: 101, inboundId: 201 },
|
||||
phase3Container: { tenantId: 10001, orderId: 102, inboundId: 202 },
|
||||
},
|
||||
phase3Loading: { tenantId: 10001, inboundId: 201, containerBookingId: 301 },
|
||||
@@ -88,6 +88,20 @@ test('bridge loading starts through a real PDA batch before preload confirmation
|
||||
assert.match(value, /confirmed\?\.mainStatus === 'LOADING' && confirmed\?\.preloadPlan\?\.status === 'CONFIRMING'/)
|
||||
assert.match(value, /confirmed\?\.preloadPlan\?\.status === 'CONFIRMED'/)
|
||||
assert.doesNotMatch(value, /关联柜次计划进入 LOADING/)
|
||||
assert.match(value, /confirmed\?\.mainStatus === 'LOADING'/)
|
||||
assert.match(value, /confirmed\?\.preloadPlan\?\.status === 'CONFIRMING'/)
|
||||
assert.match(value, /Number\(confirmed\?\.preloadPlan\?\.version\) === 2/)
|
||||
})
|
||||
|
||||
test('customs provisions released booking and completed truck for the selected loading container', () => {
|
||||
const value = source('./phase3-customs.mjs')
|
||||
assertOrder(value, [
|
||||
'selectCustomsFlow(context.createdResources)',
|
||||
'if (!await ensureServiceCenterFlow(context, container)) return',
|
||||
'const slicesPath =',
|
||||
])
|
||||
assert.match(value, /oceanBookings\.run\(context\)/)
|
||||
assert.match(value, /serviceCenter\.run\(context\)/)
|
||||
})
|
||||
|
||||
test('downstream producers prefer the phase3Loading container fixture', () => {
|
||||
|
||||
@@ -34,8 +34,11 @@ export async function run(context) {
|
||||
const ocean = context.createdResources?.oceanBooking
|
||||
const containerFlow = context.createdResources?.phase3Loading
|
||||
|| context.createdResources?.phase3ContainerLoading
|
||||
const containerFixture = context.createdResources?.orchestrationFixtures?.inboundMeasurement
|
||||
|| context.createdResources?.orchestrationFixtures?.phase3Container
|
||||
const containerFixture = [
|
||||
context.createdResources?.orders,
|
||||
context.createdResources?.orchestrationFixtures?.inboundMeasurement,
|
||||
context.createdResources?.orchestrationFixtures?.phase3Container,
|
||||
].find((item) => id(item?.inboundId) === id(containerFlow?.inboundId))
|
||||
if (!ocean?.id || ocean.finalStatus !== 'RELEASED') {
|
||||
context.addStep(MODULE, '跨服务链路前置订舱终态可用', null, false,
|
||||
'本轮海运订舱模块未返回 RELEASED 隔离记录,未伪造关联拖车预约', OPTIONS)
|
||||
|
||||
Reference in New Issue
Block a user