import { shallowMount, flushPromises } from '@vue/test-utils'
import { beforeEach, expect, it, vi } from 'vitest'
import View from './DispatchCapacityDemandsView.vue'
import * as api from '../api/dispatchCapacityDemands'
vi.mock('../api/dispatchCapacityDemands', () => ({ listDispatchCapacityDemands: vi.fn() }))
const row: api.DispatchCapacityDemand = { dispatchNo: 'PC-TEST', warehouseName: '测试仓', route: '测试仓 → ONT8', plannedDepartureAt: null, vehiclePalletSpaces: 30, scheduledPalletCount: 18, remainingPalletSpaces: null, remainingWeightKg: null, remainingVolumeCbm: null, capacityKnown: false, capacityReason: '占用标准托位、重量及体积待确认' }
const result = { records: [row], page: 1, size: 20, total: 1, pages: 1 }
const layout = { template: '
' }
function mount() { return shallowMount(View, { global: { stubs: { AdminPage: layout, ListPageLayout: layout, DataTable: { name: 'DataTable', props: ['data', 'columns', 'total', 'resultsVisible'], emits: ['update:page'], template: '
' }, QueryToolbar: { name: 'QueryToolbar', props: ['modelValue'], emits: ['update:modelValue', 'search'], template: '' }, LoadErrorState: { name: 'LoadErrorState', emits: ['retry'], template: '' } } } }) }
beforeEach(() => { vi.clearAllMocks(); vi.mocked(api.listDispatchCapacityDemands).mockResolvedValue(result) })
it('uses the dispatch source and never presents registration, publication or legacy trip navigation', async () => {
const wrapper = mount(); await flushPromises()
expect(api.listDispatchCapacityDemands).toHaveBeenCalledExactlyOnceWith({ page: 1, size: 20, origin: undefined, destination: undefined })
const table = wrapper.getComponent({ name: 'DataTable' })
expect(table.props('data')).toEqual([row])
const columns = table.props('columns') as { key: string; formatter?: (value: api.DispatchCapacityDemand) => string }[]
expect(columns.some(c => c.key === 'actions')).toBe(false)
expect(columns.find(c => c.key === 'remainingPalletSpaces')?.formatter?.(row)).toBe('待确认')
expect(columns.find(c => c.key === 'remainingPalletSpaces')?.formatter?.({ ...row, capacityKnown: true, remainingPalletSpaces: 12 })).toBe('12')
expect(wrapper.findAll('button')).toHaveLength(0)
wrapper.unmount()
})
it('applies warehouse and destination queries and resets pagination only once', async () => {
const wrapper=mount(); await flushPromises()
wrapper.getComponent({name:'DataTable'}).vm.$emit('update:page',2); await flushPromises()
const query=wrapper.getComponent({name:'QueryToolbar'})
query.vm.$emit('update:modelValue',{origin:'洛杉矶',destination:'ONT8'}); await flushPromises(); query.vm.$emit('search'); await flushPromises()
expect(api.listDispatchCapacityDemands).toHaveBeenCalledTimes(3)
expect(api.listDispatchCapacityDemands).toHaveBeenLastCalledWith({page:1,size:20,origin:'洛杉矶',destination:'ONT8'})
wrapper.unmount()
})
it('preserves the query and retries an explicit read error', async () => {
vi.mocked(api.listDispatchCapacityDemands).mockRejectedValueOnce(new Error('offline'))
const wrapper=mount(); await flushPromises()
expect(wrapper.getComponent({name:'DataTable'}).props('resultsVisible')).toBe(false)
wrapper.getComponent({name:'LoadErrorState'}).vm.$emit('retry'); await flushPromises()
expect(wrapper.getComponent({name:'DataTable'}).props('resultsVisible')).toBe(true)
expect(api.listDispatchCapacityDemands).toHaveBeenCalledTimes(2)
wrapper.unmount()
})