import { flushPromises, shallowMount } from '@vue/test-utils' import { beforeEach, afterEach, describe, expect, it, vi } from 'vitest' import { reactive } from 'vue' import ConfirmedLoadingListDetailView from './ConfirmedLoadingListDetailView.vue' const mocks = vi.hoisted(() => ({ get: vi.fn(), push: vi.fn(), replace: vi.fn(), back: vi.fn(), route: { params: { planId: '1' }, query: { warehouseId: '11' } as Record } })) vi.mock('vue-router', () => ({ useRoute: () => mocks.route, useRouter: () => mocks })) vi.mock('../api/platformLoadingLists', () => ({ getConfirmedLoadingList: mocks.get, getPreloadPlan: vi.fn() })) vi.mock('@/shared/api/http', () => ({ getApiErrorDetails: (cause: Error) => ({ message: cause.message }) })) function render() { return shallowMount(ConfirmedLoadingListDetailView, { global: { stubs: { AdminPage: { template: '
' }, LoadingListDetailDrawer: { name: 'LoadingListDetailDrawer', props: ['detail', 'error', 'loading'], template: '
' }, } } }) } const completed = (planId = '1') => ({ summary: { status: 'COMPLETED', planId, loadingListNo: `LIST-${planId}` }, items: [], histories: [] }) describe('confirmed loading list detail page', () => { beforeEach(() => { vi.clearAllMocks() mocks.route = reactive({ params: { planId: '1' }, query: { warehouseId: '11' } }) mocks.get.mockResolvedValue(completed()) vi.spyOn(window, 'print').mockImplementation(() => {}) }) afterEach(() => vi.restoreAllMocks()) it('loads read-only detail on the dedicated page and returns to the list', async () => { const wrapper = render(); await flushPromises() expect(mocks.get).toHaveBeenCalledWith('1', '11') const detail = wrapper.findComponent({ name: 'LoadingListDetailDrawer' }) expect(detail.props('detail')).toEqual(completed()) expect(window.print).not.toHaveBeenCalled() vi.spyOn(window.history, 'length', 'get').mockReturnValue(1) detail.vm.$emit('back') expect(mocks.push).toHaveBeenCalledWith({ name: 'loading-lists' }) wrapper.unmount() }) it('prints only after detail has loaded and removes the print request', async () => { mocks.route.query.print = '1' const wrapper = render(); await flushPromises() expect(window.print).toHaveBeenCalledTimes(1) expect(wrapper.findComponent({ name: 'LoadingListDetailDrawer' }).props('loading')).toBe(false) expect(mocks.replace).toHaveBeenCalledWith({ name: 'loading-list-detail', params: { planId: '1' }, query: { warehouseId: '11' } }) wrapper.unmount() }) it('keeps failure visible and does not print when loading fails', async () => { mocks.route.query.print = '1' mocks.get.mockRejectedValueOnce(new Error('清单不可用')) const wrapper = render(); await flushPromises() expect(wrapper.findComponent({ name: 'LoadingListDetailDrawer' }).props('error').message).toBe('清单不可用') expect(window.print).not.toHaveBeenCalled() wrapper.unmount() }) it('ignores a stale response after switching manifests', async () => { let resolveFirst!: (value: unknown) => void mocks.get.mockImplementationOnce(() => new Promise(resolve => { resolveFirst = resolve })) .mockResolvedValueOnce(completed('2')) const wrapper = render() mocks.route.params.planId = '2' await flushPromises() resolveFirst(completed()); await flushPromises() expect(wrapper.findComponent({ name: 'LoadingListDetailDrawer' }).props('detail')).toEqual(completed('2')) wrapper.unmount() }) })