From 049f895b44a85396650367cec72a15ddd0f57569 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Sat, 3 Oct 2026 19:04:31 +0800 Subject: [PATCH] fix(fleet): ignore stale vehicle list responses --- .../pages/VehiclesQueryRace.test.ts | 54 +++++++++++++++++++ .../pages/VehiclesView.vue | 15 +++++- 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/modules/overseas-master-data/pages/VehiclesQueryRace.test.ts diff --git a/src/modules/overseas-master-data/pages/VehiclesQueryRace.test.ts b/src/modules/overseas-master-data/pages/VehiclesQueryRace.test.ts new file mode 100644 index 00000000..3e802ea6 --- /dev/null +++ b/src/modules/overseas-master-data/pages/VehiclesQueryRace.test.ts @@ -0,0 +1,54 @@ +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: '
' } +const table = { name: 'DataTable', props: ['data', 'total', 'loading'], template: '

{{ row.plateNumber }}

' } +type Page = Awaited> +function deferred() { + let resolve!: (page: Page) => void, reject!: (reason: Error) => void + const promise = new Promise((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) +}) diff --git a/src/modules/overseas-master-data/pages/VehiclesView.vue b/src/modules/overseas-master-data/pages/VehiclesView.vue index 3168ee27..45e41606 100644 --- a/src/modules/overseas-master-data/pages/VehiclesView.vue +++ b/src/modules/overseas-master-data/pages/VehiclesView.vue @@ -1,7 +1,7 @@