Files
client-web/src/utils/firstLegOrder.test.mjs
T
2026-07-31 15:34:22 +08:00

120 lines
4.5 KiB
JavaScript

import assert from 'node:assert/strict'
import test from 'node:test'
import { createFirstLegPartySnapshot } from '../data/firstLegParties.ts'
import {
canClientCancelFirstLegOrder,
canClientEditFirstLegOrder,
createEmptyCargoItem,
getFirstLegStatusLabel,
getFirstLegTransportModeLabel,
summarizeFirstLegCargo,
validateFirstLegOrderDraft,
} from './firstLegOrder.ts'
const shipperParty = {
id: 'CP001', code: 'SHIPPER-001', name: '测试发货企业', roles: ['SHIPPER'], contactName: '测试联系人',
phone: '13800000000', email: 'shipper@example.test', countryRegion: '中国', province: '浙江省', city: '宁波市',
postalCode: '315000', address: '测试发货地址', status: 'ACTIVE',
}
const consigneeParty = {
id: 'CP002', code: 'CONSIGNEE-001', name: 'TEST CONSIGNEE LLC', roles: ['CONSIGNEE'], contactName: 'Test Receiver',
phone: '+1 555 0100', email: 'receiver@example.test', countryRegion: '美国', province: 'California', city: 'Los Angeles',
postalCode: '90001', address: '100 Test Logistics Ave', status: 'ACTIVE',
}
function validDraft() {
return {
referenceNo: 'REF-001',
transportMode: 'FCL',
businessType: 'EXPORT',
origin: '宁波',
destination: '洛杉矶',
receivingWarehouseId: 'WH005',
expectedDepartureDate: '2026-08-08',
shipperPartyId: 'CP001',
shipperPartySnapshot: createFirstLegPartySnapshot(shipperParty, 'SHIPPER'),
shipper: shipperParty.name,
consigneePartyId: 'CP003',
consigneePartySnapshot: createFirstLegPartySnapshot(consigneeParty, 'CONSIGNEE'),
consignee: consigneeParty.name,
priority: 'NORMAL',
customerRemark: '',
tradeTerm: 'FOB',
destinationCountryCode: 'US',
destinationWarehouseName: 'ONT8',
pickupMethod: 'SELF_EXPRESS',
channelCode: 'SEA-US-FBA',
channelName: '美国海运渠道',
taxMode: 'BUY_DECLARATION',
customsInspection: false,
destinationType: 'FBA',
amazonWarehouseCode: 'ONT8',
shipmentId: 'FBA-001',
items: [{ ...createEmptyCargoItem('cargo-1'), cargoNameCn: '家居用品', pieces: 100, grossWeightKg: 1200, volumeCbm: 3.5, containerType: '40HQ', containerCount: 1 }],
}
}
test('uses the confirmed status and transport labels', () => {
assert.equal(getFirstLegStatusLabel('BOOKED'), '已订舱')
assert.equal(getFirstLegStatusLabel('IN_TRANSIT'), '运输中')
assert.equal(getFirstLegTransportModeLabel('FCL'), '海运整箱 FCL')
})
test('only allows draft orders to be edited in the confirmed phase-one flow', () => {
assert.equal(canClientEditFirstLegOrder('DRAFT'), true)
assert.equal(canClientEditFirstLegOrder('PENDING_REVIEW'), false)
assert.equal(canClientCancelFirstLegOrder('DRAFT'), true)
assert.equal(canClientCancelFirstLegOrder('PENDING_REVIEW'), true)
assert.equal(canClientCancelFirstLegOrder('ACCEPTED'), false)
assert.equal(canClientCancelFirstLegOrder('BOOKED'), false)
})
test('validates the confirmed minimum submission fields', () => {
assert.deepEqual(validateFirstLegOrderDraft(validDraft()), [])
const invalid = validDraft()
invalid.origin = ''
invalid.receivingWarehouseId = ''
invalid.items[0].grossWeightKg = 0
invalid.items[0].containerType = ''
invalid.items[0].containerCount = 0
const errors = validateFirstLegOrderDraft(invalid)
assert.ok(errors.includes('请填写起运地'))
assert.ok(errors.includes('请选择平台收货仓'))
assert.ok(errors.includes('第 1 条货物毛重必须大于 0'))
assert.ok(errors.includes('第 1 条货物需要填写箱型和柜量'))
})
test('requires enabled-party snapshots and order addresses before submission', () => {
const draft = validDraft()
draft.shipperPartyId = ''
draft.shipperPartySnapshot = null
draft.consigneePartySnapshot.address = ''
const errors = validateFirstLegOrderDraft(draft)
assert.ok(errors.includes('请选择发货单位'))
assert.ok(errors.includes('请填写本单收货地址'))
})
test('does not require container details for non-FCL cargo', () => {
const draft = validDraft()
draft.transportMode = 'AIR'
draft.items[0].containerType = ''
draft.items[0].containerCount = 0
assert.deepEqual(validateFirstLegOrderDraft(draft), [])
})
test('summarizes cargo values from line items', () => {
const first = validDraft().items[0]
const second = { ...first, id: 'cargo-2', pieces: 40, packageCount: 4, grossWeightKg: 300, volumeCbm: 1.25 }
assert.deepEqual(summarizeFirstLegCargo([first, second]), {
pieces: 140,
packageCount: 5,
grossWeightKg: 1500,
volumeCbm: 4.75,
})
})