fix(web): isolate paginated filter scopes
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||
import { afterEach, expect, test, vi } from 'vitest';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import type { AlertEvent, Page } from '../../api/types';
|
||||
import AlertsPage from './AlertsPage';
|
||||
import { ROUTER_FUTURE } from '../routing/routerConfig';
|
||||
|
||||
@@ -18,6 +19,14 @@ afterEach(() => {
|
||||
Object.values(mocks).forEach((mock) => mock.mockReset());
|
||||
});
|
||||
|
||||
function alertEvent(id: string, vin: string, plate: string): AlertEvent {
|
||||
return {
|
||||
id, ruleId: 'speed-rule', ruleName: `${plate}速度告警`, ruleVersion: 1, severity: 'major', status: 'unprocessed',
|
||||
vin, plate, protocol: 'JT808', metric: 'speed_kmh', operator: 'gt', triggerValue: 90, threshold: 80, thresholdHigh: 0,
|
||||
unit: 'km/h', durationSec: 60, location: '测试位置', sourceEventId: `${id}-source`, eventAt: '2026-07-16T04:00:00Z', receivedAt: '2026-07-16T04:00:01Z', triggeredAt: '2026-07-16T04:00:00Z', recoveredAt: '', handler: '', version: 1, actions: []
|
||||
};
|
||||
}
|
||||
|
||||
test('preserves an unsubmitted event filter draft across alert tab URL changes', async () => {
|
||||
mocks.alertSummaryV2.mockResolvedValue({ active: 0, unprocessed: 0, processing: 0, recovered: 0, closed: 0, ignored: 0, unreadNotifications: 0, asOf: '' });
|
||||
mocks.alertEventsV2.mockResolvedValue({ items: [], total: 0, limit: 20, offset: 0 });
|
||||
@@ -62,3 +71,33 @@ test('loads one full notification query on a direct notifications entry', async
|
||||
expect(mocks.alertNotificationsV2).toHaveBeenCalledTimes(1);
|
||||
expect(mocks.alertNotificationsV2.mock.calls[0][0].toString()).toBe('limit=100');
|
||||
});
|
||||
|
||||
test('clears old alert rows and inspector evidence when the event scope changes', async () => {
|
||||
const oldEvent = alertEvent('old-event', 'OLDVIN', '旧告警车牌');
|
||||
const newEvent = alertEvent('new-event', 'NEWVIN', '新告警车牌');
|
||||
let resolveNew!: (value: Page<AlertEvent>) => void;
|
||||
mocks.alertSummaryV2.mockResolvedValue({ active: 1, unprocessed: 1, processing: 0, recovered: 0, closed: 0, ignored: 0, unreadNotifications: 0, asOf: '' });
|
||||
mocks.alertEventsV2.mockImplementation((query: { keyword?: string }) => query.keyword === 'OLDVIN'
|
||||
? Promise.resolve({ items: [oldEvent], total: 1, limit: 20, offset: 0 })
|
||||
: new Promise<Page<AlertEvent>>((resolve) => { resolveNew = resolve; }));
|
||||
mocks.alertEventV2.mockImplementation((id: string) => Promise.resolve(id === oldEvent.id ? oldEvent : newEvent));
|
||||
mocks.alertRulesV2.mockResolvedValue([]);
|
||||
mocks.alertNotificationsV2.mockResolvedValue({ items: [], total: 0, limit: 100, offset: 0 });
|
||||
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
render(<QueryClientProvider client={client}><MemoryRouter future={ROUTER_FUTURE} initialEntries={['/alerts?keyword=OLDVIN']}><AlertsPage /></MemoryRouter></QueryClientProvider>);
|
||||
|
||||
expect((await screen.findAllByText('旧告警车牌')).length).toBeGreaterThan(0);
|
||||
expect(await screen.findByText('old-event')).toBeInTheDocument();
|
||||
fireEvent.change(screen.getByPlaceholderText('车牌 / VIN / 规则名称'), { target: { value: 'NEWVIN' } });
|
||||
fireEvent.click(screen.getByRole('button', { name: '查询' }));
|
||||
|
||||
expect(await screen.findByText('正在更新事件…')).toBeInTheDocument();
|
||||
expect(screen.queryByText('旧告警车牌')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('old-event')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('选择告警事件')).toBeInTheDocument();
|
||||
|
||||
await act(async () => resolveNew({ items: [newEvent], total: 1, limit: 20, offset: 0 }));
|
||||
expect((await screen.findAllByText('新告警车牌')).length).toBeGreaterThan(0);
|
||||
expect(await screen.findByText('new-event')).toBeInTheDocument();
|
||||
await waitFor(() => expect(screen.queryByText('正在更新事件…')).not.toBeInTheDocument());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user