feat(monitor): retain authorized vehicles without locations
This commit is contained in:
@@ -9,11 +9,13 @@ import { ROUTER_FUTURE } from '../routing/routerConfig';
|
||||
|
||||
const vehicles = [{
|
||||
vin: 'LTEST000000000001', plate: '粤A12345', protocols: ['JT808'], primaryProtocol: 'JT808',
|
||||
longitude: 113.26, latitude: 23.13, speedKmh: 42, socPercent: 80, totalMileageKm: 1234,
|
||||
locationAvailable: true, longitude: 113.26, latitude: 23.13, speedAvailable: true, speedKmh: 42,
|
||||
socAvailable: false, socPercent: 0, mileageAvailable: true, totalMileageKm: 1234, todayMileageAvailable: true, todayMileageKm: 18.6,
|
||||
lastSeen: '2026-07-14T01:00:00Z', online: true, sourceCount: 1, onlineSourceCount: 1
|
||||
}, {
|
||||
vin: 'LTEST000000000002', plate: '粤B67890', protocols: ['JT808'], primaryProtocol: 'JT808',
|
||||
longitude: 113.28, latitude: 23.15, speedKmh: 0, socPercent: 72, totalMileageKm: 2234,
|
||||
locationAvailable: true, longitude: 113.28, latitude: 23.15, speedAvailable: true, speedKmh: 0,
|
||||
socAvailable: false, socPercent: 0, mileageAvailable: true, totalMileageKm: 2234, todayMileageAvailable: false, todayMileageKm: 0,
|
||||
lastSeen: '2026-07-14T01:00:00Z', online: true, sourceCount: 1, onlineSourceCount: 1
|
||||
}] as VehicleRealtimeRow[];
|
||||
const monitorMap = { clusters: [], points: [], total: 2 };
|
||||
@@ -58,7 +60,7 @@ vi.mock('../hooks/useMonitorData', () => ({
|
||||
useMonitorData: (...args: unknown[]) => {
|
||||
monitorDataArgsSpy(...args);
|
||||
return {
|
||||
summary: { data: { totalVehicles: 2, onlineVehicles: 2, offlineVehicles: 0, drivingVehicles: 1, idleVehicles: 1, frameToday: 10 } },
|
||||
summary: { data: { totalVehicles: 2, locationVehicles: 2, noLocationVehicles: 0, onlineVehicles: 2, offlineVehicles: 0, drivingVehicles: 1, idleVehicles: 1, frameToday: 10 } },
|
||||
vehicles: { data: { items: vehicles, total: 2 }, isError: false, ...monitorQueryFlags },
|
||||
map: { data: monitorMap, isPlaceholderData: monitorQueryFlags.isPlaceholderData },
|
||||
selectedVehicle: { data: { items: [] } }
|
||||
@@ -95,7 +97,8 @@ test('starts without a selection and supports expand, collapse, reselection, and
|
||||
expect(firstVehicle).not.toHaveClass('is-selected');
|
||||
expect(screen.queryByRole('button', { name: '取消选择车辆' })).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId('fleet-map')).toHaveAttribute('data-selected-vin', '');
|
||||
expect(screen.getByText('有实时位置')).toBeInTheDocument();
|
||||
expect(screen.getByText('车辆总数')).toBeInTheDocument();
|
||||
expect(screen.getAllByText('无实时位置').length).toBeGreaterThanOrEqual(2);
|
||||
expect(screen.getByRole('status', { name: '搜索和筛选条件修改后自动生效' })).toHaveTextContent('实时筛选');
|
||||
expect(screen.queryByRole('button', { name: '筛选' })).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('接入车辆')).not.toBeInTheDocument();
|
||||
@@ -106,6 +109,7 @@ test('starts without a selection and supports expand, collapse, reselection, and
|
||||
expect(screen.getByRole('button', { name: '取消选择车辆' })).toBeInTheDocument();
|
||||
expect(screen.getByTestId('fleet-map')).toHaveAttribute('data-selected-vin', 'LTEST000000000001');
|
||||
expect(vehicleCardArgsSpy).toHaveBeenLastCalledWith('LTEST000000000001', vehicles[0], true);
|
||||
expect(screen.getByText('SOC').parentElement).toHaveTextContent('SOC—');
|
||||
const mapRendersAfterSelection = fleetMapRenderSpy.mock.calls.length;
|
||||
const cardCallsAfterSelection = vehicleCardArgsSpy.mock.calls.length;
|
||||
|
||||
@@ -140,15 +144,17 @@ test('switches to a lightweight realtime list and resolves addresses only on dem
|
||||
const view = render(<QueryClientProvider client={queryClient}><MemoryRouter future={ROUTER_FUTURE}><MonitorPage /></MemoryRouter></QueryClientProvider>);
|
||||
fireEvent.click(screen.getByRole('button', { name: /列表/ }));
|
||||
expect(await screen.findByText('车辆实时列表')).toBeInTheDocument();
|
||||
expect(screen.getByText('速度、里程和坐标实时刷新,文字地址按需解析')).toBeInTheDocument();
|
||||
expect(screen.getByText('覆盖全部授权车辆;实时字段缺失时显示“—”,文字地址按需解析')).toBeInTheDocument();
|
||||
expect(await screen.findAllByText('粤A12345')).toHaveLength(1);
|
||||
expect(screen.getAllByText('42')).toHaveLength(1);
|
||||
expect(screen.getAllByText(/1,234/)).toHaveLength(1);
|
||||
expect(screen.getAllByText(/18\.6/)).toHaveLength(1);
|
||||
expect(screen.getAllByText(/113\.260000/)).toHaveLength(1);
|
||||
expect(reverseGeocode).not.toHaveBeenCalled();
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: '解析粤A12345位置' }));
|
||||
expect(await screen.findByText('广东省广州市天河区测试路')).toBeInTheDocument();
|
||||
expect(screen.getByText(/解析于 \d{2}:\d{2}/)).toBeInTheDocument();
|
||||
expect(reverseGeocode).toHaveBeenCalledTimes(1);
|
||||
expect(queryClient.getQueryCache().findAll({ queryKey: ['monitor', 'list-address'] })).toHaveLength(1);
|
||||
expect(screen.queryByText('综合状态')).not.toBeInTheDocument();
|
||||
@@ -160,6 +166,41 @@ test('switches to a lightweight realtime list and resolves addresses only on dem
|
||||
view.unmount();
|
||||
});
|
||||
|
||||
test('keeps authorized vehicles without realtime coordinates in the list without geocoding them', async () => {
|
||||
const row = {
|
||||
...vehicles[0],
|
||||
vin: 'LNOLOCATION0000001',
|
||||
plate: '粤A无定位',
|
||||
protocols: [],
|
||||
primaryProtocol: '',
|
||||
locationAvailable: false,
|
||||
longitude: 0,
|
||||
latitude: 0,
|
||||
speedAvailable: false,
|
||||
speedKmh: 0,
|
||||
mileageAvailable: false,
|
||||
totalMileageKm: 0,
|
||||
todayMileageAvailable: false,
|
||||
todayMileageKm: 0,
|
||||
lastSeen: '',
|
||||
online: false,
|
||||
sourceCount: 0,
|
||||
onlineSourceCount: 0
|
||||
} satisfies VehicleRealtimeRow;
|
||||
vi.spyOn(api, 'vehicleRealtime').mockResolvedValue({ items: [row], total: 1, limit: 50, offset: 0 });
|
||||
const reverseGeocode = vi.spyOn(api, 'reverseGeocode');
|
||||
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
render(<QueryClientProvider client={queryClient}><MemoryRouter future={ROUTER_FUTURE}><MonitorPage /></MemoryRouter></QueryClientProvider>);
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /列表/ }));
|
||||
|
||||
expect(await screen.findByText('粤A无定位')).toBeInTheDocument();
|
||||
expect(screen.getByText('暂无实时位置')).toBeInTheDocument();
|
||||
expect(screen.getByText('从未上报')).toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: /解析粤A无定位位置/ })).not.toBeInTheDocument();
|
||||
expect(reverseGeocode).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('pauses selected-vehicle polling in list mode and resumes it when returning to the map', () => {
|
||||
vi.spyOn(api, 'vehicleRealtime').mockResolvedValue({ items: vehicles, total: 2, limit: 50, offset: 0 });
|
||||
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
||||
|
||||
Reference in New Issue
Block a user