import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' import { createPinia, setActivePinia } from 'pinia' import CameraView from '@/views/camera/index.vue' import { wrapResponse, 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 mockListMachines = vi.fn() vi.mock('@/api/machine', () => ({ listMachines: () => mockListMachines() })) describe('Camera View', () => { beforeEach(() => { setActivePinia(createPinia()) vi.clearAllMocks() mockAdminListCameras.mockResolvedValue(wrapResponse(mockCameras)) mockListMachines.mockResolvedValue(wrapResponse(mockMachines)) }) const mountCamera = () => { return mount(CameraView, { global: { plugins: [createPinia()], 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-actions').exists()).toBe(true) }) it('应该显示新增摄像头按钮', async () => { const wrapper = mountCamera() await flushPromises() const addButton = wrapper.find('.table-actions button') expect(addButton.exists()).toBe(true) expect(addButton.text()).toContain('新增摄像头') }) it('应该显示刷新列表按钮', async () => { const wrapper = mountCamera() await flushPromises() const buttons = wrapper.findAll('.table-actions button') const refreshBtn = buttons.find((b) => b.text().includes('刷新列表')) expect(refreshBtn).toBeDefined() }) }) describe('数据加载', () => { it('页面加载时应该获取摄像头列表', async () => { mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) it('页面加载时应该获取机器列表', async () => { mountCamera() await flushPromises() expect(mockListMachines).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([], 500, '获取失败')) const wrapper = mountCamera() await flushPromises() expect(mockAdminListCameras).toHaveBeenCalled() }) }) })