import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' import { inspectOceanBookingIdentity, truckAppointmentPayload } from './truck-appointments.mjs' test('truck appointment accepts only the current marker ocean booking identity', () => { const current = inspectOceanBookingIdentity('RUN-2', { id: '91', marker: 'RUN-2', customerId: '21', warehouseId: '41', customerName: '本轮客户', }) assert.deepEqual(current.identity, { oceanBookingId: '91', customerId: '21', warehouseId: '41', customerName: '本轮客户', }) const stale = inspectOceanBookingIdentity('RUN-2', { id: '90', marker: 'RUN-1', customerId: '20', warehouseId: '40', customerName: '历史客户', }) assert.equal(stale.identity, null) assert.match(stale.reason, /marker 不属于本轮/) }) test('truck appointment fills missing identity only from the current booking detail', () => { const partial = { id: '91', marker: 'RUN-2', customerId: '21' } const beforeDetail = inspectOceanBookingIdentity('RUN-2', partial) assert.equal(beforeDetail.identity, null) assert.deepEqual(beforeDetail.missingFields, ['warehouseId', 'customerName']) const resolved = inspectOceanBookingIdentity('RUN-2', partial, { oceanBooking: { id: 91, customerId: 21, warehouseId: 41, customerName: '本轮客户', } }) assert.deepEqual(resolved.identity, { oceanBookingId: '91', customerId: '21', warehouseId: '41', customerName: '本轮客户', }) }) test('truck appointment rejects mismatched booking detail instead of mixing identities', () => { const wrongResource = inspectOceanBookingIdentity('RUN-2', { id: '91', marker: 'RUN-2' }, { oceanBooking: { id: '92', customerId: '21', warehouseId: '41', customerName: '其他订舱' }, }) assert.equal(wrongResource.identity, null) assert.match(wrongResource.reason, /资源归属不一致/) const conflictingCustomer = inspectOceanBookingIdentity('RUN-2', { id: '91', marker: 'RUN-2', customerId: '21', }, { oceanBooking: { id: '91', customerId: '22', warehouseId: '41', customerName: '本轮客户' } }) assert.equal(conflictingCustomer.identity, null) assert.match(conflictingCustomer.reason, /customerId/) }) test('create edit and stale replay payloads keep the resolved booking identity stable', () => { const context = { marker: 'RUN-2' } const identity = { oceanBookingId: '91', customerId: '21', warehouseId: '41', customerName: '本轮客户' } const payloads = [ truckAppointmentPayload(context, '2', identity), truckAppointmentPayload(context, '2', identity, 3), truckAppointmentPayload(context, '2', identity, 0), ] for (const payload of payloads) { assert.deepEqual({ oceanBookingId: payload.oceanBookingId, customerId: payload.customerId, warehouseId: payload.warehouseId, customerName: payload.customerName, }, identity) } assert.deepEqual(payloads.map((payload) => payload.expectedVersion), [0, 3, 0]) }) test('truck appointment source has no historical list or hardcoded identity fallback', () => { const source = readFileSync(new URL('truck-appointments.mjs', import.meta.url), 'utf8') assert.doesNotMatch(source, /customerId:\s*['"]10001['"]|warehouseId:\s*['"]193000000000000001['"]/) assert.match(source, /\/api\/platform\/v1\/ocean-bookings/) assert.match(source, /未使用历史订舱或硬编码客户\/仓库/) })