import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import StatsView from '@/views/stats/index.vue' import { wrapResponse, mockDashboardStats } from '../../../fixtures' // Mock element-plus vi.mock('element-plus', () => ({ ElMessage: { success: vi.fn(), error: vi.fn(), info: vi.fn() } })) // Mock stats API const mockGetDashboardStats = vi.fn() vi.mock('@/api/stats', () => ({ getDashboardStats: () => mockGetDashboardStats() })) describe('Stats View', () => { beforeEach(() => { setActivePinia(createPinia()) vi.clearAllMocks() mockGetDashboardStats.mockResolvedValue(wrapResponse(mockDashboardStats)) }) const mountStats = () => { return mount(StatsView, { global: { plugins: [createPinia()], stubs: { 'el-card': { template: '
', props: ['shadow'] }, 'el-form': { template: '
' }, 'el-form-item': { template: '
', props: ['label'] }, 'el-button': { template: '', props: ['type', 'icon', 'loading'] }, 'el-row': { template: '
', props: ['gutter'] }, 'el-col': { template: '
', props: ['xs', 'sm', 'lg'] }, 'el-statistic': { template: '
{{ title }}{{ value }}
', props: ['title', 'value', 'suffix'] }, 'el-icon': { template: '' }, 'el-empty': { template: '
{{ description }}
', props: ['description'] }, Monitor: { template: 'Monitor' }, VideoCamera: { template: 'VideoCamera' }, Connection: { template: 'Connection' }, CircleCheck: { template: 'CircleCheck' }, TrendCharts: { template: 'TrendCharts' }, Refresh: { template: 'Refresh' } } } }) } describe('页面渲染', () => { it('应该正确渲染统计页面', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.page-container').exists()).toBe(true) }) it('应该显示刷新按钮', async () => { const wrapper = mountStats() await flushPromises() const refreshBtn = wrapper.find('.filter-card button') expect(refreshBtn.exists()).toBe(true) expect(refreshBtn.text()).toContain('刷新') }) it('应该显示统计卡片', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.summary-cards').exists()).toBe(true) }) it('应该显示状态图表区域', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.status-card').exists()).toBe(true) }) }) describe('数据加载', () => { it('页面加载时应该获取统计数据', async () => { mountStats() await flushPromises() expect(mockGetDashboardStats).toHaveBeenCalled() }) it('应该正确显示机器总数', async () => { const wrapper = mountStats() await flushPromises() const stats = wrapper.findAll('.el-statistic') expect(stats.length).toBeGreaterThan(0) }) it('应该正确显示摄像头总数', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.html()).toContain(String(mockDashboardStats.cameraTotal)) }) it('应该正确显示通道总数', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.html()).toContain(String(mockDashboardStats.channelTotal)) }) it('应该正确计算在线率', async () => { const wrapper = mountStats() await flushPromises() const expectedRate = Math.round((mockDashboardStats.cameraOnline / mockDashboardStats.cameraTotal) * 100) expect(wrapper.html()).toContain(String(expectedRate)) }) }) describe('刷新功能', () => { it('点击刷新按钮应该重新加载数据', async () => { const wrapper = mountStats() await flushPromises() mockGetDashboardStats.mockClear() const refreshBtn = wrapper.find('.filter-card button') await refreshBtn.trigger('click') await flushPromises() expect(mockGetDashboardStats).toHaveBeenCalled() }) }) describe('状态条显示', () => { it('应该显示在线状态条', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.status-item.online').exists()).toBe(true) }) it('应该显示离线状态条', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.status-item.offline').exists()).toBe(true) }) it('应该显示已启用状态条', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.status-item.enabled').exists()).toBe(true) }) it('应该显示已禁用状态条', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.status-item.disabled').exists()).toBe(true) }) }) describe('更新时间显示', () => { it('数据加载后应该显示更新时间', async () => { const wrapper = mountStats() await flushPromises() expect(wrapper.find('.update-time').exists()).toBe(true) }) }) describe('错误处理', () => { it('API 返回错误码应该正确处理', async () => { mockGetDashboardStats.mockResolvedValue(wrapResponse(null, false, '服务器错误')) mountStats() await flushPromises() expect(mockGetDashboardStats).toHaveBeenCalled() }) it('API 返回空数据应该正确处理', async () => { mockGetDashboardStats.mockResolvedValue(wrapResponse(null)) mountStats() await flushPromises() expect(mockGetDashboardStats).toHaveBeenCalled() }) }) describe('空数据处理', () => { it('无数据时在线率应该为 0', async () => { mockGetDashboardStats.mockResolvedValue( wrapResponse({ machineTotal: 0, machineEnabled: 0, cameraTotal: 0, cameraOnline: 0, cameraOffline: 0, channelTotal: 0 }) ) const wrapper = mountStats() await flushPromises() expect(wrapper.html()).toContain('0') }) }) })