import test from 'node:test' import assert from 'node:assert/strict' import { readSource } from './helpers.ts' import { ADMIN_MENU_TYPE, emptyMenuManageForm, parseMenuManageItem, parseMenuManageList, toMenuCreateRequest, toMenuUpdateRequest, validateMenuManageForm, } from '../src/pages/account/menu-manage-model.ts' test('test_task_053_menu_manage_dto_normal_primary_path', () => { // 正常主路径:扁平 PermissionMenuItemVo(snake) 解析为可编辑菜单节点。 const node = parseMenuManageItem({ id: 12, name: '用户管理', column_key: 'account_users', parent_id: 1, root_column_key: 'account', menu_type: 'admin', route_path: '/account/users', sort_order: 3, }) assert.equal(node?.id, 12) assert.equal(node?.columnKey, 'account_users') assert.equal(node?.parentId, 1) assert.equal(node?.rootColumnKey, 'account') assert.equal(node?.menuType, 'admin') assert.equal(node?.routePath, '/account/users') assert.equal(node?.sortOrder, 3) }) test('test_task_053_menu_manage_dto_normal_variant_input', () => { // 正常变体:分组节点缺 route_path/sort 用默认;缺 id 行被过滤。 const node = parseMenuManageItem({ id: 20, name: '账号', column_key: 'account', parent_id: null }) assert.equal(node?.routePath, '') assert.equal(node?.sortOrder, 0) const list = parseMenuManageList([{ id: 21, name: 'x', column_key: 'k' }, { name: 'no-id' }]) assert.equal(list.length, 1) }) test('test_task_053_menu_manage_dto_normal_repeated_operation_is_idempotent', () => { // 正常重复:解析与序列化不改输入、结果稳定。 const raw = { id: 3, name: 'A', column_key: 'a', parent_id: null, sort_order: 1 } assert.deepEqual(toMenuCreateRequest(emptyMenuManageForm()), toMenuCreateRequest(emptyMenuManageForm())) const node = parseMenuManageItem(raw) assert.equal(node?.name, 'A') assert.equal((raw as { name: string }).name, 'A') }) test('test_task_053_menu_manage_dto_boundary_empty_input', () => { // 边界空值:空负载回空列表;缺省表单带 admin 类型与默认排序。 assert.deepEqual(parseMenuManageList({}), []) const form = emptyMenuManageForm() assert.equal(form.menuType, ADMIN_MENU_TYPE) assert.equal(form.sortOrder, 0) assert.equal(form.parentId, null) }) test('test_task_053_menu_manage_dto_boundary_single_item', () => { // 边界单元素:最小 id+name 可解析。 assert.equal(parseMenuManageItem({ id: 9, name: 'Only' })?.id, 9) }) test('test_task_053_menu_manage_dto_boundary_limit_or_missing_field', () => { // 边界上限/缺字段:请求体字段与 Java 对齐(必填含 menuType);权限标识/路由由后台自动生成,不随表单提交;排序取整。 const req = toMenuUpdateRequest({ ...emptyMenuManageForm(), name: 'n', columnKey: 'c', routePath: '/r', sortOrder: 2.7 }) assert.equal(req.sortOrder, 2) assert.ok('menuType' in req) assert.ok(!('routePath' in req), '路由由后台自动生成,不提交') assert.ok(!('columnKey' in req), '权限标识由后台自动生成,不提交') }) test('test_task_053_menu_manage_dto_invalid_input_rejected', () => { // 异常输入:必填缺失/空白给出与后端一致的校验文案。 const r = validateMenuManageForm(emptyMenuManageForm()) assert.equal(r.valid, false) assert.ok(r.errors.name) assert.ok(!('columnKey' in r.errors), '权限标识不参与表单校验(后台自动生成)') assert.ok(!('routePath' in r.errors), '路由不参与表单校验(后台自动生成)') assert.equal(parseMenuManageItem('garbage'), null) }) test('test_task_053_menu_manage_dto_dependency_failure_returns_actionable_message', () => { // 依赖失败/可操作:DTO 纯逻辑、字段与 Java create/update 请求一致、不内联 http。 const mod = readSource('src/pages/account/menu-manage-model.ts') assert.equal(/axios|http\./.test(mod), false, '菜单管理 DTO 保持纯逻辑') assert.match(mod, /columnKey/) assert.match(mod, /parentId/) assert.match(mod, /routePath/) assert.match(mod, /menuType/) })