Files
crawler-plugin/admin-frontend-vue/tests/align-edit-user-auth-guard.test.ts
huangzd1997 a4f60ef21c fix(权限): 用户菜单权限“自己没掉”——分区落库时级联清理跨类型误删 + 编辑弹窗空授权提交
- 级联清理的有效集改为按目标「完整直接授权」计算(读库,含 admin/app 全类型)。
  此前 admin/app 分区落库把本次提交的 id 当成完整有效集,员工持有的另一类型授权
  会整体被判越权删除;两次分区落库互相补刀,最终清空员工全部菜单权限
  (生产表现:保存某非超管的权限后,他直建员工的菜单隔三差五自己消失)
- AdminUserService 改为两类落库完成后再统一级联一次,新增 cascadeSubordinateOverreach 入口
- 后台「编辑用户」弹窗:授权未加载完成/失败时禁用保存并明确提示,
  避免以空 columnIds 整树清空该用户授权(改动密码等操作也会连带触发)
- 回归测试:deferredCascadeKeepsSubordinateGrantsOfOtherMenuType、
  perTypeReplacementDoesNotCascadeBeforeAllTypesWritten、edit_user_dialog_blocks_save_until_auth_loaded

已知既有红测试(与本次改动无关,干净 HEAD 上同样复现,未新增):
ArchitectureBoundaryTest.taskToBusinessDependencyDoesNotGrow(110 > 基线 84)、
HttpClientTimeoutEffectiveTest.connectTimeoutFiresOnUnreachableHost(本机网络环境 60s)
2026-09-13 14:18:01 +08:00

36 lines
1.7 KiB
TypeScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { readSource } from './helpers.ts'
// 回归(生产:用户菜单权限“自己没掉”):编辑用户弹窗打开时先把 columnIds 清空,再异步回填;
// 若授权尚未加载完成(或加载失败)就点保存,会把空数组提交成“清空授权”,整树权限被抹掉。
// 修复:授权未就绪时禁用保存并明确提示。
test('edit_user_dialog_blocks_save_until_auth_loaded', () => {
const dialog = readSource('src/pages/account/EditUserDialog.vue')
assert.match(dialog, /authReady/, '存在授权就绪标记')
assert.match(dialog, /authReady\.value = false/, '打开/失败时标记为未就绪')
// 加载失败分支必须保持未就绪:不能回退成“可以保存空授权”
const refreshBlock = dialog.slice(
dialog.indexOf('async function refreshAuth'),
dialog.indexOf('function close'),
)
assert.match(
refreshBlock,
/catch \(error\) \{[\s\S]*?authReady\.value = false/,
'授权加载失败保持未就绪,不用空数组覆盖服务端授权',
)
assert.match(refreshBlock, /authReady\.value = true/, '仅在加载成功后置为就绪')
// save() 自身兜底拦截,不依赖按钮禁用
const saveBlock = dialog.slice(dialog.indexOf('async function save'), dialog.indexOf('async function save') + 400)
assert.match(saveBlock, /if \(!authReady\.value\)/, '未就绪时直接拦截保存')
// 保存按钮在未就绪时禁用
assert.match(dialog, /:disabled="!authReady"/, '未就绪时保存按钮禁用')
assert.match(dialog, /加载中/, '加载中有提示')
assert.match(dialog, /保存已禁用/, '加载失败有明确提示')
})