Files
workspace/code/fms/fms-vue/tests/unit/router-nested-groups.spec.js
T
2026-09-21 23:13:14 +08:00

70 lines
3.3 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(.*)* 渲染 404 缺省页
* —— 业务入口一律由 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('访问分组裸前缀时落入 404 缺省页,不白屏也不落业务页', async () => {
const router = createTestRouter()
await router.push('/module')
// 分组无 component、无 redirect,裸前缀由表尾 /:pathMatch(.*)* 渲染 404 缺省页;
// 地址保留原样不重定向,用户能看到自己输错的是什么
expect(router.currentRoute.value.name).toBe('fallback-404')
expect(router.currentRoute.value.path).toBe('/module')
})
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')
expect(values).not.toContain('/403')
expect(values).not.toContain('/500')
})
})