Files
baiyue-firstleg/scripts/admin-test-env-modules/phase3-loading-model-bridge-contract.test.mjs
T
2026-09-20 22:18:59 +08:00

51 lines
3.1 KiB
JavaScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { stableLinkSnapshot } from './phase3-loading-model-bridge.mjs'
const source = readFileSync(fileURLToPath(new URL('./phase3-loading-model-bridge.mjs', import.meta.url)), 'utf8')
const unifiedSql = readFileSync(fileURLToPath(new URL('../../deploy/sql/头程数据库统一增量-MySQL8.sql', import.meta.url)), 'utf8')
test('unified migration selects firstleg before creating the loading model bridge', () => {
assert.match(
unifiedSql,
/USE baiyue_firstleg;[\s\S]*?CREATE TABLE(?: IF NOT EXISTS)? fl_preload_loading_plan_link/,
)
})
test('unified baseline defines declaration ledger comments before final schema validation', () => {
const eventStart = unifiedSql.indexOf('CREATE TABLE fl_order_declaration_event')
const snapshotStart = unifiedSql.indexOf('CREATE TABLE fl_order_declaration_snapshot')
const eventTable = unifiedSql.slice(eventStart, snapshotStart)
const snapshotTable = unifiedSql.slice(snapshotStart, unifiedSql.indexOf('CREATE TABLE', snapshotStart + 20))
assert.match(eventTable, /COMMENT='Order客户申报事件永久幂等账本'/)
assert.match(snapshotTable, /COMMENT='Order客户申报版本快照/)
for (const column of ['tenant_id', 'event_id', 'order_id', 'order_version', 'request_hash', 'consumed_at']) {
assert.match(eventTable, new RegExp(`\\b${column}\\b[^\\n]*COMMENT '[^']*[一-龥][^']*'`))
}
for (const column of ['tenant_id', 'order_id', 'event_id', 'order_version', 'request_hash', 'customer_remark',
'expected_arrival_at', 'channel_code', 'channel_name', 'cargoes_json', 'changes_json', 'occurred_at', 'created_at', 'updated_at']) {
assert.match(snapshotTable, new RegExp(`\\b${column}\\b[^\\n]*COMMENT '[^']*[一-龥][^']*'`))
}
})
test('bridge acceptance treats an existing pair as a read-only idempotent replay', () => {
assert.match(source, /已由推送建立的同一桥接 pair 重放返回原关联/)
assert.match(source, /桥接 pair 重放不改关联身份、状态或双侧版本/)
assert.doesNotMatch(source, /桥接同幂等键不同版本请求拒绝且不产生部分更新/)
})
test('bridge replay comparison freezes stable identity status and both versions', () => {
const link = {
id: '1', tenantId: '10', inboundId: '20', preloadPlanId: '30', preloadStatus: 'PENDING',
preloadVersion: 3, loadingPlanId: '40', containerBookingId: '50', containerNo: null,
loadingPlanStatus: 'EDITING', loadingPlanVersion: 4, allocatedPackageCount: 8,
linkedAt: '2026-08-15T09:00:00', ignoredTransportField: 'not-part-of-the-link-contract',
}
assert.deepEqual(stableLinkSnapshot({ ...link, ignoredTransportField: 'changed' }), stableLinkSnapshot(link))
assert.notDeepEqual(stableLinkSnapshot({ ...link, loadingPlanVersion: 5 }), stableLinkSnapshot(link))
assert.notDeepEqual(stableLinkSnapshot({ ...link, preloadVersion: 4 }), stableLinkSnapshot(link))
assert.notDeepEqual(stableLinkSnapshot({ ...link, allocatedPackageCount: 7 }), stableLinkSnapshot(link))
})