156 lines
4.7 KiB
JavaScript
156 lines
4.7 KiB
JavaScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { nextTick, ref } from 'vue'
|
|
import { mount } from '@vue/test-utils'
|
|
import { createPinia } from 'pinia'
|
|
import MenuDetailPanel from '@/views/system/module-management/components/MenuDetailPanel.vue'
|
|
|
|
const moduleRow = {
|
|
b_id: '1',
|
|
b_code: 'test',
|
|
b_name: '测试模块',
|
|
b_module_type: 'data',
|
|
b_parent_id: null,
|
|
b_canuse: 1,
|
|
b_xh: 10,
|
|
}
|
|
|
|
vi.mock('@/services/api', () => ({
|
|
loadDataApi: vi.fn(async (table) => {
|
|
if (table === 's_module') return { data: [moduleRow] }
|
|
return { data: [] }
|
|
}),
|
|
saveObjectApi: vi.fn(async () => ({})),
|
|
nextIdApi: vi.fn(async () => ({ data: '999' })),
|
|
describeApi: vi.fn(async () => ({ data: [] })),
|
|
}))
|
|
|
|
import ModuleManagement from '@/views/system/module-management/index.vue'
|
|
|
|
describe('模块管理 tab 切换复现', () => {
|
|
let wrapper
|
|
|
|
beforeEach(async () => {
|
|
wrapper = mount(ModuleManagement, {
|
|
global: {
|
|
plugins: [createPinia()],
|
|
stubs: {
|
|
ModuleBasicPanel: { template: '<div class="stub-basic" />' },
|
|
ModuleFieldsPanel: { template: '<div class="stub-fields" />' },
|
|
ModuleListConfigPanel: { template: '<div class="stub-list" />' },
|
|
ModuleEditConfigPanel: { template: '<div class="stub-edit" />' },
|
|
ModuleQueryConfigPanel: { template: '<div class="stub-query" />' },
|
|
ModuleAutoCodePanel: { template: '<div class="stub-autocode" />' },
|
|
ModulePowersPanel: { template: '<div class="stub-powers" />' },
|
|
ModuleI18nPanel: { template: '<div class="stub-i18n" />' },
|
|
MenuDetailPanel: { template: '<div class="stub-menu" />' },
|
|
Modal: { template: '<div class="stub-modal" />' },
|
|
Transition: { template: '<slot />' },
|
|
},
|
|
},
|
|
})
|
|
// 等待树加载
|
|
await nextTick()
|
|
await nextTick()
|
|
})
|
|
|
|
it('选中模块后 section Tabs 仅一个 tab 激活', async () => {
|
|
// 点击树节点选中模块
|
|
const node = wrapper.find('.tree-node-content')
|
|
expect(node.exists()).toBe(true)
|
|
await node.trigger('click')
|
|
await nextTick()
|
|
await nextTick()
|
|
// 等待 loadModuleConfig 完成
|
|
await new Promise((r) => setTimeout(r, 50))
|
|
await nextTick()
|
|
|
|
const sectionTabs = wrapper.find('.mm-section-tabs')
|
|
expect(sectionTabs.exists()).toBe(true)
|
|
const activeTabs = sectionTabs.findAll('.tabs-tab-active')
|
|
expect(activeTabs).toHaveLength(1)
|
|
|
|
// 点击"字段定义"
|
|
const fieldsTab = sectionTabs
|
|
.findAll('.tabs-tab')
|
|
.find((t) => t.text().includes('字段定义'))
|
|
expect(fieldsTab).toBeTruthy()
|
|
await fieldsTab.trigger('click')
|
|
await nextTick()
|
|
|
|
const activeTabs2 = sectionTabs.findAll('.tabs-tab-active')
|
|
expect(activeTabs2).toHaveLength(1)
|
|
expect(activeTabs2[0].text()).toContain('字段定义')
|
|
})
|
|
})
|
|
|
|
describe('MenuDetailPanel 暴露的保存校验 API', () => {
|
|
it('validate / saveI18n / markI18nSaved 同时暴露(defineExpose 未被覆盖)', async () => {
|
|
const menu = ref({
|
|
b_id: '1',
|
|
b_code: '',
|
|
b_name: '',
|
|
b_menu_type: 'directory',
|
|
b_canuse: 1,
|
|
})
|
|
const wrapper = mount(MenuDetailPanel, {
|
|
props: {
|
|
menu: menu.value,
|
|
parentName: '',
|
|
moduleOptions: [],
|
|
powers: [],
|
|
loading: false,
|
|
},
|
|
global: {
|
|
stubs: {
|
|
IconSelect: true,
|
|
ModulePowersPanel: true,
|
|
ModuleI18nPanel: true,
|
|
I18nQuickSetModal: true,
|
|
Tabs: { template: '<div><slot /></div>' },
|
|
TabPane: { template: '<div><slot /></div>' },
|
|
},
|
|
},
|
|
})
|
|
await nextTick()
|
|
expect(typeof wrapper.vm.validate).toBe('function')
|
|
expect(typeof wrapper.vm.saveI18n).toBe('function')
|
|
expect(typeof wrapper.vm.markI18nSaved).toBe('function')
|
|
})
|
|
|
|
it('validate 对空必填返回错误字段,且校验时切回基本信息 tab', async () => {
|
|
const menu = ref({
|
|
b_id: '1',
|
|
b_code: '',
|
|
b_name: '',
|
|
b_menu_type: 'page',
|
|
b_route: '',
|
|
b_canuse: 1,
|
|
})
|
|
const wrapper = mount(MenuDetailPanel, {
|
|
props: {
|
|
menu: menu.value,
|
|
parentName: '',
|
|
moduleOptions: [],
|
|
powers: [],
|
|
loading: false,
|
|
},
|
|
global: {
|
|
stubs: {
|
|
IconSelect: true,
|
|
ModulePowersPanel: true,
|
|
ModuleI18nPanel: true,
|
|
I18nQuickSetModal: true,
|
|
Tabs: { template: '<div><slot /></div>' },
|
|
TabPane: { template: '<div><slot /></div>' },
|
|
},
|
|
},
|
|
})
|
|
await nextTick()
|
|
const errors = await wrapper.vm.validate()
|
|
expect(errors.length).toBeGreaterThan(0)
|
|
const names = errors.map((e) => e.name)
|
|
expect(names).toContain('b_code')
|
|
expect(names).toContain('b_name')
|
|
})
|
|
})
|