diff --git a/vehicle-data-platform/apps/web/src/test/App.test.tsx b/vehicle-data-platform/apps/web/src/test/App.test.tsx
index 712730e1..1b6e74d3 100644
--- a/vehicle-data-platform/apps/web/src/test/App.test.tsx
+++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx
@@ -464,6 +464,173 @@ test('shows vehicle context when opening detail from shareable hash', async () =
expect(screen.getByText('当前车辆:部分来源离线')).toBeInTheDocument();
});
+test('refreshes vehicle context when hash changes to another detail vehicle', async () => {
+ window.history.replaceState(null, '', '/#/dashboard');
+ vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
+ const path = String(input);
+ if (path.includes('/api/vehicles/resolve')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: {
+ lookupKey: 'VIN002',
+ resolved: true,
+ vin: 'VIN002',
+ plate: '粤B20002',
+ phone: '',
+ oem: 'G7s',
+ protocols: ['JT808'],
+ online: false,
+ lastSeen: '2026-07-03 20:10:10',
+ serviceStatus: {
+ status: 'offline',
+ severity: 'error',
+ title: '车辆离线',
+ detail: '所有已知数据来源均未在线',
+ sourceCount: 1,
+ onlineSourceCount: 0
+ }
+ },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ if (path.includes('/api/dashboard/summary')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: { onlineVehicles: 3, activeToday: 4, frameToday: 1286320, issueVehicles: 7, kafkaLag: 0, protocols: [], serviceStatuses: [], linkHealth: [] },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ if (path.includes('/api/vehicle-service')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: {
+ vin: 'VIN002',
+ lookupKey: 'VIN002',
+ lookupResolved: true,
+ sources: ['JT808'],
+ sourceStatus: [],
+ realtime: [],
+ history: { items: [], total: 0, limit: 20, offset: 0 },
+ raw: { items: [], total: 0, limit: 10, offset: 0 },
+ mileage: { items: [], total: 0, limit: 20, offset: 0 },
+ quality: { items: [], total: 0, limit: 20, offset: 0 }
+ },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ return {
+ ok: true,
+ json: async () => ({
+ data: path.includes('/api/ops/health')
+ ? { linkHealth: [], kafkaLag: 0, redisOnlineKeys: 0, tdengineWritable: true, mysqlWritable: true, runtime: { requestTimeoutMs: 5000 } }
+ : { items: [], total: 0, limit: 10, offset: 0 },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ });
+
+ render();
+
+ window.history.pushState(null, '', '/#/detail?keyword=VIN002');
+ window.dispatchEvent(new HashChangeEvent('hashchange'));
+
+ expect(await screen.findByText('粤B20002 / VIN002')).toBeInTheDocument();
+ expect(screen.getByText('当前车辆:车辆离线')).toBeInTheDocument();
+});
+
+test('shows vehicle context when opening detail from sidebar navigation', async () => {
+ window.history.replaceState(null, '', '/#/dashboard');
+ vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => {
+ const path = String(input);
+ if (path.includes('/api/vehicles/resolve')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: {
+ lookupKey: 'LB9A32A24R0LS1426',
+ resolved: true,
+ vin: 'LB9A32A24R0LS1426',
+ plate: '粤AGQ8398',
+ phone: '',
+ oem: 'G7s',
+ protocols: ['JT808'],
+ online: false,
+ lastSeen: '2026-07-03 20:10:10',
+ serviceStatus: {
+ status: 'offline',
+ severity: 'error',
+ title: '车辆离线',
+ detail: '所有已知数据来源均未在线',
+ sourceCount: 1,
+ onlineSourceCount: 0
+ }
+ },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ if (path.includes('/api/dashboard/summary')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: { onlineVehicles: 3, activeToday: 4, frameToday: 1286320, issueVehicles: 7, kafkaLag: 0, protocols: [], serviceStatuses: [], linkHealth: [] },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ if (path.includes('/api/vehicle-service')) {
+ return {
+ ok: true,
+ json: async () => ({
+ data: {
+ vin: 'LB9A32A24R0LS1426',
+ lookupKey: 'LB9A32A24R0LS1426',
+ lookupResolved: true,
+ sources: ['JT808'],
+ sourceStatus: [],
+ realtime: [],
+ history: { items: [], total: 0, limit: 20, offset: 0 },
+ raw: { items: [], total: 0, limit: 10, offset: 0 },
+ mileage: { items: [], total: 0, limit: 20, offset: 0 },
+ quality: { items: [], total: 0, limit: 20, offset: 0 }
+ },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ }
+ return {
+ ok: true,
+ json: async () => ({
+ data: path.includes('/api/ops/health')
+ ? { linkHealth: [], kafkaLag: 0, redisOnlineKeys: 0, tdengineWritable: true, mysqlWritable: true, runtime: { requestTimeoutMs: 5000 } }
+ : { items: [], total: 0, limit: 10, offset: 0 },
+ traceId: 'trace-test',
+ timestamp: 1783094400000
+ })
+ } as Response;
+ });
+
+ render();
+
+ fireEvent.click(screen.getAllByText('车辆详情')[0]);
+
+ expect(await screen.findByText('粤AGQ8398 / LB9A32A24R0LS1426')).toBeInTheDocument();
+ expect(screen.getByText('当前车辆:车辆离线')).toBeInTheDocument();
+});
+
test('applies protocol from shareable history hash to API requests', async () => {
window.history.replaceState(null, '', '/#/history?keyword=%E7%B2%A4AG18312&protocol=JT808');
const fetchMock = vi.spyOn(globalThis, 'fetch').mockImplementation(async (input, init) => {