task-28(会话/菜单/权限): 锁定当前用户初始化动作契约

store.initialize 先拉当前用户再拉菜单;用户写入 store.user、成功/失败路径
及守卫短路均被契约锁定;解析器缺 id/接口失败抛可操作错误。8 用例全过。
This commit is contained in:
2026-09-05 14:13:55 +08:00
parent 8b07321fbb
commit 115df85063
+55
View File
@@ -0,0 +1,55 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import { readSource } from './helpers.ts'
import { parseCurrentUser } from '../src/api/session-model.ts'
const store = readSource('src/stores/admin-session.ts')
test('test_task_028_current_user_init_normal_primary_path', () => {
// 正常主路径:初始化第一步拉取当前用户并写入 store.user。
assert.match(store, /this\.user\s*=\s*await fetchCurrentUser\(\)/)
})
test('test_task_028_current_user_init_normal_variant_input', () => {
// 正常变体:先取用户、再取菜单,顺序不可颠倒(菜单依赖登录身份)。
assert.ok(store.indexOf('fetchCurrentUser()') < store.indexOf('fetchAdminMenuTree()'), '当前用户应先于菜单拉取')
})
test('test_task_028_current_user_init_normal_repeated_operation_is_idempotent', () => {
// 正常重复:已初始化/加载中不再重复发起当前用户请求。
assert.match(store, /if\s*\(this\.initialized\s*\|\|\s*this\.loading\)\s*return/)
const userCalls = (store.match(/fetchCurrentUser\(\)/g) || []).length
assert.ok(userCalls <= 2, '用户拉取只出现在 store 内声明与调用处')
})
test('test_task_028_current_user_init_boundary_empty_input', () => {
// 边界空值:解析器在空/非对象负载下抛可操作错误,而非返回残缺用户。
assert.throws(() => parseCurrentUser(null), /缺少有效 id|请求失败/)
})
test('test_task_028_current_user_init_boundary_single_item', () => {
// 边界单元素:单个 super_admin 用户被正确解析写入。
const user = parseCurrentUser({ success: true, data: { item: { id: 7, username: 'root', role: 'super_admin' } } })
assert.equal(user.id, 7)
assert.equal(user.username, 'root')
})
test('test_task_028_current_user_init_boundary_limit_or_missing_field', () => {
// 边界上限/缺字段:成功但字段缺失时不崩溃;初始化失败会向上抛由守卫处理。
const user = parseCurrentUser({ data: { item: { id: 2, username: '', role: '' } } })
assert.equal(user.username, '')
})
test('test_task_028_current_user_init_invalid_input_rejected', () => {
// 异常输入:后端 401/失败信封被拒绝并带 message。
assert.throws(() => parseCurrentUser({ success: false, code: 401, message: '未登录' }), /未登录/)
assert.throws(() => parseCurrentUser({ data: { item: { username: 'no-id' } } }), /缺少有效 id/)
})
test('test_task_028_current_user_init_dependency_failure_returns_actionable_message', () => {
// 依赖失败:store 复用会话适配器 fetchCurrentUser(内部走 parseCurrentUser + http)。
assert.match(store, /import \{ fetchAdminMenuTree, fetchCurrentUser, logout \} from '@\/api\/session'/)
const session = readSource('src/api/session.ts')
assert.match(session, /fetchCurrentUser/)
assert.match(session, /\/api\/admin\/current-user/)
})