20260821230656

This commit is contained in:
oneao committed 2026-08-21 23:06:56 +08:00
1 parent 2e5d532f23
commit c43b4c8364
144 files changed
+7665 -242

No files matched your search

@@ -0,0 +1,155 @@
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')
})
})