From a13a2e7371dd83704fcb2f9dbc47fe6be8188f8c Mon Sep 17 00:00:00 2001 From: timfruit Date: Tue, 23 Mar 2021 22:40:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=8C=E6=88=90role=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/enums/SysErrorCodeConstants.java | 4 +- .../permission/impl/SysRoleServiceImpl.java | 9 +- .../permission/SysRoleServiceTest.java | 308 ++++++++++++++++++ 3 files changed, 316 insertions(+), 5 deletions(-) create mode 100644 src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleServiceTest.java diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java b/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java index 0197b6c05..05ea09672 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/enums/SysErrorCodeConstants.java @@ -30,8 +30,8 @@ public interface SysErrorCodeConstants { // ========== 角色模块 1002003000 ========== ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1002003000, "角色不存在"); - ErrorCode ROLE_NAME_DUPLICATE = new ErrorCode(1002003001, "已经存在名为【{}}】的角色"); - ErrorCode ROLE_CODE_DUPLICATE = new ErrorCode(1002003002, "已经存在编码为【{}}】的角色"); + ErrorCode ROLE_NAME_DUPLICATE = new ErrorCode(1002003001, "已经存在名为【{}】的角色"); + ErrorCode ROLE_CODE_DUPLICATE = new ErrorCode(1002003002, "已经存在编码为【{}】的角色"); ErrorCode ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE = new ErrorCode(1002003004, "不能操作类型为系统内置的角色"); // ========== 用户模块 1002004000 ========== diff --git a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java index e79813636..a940852fc 100644 --- a/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java +++ b/src/main/java/cn/iocoder/dashboard/modules/system/service/permission/impl/SysRoleServiceImpl.java @@ -18,6 +18,7 @@ import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum; import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysRoleProducer; import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; import cn.iocoder.dashboard.modules.system.service.permission.SysRoleService; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import lombok.extern.slf4j.Slf4j; import org.springframework.lang.Nullable; @@ -245,7 +246,8 @@ public class SysRoleServiceImpl implements SysRoleService { * @param code 角色额编码 * @param id 角色编号 */ - private void checkDuplicateRole(String name, String code, Long id) { + @VisibleForTesting + public void checkDuplicateRole(String name, String code, Long id) { // 1. 该 name 名字被其它角色所使用 SysRoleDO role = roleMapper.selectByName(name); if (role != null && !role.getId().equals(id)) { @@ -258,7 +260,7 @@ public class SysRoleServiceImpl implements SysRoleService { // 该 code 编码被其它角色所使用 role = roleMapper.selectByCode(code); if (role != null && !role.getId().equals(id)) { - throw ServiceExceptionUtil.exception(ROLE_CODE_DUPLICATE, name); + throw ServiceExceptionUtil.exception(ROLE_CODE_DUPLICATE, code); } } @@ -267,7 +269,8 @@ public class SysRoleServiceImpl implements SysRoleService { * * @param id 角色编号 */ - private void checkUpdateRole(Long id) { + @VisibleForTesting + public void checkUpdateRole(Long id) { SysRoleDO roleDO = roleMapper.selectById(id); if (roleDO == null) { throw ServiceExceptionUtil.exception(ROLE_NOT_EXISTS); diff --git a/src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleServiceTest.java b/src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleServiceTest.java new file mode 100644 index 000000000..f180f2b92 --- /dev/null +++ b/src/test/java/cn/iocoder/dashboard/modules/system/service/permission/SysRoleServiceTest.java @@ -0,0 +1,308 @@ +package cn.iocoder.dashboard.modules.system.service.permission; + +import cn.hutool.core.bean.BeanUtil; +import cn.iocoder.dashboard.BaseDbUnitTest; +import cn.iocoder.dashboard.common.enums.CommonStatusEnum; +import cn.iocoder.dashboard.common.pojo.PageResult; +import cn.iocoder.dashboard.framework.security.core.enums.DataScopeEnum; +import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.SysRoleCreateReqVO; +import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.SysRolePageReqVO; +import cn.iocoder.dashboard.modules.system.controller.permission.vo.role.SysRoleUpdateReqVO; +import cn.iocoder.dashboard.modules.system.dal.dataobject.permission.SysRoleDO; +import cn.iocoder.dashboard.modules.system.dal.mysql.permission.SysRoleMapper; +import cn.iocoder.dashboard.modules.system.enums.permission.SysRoleTypeEnum; +import cn.iocoder.dashboard.modules.system.mq.producer.permission.SysRoleProducer; +import cn.iocoder.dashboard.modules.system.service.permission.impl.SysRoleServiceImpl; +import cn.iocoder.dashboard.util.AopTargetUtils; +import cn.iocoder.dashboard.util.AssertUtils; +import cn.iocoder.dashboard.util.RandomUtils; +import cn.iocoder.dashboard.util.object.ObjectUtils; +import com.google.common.collect.Sets; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException; +import static cn.iocoder.dashboard.util.RandomUtils.*; +import static cn.iocoder.dashboard.util.object.ObjectUtils.max; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.verify; + +@Import(SysRoleServiceImpl.class) +public class SysRoleServiceTest extends BaseDbUnitTest { + + @Resource + private SysRoleServiceImpl sysRoleService; + + @Resource + private SysRoleMapper roleMapper; + + @MockBean + private SysPermissionService sysPermissionService; + + @MockBean + private SysRoleProducer sysRoleProducer; + + @Test + public void testInitLocalCache_success() throws Exception { + SysRoleDO roleDO1 = createRoleDO("role1", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO1); + SysRoleDO roleDO2 = createRoleDO("role2", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO2); + + //调用 + sysRoleService.initLocalCache(); + + //断言 + //获取代理对象 + SysRoleServiceImpl target = (SysRoleServiceImpl) AopTargetUtils.getTarget(sysRoleService); + + Map roleCache = (Map) BeanUtil.getFieldValue(target, "roleCache"); + assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId())); + assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId())); + + Date maxUpdateTime = (Date) BeanUtil.getFieldValue(target, "maxUpdateTime"); + assertEquals(max(roleDO1.getUpdateTime(), roleDO2.getUpdateTime()), maxUpdateTime); + } + + @Test + public void testCreateRole_success() { + SysRoleCreateReqVO reqVO = randomPojo(SysRoleCreateReqVO.class, o -> { + o.setCode("role_code"); + o.setName("role_name"); + o.setRemark("remark"); + o.setType(SysRoleTypeEnum.CUSTOM.getType()); + o.setSort(1); + }); + Long roleId = sysRoleService.createRole(reqVO); + + //断言 + assertNotNull(roleId); + SysRoleDO roleDO = roleMapper.selectById(roleId); + assertPojoEquals(reqVO, roleDO); + + verify(sysRoleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testUpdateRole_success() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO); + Long roleId = roleDO.getId(); + + //调用 + SysRoleUpdateReqVO reqVO = randomPojo(SysRoleUpdateReqVO.class, o -> { + o.setId(roleId); + o.setCode("role_code"); + o.setName("update_name"); + o.setType(SysRoleTypeEnum.SYSTEM.getType()); + o.setSort(999); + }); + sysRoleService.updateRole(reqVO); + + //断言 + SysRoleDO newRoleDO = roleMapper.selectById(roleId); + assertPojoEquals(reqVO, newRoleDO); + + verify(sysRoleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testUpdateRoleStatus_success() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, CommonStatusEnum.ENABLE.getStatus()); + roleMapper.insert(roleDO); + Long roleId = roleDO.getId(); + + //调用 + sysRoleService.updateRoleStatus(roleId, CommonStatusEnum.DISABLE.getStatus()); + + //断言 + SysRoleDO newRoleDO = roleMapper.selectById(roleId); + assertEquals(CommonStatusEnum.DISABLE.getStatus(), newRoleDO.getStatus()); + + verify(sysRoleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testUpdateRoleDataScope_success() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO); + Long roleId = roleDO.getId(); + + //调用 + Set deptIdSet = Arrays.asList(1L, 2L, 3L, 4L, 5L).stream().collect(Collectors.toSet()); + sysRoleService.updateRoleDataScope(roleId, DataScopeEnum.DEPT_CUSTOM.getScore(), deptIdSet); + + //断言 + SysRoleDO newRoleDO = roleMapper.selectById(roleId); + assertEquals(DataScopeEnum.DEPT_CUSTOM.getScore(), newRoleDO.getDataScope()); + + Set newDeptIdSet = newRoleDO.getDataScopeDeptIds(); + assertTrue(deptIdSet.size() == newDeptIdSet.size()); + deptIdSet.stream().forEach(d -> assertTrue(newDeptIdSet.contains(d))); + + verify(sysRoleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testDeleteRole_success() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO); + Long roleId = roleDO.getId(); + + //调用 + sysRoleService.deleteRole(roleId); + + //断言 + SysRoleDO newRoleDO = roleMapper.selectById(roleId); + assertNull(newRoleDO); + + verify(sysRoleProducer).sendRoleRefreshMessage(); + } + + @Test + public void testGetRoles_success() { + Map idRoleMap = new HashMap<>(); + // 验证查询状态为1的角色 + SysRoleDO roleDO1 = createRoleDO("role1", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1); + roleMapper.insert(roleDO1); + idRoleMap.put(roleDO1.getId(), roleDO1); + + SysRoleDO roleDO2 = createRoleDO("role2", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1); + roleMapper.insert(roleDO2); + idRoleMap.put(roleDO2.getId(), roleDO2); + + // 以下是排除的角色 + SysRoleDO roleDO3 = createRoleDO("role3", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 2); + roleMapper.insert(roleDO3); + + //调用 + List roles = sysRoleService.getRoles(Arrays.asList(1)); + + //断言 + assertEquals(2, roles.size()); + roles.stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r)); + + } + + @Test + public void testGetRolePage_success() { + Map idRoleMap = new HashMap<>(); + // 验证名称包含"role", 状态为1,code为"code"的角色 + // 第一页 + SysRoleDO roleDO = createRoleDO("role1", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "code"); + roleMapper.insert(roleDO); + idRoleMap.put(roleDO.getId(), roleDO); + // 第二页 + roleDO = createRoleDO("role2", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "code"); + roleMapper.insert(roleDO); + + // 以下是排除的角色 + roleDO = createRoleDO("role3", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 2, "code"); + roleMapper.insert(roleDO); + roleDO = createRoleDO("role4", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "xxxxx"); + roleMapper.insert(roleDO); + + //调用 + SysRolePageReqVO reqVO = randomPojo(SysRolePageReqVO.class, o -> { + o.setName("role"); + o.setCode("code"); + o.setStatus(1); + o.setPageNo(1); + o.setPageSize(1); + o.setBeginTime(null); + o.setEndTime(null); + }); + PageResult result = sysRoleService.getRolePage(reqVO); + assertEquals(2, result.getTotal()); + result.getList().stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r)); + } + + @Test + public void testCheckDuplicateRole_success() { + sysRoleService.checkDuplicateRole(randomString(), randomString(), null); + } + + @Test + public void testCheckDuplicateRole_nameDuplicate() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO); + + String duplicateName = "role_name"; + + assertServiceException(() -> sysRoleService.checkDuplicateRole(duplicateName, randomString(), null), ROLE_NAME_DUPLICATE, duplicateName); + } + + @Test + public void testCheckDuplicateRole_codeDuplicate() { + SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> { + o.setName("role_999"); + o.setCode("code"); + o.setType(SysRoleTypeEnum.CUSTOM.getType()); + o.setStatus(1); + o.setDataScope(DataScopeEnum.ALL.getScore()); + }); + roleMapper.insert(roleDO); + + String randomName = randomString(); + String duplicateCode = "code"; + + assertServiceException(() -> sysRoleService.checkDuplicateRole(randomName, duplicateCode, null), ROLE_CODE_DUPLICATE, duplicateCode); + } + + @Test + public void testCheckUpdateRole_success() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL); + roleMapper.insert(roleDO); + Long roleId = roleDO.getId(); + + sysRoleService.checkUpdateRole(roleId); + } + + @Test + public void testCheckUpdateRole_roleIdNotExist() { + assertServiceException(() -> sysRoleService.checkUpdateRole(randomLongId()), ROLE_NOT_EXISTS); + } + + @Test + public void testCheckUpdateRole_systemRoleCanNotBeUpdate() { + SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.SYSTEM, DataScopeEnum.ALL); + roleMapper.insert(roleDO); + Long roleId = roleDO.getId(); + + assertServiceException(() -> sysRoleService.checkUpdateRole(roleId), ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); + } + + private SysRoleDO createRoleDO(String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status) { + return createRoleDO( name, typeEnum, scopeEnum, status, randomString()); + } + + private SysRoleDO createRoleDO(String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) { + return createRoleDO(null, name, typeEnum, scopeEnum, status, code); + } + + private SysRoleDO createRoleDO(String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum) { + return createRoleDO(null, name, typeEnum, scopeEnum, randomCommonStatus(), randomString()); + } + + private SysRoleDO createRoleDO(Long id, String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) { + SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> { + o.setId(id); + o.setName(name); + o.setType(typeEnum.getType()); + o.setStatus(status); + o.setDataScope(scopeEnum.getScore()); + o.setCode(code); + }); + return roleDO; + } + +} From fc3810e77c43e5acb58910641929b3fd9cc7cb73 Mon Sep 17 00:00:00 2001 From: hexiaowu Date: Fri, 9 Apr 2021 00:11:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=AF=B9=E8=B1=A1=E7=9A=84=E5=8E=BB=E9=87=8D=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20convertMap=20=E7=9A=84=E9=87=8D=E8=BD=BD?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/collection/CollectionUtils.java | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java b/src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java index 186bf1201..ccd075a96 100644 --- a/src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java +++ b/src/main/java/cn/iocoder/dashboard/util/collection/CollectionUtils.java @@ -4,8 +4,10 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import java.util.*; +import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -30,6 +32,20 @@ public class CollectionUtils { return from.stream().filter(predicate).collect(Collectors.toList()); } + public static List distinct(Collection from, Function keyMapper) { + if (CollUtil.isEmpty(from)) { + return new ArrayList<>(); + } + return distinct(from, keyMapper, (t1, t2) -> t1); + } + + public static List distinct(Collection from, Function keyMapper, BinaryOperator cover) { + if (CollUtil.isEmpty(from)) { + return new ArrayList<>(); + } + return new ArrayList<>(convertMap(from, keyMapper, Function.identity(), cover).values()); + } + public static List convertList(Collection from, Function func) { if (CollUtil.isEmpty(from)) { return new ArrayList<>(); @@ -48,30 +64,57 @@ public class CollectionUtils { if (CollUtil.isEmpty(from)) { return new HashMap<>(); } - return from.stream().collect(Collectors.toMap(keyFunc, item -> item)); + return convertMap(from, keyFunc, Function.identity()); + } + + public static Map convertMap(Collection from, Function keyFunc, Supplier> supplier) { + if (CollUtil.isEmpty(from)) { + return supplier.get(); + } + return convertMap(from, keyFunc, Function.identity(), supplier); } public static Map convertMap(Collection from, Function keyFunc, Function valueFunc) { if (CollUtil.isEmpty(from)) { return new HashMap<>(); } - return from.stream().collect(Collectors.toMap(keyFunc, valueFunc)); + return convertMap(from, keyFunc, valueFunc, (v1, v2) -> v1); + } + + public static Map convertMap(Collection from, Function keyFunc, Function valueFunc, BinaryOperator mergeFunction) { + if (CollUtil.isEmpty(from)) { + return new HashMap<>(); + } + return convertMap(from, keyFunc, valueFunc, mergeFunction, HashMap::new); + } + + public static Map convertMap(Collection from, Function keyFunc, Function valueFunc, Supplier> supplier) { + if (CollUtil.isEmpty(from)) { + return supplier.get(); + } + return convertMap(from, keyFunc, valueFunc, (v1, v2) -> v1, supplier); + } + + public static Map convertMap(Collection from, Function keyFunc, Function valueFunc, BinaryOperator mergeFunction, Supplier> supplier) { + if (CollUtil.isEmpty(from)) { + return new HashMap<>(); + } + return from.stream().collect(Collectors.toMap(keyFunc, valueFunc, mergeFunction, supplier)); } public static Map> convertMultiMap(Collection from, Function keyFunc) { if (CollUtil.isEmpty(from)) { return new HashMap<>(); } - return from.stream().collect(Collectors.groupingBy(keyFunc, - Collectors.mapping(t -> t, Collectors.toList()))); + return from.stream().collect(Collectors.groupingBy(keyFunc, Collectors.mapping(t -> t, Collectors.toList()))); } public static Map> convertMultiMap(Collection from, Function keyFunc, Function valueFunc) { if (CollUtil.isEmpty(from)) { return new HashMap<>(); } - return from.stream().collect(Collectors.groupingBy(keyFunc, - Collectors.mapping(valueFunc, Collectors.toList()))); + return from.stream() + .collect(Collectors.groupingBy(keyFunc, Collectors.mapping(valueFunc, Collectors.toList()))); } // 暂时没想好名字,先以 2 结尾噶