Files
lingniu-vehicle-ingest/vehicle-data-platform/apps/web/src/v2/routing/routeModules.test.ts
2026-07-16 03:39:47 +08:00

104 lines
4.4 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import {
routePreloadBudget,
routePreloadCandidates,
routeSectionForPath,
scheduleIdleRoutePreloads,
shouldPreloadRouteOnIntent,
shouldPreloadRoutes
} from './routeModules';
describe('route module preloading', () => {
async function flushPreloadQueue() {
for (let index = 0; index < 6; index += 1) await Promise.resolve();
}
it('maps nested and parameterized URLs to the correct lazy module', () => {
expect(routeSectionForPath('/monitor')).toBe('monitor');
expect(routeSectionForPath('/vehicles/LTEST001?tab=telemetry')).toBe('vehicles');
expect(routeSectionForPath('/alerts/rules#editor')).toBe('alerts');
expect(routeSectionForPath('/not-a-platform-route')).toBeUndefined();
});
it('skips background route preloads on save-data and 2G connections', () => {
const visible = { visibilityState: 'visible' as const, deviceMemory: 8 };
expect(shouldPreloadRoutes({ saveData: true, effectiveType: '4g' }, visible)).toBe(false);
expect(shouldPreloadRoutes({ effectiveType: 'slow-2g' }, visible)).toBe(false);
expect(shouldPreloadRoutes({ effectiveType: '2g' }, visible)).toBe(false);
expect(shouldPreloadRoutes({ effectiveType: '3g' }, visible)).toBe(true);
expect(shouldPreloadRoutes({ effectiveType: '4g' }, visible)).toBe(true);
expect(shouldPreloadRoutes({ effectiveType: '4g' }, { ...visible, visibilityState: 'hidden' })).toBe(false);
expect(shouldPreloadRouteOnIntent({ saveData: true, effectiveType: '4g' })).toBe(false);
expect(shouldPreloadRouteOnIntent({ effectiveType: '2g' })).toBe(false);
});
it('limits speculative modules by memory/network budget and route likelihood', () => {
const visible = { visibilityState: 'visible' as const };
expect(routePreloadBudget({ effectiveType: '4g' }, { ...visible, deviceMemory: 8 })).toBe(2);
expect(routePreloadBudget({ effectiveType: '3g' }, { ...visible, deviceMemory: 8 })).toBe(1);
expect(routePreloadBudget({ effectiveType: '4g' }, { ...visible, deviceMemory: 4 })).toBe(1);
expect(routePreloadBudget({ effectiveType: '4g' }, { ...visible, deviceMemory: 2 })).toBe(0);
expect(routePreloadCandidates('/monitor')).toEqual(['vehicles', 'tracks']);
expect(routePreloadCandidates('/statistics?dateFrom=2026-07-01')).toEqual(['history', 'vehicles']);
});
it('warms only likely routes in sequential idle slots and stops after cleanup', async () => {
const callbacks: Array<() => void> = [];
const cancelled: number[] = [];
const schedule = vi.fn((callback: () => void) => {
const index = callbacks.push(callback) - 1;
return () => { cancelled.push(index); };
});
const preload = vi.fn(async (_pathname: string) => undefined);
const cleanup = scheduleIdleRoutePreloads({
activePathname: '/monitor',
connection: { effectiveType: '4g' },
runtime: { visibilityState: 'visible', deviceMemory: 8 },
preload,
schedule,
isVisible: () => true
});
expect(schedule).toHaveBeenCalledTimes(1);
callbacks[0]();
await flushPreloadQueue();
expect(preload.mock.calls.map(([path]) => path)).toEqual(['/vehicles']);
expect(schedule).toHaveBeenCalledTimes(2);
callbacks[1]();
await flushPreloadQueue();
expect(preload.mock.calls.map(([path]) => path)).toEqual(['/vehicles', '/tracks']);
expect(schedule).toHaveBeenCalledTimes(2);
cleanup();
expect(cancelled).toContain(1);
});
it('does not start or continue speculative work in a background tab', async () => {
const schedule = vi.fn((_callback: () => void) => () => undefined);
scheduleIdleRoutePreloads({
activePathname: '/monitor',
connection: { effectiveType: '4g' },
runtime: { visibilityState: 'hidden', deviceMemory: 8 },
schedule
});
expect(schedule).not.toHaveBeenCalled();
const callbacks: Array<() => void> = [];
const preload = vi.fn(async () => undefined);
let visible = true;
scheduleIdleRoutePreloads({
activePathname: '/monitor',
connection: { effectiveType: '4g' },
runtime: { visibilityState: 'visible', deviceMemory: 8 },
preload,
schedule: (callback) => { callbacks.push(callback); return () => undefined; },
isVisible: () => visible
});
visible = false;
callbacks[0]();
await flushPreloadQueue();
expect(preload).not.toHaveBeenCalled();
});
});