Files
baiyue-firstleg/scripts/fleet-booking-quotes-test-env-contract.test.mjs

52 lines
4.8 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { warehouseQuoteContext, verifyBookingQuotes } from './fleet-booking-quotes-test-env.mjs'
test('warehouse date uses authoritative timezone and rejects ambiguous or customer-owned warehouse', () => {
const detail = { warehouse: { id: '92', tenantId: '0', status: 'ACTIVE', warehouseType: 'OVERSEAS', timezone: 'America/Los_Angeles' }, addresses: [{ warehouseId: '92', tenantId: '0', city: 'LA' }] }
assert.equal(warehouseQuoteContext(detail, '2026-10-04T01:00:00Z').day, '2026-10-03')
assert.equal(warehouseQuoteContext({ ...detail, warehouse: { ...detail.warehouse, timezone: 'UTC-8' } }, '2026-10-04T01:00:00Z').day, '2026-10-03')
assert.throws(() => warehouseQuoteContext({ ...detail, warehouse: { ...detail.warehouse, tenantId: '1' } }, '2026-10-04T01:00:00Z'))
assert.throws(() => warehouseQuoteContext({ ...detail, addresses: [...detail.addresses, { ...detail.addresses[0], city: 'SF' }] }, '2026-10-04T01:00:00Z'))
})
function harness(fault) {
const quotes = [], bookings = [], replay = new Map(), calls = []
let trip = { tripNo: 'TR-OWN', recordVersion: 0 }, expired = false
const context = { marker: 'TEST-CURRENT', createdResources: { merchantQualificationFixture: { marker: 'TEST-CURRENT', tenantId: '9' } }, async request(method, path, body) {
calls.push({ method, path, body: structuredClone(body) }); const url = new URL(path, 'http://offline.invalid'), p = url.pathname
const response = (data, code = '200') => ({ http: 200, body: { code, data: structuredClone(data) }, requestId: 'request', traceId: 'trace' })
if (p.endsWith('/quote-candidates')) {
const basis = url.searchParams.get('priceBasis'), currency = url.searchParams.get('currency')
return response({ records: quotes.filter(q => !expired && q.details.validFrom === '2026-10-04' && q.details.currency === currency && q.details[basis === 'PALLET' ? 'looseDeliveryPrice' : 'fullDeliveryPrice'] != null).map(q => ({ quoteNo: q.quoteNo, recordVersion: q.recordVersion, quotedUnitPrice: q.details[basis === 'PALLET' ? 'looseDeliveryPrice' : 'fullDeliveryPrice'], priceItem: basis === 'PALLET' ? 'LOOSE_DELIVERY' : 'FULL_DELIVERY', effectiveOn: '2026-10-04' })) })
}
if (p.endsWith('/quotes') && method === 'POST') { const q = { quoteNo: `FQ-${quotes.length}`, recordVersion: 0, details: body.details }; quotes.push(q); return response(q) }
if (p.includes('/quotes/FQ-')) { const q = quotes.find(q => p.endsWith(q.quoteNo)); q.details = body.details; q.recordVersion++; return response(q) }
if (p.endsWith('/trips') && method === 'POST') return response({ trip })
if (p.endsWith('/plan')) { expired = true; trip.recordVersion++; return response({ trip }) }
if (p.endsWith('/confirm')) return response(null, fault === 'accepts-stale' ? '200' : 'A0409')
if (p.endsWith('/bookings') && method === 'GET') return response({ tripRecordVersion: trip.recordVersion, records: bookings })
if (p.endsWith('/bookings') && replay.has(body.idempotencyKey)) return response({ ...replay.get(body.idempotencyKey), replayed: true })
const q = body.quoteRef ? quotes.find(q => q.quoteNo === body.quoteRef.quoteNo) : null
if (q && q.recordVersion !== body.quoteRef.recordVersion) return response(null, 'A0409')
let b
if (method === 'POST') { b = { bookingNo: `FB-${bookings.length}`, status: 'DRAFT', recordVersion: 0 }; bookings.push(b) }
else { b = bookings.find(b => p.endsWith(b.bookingNo)); b.recordVersion++ }
Object.assign(b, { cargo: body.cargo, agreedAmount: body.cargo.unitPrice * body.cargo.palletSpaces, quoteSource: q ? { quoteNo: q.quoteNo, recordVersion: q.recordVersion, quotedUnitPrice: q.details.looseDeliveryPrice } : null })
trip.recordVersion++
const result = { tripRecordVersion: trip.recordVersion, booking: b, replayed: false }
if (method === 'POST') replay.set(body.idempotencyKey, structuredClone(result))
return response(result)
} }
return { context, calls }
}
test('independent draft fixture covers source version, date, currency, manual pricing without inventory or departure writes', async () => {
const h = harness(), proof = await verifyBookingQuotes(h.context, { warehouseId: '92', originCity: 'la', day: '2026-10-04' }, '2026-10-04T12:00:00Z')
assert.equal(proof.status, 'VERIFIED_DRAFT_SOURCE_LINKAGE'); assert.ok(proof.checks.every(c => c.passed))
assert.ok(h.calls.every(c => !/inventory|\/depart$|\/assignment$|\/receipt-confirmation$/.test(c.path)))
await assert.rejects(verifyBookingQuotes(h.context, {}, ''), /no restart/)
})
test('unexpected acceptance of stale confirmation cannot be reported as successful', async () => {
const h = harness('accepts-stale')
await assert.rejects(verifyBookingQuotes(h.context, { warehouseId: '92', originCity: 'la', day: '2026-10-04' }, '2026-10-04T12:00:00Z'), /A0409/)
})