From 40905cbd04c2e332cd4bc2b9e0c5b3e1da9cccfa Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期一, 30 三月 2026 08:17:32 +0800
Subject: [PATCH] feat: complete rsf-design phase 1 integration
---
rsf-design/tests/system-manage-contract.test.mjs | 129 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 128 insertions(+), 1 deletions(-)
diff --git a/rsf-design/tests/system-manage-contract.test.mjs b/rsf-design/tests/system-manage-contract.test.mjs
index c9879e9..f542a6b 100644
--- a/rsf-design/tests/system-manage-contract.test.mjs
+++ b/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)
+})
--
Gitblit v1.9.1