Files
workspace/code/fms/fms-vue/tests/unit/router-nested-groups.spec.js
T
2026-09-15 22:10:13 +08:00

66 lines
3.0 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, expect, it } from 'vitest'
import { createMemoryHistory, createRouter } from 'vue-router'
import { menuRouteOptions, routes } from '@/router/routes'
/**
* 路由分组(/module)的契约测试。两条分组节点的硬约束:
*
* 1. 分组节点必须保持「无 component」:一旦给它配容器组件(内部再放 router-view),
* 页面会下沉一层、脱离 DefaultLayout 的 keep-alive,缓存静默失效。
*
* 2. 分组节点也不配 redirect:分组只是归类,不该自带「默认落地页」语义。
* 直接访问 /base、/module 这类裸前缀时,交给表尾的 /:pathMatch(.*)* 兜到工作台
* (/dashboard)—— 业务入口一律由 s_menu + 路由地址维护,避免出现「菜单上没配、
* 却能落在某个页面」的第二入口。
*/
function createTestRouter() {
return createRouter({ history: createMemoryHistory(), routes })
}
describe('路由分组(嵌套结构)', () => {
it('分组内子路由解析出完整路径,分组节点不带可渲染组件', async () => {
const router = createTestRouter()
await router.push('/module/i18n-type')
const matched = router.currentRoute.value.matched
expect(matched.map((record) => record.path)).toEqual(['/', '/module', '/module/i18n-type'])
// 分组节点无 components:RouterView 会跳过它,子页仍渲染在 DefaultLayout 的 router-view 上
expect(matched[1].components).toBeFalsy()
// meta 由父到子合并,子记录的 componentName 决定 keep-alive 的 include 名
expect(router.currentRoute.value.meta.componentName).toBe('I18nTypeManagement')
})
it('分组节点既无 component 也无 redirect:只是归类,不自带默认落地页', async () => {
const router = createTestRouter()
await router.push('/module/i18n-type')
const group = router.currentRoute.value.matched[1]
expect(group.path).toBe('/module')
expect(group.components).toBeFalsy()
expect(group.redirect).toBeFalsy()
})
it('访问分组裸前缀时兜到工作台,不白屏', async () => {
const router = createTestRouter()
await router.push('/module')
// 分组无 component、无 redirect,裸前缀由表尾 /:pathMatch(.*)* 兜底
expect(router.currentRoute.value.path).toBe('/dashboard')
})
it('菜单路由选项:排除模块中心(adminOnly)整组与分组节点/动态/通配路由', () => {
const values = menuRouteOptions.map((option) => option.value)
// 模块中心是系统管理员专用页(meta.adminOnly):整组排除,
// 「菜单管理」的路由下拉配不出第二入口
expect(values).not.toContain('/module/module-management')
expect(values).not.toContain('/module/menu-management')
expect(values).not.toContain('/module/i18n-type')
expect(values).toContain('/dashboard')
// 分组节点本身、详情页(:id)、404 通配、登录页都不是菜单入口
expect(values).not.toContain('/module')
expect(values).not.toContain('/detail/:id')
expect(values).not.toContain('/login')
})
})