Files
baiyue-firstleg/scripts/fleet-capacity-pool-ui-fixture-gray.test.mjs
T
2026-10-27 17:44:41 +08:00

91 lines
6.3 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { join } from 'node:path'
import { parseGrayUiFixtureArguments } from './fleet-capacity-pool-ui-fixture-gray.mjs'
import { PRIVATE_DIRECTORY, runGrayUiFixture, runUiFixture, uiActorPermissions, grayUiSchedule,
applyGrayUiTransportWindow, uiInquiryBody } from './fleet-capacity-pool-ui-fixture-test-env.mjs'
const args = ['--execute', '--environment', 'GRAY', '--run-id', 'ui-gray-offline', '--warehouse-id', '900',
'--destination-warehouse-id', '901', '--private-credentials-file', join(PRIVATE_DIRECTORY, 'ui-gray-offline.json')]
const env = { CHONGCHONG_ENV: 'prod', CHONGCHONG_ADMIN_API_BASE_URL: 'https://gray.example.invalid/api',
CHONGCHONG_ADMIN_USERNAME: 'offline', CHONGCHONG_ADMIN_PASSWORD: 'offline-only',
CHONGCHONG_ACCEPTANCE_CUSTOMER_ID: '100', CHONGCHONG_MERCHANT_USERNAME: 'existing-a', CHONGCHONG_MERCHANT_PASSWORD: 'offline-a',
CHONGCHONG_ACCEPTANCE_SECONDARY_CUSTOMER_ID: '101', CHONGCHONG_SECONDARY_MERCHANT_USERNAME: 'existing-b', CHONGCHONG_SECONDARY_MERCHANT_PASSWORD: 'offline-b' }
test('GRAY UI default plan does not access network or private credential files and keeps only four drafts', async () => {
const original = globalThis.fetch; globalThis.fetch = () => assert.fail('no network')
try {
const plan = await runGrayUiFixture(parseGrayUiFixtureArguments([]), { env: {} })
assert.equal(plan.execute, false); assert.equal(plan.environment, 'GRAY'); assert.equal(plan.fullAcceptance, false)
assert.equal(plan.stopsAt, 'OPEN_AND_4_DRAFTS_READY_FOR_UI'); assert.equal(plan.retainedPda, true)
assert.equal(plan.output, 'reports/fleet-capacity-pool-ui-gray-plan')
assert.equal(plan.privateCredentialsFile, null)
assert.match(plan.boundary, /all six UI logins/)
} finally { globalThis.fetch = original }
})
test('GRAY UI CLI requires explicit scope and private exclusive file without arbitrary lifecycle switches', () => {
assert.equal(parseGrayUiFixtureArguments(args).environment, 'GRAY')
for (const bad of [args.slice(0, -2), args.map(value => value === 'GRAY' ? 'TEST' : value),
[...args, '--private-credentials-file', args.at(-1)], [...args, '--modules', 'orders'],
[...args, '--retain-pda', 'false'], [...args, '--draft-count', '24']]) assert.throws(() => parseGrayUiFixtureArguments(bad))
})
test('GRAY UI refuses TEST profile or evidence overrides and TEST runner rejects GRAY', async () => {
const config = parseGrayUiFixtureArguments(args)
await assert.rejects(runUiFixture(config, { env }), /TEST/)
await assert.rejects(runGrayUiFixture(config, { env: { ...env, CHONGCHONG_ENV: 'test' } }), /GRAY_FIXTURE_CONFIGURATION/)
for (const name of ['readers', 'prepare', 'contextFactory', 'pickerDisable']) {
await assert.rejects(runGrayUiFixture(config, { env, [name]: {} }), /CANNOT_OVERRIDE/)
}
await assert.rejects(runGrayUiFixture(config, { env }), /Missing gray evidence configuration/)
await assert.rejects(runGrayUiFixture(config, { env: { ...env, CHONGCHONG_ADMIN_API_BASE_URL: 'http://gray.example.invalid/api' } }), /INVALID_UI_API_BASE/)
})
test('GRAY UI missing second fixed customer stops before context private files or network', async () => {
const original = globalThis.fetch; globalThis.fetch = () => assert.fail('no network')
try {
const missing = { ...env }; delete missing.CHONGCHONG_ACCEPTANCE_SECONDARY_CUSTOMER_ID
await assert.rejects(runGrayUiFixture(parseGrayUiFixtureArguments(args), { env: missing }), /第二个客户/)
} finally { globalThis.fetch = original }
})
test('only sales A receives quotation-read while dispatcher and sales B remain minimal', () => {
const prefix = 'platform:fleet:capacity-offer:'
const sales = ['list', 'inquiry-create', 'inquiry-edit', 'inquiry-cancel'].map(value => prefix + value)
assert.deepEqual(uiActorPermissions('SALES_A', true), [...sales, 'platform:fleet:quote:list'])
assert.deepEqual(uiActorPermissions('SALES_B', true), sales)
assert.deepEqual(uiActorPermissions('MANAGER', true), [prefix + 'manage'])
assert.deepEqual(uiActorPermissions('SALES_A', false), sales)
})
test('eight-hour cutoff has coherent later departure delivery and driver end without rewriting other requests', () => {
const now = Date.parse('2030-01-01T00:00:00Z'), schedule = grayUiSchedule(now)
assert.equal(Date.parse(schedule.cutoffAt), now + 8 * 3600000)
assert.equal(Date.parse(schedule.plannedDepartureAt), now + 9 * 3600000)
assert.equal(Date.parse(schedule.plannedDeliveryAt), now + 10 * 3600000)
assert.equal(Date.parse(schedule.expectedDriverEndAt), now + 12 * 3600000)
assert.deepEqual(grayUiSchedule(now + 999), schedule)
assert.match(schedule.cutoffAt, /Z$/); assert.match(schedule.plannedDepartureAt, /Z$/)
assert.doesNotMatch(schedule.plannedDeliveryAt, /Z$/)
const body = { idempotencyKey: 'stable', recordVersion: '9007199254740993' }
const applied = applyGrayUiTransportWindow('PUT', '/api/platform/v1/last-leg/dispatches/DS-1', body, schedule)
assert.equal(applied.estimatedArrivalAt, new Date(schedule.plannedDeliveryAt).toISOString())
assert.equal(applied.idempotencyKey, body.idempotencyKey); assert.equal(applied.recordVersion, body.recordVersion)
assert.equal(Object.hasOwn(body, 'estimatedArrivalAt'), false)
assert.throws(() => applyGrayUiTransportWindow('POST', '/api/platform/v1/last-leg/dispatches', body, null), /NATIVE_DELIVERY/)
assert.equal(applyGrayUiTransportWindow('POST', '/api/auth/login', body, schedule), body)
assert.equal(applyGrayUiTransportWindow('GET', '/api/platform/v1/last-leg/dispatches/DS-1', body, schedule), body)
assert.throws(() => grayUiSchedule(NaN), /CLOCK/)
})
test('four GRAY drafts are complete for both commercial types without creating reservations or commercial orders', () => {
const offer = { status: 'OPEN', canCreateInquiry: true, tripRecordVersion: 1, recordVersion: 2, destinations: [{ destinationKey: 'FBA:ONT8' }] }
const bodies = Array.from({ length: 4 }, (_, index) => uiInquiryBody(offer, index < 2 ? 'A' : 'B', index, `key-${index}`, true))
assert.deepEqual(bodies.map(body => body.businessType), ['LOCAL_LOOSEBOARD', 'US_TRUCK', 'LOCAL_LOOSEBOARD', 'US_TRUCK'])
for (const body of bodies) {
assert.equal(body.expectedPalletCount, 1); assert.equal(body.cargo.packageCount, 1); assert.equal(body.cargo.palletSpaces, 1)
assert.equal('businessOrderNo' in body, false); assert.equal('status' in body, false)
}
})