Commit 3aeebef03618b87dfcb1af1d81c6247c26384a0d
1 parent
7731b4f5
完善 MenuServiceImplTest 单元测试
Showing
15 changed files
with
456 additions
and
447 deletions
pom.xml
| ... | ... | @@ -17,7 +17,7 @@ |
| 17 | 17 | <module>yudao-module-system</module> |
| 18 | 18 | <module>yudao-module-infra</module> |
| 19 | 19 | <module>yudao-module-pay</module> |
| 20 | -<!-- <module>yudao-module-bpm</module>--> | |
| 20 | + <module>yudao-module-bpm</module> | |
| 21 | 21 | <!-- <module>yudao-module-visualization</module>--> |
| 22 | 22 | <!-- <module>yudao-module-mp</module>--> |
| 23 | 23 | <!-- <module>yudao-module-mall</module>--> | ... | ... |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/MenuIdEnum.java deleted
| 1 | -package cn.iocoder.yudao.module.system.enums.permission; | |
| 2 | - | |
| 3 | -import lombok.AllArgsConstructor; | |
| 4 | -import lombok.Getter; | |
| 5 | - | |
| 6 | -/** | |
| 7 | - * Menu 编号枚举 | |
| 8 | - */ | |
| 9 | -@Getter | |
| 10 | -@AllArgsConstructor | |
| 11 | -public enum MenuIdEnum { | |
| 12 | - | |
| 13 | - /** | |
| 14 | - * 根节点 | |
| 15 | - */ | |
| 16 | - ROOT(0L); | |
| 17 | - | |
| 18 | - private final Long id; | |
| 19 | - | |
| 20 | -} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java
| ... | ... | @@ -57,8 +57,8 @@ public class MenuController { |
| 57 | 57 | @GetMapping("/list") |
| 58 | 58 | @ApiOperation(value = "获取菜单列表", notes = "用于【菜单管理】界面") |
| 59 | 59 | @PreAuthorize("@ss.hasPermission('system:menu:query')") |
| 60 | - public CommonResult<List<MenuRespVO>> getMenus(MenuListReqVO reqVO) { | |
| 61 | - List<MenuDO> list = menuService.getMenus(reqVO); | |
| 60 | + public CommonResult<List<MenuRespVO>> getMenuList(MenuListReqVO reqVO) { | |
| 61 | + List<MenuDO> list = menuService.getMenuList(reqVO); | |
| 62 | 62 | list.sort(Comparator.comparing(MenuDO::getSort)); |
| 63 | 63 | return success(MenuConvert.INSTANCE.convertList(list)); |
| 64 | 64 | } |
| ... | ... | @@ -66,11 +66,11 @@ public class MenuController { |
| 66 | 66 | @GetMapping("/list-all-simple") |
| 67 | 67 | @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" + |
| 68 | 68 | "在多租户的场景下,会只返回租户所在套餐有的菜单") |
| 69 | - public CommonResult<List<MenuSimpleRespVO>> getSimpleMenus() { | |
| 69 | + public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() { | |
| 70 | 70 | // 获得菜单列表,只要开启状态的 |
| 71 | 71 | MenuListReqVO reqVO = new MenuListReqVO(); |
| 72 | 72 | reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); |
| 73 | - List<MenuDO> list = menuService.getTenantMenus(reqVO); | |
| 73 | + List<MenuDO> list = menuService.getMenuListByTenant(reqVO); | |
| 74 | 74 | // 排序后,返回给前端 |
| 75 | 75 | list.sort(Comparator.comparing(MenuDO::getSort)); |
| 76 | 76 | return success(MenuConvert.INSTANCE.convertList02(list)); | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
| ... | ... | @@ -9,13 +9,15 @@ import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| 9 | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; |
| 10 | 10 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; |
| 11 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| 12 | -import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum; | |
| 13 | 12 | import org.mapstruct.Mapper; |
| 14 | 13 | import org.mapstruct.factory.Mappers; |
| 15 | 14 | import org.slf4j.LoggerFactory; |
| 16 | 15 | |
| 17 | 16 | import java.util.*; |
| 18 | 17 | |
| 18 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; | |
| 19 | +import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; | |
| 20 | + | |
| 19 | 21 | @Mapper |
| 20 | 22 | public interface AuthConvert { |
| 21 | 23 | |
| ... | ... | @@ -47,7 +49,7 @@ public interface AuthConvert { |
| 47 | 49 | Map<Long, AuthMenuRespVO> treeNodeMap = new LinkedHashMap<>(); |
| 48 | 50 | menuList.forEach(menu -> treeNodeMap.put(menu.getId(), AuthConvert.INSTANCE.convertTreeNode(menu))); |
| 49 | 51 | // 处理父子关系 |
| 50 | - treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach(childNode -> { | |
| 52 | + treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(ID_ROOT)).forEach(childNode -> { | |
| 51 | 53 | // 获得父节点 |
| 52 | 54 | AuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId()); |
| 53 | 55 | if (parentNode == null) { |
| ... | ... | @@ -62,7 +64,7 @@ public interface AuthConvert { |
| 62 | 64 | parentNode.getChildren().add(childNode); |
| 63 | 65 | }); |
| 64 | 66 | // 获得到所有的根节点 |
| 65 | - return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId())); | |
| 67 | + return filterList(treeNodeMap.values(), node -> ID_ROOT.equals(node.getParentId())); | |
| 66 | 68 | } |
| 67 | 69 | |
| 68 | 70 | SocialUserBindReqDTO convert(Long userId, Integer userType, AuthSocialLoginReqVO reqVO); | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/permission/MenuDO.java
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/MenuMapper.java
| ... | ... | @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 4 | 4 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 5 | 5 | import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; |
| 6 | 6 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; |
| 7 | -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |
| 8 | 7 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 8 | |
| 10 | 9 | import java.util.List; |
| ... | ... | @@ -13,8 +12,7 @@ import java.util.List; |
| 13 | 12 | public interface MenuMapper extends BaseMapperX<MenuDO> { |
| 14 | 13 | |
| 15 | 14 | default MenuDO selectByParentIdAndName(Long parentId, String name) { |
| 16 | - return selectOne(new LambdaQueryWrapper<MenuDO>().eq(MenuDO::getParentId, parentId) | |
| 17 | - .eq(MenuDO::getName, name)); | |
| 15 | + return selectOne(MenuDO::getParentId, parentId, MenuDO::getName, name); | |
| 18 | 16 | } |
| 19 | 17 | |
| 20 | 18 | default Long selectCountByParentId(Long parentId) { |
| ... | ... | @@ -22,7 +20,8 @@ public interface MenuMapper extends BaseMapperX<MenuDO> { |
| 22 | 20 | } |
| 23 | 21 | |
| 24 | 22 | default List<MenuDO> selectList(MenuListReqVO reqVO) { |
| 25 | - return selectList(new LambdaQueryWrapperX<MenuDO>().likeIfPresent(MenuDO::getName, reqVO.getName()) | |
| 23 | + return selectList(new LambdaQueryWrapperX<MenuDO>() | |
| 24 | + .likeIfPresent(MenuDO::getName, reqVO.getName()) | |
| 26 | 25 | .eqIfPresent(MenuDO::getStatus, reqVO.getStatus())); |
| 27 | 26 | } |
| 28 | 27 | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java
| ... | ... | @@ -47,7 +47,7 @@ public interface MenuService { |
| 47 | 47 | * |
| 48 | 48 | * @return 菜单列表 |
| 49 | 49 | */ |
| 50 | - List<MenuDO> getMenus(); | |
| 50 | + List<MenuDO> getMenuList(); | |
| 51 | 51 | |
| 52 | 52 | /** |
| 53 | 53 | * 基于租户,筛选菜单列表 |
| ... | ... | @@ -56,7 +56,7 @@ public interface MenuService { |
| 56 | 56 | * @param reqVO 筛选条件请求 VO |
| 57 | 57 | * @return 菜单列表 |
| 58 | 58 | */ |
| 59 | - List<MenuDO> getTenantMenus(MenuListReqVO reqVO); | |
| 59 | + List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO); | |
| 60 | 60 | |
| 61 | 61 | /** |
| 62 | 62 | * 筛选菜单列表 |
| ... | ... | @@ -64,7 +64,7 @@ public interface MenuService { |
| 64 | 64 | * @param reqVO 筛选条件请求 VO |
| 65 | 65 | * @return 菜单列表 |
| 66 | 66 | */ |
| 67 | - List<MenuDO> getMenus(MenuListReqVO reqVO); | |
| 67 | + List<MenuDO> getMenuList(MenuListReqVO reqVO); | |
| 68 | 68 | |
| 69 | 69 | /** |
| 70 | 70 | * 获得所有菜单,从缓存中 | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
| ... | ... | @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUp |
| 10 | 10 | import cn.iocoder.yudao.module.system.convert.permission.MenuConvert; |
| 11 | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; |
| 12 | 12 | import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; |
| 13 | -import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum; | |
| 14 | 13 | import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; |
| 15 | 14 | import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; |
| 16 | 15 | import cn.iocoder.yudao.module.system.service.tenant.TenantService; |
| ... | ... | @@ -19,6 +18,7 @@ import com.google.common.collect.ImmutableMap; |
| 19 | 18 | import com.google.common.collect.ImmutableMultimap; |
| 20 | 19 | import com.google.common.collect.Multimap; |
| 21 | 20 | import lombok.Getter; |
| 21 | +import lombok.Setter; | |
| 22 | 22 | import lombok.extern.slf4j.Slf4j; |
| 23 | 23 | import org.springframework.context.annotation.Lazy; |
| 24 | 24 | import org.springframework.stereotype.Service; |
| ... | ... | @@ -31,6 +31,7 @@ import javax.annotation.Resource; |
| 31 | 31 | import java.util.*; |
| 32 | 32 | import java.util.stream.Collectors; |
| 33 | 33 | |
| 34 | +import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; | |
| 34 | 35 | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; |
| 35 | 36 | |
| 36 | 37 | /** |
| ... | ... | @@ -49,6 +50,7 @@ public class MenuServiceImpl implements MenuService { |
| 49 | 50 | * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 |
| 50 | 51 | */ |
| 51 | 52 | @Getter |
| 53 | + @Setter | |
| 52 | 54 | private volatile Map<Long, MenuDO> menuCache; |
| 53 | 55 | /** |
| 54 | 56 | * 权限与菜单缓存 |
| ... | ... | @@ -58,6 +60,7 @@ public class MenuServiceImpl implements MenuService { |
| 58 | 60 | * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 |
| 59 | 61 | */ |
| 60 | 62 | @Getter |
| 63 | + @Setter | |
| 61 | 64 | private volatile Multimap<String, MenuDO> permissionMenuCache; |
| 62 | 65 | |
| 63 | 66 | @Resource |
| ... | ... | @@ -97,9 +100,10 @@ public class MenuServiceImpl implements MenuService { |
| 97 | 100 | @Override |
| 98 | 101 | public Long createMenu(MenuCreateReqVO reqVO) { |
| 99 | 102 | // 校验父菜单存在 |
| 100 | - checkParentResource(reqVO.getParentId(), null); | |
| 103 | + validateParentMenu(reqVO.getParentId(), null); | |
| 101 | 104 | // 校验菜单(自己) |
| 102 | - checkResource(reqVO.getParentId(), reqVO.getName(), null); | |
| 105 | + validateMenu(reqVO.getParentId(), reqVO.getName(), null); | |
| 106 | + | |
| 103 | 107 | // 插入数据库 |
| 104 | 108 | MenuDO menu = MenuConvert.INSTANCE.convert(reqVO); |
| 105 | 109 | initMenuProperty(menu); |
| ... | ... | @@ -117,9 +121,10 @@ public class MenuServiceImpl implements MenuService { |
| 117 | 121 | throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS); |
| 118 | 122 | } |
| 119 | 123 | // 校验父菜单存在 |
| 120 | - checkParentResource(reqVO.getParentId(), reqVO.getId()); | |
| 124 | + validateParentMenu(reqVO.getParentId(), reqVO.getId()); | |
| 121 | 125 | // 校验菜单(自己) |
| 122 | - checkResource(reqVO.getParentId(), reqVO.getName(), reqVO.getId()); | |
| 126 | + validateMenu(reqVO.getParentId(), reqVO.getName(), reqVO.getId()); | |
| 127 | + | |
| 123 | 128 | // 更新到数据库 |
| 124 | 129 | MenuDO updateObject = MenuConvert.INSTANCE.convert(reqVO); |
| 125 | 130 | initMenuProperty(updateObject); |
| ... | ... | @@ -128,13 +133,8 @@ public class MenuServiceImpl implements MenuService { |
| 128 | 133 | menuProducer.sendMenuRefreshMessage(); |
| 129 | 134 | } |
| 130 | 135 | |
| 131 | - /** | |
| 132 | - * 删除菜单 | |
| 133 | - * | |
| 134 | - * @param menuId 菜单编号 | |
| 135 | - */ | |
| 136 | - @Transactional(rollbackFor = Exception.class) | |
| 137 | 136 | @Override |
| 137 | + @Transactional(rollbackFor = Exception.class) | |
| 138 | 138 | public void deleteMenu(Long menuId) { |
| 139 | 139 | // 校验是否还有子菜单 |
| 140 | 140 | if (menuMapper.selectCountByParentId(menuId) > 0) { |
| ... | ... | @@ -160,20 +160,20 @@ public class MenuServiceImpl implements MenuService { |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | @Override |
| 163 | - public List<MenuDO> getMenus() { | |
| 163 | + public List<MenuDO> getMenuList() { | |
| 164 | 164 | return menuMapper.selectList(); |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | 167 | @Override |
| 168 | - public List<MenuDO> getTenantMenus(MenuListReqVO reqVO) { | |
| 169 | - List<MenuDO> menus = getMenus(reqVO); | |
| 168 | + public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) { | |
| 169 | + List<MenuDO> menus = getMenuList(reqVO); | |
| 170 | 170 | // 开启多租户的情况下,需要过滤掉未开通的菜单 |
| 171 | 171 | tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId()))); |
| 172 | 172 | return menus; |
| 173 | 173 | } |
| 174 | 174 | |
| 175 | 175 | @Override |
| 176 | - public List<MenuDO> getMenus(MenuListReqVO reqVO) { | |
| 176 | + public List<MenuDO> getMenuList(MenuListReqVO reqVO) { | |
| 177 | 177 | return menuMapper.selectList(reqVO); |
| 178 | 178 | } |
| 179 | 179 | |
| ... | ... | @@ -223,8 +223,8 @@ public class MenuServiceImpl implements MenuService { |
| 223 | 223 | * @param childId 当前菜单编号 |
| 224 | 224 | */ |
| 225 | 225 | @VisibleForTesting |
| 226 | - public void checkParentResource(Long parentId, Long childId) { | |
| 227 | - if (parentId == null || MenuIdEnum.ROOT.getId().equals(parentId)) { | |
| 226 | + void validateParentMenu(Long parentId, Long childId) { | |
| 227 | + if (parentId == null || ID_ROOT.equals(parentId)) { | |
| 228 | 228 | return; |
| 229 | 229 | } |
| 230 | 230 | // 不能设置自己为父菜单 |
| ... | ... | @@ -253,7 +253,7 @@ public class MenuServiceImpl implements MenuService { |
| 253 | 253 | * @param id 菜单编号 |
| 254 | 254 | */ |
| 255 | 255 | @VisibleForTesting |
| 256 | - public void checkResource(Long parentId, String name, Long id) { | |
| 256 | + void validateMenu(Long parentId, String name, Long id) { | |
| 257 | 257 | MenuDO menu = menuMapper.selectByParentIdAndName(parentId, name); |
| 258 | 258 | if (menu == null) { |
| 259 | 259 | return; | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java
| ... | ... | @@ -190,7 +190,7 @@ public class PermissionServiceImpl implements PermissionService { |
| 190 | 190 | public Set<Long> getRoleMenuIds(Long roleId) { |
| 191 | 191 | // 如果是管理员的情况下,获取全部菜单编号 |
| 192 | 192 | if (roleService.hasAnySuperAdmin(Collections.singleton(roleId))) { |
| 193 | - return convertSet(menuService.getMenus(), MenuDO::getId); | |
| 193 | + return convertSet(menuService.getMenuList(), MenuDO::getId); | |
| 194 | 194 | } |
| 195 | 195 | // 如果是非管理员的情况下,获得拥有的菜单编号 |
| 196 | 196 | return convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImpl.java
| ... | ... | @@ -248,7 +248,7 @@ public class TenantServiceImpl implements TenantService { |
| 248 | 248 | TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId()); |
| 249 | 249 | Set<Long> menuIds; |
| 250 | 250 | if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的 |
| 251 | - menuIds = CollectionUtils.convertSet(menuService.getMenus(), MenuDO::getId); | |
| 251 | + menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId); | |
| 252 | 252 | } else { |
| 253 | 253 | menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds(); |
| 254 | 254 | } | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.service.permission; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 4 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 5 | +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; | |
| 6 | +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; | |
| 7 | +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO; | |
| 8 | +import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | |
| 9 | +import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; | |
| 10 | +import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; | |
| 11 | +import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; | |
| 12 | +import cn.iocoder.yudao.module.system.service.tenant.TenantService; | |
| 13 | +import com.google.common.collect.LinkedListMultimap; | |
| 14 | +import com.google.common.collect.Multimap; | |
| 15 | +import org.junit.jupiter.api.Test; | |
| 16 | +import org.springframework.boot.test.mock.mockito.MockBean; | |
| 17 | +import org.springframework.context.annotation.Import; | |
| 18 | + | |
| 19 | +import javax.annotation.Resource; | |
| 20 | +import java.util.*; | |
| 21 | + | |
| 22 | +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | |
| 23 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | |
| 24 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | |
| 25 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 26 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | |
| 27 | +import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; | |
| 28 | +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | |
| 29 | +import static java.util.Arrays.asList; | |
| 30 | +import static java.util.Collections.singletonList; | |
| 31 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 32 | +import static org.junit.jupiter.api.Assertions.assertNull; | |
| 33 | +import static org.mockito.ArgumentMatchers.argThat; | |
| 34 | +import static org.mockito.Mockito.doNothing; | |
| 35 | +import static org.mockito.Mockito.verify; | |
| 36 | + | |
| 37 | +@Import(MenuServiceImpl.class) | |
| 38 | +public class MenuServiceImplTest extends BaseDbUnitTest { | |
| 39 | + | |
| 40 | + @Resource | |
| 41 | + private MenuServiceImpl menuService; | |
| 42 | + | |
| 43 | + @Resource | |
| 44 | + private MenuMapper menuMapper; | |
| 45 | + | |
| 46 | + @MockBean | |
| 47 | + private PermissionService permissionService; | |
| 48 | + @MockBean | |
| 49 | + private MenuProducer menuProducer; | |
| 50 | + @MockBean | |
| 51 | + private TenantService tenantService; | |
| 52 | + | |
| 53 | + @Test | |
| 54 | + public void testInitLocalCache_success() { | |
| 55 | + MenuDO menuDO1 = randomPojo(MenuDO.class); | |
| 56 | + menuMapper.insert(menuDO1); | |
| 57 | + MenuDO menuDO2 = randomPojo(MenuDO.class); | |
| 58 | + menuMapper.insert(menuDO2); | |
| 59 | + | |
| 60 | + // 调用 | |
| 61 | + menuService.initLocalCache(); | |
| 62 | + // 校验 menuCache 缓存 | |
| 63 | + Map<Long, MenuDO> menuCache = menuService.getMenuCache(); | |
| 64 | + assertEquals(2, menuCache.size()); | |
| 65 | + assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId())); | |
| 66 | + assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId())); | |
| 67 | + // 校验 permissionMenuCache 缓存 | |
| 68 | + Multimap<String, MenuDO> permissionMenuCache = menuService.getPermissionMenuCache(); | |
| 69 | + assertEquals(2, permissionMenuCache.size()); | |
| 70 | + assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission())); | |
| 71 | + assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission())); | |
| 72 | + } | |
| 73 | + | |
| 74 | + @Test | |
| 75 | + public void testCreateMenu_success() { | |
| 76 | + // mock 数据(构造父菜单) | |
| 77 | + MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, | |
| 78 | + "parent", 0L); | |
| 79 | + menuMapper.insert(menuDO); | |
| 80 | + Long parentId = menuDO.getId(); | |
| 81 | + // 准备参数 | |
| 82 | + MenuCreateReqVO reqVO = randomPojo(MenuCreateReqVO.class, o -> { | |
| 83 | + o.setParentId(parentId); | |
| 84 | + o.setName("testSonName"); | |
| 85 | + o.setType(MenuTypeEnum.MENU.getType()); | |
| 86 | + }); | |
| 87 | + Long menuId = menuService.createMenu(reqVO); | |
| 88 | + | |
| 89 | + // 校验记录的属性是否正确 | |
| 90 | + MenuDO dbMenu = menuMapper.selectById(menuId); | |
| 91 | + assertPojoEquals(reqVO, dbMenu); | |
| 92 | + // 校验调用 | |
| 93 | + verify(menuProducer).sendMenuRefreshMessage(); | |
| 94 | + } | |
| 95 | + | |
| 96 | + @Test | |
| 97 | + public void testUpdateMenu_success() { | |
| 98 | + // mock 数据(构造父子菜单) | |
| 99 | + MenuDO sonMenuDO = initParentAndSonMenu(); | |
| 100 | + Long sonId = sonMenuDO.getId(); | |
| 101 | + // 准备参数 | |
| 102 | + MenuUpdateReqVO reqVO = randomPojo(MenuUpdateReqVO.class, o -> { | |
| 103 | + o.setId(sonId); | |
| 104 | + o.setName("testSonName"); // 修改名字 | |
| 105 | + o.setParentId(sonMenuDO.getParentId()); | |
| 106 | + o.setType(MenuTypeEnum.MENU.getType()); | |
| 107 | + }); | |
| 108 | + | |
| 109 | + // 调用 | |
| 110 | + menuService.updateMenu(reqVO); | |
| 111 | + // 校验记录的属性是否正确 | |
| 112 | + MenuDO dbMenu = menuMapper.selectById(sonId); | |
| 113 | + assertPojoEquals(reqVO, dbMenu); | |
| 114 | + // 校验调用 | |
| 115 | + verify(menuProducer).sendMenuRefreshMessage(); | |
| 116 | + } | |
| 117 | + | |
| 118 | + @Test | |
| 119 | + public void testUpdateMenu_sonIdNotExist() { | |
| 120 | + // 准备参数 | |
| 121 | + MenuUpdateReqVO reqVO = randomPojo(MenuUpdateReqVO.class); | |
| 122 | + // 调用,并断言异常 | |
| 123 | + assertServiceException(() -> menuService.updateMenu(reqVO), MENU_NOT_EXISTS); | |
| 124 | + } | |
| 125 | + | |
| 126 | + @Test | |
| 127 | + public void testDeleteMenu_success() { | |
| 128 | + // mock 数据 | |
| 129 | + MenuDO menuDO = randomPojo(MenuDO.class); | |
| 130 | + menuMapper.insert(menuDO); | |
| 131 | + // 准备参数 | |
| 132 | + Long id = menuDO.getId(); | |
| 133 | + | |
| 134 | + // 调用 | |
| 135 | + menuService.deleteMenu(id); | |
| 136 | + // 断言 | |
| 137 | + MenuDO dbMenuDO = menuMapper.selectById(id); | |
| 138 | + assertNull(dbMenuDO); | |
| 139 | + verify(permissionService).processMenuDeleted(id); | |
| 140 | + verify(menuProducer).sendMenuRefreshMessage(); | |
| 141 | + } | |
| 142 | + | |
| 143 | + @Test | |
| 144 | + public void testDeleteMenu_menuNotExist() { | |
| 145 | + assertServiceException(() -> menuService.deleteMenu(randomLongId()), | |
| 146 | + MENU_NOT_EXISTS); | |
| 147 | + } | |
| 148 | + | |
| 149 | + @Test | |
| 150 | + public void testDeleteMenu_existChildren() { | |
| 151 | + // mock 数据(构造父子菜单) | |
| 152 | + MenuDO sonMenu = initParentAndSonMenu(); | |
| 153 | + // 准备参数 | |
| 154 | + Long parentId = sonMenu.getParentId(); | |
| 155 | + | |
| 156 | + // 调用并断言异常 | |
| 157 | + assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN); | |
| 158 | + } | |
| 159 | + | |
| 160 | + @Test | |
| 161 | + public void testGetMenuList_all() { | |
| 162 | + // mock 数据 | |
| 163 | + MenuDO menu100 = randomPojo(MenuDO.class); | |
| 164 | + menuMapper.insert(menu100); | |
| 165 | + MenuDO menu101 = randomPojo(MenuDO.class); | |
| 166 | + menuMapper.insert(menu101); | |
| 167 | + // 准备参数 | |
| 168 | + | |
| 169 | + // 调用 | |
| 170 | + List<MenuDO> list = menuService.getMenuList(); | |
| 171 | + // 断言 | |
| 172 | + assertEquals(2, list.size()); | |
| 173 | + assertPojoEquals(menu100, list.get(0)); | |
| 174 | + assertPojoEquals(menu101, list.get(1)); | |
| 175 | + } | |
| 176 | + | |
| 177 | + @Test | |
| 178 | + public void testGetMenuList() { | |
| 179 | + // mock 数据 | |
| 180 | + MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setName("芋艿").setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 181 | + menuMapper.insert(menuDO); | |
| 182 | + // 测试 status 不匹配 | |
| 183 | + menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | |
| 184 | + // 测试 name 不匹配 | |
| 185 | + menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setName("艿"))); | |
| 186 | + // 准备参数 | |
| 187 | + MenuListReqVO reqVO = new MenuListReqVO().setName("芋").setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 188 | + | |
| 189 | + // 调用 | |
| 190 | + List<MenuDO> result = menuService.getMenuList(reqVO); | |
| 191 | + // 断言 | |
| 192 | + assertEquals(1, result.size()); | |
| 193 | + assertPojoEquals(menuDO, result.get(0)); | |
| 194 | + } | |
| 195 | + | |
| 196 | + @Test | |
| 197 | + public void testGetMenuListByTenant() { | |
| 198 | + // mock 数据 | |
| 199 | + MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 200 | + menuMapper.insert(menu100); | |
| 201 | + MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); | |
| 202 | + menuMapper.insert(menu101); | |
| 203 | + MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 204 | + menuMapper.insert(menu102); | |
| 205 | + // mock 过滤菜单 | |
| 206 | + Set<Long> menuIds = asSet(100L, 101L); | |
| 207 | + doNothing().when(tenantService).handleTenantMenu(argThat(handler -> { | |
| 208 | + handler.handle(menuIds); | |
| 209 | + return true; | |
| 210 | + })); | |
| 211 | + // 准备参数 | |
| 212 | + MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 213 | + | |
| 214 | + // 调用 | |
| 215 | + List<MenuDO> result = menuService.getMenuListByTenant(reqVO); | |
| 216 | + // 断言 | |
| 217 | + assertEquals(1, result.size()); | |
| 218 | + assertPojoEquals(menu100, result.get(0)); | |
| 219 | + } | |
| 220 | + | |
| 221 | + @Test | |
| 222 | + public void testListMenusFromCache_withoutId() { | |
| 223 | + // mock 缓存 | |
| 224 | + Map<Long, MenuDO> menuCache = new HashMap<>(); | |
| 225 | + // 可被匹配 | |
| 226 | + MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setId(1L) | |
| 227 | + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 228 | + menuCache.put(menuDO.getId(), menuDO); | |
| 229 | + // 测试 type 不匹配 | |
| 230 | + menuCache.put(3L, randomPojo(MenuDO.class, o -> o.setId(3L) | |
| 231 | + .setType(MenuTypeEnum.BUTTON.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); | |
| 232 | + // 测试 status 不匹配 | |
| 233 | + menuCache.put(4L, randomPojo(MenuDO.class, o -> o.setId(4L) | |
| 234 | + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.DISABLE.getStatus()))); | |
| 235 | + menuService.setMenuCache(menuCache); | |
| 236 | + // 准备参数 | |
| 237 | + Collection<Integer> menuTypes = singletonList(MenuTypeEnum.MENU.getType()); | |
| 238 | + Collection<Integer> menusStatuses = singletonList(CommonStatusEnum.ENABLE.getStatus()); | |
| 239 | + | |
| 240 | + // 调用 | |
| 241 | + List<MenuDO> list = menuService.getMenuListFromCache(menuTypes, menusStatuses); | |
| 242 | + // 断言 | |
| 243 | + assertEquals(1, list.size()); | |
| 244 | + assertPojoEquals(menuDO, list.get(0)); | |
| 245 | + } | |
| 246 | + | |
| 247 | + @Test | |
| 248 | + public void testListMenusFromCache_withId() { | |
| 249 | + // mock 缓存 | |
| 250 | + Map<Long, MenuDO> menuCache = new HashMap<>(); | |
| 251 | + // 可被匹配 | |
| 252 | + MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setId(1L) | |
| 253 | + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 254 | + menuCache.put(menuDO.getId(), menuDO); | |
| 255 | + // 测试 id 不匹配 | |
| 256 | + menuCache.put(2L, randomPojo(MenuDO.class, o -> o.setId(2L) | |
| 257 | + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); | |
| 258 | + // 测试 type 不匹配 | |
| 259 | + menuCache.put(3L, randomPojo(MenuDO.class, o -> o.setId(3L) | |
| 260 | + .setType(MenuTypeEnum.BUTTON.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); | |
| 261 | + // 测试 status 不匹配 | |
| 262 | + menuCache.put(4L, randomPojo(MenuDO.class, o -> o.setId(4L) | |
| 263 | + .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.DISABLE.getStatus()))); | |
| 264 | + menuService.setMenuCache(menuCache); | |
| 265 | + // 准备参数 | |
| 266 | + Collection<Long> menuIds = asList(1L, 3L, 4L); | |
| 267 | + Collection<Integer> menuTypes = singletonList(MenuTypeEnum.MENU.getType()); | |
| 268 | + Collection<Integer> menusStatuses = singletonList(CommonStatusEnum.ENABLE.getStatus()); | |
| 269 | + | |
| 270 | + // 调用 | |
| 271 | + List<MenuDO> list = menuService.getMenuListFromCache(menuIds, menuTypes, menusStatuses); | |
| 272 | + // 断言 | |
| 273 | + assertEquals(1, list.size()); | |
| 274 | + assertPojoEquals(menuDO, list.get(0)); | |
| 275 | + } | |
| 276 | + | |
| 277 | + @Test | |
| 278 | + public void testGetMenuListByPermissionFromCache() { | |
| 279 | + // mock 缓存 | |
| 280 | + Multimap<String, MenuDO> permissionMenuCache = LinkedListMultimap.create(); | |
| 281 | + // 可被匹配 | |
| 282 | + MenuDO menuDO01 = randomPojo(MenuDO.class, o -> o.setId(1L).setPermission("123")); | |
| 283 | + permissionMenuCache.put(menuDO01.getPermission(), menuDO01); | |
| 284 | + MenuDO menuDO02 = randomPojo(MenuDO.class, o -> o.setId(2L).setPermission("123")); | |
| 285 | + permissionMenuCache.put(menuDO02.getPermission(), menuDO02); | |
| 286 | + // 不可匹配 | |
| 287 | + permissionMenuCache.put("456", randomPojo(MenuDO.class, o -> o.setId(3L).setPermission("456"))); | |
| 288 | + menuService.setPermissionMenuCache(permissionMenuCache); | |
| 289 | + // 准备参数 | |
| 290 | + String permission = "123"; | |
| 291 | + | |
| 292 | + // 调用 | |
| 293 | + List<MenuDO> list = menuService.getMenuListByPermissionFromCache(permission); | |
| 294 | + // 断言 | |
| 295 | + assertEquals(2, list.size()); | |
| 296 | + assertPojoEquals(menuDO01, list.get(0)); | |
| 297 | + assertPojoEquals(menuDO02, list.get(1)); | |
| 298 | + } | |
| 299 | + | |
| 300 | + @Test | |
| 301 | + public void testGetMenu() { | |
| 302 | + // mock 数据 | |
| 303 | + MenuDO menu = randomPojo(MenuDO.class); | |
| 304 | + menuMapper.insert(menu); | |
| 305 | + // 准备参数 | |
| 306 | + Long id = menu.getId(); | |
| 307 | + | |
| 308 | + // 调用 | |
| 309 | + MenuDO dbMenu = menuService.getMenu(id); | |
| 310 | + // 断言 | |
| 311 | + assertPojoEquals(menu, dbMenu); | |
| 312 | + } | |
| 313 | + | |
| 314 | + @Test | |
| 315 | + public void testValidateParentMenu_success() { | |
| 316 | + // mock 数据 | |
| 317 | + MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | |
| 318 | + menuMapper.insert(menuDO); | |
| 319 | + // 准备参数 | |
| 320 | + Long parentId = menuDO.getId(); | |
| 321 | + | |
| 322 | + // 调用,无需断言 | |
| 323 | + menuService.validateParentMenu(parentId, null); | |
| 324 | + } | |
| 325 | + | |
| 326 | + @Test | |
| 327 | + public void testValidateParentMenu_canNotSetSelfToBeParent() { | |
| 328 | + // 调用,并断言异常 | |
| 329 | + assertServiceException(() -> menuService.validateParentMenu(1L, 1L), | |
| 330 | + MENU_PARENT_ERROR); | |
| 331 | + } | |
| 332 | + | |
| 333 | + @Test | |
| 334 | + public void testValidateParentMenu_parentNotExist() { | |
| 335 | + // 调用,并断言异常 | |
| 336 | + assertServiceException(() -> menuService.validateParentMenu(randomLongId(), null), | |
| 337 | + MENU_PARENT_NOT_EXISTS); | |
| 338 | + } | |
| 339 | + | |
| 340 | + @Test | |
| 341 | + public void testValidateParentMenu_parentTypeError() { | |
| 342 | + // mock 数据 | |
| 343 | + MenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L); | |
| 344 | + menuMapper.insert(menuDO); | |
| 345 | + // 准备参数 | |
| 346 | + Long parentId = menuDO.getId(); | |
| 347 | + | |
| 348 | + // 调用,并断言异常 | |
| 349 | + assertServiceException(() -> menuService.validateParentMenu(parentId, null), | |
| 350 | + MENU_PARENT_NOT_DIR_OR_MENU); | |
| 351 | + } | |
| 352 | + | |
| 353 | + @Test | |
| 354 | + public void testValidateMenu_success() { | |
| 355 | + // mock 父子菜单 | |
| 356 | + MenuDO sonMenu = initParentAndSonMenu(); | |
| 357 | + // 准备参数 | |
| 358 | + Long parentId = sonMenu.getParentId(); | |
| 359 | + Long otherSonMenuId = randomLongId(); | |
| 360 | + String otherSonMenuName = randomString(); | |
| 361 | + | |
| 362 | + // 调用,无需断言 | |
| 363 | + menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId); | |
| 364 | + } | |
| 365 | + | |
| 366 | + @Test | |
| 367 | + public void testValidateMenu_sonMenuNameDuplicate() { | |
| 368 | + // mock 父子菜单 | |
| 369 | + MenuDO sonMenu = initParentAndSonMenu(); | |
| 370 | + // 准备参数 | |
| 371 | + Long parentId = sonMenu.getParentId(); | |
| 372 | + Long otherSonMenuId = randomLongId(); | |
| 373 | + String otherSonMenuName = sonMenu.getName(); //相同名称 | |
| 374 | + | |
| 375 | + // 调用,并断言异常 | |
| 376 | + assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId), | |
| 377 | + MENU_NAME_DUPLICATE); | |
| 378 | + } | |
| 379 | + | |
| 380 | + // ====================== 初始化方法 ====================== | |
| 381 | + | |
| 382 | + /** | |
| 383 | + * 构造父子菜单,返回子菜单 | |
| 384 | + * | |
| 385 | + * @return 子菜单 | |
| 386 | + */ | |
| 387 | + private MenuDO initParentAndSonMenu() { | |
| 388 | + // 构造父子菜单 | |
| 389 | + MenuDO parentMenuDO = createMenuDO(MenuTypeEnum.MENU, "parent", ID_ROOT); | |
| 390 | + menuMapper.insert(parentMenuDO); | |
| 391 | + // 构建子菜单 | |
| 392 | + MenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", | |
| 393 | + parentMenuDO.getParentId()); | |
| 394 | + menuMapper.insert(sonMenuDO); | |
| 395 | + return sonMenuDO; | |
| 396 | + } | |
| 397 | + | |
| 398 | + private MenuDO createMenuDO(MenuTypeEnum type, String name, Long parentId) { | |
| 399 | + return createMenuDO(type, name, parentId, randomCommonStatus()); | |
| 400 | + } | |
| 401 | + | |
| 402 | + private MenuDO createMenuDO(MenuTypeEnum type, String name, Long parentId, Integer status) { | |
| 403 | + return randomPojo(MenuDO.class, o -> o.setId(null).setName(name).setParentId(parentId) | |
| 404 | + .setType(type.getType()).setStatus(status)); | |
| 405 | + } | |
| 406 | + | |
| 407 | +} | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceTest.java deleted
| 1 | -package cn.iocoder.yudao.module.system.service.permission; | |
| 2 | - | |
| 3 | -import cn.hutool.core.bean.BeanUtil; | |
| 4 | -import cn.hutool.core.lang.Assert; | |
| 5 | -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 6 | -import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils; | |
| 7 | -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 8 | -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; | |
| 9 | -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; | |
| 10 | -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO; | |
| 11 | -import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | |
| 12 | -import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; | |
| 13 | -import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; | |
| 14 | -import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; | |
| 15 | -import cn.iocoder.yudao.module.system.service.tenant.TenantService; | |
| 16 | -import com.google.common.collect.Multimap; | |
| 17 | -import org.junit.jupiter.api.Test; | |
| 18 | -import org.springframework.boot.test.mock.mockito.MockBean; | |
| 19 | -import org.springframework.context.annotation.Import; | |
| 20 | - | |
| 21 | -import javax.annotation.Resource; | |
| 22 | -import java.util.*; | |
| 23 | - | |
| 24 | -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | |
| 25 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | |
| 26 | -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 27 | -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | |
| 28 | -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | |
| 29 | -import static org.junit.jupiter.api.Assertions.*; | |
| 30 | -import static org.mockito.ArgumentMatchers.argThat; | |
| 31 | -import static org.mockito.Mockito.doNothing; | |
| 32 | -import static org.mockito.Mockito.verify; | |
| 33 | - | |
| 34 | -// TODO @芋艿:单测的代码质量可以提升下 | |
| 35 | -@Import(MenuServiceImpl.class) | |
| 36 | -public class MenuServiceTest extends BaseDbUnitTest { | |
| 37 | - | |
| 38 | - @Resource | |
| 39 | - private MenuServiceImpl menuService; | |
| 40 | - | |
| 41 | - @Resource | |
| 42 | - private MenuMapper menuMapper; | |
| 43 | - | |
| 44 | - @MockBean | |
| 45 | - private PermissionService permissionService; | |
| 46 | - @MockBean | |
| 47 | - private MenuProducer menuProducer; | |
| 48 | - @MockBean | |
| 49 | - private TenantService tenantService; | |
| 50 | - | |
| 51 | - @Test | |
| 52 | - public void testInitLocalCache_success() { | |
| 53 | - MenuDO menuDO1 = randomPojo(MenuDO.class); | |
| 54 | - menuMapper.insert(menuDO1); | |
| 55 | - MenuDO menuDO2 = randomPojo(MenuDO.class); | |
| 56 | - menuMapper.insert(menuDO2); | |
| 57 | - | |
| 58 | - // 调用 | |
| 59 | - menuService.initLocalCache(); | |
| 60 | - // 校验 menuCache 缓存 | |
| 61 | - Map<Long, MenuDO> menuCache = menuService.getMenuCache(); | |
| 62 | - Assert.isTrue(menuCache.size() == 2); | |
| 63 | - assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId())); | |
| 64 | - assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId())); | |
| 65 | - // 校验 permissionMenuCache 缓存 | |
| 66 | - Multimap<String, MenuDO> permissionMenuCache = menuService.getPermissionMenuCache(); | |
| 67 | - Assert.isTrue(permissionMenuCache.size() == 2); | |
| 68 | - assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission())); | |
| 69 | - assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission())); | |
| 70 | - } | |
| 71 | - | |
| 72 | - @Test | |
| 73 | - public void testCreateMenu_success() { | |
| 74 | - //构造父目录 | |
| 75 | - MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | |
| 76 | - menuMapper.insert(menuDO); | |
| 77 | - Long parentId = menuDO.getId(); | |
| 78 | - | |
| 79 | - //调用 | |
| 80 | - MenuCreateReqVO vo = randomPojo(MenuCreateReqVO.class, o -> { | |
| 81 | - o.setParentId(parentId); | |
| 82 | - o.setName("testSonName"); | |
| 83 | - o.setType(MenuTypeEnum.MENU.getType()); | |
| 84 | - o.setStatus(randomCommonStatus()); | |
| 85 | - }); | |
| 86 | - Long menuId = menuService.createMenu(vo); | |
| 87 | - | |
| 88 | - //断言 | |
| 89 | - assertNotNull(menuId); | |
| 90 | - // 校验记录的属性是否正确 | |
| 91 | - MenuDO ret = menuMapper.selectById(menuId); | |
| 92 | - assertPojoEquals(vo, ret); | |
| 93 | - // 校验调用 | |
| 94 | - verify(menuProducer).sendMenuRefreshMessage(); | |
| 95 | - } | |
| 96 | - | |
| 97 | - @Test | |
| 98 | - public void testUpdateMenu_success() { | |
| 99 | - //构造父子目录 | |
| 100 | - MenuDO sonMenuDO = initParentAndSonMenuDO(); | |
| 101 | - Long sonId = sonMenuDO.getId(); | |
| 102 | - Long parentId = sonMenuDO.getParentId(); | |
| 103 | - | |
| 104 | - //调用 | |
| 105 | - MenuUpdateReqVO vo = randomPojo(MenuUpdateReqVO.class, o -> { | |
| 106 | - o.setId(sonId); | |
| 107 | - o.setParentId(parentId); | |
| 108 | - o.setType(MenuTypeEnum.MENU.getType()); | |
| 109 | - o.setStatus(randomCommonStatus()); | |
| 110 | - o.setName("pppppp"); //修改名字 | |
| 111 | - }); | |
| 112 | - menuService.updateMenu(vo); | |
| 113 | - | |
| 114 | - //断言 | |
| 115 | - // 校验记录的属性是否正确 | |
| 116 | - MenuDO ret = menuMapper.selectById(sonId); | |
| 117 | - assertPojoEquals(vo, ret); | |
| 118 | - // 校验调用 | |
| 119 | - verify(menuProducer).sendMenuRefreshMessage(); | |
| 120 | - } | |
| 121 | - | |
| 122 | - @Test | |
| 123 | - public void testUpdateMenu_sonIdNotExist() { | |
| 124 | - Long sonId = 99999L; | |
| 125 | - Long parentId = 10000L; | |
| 126 | - | |
| 127 | - //调用 | |
| 128 | - MenuUpdateReqVO vo = randomPojo(MenuUpdateReqVO.class, o -> { | |
| 129 | - o.setId(sonId); | |
| 130 | - o.setParentId(parentId); | |
| 131 | - o.setType(MenuTypeEnum.MENU.getType()); | |
| 132 | - o.setStatus(randomCommonStatus()); | |
| 133 | - }); | |
| 134 | - //断言 | |
| 135 | - assertServiceException(() -> menuService.updateMenu(vo), MENU_NOT_EXISTS); | |
| 136 | - } | |
| 137 | - | |
| 138 | - @Test | |
| 139 | - public void testDeleteMenu_success() { | |
| 140 | - MenuDO sonMenuDO = initParentAndSonMenuDO(); | |
| 141 | - Long sonId = sonMenuDO.getId(); | |
| 142 | - | |
| 143 | - // 调用 | |
| 144 | - menuService.deleteMenu(sonId); | |
| 145 | - | |
| 146 | - // 断言 | |
| 147 | - MenuDO menuDO = menuMapper.selectById(sonId); | |
| 148 | - assertNull(menuDO); | |
| 149 | - verify(permissionService).processMenuDeleted(sonId); | |
| 150 | - verify(menuProducer).sendMenuRefreshMessage(); | |
| 151 | - } | |
| 152 | - | |
| 153 | - @Test | |
| 154 | - public void testDeleteMenu_menuNotExist() { | |
| 155 | - Long sonId = 99999L; | |
| 156 | - | |
| 157 | - assertServiceException(() -> menuService.deleteMenu(sonId), MENU_NOT_EXISTS); | |
| 158 | - } | |
| 159 | - | |
| 160 | - @Test | |
| 161 | - public void testDeleteMenu_existChildren() { | |
| 162 | - MenuDO sonMenu = initParentAndSonMenuDO(); | |
| 163 | - Long parentId = sonMenu.getParentId(); | |
| 164 | - | |
| 165 | - assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN); | |
| 166 | - } | |
| 167 | - | |
| 168 | - @Test | |
| 169 | - public void testGetMenus() { | |
| 170 | - // mock 数据 | |
| 171 | - MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 172 | - menuMapper.insert(menu100); | |
| 173 | - MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); | |
| 174 | - menuMapper.insert(menu101); | |
| 175 | - // 准备参数 | |
| 176 | - MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 177 | - | |
| 178 | - // 调用 | |
| 179 | - List<MenuDO> result = menuService.getMenus(reqVO); | |
| 180 | - // 断言 | |
| 181 | - assertEquals(1, result.size()); | |
| 182 | - assertPojoEquals(menu100, result.get(0)); | |
| 183 | - } | |
| 184 | - | |
| 185 | - @Test | |
| 186 | - public void testTenantMenus() { | |
| 187 | - // mock 数据 | |
| 188 | - MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 189 | - menuMapper.insert(menu100); | |
| 190 | - MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); | |
| 191 | - menuMapper.insert(menu101); | |
| 192 | - MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 193 | - menuMapper.insert(menu102); | |
| 194 | - // mock 过滤菜单 | |
| 195 | - // mock 账户额度充足 | |
| 196 | - Set<Long> menuIds = asSet(100L, 101L); | |
| 197 | - doNothing().when(tenantService).handleTenantMenu(argThat(handler -> { | |
| 198 | - handler.handle(menuIds); | |
| 199 | - return true; | |
| 200 | - })); | |
| 201 | - // 准备参数 | |
| 202 | - MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | |
| 203 | - | |
| 204 | - // 调用 | |
| 205 | - List<MenuDO> result = menuService.getTenantMenus(reqVO); | |
| 206 | - // 断言 | |
| 207 | - assertEquals(1, result.size()); | |
| 208 | - assertPojoEquals(menu100, result.get(0)); | |
| 209 | - } | |
| 210 | - | |
| 211 | - @Test | |
| 212 | - public void testGetMenusReqVo_success() { | |
| 213 | - Map<Long, MenuDO> idMenuMap = new HashMap<>(); | |
| 214 | - // 用于验证可以模糊搜索名称包含"name",状态为1的menu | |
| 215 | - MenuDO menu = createMenuDO(MenuTypeEnum.MENU, "name2", 0L, 1); | |
| 216 | - menuMapper.insert(menu); | |
| 217 | - idMenuMap.put(menu.getId(), menu); | |
| 218 | - | |
| 219 | - menu = createMenuDO(MenuTypeEnum.MENU, "11name111", 0L, 1); | |
| 220 | - menuMapper.insert(menu); | |
| 221 | - idMenuMap.put(menu.getId(), menu); | |
| 222 | - | |
| 223 | - menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 1); | |
| 224 | - menuMapper.insert(menu); | |
| 225 | - idMenuMap.put(menu.getId(), menu); | |
| 226 | - | |
| 227 | - // 以下是不符合搜索条件的的menu | |
| 228 | - menu = createMenuDO(MenuTypeEnum.MENU, "xxxxxx", 0L, 1); | |
| 229 | - menuMapper.insert(menu); | |
| 230 | - menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 2); | |
| 231 | - menuMapper.insert(menu); | |
| 232 | - | |
| 233 | - // 调用 | |
| 234 | - MenuListReqVO reqVO = new MenuListReqVO(); | |
| 235 | - reqVO.setStatus(1); | |
| 236 | - reqVO.setName("name"); | |
| 237 | - List<MenuDO> menuDOS = menuService.getMenus(reqVO); | |
| 238 | - | |
| 239 | - // 断言 | |
| 240 | - assertEquals(menuDOS.size(), idMenuMap.size()); | |
| 241 | - menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m)); | |
| 242 | - } | |
| 243 | - | |
| 244 | - @Test | |
| 245 | - public void testListMenusFromCache_success() throws Exception { | |
| 246 | - Map<Long, MenuDO> mockCacheMap = new HashMap<>(); | |
| 247 | - // 获取代理对象 | |
| 248 | - MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService); | |
| 249 | - BeanUtil.setFieldValue(target, "menuCache", mockCacheMap); | |
| 250 | - | |
| 251 | - Map<Long, MenuDO> idMenuMap = new HashMap<>(); | |
| 252 | - // 用于验证搜索类型为MENU,状态为1的menu | |
| 253 | - MenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1); | |
| 254 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 255 | - idMenuMap.put(menuDO.getId(), menuDO); | |
| 256 | - | |
| 257 | - menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1); | |
| 258 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 259 | - idMenuMap.put(menuDO.getId(), menuDO); | |
| 260 | - | |
| 261 | - // 以下是不符合搜索条件的menu | |
| 262 | - menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1); | |
| 263 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 264 | - menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2); | |
| 265 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 266 | - | |
| 267 | - List<MenuDO> menuDOS = menuService.getMenuListFromCache(Collections.singletonList(MenuTypeEnum.MENU.getType()), | |
| 268 | - Collections.singletonList(CommonStatusEnum.DISABLE.getStatus())); | |
| 269 | - assertEquals(menuDOS.size(), idMenuMap.size()); | |
| 270 | - menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m)); | |
| 271 | - } | |
| 272 | - | |
| 273 | - @Test | |
| 274 | - public void testListMenusFromCache2_success() throws Exception { | |
| 275 | - Map<Long, MenuDO> mockCacheMap = new HashMap<>(); | |
| 276 | - // 获取代理对象 | |
| 277 | - MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService); | |
| 278 | - BeanUtil.setFieldValue(target, "menuCache", mockCacheMap); | |
| 279 | - | |
| 280 | - Map<Long, MenuDO> idMenuMap = new HashMap<>(); | |
| 281 | - // 验证搜索id为1, 类型为MENU, 状态为1 的menu | |
| 282 | - MenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1); | |
| 283 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 284 | - idMenuMap.put(menuDO.getId(), menuDO); | |
| 285 | - | |
| 286 | - // 以下是不符合搜索条件的menu | |
| 287 | - menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1); | |
| 288 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 289 | - menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1); | |
| 290 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 291 | - menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2); | |
| 292 | - mockCacheMap.put(menuDO.getId(), menuDO); | |
| 293 | - | |
| 294 | - List<MenuDO> menuDOS = menuService.getMenuListFromCache(Collections.singletonList(1L), | |
| 295 | - Collections.singletonList(MenuTypeEnum.MENU.getType()), Collections.singletonList(1)); | |
| 296 | - assertEquals(menuDOS.size(), idMenuMap.size()); | |
| 297 | - menuDOS.forEach(menu -> assertPojoEquals(idMenuMap.get(menu.getId()), menu)); | |
| 298 | - } | |
| 299 | - | |
| 300 | - @Test | |
| 301 | - public void testCheckParentResource_success() { | |
| 302 | - MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | |
| 303 | - menuMapper.insert(menuDO); | |
| 304 | - Long parentId = menuDO.getId(); | |
| 305 | - | |
| 306 | - menuService.checkParentResource(parentId, null); | |
| 307 | - } | |
| 308 | - | |
| 309 | - @Test | |
| 310 | - public void testCheckParentResource_canNotSetSelfToBeParent() { | |
| 311 | - assertServiceException(() -> menuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR); | |
| 312 | - } | |
| 313 | - | |
| 314 | - @Test | |
| 315 | - public void testCheckParentResource_parentNotExist() { | |
| 316 | - assertServiceException(() -> menuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS); | |
| 317 | - } | |
| 318 | - | |
| 319 | - @Test | |
| 320 | - public void testCheckParentResource_parentTypeError() { | |
| 321 | - MenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L); | |
| 322 | - menuMapper.insert(menuDO); | |
| 323 | - Long parentId = menuDO.getId(); | |
| 324 | - | |
| 325 | - assertServiceException(() -> menuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU); | |
| 326 | - } | |
| 327 | - | |
| 328 | - @Test | |
| 329 | - public void testCheckResource_success() { | |
| 330 | - MenuDO sonMenu = initParentAndSonMenuDO(); | |
| 331 | - Long parentId = sonMenu.getParentId(); | |
| 332 | - | |
| 333 | - Long otherSonMenuId = randomLongId(); | |
| 334 | - String otherSonMenuName = randomString(); | |
| 335 | - | |
| 336 | - menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId); | |
| 337 | - } | |
| 338 | - | |
| 339 | - @Test | |
| 340 | - public void testCheckResource_sonMenuNameDuplicate(){ | |
| 341 | - MenuDO sonMenu=initParentAndSonMenuDO(); | |
| 342 | - Long parentId=sonMenu.getParentId(); | |
| 343 | - | |
| 344 | - Long otherSonMenuId=randomLongId(); | |
| 345 | - String otherSonMenuName=sonMenu.getName(); //相同名称 | |
| 346 | - | |
| 347 | - assertServiceException(() -> menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE); | |
| 348 | - } | |
| 349 | - | |
| 350 | - /** | |
| 351 | - * 构造父子目录,返回子目录 | |
| 352 | - * | |
| 353 | - * @return | |
| 354 | - */ | |
| 355 | - private MenuDO initParentAndSonMenuDO() { | |
| 356 | - //构造父子目录 | |
| 357 | - MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | |
| 358 | - menuMapper.insert(menuDO); | |
| 359 | - Long parentId = menuDO.getId(); | |
| 360 | - | |
| 361 | - MenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", parentId); | |
| 362 | - menuMapper.insert(sonMenuDO); | |
| 363 | - return sonMenuDO; | |
| 364 | - } | |
| 365 | - | |
| 366 | - private MenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId) { | |
| 367 | - return createMenuDO(typeEnum, menuName, parentId, randomCommonStatus()); | |
| 368 | - } | |
| 369 | - | |
| 370 | - private MenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) { | |
| 371 | - return createMenuDO(null, typeEnum, menuName, parentId, status); | |
| 372 | - } | |
| 373 | - | |
| 374 | - private MenuDO createMenuDO(Long id, MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) { | |
| 375 | - return randomPojo(MenuDO.class, o -> { | |
| 376 | - o.setId(id); | |
| 377 | - o.setParentId(parentId); | |
| 378 | - o.setType(typeEnum.getType()); | |
| 379 | - o.setStatus(status); | |
| 380 | - o.setName(menuName); | |
| 381 | - }); | |
| 382 | - } | |
| 383 | - | |
| 384 | -} |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java
| ... | ... | @@ -163,7 +163,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { |
| 163 | 163 | // mock 方法 |
| 164 | 164 | when(roleService.hasAnySuperAdmin(eq(singleton(100L)))).thenReturn(true); |
| 165 | 165 | List<MenuDO> menuList = singletonList(randomPojo(MenuDO.class).setId(1L)); |
| 166 | - when(menuService.getMenus()).thenReturn(menuList); | |
| 166 | + when(menuService.getMenuList()).thenReturn(menuList); | |
| 167 | 167 | |
| 168 | 168 | // 调用 |
| 169 | 169 | Set<Long> menuIds = permissionService.getRoleMenuIds(roleId); | ... | ... |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java
| ... | ... | @@ -453,7 +453,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { |
| 453 | 453 | tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据 |
| 454 | 454 | TenantContextHolder.setTenantId(dbTenant.getId()); |
| 455 | 455 | // mock 菜单 |
| 456 | - when(menuService.getMenus()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)), | |
| 456 | + when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)), | |
| 457 | 457 | randomPojo(MenuDO.class, o -> o.setId(101L)))); |
| 458 | 458 | |
| 459 | 459 | // 调用 | ... | ... |
yudao-server/pom.xml
| ... | ... | @@ -48,11 +48,11 @@ |
| 48 | 48 | <!-- <version>${revision}</version>--> |
| 49 | 49 | <!-- </dependency>--> |
| 50 | 50 | <!-- 工作流 --> |
| 51 | -<!-- <dependency>--> | |
| 52 | -<!-- <groupId>cn.iocoder.boot</groupId>--> | |
| 53 | -<!-- <artifactId>yudao-module-bpm-biz</artifactId>--> | |
| 54 | -<!-- <version>${revision}</version>--> | |
| 55 | -<!-- </dependency>--> | |
| 51 | + <dependency> | |
| 52 | + <groupId>cn.iocoder.boot</groupId> | |
| 53 | + <artifactId>yudao-module-bpm-biz</artifactId> | |
| 54 | + <version>${revision}</version> | |
| 55 | + </dependency> | |
| 56 | 56 | <!-- 支付服务 --> |
| 57 | 57 | <dependency> |
| 58 | 58 | <groupId>cn.iocoder.boot</groupId> | ... | ... |