55 lines
3.3 KiB
TypeScript
55 lines
3.3 KiB
TypeScript
import { afterEach, expect, it, vi } from 'vitest'
|
|||
|
|
import { flushPromises, shallowMount, type VueWrapper } from '@vue/test-utils'
|
||
|
|
import VehiclesView from './VehiclesView.vue'
|
||
|
|
import * as api from '../api/overseasMasterData'
|
||
|
|
|
||
|
|
vi.mock('vue-router', () => ({ useRouter: () => ({ push: vi.fn() }) }))
|
||
|
|
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => true }) }))
|
||
|
|
vi.mock('../api/overseasMasterData', () => ({ listVehicles: vi.fn(), getVehicle: vi.fn(), createVehicle: vi.fn(), updateVehicle: vi.fn(), changeVehicleStatus: vi.fn(), exportVehicles: vi.fn() }))
|
||
|
|
const layout = { template: '<div><slot/></div>' }
|
||
|
|
const table = { name: 'DataTable', props: ['data', 'total', 'loading'], template: '<div><slot name="filters"/><slot name="notices"/><p v-for="row in data">{{ row.plateNumber }}</p></div>' }
|
||
|
|
type Page = Awaited<ReturnType<typeof api.listVehicles>>
|
||
|
|
function deferred() {
|
||
|
|
let resolve!: (page: Page) => void, reject!: (reason: Error) => void
|
||
|
|
const promise = new Promise<Page>((yes, no) => { resolve = yes; reject = no })
|
||
|
|
return { promise, resolve, reject }
|
||
|
|
}
|
||
|
|
function page(plateNumber: string): Page {
|
||
|
|
return { records: [{ id: plateNumber, plateNumber } as Page['records'][number]], total: 1, page: 1, size: 20, pages: 1 }
|
||
|
|
}
|
||
|
|
const wrappers: VueWrapper[] = []
|
||
|
|
function mount() {
|
||
|
|
const wrapper = shallowMount(VehiclesView, { global: { stubs: { AdminPage: layout, ListPageLayout: layout, DataTable: table, QueryToolbar: true, LoadErrorState: true, AppDialog: true } } })
|
||
|
|
wrappers.push(wrapper); return wrapper
|
||
|
|
}
|
||
|
|
afterEach(() => { wrappers.splice(0).forEach(wrapper => wrapper.unmount()); vi.clearAllMocks() })
|
||
|
|
|
||
|
|
it.each(['success', 'failure'] as const)('keeps the selected ownership results after a stale %s', async outcome => {
|
||
|
|
const old = deferred(), current = deferred()
|
||
|
|
vi.mocked(api.listVehicles).mockReturnValueOnce(old.promise).mockReturnValueOnce(current.promise)
|
||
|
|
const wrapper = mount()
|
||
|
|
await wrapper.get('[role="tab"][aria-selected="false"]').trigger('click')
|
||
|
|
expect(api.listVehicles).toHaveBeenLastCalledWith(expect.objectContaining({ ownership: 'DISPATCHED' }))
|
||
|
|
current.resolve(page('EXTERNAL-CURRENT')); await flushPromises()
|
||
|
|
if (outcome === 'success') old.resolve(page('OWNED-STALE'))
|
||
|
|
else old.reject(new Error('old request failed'))
|
||
|
|
await flushPromises()
|
||
|
|
expect(wrapper.text()).toContain('EXTERNAL-CURRENT')
|
||
|
|
expect(wrapper.text()).not.toContain('OWNED-STALE')
|
||
|
|
expect(wrapper.findComponent({ name: 'LoadErrorState' }).exists()).toBe(false)
|
||
|
|
expect(wrapper.findComponent({ name: 'DataTable' }).props('total')).toBe(1)
|
||
|
|
})
|
||
|
|
|
||
|
|
it('keeps loading until the currently selected query finishes', async () => {
|
||
|
|
const old = deferred(), current = deferred()
|
||
|
|
vi.mocked(api.listVehicles).mockReturnValueOnce(old.promise).mockReturnValueOnce(current.promise)
|
||
|
|
const wrapper = mount()
|
||
|
|
await wrapper.get('[role="tab"][aria-selected="false"]').trigger('click')
|
||
|
|
old.resolve(page('OWNED-STALE')); await flushPromises()
|
||
|
|
expect(wrapper.findComponent({ name: 'DataTable' }).props('loading')).toBe(true)
|
||
|
|
expect(wrapper.text()).not.toContain('OWNED-STALE')
|
||
|
|
current.resolve(page('EXTERNAL-CURRENT')); await flushPromises()
|
||
|
|
expect(wrapper.findComponent({ name: 'DataTable' }).props('loading')).toBe(false)
|
||
|
|
expect(api.listVehicles).toHaveBeenCalledTimes(2)
|
||
|
|
})
|