feat: 对齐管理员菜单排序与默认首页
This commit is contained in:
parent
828a321bdb
commit
7056663fe0
2
API.md
2
API.md
@ -149,6 +149,8 @@ QQBot 插件 worker 队列依赖 Redis。K8s 生产清单提供内部 Redis Serv
|
|||||||
| `PUT` | `/system/user/:id` | 更新用户 |
|
| `PUT` | `/system/user/:id` | 更新用户 |
|
||||||
| `DELETE` | `/system/user/:id` | 删除用户 |
|
| `DELETE` | `/system/user/:id` | 删除用户 |
|
||||||
|
|
||||||
|
系统菜单实体包含 `sort` 字段;菜单树输出按 `meta.order` 优先,其次按 `sort` 升序排列。Admin 菜单管理页面维护 `sort`,不要把普通菜单排序写进隐藏的 route meta。
|
||||||
|
|
||||||
### Dict
|
### Dict
|
||||||
|
|
||||||
| 方法 | 路径 | 说明 |
|
| 方法 | 路径 | 说明 |
|
||||||
|
|||||||
@ -7,7 +7,6 @@ UPDATE `admin_menu`
|
|||||||
SET `meta` = CASE `name`
|
SET `meta` = CASE `name`
|
||||||
WHEN 'Dashboard' THEN '{"order":-1,"title":"page.dashboard.title"}'
|
WHEN 'Dashboard' THEN '{"order":-1,"title":"page.dashboard.title"}'
|
||||||
WHEN 'Analytics' THEN '{"affixTab":true,"title":"page.dashboard.analytics"}'
|
WHEN 'Analytics' THEN '{"affixTab":true,"title":"page.dashboard.analytics"}'
|
||||||
WHEN 'Workspace' THEN '{"icon":"carbon:workspace","title":"page.dashboard.workspace"}'
|
|
||||||
WHEN 'System' THEN '{"badge":"new","badgeType":"normal","badgeVariants":"primary","icon":"carbon:settings","order":9997,"title":"system.title"}'
|
WHEN 'System' THEN '{"badge":"new","badgeType":"normal","badgeVariants":"primary","icon":"carbon:settings","order":9997,"title":"system.title"}'
|
||||||
WHEN 'SystemRole' THEN '{"icon":"carbon:user-role","title":"system.role.title"}'
|
WHEN 'SystemRole' THEN '{"icon":"carbon:user-role","title":"system.role.title"}'
|
||||||
WHEN 'SystemRoleCreate' THEN '{"title":"common.create"}'
|
WHEN 'SystemRoleCreate' THEN '{"title":"common.create"}'
|
||||||
@ -34,7 +33,6 @@ END
|
|||||||
WHERE `name` IN (
|
WHERE `name` IN (
|
||||||
'Dashboard',
|
'Dashboard',
|
||||||
'Analytics',
|
'Analytics',
|
||||||
'Workspace',
|
|
||||||
'System',
|
'System',
|
||||||
'SystemRole',
|
'SystemRole',
|
||||||
'SystemRoleCreate',
|
'SystemRoleCreate',
|
||||||
|
|||||||
@ -47,16 +47,16 @@ INSERT INTO admin_user (
|
|||||||
status
|
status
|
||||||
) VALUES (
|
) VALUES (
|
||||||
2041700000000000002,
|
2041700000000000002,
|
||||||
'admin',
|
'kwitsukasa',
|
||||||
'123456',
|
'123456',
|
||||||
'Admin',
|
'KwiTsukasa',
|
||||||
'',
|
'',
|
||||||
2041700000000200001,
|
2041700000000200001,
|
||||||
'/workspace',
|
'/analytics',
|
||||||
'Asia/Shanghai',
|
'Asia/Shanghai',
|
||||||
1
|
1
|
||||||
) ON DUPLICATE KEY UPDATE
|
) ON DUPLICATE KEY UPDATE
|
||||||
password = VALUES(password),
|
username = VALUES(username),
|
||||||
real_name = VALUES(real_name),
|
real_name = VALUES(real_name),
|
||||||
avatar = VALUES(avatar),
|
avatar = VALUES(avatar),
|
||||||
dept_id = VALUES(dept_id),
|
dept_id = VALUES(dept_id),
|
||||||
@ -84,7 +84,7 @@ INSERT INTO admin_menu (
|
|||||||
'Dashboard',
|
'Dashboard',
|
||||||
'/dashboard',
|
'/dashboard',
|
||||||
NULL,
|
NULL,
|
||||||
'/workspace',
|
'/analytics',
|
||||||
NULL,
|
NULL,
|
||||||
'catalog',
|
'catalog',
|
||||||
'{"order":-1,"title":"page.dashboard.title"}',
|
'{"order":-1,"title":"page.dashboard.title"}',
|
||||||
@ -92,15 +92,15 @@ INSERT INTO admin_menu (
|
|||||||
0
|
0
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
2041700000000100102,
|
2041700000000100101,
|
||||||
2041700000000100001,
|
2041700000000100001,
|
||||||
'Workspace',
|
'Analytics',
|
||||||
'/workspace',
|
'/analytics',
|
||||||
'/dashboard/workspace/index',
|
'/dashboard/analytics/index',
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
'menu',
|
'menu',
|
||||||
'{"icon":"carbon:workspace","title":"page.dashboard.workspace"}',
|
'{"affixTab":true,"title":"page.dashboard.analytics"}',
|
||||||
1,
|
1,
|
||||||
0
|
0
|
||||||
),
|
),
|
||||||
|
|||||||
@ -210,7 +210,6 @@ INSERT INTO `admin_menu` (`id`, `pid`, `name`, `path`, `component`, `redirect`,
|
|||||||
VALUES
|
VALUES
|
||||||
(2041700000000100001, 0, 'Dashboard', '/dashboard', NULL, '/analytics', NULL, 'catalog', '{"order":-1,"title":"page.dashboard.title"}', 1, 0),
|
(2041700000000100001, 0, 'Dashboard', '/dashboard', NULL, '/analytics', NULL, 'catalog', '{"order":-1,"title":"page.dashboard.title"}', 1, 0),
|
||||||
(2041700000000100101, 2041700000000100001, 'Analytics', '/analytics', '/dashboard/analytics/index', NULL, NULL, 'menu', '{"affixTab":true,"title":"page.dashboard.analytics"}', 1, 0),
|
(2041700000000100101, 2041700000000100001, 'Analytics', '/analytics', '/dashboard/analytics/index', NULL, NULL, 'menu', '{"affixTab":true,"title":"page.dashboard.analytics"}', 1, 0),
|
||||||
(2041700000000100102, 2041700000000100001, 'Workspace', '/workspace', '/dashboard/workspace/index', NULL, NULL, 'menu', '{"icon":"carbon:workspace","title":"page.dashboard.workspace"}', 1, 0),
|
|
||||||
(2041700000000100002, 0, 'System', '/system', NULL, NULL, NULL, 'catalog', '{"badge":"new","badgeType":"normal","badgeVariants":"primary","icon":"carbon:settings","order":9997,"title":"system.title"}', 1, 9997),
|
(2041700000000100002, 0, 'System', '/system', NULL, NULL, NULL, 'catalog', '{"badge":"new","badgeType":"normal","badgeVariants":"primary","icon":"carbon:settings","order":9997,"title":"system.title"}', 1, 9997),
|
||||||
(2041700000000100199, 2041700000000100002, 'SystemUser', '/system/user', '/system/user/list', NULL, 'System:User:List', 'menu', '{"icon":"carbon:user-profile","title":"system.user.title"}', 1, 0),
|
(2041700000000100199, 2041700000000100002, 'SystemUser', '/system/user', '/system/user/list', NULL, 'System:User:List', 'menu', '{"icon":"carbon:user-profile","title":"system.user.title"}', 1, 0),
|
||||||
(2041700000000120191, 2041700000000100199, 'SystemUserCreate', NULL, NULL, NULL, 'System:User:Create', 'button', '{"title":"common.create"}', 1, 0),
|
(2041700000000120191, 2041700000000100199, 'SystemUserCreate', NULL, NULL, NULL, 'System:User:Create', 'button', '{"title":"common.create"}', 1, 0),
|
||||||
@ -277,7 +276,7 @@ ON DUPLICATE KEY UPDATE
|
|||||||
INSERT INTO `admin_role` (`id`, `role_code`, `name`, `remark`, `status`)
|
INSERT INTO `admin_role` (`id`, `role_code`, `name`, `remark`, `status`)
|
||||||
VALUES
|
VALUES
|
||||||
(2041700000000010001, 'super', '超级管理员', '拥有所有后台权限', 1),
|
(2041700000000010001, 'super', '超级管理员', '拥有所有后台权限', 1),
|
||||||
(2041700000000010002, 'admin', '管理员', '拥有系统管理与工作台权限', 1),
|
(2041700000000010002, 'admin', '管理员', '拥有系统管理与环境总览权限', 1),
|
||||||
(2041700000000010003, 'user', '普通用户', '仅拥有基础查看权限', 1)
|
(2041700000000010003, 'user', '普通用户', '仅拥有基础查看权限', 1)
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
`name` = VALUES(`name`),
|
`name` = VALUES(`name`),
|
||||||
@ -287,11 +286,9 @@ ON DUPLICATE KEY UPDATE
|
|||||||
|
|
||||||
INSERT INTO `admin_user` (`id`, `username`, `password`, `real_name`, `avatar`, `dept_id`, `home_path`, `timezone`, `status`)
|
INSERT INTO `admin_user` (`id`, `username`, `password`, `real_name`, `avatar`, `dept_id`, `home_path`, `timezone`, `status`)
|
||||||
VALUES
|
VALUES
|
||||||
(2041700000000000001, 'vben', '123456', 'Vben', '', 2041700000000200002, '/workspace', 'Asia/Shanghai', 1),
|
(2041700000000000002, 'kwitsukasa', '123456', 'KwiTsukasa', '', 2041700000000200001, '/analytics', 'Asia/Shanghai', 1)
|
||||||
(2041700000000000002, 'admin', '123456', 'Admin', '', 2041700000000200001, '/workspace', 'Asia/Shanghai', 1),
|
|
||||||
(2041700000000000003, 'jack', '123456', 'Jack', '', 2041700000000200003, '/analytics', 'Asia/Shanghai', 1)
|
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
`password` = VALUES(`password`),
|
`username` = VALUES(`username`),
|
||||||
`real_name` = VALUES(`real_name`),
|
`real_name` = VALUES(`real_name`),
|
||||||
`dept_id` = VALUES(`dept_id`),
|
`dept_id` = VALUES(`dept_id`),
|
||||||
`home_path` = VALUES(`home_path`),
|
`home_path` = VALUES(`home_path`),
|
||||||
@ -331,16 +328,12 @@ ON DUPLICATE KEY UPDATE
|
|||||||
|
|
||||||
DELETE FROM `admin_user_role`
|
DELETE FROM `admin_user_role`
|
||||||
WHERE `user_id` IN (
|
WHERE `user_id` IN (
|
||||||
2041700000000000001,
|
2041700000000000002
|
||||||
2041700000000000002,
|
|
||||||
2041700000000000003
|
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO `admin_user_role` (`user_id`, `role_id`)
|
INSERT INTO `admin_user_role` (`user_id`, `role_id`)
|
||||||
VALUES
|
VALUES
|
||||||
(2041700000000000001, 2041700000000010001),
|
(2041700000000000002, 2041700000000010002);
|
||||||
(2041700000000000002, 2041700000000010002),
|
|
||||||
(2041700000000000003, 2041700000000010003);
|
|
||||||
|
|
||||||
DELETE FROM `admin_role_menu`
|
DELETE FROM `admin_role_menu`
|
||||||
WHERE `role_id` IN (
|
WHERE `role_id` IN (
|
||||||
|
|||||||
@ -210,6 +210,7 @@ export class AdminMenuService {
|
|||||||
pid: data.pid || '0',
|
pid: data.pid || '0',
|
||||||
redirect: data.redirect || null,
|
redirect: data.redirect || null,
|
||||||
status: data.status ?? 1,
|
status: data.status ?? 1,
|
||||||
|
sort: Number(data.sort ?? 0),
|
||||||
type: data.type || 'menu',
|
type: data.type || 'menu',
|
||||||
};
|
};
|
||||||
if (includeEmptyMeta || Object.keys(meta).length > 0) {
|
if (includeEmptyMeta || Object.keys(meta).length > 0) {
|
||||||
@ -321,6 +322,7 @@ export class AdminMenuService {
|
|||||||
pid: menu.pid || '0',
|
pid: menu.pid || '0',
|
||||||
redirect: menu.redirect,
|
redirect: menu.redirect,
|
||||||
status: menu.status,
|
status: menu.status,
|
||||||
|
sort: menu.sort,
|
||||||
type: menu.type,
|
type: menu.type,
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,9 @@ import type {
|
|||||||
AdminUserListQuery,
|
AdminUserListQuery,
|
||||||
} from '../../contract/admin.types';
|
} from '../../contract/admin.types';
|
||||||
|
|
||||||
|
const BUILTIN_ADMIN_USER_ID = '2041700000000000002';
|
||||||
|
const DEFAULT_ADMIN_HOME_PATH = '/analytics';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AdminUserService {
|
export class AdminUserService {
|
||||||
/**
|
/**
|
||||||
@ -97,7 +100,7 @@ export class AdminUserService {
|
|||||||
|
|
||||||
const user = this.userRepository.create({
|
const user = this.userRepository.create({
|
||||||
deptId: data.deptId || null,
|
deptId: data.deptId || null,
|
||||||
homePath: data.homePath || '/workspace',
|
homePath: data.homePath || DEFAULT_ADMIN_HOME_PATH,
|
||||||
password: data.password || '123456',
|
password: data.password || '123456',
|
||||||
realName: data.realName,
|
realName: data.realName,
|
||||||
status: data.status ?? 1,
|
status: data.status ?? 1,
|
||||||
@ -156,7 +159,11 @@ export class AdminUserService {
|
|||||||
if (id === currentUserId) {
|
if (id === currentUserId) {
|
||||||
throwVbenError('不能删除当前登录用户', HttpStatus.BAD_REQUEST);
|
throwVbenError('不能删除当前登录用户', HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
if (user.username === 'admin') {
|
if (
|
||||||
|
user.id === BUILTIN_ADMIN_USER_ID ||
|
||||||
|
user.username === 'admin' ||
|
||||||
|
user.username === 'kwitsukasa'
|
||||||
|
) {
|
||||||
throwVbenError('不能删除内置管理员账号', HttpStatus.BAD_REQUEST);
|
throwVbenError('不能删除内置管理员账号', HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +190,8 @@ export class AdminUserService {
|
|||||||
user.realName = realName;
|
user.realName = realName;
|
||||||
}
|
}
|
||||||
if (data.homePath !== undefined) {
|
if (data.homePath !== undefined) {
|
||||||
user.homePath = String(data.homePath || '').trim() || '/workspace';
|
user.homePath =
|
||||||
|
String(data.homePath || '').trim() || DEFAULT_ADMIN_HOME_PATH;
|
||||||
}
|
}
|
||||||
if (data.avatar !== undefined) {
|
if (data.avatar !== undefined) {
|
||||||
user.avatar = String(data.avatar || '').trim();
|
user.avatar = String(data.avatar || '').trim();
|
||||||
|
|||||||
@ -65,6 +65,75 @@ describe('AdminMenuService', () => {
|
|||||||
expect.arrayContaining(['Blog:Theme:List', 'Blog:Theme:Import']),
|
expect.arrayContaining(['Blog:Theme:List', 'Blog:Theme:Import']),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns and orders menus by the persisted sort field', async () => {
|
||||||
|
const service = new AdminMenuService({
|
||||||
|
find: jest.fn(async () => [
|
||||||
|
createMenu({
|
||||||
|
id: '2',
|
||||||
|
meta: { title: 'Second' },
|
||||||
|
name: 'Second',
|
||||||
|
path: '/second',
|
||||||
|
sort: 20,
|
||||||
|
type: 'menu',
|
||||||
|
}),
|
||||||
|
createMenu({
|
||||||
|
id: '1',
|
||||||
|
meta: { title: 'First' },
|
||||||
|
name: 'First',
|
||||||
|
path: '/first',
|
||||||
|
sort: 10,
|
||||||
|
type: 'menu',
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
} as any);
|
||||||
|
const user = {
|
||||||
|
roles: [
|
||||||
|
{
|
||||||
|
isDeleted: false,
|
||||||
|
roleCode: 'super',
|
||||||
|
status: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as AdminUser;
|
||||||
|
|
||||||
|
await expect(service.getRouteMenus(user)).resolves.toEqual([
|
||||||
|
expect.objectContaining({ name: 'First', sort: 10 }),
|
||||||
|
expect.objectContaining({ name: 'Second', sort: 20 }),
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('persists menu sort values from create and update inputs', async () => {
|
||||||
|
const repository = {
|
||||||
|
create: jest.fn((input) => input),
|
||||||
|
save: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
|
};
|
||||||
|
const service = new AdminMenuService(repository as any);
|
||||||
|
|
||||||
|
await service.createMenu({
|
||||||
|
name: 'SortedMenu',
|
||||||
|
path: '/sorted',
|
||||||
|
sort: 8,
|
||||||
|
type: 'menu',
|
||||||
|
} as any);
|
||||||
|
await service.updateMenu('menu-1', {
|
||||||
|
name: 'SortedMenu',
|
||||||
|
path: '/sorted',
|
||||||
|
sort: 9,
|
||||||
|
type: 'menu',
|
||||||
|
} as any);
|
||||||
|
|
||||||
|
expect(repository.create).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ sort: 8 }),
|
||||||
|
);
|
||||||
|
expect(repository.update).toHaveBeenCalledWith(
|
||||||
|
{
|
||||||
|
id: 'menu-1',
|
||||||
|
},
|
||||||
|
expect.objectContaining({ sort: 9 }),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -10,6 +10,10 @@ describe('admin user avatar sql', () => {
|
|||||||
join(process.cwd(), 'sql/vben-admin-init.sql'),
|
join(process.cwd(), 'sql/vben-admin-init.sql'),
|
||||||
'utf8',
|
'utf8',
|
||||||
);
|
);
|
||||||
|
const refactorSeedSql = readFileSync(
|
||||||
|
join(process.cwd(), 'sql/refactor-v3/01-seed-core.sql'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
it('adds avatar column for existing databases', () => {
|
it('adds avatar column for existing databases', () => {
|
||||||
expect(avatarSql).toContain("COLUMN_NAME = 'avatar'");
|
expect(avatarSql).toContain("COLUMN_NAME = 'avatar'");
|
||||||
@ -25,4 +29,17 @@ describe('admin user avatar sql', () => {
|
|||||||
);
|
);
|
||||||
expect(initSql).not.toContain('`avatar` = VALUES(`avatar`)');
|
expect(initSql).not.toContain('`avatar` = VALUES(`avatar`)');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('seeds the renamed administrator and removes the fake workspace menu', () => {
|
||||||
|
expect(initSql).toContain("'kwitsukasa', '123456', 'KwiTsukasa'");
|
||||||
|
expect(initSql).toContain("'/analytics', 'Asia/Shanghai'");
|
||||||
|
expect(initSql).toContain("'Analytics', '/analytics'");
|
||||||
|
expect(initSql).not.toContain("'vben', '123456'");
|
||||||
|
expect(initSql).not.toContain("'jack', '123456'");
|
||||||
|
expect(initSql).not.toContain("'Workspace'");
|
||||||
|
expect(initSql).not.toContain("'/workspace'");
|
||||||
|
expect(initSql).toContain('`username` = VALUES(`username`)');
|
||||||
|
expect(initSql).not.toContain('`password` = VALUES(`password`)');
|
||||||
|
expect(refactorSeedSql).not.toContain('password = VALUES(password)');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,8 +2,10 @@ import { AdminUserService } from '../../src/modules/admin/identity/user/admin-us
|
|||||||
|
|
||||||
describe('AdminUserService profile', () => {
|
describe('AdminUserService profile', () => {
|
||||||
const userRepository = {
|
const userRepository = {
|
||||||
|
create: jest.fn((input) => ({ ...input })),
|
||||||
findOne: jest.fn(),
|
findOne: jest.fn(),
|
||||||
save: jest.fn(),
|
save: jest.fn(),
|
||||||
|
update: jest.fn(),
|
||||||
};
|
};
|
||||||
const roleRepository = {
|
const roleRepository = {
|
||||||
find: jest.fn(),
|
find: jest.fn(),
|
||||||
@ -22,10 +24,33 @@ describe('AdminUserService profile', () => {
|
|||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses environment overview as the default home path for created users', async () => {
|
||||||
|
userRepository.findOne.mockResolvedValue(null);
|
||||||
|
roleRepository.find.mockResolvedValue([]);
|
||||||
|
|
||||||
|
await service.createUser({
|
||||||
|
realName: '新用户',
|
||||||
|
roleIds: [],
|
||||||
|
username: 'new-user',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(userRepository.create).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
homePath: '/analytics',
|
||||||
|
username: 'new-user',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(userRepository.save).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
homePath: '/analytics',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('updates current profile fields including uploaded avatar url', async () => {
|
it('updates current profile fields including uploaded avatar url', async () => {
|
||||||
const user = {
|
const user = {
|
||||||
avatar: '',
|
avatar: '',
|
||||||
homePath: '/workspace',
|
homePath: '/analytics',
|
||||||
id: '2041700000000000001',
|
id: '2041700000000000001',
|
||||||
realName: '旧姓名',
|
realName: '旧姓名',
|
||||||
roles: [],
|
roles: [],
|
||||||
@ -61,11 +86,51 @@ describe('AdminUserService profile', () => {
|
|||||||
expect(result).toEqual(user);
|
expect(result).toEqual(user);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('falls back to environment overview when current profile clears home path', async () => {
|
||||||
|
const user = {
|
||||||
|
avatar: '',
|
||||||
|
homePath: '/profile',
|
||||||
|
id: '2041700000000000002',
|
||||||
|
realName: 'KwiTsukasa',
|
||||||
|
roles: [],
|
||||||
|
timezone: 'Asia/Shanghai',
|
||||||
|
username: 'kwitsukasa',
|
||||||
|
};
|
||||||
|
userRepository.findOne.mockResolvedValue(user);
|
||||||
|
|
||||||
|
await service.updateCurrentProfile(user.id, {
|
||||||
|
homePath: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(userRepository.save).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
homePath: '/analytics',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prevents deleting the renamed built-in administrator account', async () => {
|
||||||
|
userRepository.findOne.mockResolvedValue({
|
||||||
|
id: '2041700000000000002',
|
||||||
|
isDeleted: false,
|
||||||
|
username: 'kwitsukasa',
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(service.deleteUser('2041700000000000002')).rejects.toMatchObject(
|
||||||
|
{
|
||||||
|
response: expect.objectContaining({
|
||||||
|
msg: '不能删除内置管理员账号',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(userRepository.update).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('serializes avatar and userId for Admin frontend user store', () => {
|
it('serializes avatar and userId for Admin frontend user store', () => {
|
||||||
expect(
|
expect(
|
||||||
service.serializeUser({
|
service.serializeUser({
|
||||||
avatar: '/api/minio/download?objectName=avatars%2Favatar.jpg',
|
avatar: '/api/minio/download?objectName=avatars%2Favatar.jpg',
|
||||||
homePath: '/workspace',
|
homePath: '/analytics',
|
||||||
id: '2041700000000000001',
|
id: '2041700000000000001',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
roles: [],
|
roles: [],
|
||||||
@ -74,7 +139,7 @@ describe('AdminUserService profile', () => {
|
|||||||
} as any),
|
} as any),
|
||||||
).toEqual({
|
).toEqual({
|
||||||
avatar: '/api/minio/download?objectName=avatars%2Favatar.jpg',
|
avatar: '/api/minio/download?objectName=avatars%2Favatar.jpg',
|
||||||
homePath: '/workspace',
|
homePath: '/analytics',
|
||||||
id: '2041700000000000001',
|
id: '2041700000000000001',
|
||||||
realName: '管理员',
|
realName: '管理员',
|
||||||
roles: [],
|
roles: [],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user