Files
admin-web/src/modules/loading-lists/api/platformLoadingLists.test.ts
T

89 lines
4.6 KiB
TypeScript
Raw Normal View History

2026-08-10 15:36:53 +08:00
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { http } from '@/shared/api/http'
import {
getConfirmedLoadingList,
getPreloadPlan,
listConfirmedLoadingLists,
listPreloadPlans,
updatePreloadTransport,
} from './platformLoadingLists'
const preloadSummary = {
planId: 1900000000000000001n as unknown as string,
preloadNo: 'PL-001',
containerNo: 'MSCU1234567',
internalContainerNo: 'YG-001',
customers: [{ accountId: 1900000000000000002n as unknown as string, customerName: '测试客户' }],
warehouseId: 1900000000000000003n as unknown as string,
warehouseName: '义乌仓',
vesselName: 'MATSON',
voyageNo: '001E',
containerType: '40HC',
status: 'LOADING',
skuCount: '2',
totalPackageCount: '10',
totalVolumeCbm: 12.3,
totalGrossWeightKg: 1200,
createdAt: '2026-08-10T10:00:00',
version: 3,
}
const detail = {
summary: preloadSummary,
items: [{
itemId: 11, accountId: 12, inboundId: 13, inboundDetailId: 14, productQuantity: 20,
customerName: '测试客户', inboundCode: 'RK001', skuCode: 'SKU001', destinationWarehouse: 'ONT8', chineseName: '产品', englishName: null,
goodsImageUrl: null, packageCount: 2, palletCount: 1, grossWeightKg: 10, netWeightKg: 9, volumeCbm: 1,
dimensionalWeightKg: 2, unitsPerPackage: 10, fbaTrackingNo: null, shipmentNo: null, shippingMark: null,
internalRemark: null, customerRemark: null, warehouseRemark: null, loadSequence: 1, frozenAt: null,
}],
histories: [{ historyId: 21, itemId: 11, actionType: 'UPDATE_TRANSPORT', fromStatus: 'LOADING', toStatus: 'LOADING', beforeSnapshot: null, afterSnapshot: null, operatorId: 22, operatorName: '操作员', operationReason: '调整', occurredAt: '2026-08-10T11:00:00' }],
}
describe('platform loading lists API', () => {
beforeEach(() => vi.restoreAllMocks())
2026-08-10 17:42:17 +08:00
it('queries preload plans across all warehouses with fixed LOADING status', async () => {
2026-08-10 15:36:53 +08:00
const get = vi.spyOn(http, 'get').mockResolvedValue({ code: '200', message: 'ok', data: { records: [preloadSummary], page: '1', size: '20', total: '1', pages: '1' } })
2026-08-10 17:42:17 +08:00
const result = await listPreloadPlans({ page: 1, size: 20, keyword: 'PL' })
2026-08-10 15:36:53 +08:00
2026-08-10 17:42:17 +08:00
expect(get).toHaveBeenCalledWith('/platform/v1/first-leg/loading-plans', { params: { page: 1, size: 20, keyword: 'PL', status: 'LOADING' } })
2026-08-10 15:36:53 +08:00
expect(result.total).toBe(1)
expect(result.records[0]?.planId).toBe('1900000000000000001')
expect(result.records[0]?.customers[0]?.accountId).toBe('1900000000000000002')
})
it('normalizes long ids in preload detail items and history', async () => {
vi.spyOn(http, 'get').mockResolvedValue({ code: '200', message: 'ok', data: detail })
const result = await getPreloadPlan('100', '300')
expect(result.items[0]).toMatchObject({ itemId: '11', accountId: '12', inboundId: '13', inboundDetailId: '14', productQuantity: '20' })
expect(result.histories[0]).toMatchObject({ historyId: '21', itemId: '11', operatorId: '22' })
})
it('updates transport with expectedVersion, warehouse and idempotency key', async () => {
const patch = vi.spyOn(http, 'patch').mockResolvedValue({ code: '200', message: 'ok', data: detail })
await updatePreloadTransport('100', '300', { containerNo: 'MSCU1234567', voyageNo: '001E', expectedVersion: 3, operationReason: '调整' })
expect(patch.mock.calls[0]?.[0]).toBe('/platform/v1/first-leg/loading-plans/100/transport')
expect(patch.mock.calls[0]?.[1]).toMatchObject({ expectedVersion: 3, voyageNo: '001E' })
expect(patch.mock.calls[0]?.[2]).toMatchObject({ params: { warehouseId: '300' }, headers: { 'Idempotency-Key': expect.any(String) } })
})
it('uses distinct completed list and detail endpoints', async () => {
const confirmed = { ...preloadSummary, loadingListNo: 'LL-001', totalNetWeightKg: 1100, totalQuantity: '20', remark: null, createdBy: 9, createdByName: '操作员', status: 'COMPLETED' }
const get = vi.spyOn(http, 'get')
.mockResolvedValueOnce({ code: '200', message: 'ok', data: { records: [confirmed], page: '1', size: '20', total: '1', pages: '1' } })
.mockResolvedValueOnce({ code: '200', message: 'ok', data: { ...detail, summary: confirmed } })
2026-08-10 17:42:17 +08:00
const page = await listConfirmedLoadingLists({ page: 1, size: 20 })
2026-08-10 15:36:53 +08:00
const loaded = await getConfirmedLoadingList('100', '300')
expect(get.mock.calls[0]?.[0]).toBe('/platform/v1/first-leg/loading-lists')
2026-08-10 17:42:17 +08:00
expect(get.mock.calls[0]?.[1]).toEqual({ params: { page: 1, size: 20 } })
2026-08-10 15:36:53 +08:00
expect(get.mock.calls[1]?.[0]).toBe('/platform/v1/first-leg/loading-lists/100')
expect(page.records[0]?.createdBy).toBe('9')
expect(loaded.summary.status).toBe('COMPLETED')
})
})