import test from 'node:test' import assert from 'node:assert/strict' import { readSource } from './helpers.ts' import { buildMenuManageTree, menuFormFromNode, menuParentChangeReason, parseMenuManageList, toMenuUpdateRequest, } from '../src/pages/account/menu-manage-model.ts' test('test_task_056_menu_edit_form_normal_primary_path', () => { // 正常主路径:从节点回填可编辑表单(含 parentId/routePath/sort)。 const node = parseMenuManageList([ { id: 4, name: '用户管理', column_key: 'account_users', parent_id: 1, route_path: '/account/users', sort_order: 2, menu_type: 'admin' }, ])[0] const form = menuFormFromNode(node) assert.equal(form.name, '用户管理') assert.equal(form.columnKey, 'account_users') assert.equal(form.parentId, 1) assert.equal(form.routePath, '/account/users') assert.equal(form.sortOrder, 2) }) test('test_task_056_menu_edit_form_normal_variant_input', () => { // 正常变体:根节点回填 parentId=null;权限标识/路由由后台自动生成,不随 update 请求体提交。 const node = parseMenuManageList([{ id: 1, name: '账号', column_key: 'account', parent_id: null, sort_order: 0 }])[0] const form = menuFormFromNode(node) assert.equal(form.parentId, null) assert.ok(!('columnKey' in toMenuUpdateRequest(form)), 'update 请求体不携带权限标识') }) test('test_task_056_menu_edit_form_normal_repeated_operation_is_idempotent', () => { // 正常重复:回填不改节点、结果稳定。 const node = parseMenuManageList([{ id: 5, name: 'A', column_key: 'a', parent_id: null, sort_order: 1 }])[0] assert.deepEqual(menuFormFromNode(node), menuFormFromNode(node)) assert.equal(node.name, 'A') }) test('test_task_056_menu_edit_form_boundary_empty_input', () => { // 边界空值:仅 id+name 节点回填,其余字段给默认,不崩溃。 const node = parseMenuManageList([{ id: 7, name: 'Only' }])[0] const form = menuFormFromNode(node) assert.equal(form.columnKey, '') assert.equal(form.routePath, '') assert.equal(form.sortOrder, 0) }) test('test_task_056_menu_edit_form_boundary_single_item', () => { // 边界单元素:单根节点可安全改父为根(null)。 const node = parseMenuManageList([{ id: 9, name: 'Only', column_key: 'only', parent_id: null }])[0] assert.equal(menuParentChangeReason(node, null), undefined) }) test('test_task_056_menu_edit_form_boundary_limit_or_missing_field', () => { // 边界上限/越权父:不能把自身/子孙设为父(防环)。 const tree = buildMenuManageTree( parseMenuManageList([ { id: 1, name: '根', column_key: 'root', parent_id: null }, { id: 2, name: '子', column_key: 'sub', parent_id: 1 }, { id: 3, name: '孙', column_key: 'leaf', parent_id: 2 }, ]), ) const root = tree[0] const sub = root.children?.[0]! const leaf = sub.children?.[0]! assert.match(menuParentChangeReason(sub, sub.id) || '', /自身/) assert.match(menuParentChangeReason(root, leaf.id) || '', /子菜单/) }) test('test_task_056_menu_edit_form_invalid_input_rejected', () => { // 异常输入:父选自身/子孙被拒;换父到合法节点(自身父=1)允许。 const node = parseMenuManageList([{ id: 1, name: 'A', column_key: 'a', parent_id: null }])[0] assert.ok(menuParentChangeReason(node, 1)) assert.equal(menuParentChangeReason(node, 99), undefined) }) test('test_task_056_menu_edit_form_dependency_failure_returns_actionable_message', () => { // 依赖失败/编辑走 adapter:PUT permission-menus/{id},页面用 updateMenu + 回填 + 防环校验。 const api = readSource('src/pages/account/menu-manage-api.ts') assert.match(api, /updateMenu/) assert.match(api, /http\.put/) assert.match(api, /permission-menus/) const page = readSource('src/pages/account/MenusPage.vue') assert.match(page, /updateMenu/) assert.match(page, /menuFormFromNode|menuParentChangeReason/) assert.equal(/http\.(get|post|put)|unwrap\(/.test(page), false, '页面不内联请求') })