import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import { describe, expect, it } from 'vitest'; import { normalizeDashboard } from '../src/api/dashboard'; describe('pAGE-24 dashboard contracts', () => { const pageSource = readFileSync(resolve(process.cwd(), 'src/pages/overview/DashboardPage.vue'), 'utf8'); const chartSource = readFileSync(resolve(process.cwd(), 'src/pages/overview/components/DashboardChart.vue'), 'utf8'); it('normalizes incomplete server data without creating fake business values', () => { const view = normalizeDashboard({ system: { services: null } as any, metrics: null, trend: { points: null } as any, lifecycle: undefined, risks: null, geography: { available: false, regions: null } as any, activities: undefined, } as unknown as Partial>); expect(view.metrics).toEqual([]); expect(view.trend.points).toEqual([]); expect(view.lifecycle).toEqual([]); expect(view.risks).toEqual([]); expect(view.activities).toEqual([]); expect(view.geography.available).toBe(false); expect(view.geography.regions).toEqual([]); }); it('defines the hybrid cockpit and explicit permission-safe geography fallback', () => { expect(pageSource).toContain('data-scene'); expect(pageSource).toContain('进入大屏'); expect(pageSource).toContain('退出大屏'); expect(pageSource).toContain('dashboard.geography.available'); expect(pageSource).toContain('补齐项目省、市编码后,将自动启用地图'); expect(pageSource).toContain('当前身份没有查看仪表盘或相关业务数据的权限'); expect(pageSource).toContain('onActivated(activateDashboard)'); expect(pageSource).toContain('onDeactivated(deactivateDashboard)'); expect(pageSource).toContain('dashboardAbortController?.abort()'); expect(pageSource).toContain('setInterval(() => void loadDashboard(true), 60000)'); expect(pageSource).not.toMatch(/ { expect(chartSource).toContain("from 'echarts/core'"); expect(chartSource).toContain('ResizeObserver'); expect(chartSource).toContain('chart.dispose()'); expect(chartSource).toContain('aria-label="label"'); }); });