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