165 lines
7.6 KiB
JavaScript
165 lines
7.6 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import test from 'node:test'
|
|
import { attachDeliveredOrderFixture, missingRequiredStateFixtures, normalizeStateRequirements } from './manual-state-matrix.mjs'
|
|
import { normalizeModuleOrder, parseArguments } from '../admin-test-env-acceptance.mjs'
|
|
|
|
const entry = readFileSync(new URL('../admin-test-env-acceptance.mjs', import.meta.url), 'utf8')
|
|
const source = readFileSync(new URL('./manual-state-matrix.mjs', import.meta.url), 'utf8')
|
|
const loadingSource = readFileSync(new URL('./manual-state-loading-pda.mjs', import.meta.url), 'utf8')
|
|
|
|
test('DELIVERED 必须回查本轮已签收但根未完成的正式订单', async () => {
|
|
const matrix = { pages: { unifiedOrders: { fixtures: {} } } }
|
|
const context = { marker: 'run-1', createdResources: { phase5OverseasFulfillment: { marker: 'run-1',
|
|
orderCompletionProof: { customerId: '7', rootOrderId: '99', rootDelivered: true, expectedCompleted: false } } },
|
|
request: async (method, path) => {
|
|
assert.equal(method, 'GET')
|
|
assert.equal(path, '/api/platform/v1/orders/99?tenantId=7')
|
|
return { body: { data: { summary: { orderId: '99', mainStatus: 'DELIVERED' } } } }
|
|
}, apiSuccess: (_m, _n, response) => response.body.data,
|
|
assert: (_m, _n, _r, valid) => assert.equal(valid, true) }
|
|
await attachDeliveredOrderFixture(context, matrix)
|
|
assert.equal(matrix.pages.unifiedOrders.fixtures.DELIVERED.id, '99')
|
|
context.createdResources.phase5OverseasFulfillment.marker = 'old'
|
|
await assert.rejects(attachDeliveredOrderFixture(context, matrix), /本轮/)
|
|
})
|
|
|
|
test('default full acceptance includes the retained manual state matrix after lifecycle modules', () => {
|
|
assert.match(entry, /'manual-state-matrix'/)
|
|
assert.ok(entry.indexOf("'phase3-order-splitting'") < entry.indexOf("'manual-state-matrix'"))
|
|
assert.ok(entry.indexOf("'manual-state-matrix'") < entry.indexOf("'finance-full-fixtures'"))
|
|
})
|
|
|
|
test('focused matrix execution injects real container lifecycle prerequisites and removes its internal group', () => {
|
|
const expected = [
|
|
'merchant-qualification-fixture',
|
|
'orders',
|
|
'inbound-measurement',
|
|
'phase3-container-loading',
|
|
'phase3-loading',
|
|
'ocean-bookings',
|
|
'phase3-pda-convergence',
|
|
'phase3-evidence-gate',
|
|
'phase3-loading-finalize',
|
|
'phase3-customs',
|
|
'phase3-port-schedules',
|
|
'truck-appointments',
|
|
'service-center-flow',
|
|
'phase3-outbound-dispatch',
|
|
'phase3-container-documents',
|
|
'phase3-carrier-schedule-queries',
|
|
'phase4-carrier-pickup-ready',
|
|
'phase4-tail-order-controls',
|
|
'phase4-overseas-pda',
|
|
'phase4-overseas-pda-operations',
|
|
'phase4-overseas-client-services',
|
|
'phase4-overseas-dispatch',
|
|
'phase4-overseas-business',
|
|
'phase5-overseas-fulfillment',
|
|
'manual-state-matrix',
|
|
]
|
|
assert.deepEqual(normalizeModuleOrder(['order-inbound-status-fixtures', 'manual-state-matrix']), expected)
|
|
assert.deepEqual(parseArguments([
|
|
'--modules', 'order-inbound-status-fixtures,manual-state-matrix',
|
|
]).modules, expected)
|
|
})
|
|
|
|
test('focused splitting and manual groups resolve producers before consumers without duplicate internal runs', () => {
|
|
const expected = [
|
|
'merchant-qualification-fixture',
|
|
'orders',
|
|
'inbound-measurement',
|
|
'phase3-container-loading',
|
|
'phase3-loading',
|
|
'ocean-bookings',
|
|
'phase3-pda-convergence',
|
|
'phase3-evidence-gate',
|
|
'phase3-loading-finalize',
|
|
'phase3-order-splitting',
|
|
'phase3-customs',
|
|
'phase3-port-schedules',
|
|
'truck-appointments',
|
|
'service-center-flow',
|
|
'phase3-outbound-dispatch',
|
|
'phase3-container-documents',
|
|
'phase3-carrier-schedule-queries',
|
|
'phase4-carrier-pickup-ready',
|
|
'phase4-tail-order-controls',
|
|
'phase4-overseas-pda',
|
|
'phase4-overseas-pda-operations',
|
|
'phase4-overseas-client-services',
|
|
'phase4-overseas-dispatch',
|
|
'phase4-overseas-business',
|
|
'phase5-overseas-fulfillment',
|
|
'manual-state-matrix',
|
|
]
|
|
assert.deepEqual(normalizeModuleOrder([
|
|
'phase3-order-splitting', 'manual-state-loading-pda', 'manual-state-matrix',
|
|
]), expected)
|
|
})
|
|
|
|
test('matrix delegates bounded groups and asserts every declared status has a retained id', () => {
|
|
for (const group of ['order-inbound-status-fixtures', 'manual-state-loading-pda',
|
|
'manual-state-ocean-trucking']) assert.match(source, new RegExp(group))
|
|
assert.doesNotMatch(source, /manual-state-customs-dispatch/)
|
|
assert.match(source, /createdResources\.manualStateMatrix/)
|
|
assert.match(source, /supportedStatuses/)
|
|
assert.match(source, /requiredStatuses/)
|
|
assert.match(source, /fixtures\?\.\[status\]\?\.id/)
|
|
assert.match(source, /requiredActions/)
|
|
assert.match(source, /actions\?\.\[action\]\?\.documentId/)
|
|
assert.match(source, /actions\?\.\[action\]\?\.completedAt/)
|
|
})
|
|
|
|
test('fixture-unavailable statuses stay supported without becoming hard requirements', () => {
|
|
const matrix = { pages: {
|
|
inbounds: { requiredStatuses: ['WAIT_MEASURE', 'MEASURE_REJECTED', 'WAIT_PRICING', 'FEE_CONFIRMING', 'INBOUNDING', 'VOIDED'], fixtures: {
|
|
WAIT_MEASURE: { id: '1' },
|
|
FEE_CONFIRMING: { id: '5' },
|
|
WAIT_PRICING: { id: '6' },
|
|
} },
|
|
unifiedOrders: { requiredStatuses: ['WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED'], fixtures: {
|
|
WAIT_SPLIT: { id: '2' }, LOADING: { id: '3' }, LOADED: { id: '4' },
|
|
} },
|
|
} }
|
|
|
|
normalizeStateRequirements(matrix)
|
|
|
|
assert.deepEqual(matrix.pages.inbounds.supportedStatuses,
|
|
['WAIT_MEASURE', 'MEASURE_REJECTED', 'WAIT_PRICING', 'FEE_CONFIRMING', 'INBOUNDING', 'VOIDED'])
|
|
assert.deepEqual(matrix.pages.inbounds.requiredStatuses, ['WAIT_MEASURE', 'WAIT_PRICING', 'FEE_CONFIRMING'])
|
|
assert.equal(matrix.pages.inbounds.coverageGaps.FEE_CONFIRMING, undefined)
|
|
assert.deepEqual(matrix.pages.unifiedOrders.requiredStatuses, ['WAIT_SPLIT', 'LOADING', 'LOADED', 'DELIVERED'])
|
|
assert.equal(matrix.pages.inbounds.coverageGaps.WAIT_PRICING, undefined)
|
|
assert.equal(matrix.pages.inbounds.coverageGaps.INBOUNDING.category, 'fixture-unavailable')
|
|
assert.equal(matrix.pages.unifiedOrders.coverageGaps, undefined)
|
|
assert.deepEqual(missingRequiredStateFixtures(matrix), ['unifiedOrders:DELIVERED'])
|
|
assert.match(source, /gap\.category, \{ marker: context\.marker, page, status, blocking: false \}/)
|
|
})
|
|
|
|
test('unknown missing status is never swallowed by the known coverage-gap allowlist', () => {
|
|
const matrix = { pages: {
|
|
unifiedOrders: { supportedStatuses: ['WAIT_SPLIT', 'UNKNOWN_FUTURE_STATUS'], requiredStatuses: [], fixtures: {
|
|
WAIT_SPLIT: { id: '1' },
|
|
} },
|
|
} }
|
|
|
|
normalizeStateRequirements(matrix)
|
|
|
|
assert.deepEqual(matrix.pages.unifiedOrders.requiredStatuses, ['WAIT_SPLIT', 'UNKNOWN_FUTURE_STATUS'])
|
|
assert.deepEqual(missingRequiredStateFixtures(matrix), ['unifiedOrders:UNKNOWN_FUTURE_STATUS'])
|
|
})
|
|
|
|
test('LOADING and LOADED fixtures are resolved through inbound and unified-order details', () => {
|
|
assert.match(loadingSource, /matrix\.pages\.unifiedOrders\.fixtures\.LOADING/)
|
|
assert.match(loadingSource, /loadingOrder\?\.summary\?\.mainStatus === 'LOADING'/)
|
|
assert.match(source, /attachUnifiedOrderFixture\(context, matrix, 'phase3Loading', 'LOADED'\)/)
|
|
assert.match(source, /\/api\/platform\/inbounds\/\$\{encodeURIComponent\(inboundId\)\}/)
|
|
assert.match(source, /id\(inbound\?\.summary\?\.id\) === inboundId/)
|
|
assert.match(source, /inbound\?\.summary\?\.processStatus === expectedStatus/)
|
|
assert.match(source, /\/api\/platform\/v1\/orders\/\$\{encodeURIComponent\(orderId\)\}/)
|
|
assert.match(source, /unified\?\.summary\?\.mainStatus === expectedStatus/)
|
|
assert.match(source, /matrix\.pages\.unifiedOrders\.fixtures\[expectedStatus\]/)
|
|
assert.doesNotMatch(source, /clearResolvedProvisionalGap/)
|
|
})
|