test: stabilize preload push replay assertions

This commit is contained in:
2026-08-15 17:32:16 +08:00
parent 8350bcdf00
commit 05921eca13
5 changed files with 202 additions and 24 deletions
@@ -5,6 +5,7 @@ import test from 'node:test'
import { selectCustomsFlow } from './phase3-customs.mjs'
import { buildFinalizeResource } from './phase3-loading-finalize.mjs'
import { selectContainerLoadingFixture, selectPlatformChannelIsolationPair } from './phase3-container-loading.mjs'
import { diffPushPreloadStability, projectPushPreloadStability } from './push-preload-stability.mjs'
import { AcceptanceRun, normalizeModuleOrder, parseArguments } from '../admin-test-env-acceptance.mjs'
function source(name) {
@@ -132,9 +133,53 @@ test('push replay and both conflict modes preserve the complete pre-PDA snapshot
assert.match(value, /非法 push 后回查柜次计划[\s\S]*非法 push 后回查预装历史[\s\S]*非法 push 后回查 bridge/)
assert.match(value, /两类非法 push 后计划版本历史关联(?:和)?任务仍?零漂移/)
assert.match(value, /codeOf\(rejectedTaskResponse\) === 'A0404'/)
assert.match(value, /projectPushPreloadStability/)
assert.match(value, /diffPushPreloadStability/)
assert.match(value, /首次 push 后读取事务完成态柜次计划/)
assert.match(value, /事务完成态计划版本与 bridge 一致且保持 EDITING/)
assert.match(value, /plan: postPushPlan, detail:/)
assert.match(value, /expectedVersion: Number\(postPushPlan\.version\)/)
assert.match(value, /changed=\$\{(?:pushReplayDiff|replayDiff|rejectedDiff)\.join/)
assert.doesNotMatch(value, /baselineBytes=|replayBytes=|rejectedBytes=/)
}
})
test('push stability projection sorts unordered facts and reports persisted field drift', () => {
const baseline = projectPushPreloadStability({
plan: { id: '10', bookingId: '20', status: 'EDITING', version: 2,
items: [{ id: '2', inboundId: '42', packageCount: 1, version: 1 },
{ id: '1', inboundId: '41', packageCount: 1, version: 1 }] },
detail: { summary: { planId: '10', containerBookingId: '20', status: 'EDITING', version: 2,
readiness: { preloadPushed: true, preloadLinkCount: 2, confirmationStatus: 'PENDING',
blockingReasons: ['CONTAINER_NO_MISSING', 'OCEAN_BOOKING_NOT_LINKED'] } },
items: [{ itemId: '2', inboundId: '42', packageCount: 1 }, { itemId: '1', inboundId: '41', packageCount: 1 }],
histories: [{ historyId: '2', actionType: 'PUSH' }, { historyId: '1', actionType: 'CREATE' }] },
links: [{ id: '2', inboundId: '42', loadingPlanId: '10', allocatedPackageCount: 1 },
{ id: '1', inboundId: '41', loadingPlanId: '10', allocatedPackageCount: 1 }],
task: { http: 200, code: 'A0404' },
})
const reordered = projectPushPreloadStability({
plan: { id: '10', bookingId: '20', status: 'EDITING', version: 2,
items: [{ id: '1', inboundId: '41', packageCount: 1, version: 1 },
{ id: '2', inboundId: '42', packageCount: 1, version: 1 }], updatedAt: 'ignored' },
detail: { summary: { planId: '10', containerBookingId: '20', status: 'EDITING', version: 2,
readiness: { preloadPushed: true, preloadLinkCount: 2, confirmationStatus: 'PENDING',
blockingReasons: ['OCEAN_BOOKING_NOT_LINKED', 'CONTAINER_NO_MISSING'] } },
items: [{ itemId: '1', inboundId: '41', packageCount: 1 }, { itemId: '2', inboundId: '42', packageCount: 1 }],
histories: [{ historyId: '1', actionType: 'CREATE' }, { historyId: '2', actionType: 'PUSH' }] },
links: [{ id: '1', inboundId: '41', loadingPlanId: '10', allocatedPackageCount: 1 },
{ id: '2', inboundId: '42', loadingPlanId: '10', allocatedPackageCount: 1 }],
task: { http: 200, code: 'A0404' },
})
assert.deepEqual(diffPushPreloadStability(baseline, reordered), [])
const drifted = structuredClone(reordered)
drifted.plan.version = 3
drifted.links[0].preloadVersion = 2
assert.deepEqual(diffPushPreloadStability(baseline, drifted), [
'links[0].preloadVersion:null->2', 'plan.version:2->3',
])
})
test('push orchestration is transactional and a bridge failure cannot reach PDA creation', () => {
const service = source('../../firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java')
const serviceTest = source('../../firstleg/src/test/java/com/baiyue/firstleg/service/SmartLoadingServiceTest.java')
@@ -212,7 +257,7 @@ test('container loading arranges a simulation before linking a confirmed real bo
}
assert.doesNotMatch(value, /loading-booking-(?:submit|confirm)|ocean-bookings\/.*\/(?:submit|confirm)/)
assert.match(value, /containerAllocations\.length === 0/)
assert.match(value, /expectedVersion: Number\(pushed\.version\), operationReason: context\.marker/)
assert.match(value, /expectedVersion: Number\(postPushPlan\.version\), operationReason: context\.marker/)
assert.match(value, /function responseEvidence\(response\)[\s\S]*HTTP=\$\{response\?\.http \?\? 'missing'\}[\s\S]*code=\$\{codeOf\(response\)\}[\s\S]*requestId=\$\{response\?\.requestId \|\| 'missing'\}[\s\S]*traceId=\$\{response\?\.traceId \|\| 'missing'\}/)
assert.match(value, /emptySimulation = context\.apiSuccess\(MODULE, '空模拟柜首次关联真实订舱', emptyLink,\s+responseEvidence\(emptyLink\), OPTIONS\)\s+if \(!emptySimulation\) return\s+const emptyUnlink = await request/)
assert.match(value, /emptySimulation = context\.apiSuccess\(MODULE, '空模拟柜允许解除关联', emptyUnlink,\s+responseEvidence\(emptyUnlink\), OPTIONS\)\s+if \(!emptySimulation\) return\s+const emptyRelink = await request/)