60 lines
4.3 KiB
TypeScript
60 lines
4.3 KiB
TypeScript
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
|
|
import { shallowMount, flushPromises, type VueWrapper } from '@vue/test-utils'
|
|
import VehicleFulfillmentTable from './VehicleFulfillmentTable.vue'
|
|
import * as api from '../api/vehicleFulfillment'
|
|
const permissions = vi.hoisted(() => ({ allowed: true }))
|
|
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => permissions.allowed }) }))
|
|
vi.mock('../api/vehicleFulfillment', () => ({ listVehicleDeliveries: vi.fn(), listVehicleAssignmentChanges: vi.fn() }))
|
|
const wrappers: VueWrapper[] = []
|
|
const result = (number: string) => ({ records: [{ deliveryNo: number }], page: 1, size: 10, total: 1, pages: 1 })
|
|
function mount(kind: 'deliveries' | 'changes' = 'deliveries') {
|
|
const wrapper = shallowMount(VehicleFulfillmentTable, { props: { vehicleId: '900719925474099301', kind }, global: { stubs: {
|
|
DataTable: { name: 'DataTable', props: ['data','columns','page','pageSize','total','loading'], emits: ['update:page','update:pageSize'], template: '<div><slot name="toolbar-actions"/></div>' },
|
|
ElButton: { template: '<button><slot/></button>' }, LoadErrorState: { name: 'LoadErrorState', props: ['message'], template: '<p>{{ message }}</p>' }, ApiErrorMeta: true,
|
|
} } }); wrappers.push(wrapper); return wrapper
|
|
}
|
|
beforeEach(() => {
|
|
vi.clearAllMocks(); permissions.allowed = true
|
|
vi.mocked(api.listVehicleDeliveries).mockResolvedValue(result('DL-1') as Awaited<ReturnType<typeof api.listVehicleDeliveries>>)
|
|
vi.mocked(api.listVehicleAssignmentChanges).mockResolvedValue({ records: [], page: 1, size: 10, total: 0, pages: 0 })
|
|
})
|
|
afterEach(() => { wrappers.splice(0).forEach(w => w.unmount()) })
|
|
it('loads only its displayed projection once and does not fetch per-row details', async () => {
|
|
const wrapper = mount(); await flushPromises()
|
|
expect(api.listVehicleDeliveries).toHaveBeenCalledExactlyOnceWith('900719925474099301',1,10)
|
|
expect(api.listVehicleAssignmentChanges).not.toHaveBeenCalled()
|
|
expect(wrapper.findComponent({ name: 'DataTable' }).props('data')).toEqual(result('DL-1').records)
|
|
})
|
|
it('does not call either endpoint without the required viewing permissions', async () => {
|
|
permissions.allowed = false; const wrapper = mount(); await flushPromises()
|
|
expect(api.listVehicleDeliveries).not.toHaveBeenCalled(); expect(api.listVehicleAssignmentChanges).not.toHaveBeenCalled()
|
|
expect(wrapper.text()).toContain('暂无派送记录查看权限')
|
|
})
|
|
it('changing vehicle from a later page resets pagination and sends one scoped request', async () => {
|
|
const wrapper = mount(); await flushPromises()
|
|
wrapper.findComponent({ name: 'DataTable' }).vm.$emit('update:page', 3); await flushPromises()
|
|
vi.mocked(api.listVehicleDeliveries).mockClear()
|
|
await wrapper.setProps({ vehicleId: '900719925474099302' }); await flushPromises()
|
|
expect(api.listVehicleDeliveries).toHaveBeenCalledExactlyOnceWith('900719925474099302',1,10)
|
|
})
|
|
it('a late response for the previous vehicle cannot replace the new vehicle records', async () => {
|
|
let resolveOld!: (value: Awaited<ReturnType<typeof api.listVehicleDeliveries>>) => void
|
|
vi.mocked(api.listVehicleDeliveries).mockImplementationOnce(() => new Promise(resolve => { resolveOld=resolve }))
|
|
const wrapper = mount()
|
|
await wrapper.setProps({ vehicleId: '900719925474099302' }); await flushPromises()
|
|
resolveOld(result('DL-OLD') as Awaited<ReturnType<typeof api.listVehicleDeliveries>>); await flushPromises()
|
|
expect(wrapper.findComponent({ name: 'DataTable' }).props('data')).toEqual(result('DL-1').records)
|
|
})
|
|
it('changes use the history endpoint and do not reveal current customer delivery data', async () => {
|
|
mount('changes'); await flushPromises()
|
|
expect(api.listVehicleAssignmentChanges).toHaveBeenCalledExactlyOnceWith('900719925474099301',1,10)
|
|
expect(api.listVehicleDeliveries).not.toHaveBeenCalled()
|
|
})
|
|
it('failed reads show an error and clear stale rows instead of showing unrelated prior data', async () => {
|
|
const wrapper = mount(); await flushPromises()
|
|
vi.mocked(api.listVehicleDeliveries).mockRejectedValueOnce(new Error('读取失败'))
|
|
await wrapper.find('button').trigger('click'); await flushPromises()
|
|
expect(wrapper.findComponent({ name: 'DataTable' }).props('data')).toEqual([])
|
|
expect(wrapper.findComponent({ name: 'LoadErrorState' }).exists()).toBe(true)
|
|
})
|