perf(web): make mileage exports cancellable

This commit is contained in:
lingniu
2026-07-16 01:43:57 +08:00
parent 639564b96d
commit c834a0406c
8 changed files with 246 additions and 15 deletions

View File

@@ -126,5 +126,54 @@ test('exports the full fleet mileage with one paginated query instead of VIN bat
expect(exportMileageCall.get('vins')).toBeNull();
expect(exportMileageCall.get('vehicleScope')).toBe('bound');
expect(exportMocks.downloadMileageWorkbook.mock.calls[0][0].vehicles).toHaveLength(1);
expect(mocks.vehicleCoverage.mock.calls[mocks.vehicleCoverage.mock.calls.length - 1][1]).toBeInstanceOf(AbortSignal);
expect(mocks.dailyMileage.mock.calls[mocks.dailyMileage.mock.calls.length - 1][1]).toBeInstanceOf(AbortSignal);
expect(exportMocks.downloadMileageWorkbook.mock.calls[0][1]).toBeInstanceOf(AbortSignal);
expect(screen.getByText(/已导出 1 辆车/)).toBeInTheDocument();
});
test('shows export progress and lets the user cancel the active request', async () => {
prepareData();
let exportSignal: AbortSignal | undefined;
mocks.vehicleCoverage.mockImplementation((params: URLSearchParams, signal?: AbortSignal) => {
if (params.get('limit') !== String(2_000)) {
return Promise.resolve({ items: [{ vin: 'LTEST000000000001', plate: '粤A12345' }], total: 1, limit: 20, offset: 0 });
}
exportSignal = signal;
return new Promise((_resolve, reject) => {
signal?.addEventListener('abort', () => reject(new DOMException('cancelled', 'AbortError')), { once: true });
});
});
renderPage('/statistics?dateFrom=2026-07-13&dateTo=2026-07-14');
await waitFor(() => expect(screen.getByRole('button', { name: '导出 Excel' })).toBeEnabled());
fireEvent.click(screen.getByRole('button', { name: '导出 Excel' }));
expect(await screen.findByRole('progressbar', { name: '正在读取车辆档案' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: '取消导出' })).toBeEnabled();
fireEvent.click(screen.getByRole('button', { name: '取消导出' }));
await waitFor(() => expect(exportSignal?.aborted).toBe(true));
expect(await screen.findByText(/已取消导出/)).toBeInTheDocument();
expect(exportMocks.downloadMileageWorkbook).not.toHaveBeenCalled();
});
test('aborts an active export when the mileage route unmounts', async () => {
prepareData();
let exportSignal: AbortSignal | undefined;
mocks.vehicleCoverage.mockImplementation((params: URLSearchParams, signal?: AbortSignal) => {
if (params.get('limit') !== String(2_000)) {
return Promise.resolve({ items: [{ vin: 'LTEST000000000001', plate: '粤A12345' }], total: 1, limit: 20, offset: 0 });
}
exportSignal = signal;
return new Promise(() => undefined);
});
const view = renderPage('/statistics?dateFrom=2026-07-13&dateTo=2026-07-14');
await waitFor(() => expect(screen.getByRole('button', { name: '导出 Excel' })).toBeEnabled());
fireEvent.click(screen.getByRole('button', { name: '导出 Excel' }));
expect(await screen.findByRole('progressbar', { name: '正在读取车辆档案' })).toBeInTheDocument();
view.unmount();
expect(exportSignal?.aborted).toBe(true);
expect(exportMocks.downloadMileageWorkbook).not.toHaveBeenCalled();
});