zhou zhou
15 小时以前 40905cbd04c2e332cd4bc2b9e0c5b3e1da9cccfa
rsf-design/tests/system-manage-contract.test.mjs
@@ -1,20 +1,147 @@
import assert from 'node:assert/strict'
import { register } from 'node:module'
import test from 'node:test'
import { buildUserListParams, buildRoleListParams } from '../src/api/system-manage.js'
const menuTreeFixture = [
  {
    id: 1,
    parentId: 0,
    name: 'menu.user',
    route: 'user',
    type: 0,
    component: 'user',
    authority: 'system:user',
    icon: 'People',
    sort: 1,
    status: 1,
    memo: 'User menu',
    children: [
      {
        id: 2,
        parentId: 1,
        name: 'Query User',
        type: 1,
        authority: 'system:user:list',
        icon: 'Search',
        sort: 1,
        status: 0,
        memo: 'Query action'
      }
    ]
  }
]
register(
  `data:text/javascript,export function resolve(specifier, context, nextResolve){ if(specifier===\'@/utils/http\'){ return { shortCircuit:true, url:\'data:text/javascript,export default { get(){ return Promise.resolve({}) }, post(config){ if(config?.url===\\'/menu/list\\'){ globalThis.__lastMenuListConfig = config; return Promise.resolve(${JSON.stringify(menuTreeFixture.flatMap((node) => [node, ...node.children]))}) } if(config?.url===\\'/menu/tree\\'){ globalThis.__lastMenuTreeConfig = config; return Promise.resolve(${JSON.stringify(menuTreeFixture)}) } return Promise.resolve(config) } }\' } } return nextResolve(specifier, context) }`,
  import.meta.url
)
const {
  buildUserListParams,
  buildRoleListParams,
  fetchDeleteMenu,
  fetchGetMenuList,
  fetchGetMenuTree,
  fetchResetUserPassword,
  fetchGetRoleScopeList,
  fetchGetRoleScopeTree,
  fetchSaveMenu,
  fetchUpdateMenu
} = await import('../src/api/system-manage.js')
test('buildUserListParams matches the rsf-admin paging contract', () => {
  assert.equal(typeof buildUserListParams, 'function')
  assert.equal(typeof buildRoleListParams, 'function')
  assert.deepEqual(
    buildUserListParams({
      current: 2,
      pageSize: 20,
      username: 'root',
      email: 'root@example.com',
      deptId: 3
    }),
    {
      current: 2,
      pageSize: 20,
      username: 'root',
      email: 'root@example.com',
      deptId: 3
    }
  )
})
test('fetchResetUserPassword requires an admin update payload', () => {
  assert.throws(() => fetchResetUserPassword(1), /object payload/i)
  assert.throws(() => fetchResetUserPassword({ id: 1 }), /password/i)
  return fetchResetUserPassword({ id: 1, newPassword: 'secret' }).then((config) => {
    assert.equal(config.params.password, 'secret')
  })
})
test('fetchGetMenuList folds button nodes into authList', async () => {
  const menuList = await fetchGetMenuList()
  assert.equal(menuList.length, 1)
  assert.equal(menuList[0].id, '1')
  assert.equal(menuList[0].parentId, '0')
  assert.equal(menuList[0].route, 'user')
  assert.equal(menuList[0].authority, 'system:user')
  assert.equal(menuList[0].status, 1)
  assert.equal(menuList[0].memo, 'User menu')
  assert.equal(menuList[0].meta.title, 'menus.user')
  assert.equal(menuList[0].component, 'user')
  assert.equal(menuList[0].meta.sort, 1)
  assert.equal(menuList[0].meta.isEnable, true)
  assert.deepEqual(menuList[0].meta.authList, [
    {
      id: '2',
      parentId: '1',
      parentName: '',
      name: 'Query User',
      title: 'Query User',
      route: '',
      component: '',
      authMark: 'system:user:list',
      authority: 'system:user:list',
      icon: 'Search',
      sort: 1,
      status: 0,
      memo: 'Query action',
      type: 1
    }
  ])
  assert.equal(menuList[0].children.length, 0)
  assert.deepEqual(globalThis.__lastMenuListConfig?.params, {})
})
test('menu tree helpers always send an explicit empty body for Spring Map request bodies', async () => {
  await fetchGetMenuTree()
  assert.deepEqual(globalThis.__lastMenuTreeConfig?.params, {})
  await fetchGetRoleScopeTree('menu')
  assert.equal(globalThis.__lastMenuTreeConfig?.url, '/menu/tree')
  assert.deepEqual(globalThis.__lastMenuTreeConfig?.params, {})
})
test('menu CRUD helpers target the real rsf-server endpoints', async () => {
  assert.equal(typeof fetchSaveMenu, 'function')
  assert.equal(typeof fetchUpdateMenu, 'function')
  assert.equal(typeof fetchDeleteMenu, 'function')
  const saveConfig = await fetchSaveMenu({ name: '菜单' })
  const updateConfig = await fetchUpdateMenu({ id: 1, name: '菜单' })
  const deleteConfig = await fetchDeleteMenu('1,2')
  assert.equal(saveConfig.url, '/menu/save')
  assert.deepEqual(saveConfig.params, { name: '菜单' })
  assert.equal(updateConfig.url, '/menu/update')
  assert.deepEqual(updateConfig.params, { id: 1, name: '菜单' })
  assert.equal(deleteConfig.url, '/menu/remove/1,2')
})
test('scope resolvers fail fast on invalid scope types', () => {
  assert.throws(() => fetchGetRoleScopeList('invalid', 1), /Unsupported scope type/i)
  assert.throws(() => fetchGetRoleScopeTree('invalid', {}), /Unsupported scope type/i)
})