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 CameraView from '@/views/camera/index.vue' import { wrapResponse, wrapPageResponse, wrapArrayResponse, mockCameras, mockMachines } 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(), warning: vi.fn() }, ElMessageBox: { confirm: vi.fn().mockResolvedValue(true) } })) // Mock camera API const mockAdminListCameras = vi.fn() const mockAdminAddCamera = vi.fn() const mockAdminUpdateCamera = vi.fn() const mockAdminDeleteCamera = vi.fn() const mockAdminCheckCamera = vi.fn() vi.mock('@/api/camera', () => ({ adminListCameras: (...args: any[]) => mockAdminListCameras(...args), adminAddCamera: (...args: any[]) => mockAdminAddCamera(...args), adminUpdateCamera: (...args: any[]) => mockAdminUpdateCamera(...args), adminDeleteCamera: (...args: any[]) => mockAdminDeleteCamera(...args), adminCheckCamera: (...args: any[]) => mockAdminCheckCamera(...args) })) // Mock machine API const mockListAllMachines = vi.fn() vi.mock('@/api/machine', () => ({ listAllMachines: () => mockListAllMachines() })) // Create i18n instance const i18n = createI18n({ legacy: false, locale: 'zh-CN', messages: { 'zh-CN': { 摄像头管理: '摄像头管理', 新增摄像头: '新增摄像头', 刷新列表: '刷新列表', 搜索: '搜索', 重置: '重置', 编辑: '编辑', 删除: '删除', 检测: '检测', 查看通道: '查看通道', 确认删除: '确认删除', 在线: '在线', 离线: '离线', 全部: '全部', 状态: '状态', 机器: '机器', 摄像头ID: '摄像头ID', 名称: '名称', 品牌: '品牌', IP地址: 'IP地址', 端口: '端口', 操作: '操作', 取消: '取消', 确定: '确定' } } }) describe('Camera View', () => { beforeEach(() => { setActivePinia(createPinia()) vi.clearAllMocks() mockAdminListCameras.mockResolvedValue(wrapPageResponse(mockCameras)) mockListAllMachines.mockResolvedValue(wrapArrayResponse(mockMachines)) }) const mountCamera = () => { return mount(CameraView, { global: { plugins: [createPinia(), i18n], stubs: { 'el-form': { template: '
' }, 'el-form-item': { template: '
' }, 'el-input': { template: '', props: ['modelValue', 'placeholder', 'disabled', 'type'] }, 'el-input-number': { template: '', props: ['modelValue', 'min', 'max'] }, 'el-select': { template: '', props: ['modelValue', 'placeholder', 'clearable'] }, 'el-option': { template: '', props: ['label', 'value'] }, 'el-button': { template: '', props: ['type', 'icon', 'loading', 'link', 'plain'], computed: { htmlType() { return 'button' } } }, 'el-table': { template: '
', props: ['data', 'loading', 'border'] }, 'el-table-column': { template: '', props: ['prop', 'label', 'width', 'align', 'type', 'fixed', 'minWidth', 'showOverflowTooltip'] }, 'el-tag': { template: '', props: ['type'] }, 'el-dialog': { template: '
', props: ['modelValue', 'title', 'width', 'destroyOnClose'] }, 'el-row': { template: '
' }, 'el-col': { template: '
', props: ['span'] }, 'el-switch': { template: '', props: ['modelValue'] } } } }) } describe('页面渲染', () => { it('应该正确渲染摄像头管理页面', async () => { const wrapper = mountCamera() await flushPromises() expect(wrapper.find('.page-container').exists()).toBe(true) expect(wrapper.find('.search-form').exists()).toBe(true) expect(wrapper.find('.table-wrapper').exists()).toBe(true) }) it('应该显示新增摄像头按钮', async () => { const wrapper = mountCamera() await flushPromises() const buttons = wrapper.findAll('.search-form button') const addButton = buttons.find((b) => b.text().includes('新增')) expect(addButton).toBeDefined() }) it('应该显示查询和重置按钮', async () => { const wrapper = mountCamera() await flushPromises() const buttons = wrapper.findAll('.search-form button') const searchBtn = buttons.find((b) => b.text().includes('查询')) const resetBtn = buttons.find((b) => b.text().includes('重置')) expect(searchBtn).toBeDefined() expect(resetBtn).toBeDefined() }) }) describe('数据加载', () => { it('页面加载时应该获取摄像头列表', async () => { mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) it('页面加载时应该获取机器列表', async () => { mountCamera() await flushPromises() expect(mockListAllMachines).toHaveBeenCalled() }) }) describe('搜索和过滤', () => { it('选择机器应该触发查询', async () => { const wrapper = mountCamera() await flushPromises() mockAdminListCameras.mockClear() const searchBtn = wrapper.findAll('button').find((btn) => btn.text().includes('搜索')) if (searchBtn) { await searchBtn.trigger('click') await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() } }) it('重置应该清空筛选条件', async () => { const wrapper = mountCamera() await flushPromises() mockAdminListCameras.mockClear() const resetBtn = wrapper.findAll('button').find((btn) => btn.text().includes('重置')) if (resetBtn) { await resetBtn.trigger('click') await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() } }) }) describe('新增摄像头', () => { it('点击新增按钮应该打开弹窗', async () => { const wrapper = mountCamera() await flushPromises() const addBtn = wrapper.findAll('button').find((btn) => btn.text().includes('新增摄像头')) if (addBtn) { await addBtn.trigger('click') await flushPromises() expect(wrapper.find('.el-dialog').exists()).toBe(true) } }) it('新增摄像头成功应该刷新列表', async () => { mockAdminAddCamera.mockResolvedValue(wrapResponse({ id: 4, cameraId: 'cam-004' })) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) }) describe('编辑摄像头', () => { it('编辑摄像头成功应该刷新列表', async () => { mockAdminUpdateCamera.mockResolvedValue(wrapResponse(mockCameras[0])) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) }) describe('删除摄像头', () => { it('删除摄像头成功应该刷新列表', async () => { mockAdminDeleteCamera.mockResolvedValue(wrapResponse(null)) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) }) describe('检测摄像头', () => { it('检测成功应该显示成功消息', async () => { mockAdminCheckCamera.mockResolvedValue(wrapResponse(true)) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) it('检测失败应该显示警告消息', async () => { mockAdminCheckCamera.mockResolvedValue(wrapResponse(false)) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) }) describe('通道列表', () => { it('应该能够显示通道弹窗', async () => { const wrapper = mountCamera() await flushPromises() expect(wrapper.html()).toBeDefined() }) }) describe('状态过滤', () => { it('选择在线状态应该过滤列表', async () => { const wrapper = mountCamera() await flushPromises() expect(wrapper.html()).toBeDefined() }) it('选择离线状态应该过滤列表', async () => { const wrapper = mountCamera() await flushPromises() expect(wrapper.html()).toBeDefined() }) }) describe('错误处理', () => { it('API 返回错误码应该正确处理', async () => { mockAdminListCameras.mockResolvedValue(wrapResponse([], false, '获取失败')) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) }) })