1. 修复回滚父子角色功能时错误的代码逻辑,补全单元测试用例

2. 新增支持切换后业务菜单查询需限定只查询该公司业务数据能力
This commit is contained in:
chenbowen
2025-07-10 19:05:58 +08:00
parent 92959efdc6
commit 7f0957d9c4
60 changed files with 1749 additions and 64 deletions

View File

@@ -81,7 +81,7 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
assertPojoEquals(accessTokenDO, dbAccessTokenDO, "expiresTime", "createTime", "updateTime", "deleted");
assertEquals(userId, accessTokenDO.getUserId());
assertEquals(userType, accessTokenDO.getUserType());
assertEquals(2, accessTokenDO.getUserInfo().size());
assertEquals(6, accessTokenDO.getUserInfo().size());
assertEquals(user.getNickname(), accessTokenDO.getUserInfo().get("nickname"));
assertEquals(clientId, accessTokenDO.getClientId());
assertEquals(scopes, accessTokenDO.getScopes());

View File

@@ -1,12 +1,16 @@
package cn.iocoder.yudao.module.system.service.permission;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.rolemenuexclusion.RoleMenuExclusionDO;
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
import cn.iocoder.yudao.module.system.dal.mysql.rolemenuexclusion.RoleMenuExclusionMapper;
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
@@ -17,6 +21,7 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -25,6 +30,9 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Import({PermissionServiceImpl.class, RoleServiceImpl.class})
public class PermissionServiceTest extends BaseDbUnitTest {
@@ -35,6 +43,8 @@ public class PermissionServiceTest extends BaseDbUnitTest {
@Resource
private RoleMenuMapper roleMenuMapper;
@Resource
private RoleMenuExclusionMapper roleMenuExclusionMapper;
@Resource
private UserRoleMapper userRoleMapper;
@Resource
@@ -263,5 +273,114 @@ public class PermissionServiceTest extends BaseDbUnitTest {
// ========== 用户-部门的相关方法 ==========
// ========== 父子角色的相关方法 ==========
@Test
public void testGetAllParentAndSelfRoleIds() {
// mock 3层父子关系 A->B->C
RoleDO roleA = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(roleA);
RoleDO roleB = randomPojo(RoleDO.class, o -> o.setParentId(roleA.getId()));
roleMapper.insert(roleB);
RoleDO roleC = randomPojo(RoleDO.class, o -> o.setParentId(roleB.getId()));
roleMapper.insert(roleC);
// 调用 PermissionService 的父子角色链路能力
Set<Long> ids = roleService.getAllParentAndSelfRoleIds(asSet(roleC.getId()));
// 断言递归能拿到所有父节点和自身
assertEquals(asSet(roleA.getId(), roleB.getId(), roleC.getId()), ids);
}
@Test
public void testIsChildRole_trueAndFalse() {
// mock 3层父子关系 A->B->C
RoleDO roleA = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(roleA);
RoleDO roleB = randomPojo(RoleDO.class, o -> o.setParentId(roleA.getId()));
roleMapper.insert(roleB);
RoleDO roleC = randomPojo(RoleDO.class, o -> o.setParentId(roleB.getId()));
roleMapper.insert(roleC);
// 断言 C 是 A 的子孙节点
assertTrue(roleService.isChildRole(roleA.getId(), roleC.getId()));
// 断言 A 不是 C 的子孙节点
assertFalse(roleService.isChildRole(roleC.getId(), roleA.getId()));
}
@Test
public void testUpdateRole_parentIsChildException() {
// mock 2层父子关系 A->B
RoleDO roleA = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(roleA);
RoleDO roleB = randomPojo(RoleDO.class, o -> o.setParentId(roleA.getId()));
roleMapper.insert(roleB);
// 尝试把A的父节点改为B形成环
RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class, o -> o.setId(roleA.getId()).setParentId(roleB.getId()));
assertThrows(ServiceException.class, () -> roleService.updateRole(reqVO));
}
@Test
public void testChildRoleInheritParentRoleMenus() {
// mock 父子关系 A->B
RoleDO parentRole = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(parentRole);
RoleDO childRole = randomPojo(RoleDO.class, o -> o.setParentId(parentRole.getId()));
roleMapper.insert(childRole);
// 给父角色分配菜单
RoleMenuDO parentMenu1 = randomPojo(RoleMenuDO.class).setRoleId(parentRole.getId()).setMenuId(101L);
roleMenuMapper.insert(parentMenu1);
RoleMenuDO parentMenu2 = randomPojo(RoleMenuDO.class).setRoleId(parentRole.getId()).setMenuId(102L);
roleMenuMapper.insert(parentMenu2);
// 给子角色分配部分菜单
RoleMenuDO childMenu = randomPojo(RoleMenuDO.class).setRoleId(childRole.getId()).setMenuId(201L);
roleMenuMapper.insert(childMenu);
// 调用:获取子角色的所有菜单(应包含父角色的菜单)
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(childRole.getId());
// 断言:包含父角色和子角色自己的菜单
assertEquals(asSet(101L, 102L, 201L), menuIds);
}
@Test
public void testChildRoleExcludeParentMenu() {
// mock 父子关系 A->B
RoleDO parentRole = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(parentRole);
RoleDO childRole = randomPojo(RoleDO.class, o -> o.setParentId(parentRole.getId()));
roleMapper.insert(childRole);
// 父角色分配菜单
RoleMenuDO parentMenu = randomPojo(RoleMenuDO.class).setRoleId(parentRole.getId()).setMenuId(101L);
roleMenuMapper.insert(parentMenu);
// 子角色排除父菜单(模拟排除表)
RoleMenuExclusionDO exclusion = new RoleMenuExclusionDO();
exclusion.setRoleId(childRole.getId());
exclusion.setMenuId(101L);
roleMenuExclusionMapper.insert(exclusion);
// 调用:获取子角色菜单(应不包含父菜单)
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(childRole.getId());
assertFalse(menuIds.contains(101L));
}
@Test
public void testChildRoleRemoveExclusionThenInheritMenu() {
// mock 父子关系 A->B
RoleDO parentRole = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(parentRole);
RoleDO childRole = randomPojo(RoleDO.class, o -> o.setParentId(parentRole.getId()));
roleMapper.insert(childRole);
// 父角色分配菜单
RoleMenuDO parentMenu = randomPojo(RoleMenuDO.class).setRoleId(parentRole.getId()).setMenuId(101L);
roleMenuMapper.insert(parentMenu);
// 子角色排除父菜单
RoleMenuExclusionDO exclusion = new RoleMenuExclusionDO();
exclusion.setRoleId(childRole.getId());
exclusion.setMenuId(101L);
roleMenuExclusionMapper.insert(exclusion);
// 先断言排除
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(childRole.getId());
assertFalse(menuIds.contains(101L));
// 取消排除
roleMenuExclusionMapper.deleteListByRoleIdAndMenuIds(childRole.getId(), Collections.singleton(101L));
// 再次获取,应能继承
Set<Long> menuIds2 = permissionService.getRoleMenuListByRoleId(childRole.getId());
assertTrue(menuIds2.contains(101L));
}
}

View File

@@ -390,4 +390,122 @@ public class RoleServiceImplTest extends BaseDbUnitTest {
// 调用, 并断言异常
assertServiceException(() -> roleService.validateRoleList(ids), ROLE_IS_DISABLE, RoleDO.getName());
}
@Test
public void testIsChildRole_trueAndFalse() {
// mock 3层父子关系 A->B->C
RoleDO roleA = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(roleA);
RoleDO roleB = randomPojo(RoleDO.class, o -> o.setParentId(roleA.getId()));
roleMapper.insert(roleB);
RoleDO roleC = randomPojo(RoleDO.class, o -> o.setParentId(roleB.getId()));
roleMapper.insert(roleC);
// 断言 C 的 parentId 是 A 的子孙节点
assertTrue(roleService.getClass().cast(roleService).isChildRole(roleA.getId(), roleC.getId()));
// 断言 A 不是 C 的子孙节点
assertFalse(roleService.getClass().cast(roleService).isChildRole(roleC.getId(), roleA.getId()));
}
@Test
public void testGetAllParentAndSelfRoleIds_multiLevelAndLoop() {
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
.thenReturn(roleService);
// mock 3层父子关系 A->B->C
RoleDO roleA = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(roleA);
RoleDO roleB = randomPojo(RoleDO.class, o -> o.setParentId(roleA.getId()));
roleMapper.insert(roleB);
RoleDO roleC = randomPojo(RoleDO.class, o -> o.setParentId(roleB.getId()));
roleMapper.insert(roleC);
// 断言递归能拿到所有父节点
Set<Long> ids = roleService.getAllParentAndSelfRoleIds(singleton(roleC.getId()));
assertTrue(ids.contains(roleA.getId()));
assertTrue(ids.contains(roleB.getId()));
assertTrue(ids.contains(roleC.getId()));
// mock 环路C->A
roleC.setParentId(roleA.getId());
roleMapper.updateById(roleC);
// 不会死循环
Set<Long> idsLoop = roleService.getAllParentAndSelfRoleIds(singleton(roleC.getId()));
assertTrue(idsLoop.contains(roleA.getId()));
}
}
@Test
public void testHasAnyAdmin_trueAndFalse() {
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
.thenReturn(roleService);
// mock admin
RoleDO adminRole = randomPojo(RoleDO.class).setCode("super_admin");
roleMapper.insert(adminRole);
assertTrue(roleService.hasAnyAdmin(singletonList(adminRole.getId())));
// mock 普通
RoleDO normalRole = randomPojo(RoleDO.class).setCode("user");
roleMapper.insert(normalRole);
assertFalse(roleService.hasAnyAdmin(singletonList(normalRole.getId())));
}
}
@Test
public void testUpdateRole_parentIsChildException() {
// mock 2层父子关系 A->B
RoleDO roleA = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(roleA);
RoleDO roleB = randomPojo(RoleDO.class, o -> o.setParentId(roleA.getId()));
roleMapper.insert(roleB);
// 尝试把A的父节点改为B形成环
RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class, o -> o.setId(roleA.getId()).setParentId(roleB.getId()));
assertServiceException(() -> roleService.updateRole(reqVO), ROLE_PARENT_IS_CHILD, reqVO.getName());
}
@Test
public void testGetRoleListFromCache_empty() {
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
.thenReturn(roleService);
// 空集合
List<RoleDO> list = roleService.getRoleListFromCache(List.of());
assertTrue(list.isEmpty());
}
}
@Test
public void testValidateRoleList_empty() {
// 空集合
roleService.validateRoleList(List.of()); // 不抛异常
}
@Test
public void testUpdateRoleDataScope_roleNotExist() {
assertServiceException(() -> roleService.updateRoleDataScope(randomLongId(), 1, Set.of(1L)), ROLE_NOT_EXISTS);
}
@Test
public void testDeleteRole_hasChildrenException() {
// mock 父子关系
RoleDO parent = randomPojo(RoleDO.class, o -> o.setParentId(0L));
roleMapper.insert(parent);
RoleDO child = randomPojo(RoleDO.class, o -> o.setParentId(parent.getId()));
roleMapper.insert(child);
assertServiceException(() -> roleService.deleteRole(parent.getId()), ROLE_CAN_NOT_DELETE_HAS_CHILDREN, parent.getName());
}
@Test
public void testDeleteRole_roleNotExist() {
assertServiceException(() -> roleService.deleteRole(randomLongId()), ROLE_NOT_EXISTS);
}
@Test
public void testCreateRole_superAdminCodeError() {
RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class).setCode("super_admin");
assertServiceException(() -> roleService.createRole(reqVO, null), ROLE_ADMIN_CODE_ERROR, "super_admin");
}
@Test
public void testValidateRoleDuplicate_codeEmpty() {
// name 不重复code 为空
roleService.validateRoleDuplicate(randomString(), "", null); // 不抛异常
}
}

View File

@@ -18,11 +18,13 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.userdept.UserDeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.dal.mysql.userdept.UserDeptMapper;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.dept.DeptServiceImpl;
import cn.iocoder.yudao.module.system.service.dept.PostService;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
@@ -56,7 +58,7 @@ import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
@Import({AdminUserServiceImpl.class,UserDeptServiceImpl.class})
@Import({AdminUserServiceImpl.class,UserDeptServiceImpl.class,DeptServiceImpl.class})
public class AdminUserServiceImplTest extends BaseDbUnitTest {
@Resource
@@ -69,10 +71,11 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
@Resource
private UserDeptMapper userDeptMapper;
@Resource
private DeptMapper deptMapper;
@Resource
private UserDeptServiceImpl userDeptService;
@MockBean
private DeptService deptService;
@Resource
private DeptServiceImpl deptService;
@MockBean
private PostService postService;
@MockBean
@@ -99,7 +102,12 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
o.setMobile(randomString());
o.setPostIds(asSet(1L, 2L));
o.setDeptIds(asSet(1L, 2L));
}).setId(null); // 避免 id 被赋值
// 新建对应的部门
deptMapper.insert(randomPojo(DeptDO.class, o -> {o.setId(1L);o.setStatus(CommonStatusEnum.ENABLE.getStatus());}));
deptMapper.insert(randomPojo(DeptDO.class, o -> {o.setId(2L);o.setStatus(CommonStatusEnum.ENABLE.getStatus());}));
// mock 账户额度充足
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(1));
doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
@@ -147,16 +155,20 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
@Test
public void testUpdateUser_success() {
// mock 数据
AdminUserDO dbUser = randomAdminUserDO(o -> o.setPostIds(asSet(1L, 2L)));
AdminUserDO dbUser = randomAdminUserDO(o -> o.setPostIds(asSet(1L, 2L)).setDeptIds(asSet(1L, 2L)));
userMapper.insert(dbUser);
userPostMapper.insert(new UserPostDO().setUserId(dbUser.getId()).setPostId(1L));
userPostMapper.insert(new UserPostDO().setUserId(dbUser.getId()).setPostId(2L));
// 新增对应的部门
deptMapper.insert(randomPojo(DeptDO.class, o -> {o.setId(1L);o.setStatus(CommonStatusEnum.ENABLE.getStatus());}));
deptMapper.insert(randomPojo(DeptDO.class, o -> {o.setId(2L);o.setStatus(CommonStatusEnum.ENABLE.getStatus());}));
// 准备参数
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class, o -> {
o.setId(dbUser.getId());
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
o.setMobile(randomString());
o.setPostIds(asSet(2L, 3L));
o.setDeptIds(asSet(1L, 2L));
});
// mock postService 的方法
List<PostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
@@ -299,7 +311,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
// 调用
AdminUserDO user = userService.getUserByUsername(username);
// 断言
assertPojoEquals(dbUser, user,"deptIds");
assertPojoEquals(dbUser, user,"deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -313,7 +325,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
// 调用
AdminUserDO user = userService.getUserByMobile(mobile);
// 断言
assertPojoEquals(dbUser, user,"deptIds");
assertPojoEquals(dbUser, user,"deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -330,7 +342,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
// reqVO.setDeptId(1L); // 其中1L 是 2L 的父部门
// mock 方法
List<DeptDO> deptList = newArrayList(randomPojo(DeptDO.class, o -> o.setId(2L)));
when(deptService.getChildDeptList(eq(reqVO.getDeptId()))).thenReturn(deptList);
deptService.getChildDeptList(reqVO.getDeptId());
// 新增 1L 和用户关联关系
userDeptMapper.insert(new UserDeptDO().setUserId(dbUser.getId()).setDeptId(1L));
// 调用
@@ -338,7 +350,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbUser, pageResult.getList().get(0), "deptIds");
assertPojoEquals(dbUser, pageResult.getList().get(0), "deptIds", "companyIds", "companyDeptInfos");
}
/**
@@ -376,7 +388,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
// 调用
AdminUserDO user = userService.getUser(userId);
// 断言
assertPojoEquals(dbUser, user, "deptIds");
assertPojoEquals(dbUser, user, "deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -397,7 +409,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
List<AdminUserDO> list = userService.getUserListByDeptIds(deptIds);
// 断言
assertEquals(1, list.size());
assertPojoEquals(dbUser, list.get(0), "deptIds");
assertPojoEquals(dbUser, list.get(0), "deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -520,7 +532,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
List<AdminUserDO> result = userService.getUserListByPostIds(postIds);
// 断言
assertEquals(1, result.size());
assertPojoEquals(user1, result.get(0), "deptIds");
assertPojoEquals(user1, result.get(0), "deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -539,7 +551,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
List<AdminUserDO> result = userService.getUserList(ids);
// 断言
assertEquals(1, result.size());
assertPojoEquals(user, result.get(0), "deptIds");
assertPojoEquals(user, result.get(0), "deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -558,7 +570,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
Map<Long, AdminUserDO> result = userService.getUserMap(ids);
// 断言
assertEquals(1, result.size());
assertPojoEquals(user, result.get(user.getId()), "deptIds");
assertPojoEquals(user, result.get(user.getId()), "deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -575,7 +587,7 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
List<AdminUserDO> result = userService.getUserListByNickname(nickname);
// 断言
assertEquals(1, result.size());
assertPojoEquals(user, result.get(0),"deptIds");
assertPojoEquals(user, result.get(0),"deptIds", "companyIds", "companyDeptInfos");
}
@Test
@@ -588,15 +600,12 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
userMapper.insert(user2);
// 准备参数
Integer status = CommonStatusEnum.DISABLE.getStatus();
// 新增 1L 和用户关联关系 未关联 部门的用户无法被正确查询
userDeptMapper.insert(new UserDeptDO().setUserId(user2.getId()).setDeptId(1L));
userDeptMapper.insert(new UserDeptDO().setUserId(user.getId()).setDeptId(1L));
// 调用
List<AdminUserDO> result = userService.getUserListByStatus(status);
// 断言
assertEquals(1, result.size());
AdminUserDO user1 = userService.getUser(result.get(0).getId());
assertPojoEquals(user, user1, "deptIds");
assertPojoEquals(user, user1, "deptIds","companyIds","companyDeptInfos");
}
@Test
@@ -640,7 +649,8 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
Consumer<AdminUserDO> consumer = (o) -> {
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
o.setSex(randomEle(SexEnum.values()).getSex());
o.setDeptIds(new HashSet<>(asSet(1L, 2L))); // 保证 deptIds 的范围
o.setDeptIds(new HashSet<>(asSet(1L, 2L)));
o.setCompanyDeptInfos(null);// 保证 deptIds 的范围
};
return randomPojo(AdminUserDO.class, ArrayUtils.append(consumer, consumers));
}
@@ -651,4 +661,88 @@ public class AdminUserServiceImplTest extends BaseDbUnitTest {
return randomPojo(UserDeptDO.class, ArrayUtils.append(consumer, consumers));
}
@Test
public void testCreateUser_withMultipleDepts() {
// 构造带多个部门的用户
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class, o -> {
o.setDeptIds(asSet(1L, 2L, 3L));
o.setSex(1);
}).setId(null);
// 新建对应的部门
deptMapper.insert(new DeptDO().setId(1L).setName("部门1").setStatus(CommonStatusEnum.ENABLE.getStatus()));
deptMapper.insert(new DeptDO().setId(2L).setName("部门2").setStatus(CommonStatusEnum.ENABLE.getStatus()));
deptMapper.insert(new DeptDO().setId(3L).setName("部门3").setStatus(CommonStatusEnum.ENABLE.getStatus()));
// mock 账户额度充足、部门可用
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(1));
doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
handler.handle(tenant);
return true;
}));
List<PostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
randomPojo(PostDO.class, o -> {
o.setId(postId);
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
}));
when(postService.getPostList(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
when(passwordEncoder.encode(eq(reqVO.getPassword()))).thenReturn("yudaoyuanma");
// 调用
Long userId = userService.createUser(reqVO);
// 校验 user_dept 表有3条数据
List<UserDeptDO> userDepts = userDeptMapper.selectValidListByUserIds(singleton(userId));
assertEquals(3, userDepts.size());
assertTrue(userDepts.stream().anyMatch(ud -> ud.getDeptId().equals(1L)));
assertTrue(userDepts.stream().anyMatch(ud -> ud.getDeptId().equals(2L)));
assertTrue(userDepts.stream().anyMatch(ud -> ud.getDeptId().equals(3L)));
}
@Test
public void testUpdateUser_changeDepts() {
// 先插入用户和2个部门
AdminUserDO dbUser = randomAdminUserDO(o -> o.setDeptIds(asSet(1L, 2L)));
userMapper.insert(dbUser);
userDeptMapper.insert(new UserDeptDO().setUserId(dbUser.getId()).setDeptId(1L));
userDeptMapper.insert(new UserDeptDO().setUserId(dbUser.getId()).setDeptId(2L));
// 新建对应的部门
deptMapper.insert(new DeptDO().setId(1L).setName("部门1").setStatus(CommonStatusEnum.ENABLE.getStatus()));
deptMapper.insert(new DeptDO().setId(2L).setName("部门2").setStatus(CommonStatusEnum.ENABLE.getStatus()));
// 更新为3个新部门
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class, o -> {
o.setId(dbUser.getId());
o.setSex(1);
o.setDeptIds(asSet(1L, 2L));
});
// mock postService 的方法
List<PostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
randomPojo(PostDO.class, o -> {
o.setId(postId);
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
}));
when(postService.getPostList(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
// 调用
userService.updateUser(reqVO);
// 校验 user_dept 表
List<UserDeptDO> userDepts = userDeptMapper.selectValidListByUserIds(singleton(dbUser.getId()));
assertEquals(2, userDepts.size());
assertTrue(userDepts.stream().anyMatch(ud -> ud.getDeptId().equals(2L)));
assertTrue(userDepts.stream().anyMatch(ud -> ud.getDeptId().equals(1L)));
}
@Test
public void testGetUser_withMultipleDepts() {
// 插入用户和多个部门
AdminUserDO dbUser = randomAdminUserDO();
userMapper.insert(dbUser);
// 插入用户部门关系
userDeptMapper.insert(new UserDeptDO().setUserId(dbUser.getId()).setDeptId(1L));
userDeptMapper.insert(new UserDeptDO().setUserId(dbUser.getId()).setDeptId(2L));
// 插入部门
deptMapper.insert(new DeptDO().setId(1L).setName("部门1").setStatus(CommonStatusEnum.ENABLE.getStatus()));
deptMapper.insert(new DeptDO().setId(2L).setName("部门2").setStatus(CommonStatusEnum.ENABLE.getStatus()));
AdminUserDO user = userService.getUser(dbUser.getId());
assertTrue(user.getDeptIds().contains(1L));
assertTrue(user.getDeptIds().contains(2L));
}
}