This commit is contained in:
2026-08-12 10:59:39 +08:00
parent 91c6ebca5c
commit 4d0c245b60
16 changed files with 1368 additions and 12 deletions
@@ -4,6 +4,7 @@ import test from 'node:test'
import { selectCustomsFlow } from './phase3-customs.mjs'
import { buildFinalizeResource } from './phase3-loading-finalize.mjs'
import { AcceptanceRun } from '../admin-test-env-acceptance.mjs'
function source(name) {
return readFileSync(new URL(name, import.meta.url), 'utf8')
@@ -118,6 +119,16 @@ test('PDA inventory snapshot gates batch and records the only safe mutation gap'
assert.match(convergence, /fixture\?\.inventoryMutationVerified !== true/)
})
test('PDA completion acceptance verifies immutable BATCH audit with operator metadata', () => {
const container = source('./phase3-container-loading.mjs')
const convergence = source('./phase3-pda-convergence.mjs')
assert.match(container, /回查完成后的 PDA 操作审计/)
assert.match(container, /item\.actionType === 'BATCH'/)
assert.match(container, /Boolean\(item\.operatorId\) && Boolean\(item\.createdAt\)/)
assert.match(convergence, /PDA 原子批次完成审计包含 BATCH 操作/)
assert.match(convergence, /item\.actionType === 'BATCH'/)
})
test('customs provisions released booking and completed truck for the selected loading container', () => {
const value = source('./phase3-customs.mjs')
assertOrder(value, [
@@ -138,3 +149,53 @@ test('downstream producers prefer the phase3Loading container fixture', () => {
assert.match(serviceCenter, /context\.createdResources\?\.phase3Loading\s*\|\|\s*context\.createdResources\?\.phase3ContainerLoading/)
assert.match(ocean, /await action\('放舱', 'release'/)
})
test('default acceptance order verifies loading evidence before finalizing LOADED', () => {
const entry = source('../admin-test-env-acceptance.mjs')
assertOrder(entry, [
"'phase3-loading'",
"'phase3-loading-model-bridge'",
"'phase3-pda-convergence'",
"'phase3-evidence-gate'",
"'phase3-customs'",
"'phase3-loading-finalize'",
])
})
test('phase3 loading provisions its own marker-isolated WAIT_SPLIT fixture', async () => {
const run = new AcceptanceRun({ gateway: 'http://127.0.0.1', modules: [], username: '', password: '', output: '' })
const entry = source('../admin-test-env-acceptance.mjs')
assert.match(entry, /module === 'phase3-loading'/)
assert.match(entry, /preparePhase3LoadingFixture\(\)/)
assert.match(entry, /orders-phase3-loading-fixture/)
assert.match(entry, /inbound-measurement-phase3-loading-fixture/)
assert.match(entry, /marker: originalMarker/)
assert.match(entry, /sourceMarker: fixtureMarker/)
assert.match(entry, /phase3Loading: loadingFixture,\s*\n\s*inboundMeasurement: loadingFixture/)
assert.equal(run.marker.includes('-LOAD'), false)
})
test('customs and finalize consume the same loading inbound identity', () => {
const loadingFixture = { marker: 'RUN-1', tenantId: 10001, orderId: 101, inboundId: 201 }
const loading = {
marker: 'RUN-1', tenantId: 10001, inboundId: 201,
containerBookingId: 301, loadingPlanId: 401, finalStatus: 'COMPLETED',
}
const selected = selectCustomsFlow({
orchestrationFixtures: {
phase3Loading: loadingFixture,
inboundMeasurement: loadingFixture,
},
phase3Loading: loading,
})
assert.equal(selected.fixture.marker, loading.marker)
assert.equal(selected.fixture.inboundId, loading.inboundId)
assert.equal(selected.container.inboundId, loading.inboundId)
const finalized = buildFinalizeResource(loading, {
summary: { processStatus: 'LOADED', version: 6 },
}, { http: 200, body: { code: '200' } })
assert.equal(finalized.marker, loading.marker)
assert.equal(finalized.inboundId, loading.inboundId)
assert.equal(finalized.finalStatus, 'LOADED')
})