| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- import { describe, it, expect, vi, beforeEach } from 'vitest'
- import { mount, flushPromises } from '@vue/test-utils'
- import { createPinia, setActivePinia } from 'pinia'
- import { createI18n } from 'vue-i18n'
- import DashboardView from '@/views/dashboard/index.vue'
- import { wrapResponse, mockDashboardStats } from '../../../fixtures'
- // Mock vue-router
- const mockPush = vi.fn()
- vi.mock('vue-router', () => ({
- useRouter: () => ({ push: mockPush }),
- useRoute: () => ({ query: {} })
- }))
- // Mock element-plus
- vi.mock('element-plus', () => ({
- ElMessage: {
- success: vi.fn(),
- error: vi.fn(),
- info: vi.fn()
- }
- }))
- // Mock __APP_VERSION__
- vi.stubGlobal('__APP_VERSION__', '1.0.0')
- // Mock stats API
- const mockGetDashboardStats = vi.fn()
- vi.mock('@/api/stats', () => ({
- getDashboardStats: () => mockGetDashboardStats()
- }))
- // Create i18n instance
- const i18n = createI18n({
- legacy: false,
- locale: 'zh-CN',
- messages: {
- 'zh-CN': {
- 仪表盘: '仪表盘',
- '欢迎回来,这是您的数据概览': '欢迎回来,这是您的数据概览',
- 机器总数: '机器总数',
- 已启用: '已启用',
- 已禁用: '已禁用',
- 摄像头总数: '摄像头总数',
- 在线: '在线',
- 离线: '离线',
- 通道总数: '通道总数',
- 可用通道数量: '可用通道数量',
- 摄像头在线率: '摄像头在线率',
- 系统运行正常: '系统运行正常',
- 快捷操作: '快捷操作',
- 刷新数据: '刷新数据',
- 摄像头管理: '摄像头管理',
- 机器管理: '机器管理',
- 'Stream 测试': 'Stream 测试',
- 观看统计: '观看统计',
- 系统信息: '系统信息',
- 系统状态: '系统状态',
- 正常: '正常',
- 数据更新时间: '数据更新时间',
- 版本: '版本',
- 获取统计数据失败: '获取统计数据失败'
- }
- }
- })
- describe('Dashboard View', () => {
- beforeEach(() => {
- setActivePinia(createPinia())
- vi.clearAllMocks()
- mockGetDashboardStats.mockResolvedValue(wrapResponse(mockDashboardStats))
- mockPush.mockClear()
- })
- const mountDashboard = () => {
- return mount(DashboardView, {
- global: {
- plugins: [createPinia(), i18n]
- }
- })
- }
- describe('页面渲染', () => {
- it('应该正确渲染仪表盘页面', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.find('.dashboard').exists()).toBe(true)
- expect(wrapper.find('.dashboard__header').exists()).toBe(true)
- expect(wrapper.find('.dashboard__title').exists()).toBe(true)
- })
- it('应该显示页面标题', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.find('.dashboard__title').text()).toBe('仪表盘')
- })
- it('应该显示统计卡片', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.find('.dashboard__stats').exists()).toBe(true)
- expect(wrapper.findAll('.dashboard__card').length).toBe(4)
- })
- it('应该显示快捷操作按钮', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.find('.dashboard__actions').exists()).toBe(true)
- expect(wrapper.findAll('.dashboard__action').length).toBeGreaterThan(0)
- })
- it('应该显示系统信息', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.find('.dashboard__info').exists()).toBe(true)
- })
- })
- describe('数据加载', () => {
- it('页面加载时应该调用获取统计数据 API', async () => {
- mountDashboard()
- await flushPromises()
- expect(mockGetDashboardStats).toHaveBeenCalled()
- })
- it('应该正确显示机器总数', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const cards = wrapper.findAll('.dashboard__card')
- const machineCard = cards[0]
- expect(machineCard.find('.dashboard__card-value').text()).toBe(String(mockDashboardStats.machineTotal))
- })
- it('应该正确显示摄像头总数', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const cards = wrapper.findAll('.dashboard__card')
- const cameraCard = cards[1]
- expect(cameraCard.find('.dashboard__card-value').text()).toBe(String(mockDashboardStats.cameraTotal))
- })
- it('应该正确显示通道总数', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const cards = wrapper.findAll('.dashboard__card')
- const channelCard = cards[2]
- expect(channelCard.find('.dashboard__card-value').text()).toBe(String(mockDashboardStats.channelTotal))
- })
- it('应该正确计算并显示在线率', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const expectedRate = Math.round((mockDashboardStats.cameraOnline / mockDashboardStats.cameraTotal) * 100)
- const cards = wrapper.findAll('.dashboard__card')
- const rateCard = cards[3]
- expect(rateCard.find('.dashboard__card-value').text()).toContain(String(expectedRate))
- })
- })
- describe('快捷操作导航', () => {
- it('点击摄像头管理应该跳转', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const actions = wrapper.findAll('.dashboard__action')
- const cameraAction = actions.find((a) => a.text().includes('摄像头管理'))
- if (cameraAction) {
- await cameraAction.trigger('click')
- expect(mockPush).toHaveBeenCalledWith('/camera')
- }
- })
- it('点击机器管理应该跳转', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const actions = wrapper.findAll('.dashboard__action')
- const machineAction = actions.find((a) => a.text().includes('机器管理'))
- if (machineAction) {
- await machineAction.trigger('click')
- expect(mockPush).toHaveBeenCalledWith('/machine')
- }
- })
- it('点击 Stream 测试应该跳转', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const actions = wrapper.findAll('.dashboard__action')
- const streamAction = actions.find((a) => a.text().includes('Stream 测试'))
- if (streamAction) {
- await streamAction.trigger('click')
- expect(mockPush).toHaveBeenCalledWith('/stream-test')
- }
- })
- it('点击观看统计应该跳转', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const actions = wrapper.findAll('.dashboard__action')
- const statsAction = actions.find((a) => a.text().includes('观看统计'))
- if (statsAction) {
- await statsAction.trigger('click')
- expect(mockPush).toHaveBeenCalledWith('/stats')
- }
- })
- })
- describe('刷新数据', () => {
- it('点击刷新按钮应该重新加载数据', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- mockGetDashboardStats.mockClear()
- const refreshBtn = wrapper.find('.dashboard__refresh')
- await refreshBtn.trigger('click')
- await flushPromises()
- expect(mockGetDashboardStats).toHaveBeenCalled()
- })
- it('刷新时应该显示加载状态', async () => {
- let resolvePromise: Function
- mockGetDashboardStats.mockImplementation(
- () =>
- new Promise((resolve) => {
- resolvePromise = resolve
- })
- )
- const wrapper = mountDashboard()
- await flushPromises()
- mockGetDashboardStats.mockClear()
- mockGetDashboardStats.mockImplementation(
- () =>
- new Promise((resolve) => {
- resolvePromise = () => resolve(wrapResponse(mockDashboardStats))
- })
- )
- const refreshBtn = wrapper.find('.dashboard__refresh')
- await refreshBtn.trigger('click')
- // 检查加载状态图标
- expect(wrapper.find('.dashboard__refresh-icon').exists()).toBe(true)
- resolvePromise!()
- await flushPromises()
- })
- })
- describe('错误处理', () => {
- it('获取数据失败应该显示错误消息', async () => {
- const { ElMessage } = await import('element-plus')
- mockGetDashboardStats.mockResolvedValue(wrapResponse(null, 500, '服务器错误'))
- mountDashboard()
- await flushPromises()
- // 错误处理逻辑测试
- expect(mockGetDashboardStats).toHaveBeenCalled()
- })
- it('网络错误应该显示错误消息', async () => {
- mockGetDashboardStats.mockResolvedValue(wrapResponse(null, 500, '网络错误'))
- mountDashboard()
- await flushPromises()
- expect(mockGetDashboardStats).toHaveBeenCalled()
- })
- })
- describe('系统信息', () => {
- it('应该显示系统状态为正常', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.find('.dashboard__badge--success').text()).toBe('正常')
- })
- it('应该显示版本号', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- expect(wrapper.text()).toContain('v1.0.0')
- })
- it('数据更新后应该显示更新时间', async () => {
- const wrapper = mountDashboard()
- await flushPromises()
- const infoItems = wrapper.findAll('.dashboard__info-item')
- const updateTimeItem = infoItems.find((item) => item.text().includes('数据更新时间'))
- expect(updateTimeItem).toBeDefined()
- })
- })
- describe('空数据处理', () => {
- it('无数据时应该显示默认值', async () => {
- mockGetDashboardStats.mockResolvedValue(wrapResponse(null))
- const wrapper = mountDashboard()
- await flushPromises()
- const cards = wrapper.findAll('.dashboard__card')
- // 默认值为 0
- expect(cards[0].find('.dashboard__card-value').text()).toBe('0')
- })
- it('在线率为零时应该显示 0%', async () => {
- mockGetDashboardStats.mockResolvedValue(
- wrapResponse({
- ...mockDashboardStats,
- cameraTotal: 0,
- cameraOnline: 0
- })
- )
- const wrapper = mountDashboard()
- await flushPromises()
- const cards = wrapper.findAll('.dashboard__card')
- const rateCard = cards[3]
- expect(rateCard.find('.dashboard__card-value').text()).toContain('0')
- })
- })
- })
|