20260819173221

This commit is contained in:
oneao committed 2026-08-19 17:32:25 +08:00
1 parent 1ffc8e1ac9
commit a0a4273f4c
326 files changed
+301646 -2314

No files matched your search

+108
View File
@@ -0,0 +1,108 @@
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
import { setActivePinia, createPinia } from 'pinia'
import { useAuthStore } from '@/stores/auth'
import { usePermissionStore } from '@/stores/permissions'
import { createTestPinia } from './helpers/app.js'
import router from '@/router'
// mock 后端数据接口
vi.mock('@/services/api', () => ({
loadDataApi: vi.fn(),
}))
import { loadDataApi } from '@/services/api'
const mockModules = [
{
b_id: '1',
b_code: 'm1',
b_name: 'M1',
b_canuse: 1,
b_canmenu: 1,
b_module_type: 'directory',
b_parent_id: null,
b_icon: '',
b_route: '',
},
]
beforeEach(() => {
localStorage.clear()
sessionStorage.clear()
setActivePinia(createPinia())
loadDataApi.mockReset()
loadDataApi.mockImplementation((view) =>
Promise.resolve({ data: view === 's_module' ? mockModules : [], code: 0, success: true }),
)
// 回到登录页,断开受保护路由状态
return router.push('/login').catch(() => {})
})
afterEach(() => {
if (router.hasRoute('biz')) router.removeRoute('biz')
})
describe('路由守卫 权限加载(三场景)', () => {
it('场景·未登录:访问受保护页 → 重定向 /login?redirect', async () => {
await router.push('/dashboard')
expect(router.currentRoute.value.path).toBe('/login')
expect(router.currentRoute.value.query.redirect).toBe('/dashboard')
})
it('场景·登录:访问受保护页 → 触发 load,菜单数据就绪(同主体不重复请求)', async () => {
const auth = useAuthStore()
auth.setSession({ token: 't', user: { id: 123, account: 'u1', name: 'U' } }, 'ORG')
await router.push('/dashboard')
expect(loadDataApi).toHaveBeenCalled()
expect(usePermissionStore().modules.length).toBe(1)
// 再次进入另一受保护页(同主体)不应重复发请求
loadDataApi.mockClear()
await router.push('/test/list')
expect(loadDataApi).not.toHaveBeenCalled()
})
it('场景·登录:访问无权限 moduleId 路由 → 重定向 /dashboard', async () => {
const auth = useAuthStore()
auth.setSession({ token: 't', user: { id: 123, account: 'u1', name: 'U' } }, 'ORG')
router.addRoute({
path: '/biz',
name: 'biz',
component: { render: () => null },
meta: { requiresAuth: true, moduleId: 'm-no' },
})
await router.push('/biz')
expect(router.currentRoute.value.path).toBe('/dashboard')
})
it('场景·刷新已登录态:persist 恢复后守卫 load 成功,无 clear 竞态', async () => {
// 按 pinia-plugin-persistedstate v4 的实际存储格式写入(纯 state JSON,无 {state, version} 包装)
sessionStorage.setItem(
'fms-login',
JSON.stringify({ loginInfo: { token: 't', user: { id: 123, account: 'u1', name: 'U' } } }),
)
localStorage.setItem(
'fms-user',
JSON.stringify({ userInfo: { orgId: 'ORG', account: 'u1' } }),
)
// 用 createTestPinia(内部已 install,persist 插件真实注册),等价于刷新页面
const pinia = createTestPinia()
const a = useAuthStore() // 首次创建
await a.$hydrate() // 显式从 localStorage 恢复(等价于刷新页面)
expect(useAuthStore().isAuthenticated).toBe(true)
await router.push('/dashboard')
expect(usePermissionStore().modules.length).toBe(1)
})
it('场景·切换账号:旧主体请求作废,新主体重新加载', async () => {
const auth = useAuthStore()
auth.setSession({ token: 't', user: { id: 123, account: 'u1', name: 'U' } }, 'ORG')
await router.push('/dashboard')
expect(usePermissionStore().modules.length).toBe(1)
// 切换到另一账号
auth.setSession({ token: 't2', user: { id: 999, account: 'u2', name: 'U2' } }, 'ORG2')
loadDataApi.mockClear()
await router.push('/test/list')
expect(loadDataApi).toHaveBeenCalled() // 新主体重新加载
expect(usePermissionStore().modules.length).toBe(1)
})
})