Files
workspace/code/fms/fms-vue/tests/menus.spec.js
T
2026-09-04 23:24:45 +08:00

151 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, beforeEach, vi } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useAuthStore } from '@/stores/auth'
import { useMenuStore } from '@/stores/menus'
// mock 后端数据接口,避免真实网络请求
vi.mock('@/services/api', () => ({
loadDataApi: vi.fn(),
}))
import { loadDataApi } from '@/services/api'
const mockMenus = [
{
b_id: '1',
b_code: 'sys',
b_name: '系统',
b_menu_type: 'directory',
b_parent_id: null,
b_canuse: 1,
},
{
b_id: '2',
b_code: 'module',
b_name: '模块管理',
b_menu_type: 'page',
b_parent_id: '1',
b_route: '/module/module-management',
b_canuse: 1,
},
{
b_id: '3',
b_code: 'menu',
b_name: '菜单管理',
b_menu_type: 'page',
b_parent_id: '1',
b_route: '/module/menu-management',
b_canuse: 1,
},
{
b_id: '4',
b_code: 'i18n',
b_name: '多语言类型',
b_menu_type: 'page',
b_parent_id: '1',
b_route: '/module/i18n-type',
b_canuse: 1,
},
]
function mockSModuleData(menus) {
loadDataApi.mockImplementation((view) =>
Promise.resolve({
data: view === 's_menu' ? menus : [],
code: 0,
success: true,
}),
)
}
function setUser(account, id) {
const auth = useAuthStore()
auth.setSession({ token: 't', user: { id, account } }, 'ORG')
}
/** 冲刷微任务:让 setSession 触发的 watch(clear) 先执行 */
const flush = () => Promise.resolve()
function collectCodes(nodes) {
const codes = []
for (const node of nodes) {
codes.push(String(node.b_code))
if (node.children) codes.push(...collectCodes(node.children))
}
return codes
}
beforeEach(() => {
setActivePinia(createPinia())
loadDataApi.mockReset()
})
describe('menus store(s_menu 动态菜单)', () => {
it('普通用户:隐藏编码 module 的菜单(含空目录剪枝)', async () => {
mockSModuleData(mockMenus)
setUser('u1', 123)
await flush()
const menus = useMenuStore()
await menus.load()
const codes = collectCodes(menus.visibleMenus)
expect(codes).toContain('sys')
expect(codes).toContain('menu')
expect(codes).toContain('i18n')
expect(codes).not.toContain('module')
})
it('普通用户:目录下仅剩 module 子项时,目录整体不渲染', async () => {
// 系统目录下只有「模块管理」这一个可用子菜单
mockSModuleData(mockMenus.filter((m) => m.b_code !== 'menu' && m.b_code !== 'i18n'))
setUser('u1', 123)
await flush()
const menus = useMenuStore()
await menus.load()
expect(menus.visibleMenus).toEqual([])
})
it('g3soft:module 菜单可见', async () => {
mockSModuleData(mockMenus)
setUser('g3soft', 1)
await flush()
const menus = useMenuStore()
await menus.load()
expect(menus.isG3soft).toBe(true)
expect(collectCodes(menus.visibleMenus)).toContain('module')
})
it('同一主体重复 load 不重复发请求', async () => {
mockSModuleData(mockMenus)
setUser('u1', 123)
await flush()
const menus = useMenuStore()
await menus.load()
await menus.load()
expect(loadDataApi).toHaveBeenCalledTimes(1)
})
it('切换账号:缓存清空并重新加载', async () => {
mockSModuleData(mockMenus)
setUser('u1', 123)
await flush()
const menus = useMenuStore()
await menus.load()
expect(menus.rawMenus.length).toBe(mockMenus.length)
// 切换到另一个主体:watch(clear) 清空已加载数据
setUser('u2', 999)
await flush()
await flush()
expect(menus.rawMenus.length).toBe(0)
expect(menus.visibleMenus).toEqual([])
// 新主体 load 重新拉取
loadDataApi.mockClear()
await menus.load()
expect(menus.rawMenus.length).toBe(mockMenus.length)
})
})