Files
baiyue-firstleg/scripts/admin-test-env-modules/ocean-booking-fixture-contract.test.mjs
T
2026-09-15 10:37:34 +08:00

94 lines
5.8 KiB
JavaScript

import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import { oceanBookingDraft, oceanBookingDraftWithoutCustomer, publishPlatformLogisticsChannels, resolveOceanBookingAgent, resolveOceanBookingMaster } from './ocean-booking-fixture.mjs'
const read = (name) => readFileSync(new URL(name, import.meta.url), 'utf8')
const master = { customerId: '21', customerName: 'IT 测试客户', channelCode: 'SEA-US', channelName: '美西海运', warehouseId: '41', warehouseName: '深圳仓' }
test('fixture resolves current-marker customer channel and warehouse without inventing data', async () => {
const steps = []
const context = { marker: 'ADMIN-RUN-1', createdResources: { orchestrationFixtures: { phase3Container: { marker: 'ADMIN-RUN-1', tenantId: '21', inboundId: '31' } } },
request: async () => ({ body: { code: '200', data: { summary: { tenantId: 21, customerName: master.customerName, channelCode: master.channelCode, channelName: master.channelName, warehouseId: 41, warehouseName: master.warehouseName } } } }),
addStep: (...args) => steps.push(args) }
assert.deepEqual(await resolveOceanBookingMaster(context, 'test'), master)
assert.equal(steps.length, 0)
const blocked = { marker: 'ADMIN-RUN-2', createdResources: {}, addStep: (...args) => steps.push(args) }
assert.equal(await resolveOceanBookingMaster(blocked, 'test'), null)
assert.match(steps.at(-1)[4], /missing=customerId,customerName,channelCode,channelName,warehouseId,warehouseName/)
})
test('shared DRAFT uses requirements and never registers a real container number', () => {
const draft = oceanBookingDraft({ marker: 'ADMIN-RUN-3' }, '3', master)
assert.equal(draft.channelName, undefined)
assert.equal(draft.warehouseName, undefined)
assert.deepEqual(draft.containerRequirements, [{ containerType: '40HQ', containerKind: 'FCL', quantity: 1, capacityCbm: 68, maxWeightKg: 19500 }])
assert.equal(Object.hasOwn(draft, 'containers'), false)
assert.equal(JSON.stringify(draft).includes('containerNo'), false)
assert.equal('serviceTerm' in draft, false)
assert.equal('freightTerm' in draft, false)
assert.equal(draft.carrierCode, 'OTHER')
for (const field of ['billOfLadingNo', 'vesselName', 'voyageNo', 'estimatedSailingAt', 'estimatedArrivalAt']) assert.ok(draft[field])
})
test('shared DRAFT permits an omitted customer without inventing placeholders', () => {
const draft = oceanBookingDraftWithoutCustomer({ marker: 'ADMIN-RUN-OPTIONAL' }, 'optional', master)
assert.equal(Object.hasOwn(draft, 'customerId'), false)
assert.equal(Object.hasOwn(draft, 'customerName'), false)
assert.equal(draft.containerRequirements[0].quantity, 1)
})
test('explicit requirement rows preserve quantity and fixed catalog facts', () => {
const requirements = [
{ containerType: '40HQ', containerKind: 'FCL', quantity: 2, capacityCbm: 68, maxWeightKg: 19500 },
{ containerType: '40GP', containerKind: 'FCL', quantity: 1, capacityCbm: 58, maxWeightKg: 19500 },
]
const draft = oceanBookingDraft({ marker: 'ADMIN-RUN-MULTI' }, 'multi', master, { containerRequirements: requirements })
assert.deepEqual(draft.containerRequirements, requirements)
assert.equal(JSON.stringify(draft).includes('containerNo'), false)
})
test('supplier names are emitted only with formal supplier ids', () => {
const draft = oceanBookingDraft({ marker: 'ADMIN-RUN-SUPPLIER' }, 'supplier', master,
{ shippingCompanyName: '无来源船公司', bookingAgentName: '无来源代理' })
assert.equal(draft.shippingCompanyName, null)
assert.equal(draft.bookingAgentName, null)
})
test('platform channel producer uses the selected origin warehouse and publishes current-marker resources', async () => {
const calls = []
const context = { marker: 'ADMIN-RUN-CHANNELS', createdResources: {}, request: async (method, path) => {
calls.push({ method, path }); return { body: { code: '200', data: [{ channelCode: 'SEA-A', channelName: '海运 A' }] } }
}, apiSuccess: (_module, _name, response) => response.body.data,
assert: (_module, _name, _response, condition) => assert.equal(condition, true) }
const catalog = await publishPlatformLogisticsChannels(context, '41', 'test')
assert.deepEqual(calls, [{ method: 'GET', path: '/api/platform/v1/ocean-bookings/channels?originWarehouseId=41' }])
assert.equal(catalog.marker, context.marker)
assert.deepEqual(context.createdResources.platformLogisticsChannels, catalog)
})
test('booking agent fixture uses the carrier-filtered server candidates', async () => {
const calls = []
const context = { request: async (method, path) => {
calls.push({ method, path }); return { body: { code: '200', data: [{ supplierId: 81, name: 'MATSON 代理' }] } }
}, apiSuccess: (_module, _name, response) => response.body.data,
assert: (_module, _name, _response, condition) => assert.equal(condition, true) }
assert.deepEqual(await resolveOceanBookingAgent(context, 'test', 'matson'), { id: '81', name: 'MATSON 代理' })
assert.deepEqual(calls, [{ method: 'GET', path: '/api/platform/v1/ocean-bookings/booking-agents?carrierCode=MATSON' }])
})
test('all production booking fixtures use DRAFT release and the shared requirements contract', () => {
for (const name of ['ocean-bookings.mjs', 'phase3-loading.mjs', 'phase3-container-loading.mjs', 'phase3-order-splitting.mjs', 'manual-state-loading-pda.mjs', 'manual-state-ocean-trucking.mjs']) {
const source = read(name)
assert.doesNotMatch(source, /realContainerBookingId|ocean-bookings\/[^`'"\s]+\/(?:submit|confirm)/, name)
assert.match(source, /containerRequirements/, name)
}
})
test('manual PDA state fixture resolves an agent bound to the selected carrier', () => {
const source = read('manual-state-loading-pda.mjs')
assert.match(source, /resolveOceanBookingAgent\(context, MODULE, carrier\.carrierCode, OPTIONS\)/)
assert.doesNotMatch(source, /suppliers\?tenantId=0&category=BOOKING/)
})