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')
})
})
})