import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import test from 'node:test' import { fileURLToPath } from 'node:url' import { normalizeDigitalEmployeeDashboardPayload } from '../src/services/analytics.js' const topBar = readFileSync( fileURLToPath(new URL('../src/components/layout/TopBar.vue', import.meta.url)), 'utf8' ) const overviewView = readFileSync( fileURLToPath(new URL('../src/views/OverviewView.vue', import.meta.url)), 'utf8' ) const overviewViewModel = readFileSync( fileURLToPath(new URL('../src/composables/useOverviewView.js', import.meta.url)), 'utf8' ) const analyticsService = readFileSync( fileURLToPath(new URL('../src/services/analytics.js', import.meta.url)), 'utf8' ) const dashboardComponent = readFileSync( fileURLToPath(new URL('../src/components/dashboard/DigitalEmployeeDashboard.vue', import.meta.url)), 'utf8' ) const dailyChartComponent = readFileSync( fileURLToPath(new URL('../src/components/charts/DigitalEmployeeDailyWorkChart.vue', import.meta.url)), 'utf8' ) const dashboardModel = readFileSync( fileURLToPath(new URL('../src/views/scripts/overviewDigitalEmployeeDashboardModel.js', import.meta.url)), 'utf8' ) test('digital employee dashboard normalizes backend payload fields', () => { const dashboard = normalizeDigitalEmployeeDashboardPayload({ window_days: 7, generated_at: '2026-06-01T08:00:00Z', has_real_data: true, totals: { totalRuns: 3, successRuns: 2, failedRuns: 1, businessOutputs: 8 }, daily_work: [{ date: '06-01', total: 3, businessOutputs: 8 }], task_distribution: [{ name: '知识制度整理', count: 2 }], category_distribution: [{ name: '整理', count: 2 }], recent_runs: [{ runId: 'run-001', taskLabel: '知识制度整理' }] }) assert.equal(dashboard.windowDays, 7) assert.equal(dashboard.generatedAt, '2026-06-01T08:00:00Z') assert.equal(dashboard.hasRealData, true) assert.equal(dashboard.totals.totalRuns, 3) assert.equal(dashboard.dailyWork[0].businessOutputs, 8) assert.equal(dashboard.taskDistribution[0].name, '知识制度整理') assert.equal(dashboard.categoryDistribution[0].name, '整理') assert.equal(dashboard.recentRuns[0].runId, 'run-001') }) test('digital employee dashboard is wired into overview dashboard switch', () => { assert.match(topBar, /label: '数字员工看板', value: 'digitalEmployee'/) assert.match(overviewView, / { assert.match(dashboardComponent, /每日工作趋势/) assert.match(dashboardComponent, /每日工作摘要/) assert.match(dashboardComponent, /技能类型分布/) assert.match(dashboardComponent, /工作模块排行/) assert.match(dashboardComponent, /最近工作记录/) assert.match(dashboardComponent, /DigitalEmployeeDailyWorkChart/) assert.match(dashboardComponent, /DonutChart/) assert.match(dashboardComponent, /BarChart/) assert.match(dailyChartComponent, /echarts\/charts/) assert.match(dailyChartComponent, /name: '工作次数'/) assert.match(dailyChartComponent, /name: '业务产出'/) assert.doesNotMatch(dashboardComponent, /hermes/i) }) test('digital employee dashboard uses filled card layout for charts and rows', () => { assert.match(dashboardComponent, /digital-chart-fill digital-trend-fill/) assert.match(dashboardComponent, /digital-chart-fill digital-donut-fill/) assert.match(dashboardComponent, /digital-chart-fill digital-bar-fill/) assert.match(dashboardComponent, /digital-output-grid digital-card-fill/) assert.match(dashboardComponent, /grid-auto-rows: minmax\(300px, auto\)/) assert.match(dashboardComponent, /\.digital-work-trend-panel \{\s*grid-column: span 7/s) assert.match(dashboardComponent, /\.digital-work-day-panel \{\s*grid-column: span 5/s) assert.match(dashboardComponent, /\.digital-recent-panel \{\s*grid-column: span 12/s) assert.match(dailyChartComponent, /height: 100%/) assert.match(dailyChartComponent, /min-height: 280px/) })