mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	完善 MenuServiceImplTest 单元测试
This commit is contained in:
		
							
								
								
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -17,7 +17,7 @@ | ||||
|         <module>yudao-module-system</module> | ||||
|         <module>yudao-module-infra</module> | ||||
|         <module>yudao-module-pay</module> | ||||
| <!--        <module>yudao-module-bpm</module>--> | ||||
|         <module>yudao-module-bpm</module> | ||||
| <!--        <module>yudao-module-visualization</module>--> | ||||
| <!--        <module>yudao-module-mp</module>--> | ||||
|         <!--        <module>yudao-module-mall</module>--> | ||||
|   | ||||
| @@ -1,20 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.system.enums.permission; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Getter; | ||||
|  | ||||
| /** | ||||
|  * Menu 编号枚举 | ||||
|  */ | ||||
| @Getter | ||||
| @AllArgsConstructor | ||||
| public enum MenuIdEnum { | ||||
|  | ||||
|     /** | ||||
|      * 根节点 | ||||
|      */ | ||||
|     ROOT(0L); | ||||
|  | ||||
|     private final Long id; | ||||
|  | ||||
| } | ||||
| @@ -57,8 +57,8 @@ public class MenuController { | ||||
|     @GetMapping("/list") | ||||
|     @ApiOperation(value = "获取菜单列表", notes = "用于【菜单管理】界面") | ||||
|     @PreAuthorize("@ss.hasPermission('system:menu:query')") | ||||
|     public CommonResult<List<MenuRespVO>> getMenus(MenuListReqVO reqVO) { | ||||
|         List<MenuDO> list = menuService.getMenus(reqVO); | ||||
|     public CommonResult<List<MenuRespVO>> getMenuList(MenuListReqVO reqVO) { | ||||
|         List<MenuDO> list = menuService.getMenuList(reqVO); | ||||
|         list.sort(Comparator.comparing(MenuDO::getSort)); | ||||
|         return success(MenuConvert.INSTANCE.convertList(list)); | ||||
|     } | ||||
| @@ -66,11 +66,11 @@ public class MenuController { | ||||
|     @GetMapping("/list-all-simple") | ||||
|     @ApiOperation(value = "获取菜单精简信息列表", notes = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" + | ||||
|             "在多租户的场景下,会只返回租户所在套餐有的菜单") | ||||
|     public CommonResult<List<MenuSimpleRespVO>> getSimpleMenus() { | ||||
|     public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() { | ||||
|         // 获得菜单列表,只要开启状态的 | ||||
|         MenuListReqVO reqVO = new MenuListReqVO(); | ||||
|         reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||
|         List<MenuDO> list = menuService.getTenantMenus(reqVO); | ||||
|         List<MenuDO> list = menuService.getMenuListByTenant(reqVO); | ||||
|         // 排序后,返回给前端 | ||||
|         list.sort(Comparator.comparing(MenuDO::getSort)); | ||||
|         return success(MenuConvert.INSTANCE.convertList02(list)); | ||||
|   | ||||
| @@ -9,13 +9,15 @@ import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum; | ||||
| import org.mapstruct.Mapper; | ||||
| import org.mapstruct.factory.Mappers; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.util.*; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList; | ||||
| import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; | ||||
|  | ||||
| @Mapper | ||||
| public interface AuthConvert { | ||||
|  | ||||
| @@ -47,7 +49,7 @@ public interface AuthConvert { | ||||
|         Map<Long, AuthMenuRespVO> treeNodeMap = new LinkedHashMap<>(); | ||||
|         menuList.forEach(menu -> treeNodeMap.put(menu.getId(), AuthConvert.INSTANCE.convertTreeNode(menu))); | ||||
|         // 处理父子关系 | ||||
|         treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(MenuIdEnum.ROOT.getId())).forEach(childNode -> { | ||||
|         treeNodeMap.values().stream().filter(node -> !node.getParentId().equals(ID_ROOT)).forEach(childNode -> { | ||||
|             // 获得父节点 | ||||
|             AuthMenuRespVO parentNode = treeNodeMap.get(childNode.getParentId()); | ||||
|             if (parentNode == null) { | ||||
| @@ -62,7 +64,7 @@ public interface AuthConvert { | ||||
|             parentNode.getChildren().add(childNode); | ||||
|         }); | ||||
|         // 获得到所有的根节点 | ||||
|         return CollectionUtils.filterList(treeNodeMap.values(), node -> MenuIdEnum.ROOT.getId().equals(node.getParentId())); | ||||
|         return filterList(treeNodeMap.values(), node -> ID_ROOT.equals(node.getParentId())); | ||||
|     } | ||||
|  | ||||
|     SocialUserBindReqDTO convert(Long userId, Integer userType, AuthSocialLoginReqVO reqVO); | ||||
|   | ||||
| @@ -21,7 +21,12 @@ import lombok.EqualsAndHashCode; | ||||
| public class MenuDO extends BaseDO { | ||||
|  | ||||
|     /** | ||||
|      * 菜单ID | ||||
|      * 菜单编号 - 根节点 | ||||
|      */ | ||||
|     public static final Long ID_ROOT = 0L; | ||||
|  | ||||
|     /** | ||||
|      * 菜单编号 | ||||
|      */ | ||||
|     @TableId | ||||
|     private Long id; | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||||
| import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import org.apache.ibatis.annotations.Mapper; | ||||
|  | ||||
| import java.util.List; | ||||
| @@ -13,8 +12,7 @@ import java.util.List; | ||||
| public interface MenuMapper extends BaseMapperX<MenuDO> { | ||||
|  | ||||
|     default MenuDO selectByParentIdAndName(Long parentId, String name) { | ||||
|         return selectOne(new LambdaQueryWrapper<MenuDO>().eq(MenuDO::getParentId, parentId) | ||||
|                 .eq(MenuDO::getName, name)); | ||||
|         return selectOne(MenuDO::getParentId, parentId, MenuDO::getName, name); | ||||
|     } | ||||
|  | ||||
|     default Long selectCountByParentId(Long parentId) { | ||||
| @@ -22,7 +20,8 @@ public interface MenuMapper extends BaseMapperX<MenuDO> { | ||||
|     } | ||||
|  | ||||
|     default List<MenuDO> selectList(MenuListReqVO reqVO) { | ||||
|         return selectList(new LambdaQueryWrapperX<MenuDO>().likeIfPresent(MenuDO::getName, reqVO.getName()) | ||||
|         return selectList(new LambdaQueryWrapperX<MenuDO>() | ||||
|                 .likeIfPresent(MenuDO::getName, reqVO.getName()) | ||||
|                 .eqIfPresent(MenuDO::getStatus, reqVO.getStatus())); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -47,7 +47,7 @@ public interface MenuService { | ||||
|      * | ||||
|      * @return 菜单列表 | ||||
|      */ | ||||
|     List<MenuDO> getMenus(); | ||||
|     List<MenuDO> getMenuList(); | ||||
|  | ||||
|     /** | ||||
|      * 基于租户,筛选菜单列表 | ||||
| @@ -56,7 +56,7 @@ public interface MenuService { | ||||
|      * @param reqVO 筛选条件请求 VO | ||||
|      * @return 菜单列表 | ||||
|      */ | ||||
|     List<MenuDO> getTenantMenus(MenuListReqVO reqVO); | ||||
|     List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO); | ||||
|  | ||||
|     /** | ||||
|      * 筛选菜单列表 | ||||
| @@ -64,7 +64,7 @@ public interface MenuService { | ||||
|      * @param reqVO 筛选条件请求 VO | ||||
|      * @return 菜单列表 | ||||
|      */ | ||||
|     List<MenuDO> getMenus(MenuListReqVO reqVO); | ||||
|     List<MenuDO> getMenuList(MenuListReqVO reqVO); | ||||
|  | ||||
|     /** | ||||
|      * 获得所有菜单,从缓存中 | ||||
|   | ||||
| @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUp | ||||
| import cn.iocoder.yudao.module.system.convert.permission.MenuConvert; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | ||||
| import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.MenuIdEnum; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; | ||||
| import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; | ||||
| import cn.iocoder.yudao.module.system.service.tenant.TenantService; | ||||
| @@ -19,6 +18,7 @@ import com.google.common.collect.ImmutableMap; | ||||
| import com.google.common.collect.ImmutableMultimap; | ||||
| import com.google.common.collect.Multimap; | ||||
| import lombok.Getter; | ||||
| import lombok.Setter; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.stereotype.Service; | ||||
| @@ -31,6 +31,7 @@ import javax.annotation.Resource; | ||||
| import java.util.*; | ||||
| import java.util.stream.Collectors; | ||||
|  | ||||
| import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; | ||||
| import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | ||||
|  | ||||
| /** | ||||
| @@ -49,6 +50,7 @@ public class MenuServiceImpl implements MenuService { | ||||
|      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 | ||||
|      */ | ||||
|     @Getter | ||||
|     @Setter | ||||
|     private volatile Map<Long, MenuDO> menuCache; | ||||
|     /** | ||||
|      * 权限与菜单缓存 | ||||
| @@ -58,6 +60,7 @@ public class MenuServiceImpl implements MenuService { | ||||
|      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向 | ||||
|      */ | ||||
|     @Getter | ||||
|     @Setter | ||||
|     private volatile Multimap<String, MenuDO> permissionMenuCache; | ||||
|  | ||||
|     @Resource | ||||
| @@ -97,9 +100,10 @@ public class MenuServiceImpl implements MenuService { | ||||
|     @Override | ||||
|     public Long createMenu(MenuCreateReqVO reqVO) { | ||||
|         // 校验父菜单存在 | ||||
|         checkParentResource(reqVO.getParentId(), null); | ||||
|         validateParentMenu(reqVO.getParentId(), null); | ||||
|         // 校验菜单(自己) | ||||
|         checkResource(reqVO.getParentId(), reqVO.getName(), null); | ||||
|         validateMenu(reqVO.getParentId(), reqVO.getName(), null); | ||||
|  | ||||
|         // 插入数据库 | ||||
|         MenuDO menu = MenuConvert.INSTANCE.convert(reqVO); | ||||
|         initMenuProperty(menu); | ||||
| @@ -117,9 +121,10 @@ public class MenuServiceImpl implements MenuService { | ||||
|             throw ServiceExceptionUtil.exception(MENU_NOT_EXISTS); | ||||
|         } | ||||
|         // 校验父菜单存在 | ||||
|         checkParentResource(reqVO.getParentId(), reqVO.getId()); | ||||
|         validateParentMenu(reqVO.getParentId(), reqVO.getId()); | ||||
|         // 校验菜单(自己) | ||||
|         checkResource(reqVO.getParentId(), reqVO.getName(), reqVO.getId()); | ||||
|         validateMenu(reqVO.getParentId(), reqVO.getName(), reqVO.getId()); | ||||
|  | ||||
|         // 更新到数据库 | ||||
|         MenuDO updateObject = MenuConvert.INSTANCE.convert(reqVO); | ||||
|         initMenuProperty(updateObject); | ||||
| @@ -128,13 +133,8 @@ public class MenuServiceImpl implements MenuService { | ||||
|         menuProducer.sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除菜单 | ||||
|      * | ||||
|      * @param menuId 菜单编号 | ||||
|      */ | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @Override | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     public void deleteMenu(Long menuId) { | ||||
|         // 校验是否还有子菜单 | ||||
|         if (menuMapper.selectCountByParentId(menuId) > 0) { | ||||
| @@ -160,20 +160,20 @@ public class MenuServiceImpl implements MenuService { | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<MenuDO> getMenus() { | ||||
|     public List<MenuDO> getMenuList() { | ||||
|         return menuMapper.selectList(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<MenuDO> getTenantMenus(MenuListReqVO reqVO) { | ||||
|         List<MenuDO> menus = getMenus(reqVO); | ||||
|     public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) { | ||||
|         List<MenuDO> menus = getMenuList(reqVO); | ||||
|         // 开启多租户的情况下,需要过滤掉未开通的菜单 | ||||
|         tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId()))); | ||||
|         return menus; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<MenuDO> getMenus(MenuListReqVO reqVO) { | ||||
|     public List<MenuDO> getMenuList(MenuListReqVO reqVO) { | ||||
|         return menuMapper.selectList(reqVO); | ||||
|     } | ||||
|  | ||||
| @@ -223,8 +223,8 @@ public class MenuServiceImpl implements MenuService { | ||||
|      * @param childId 当前菜单编号 | ||||
|      */ | ||||
|     @VisibleForTesting | ||||
|     public void checkParentResource(Long parentId, Long childId) { | ||||
|         if (parentId == null || MenuIdEnum.ROOT.getId().equals(parentId)) { | ||||
|     void validateParentMenu(Long parentId, Long childId) { | ||||
|         if (parentId == null || ID_ROOT.equals(parentId)) { | ||||
|             return; | ||||
|         } | ||||
|         // 不能设置自己为父菜单 | ||||
| @@ -253,7 +253,7 @@ public class MenuServiceImpl implements MenuService { | ||||
|      * @param id 菜单编号 | ||||
|      */ | ||||
|     @VisibleForTesting | ||||
|     public void checkResource(Long parentId, String name, Long id) { | ||||
|     void validateMenu(Long parentId, String name, Long id) { | ||||
|         MenuDO menu = menuMapper.selectByParentIdAndName(parentId, name); | ||||
|         if (menu == null) { | ||||
|             return; | ||||
|   | ||||
| @@ -190,7 +190,7 @@ public class PermissionServiceImpl implements PermissionService { | ||||
|     public Set<Long> getRoleMenuIds(Long roleId) { | ||||
|         // 如果是管理员的情况下,获取全部菜单编号 | ||||
|         if (roleService.hasAnySuperAdmin(Collections.singleton(roleId))) { | ||||
|             return convertSet(menuService.getMenus(), MenuDO::getId); | ||||
|             return convertSet(menuService.getMenuList(), MenuDO::getId); | ||||
|         } | ||||
|         // 如果是非管理员的情况下,获得拥有的菜单编号 | ||||
|         return convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); | ||||
|   | ||||
| @@ -248,7 +248,7 @@ public class TenantServiceImpl implements TenantService { | ||||
|         TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId()); | ||||
|         Set<Long> menuIds; | ||||
|         if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的 | ||||
|             menuIds = CollectionUtils.convertSet(menuService.getMenus(), MenuDO::getId); | ||||
|             menuIds = CollectionUtils.convertSet(menuService.getMenuList(), MenuDO::getId); | ||||
|         } else { | ||||
|             menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getMenuIds(); | ||||
|         } | ||||
|   | ||||
| @@ -0,0 +1,407 @@ | ||||
| package cn.iocoder.yudao.module.system.service.permission; | ||||
|  | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | ||||
| import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; | ||||
| import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; | ||||
| import cn.iocoder.yudao.module.system.service.tenant.TenantService; | ||||
| import com.google.common.collect.LinkedListMultimap; | ||||
| import com.google.common.collect.Multimap; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.boot.test.mock.mockito.MockBean; | ||||
| import org.springframework.context.annotation.Import; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.util.*; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | ||||
| import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | ||||
| import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | ||||
| import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | ||||
| import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | ||||
| import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; | ||||
| import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | ||||
| import static java.util.Arrays.asList; | ||||
| import static java.util.Collections.singletonList; | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
| import static org.junit.jupiter.api.Assertions.assertNull; | ||||
| import static org.mockito.ArgumentMatchers.argThat; | ||||
| import static org.mockito.Mockito.doNothing; | ||||
| import static org.mockito.Mockito.verify; | ||||
|  | ||||
| @Import(MenuServiceImpl.class) | ||||
| public class MenuServiceImplTest extends BaseDbUnitTest { | ||||
|  | ||||
|     @Resource | ||||
|     private MenuServiceImpl menuService; | ||||
|  | ||||
|     @Resource | ||||
|     private MenuMapper menuMapper; | ||||
|  | ||||
|     @MockBean | ||||
|     private PermissionService permissionService; | ||||
|     @MockBean | ||||
|     private MenuProducer menuProducer; | ||||
|     @MockBean | ||||
|     private TenantService tenantService; | ||||
|  | ||||
|     @Test | ||||
|     public void testInitLocalCache_success() { | ||||
|         MenuDO menuDO1 = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menuDO1); | ||||
|         MenuDO menuDO2 = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menuDO2); | ||||
|  | ||||
|         // 调用 | ||||
|         menuService.initLocalCache(); | ||||
|         // 校验 menuCache 缓存 | ||||
|         Map<Long, MenuDO> menuCache = menuService.getMenuCache(); | ||||
|         assertEquals(2, menuCache.size()); | ||||
|         assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId())); | ||||
|         assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId())); | ||||
|         // 校验 permissionMenuCache 缓存 | ||||
|         Multimap<String, MenuDO> permissionMenuCache = menuService.getPermissionMenuCache(); | ||||
|         assertEquals(2, permissionMenuCache.size()); | ||||
|         assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission())); | ||||
|         assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCreateMenu_success() { | ||||
|         // mock 数据(构造父菜单) | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, | ||||
|                 "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         Long parentId = menuDO.getId(); | ||||
|         // 准备参数 | ||||
|         MenuCreateReqVO reqVO = randomPojo(MenuCreateReqVO.class, o -> { | ||||
|             o.setParentId(parentId); | ||||
|             o.setName("testSonName"); | ||||
|             o.setType(MenuTypeEnum.MENU.getType()); | ||||
|         }); | ||||
|         Long menuId = menuService.createMenu(reqVO); | ||||
|  | ||||
|         // 校验记录的属性是否正确 | ||||
|         MenuDO dbMenu = menuMapper.selectById(menuId); | ||||
|         assertPojoEquals(reqVO, dbMenu); | ||||
|         // 校验调用 | ||||
|         verify(menuProducer).sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testUpdateMenu_success() { | ||||
|         // mock 数据(构造父子菜单) | ||||
|         MenuDO sonMenuDO = initParentAndSonMenu(); | ||||
|         Long sonId = sonMenuDO.getId(); | ||||
|         // 准备参数 | ||||
|         MenuUpdateReqVO reqVO = randomPojo(MenuUpdateReqVO.class, o -> { | ||||
|             o.setId(sonId); | ||||
|             o.setName("testSonName"); // 修改名字 | ||||
|             o.setParentId(sonMenuDO.getParentId()); | ||||
|             o.setType(MenuTypeEnum.MENU.getType()); | ||||
|         }); | ||||
|  | ||||
|         // 调用 | ||||
|         menuService.updateMenu(reqVO); | ||||
|         // 校验记录的属性是否正确 | ||||
|         MenuDO dbMenu = menuMapper.selectById(sonId); | ||||
|         assertPojoEquals(reqVO, dbMenu); | ||||
|         // 校验调用 | ||||
|         verify(menuProducer).sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testUpdateMenu_sonIdNotExist() { | ||||
|         // 准备参数 | ||||
|         MenuUpdateReqVO reqVO = randomPojo(MenuUpdateReqVO.class); | ||||
|         // 调用,并断言异常 | ||||
|         assertServiceException(() -> menuService.updateMenu(reqVO), MENU_NOT_EXISTS); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testDeleteMenu_success() { | ||||
|         // mock 数据 | ||||
|         MenuDO menuDO = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menuDO); | ||||
|         // 准备参数 | ||||
|         Long id = menuDO.getId(); | ||||
|  | ||||
|         // 调用 | ||||
|         menuService.deleteMenu(id); | ||||
|         // 断言 | ||||
|         MenuDO dbMenuDO = menuMapper.selectById(id); | ||||
|         assertNull(dbMenuDO); | ||||
|         verify(permissionService).processMenuDeleted(id); | ||||
|         verify(menuProducer).sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testDeleteMenu_menuNotExist() { | ||||
|         assertServiceException(() -> menuService.deleteMenu(randomLongId()), | ||||
|                 MENU_NOT_EXISTS); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testDeleteMenu_existChildren() { | ||||
|         // mock 数据(构造父子菜单) | ||||
|         MenuDO sonMenu = initParentAndSonMenu(); | ||||
|         // 准备参数 | ||||
|         Long parentId = sonMenu.getParentId(); | ||||
|  | ||||
|         // 调用并断言异常 | ||||
|         assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenuList_all() { | ||||
|         // mock 数据 | ||||
|         MenuDO menu100 = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menu100); | ||||
|         MenuDO menu101 = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menu101); | ||||
|         // 准备参数 | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> list = menuService.getMenuList(); | ||||
|         // 断言 | ||||
|         assertEquals(2, list.size()); | ||||
|         assertPojoEquals(menu100, list.get(0)); | ||||
|         assertPojoEquals(menu101, list.get(1)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenuList() { | ||||
|         // mock 数据 | ||||
|         MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setName("芋艿").setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuMapper.insert(menuDO); | ||||
|         // 测试 status 不匹配 | ||||
|         menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); | ||||
|         // 测试 name 不匹配 | ||||
|         menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setName("艿"))); | ||||
|         // 准备参数 | ||||
|         MenuListReqVO reqVO = new MenuListReqVO().setName("芋").setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> result = menuService.getMenuList(reqVO); | ||||
|         // 断言 | ||||
|         assertEquals(1, result.size()); | ||||
|         assertPojoEquals(menuDO, result.get(0)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenuListByTenant() { | ||||
|         // mock 数据 | ||||
|         MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuMapper.insert(menu100); | ||||
|         MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); | ||||
|         menuMapper.insert(menu101); | ||||
|         MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuMapper.insert(menu102); | ||||
|         // mock 过滤菜单 | ||||
|         Set<Long> menuIds = asSet(100L, 101L); | ||||
|         doNothing().when(tenantService).handleTenantMenu(argThat(handler -> { | ||||
|             handler.handle(menuIds); | ||||
|             return true; | ||||
|         })); | ||||
|         // 准备参数 | ||||
|         MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> result = menuService.getMenuListByTenant(reqVO); | ||||
|         // 断言 | ||||
|         assertEquals(1, result.size()); | ||||
|         assertPojoEquals(menu100, result.get(0)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testListMenusFromCache_withoutId() { | ||||
|         // mock 缓存 | ||||
|         Map<Long, MenuDO> menuCache = new HashMap<>(); | ||||
|         // 可被匹配 | ||||
|         MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setId(1L) | ||||
|                 .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuCache.put(menuDO.getId(), menuDO); | ||||
|         // 测试 type 不匹配 | ||||
|         menuCache.put(3L, randomPojo(MenuDO.class, o -> o.setId(3L) | ||||
|                 .setType(MenuTypeEnum.BUTTON.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); | ||||
|         // 测试 status 不匹配 | ||||
|         menuCache.put(4L, randomPojo(MenuDO.class, o -> o.setId(4L) | ||||
|                 .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.DISABLE.getStatus()))); | ||||
|         menuService.setMenuCache(menuCache); | ||||
|         // 准备参数 | ||||
|         Collection<Integer> menuTypes = singletonList(MenuTypeEnum.MENU.getType()); | ||||
|         Collection<Integer> menusStatuses = singletonList(CommonStatusEnum.ENABLE.getStatus()); | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> list = menuService.getMenuListFromCache(menuTypes, menusStatuses); | ||||
|         // 断言 | ||||
|         assertEquals(1, list.size()); | ||||
|         assertPojoEquals(menuDO, list.get(0)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testListMenusFromCache_withId() { | ||||
|         // mock 缓存 | ||||
|         Map<Long, MenuDO> menuCache = new HashMap<>(); | ||||
|         // 可被匹配 | ||||
|         MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setId(1L) | ||||
|                 .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuCache.put(menuDO.getId(), menuDO); | ||||
|         // 测试 id 不匹配 | ||||
|         menuCache.put(2L, randomPojo(MenuDO.class, o -> o.setId(2L) | ||||
|                 .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); | ||||
|         // 测试 type 不匹配 | ||||
|         menuCache.put(3L, randomPojo(MenuDO.class, o -> o.setId(3L) | ||||
|                 .setType(MenuTypeEnum.BUTTON.getType()).setStatus(CommonStatusEnum.ENABLE.getStatus()))); | ||||
|         // 测试 status 不匹配 | ||||
|         menuCache.put(4L, randomPojo(MenuDO.class, o -> o.setId(4L) | ||||
|                 .setType(MenuTypeEnum.MENU.getType()).setStatus(CommonStatusEnum.DISABLE.getStatus()))); | ||||
|         menuService.setMenuCache(menuCache); | ||||
|         // 准备参数 | ||||
|         Collection<Long> menuIds = asList(1L, 3L, 4L); | ||||
|         Collection<Integer> menuTypes = singletonList(MenuTypeEnum.MENU.getType()); | ||||
|         Collection<Integer> menusStatuses = singletonList(CommonStatusEnum.ENABLE.getStatus()); | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> list = menuService.getMenuListFromCache(menuIds, menuTypes, menusStatuses); | ||||
|         // 断言 | ||||
|         assertEquals(1, list.size()); | ||||
|         assertPojoEquals(menuDO, list.get(0)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenuListByPermissionFromCache() { | ||||
|         // mock 缓存 | ||||
|         Multimap<String, MenuDO> permissionMenuCache = LinkedListMultimap.create(); | ||||
|         // 可被匹配 | ||||
|         MenuDO menuDO01 = randomPojo(MenuDO.class, o -> o.setId(1L).setPermission("123")); | ||||
|         permissionMenuCache.put(menuDO01.getPermission(), menuDO01); | ||||
|         MenuDO menuDO02 = randomPojo(MenuDO.class, o -> o.setId(2L).setPermission("123")); | ||||
|         permissionMenuCache.put(menuDO02.getPermission(), menuDO02); | ||||
|         // 不可匹配 | ||||
|         permissionMenuCache.put("456", randomPojo(MenuDO.class, o -> o.setId(3L).setPermission("456"))); | ||||
|         menuService.setPermissionMenuCache(permissionMenuCache); | ||||
|         // 准备参数 | ||||
|         String permission = "123"; | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> list = menuService.getMenuListByPermissionFromCache(permission); | ||||
|         // 断言 | ||||
|         assertEquals(2, list.size()); | ||||
|         assertPojoEquals(menuDO01, list.get(0)); | ||||
|         assertPojoEquals(menuDO02, list.get(1)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenu() { | ||||
|         // mock 数据 | ||||
|         MenuDO menu = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menu); | ||||
|         // 准备参数 | ||||
|         Long id = menu.getId(); | ||||
|  | ||||
|         // 调用 | ||||
|         MenuDO dbMenu = menuService.getMenu(id); | ||||
|         // 断言 | ||||
|         assertPojoEquals(menu, dbMenu); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testValidateParentMenu_success() { | ||||
|         // mock 数据 | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         // 准备参数 | ||||
|         Long parentId = menuDO.getId(); | ||||
|  | ||||
|         // 调用,无需断言 | ||||
|         menuService.validateParentMenu(parentId, null); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testValidateParentMenu_canNotSetSelfToBeParent() { | ||||
|         // 调用,并断言异常 | ||||
|         assertServiceException(() -> menuService.validateParentMenu(1L, 1L), | ||||
|                 MENU_PARENT_ERROR); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testValidateParentMenu_parentNotExist() { | ||||
|         // 调用,并断言异常 | ||||
|         assertServiceException(() -> menuService.validateParentMenu(randomLongId(), null), | ||||
|                 MENU_PARENT_NOT_EXISTS); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testValidateParentMenu_parentTypeError() { | ||||
|         // mock 数据 | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         // 准备参数 | ||||
|         Long parentId = menuDO.getId(); | ||||
|  | ||||
|         // 调用,并断言异常 | ||||
|         assertServiceException(() -> menuService.validateParentMenu(parentId, null), | ||||
|                 MENU_PARENT_NOT_DIR_OR_MENU); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testValidateMenu_success() { | ||||
|         // mock 父子菜单 | ||||
|         MenuDO sonMenu = initParentAndSonMenu(); | ||||
|         // 准备参数 | ||||
|         Long parentId = sonMenu.getParentId(); | ||||
|         Long otherSonMenuId = randomLongId(); | ||||
|         String otherSonMenuName = randomString(); | ||||
|  | ||||
|         // 调用,无需断言 | ||||
|         menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testValidateMenu_sonMenuNameDuplicate() { | ||||
|         // mock 父子菜单 | ||||
|         MenuDO sonMenu = initParentAndSonMenu(); | ||||
|         // 准备参数 | ||||
|         Long parentId = sonMenu.getParentId(); | ||||
|         Long otherSonMenuId = randomLongId(); | ||||
|         String otherSonMenuName = sonMenu.getName(); //相同名称 | ||||
|  | ||||
|         // 调用,并断言异常 | ||||
|         assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId), | ||||
|                 MENU_NAME_DUPLICATE); | ||||
|     } | ||||
|  | ||||
|     // ====================== 初始化方法 ====================== | ||||
|  | ||||
|     /** | ||||
|      * 构造父子菜单,返回子菜单 | ||||
|      * | ||||
|      * @return 子菜单 | ||||
|      */ | ||||
|     private MenuDO initParentAndSonMenu() { | ||||
|         // 构造父子菜单 | ||||
|         MenuDO parentMenuDO = createMenuDO(MenuTypeEnum.MENU, "parent", ID_ROOT); | ||||
|         menuMapper.insert(parentMenuDO); | ||||
|         // 构建子菜单 | ||||
|         MenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", | ||||
|                 parentMenuDO.getParentId()); | ||||
|         menuMapper.insert(sonMenuDO); | ||||
|         return sonMenuDO; | ||||
|     } | ||||
|  | ||||
|     private MenuDO createMenuDO(MenuTypeEnum type, String name, Long parentId) { | ||||
|         return createMenuDO(type, name, parentId, randomCommonStatus()); | ||||
|     } | ||||
|  | ||||
|     private MenuDO createMenuDO(MenuTypeEnum type, String name, Long parentId, Integer status) { | ||||
|         return randomPojo(MenuDO.class, o -> o.setId(null).setName(name).setParentId(parentId) | ||||
|                 .setType(type.getType()).setStatus(status)); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,384 +0,0 @@ | ||||
| package cn.iocoder.yudao.module.system.service.permission; | ||||
|  | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.lang.Assert; | ||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||
| import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils; | ||||
| import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; | ||||
| import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO; | ||||
| import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; | ||||
| import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper; | ||||
| import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; | ||||
| import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer; | ||||
| import cn.iocoder.yudao.module.system.service.tenant.TenantService; | ||||
| import com.google.common.collect.Multimap; | ||||
| import org.junit.jupiter.api.Test; | ||||
| import org.springframework.boot.test.mock.mockito.MockBean; | ||||
| import org.springframework.context.annotation.Import; | ||||
|  | ||||
| import javax.annotation.Resource; | ||||
| import java.util.*; | ||||
|  | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | ||||
| import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | ||||
| import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | ||||
| import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; | ||||
| import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
| import static org.mockito.ArgumentMatchers.argThat; | ||||
| import static org.mockito.Mockito.doNothing; | ||||
| import static org.mockito.Mockito.verify; | ||||
|  | ||||
| // TODO @芋艿:单测的代码质量可以提升下 | ||||
| @Import(MenuServiceImpl.class) | ||||
| public class MenuServiceTest extends BaseDbUnitTest { | ||||
|  | ||||
|     @Resource | ||||
|     private MenuServiceImpl menuService; | ||||
|  | ||||
|     @Resource | ||||
|     private MenuMapper menuMapper; | ||||
|  | ||||
|     @MockBean | ||||
|     private PermissionService permissionService; | ||||
|     @MockBean | ||||
|     private MenuProducer menuProducer; | ||||
|     @MockBean | ||||
|     private TenantService tenantService; | ||||
|  | ||||
|     @Test | ||||
|     public void testInitLocalCache_success() { | ||||
|         MenuDO menuDO1 = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menuDO1); | ||||
|         MenuDO menuDO2 = randomPojo(MenuDO.class); | ||||
|         menuMapper.insert(menuDO2); | ||||
|  | ||||
|         // 调用 | ||||
|         menuService.initLocalCache(); | ||||
|         // 校验 menuCache 缓存 | ||||
|         Map<Long, MenuDO> menuCache = menuService.getMenuCache(); | ||||
|         Assert.isTrue(menuCache.size() == 2); | ||||
|         assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId())); | ||||
|         assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId())); | ||||
|         // 校验 permissionMenuCache 缓存 | ||||
|         Multimap<String, MenuDO> permissionMenuCache = menuService.getPermissionMenuCache(); | ||||
|         Assert.isTrue(permissionMenuCache.size() == 2); | ||||
|         assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission())); | ||||
|         assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission())); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCreateMenu_success() { | ||||
|         //构造父目录 | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         Long parentId = menuDO.getId(); | ||||
|  | ||||
|         //调用 | ||||
|         MenuCreateReqVO vo = randomPojo(MenuCreateReqVO.class, o -> { | ||||
|             o.setParentId(parentId); | ||||
|             o.setName("testSonName"); | ||||
|             o.setType(MenuTypeEnum.MENU.getType()); | ||||
|             o.setStatus(randomCommonStatus()); | ||||
|         }); | ||||
|         Long menuId = menuService.createMenu(vo); | ||||
|  | ||||
|         //断言 | ||||
|         assertNotNull(menuId); | ||||
|         // 校验记录的属性是否正确 | ||||
|         MenuDO ret = menuMapper.selectById(menuId); | ||||
|         assertPojoEquals(vo, ret); | ||||
|         // 校验调用 | ||||
|         verify(menuProducer).sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testUpdateMenu_success() { | ||||
|         //构造父子目录 | ||||
|         MenuDO sonMenuDO = initParentAndSonMenuDO(); | ||||
|         Long sonId = sonMenuDO.getId(); | ||||
|         Long parentId = sonMenuDO.getParentId(); | ||||
|  | ||||
|         //调用 | ||||
|         MenuUpdateReqVO vo = randomPojo(MenuUpdateReqVO.class, o -> { | ||||
|             o.setId(sonId); | ||||
|             o.setParentId(parentId); | ||||
|             o.setType(MenuTypeEnum.MENU.getType()); | ||||
|             o.setStatus(randomCommonStatus()); | ||||
|             o.setName("pppppp"); //修改名字 | ||||
|         }); | ||||
|         menuService.updateMenu(vo); | ||||
|  | ||||
|         //断言 | ||||
|         // 校验记录的属性是否正确 | ||||
|         MenuDO ret = menuMapper.selectById(sonId); | ||||
|         assertPojoEquals(vo, ret); | ||||
|         // 校验调用 | ||||
|         verify(menuProducer).sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testUpdateMenu_sonIdNotExist() { | ||||
|         Long sonId = 99999L; | ||||
|         Long parentId = 10000L; | ||||
|  | ||||
|         //调用 | ||||
|         MenuUpdateReqVO vo = randomPojo(MenuUpdateReqVO.class, o -> { | ||||
|             o.setId(sonId); | ||||
|             o.setParentId(parentId); | ||||
|             o.setType(MenuTypeEnum.MENU.getType()); | ||||
|             o.setStatus(randomCommonStatus()); | ||||
|         }); | ||||
|         //断言 | ||||
|         assertServiceException(() -> menuService.updateMenu(vo), MENU_NOT_EXISTS); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testDeleteMenu_success() { | ||||
|         MenuDO sonMenuDO = initParentAndSonMenuDO(); | ||||
|         Long sonId = sonMenuDO.getId(); | ||||
|  | ||||
|         // 调用 | ||||
|         menuService.deleteMenu(sonId); | ||||
|  | ||||
|         // 断言 | ||||
|         MenuDO menuDO = menuMapper.selectById(sonId); | ||||
|         assertNull(menuDO); | ||||
|         verify(permissionService).processMenuDeleted(sonId); | ||||
|         verify(menuProducer).sendMenuRefreshMessage(); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testDeleteMenu_menuNotExist() { | ||||
|         Long sonId = 99999L; | ||||
|  | ||||
|         assertServiceException(() -> menuService.deleteMenu(sonId), MENU_NOT_EXISTS); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testDeleteMenu_existChildren() { | ||||
|         MenuDO sonMenu = initParentAndSonMenuDO(); | ||||
|         Long parentId = sonMenu.getParentId(); | ||||
|  | ||||
|         assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenus() { | ||||
|         // mock 数据 | ||||
|         MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuMapper.insert(menu100); | ||||
|         MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); | ||||
|         menuMapper.insert(menu101); | ||||
|         // 准备参数 | ||||
|         MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> result = menuService.getMenus(reqVO); | ||||
|         // 断言 | ||||
|         assertEquals(1, result.size()); | ||||
|         assertPojoEquals(menu100, result.get(0)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testTenantMenus() { | ||||
|         // mock 数据 | ||||
|         MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuMapper.insert(menu100); | ||||
|         MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus())); | ||||
|         menuMapper.insert(menu101); | ||||
|         MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus())); | ||||
|         menuMapper.insert(menu102); | ||||
|         // mock 过滤菜单 | ||||
|         // mock 账户额度充足 | ||||
|         Set<Long> menuIds = asSet(100L, 101L); | ||||
|         doNothing().when(tenantService).handleTenantMenu(argThat(handler -> { | ||||
|             handler.handle(menuIds); | ||||
|             return true; | ||||
|         })); | ||||
|         // 准备参数 | ||||
|         MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()); | ||||
|  | ||||
|         // 调用 | ||||
|         List<MenuDO> result = menuService.getTenantMenus(reqVO); | ||||
|         // 断言 | ||||
|         assertEquals(1, result.size()); | ||||
|         assertPojoEquals(menu100, result.get(0)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testGetMenusReqVo_success() { | ||||
|         Map<Long, MenuDO> idMenuMap = new HashMap<>(); | ||||
|         // 用于验证可以模糊搜索名称包含"name",状态为1的menu | ||||
|         MenuDO menu = createMenuDO(MenuTypeEnum.MENU, "name2", 0L, 1); | ||||
|         menuMapper.insert(menu); | ||||
|         idMenuMap.put(menu.getId(), menu); | ||||
|  | ||||
|         menu = createMenuDO(MenuTypeEnum.MENU, "11name111", 0L, 1); | ||||
|         menuMapper.insert(menu); | ||||
|         idMenuMap.put(menu.getId(), menu); | ||||
|  | ||||
|         menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 1); | ||||
|         menuMapper.insert(menu); | ||||
|         idMenuMap.put(menu.getId(), menu); | ||||
|  | ||||
|         // 以下是不符合搜索条件的的menu | ||||
|         menu = createMenuDO(MenuTypeEnum.MENU, "xxxxxx", 0L, 1); | ||||
|         menuMapper.insert(menu); | ||||
|         menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 2); | ||||
|         menuMapper.insert(menu); | ||||
|  | ||||
|         // 调用 | ||||
|         MenuListReqVO reqVO = new MenuListReqVO(); | ||||
|         reqVO.setStatus(1); | ||||
|         reqVO.setName("name"); | ||||
|         List<MenuDO> menuDOS = menuService.getMenus(reqVO); | ||||
|  | ||||
|         // 断言 | ||||
|         assertEquals(menuDOS.size(), idMenuMap.size()); | ||||
|         menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testListMenusFromCache_success() throws Exception { | ||||
|         Map<Long, MenuDO> mockCacheMap = new HashMap<>(); | ||||
|         // 获取代理对象 | ||||
|         MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService); | ||||
|         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap); | ||||
|  | ||||
|         Map<Long, MenuDO> idMenuMap = new HashMap<>(); | ||||
|         // 用于验证搜索类型为MENU,状态为1的menu | ||||
|         MenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|         idMenuMap.put(menuDO.getId(), menuDO); | ||||
|  | ||||
|         menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|         idMenuMap.put(menuDO.getId(), menuDO); | ||||
|  | ||||
|         // 以下是不符合搜索条件的menu | ||||
|         menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|         menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|  | ||||
|         List<MenuDO> menuDOS = menuService.getMenuListFromCache(Collections.singletonList(MenuTypeEnum.MENU.getType()), | ||||
|                 Collections.singletonList(CommonStatusEnum.DISABLE.getStatus())); | ||||
|         assertEquals(menuDOS.size(), idMenuMap.size()); | ||||
|         menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testListMenusFromCache2_success() throws Exception { | ||||
|         Map<Long, MenuDO> mockCacheMap = new HashMap<>(); | ||||
|         // 获取代理对象 | ||||
|         MenuServiceImpl target = (MenuServiceImpl) SpringAopUtils.getTarget(menuService); | ||||
|         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap); | ||||
|  | ||||
|         Map<Long, MenuDO> idMenuMap = new HashMap<>(); | ||||
|         // 验证搜索id为1, 类型为MENU, 状态为1 的menu | ||||
|         MenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|         idMenuMap.put(menuDO.getId(), menuDO); | ||||
|  | ||||
|         // 以下是不符合搜索条件的menu | ||||
|         menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|         menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|         menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2); | ||||
|         mockCacheMap.put(menuDO.getId(), menuDO); | ||||
|  | ||||
|         List<MenuDO> menuDOS = menuService.getMenuListFromCache(Collections.singletonList(1L), | ||||
|                 Collections.singletonList(MenuTypeEnum.MENU.getType()), Collections.singletonList(1)); | ||||
|         assertEquals(menuDOS.size(), idMenuMap.size()); | ||||
|         menuDOS.forEach(menu -> assertPojoEquals(idMenuMap.get(menu.getId()), menu)); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCheckParentResource_success() { | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         Long parentId = menuDO.getId(); | ||||
|  | ||||
|         menuService.checkParentResource(parentId, null); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCheckParentResource_canNotSetSelfToBeParent() { | ||||
|         assertServiceException(() -> menuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCheckParentResource_parentNotExist() { | ||||
|         assertServiceException(() -> menuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCheckParentResource_parentTypeError() { | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         Long parentId = menuDO.getId(); | ||||
|  | ||||
|         assertServiceException(() -> menuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCheckResource_success() { | ||||
|         MenuDO sonMenu = initParentAndSonMenuDO(); | ||||
|         Long parentId = sonMenu.getParentId(); | ||||
|  | ||||
|         Long otherSonMenuId = randomLongId(); | ||||
|         String otherSonMenuName = randomString(); | ||||
|  | ||||
|         menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void testCheckResource_sonMenuNameDuplicate(){ | ||||
|         MenuDO sonMenu=initParentAndSonMenuDO(); | ||||
|         Long parentId=sonMenu.getParentId(); | ||||
|  | ||||
|         Long otherSonMenuId=randomLongId(); | ||||
|         String otherSonMenuName=sonMenu.getName(); //相同名称 | ||||
|  | ||||
|         assertServiceException(() -> menuService.checkResource(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 构造父子目录,返回子目录 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     private MenuDO initParentAndSonMenuDO() { | ||||
|         //构造父子目录 | ||||
|         MenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L); | ||||
|         menuMapper.insert(menuDO); | ||||
|         Long parentId = menuDO.getId(); | ||||
|  | ||||
|         MenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", parentId); | ||||
|         menuMapper.insert(sonMenuDO); | ||||
|         return sonMenuDO; | ||||
|     } | ||||
|  | ||||
|     private MenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId) { | ||||
|         return createMenuDO(typeEnum, menuName, parentId, randomCommonStatus()); | ||||
|     } | ||||
|  | ||||
|     private MenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) { | ||||
|         return createMenuDO(null, typeEnum, menuName, parentId, status); | ||||
|     } | ||||
|  | ||||
|     private MenuDO createMenuDO(Long id, MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) { | ||||
|         return randomPojo(MenuDO.class, o -> { | ||||
|             o.setId(id); | ||||
|             o.setParentId(parentId); | ||||
|             o.setType(typeEnum.getType()); | ||||
|             o.setStatus(status); | ||||
|             o.setName(menuName); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -163,7 +163,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { | ||||
|         // mock 方法 | ||||
|         when(roleService.hasAnySuperAdmin(eq(singleton(100L)))).thenReturn(true); | ||||
|         List<MenuDO> menuList = singletonList(randomPojo(MenuDO.class).setId(1L)); | ||||
|         when(menuService.getMenus()).thenReturn(menuList); | ||||
|         when(menuService.getMenuList()).thenReturn(menuList); | ||||
|  | ||||
|         // 调用 | ||||
|         Set<Long> menuIds = permissionService.getRoleMenuIds(roleId); | ||||
|   | ||||
| @@ -453,7 +453,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { | ||||
|         tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据 | ||||
|         TenantContextHolder.setTenantId(dbTenant.getId()); | ||||
|         // mock 菜单 | ||||
|         when(menuService.getMenus()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)), | ||||
|         when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)), | ||||
|                         randomPojo(MenuDO.class, o -> o.setId(101L)))); | ||||
|  | ||||
|         // 调用 | ||||
|   | ||||
| @@ -48,11 +48,11 @@ | ||||
| <!--            <version>${revision}</version>--> | ||||
| <!--        </dependency>--> | ||||
|         <!-- 工作流 --> | ||||
| <!--        <dependency>--> | ||||
| <!--            <groupId>cn.iocoder.boot</groupId>--> | ||||
| <!--            <artifactId>yudao-module-bpm-biz</artifactId>--> | ||||
| <!--            <version>${revision}</version>--> | ||||
| <!--        </dependency>--> | ||||
|         <dependency> | ||||
|             <groupId>cn.iocoder.boot</groupId> | ||||
|             <artifactId>yudao-module-bpm-biz</artifactId> | ||||
|             <version>${revision}</version> | ||||
|         </dependency> | ||||
|         <!-- 支付服务 --> | ||||
|         <dependency> | ||||
|             <groupId>cn.iocoder.boot</groupId> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV