diff --git a/admin-frontend-vue/src/stores/admin-session.ts b/admin-frontend-vue/src/stores/admin-session.ts index f326fc50..6aadd783 100644 --- a/admin-frontend-vue/src/stores/admin-session.ts +++ b/admin-frontend-vue/src/stores/admin-session.ts @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { fetchAdminMenuTree, fetchCurrentUser, logout } from '@/api/session' import type { AdminMenuNode, AdminUser } from '@/types/admin' +import { isSuperAdminRole } from '@/types/admin' import { firstVisiblePath } from '@/router/helpers' export const useAdminSessionStore = defineStore('admin-session', { @@ -12,7 +13,7 @@ export const useAdminSessionStore = defineStore('admin-session', { error: '', }), getters: { - isSuperAdmin: (state) => state.user?.role === 'super_admin', + isSuperAdmin: (state) => isSuperAdminRole(state.user?.role), firstVisible: (state): string => { return firstVisiblePath(state.menuTree) }, diff --git a/admin-frontend-vue/tests/task-31.test.ts b/admin-frontend-vue/tests/task-31.test.ts new file mode 100644 index 00000000..48924460 --- /dev/null +++ b/admin-frontend-vue/tests/task-31.test.ts @@ -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\(/) +})