2026-08-11 18:06:35 +08:00
import { flushPromises , shallowMount } from '@vue/test-utils'
import { beforeEach , describe , expect , it , vi } from 'vitest'
2026-10-20 11:33:39 +08:00
import { getPlatformUnifiedOrderStatusCounts , listPlatformUnifiedOrders , updatePlatformUnifiedOrderPlanning } from '@/modules/unified-orders/api/unifiedOrders'
2026-09-01 21:09:39 +08:00
import { createPlatformExportTask } from '@/modules/downloads'
import { showExportTaskCreatedDialog } from '@/shared/components/exportTaskCreatedDialog'
2026-09-03 11:47:32 +08:00
import { ApiResponseError } from '@/shared/api/http'
2026-09-04 18:47:43 +08:00
import { ElMessage } from 'element-plus'
2026-08-11 18:06:35 +08:00
import UnifiedOrdersView from './UnifiedOrdersView.vue'
vi . mock ( 'vue-router' , () => ({
useRoute : () => ({ params : {}, query : {} }),
useRouter : () => ({ push : vi.fn () }),
}))
vi . mock ( '@/core/access/accessPreview' , () => ({ useAccessPreviewStore : () => ({ can : () => true }) }))
2026-10-20 23:34:11 +08:00
vi . mock ( '@/modules/iam' , async importOriginal => ({
... await importOriginal < typeof import ( '@/modules/iam' ) >(), listPlatformTenants : vi.fn (). mockResolvedValue ({ records : [], page : 1 , size : 200 , total : 0 , pages : 0 }) }))
2026-08-11 18:06:35 +08:00
vi . mock ( '@/modules/warehouses' , () => ({ listAllPlatformWarehouses : vi.fn (). mockResolvedValue ([]) }))
2026-10-20 23:49:47 +08:00
vi . mock ( '@/modules/inbounds' , async () => {
const { defineComponent } = await import ( 'vue' )
return {
2026-10-19 15:59:14 +08:00
downloadWeightImage : vi.fn (), getInboundMeasurement : vi.fn (),
2026-10-20 23:49:47 +08:00
InboundTaskList : defineComponent ({
2026-10-20 17:24:50 +08:00
name : 'InboundTaskList' , props : [ 'mode' , 'title' , 'taskLoader' ],
methods : { reload() { return this . taskLoader ({ page : 1 , size : 20 }) } },
mounted() { void this . reload () },
template : '<section><slot name="filters" :loading="false" /><slot name="status-tabs" /></section>' ,
2026-10-20 23:49:47 +08:00
}),
}
})
2026-09-01 21:09:39 +08:00
vi . mock ( '@/modules/downloads' , () => ({ createPlatformExportTask : vi.fn () }))
vi . mock ( '@/shared/components/exportTaskCreatedDialog' , () => ({ showExportTaskCreatedDialog : vi.fn () }))
2026-08-11 18:06:35 +08:00
vi . mock ( '@/modules/unified-orders/workflows' , () => ({ UnifiedOrderWorkflowPanel : { template : '<div />' } }))
2026-08-29 10:57:01 +08:00
vi . mock ( '@/modules/unified-orders/api/coLoadGroups' , () => ({
cancelPlatformCoLoadGroup : vi.fn (),
createPlatformCoLoadGroup : vi.fn (),
2026-08-31 10:48:23 +08:00
getPlatformCoLoadGroupByInboundCode : vi.fn (),
2026-08-29 10:57:01 +08:00
}))
2026-08-11 18:06:35 +08:00
vi . mock ( '@/modules/unified-orders/api/unifiedOrders' , () => ({
2026-09-14 16:56:11 +08:00
updatePlatformUnifiedOrderRemarks : vi.fn (),
2026-08-11 18:06:35 +08:00
approvePlatformUnifiedOrder : vi.fn (),
getPlatformUnifiedOrder : vi.fn (),
listPlatformUnifiedOrderFeeDetails : vi.fn (),
2026-10-20 11:33:39 +08:00
getPlatformUnifiedOrderStatusCounts : vi.fn (). mockResolvedValue ({ counts : {} }), listPlatformUnifiedOrders : vi.fn (),
2026-09-03 11:47:32 +08:00
updatePlatformUnifiedOrderPlanning : vi.fn (),
2026-08-11 18:06:35 +08:00
unifiedOrderStatusOptions : [
{ value : 'PENDING_REVIEW' , label : '待审核' },
{ value : 'WAIT_MEASURE' , label : '待测量数据' },
2026-10-20 17:24:50 +08:00
{ value : 'WAIT_SPLIT' , label : '待装柜' },
2026-08-11 18:06:35 +08:00
{ value : 'LOADING' , label : '装柜中' },
{ value : 'LOADED' , label : '装柜完成' },
2026-10-20 11:33:39 +08:00
{ value : 'DELIVERING' , label : '派送中' },
2026-10-20 21:33:46 +08:00
{ value : 'SIGNED' , label : '派送完成' },
2026-08-11 18:06:35 +08:00
],
}))
function emptyPage() {
return { records : [], page : 1 , size : 20 , total : 0 , pages : 0 }
}
function mountView() {
return shallowMount ( UnifiedOrdersView , {
global : {
directives : { loading : () => undefined },
stubs : {
AdminPage : { template : '<main><slot /></main>' },
2026-10-19 15:59:14 +08:00
InboundTaskList : false ,
2026-08-11 18:06:35 +08:00
ListPageLayout : { template : '<section><slot name="toolbar" /><slot name="state" /><slot /></section>' },
2026-10-28 12:01:43 +08:00
QueryToolbar : { name : 'QueryToolbar' , props : [ 'modelValue' , 'fields' , 'maxVisible' ], emits : [ 'update:modelValue' , 'search' , 'reset' ], template : '<div data-testid="query-toolbar"><slot name="actions" /></div>' },
2026-09-30 14:01:58 +08:00
DataTable : { name : 'DataTable' , props : [ 'page' , 'pageSize' , 'data' ], emits : [ 'update:page' , 'update:pageSize' , 'selection-change' ], template : '<div data-testid="data-table"><slot name="toolbar-start" /><slot name="toolbar-actions" /><slot name="filters" /><slot name="notices" /><div v-for="row in data" :key="row.orderId" class="test-row"><slot name="estimatedVolume" :row="row" /><slot name="expectedArrival" :row="row" /></div></div>' },
2026-08-11 18:06:35 +08:00
'el-button' : { template : '<button><slot /></button>' },
2026-09-03 11:47:32 +08:00
'el-input-number' : { name : 'ElInputNumber' , props : [ 'modelValue' , 'disabled' ], emits : [ 'update:modelValue' , 'change' ], template : '<input class="number-input" :value="modelValue" :disabled="disabled" @change="$emit(\'change\')" />' },
'el-date-picker' : { name : 'ElDatePicker' , props : [ 'modelValue' , 'disabled' ], emits : [ 'update:modelValue' , 'change' ], template : '<input class="date-input" :value="modelValue" :disabled="disabled" @change="$emit(\'change\')" />' },
ApiErrorMeta : { props : [ 'details' ], template : '<code class="api-meta">{{ details.code }} {{ details.requestId }} {{ details.traceId }}</code>' },
2026-08-11 18:06:35 +08:00
},
},
})
}
describe ( 'UnifiedOrdersView list request coordination' , () => {
beforeEach (() => {
2026-10-20 11:33:39 +08:00
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockReset (). mockResolvedValue ({ counts : {} })
2026-08-11 18:06:35 +08:00
vi . mocked ( listPlatformUnifiedOrders ). mockReset (). mockResolvedValue ( emptyPage ())
2026-09-03 11:47:32 +08:00
vi . mocked ( updatePlatformUnifiedOrderPlanning ). mockReset ()
2026-09-01 21:09:39 +08:00
vi . mocked ( createPlatformExportTask ). mockReset (). mockResolvedValue ({ taskName : '国内仓订单' , taskNo : 'EXP-1' } as never )
vi . mocked ( showExportTaskCreatedDialog ). mockReset (). mockResolvedValue ( false )
2026-08-11 18:06:35 +08:00
})
2026-10-20 17:24:50 +08:00
it ( 'shares applied filters, advanced fields and reset across measurement review and other tabs' , async () => {
const wrapper = mountView ()
await flushPromises ()
const model = { receivingWarehouseId : '9007199254740993' , destinationWarehouseId : '200' , inboundCode : ' IN-9 ' , tenantId : '300' , channelName : '海派' , containerNo : 'CONT-1' , cabinetNo : 'CAB-1' , loaded : 'false' , fullContainer : 'true' , expectedArrivalDate : '2026-10-20' , sailingDate : '2026-11-01' , feeReviewStatus : 'APPROVED' , measurementReviewStatus : 'PENDING' , fbaCode : 'SKU-1' , createdRange : [ '2026-10-01' , '2026-10-20' ] }
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
toolbar . vm . $emit ( 'update:modelValue' , { ... toolbar . props ( 'modelValue' ), ... model })
await flushPromises ()
toolbar . vm . $emit ( 'search' )
await flushPromises ()
const ordinaryQuery = vi . mocked ( listPlatformUnifiedOrders ). mock . lastCall ! [ 0 ]
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text (). startsWith ( '测量数据审核' )) ! . trigger ( 'click' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ({ ... ordinaryQuery , mainStatus : 'MEASUREMENT_REVIEW' })
const reviewToolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
expect ( reviewToolbar . props ( 'modelValue' )). toMatchObject ( model )
expect ( reviewToolbar . attributes ( 'preference-key' )). toBe ( 'unified-orders-query-v2' )
2026-10-28 12:01:43 +08:00
expect ( reviewToolbar . props ( 'maxVisible' )). toBe ( 3 )
expect ( reviewToolbar . props ( 'fields' ). map (( field : { key : string }) => field . key )). toEqual ( expect . arrayContaining ([ 'createdRange' , 'tenantId' , 'inboundCode' ]))
2026-10-20 17:24:50 +08:00
reviewToolbar . vm . $emit ( 'reset' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ mainStatus : 'MEASUREMENT_REVIEW' , receivingWarehouseId : undefined , inboundCode : undefined , channelName : undefined , tenantId : undefined }))
reviewToolbar . vm . $emit ( 'update:modelValue' , { ... reviewToolbar . props ( 'modelValue' ), inboundCode : 'IN-REVIEW' })
await flushPromises ()
reviewToolbar . vm . $emit ( 'search' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ mainStatus : 'MEASUREMENT_REVIEW' , inboundCode : 'IN-REVIEW' }))
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text (). startsWith ( '待审核' )) ! . trigger ( 'click' )
await flushPromises ()
expect ( wrapper . getComponent ({ name : 'QueryToolbar' }). props ( 'modelValue' )). toMatchObject ({ inboundCode : 'IN-REVIEW' })
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ mainStatus : 'PENDING_REVIEW' , inboundCode : 'IN-REVIEW' }))
})
2026-10-28 12:01:43 +08:00
it . each ([ '全部' , '测量数据审核' ])( 'limits fields after saved ordering without changing filters or querying when %s is expanded and collapsed' , async ( tabLabel ) => {
const wrapper = mountView ()
await flushPromises ()
if ( tabLabel !== '全部' ) {
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text (). startsWith ( tabLabel )) ! . trigger ( 'click' )
await flushPromises ()
}
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
const fieldKeys = toolbar . props ( 'fields' ). map (( field : { key : string }) => field . key )
expect ( fieldKeys ). toHaveLength ( 15 )
expect ( fieldKeys ). toEqual ( expect . arrayContaining ([ 'createdRange' , 'tenantId' , 'inboundCode' ]))
expect ( toolbar . props ( 'maxVisible' )). toBe ( 3 )
const model = { ... toolbar . props ( 'modelValue' ), tenantId : 'customer-1' , inboundCode : 'IN-KEEP' , createdRange : [ '2026-10-01' , '2026-10-28' ] }
toolbar . vm . $emit ( 'update:modelValue' , model )
await flushPromises ()
const requestCount = vi . mocked ( listPlatformUnifiedOrders ). mock . calls . length
await wrapper . get ( '[aria-controls="unified-orders-advanced-filters"]' ). trigger ( 'click' )
expect ( toolbar . props ( 'maxVisible' )). toBeUndefined ()
await wrapper . get ( '[aria-controls="unified-orders-advanced-filters"]' ). trigger ( 'click' )
expect ( toolbar . props ( 'maxVisible' )). toBe ( 3 )
expect ( toolbar . props ( 'fields' ). map (( field : { key : string }) => field . key )). toEqual ( fieldKeys )
expect ( toolbar . props ( 'modelValue' )). toEqual ( model )
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( requestCount )
wrapper . unmount ()
})
2026-10-20 11:33:39 +08:00
it ( 'shows only supported counts, keeps all text-only and never scopes counts by status or pagination' , async () => {
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockResolvedValue ({ counts : { PENDING_REVIEW : 12 , WAIT_MEASURE : 0 , SIGNED : 3 } })
const wrapper = mountView ()
await flushPromises ()
const tabs = wrapper . findAll ( '[role="tab"]' )
expect ( tabs [ 0 ] ! . text ()). toBe ( '全部' )
expect ( tabs [ 1 ] ! . text ()). toBe ( '待审核(12) ' )
expect ( tabs [ 2 ] ! . text ()). toBe ( '待测量数据(0) ' )
expect ( tabs [ 3 ] ! . text ()). toBe ( '测量数据审核' )
2026-10-20 21:33:46 +08:00
expect ( tabs . at ( - 1 ) ! . text ()). toBe ( '派送完成(3) ' )
2026-10-20 11:33:39 +08:00
expect ( tabs . map (( tab ) => tab . text ())). not . toContain ( '派送完成' )
expect ( tabs . map (( tab ) => tab . text ())). not . toContain ( '已完成' )
await tabs [ 1 ] ! . trigger ( 'click' )
wrapper . getComponent ({ name : 'DataTable' }). vm . $emit ( 'update:page' , 2 )
await flushPromises ()
expect ( getPlatformUnifiedOrderStatusCounts ). toHaveBeenCalledTimes ( 1 )
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
toolbar . vm . $emit ( 'update:modelValue' , { ... toolbar . props ( 'modelValue' ), inboundCode : ' IN-9 ' , loaded : 'false' })
toolbar . vm . $emit ( 'search' )
await flushPromises ()
expect ( getPlatformUnifiedOrderStatusCounts ). toHaveBeenCalledTimes ( 2 )
const params = vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mock . lastCall ! [ 0 ]
expect ( params ). toMatchObject ({ inboundCode : 'IN-9' , loaded : false })
expect ( params ). not . toHaveProperty ( 'mainStatus' )
expect ( params ). not . toHaveProperty ( 'page' )
expect ( params ). not . toHaveProperty ( 'size' )
toolbar . vm . $emit ( 'reset' )
await flushPromises ()
expect ( getPlatformUnifiedOrderStatusCounts ). toHaveBeenCalledTimes ( 3 )
})
it ( 'ignores older count responses and hides stale counts during loading and failures with retry' , async () => {
let resolveOld !: ( value : { counts : { PENDING_REVIEW : number } }) => void
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockImplementationOnce (() => new Promise (( resolve ) => { resolveOld = resolve }))
const wrapper = mountView ()
await flushPromises ()
expect ( wrapper . get ( '[role="tablist"]' ). attributes ( 'aria-busy' )). toBe ( 'true' )
expect ( wrapper . find ( '.order-status-count' ). exists ()). toBe ( false )
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockResolvedValueOnce ({ counts : { PENDING_REVIEW : 7 } })
wrapper . getComponent ({ name : 'QueryToolbar' }). vm . $emit ( 'search' )
await flushPromises ()
resolveOld ({ counts : { PENDING_REVIEW : 99 } })
await flushPromises ()
expect ( wrapper . findAll ( '[role="tab"]' )[ 1 ] ! . text ()). toBe ( '待审核(7) ' )
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockRejectedValueOnce ( new Error ( '统计不可用' ))
wrapper . getComponent ({ name : 'QueryToolbar' }). vm . $emit ( 'search' )
await flushPromises ()
expect ( wrapper . find ( '.order-status-count' ). exists ()). toBe ( false )
expect ( wrapper . findComponent ({ name : 'DataTable' }). exists ()). toBe ( true )
expect ( wrapper . find ( '.order-status-feedback' ). text ()). toContain ( '重试数量' )
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockResolvedValueOnce ({ counts : { PENDING_REVIEW : 8 , MEASUREMENT_REVIEW : 3 } })
await wrapper . findAll ( 'button' ). find (( button ) => button . text () === '重试数量' ) ! . trigger ( 'click' )
await flushPromises ()
expect ( wrapper . findAll ( '[role="tab"]' )[ 1 ] ! . text ()). toBe ( '待审核(8) ' )
expect ( wrapper . findAll ( '[role="tab"]' )[ 3 ] ! . text ()). toBe ( '测量数据审核(3) ' )
})
2026-10-20 23:49:50 +08:00
it ( 'keeps every count and the toolbar state stable when switching between ordinary and review tabs' , async () => {
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockResolvedValueOnce ({ counts : { PENDING_REVIEW : 12 , WAIT_MEASURE : 0 , MEASUREMENT_REVIEW : 4 , SIGNED : 3 } })
const wrapper = mountView ()
await flushPromises ()
const labels = wrapper . findAll ( '[role="tab"]' ). map ( tab => tab . text ())
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockImplementation (() => new Promise (() => {}))
for ( const label of [ '待审核(12) ' , '测量数据审核(4) ' , '待测量数据(0) ' , '全部' ]) {
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text () === label ) ! . trigger ( 'click' )
await flushPromises ()
expect ( wrapper . findAll ( '[role="tab"]' ). map ( tab => tab . text ())). toEqual ( labels )
expect ( wrapper . get ( '[aria-selected="true"]' ). text ()). toBe ( label )
expect ( wrapper . get ( '[role="tablist"]' ). attributes ( 'aria-busy' )). toBe ( 'false' )
expect ( wrapper . find ( '.order-status-feedback' ). exists ()). toBe ( false )
expect ( getPlatformUnifiedOrderStatusCounts ). toHaveBeenCalledTimes ( 1 )
}
})
2026-10-22 11:56:54 +08:00
it . each ([ '全部' , '测量数据审核' ])( 'keeps the %s tab bar mounted without a loading text row during query' , async ( label ) => {
const wrapper = mountView ()
await flushPromises ()
if ( label !== '全部' ) {
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text () === label ) ! . trigger ( 'click' )
await flushPromises ()
}
const tabList = wrapper . get ( '[role="tablist"]' ). element
let resolveCounts !: ( value : { counts : {} }) => void
vi . mocked ( getPlatformUnifiedOrderStatusCounts ). mockImplementationOnce (() => new Promise ( resolve => { resolveCounts = resolve }))
wrapper . getComponent ({ name : 'QueryToolbar' }). vm . $emit ( 'search' )
await flushPromises ()
expect ( wrapper . get ( '[role="tablist"]' ). element ). toBe ( tabList )
expect ( wrapper . get ( '[role="tablist"]' ). attributes ( 'aria-busy' )). toBe ( 'true' )
expect ( wrapper . find ( '.order-status-feedback' ). exists ()). toBe ( false )
resolveCounts ({ counts : {} })
await flushPromises ()
expect ( wrapper . get ( '[role="tablist"]' ). element ). toBe ( tabList )
expect ( wrapper . get ( '[role="tablist"]' ). attributes ( 'aria-busy' )). toBe ( 'false' )
wrapper . unmount ()
})
2026-10-20 23:49:50 +08:00
it . each ([ 'success' , 'failure' ] as const )( 'ignores an older tab request %s after the current tab has loaded' , async ( outcome ) => {
const wrapper = mountView ()
await flushPromises ()
let resolveOlder !: ( value : Awaited < ReturnType < typeof listPlatformUnifiedOrders >>) => void
let rejectOlder !: ( reason : Error ) => void
vi . mocked ( listPlatformUnifiedOrders ). mockImplementationOnce (() => new Promise (( resolve , reject ) => { resolveOlder = resolve ; rejectOlder = reject }))
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text () === '待审核' ) ! . trigger ( 'click' )
const latest = { ... emptyPage (), records : [{ orderId : 'new-order' , tenantId : '8' , orderVersion : 1 , inboundCode : 'IN-NEW' , internalOrderStatus : 'SUBMITTED' , mainStatus : 'WAIT_MEASURE' , expectedArrivalAt : null , estimatedVolumeCbm : null }], total : 1 , pages : 1 } as Awaited < ReturnType < typeof listPlatformUnifiedOrders >>
vi . mocked ( listPlatformUnifiedOrders ). mockResolvedValueOnce ( latest )
await wrapper . findAll ( '[role="tab"]' ). find ( tab => tab . text () === '待测量数据' ) ! . trigger ( 'click' )
await flushPromises ()
expect ( wrapper . getComponent ({ name : 'DataTable' }). props ( 'data' )). toEqual ( latest . records )
if ( outcome === 'success' ) resolveOlder ( emptyPage ())
else rejectOlder ( new Error ( '旧页签请求失败' ))
await flushPromises ()
expect ( wrapper . get ( '[aria-selected="true"]' ). text ()). toBe ( '待测量数据' )
expect ( wrapper . getComponent ({ name : 'DataTable' }). props ( 'data' )). toEqual ( latest . records )
expect ( wrapper . findComponent ({ name : 'LoadErrorState' }). exists ()). toBe ( false )
})
2026-08-11 18:06:35 +08:00
it ( 'loads once initially and once for query, reset, status tab and pagination' , async () => {
const wrapper = mountView ()
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 1 )
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
toolbar . vm . $emit ( 'search' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 2 )
toolbar . vm . $emit ( 'reset' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 3 )
await wrapper . findAll ( '.status-tab' )[ 1 ] ! . trigger ( 'click' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 4 )
wrapper . getComponent ({ name : 'DataTable' }). vm . $emit ( 'update:page' , 2 )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 5 )
})
2026-10-19 15:59:14 +08:00
it ( 'opens the existing measurement review list beside measurement and returns to order queries' , async () => {
const wrapper = mountView ()
await flushPromises ()
const labels = wrapper . findAll ( '[role="tab"]' ). map (( tab ) => tab . text ())
expect ( labels . indexOf ( '测量数据审核' )). toBe ( labels . indexOf ( '待测量数据' ) + 1 )
await wrapper . findAll ( '[role="tab"]' ). find (( tab ) => tab . text () === '测量数据审核' ) ! . trigger ( 'click' )
await flushPromises ()
expect ( wrapper . getComponent ({ name : 'InboundTaskList' }). props ()). toMatchObject ({ mode : 'review' , title : '订单列表' })
2026-10-20 23:34:11 +08:00
expect ( wrapper . getComponent ({ name : 'InboundTaskList' }). classes ()). toContain ( 'is-embedded' )
expect ( wrapper . get ( 'main' ). classes ()). not . toContain ( 'is-embedded' )
2026-10-19 15:59:14 +08:00
expect ( wrapper . get ( '[aria-selected="true"]' ). text ()). toBe ( '测量数据审核' )
2026-10-20 17:24:50 +08:00
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 2 )
2026-10-19 15:59:14 +08:00
await wrapper . findAll ( '[role="tab"]' ). find (( tab ) => tab . text () === '待测量数据' ) ! . trigger ( 'click' )
await flushPromises ()
expect ( wrapper . findComponent ({ name : 'InboundTaskList' }). exists ()). toBe ( false )
2026-10-20 23:34:11 +08:00
expect ( wrapper . find ( '.is-embedded' ). exists ()). toBe ( false )
2026-10-19 15:59:14 +08:00
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ mainStatus : 'WAIT_MEASURE' }))
2026-10-20 17:24:50 +08:00
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 3 )
2026-10-19 15:59:14 +08:00
})
2026-08-11 18:06:35 +08:00
it ( 'does not apply draft filters to pagination until query is submitted' , async () => {
const wrapper = mountView ()
await flushPromises ()
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
const draft = { ... toolbar . props ( 'modelValue' ), inboundCode : ' DRAFT-CODE ' }
toolbar . vm . $emit ( 'update:modelValue' , draft )
await wrapper . vm . $nextTick ()
wrapper . getComponent ({ name : 'DataTable' }). vm . $emit ( 'update:page' , 2 )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ page : 2 , inboundCode : undefined }))
toolbar . vm . $emit ( 'search' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 3 )
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ page : 1 , inboundCode : 'DRAFT-CODE' }))
})
it ( 'resets a later page and changes page size with one request per interaction' , async () => {
const wrapper = mountView ()
await flushPromises ()
const table = wrapper . getComponent ({ name : 'DataTable' })
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
table . vm . $emit ( 'update:page' , 3 )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 2 )
toolbar . vm . $emit ( 'reset' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 3 )
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ page : 1 }))
table . vm . $emit ( 'update:pageSize' , 50 )
table . vm . $emit ( 'update:page' , 1 )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 4 )
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ page : 1 , size : 50 }))
})
2026-08-25 22:08:59 +08:00
it ( 'does not turn a cleared full-container filter into false' , async () => {
const wrapper = mountView ()
await flushPromises ()
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
const selected = { ... toolbar . props ( 'modelValue' ), fullContainer : 'true' }
toolbar . vm . $emit ( 'update:modelValue' , selected )
toolbar . vm . $emit ( 'search' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ fullContainer : true }))
toolbar . vm . $emit ( 'update:modelValue' , { ... selected , fullContainer : undefined })
toolbar . vm . $emit ( 'search' )
await flushPromises ()
expect ( listPlatformUnifiedOrders ). toHaveBeenLastCalledWith ( expect . objectContaining ({ fullContainer : undefined }))
})
2026-09-01 21:09:39 +08:00
it ( 'exports the selected business order numbers without loading other pages' , async () => {
const wrapper = mountView ()
await flushPromises ()
wrapper . getComponent ({ name : 'DataTable' }). vm . $emit ( 'selection-change' , [
{ orderId : '1' , orderNo : 'ORDER-1' , tenantId : '8' },
{ orderId : '2' , orderNo : 'ORDER-2' , tenantId : '8' },
])
await wrapper . vm . $nextTick ()
await wrapper . findAll ( 'button' ). find (( button ) => button . text (). includes ( '导出' )) ! . trigger ( 'click' )
await flushPromises ()
expect ( createPlatformExportTask ). toHaveBeenCalledWith ({
exportType : 'DOMESTIC_WAREHOUSE_ORDER_LIST' , format : 'XLSX' , taskName : '国内仓订单-已选2票' ,
parameters : { selectedOrderNos : [ 'ORDER-1' , 'ORDER-2' ] },
})
expect ( listPlatformUnifiedOrders ). toHaveBeenCalledTimes ( 1 )
})
it ( 'exports every result matching the applied filters instead of the current page' , async () => {
const wrapper = mountView ()
await flushPromises ()
const toolbar = wrapper . getComponent ({ name : 'QueryToolbar' })
toolbar . vm . $emit ( 'update:modelValue' , {
... toolbar . props ( 'modelValue' ), inboundCode : ' IN-8 ' , loaded : 'false' , createdRange : [ '2026-08-01' , '2026-08-31' ],
})
toolbar . vm . $emit ( 'search' )
await flushPromises ()
await wrapper . findAll ( 'button' ). find (( button ) => button . text () === '导出' ) ! . trigger ( 'click' )
await flushPromises ()
expect ( createPlatformExportTask ). toHaveBeenCalledWith ( expect . objectContaining ({
exportType : 'DOMESTIC_WAREHOUSE_ORDER_LIST' , taskName : '国内仓订单-当前筛选' ,
parameters : expect.objectContaining ({
inboundCode : 'IN-8' , loaded : false ,
createdFrom : '2026-08-01T00:00:00' , createdTo : '2026-08-31T23:59:59' ,
}),
}))
expect ( createPlatformExportTask ). not . toHaveBeenCalledWith ( expect . objectContaining ({
parameters : expect.objectContaining ({ page : expect.anything (), size : expect.anything () }),
}))
})
2026-09-03 11:47:32 +08:00
2026-09-04 18:47:43 +08:00
it ( 'edits arrival and estimated volume and reports compact failure evidence through a message' , async () => {
const errorMessage = vi . spyOn ( ElMessage , 'error' ). mockImplementation (() => undefined as never )
2026-09-03 11:47:32 +08:00
vi . mocked ( listPlatformUnifiedOrders ). mockResolvedValue ({
records : [{
orderId : '2089223263733518337' , orderVersion : 7 , tenantId : '2089176869176389634' ,
2026-09-15 17:46:44 +08:00
internalOrderStatus : 'SUBMITTED' ,
2026-09-03 11:47:32 +08:00
inboundCode : 'NYEXX2609030001' , expectedArrivalAt : '2026-09-10T08:30:00' , estimatedVolumeCbm : 0.25 ,
}], page : 1 , size : 20 , total : 1 , pages : 1 ,
} as never )
vi . mocked ( updatePlatformUnifiedOrderPlanning )
. mockResolvedValueOnce ({ version : 8 } as never )
. mockRejectedValueOnce ( new ApiResponseError ( '订单版本已变化' , 'A0409' , 200 , undefined , 'req-planning' , 'trace-planning' ))
const wrapper = mountView ()
await flushPromises ()
const volume = wrapper . getComponent ({ name : 'ElInputNumber' })
volume . vm . $emit ( 'update:modelValue' , 0.5 )
volume . vm . $emit ( 'change' , 0.5 )
await flushPromises ()
expect ( updatePlatformUnifiedOrderPlanning ). toHaveBeenNthCalledWith ( 1 ,
'2089176869176389634' , '2089223263733518337' , {
expectedVersion : 7 , expectedArrivalAt : '2026-09-10T08:30:00' , estimatedVolumeCbm : 0.5 ,
})
const arrival = wrapper . getComponent ({ name : 'ElDatePicker' })
arrival . vm . $emit ( 'update:modelValue' , '2026-09-12T16:00:00' )
arrival . vm . $emit ( 'change' , '2026-09-12T16:00:00' )
await flushPromises ()
expect ( updatePlatformUnifiedOrderPlanning ). toHaveBeenNthCalledWith ( 2 ,
'2089176869176389634' , '2089223263733518337' , {
expectedVersion : 8 , expectedArrivalAt : '2026-09-12T16:00:00' , estimatedVolumeCbm : 0.5 ,
})
expect ( wrapper . getComponent ({ name : 'ElDatePicker' }). props ( 'modelValue' )). toBe ( '2026-09-12T16:00:00' )
2026-09-04 18:47:43 +08:00
expect ( wrapper . text ()). not . toContain ( '订单版本已变化' )
expect ( wrapper . find ( '.planning-error' ). exists ()). toBe ( false )
expect ( errorMessage ). toHaveBeenCalledWith ( expect . objectContaining ({
message : '订单版本已变化(错误码 A0409; Request ID req-planning; Trace ID trace-planning) ' ,
showClose : true ,
}))
2026-09-03 11:47:32 +08:00
})
2026-09-15 17:46:44 +08:00
it ( 'shows planning values without editors after the order enters irreversible fulfillment' , async () => {
vi . mocked ( listPlatformUnifiedOrders ). mockResolvedValue ({
records : [{
orderId : '2099751993783402497' , orderVersion : 7 , tenantId : '2097708157074210818' ,
internalOrderStatus : 'PROCESSING' , mainStatus : 'LOADED' , inboundCode : 'AT0E9B5BF2839C6944CFA3' ,
expectedArrivalAt : '2026-10-15T00:00:00' , estimatedVolumeCbm : 220 ,
}], page : 1 , size : 20 , total : 1 , pages : 1 ,
} as never )
const wrapper = mountView ()
await flushPromises ()
expect ( wrapper . findComponent ({ name : 'ElInputNumber' }). exists ()). toBe ( false )
expect ( wrapper . findComponent ({ name : 'ElDatePicker' }). exists ()). toBe ( false )
expect ( wrapper . text ()). toContain ( '220' )
expect ( wrapper . text ()). toContain ( '2026-10-15 00:00' )
expect ( updatePlatformUnifiedOrderPlanning ). not . toHaveBeenCalled ()
})
2026-08-11 18:06:35 +08:00
})