import ElementPlus from 'element-plus' import { createPinia, setActivePinia } from 'pinia' import { createMemoryHistory, createRouter } from 'vue-router' import { flushPromises, mount } from '@vue/test-utils' import { beforeEach, describe, expect, it, vi } from 'vitest' import ContainersView from './ContainersView.vue' import { listAllPlatformWarehouses } from '@/modules/warehouses' import { listContainers } from '../api/platformContainerLoading' vi.mock('@/modules/warehouses', () => ({ listAllPlatformWarehouses: vi.fn() })) vi.mock('../api/platformContainerLoading', () => ({ listContainers: vi.fn(), getContainer: vi.fn(), createContainer: vi.fn(), updateContainer: vi.fn(), updateContainerTransport: vi.fn() })) describe('ContainersView', () => { beforeEach(() => { setActivePinia(createPinia()) vi.mocked(listAllPlatformWarehouses).mockResolvedValue([]) vi.mocked(listContainers).mockResolvedValue({ records: [{ id: '9001', planId: null, bookingNo: 'BK-1', cabinetNo: 'CB-1', containerNo: 'MSCU-1', warehouseId: '8', warehouseName: '义乌仓', containerType: '40HQ', planStatus: 'EDITING', version: 0, billOfLadingNo: null, vesselName: null, voyageNo: null, shippingCompanyId: null, shippingCompanyName: null, departurePortCode: null, departurePortName: '宁波', destinationPortCode: null, destinationPortName: '长滩', destinationWarehouseCode: null, destinationWarehouseName: null, capacityCbm: 68, maxWeightKg: 28000, terminalTruckingCompany: null, loadingAt: null, estimatedSailingAt: null, actualSailingAt: null, estimatedPortArrivalAt: null, actualPortArrivalAt: null, estimatedWarehouseArrivalAt: null, actualWarehouseArrivalAt: null }], page: 1, size: 20, total: 1, pages: 1 }) }) it('loads the real paged contract and renders core container fields', async () => { const router = createRouter({ history: createMemoryHistory(), routes: [{ path: '/', component: ContainersView }] }) await router.push('/'); await router.isReady() const wrapper = mount(ContainersView, { global: { plugins: [ElementPlus, router] } }) await flushPromises() expect(listContainers).toHaveBeenCalledWith(expect.objectContaining({ page: 1, size: 20 })) expect(wrapper.text()).toContain('CB-1') expect(wrapper.text()).toContain('MSCU-1') expect(wrapper.text()).toContain('宁波 → 长滩') expect(wrapper.find('button[aria-label="查看 CB-1"]').exists()).toBe(true) }) it('uses stable view labels when cabinetNo is missing', async () => { const base = { id: '9001', planId: null, bookingNo: 'BK-1', cabinetNo: 'CB-1', containerNo: 'MSCU-1', warehouseId: '8', warehouseName: '义乌仓', containerType: '40HQ', planStatus: 'EDITING' as const, version: 0, billOfLadingNo: null, vesselName: null, voyageNo: null, shippingCompanyId: null, shippingCompanyName: null, departurePortCode: null, departurePortName: '宁波', destinationPortCode: null, destinationPortName: '长滩', destinationWarehouseCode: null, destinationWarehouseName: null, capacityCbm: 68, maxWeightKg: 28000, terminalTruckingCompany: null, loadingAt: null, estimatedSailingAt: null, actualSailingAt: null, estimatedPortArrivalAt: null, actualPortArrivalAt: null, estimatedWarehouseArrivalAt: null, actualWarehouseArrivalAt: null, } vi.mocked(listContainers).mockResolvedValueOnce({ records: [ { ...base, id: '9002', cabinetNo: undefined, containerNo: 'MSCU-2', bookingNo: 'BK-2' }, { ...base, id: '9003', cabinetNo: '', containerNo: null, bookingNo: 'BK-3' }, { ...base, id: '9004', cabinetNo: null, containerNo: null, bookingNo: '' }, ], page: 1, size: 20, total: 3, pages: 1, } as never) const router = createRouter({ history: createMemoryHistory(), routes: [{ path: '/', component: ContainersView }] }) await router.push('/'); await router.isReady() const wrapper = mount(ContainersView, { global: { plugins: [ElementPlus, router] } }) await flushPromises() const labels = wrapper.findAll('.el-table__body button') .map((button) => button.attributes('aria-label')) .filter((label): label is string => Boolean(label)) expect(labels).toEqual(expect.arrayContaining(['查看 MSCU-2', '查看 BK-3', '查看货柜详情'])) expect(labels.every((label) => !/undefined|null/.test(label))).toBe(true) }) })