task-31(会话/菜单/权限): 超级管理员菜单判定走角色归一
store.isSuperAdmin getter 改用 isSuperAdminRole(role) 归一判定,替代裸等值 比较;大小写/空白差异的角色串也能正确放行全部菜单。8 用例全过。
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { fetchAdminMenuTree, fetchCurrentUser, logout } from '@/api/session'
|
import { fetchAdminMenuTree, fetchCurrentUser, logout } from '@/api/session'
|
||||||
import type { AdminMenuNode, AdminUser } from '@/types/admin'
|
import type { AdminMenuNode, AdminUser } from '@/types/admin'
|
||||||
|
import { isSuperAdminRole } from '@/types/admin'
|
||||||
import { firstVisiblePath } from '@/router/helpers'
|
import { firstVisiblePath } from '@/router/helpers'
|
||||||
|
|
||||||
export const useAdminSessionStore = defineStore('admin-session', {
|
export const useAdminSessionStore = defineStore('admin-session', {
|
||||||
@@ -12,7 +13,7 @@ export const useAdminSessionStore = defineStore('admin-session', {
|
|||||||
error: '',
|
error: '',
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isSuperAdmin: (state) => state.user?.role === 'super_admin',
|
isSuperAdmin: (state) => isSuperAdminRole(state.user?.role),
|
||||||
firstVisible: (state): string => {
|
firstVisible: (state): string => {
|
||||||
return firstVisiblePath(state.menuTree)
|
return firstVisiblePath(state.menuTree)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import test from 'node:test'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import { readSource } from './helpers.ts'
|
||||||
|
import { isSuperAdminRole, isSuperUser } from '../src/types/admin.ts'
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_normal_primary_path', () => {
|
||||||
|
// 正常主路径:super_admin 角色判定为超级管理员,可进全部菜单。
|
||||||
|
assert.equal(isSuperAdminRole('super_admin'), true)
|
||||||
|
assert.equal(isSuperUser({ role: 'super_admin' }), true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_normal_variant_input', () => {
|
||||||
|
// 正常变体:admin/normal 不是超级管理员。
|
||||||
|
assert.equal(isSuperAdminRole('admin'), false)
|
||||||
|
assert.equal(isSuperAdminRole('normal'), false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_normal_repeated_operation_is_idempotent', () => {
|
||||||
|
// 正常重复:大小写/空白差异归一后判定稳定。
|
||||||
|
assert.equal(isSuperAdminRole('SUPER_ADMIN'), isSuperAdminRole('super_admin'))
|
||||||
|
assert.equal(isSuperAdminRole(' Super_Admin '), true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_boundary_empty_input', () => {
|
||||||
|
// 边界空值:空/null 角色不判为超级管理员,也不抛错。
|
||||||
|
assert.equal(isSuperAdminRole(''), false)
|
||||||
|
assert.equal(isSuperAdminRole(undefined), false)
|
||||||
|
assert.equal(isSuperAdminRole(null), false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_boundary_single_item', () => {
|
||||||
|
// 边界单元素:单个 super_admin 用户被 store getter 识别。
|
||||||
|
const store = readSource('src/stores/admin-session.ts')
|
||||||
|
assert.match(store, /isSuperAdmin\s*:/, 'store 提供 isSuperAdmin getter')
|
||||||
|
assert.match(store, /isSuperAdminRole/, 'getter 复用角色归一判定')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_boundary_limit_or_missing_field', () => {
|
||||||
|
// 边界上限/缺字段:未知角色串不误判超级管理员。
|
||||||
|
assert.equal(isSuperAdminRole('owner'), false)
|
||||||
|
assert.equal(isSuperAdminRole('xxx'), false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_invalid_input_rejected', () => {
|
||||||
|
// 异常输入:store getter 不应再用未归一化的原始等值比较。
|
||||||
|
const store = readSource('src/stores/admin-session.ts')
|
||||||
|
assert.equal(store.includes("role === 'super_admin'"), false, '不允许裸等值判定,需走角色归一')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test_task_031_super_admin_judge_dependency_failure_returns_actionable_message', () => {
|
||||||
|
// 依赖失败:类型契约模块提供角色判定,供 store 与守卫复用。
|
||||||
|
const source = readSource('src/stores/admin-session.ts')
|
||||||
|
assert.match(source, /isSuperAdminRole/)
|
||||||
|
const adminTypes = readSource('src/types/admin.ts')
|
||||||
|
assert.match(adminTypes, /isSuperAdminRole/)
|
||||||
|
assert.match(adminTypes, /roleKind\(/)
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user