0fcee02189
新增 user-menu-auth.ts 纯解析:parseMenuOptionList 归一 permission-menus 扁平项、
buildMenuOptionTree 按 parent_id 组装并按 (sort,key) 排序、parseUserGrantedColumnIds/
normalizeMenuIds 解包用户已授权 id 去重升序。user-menu-auth-api.ts 走 GET
/api/admin/permission-menus(menuType=admin) 与 /permission-users/{id}/columns 加载授权树与已勾选。
8 用例全过,355 单测 + build 绿。
88 lines
4.2 KiB
TypeScript
88 lines
4.2 KiB
TypeScript
import test from 'node:test'
|
||
import assert from 'node:assert/strict'
|
||
import { readSource } from './helpers.ts'
|
||
import {
|
||
ADMIN_MENU_TYPE,
|
||
buildMenuOptionTree,
|
||
normalizeMenuIds,
|
||
parseMenuOptionList,
|
||
parsePermissionMenuItem,
|
||
parseUserGrantedColumnIds,
|
||
} from '../src/pages/account/user-menu-auth.ts'
|
||
|
||
test('test_task_049_user_menu_auth_load_normal_primary_path', () => {
|
||
// 正常主路径:扁平 permission-menus 归一后按 parent_id 组装出嵌套、按 sort 排序的树。
|
||
const items = parseMenuOptionList({
|
||
success: true,
|
||
data: [
|
||
{ id: 1, name: '账号权限', column_key: 'account', parent_id: null, sort_order: 1, menu_type: 'admin' },
|
||
{ id: 2, name: '用户管理', column_key: 'account_users', parent_id: 1, sort_order: 1, menu_type: 'admin' },
|
||
{ id: 3, name: '角色组', column_key: 'account_groups', parent_id: 1, sort_order: 2, menu_type: 'admin' },
|
||
],
|
||
})
|
||
assert.equal(items.length, 3)
|
||
const tree = buildMenuOptionTree(items)
|
||
assert.equal(tree.length, 1)
|
||
assert.equal(tree[0].id, 1)
|
||
assert.equal(tree[0].children?.length, 2)
|
||
assert.equal(tree[0].children?.[0].key, 'account_users')
|
||
assert.deepEqual(parseUserGrantedColumnIds({ success: true, data: { columnIds: [3, 2] } }), [2, 3])
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_normal_variant_input', () => {
|
||
// 正常变体:缺 column_key 用 id 兜底;父节点缺失的子节点按根处理。
|
||
const orphan = parsePermissionMenuItem({ id: 9, name: '孤儿', parent_id: 99, sort_order: 0 })
|
||
assert.equal(orphan?.parentId, 99)
|
||
assert.equal(buildMenuOptionTree([orphan as never])[0].id, 9)
|
||
const node = parsePermissionMenuItem({ id: 5, name: 'x', sort_order: 3 })
|
||
assert.equal(node?.key, '5')
|
||
assert.equal(node?.name, 'x')
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_normal_repeated_operation_is_idempotent', () => {
|
||
// 正常重复:组装不改输入、结果稳定。
|
||
const items = parseMenuOptionList([{ id: 1, name: 'A', parent_id: null, sort_order: 0 }])
|
||
assert.deepEqual(buildMenuOptionTree(items), buildMenuOptionTree(items))
|
||
assert.equal(items[0].id, 1)
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_boundary_empty_input', () => {
|
||
// 边界空值:空负载/空数组/缺 granted 字段均回默认,不崩溃。
|
||
assert.deepEqual(parseMenuOptionList({}), [])
|
||
assert.deepEqual(buildMenuOptionTree([]), [])
|
||
assert.deepEqual(parseUserGrantedColumnIds({ success: true, data: {} }), [])
|
||
assert.deepEqual(normalizeMenuIds(undefined), [])
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_boundary_single_item', () => {
|
||
// 边界单元素:单根节点成树。
|
||
const items = parseMenuOptionList([{ id: 7, name: 'Only', column_key: 'only', parent_id: null, sort_order: 0 }])
|
||
const tree = buildMenuOptionTree(items)
|
||
assert.equal(tree.length, 1)
|
||
assert.equal(tree[0].key, 'only')
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_boundary_limit_or_missing_field', () => {
|
||
// 边界上限/缺字段:缺 id 的行被过滤;非法/重复 granted 去重并升序。
|
||
assert.equal(parsePermissionMenuItem({ name: 'no-id' }), null)
|
||
assert.deepEqual(normalizeMenuIds([2, 1, 2, -1, 3.7, 'x' as never]), [1, 2, 3])
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_invalid_input_rejected', () => {
|
||
// 异常输入:success=false 抛后端 message;granted 无 columnIds 字段回默认。
|
||
assert.throws(() => parseMenuOptionList({ success: false, message: '无权限查看菜单' }), /无权限查看菜单/)
|
||
assert.deepEqual(parseUserGrantedColumnIds({ success: true, data: { nothing: 1 } }), [])
|
||
})
|
||
|
||
test('test_task_049_user_menu_auth_load_dependency_failure_returns_actionable_message', () => {
|
||
// 依赖失败/加载走 adapter:GET permission-menus(menuType=admin)+permission-users/{id}/columns,页面不内联。
|
||
const mod = readSource('src/pages/account/user-menu-auth.ts')
|
||
assert.equal(/axios|http\./.test(mod), false, '解析模型保持纯逻辑')
|
||
const api = readSource('src/pages/account/user-menu-auth-api.ts')
|
||
assert.match(api, /permission-menus/)
|
||
assert.match(api, /permission-users\/\$?\{?userId|permission-users/)
|
||
assert.match(api, new RegExp(`menuType.*${ADMIN_MENU_TYPE}|${ADMIN_MENU_TYPE}`))
|
||
assert.match(api, /parseMenuOptionList/)
|
||
assert.match(api, /parseUserGrantedColumnIds/)
|
||
})
|