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() })