import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' import { 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') 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', 'phase3-container-loading', 'phase3-loading', 'ocean-bookings', 'phase3-customs', 'phase3-loading-finalize', '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', 'phase3-container-loading', 'phase3-loading', 'phase3-order-splitting', 'ocean-bookings', 'phase3-customs', 'phase3-loading-finalize', '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', 'WAIT_PRICING', 'FEE_CONFIRMING', 'INBOUNDING', 'VOIDED'], fixtures: { WAIT_MEASURE: { id: '1' }, } }, 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', 'WAIT_PRICING', 'FEE_CONFIRMING', 'INBOUNDING', 'VOIDED']) assert.deepEqual(matrix.pages.inbounds.requiredStatuses, ['WAIT_MEASURE']) assert.deepEqual(matrix.pages.unifiedOrders.requiredStatuses, ['WAIT_SPLIT', 'LOADING', 'LOADED']) assert.equal(matrix.pages.inbounds.coverageGaps.WAIT_PRICING.category, 'fixture-unavailable') assert.equal(matrix.pages.unifiedOrders.coverageGaps.DELIVERED.category, 'fixture-unavailable') assert.deepEqual(missingRequiredStateFixtures(matrix), []) }) 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(source, /attachUnifiedOrderFixture\(context, matrix, 'phase3ContainerLoading', '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.match(source, /clearResolvedProvisionalGap\(context, expectedStatus\)/) assert.match(source, /gap\?\.name === `统一订单列表保留 \$\{status\}`/) })