| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- 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: '<form><slot /></form>' },
- 'el-form-item': { template: '<div class="el-form-item"><slot /></div>' },
- 'el-input': {
- template: '<input :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" />',
- props: ['modelValue', 'placeholder', 'disabled', 'type']
- },
- 'el-input-number': {
- template:
- '<input type="number" :value="modelValue" @input="$emit(\'update:modelValue\', parseInt($event.target.value))" />',
- props: ['modelValue', 'min', 'max']
- },
- 'el-select': {
- template:
- '<select :value="modelValue" @change="$emit(\'update:modelValue\', $event.target.value); $emit(\'change\', $event.target.value)"><slot /></select>',
- props: ['modelValue', 'placeholder', 'clearable']
- },
- 'el-option': {
- template: '<option :value="value">{{ label }}</option>',
- props: ['label', 'value']
- },
- 'el-button': {
- template: '<button :type="htmlType" :disabled="loading" @click="$emit(\'click\')"><slot /></button>',
- props: ['type', 'icon', 'loading', 'link', 'plain'],
- computed: {
- htmlType() {
- return 'button'
- }
- }
- },
- 'el-table': {
- template: '<table class="el-table"><slot /></table>',
- props: ['data', 'loading', 'border']
- },
- 'el-table-column': {
- template: '<td class="el-table-column"></td>',
- props: ['prop', 'label', 'width', 'align', 'type', 'fixed', 'minWidth', 'showOverflowTooltip']
- },
- 'el-tag': {
- template: '<span class="el-tag"><slot /></span>',
- props: ['type']
- },
- 'el-dialog': {
- template: '<div v-if="modelValue" class="el-dialog"><slot /><slot name="footer" /></div>',
- props: ['modelValue', 'title', 'width', 'destroyOnClose']
- },
- 'el-row': { template: '<div class="el-row"><slot /></div>' },
- 'el-col': { template: '<div class="el-col"><slot /></div>', props: ['span'] },
- 'el-switch': {
- template:
- '<input type="checkbox" :checked="modelValue" @change="$emit(\'update:modelValue\', $event.target.checked)" />',
- 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()
- })
- })
- })
|