{(sourceReadiness?.sources ?? []).map((item) => (
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 120319f9..85dab955 100644
--- a/vehicle-data-platform/apps/web/src/test/App.test.tsx
+++ b/vehicle-data-platform/apps/web/src/test/App.test.tsx
@@ -174,146 +174,6 @@ test('exposes AMap operations shortcuts when map key is configured', async () =>
})
} as Response;
}
- if (path.includes('/api/ops/source-readiness')) {
- return {
- ok: true,
- json: async () => ({
- data: {
- totalVehicles: 1033,
- onlineVehicles: 208,
- kafkaLag: 0,
- activeConnections: 1234,
- redisOnlineKeys: 368,
- platformRelease: 'platform-dashboard-test',
- sources: [
- {
- protocol: 'GB32960',
- role: '整车与氢能实时数据主来源',
- online: 73,
- total: 340,
- onlineRate: 21.47,
- missingVehicles: 693,
- severity: 'warning',
- status: '覆盖不足',
- evidence: '在线 73/340,缺失车辆 693,Kafka Lag 0',
- action: '核对现代和交投平台转发清单。',
- acceptance: '缺失来源车辆下降,单源车辆可解释。',
- vehiclesHash: '#/vehicles?protocol=GB32960&missingProtocol=GB32960',
- realtimeHash: '#/realtime?protocol=GB32960&online=online',
- historyHash: '#/history-query?protocol=GB32960&tab=raw&includeFields=true',
- alertHash: '#/alert-events?protocol=GB32960'
- },
- {
- protocol: 'JT808',
- role: '位置、总里程和设备在线主来源',
- online: 174,
- total: 424,
- onlineRate: 41.04,
- missingVehicles: 609,
- severity: 'warning',
- status: '覆盖不足',
- evidence: '在线 174/424,缺失车辆 609,Kafka Lag 0',
- action: '补齐手机号绑定和注册缺失车辆。',
- acceptance: '未知 VIN 注册下降,位置与里程持续可查。',
- vehiclesHash: '#/vehicles?protocol=JT808&missingProtocol=JT808',
- realtimeHash: '#/realtime?protocol=JT808&online=online',
- historyHash: '#/history-query?protocol=JT808&tab=raw&includeFields=true',
- alertHash: '#/alert-events?protocol=JT808'
- },
- {
- protocol: 'YUTONG_MQTT',
- role: '宇通派生工况与燃料电池补充来源',
- online: 11,
- total: 50,
- onlineRate: 22,
- missingVehicles: 983,
- severity: 'ok',
- status: '生产可用',
- evidence: '在线 11/50,缺失车辆 983,Kafka Lag 0',
- action: '保持实时、轨迹、RAW 和统计链路巡检。',
- acceptance: '车辆服务可回查实时、轨迹和 RAW 证据。',
- vehiclesHash: '#/vehicles?protocol=YUTONG_MQTT&missingProtocol=YUTONG_MQTT',
- realtimeHash: '#/realtime?protocol=YUTONG_MQTT&online=online',
- historyHash: '#/history-query?protocol=YUTONG_MQTT&tab=raw&includeFields=true',
- alertHash: '#/alert-events?protocol=YUTONG_MQTT'
- }
- ]
- },
- traceId: 'trace-test',
- timestamp: 1783094400000
- })
- } as Response;
- }
- if (path.includes('/api/ops/source-readiness')) {
- return {
- ok: true,
- json: async () => ({
- data: {
- totalVehicles: 1033,
- onlineVehicles: 208,
- kafkaLag: 0,
- activeConnections: 1234,
- redisOnlineKeys: 368,
- platformRelease: 'platform-dashboard-test',
- sources: [
- {
- protocol: 'GB32960',
- role: '整车与氢能实时数据主来源',
- online: 73,
- total: 340,
- onlineRate: 21.47,
- missingVehicles: 693,
- severity: 'warning',
- status: '覆盖不足',
- evidence: '在线 73/340,缺失车辆 693,Kafka Lag 0',
- action: '核对现代和交投平台转发清单。',
- acceptance: '缺失来源车辆下降,单源车辆可解释。',
- vehiclesHash: '#/vehicles?protocol=GB32960&missingProtocol=GB32960',
- realtimeHash: '#/realtime?protocol=GB32960&online=online',
- historyHash: '#/history-query?protocol=GB32960&tab=raw&includeFields=true',
- alertHash: '#/alert-events?protocol=GB32960'
- },
- {
- protocol: 'JT808',
- role: '位置、总里程和设备在线主来源',
- online: 174,
- total: 424,
- onlineRate: 41.04,
- missingVehicles: 609,
- severity: 'warning',
- status: '覆盖不足',
- evidence: '在线 174/424,缺失车辆 609,Kafka Lag 0',
- action: '补齐手机号绑定和注册缺失车辆。',
- acceptance: '未知 VIN 注册下降,位置与里程持续可查。',
- vehiclesHash: '#/vehicles?protocol=JT808&missingProtocol=JT808',
- realtimeHash: '#/realtime?protocol=JT808&online=online',
- historyHash: '#/history-query?protocol=JT808&tab=raw&includeFields=true',
- alertHash: '#/alert-events?protocol=JT808'
- },
- {
- protocol: 'YUTONG_MQTT',
- role: '宇通派生工况与燃料电池补充来源',
- online: 11,
- total: 50,
- onlineRate: 22,
- missingVehicles: 983,
- severity: 'ok',
- status: '生产可用',
- evidence: '在线 11/50,缺失车辆 983,Kafka Lag 0',
- action: '保持实时、轨迹、RAW 和统计链路巡检。',
- acceptance: '车辆服务可回查实时、轨迹和 RAW 证据。',
- vehiclesHash: '#/vehicles?protocol=YUTONG_MQTT&missingProtocol=YUTONG_MQTT',
- realtimeHash: '#/realtime?protocol=YUTONG_MQTT&online=online',
- historyHash: '#/history-query?protocol=YUTONG_MQTT&tab=raw&includeFields=true',
- alertHash: '#/alert-events?protocol=YUTONG_MQTT'
- }
- ]
- },
- traceId: 'trace-test',
- timestamp: 1783094400000
- })
- } as Response;
- }
return {
ok: true,
json: async () => ({
@@ -983,6 +843,10 @@ test('dashboard exposes vehicle data center capability matrix', async () => {
fireEvent.click(screen.getByRole('button', { name: '复制流转图' }));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【车辆数据中台数据流转图】'));
expect(writeText).toHaveBeenCalledWith(expect.stringContaining('03. 实时投影 / Redis KV'));
+ fireEvent.click(screen.getByRole('button', { name: '复制接入交接' }));
+ expect(writeText).toHaveBeenCalledWith(expect.stringContaining('【三源接入到车辆服务交接摘要】'));
+ expect(writeText).toHaveBeenCalledWith(expect.stringContaining('1. GB32960 - 覆盖不足'));
+ expect(writeText).toHaveBeenCalledWith(expect.stringContaining('RAW:http://localhost:3000/#/history-query?protocol=GB32960&tab=raw&includeFields=true'));
fireEvent.click(screen.getAllByRole('button', { name: '实时' })[0]);
expect(window.location.hash).toBe('#/realtime?protocol=GB32960&online=online');