mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
1、线程池bean命名规范;2、菜单管理controller、service单元测试完善;3、已有controller单测替换mock static SecurityFrameworkUtils;
This commit is contained in:
+32
@@ -0,0 +1,32 @@
|
||||
package com.cf.imes.module.system.framework.executor.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* system服务线程池配置
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2026/1/26 14:29
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class SystemThreadPoolConfiguration {
|
||||
public static final String SYSTEM_PERMISSION_THREAD_POOL_TASK_EXECUTOR = "systemPermissionThreadPoolTaskExecutor";
|
||||
|
||||
@Bean("systemPermissionThreadPoolTaskExecutor")
|
||||
public ThreadPoolTaskExecutor systemPermissionThreadPoolTaskExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(8); // 设置核心线程数
|
||||
executor.setMaxPoolSize(8); // 设置最大线程数
|
||||
executor.setKeepAliveSeconds(60); // 设置空闲时间
|
||||
executor.setQueueCapacity(100); // 设置队列大小
|
||||
executor.setThreadNamePrefix("system-permission-Executor-"); // 配置线程池的前缀
|
||||
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
// 进行加载
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
+28
-26
@@ -36,6 +36,7 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -53,6 +54,7 @@ import java.util.stream.IntStream;
|
||||
|
||||
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
|
||||
import static com.cf.imes.module.system.framework.executor.config.SystemThreadPoolConfiguration.SYSTEM_PERMISSION_THREAD_POOL_TASK_EXECUTOR;
|
||||
|
||||
/**
|
||||
* 菜单 Service 实现
|
||||
@@ -80,6 +82,8 @@ public class MenuServiceImpl implements MenuService {
|
||||
@Resource
|
||||
private TransProperties transProperties;
|
||||
|
||||
@Resource(name = SYSTEM_PERMISSION_THREAD_POOL_TASK_EXECUTOR)
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
|
||||
private static final String FIELD_CHARACTER = ":*:%s";
|
||||
|
||||
@@ -167,7 +171,7 @@ public class MenuServiceImpl implements MenuService {
|
||||
* @param sourceType
|
||||
*/
|
||||
private void validateManageSourceTypeOperatePermission(Integer sourceType) {
|
||||
if (!SecurityFrameworkUtils.isCfOrg() && sourceType.equals(MenuSourceTypeEnum.MANAGEMENT.getType())) {
|
||||
if (!SecurityFrameworkUtils.isCfOrg() && MenuSourceTypeEnum.MANAGEMENT.getType().equals(sourceType)) {
|
||||
throw new ServiceException(MANAGEMENT_MENU_OPERATION_PERMISSION_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -181,33 +185,32 @@ public class MenuServiceImpl implements MenuService {
|
||||
*/
|
||||
private void flushCacheWhenOperateMenu(Long menuId, String newPermission, String oldPermission) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
if (ObjectUtil.isNotNull(oldPermission)) {
|
||||
// 移除 USER_ROLE_ID_LIST:*:旧的permission
|
||||
String oldMenuPerPattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.PERMISSION_MENU_ID_LIST).append(FIELD_CHARACTER)), oldPermission);
|
||||
Long oldBatchDelPerNum = scanAndDelKeys(oldMenuPerPattern);
|
||||
log.info("[updateMenu] 批量删除redis[{}]数量:{}", oldMenuPerPattern, oldBatchDelPerNum);
|
||||
}
|
||||
try {
|
||||
if (ObjectUtil.isNotNull(oldPermission)) {
|
||||
// 移除 USER_ROLE_ID_LIST:*:旧的permission
|
||||
String oldMenuPerPattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.PERMISSION_MENU_ID_LIST).append(FIELD_CHARACTER)), oldPermission);
|
||||
Long oldBatchDelPerNum = scanAndDelKeys(oldMenuPerPattern);
|
||||
log.info("[updateMenu] 批量删除redis[{}]数量:{}", oldMenuPerPattern, oldBatchDelPerNum);
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotNull(newPermission)) {
|
||||
// 移除 USER_ROLE_ID_LIST:*:新的permission
|
||||
String newMenuPerPattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.PERMISSION_MENU_ID_LIST).append(FIELD_CHARACTER)), newPermission);
|
||||
Long newBatchDelPerNum = scanAndDelKeys(newMenuPerPattern);
|
||||
log.info("[updateMenu] 批量删除redis[{}]数量:{}", newMenuPerPattern, newBatchDelPerNum);
|
||||
}
|
||||
if (ObjectUtil.isNotNull(newPermission)) {
|
||||
// 移除 USER_ROLE_ID_LIST:*:新的permission
|
||||
String newMenuPerPattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.PERMISSION_MENU_ID_LIST).append(FIELD_CHARACTER)), newPermission);
|
||||
Long newBatchDelPerNum = scanAndDelKeys(newMenuPerPattern);
|
||||
log.info("[updateMenu] 批量删除redis[{}]数量:{}", newMenuPerPattern, newBatchDelPerNum);
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotNull(menuId)) {
|
||||
// 移除 MENU_ROLE_ID_LIST:*:menuId
|
||||
String menuRolePattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.MENU_ROLE_ID_LIST).append(FIELD_CHARACTER)), menuId);
|
||||
Long batchDelRoleNum = scanAndDelKeys(menuRolePattern);
|
||||
log.info("[deleteMenu] 批量删除redis[{}]数量:{}", menuRolePattern, batchDelRoleNum);
|
||||
}
|
||||
|
||||
// 清空本地缓存
|
||||
redisTemplate.convertAndSend(com.cf.imes.framework.redis.constants.RedisKeyConstants.PERMISSION_REFRESH, "");
|
||||
}).exceptionally(e -> {
|
||||
log.error("[deleteMenu] redis 清空PERMISSION_MENU_ID_LIST或message发送失败, topic:{}, 异常:{}", com.cf.imes.framework.redis.constants.RedisKeyConstants.PERMISSION_REFRESH, e);
|
||||
return null;
|
||||
});
|
||||
// 清空本地缓存
|
||||
redisTemplate.convertAndSend(com.cf.imes.framework.redis.constants.RedisKeyConstants.PERMISSION_REFRESH, "");
|
||||
} catch (Exception e) {
|
||||
log.error("[deleteMenu] redis 清空PERMISSION_MENU_ID_LIST或message发送失败, topic:{}, 异常:{}", com.cf.imes.framework.redis.constants.RedisKeyConstants.PERMISSION_REFRESH, e);
|
||||
}
|
||||
}, threadPoolTaskExecutor);
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +266,7 @@ public class MenuServiceImpl implements MenuService {
|
||||
|
||||
@Override
|
||||
public List<MenuDO> getMenuList(Collection<Long> ids) {
|
||||
return menuMapper.selectBatchIds(ids);
|
||||
return menuMapper.selectByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -272,7 +275,7 @@ public class MenuServiceImpl implements MenuService {
|
||||
if(CollUtil.isEmpty(ids)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return menuMapper.selectBatchIds(ids);
|
||||
return menuMapper.selectByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,8 +303,7 @@ public class MenuServiceImpl implements MenuService {
|
||||
throw new ServiceException(MENU_PARENT_NOT_EXISTS);
|
||||
}
|
||||
// 父菜单必须是目录或者菜单类型
|
||||
if (!MenuTypeEnum.DIR.getType().equals(menu.getType())
|
||||
&& !MenuTypeEnum.MENU.getType().equals(menu.getType())) {
|
||||
if (MenuTypeEnum.BUTTON.getType().equals(menu.getType())) {
|
||||
throw new ServiceException(MENU_PARENT_NOT_DIR_OR_MENU);
|
||||
}
|
||||
}
|
||||
@@ -407,7 +409,7 @@ public class MenuServiceImpl implements MenuService {
|
||||
String src = item.getString("src");
|
||||
String dst = item.getString("dst");
|
||||
|
||||
if (menuDO == null || !menuDO.getName().equals(UnicodeUtil.toString(src))) {
|
||||
if (!menuDO.getName().equals(UnicodeUtil.toString(src))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -2,6 +2,7 @@ package com.cf.imes.module.system.common;
|
||||
|
||||
import com.cf.imes.framework.security.core.LoginUser;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
@@ -16,6 +17,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
* @author Gqr
|
||||
* @since 2026/1/16 10:20
|
||||
*/
|
||||
@Slf4j
|
||||
public class WithMockLoginUserExtension implements BeforeEachCallback, AfterEachCallback {
|
||||
@Override
|
||||
public void afterEach(ExtensionContext context) {
|
||||
@@ -33,6 +35,8 @@ public class WithMockLoginUserExtension implements BeforeEachCallback, AfterEach
|
||||
loginUser.setDeptId(ann.deptId());
|
||||
loginUser.setNickname(ann.username());
|
||||
loginUser.setIsSupAdmin(ann.isSuperAdmin());
|
||||
loginUser.setUserType(ann.userType());
|
||||
loginUser.setProductId(ann.productId());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
+102
-97
@@ -6,10 +6,12 @@ import com.cf.imes.framework.ip.core.service.dto.IPQueryDataRespDTO;
|
||||
import com.cf.imes.framework.security.config.SecurityProperties;
|
||||
import com.cf.imes.framework.security.core.LoginUser;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
|
||||
import com.cf.imes.framework.web.config.ChenfengWebAutoConfiguration;
|
||||
import com.cf.imes.module.infra.api.logger.ApiErrorLogApi;
|
||||
import com.cf.imes.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginSmsCheckReqVO;
|
||||
@@ -31,6 +33,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -74,6 +77,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
*/
|
||||
@WebMvcTest(controllers = AuthController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||
@Import(ChenfengWebAutoConfiguration.class)
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
@TestPropertySource(properties = {
|
||||
"spring.application.name=test-app"
|
||||
})
|
||||
@@ -283,136 +287,138 @@ class AuthControllerTest extends BaseWebUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L)
|
||||
void testGetPermissionInfo_success() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> utilities = mockStatic(SecurityFrameworkUtils.class)) {
|
||||
utilities.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
|
||||
utilities.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(false);
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
user.setOrganId(100L);
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
user.setOrganId(100L);
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
when(organService.validOrgan(100L)).thenReturn(organization);
|
||||
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
when(organService.validOrgan(100L)).thenReturn(organization);
|
||||
when(ipQueryService.serviceEnable()).thenReturn(false);
|
||||
|
||||
when(ipQueryService.serviceEnable()).thenReturn(false);
|
||||
Set<Long> roleIds = new HashSet<>(Arrays.asList(10L, 20L));
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
|
||||
Set<Long> roleIds = new HashSet<>(Arrays.asList(10L, 20L));
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
RoleDO role1 = new RoleDO();
|
||||
role1.setId(10L);
|
||||
role1.setStatus(1);
|
||||
RoleDO role2 = new RoleDO();
|
||||
role2.setId(20L);
|
||||
role2.setStatus(1);
|
||||
when(roleService.getRoleList1(roleIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(role1, role2)));
|
||||
|
||||
RoleDO role1 = new RoleDO(); role1.setId(10L); role1.setStatus(1);
|
||||
RoleDO role2 = new RoleDO(); role2.setId(20L); role2.setStatus(1);
|
||||
when(roleService.getRoleList1(roleIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(role1, role2)));
|
||||
Set<Long> menuIds = new HashSet<>(Arrays.asList(1000L, 2000L));
|
||||
when(permissionService.getRoleMenuListByRoleId2(anySet(), eq(100L))).thenReturn(menuIds);
|
||||
|
||||
Set<Long> menuIds = new HashSet<>(Arrays.asList(1000L, 2000L));
|
||||
when(permissionService.getRoleMenuListByRoleId2(anySet(), eq(100L))).thenReturn(menuIds);
|
||||
MenuDO menu1 = new MenuDO();
|
||||
menu1.setId(1000L);
|
||||
menu1.setStatus(1);
|
||||
MenuDO menu2 = new MenuDO();
|
||||
menu2.setId(2000L);
|
||||
menu2.setStatus(1);
|
||||
when(menuService.getCustomEndPointMenuList(menuIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(menu1, menu2)));
|
||||
|
||||
MenuDO menu1 = new MenuDO(); menu1.setId(1000L); menu1.setStatus(1);
|
||||
MenuDO menu2 = new MenuDO(); menu2.setId(2000L); menu2.setStatus(1);
|
||||
when(menuService.getCustomEndPointMenuList(menuIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(menu1, menu2)));
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").exists());
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").exists());
|
||||
|
||||
// 验证调用顺序/次数(可选)
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
verify(organService, times(1)).validOrgan(100L);
|
||||
verify(roleService, times(1)).getRoleList1(roleIds);
|
||||
verify(menuService, times(1)).getCustomEndPointMenuList(menuIds);
|
||||
}
|
||||
// 验证调用顺序/次数(可选)
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
verify(organService, times(1)).validOrgan(100L);
|
||||
verify(roleService, times(1)).getRoleList1(roleIds);
|
||||
verify(menuService, times(1)).getCustomEndPointMenuList(menuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L, userType = 2)
|
||||
void testGetPermissionInfo_success_branch() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> utilities = mockStatic(SecurityFrameworkUtils.class)) {
|
||||
utilities.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
|
||||
utilities.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(true);
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
user.setOrganId(100L);
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
user.setOrganId(100L);
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
when(organService.validOrgan(100L)).thenReturn(organization);
|
||||
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
when(organService.validOrgan(100L)).thenReturn(organization);
|
||||
IPQueryDataRespDTO ipResp = new IPQueryDataRespDTO();
|
||||
ipResp.setProv("浙江");
|
||||
ipResp.setCity("杭州");
|
||||
ipResp.setArea("西湖");
|
||||
when(ipQueryService.serviceEnable()).thenReturn(true);
|
||||
when(ipQueryService.querySource(anyString())).thenReturn(ipResp);
|
||||
|
||||
IPQueryDataRespDTO ipResp = new IPQueryDataRespDTO();
|
||||
ipResp.setProv("浙江");
|
||||
ipResp.setCity("杭州");
|
||||
ipResp.setArea("西湖");
|
||||
when(ipQueryService.serviceEnable()).thenReturn(true);
|
||||
when(ipQueryService.querySource(anyString())).thenReturn(ipResp);
|
||||
Set<Long> roleIds = new HashSet<>(Arrays.asList(10L, 20L));
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
|
||||
Set<Long> roleIds = new HashSet<>(Arrays.asList(10L, 20L));
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
RoleDO role1 = new RoleDO();
|
||||
role1.setId(10L);
|
||||
role1.setStatus(1);
|
||||
RoleDO role2 = new RoleDO();
|
||||
role2.setId(20L);
|
||||
role2.setStatus(1);
|
||||
when(roleService.getRoleList1(roleIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(role1, role2)));
|
||||
|
||||
RoleDO role1 = new RoleDO(); role1.setId(10L); role1.setStatus(1);
|
||||
RoleDO role2 = new RoleDO(); role2.setId(20L); role2.setStatus(1);
|
||||
when(roleService.getRoleList1(roleIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(role1, role2)));
|
||||
Set<Long> menuIds = new HashSet<>(Arrays.asList(1000L, 2000L));
|
||||
when(permissionService.getRoleMenuListByRoleId2(anySet(), eq(100L))).thenReturn(menuIds);
|
||||
|
||||
Set<Long> menuIds = new HashSet<>(Arrays.asList(1000L, 2000L));
|
||||
when(permissionService.getRoleMenuListByRoleId2(anySet(), eq(100L))).thenReturn(menuIds);
|
||||
MenuDO menu1 = new MenuDO();
|
||||
menu1.setId(1000L);
|
||||
menu1.setStatus(1);
|
||||
MenuDO menu2 = new MenuDO();
|
||||
menu2.setId(2000L);
|
||||
menu2.setStatus(1);
|
||||
when(menuService.getManageEndPointMenuList(menuIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(menu1, menu2)));
|
||||
|
||||
MenuDO menu1 = new MenuDO(); menu1.setId(1000L); menu1.setStatus(1);
|
||||
MenuDO menu2 = new MenuDO(); menu2.setId(2000L); menu2.setStatus(1);
|
||||
when(menuService.getManageEndPointMenuList(menuIds))
|
||||
.thenReturn(new ArrayList<>(Arrays.asList(menu1, menu2)));
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").exists());
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").exists());
|
||||
|
||||
// 验证调用顺序/次数(可选)
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
verify(organService, times(1)).validOrgan(100L);
|
||||
verify(ipQueryService, times(1)).querySource(anyString());
|
||||
verify(roleService, times(1)).getRoleList1(roleIds);
|
||||
verify(menuService, times(1)).getManageEndPointMenuList(menuIds);
|
||||
}
|
||||
// 验证调用顺序/次数(可选)
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
verify(organService, times(1)).validOrgan(100L);
|
||||
verify(ipQueryService, times(1)).querySource(anyString());
|
||||
verify(roleService, times(1)).getRoleList1(roleIds);
|
||||
verify(menuService, times(1)).getManageEndPointMenuList(menuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L)
|
||||
void testGetPermissionInfo_success_roleEmpty() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> utilities = mockStatic(SecurityFrameworkUtils.class)) {
|
||||
utilities.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
|
||||
utilities.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(true);
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
user.setOrganId(100L);
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
user.setOrganId(100L);
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
when(organService.validOrgan(100L)).thenReturn(organization);
|
||||
|
||||
OrganizationDO organization = new OrganizationDO();
|
||||
when(organService.validOrgan(100L)).thenReturn(organization);
|
||||
when(ipQueryService.serviceEnable()).thenReturn(false);
|
||||
|
||||
when(ipQueryService.serviceEnable()).thenReturn(false);
|
||||
Set<Long> roleIds = new HashSet<>();
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
|
||||
Set<Long> roleIds = new HashSet<>();
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.roles").isEmpty());
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.roles").isEmpty());
|
||||
|
||||
// 验证调用顺序/次数(可选)
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
verify(organService, times(1)).validOrgan(100L);
|
||||
verify(ipQueryService, never()).querySource(anyString());
|
||||
verify(roleService, never()).getRoleList1(roleIds);
|
||||
verify(menuService, never()).getManageEndPointMenuList(anySet());
|
||||
}
|
||||
// 验证调用顺序/次数(可选)
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
verify(organService, times(1)).validOrgan(100L);
|
||||
verify(ipQueryService, never()).querySource(anyString());
|
||||
verify(roleService, never()).getRoleList1(roleIds);
|
||||
verify(menuService, never()).getManageEndPointMenuList(anySet());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L)
|
||||
void testGetPermissionInfo_userNull() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> utilities = mockStatic(SecurityFrameworkUtils.class)) {
|
||||
utilities.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
|
||||
|
||||
when(userService.getUser(1L)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/auth/get-permission-info"))
|
||||
@@ -420,7 +426,6 @@ class AuthControllerTest extends BaseWebUnitTest {
|
||||
.andExpect(jsonPath("$.data").isEmpty()); // 返回 null
|
||||
|
||||
verify(userService, times(1)).getUser(1L);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-1
@@ -2,6 +2,7 @@ package com.cf.imes.module.system.controller.admin.dict;
|
||||
|
||||
import com.cf.imes.framework.common.enums.CommonStatusEnum;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.dict.vo.data.DictDataSimpleRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.dict.vo.data.DictDataTransReqVO;
|
||||
@@ -37,7 +38,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @since 2026/1/14 15:38
|
||||
*/
|
||||
@WebMvcTest(controllers = DictDataController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||
class DictDataControllerTest {
|
||||
class DictDataControllerTest extends BaseWebUnitTest {
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ package com.cf.imes.module.system.controller.admin.dict;
|
||||
import com.cf.imes.framework.common.enums.CommonStatusEnum;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.excel.core.util.ExcelUtils;
|
||||
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
|
||||
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypeRespVO;
|
||||
import com.cf.imes.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.dict.DictTypeDO;
|
||||
@@ -42,7 +43,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @since 2026/1/14 17:25
|
||||
*/
|
||||
@WebMvcTest(controllers = DictTypeController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||
public class DictTypeControllerTest {
|
||||
class DictTypeControllerTest extends BaseWebUnitTest {
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
|
||||
+12
-11
@@ -3,7 +3,9 @@ package com.cf.imes.module.system.controller.admin.funds.products;
|
||||
import com.cf.imes.framework.common.pojo.PageParam;
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.products.vo.product.ProductSaveReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.funds.products.ProductsDO;
|
||||
@@ -11,6 +13,7 @@ import com.cf.imes.module.system.enums.products.ProductStatusEnum;
|
||||
import com.cf.imes.module.system.service.funds.products.ProductsService;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
@@ -41,6 +44,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
* @since 2025/10/14 11:16
|
||||
*/
|
||||
@WebMvcTest(controllers = ProductsController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
class ProductsControllerTest extends BaseWebUnitTest {
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@@ -164,6 +168,7 @@ class ProductsControllerTest extends BaseWebUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userType = 2)
|
||||
void testGetAvailableProductsPage() throws Exception {
|
||||
ProductPageReqVO reqVO = new ProductPageReqVO();
|
||||
PageResult<ProductsDO> mockPage = new PageResult<>();
|
||||
@@ -171,21 +176,17 @@ class ProductsControllerTest extends BaseWebUnitTest {
|
||||
mockPage.setList(List.of(new ProductsDO().setId(1L).setProductName("已上架产品")));
|
||||
when(productsService.getPage(any())).thenReturn(mockPage);
|
||||
|
||||
// mock 管理端标识
|
||||
try (var ignored = mockStatic(SecurityFrameworkUtils.class)) {
|
||||
when(SecurityFrameworkUtils.isManageEndPoint()).thenReturn(true);
|
||||
mockMvc.perform(get("/system/products/available")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(reqVO)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.list[0].productName").value("已上架产品"));
|
||||
|
||||
mockMvc.perform(get("/system/products/available")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(reqVO)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data.list[0].productName").value("已上架产品"));
|
||||
|
||||
verify(productsService, times(1)).getPage(any());
|
||||
}
|
||||
verify(productsService, times(1)).getPage(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(productId = 123L)
|
||||
void testGetAvailableProductsPage_nonManager() throws Exception {
|
||||
ProductPageReqVO reqVO = new ProductPageReqVO();
|
||||
|
||||
|
||||
+35
-52
@@ -1,15 +1,15 @@
|
||||
package com.cf.imes.module.system.controller.admin.funds.purchase;
|
||||
|
||||
import com.cf.imes.framework.common.pojo.PageResult;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordPageReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.funds.purchase.vo.PurchaseRecordRespVO;
|
||||
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
@@ -39,6 +39,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
controllers = PurchaseController.class,
|
||||
excludeAutoConfiguration = SecurityAutoConfiguration.class
|
||||
)
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
class PurchaseControllerTest extends BaseWebUnitTest {
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@@ -50,13 +51,8 @@ class PurchaseControllerTest extends BaseWebUnitTest {
|
||||
* 非管理端:获取购买记录分页
|
||||
*/
|
||||
@Test
|
||||
@WithMockLoginUser(organId = 1L)
|
||||
void testGetPurchaseRecord_nonManage() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
|
||||
|
||||
// mock 当前为非管理端
|
||||
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(false);
|
||||
mocked.when(SecurityFrameworkUtils::getUserOrganId).thenReturn(1L);
|
||||
|
||||
// mock service 返回
|
||||
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
|
||||
respVO.setId(1L);
|
||||
@@ -84,18 +80,15 @@ class PurchaseControllerTest extends BaseWebUnitTest {
|
||||
.getPurchaseRecord(captor.capture());
|
||||
|
||||
assertEquals(1L, captor.getValue().getOrganId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理端:获取购买记录分页
|
||||
*/
|
||||
@Test
|
||||
@WithMockLoginUser(userType = 2)
|
||||
void testGetPurchaseRecord_manage() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
|
||||
|
||||
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(true);
|
||||
|
||||
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
|
||||
pageResult.setTotal(0L);
|
||||
pageResult.setList(Collections.emptyList());
|
||||
@@ -110,64 +103,54 @@ class PurchaseControllerTest extends BaseWebUnitTest {
|
||||
|
||||
verify(purchaseService, times(1))
|
||||
.getPurchaseRecord(any());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 非管理端:导出购买记录
|
||||
*/
|
||||
@Test
|
||||
@WithMockLoginUser(organId = 1L)
|
||||
void testExportPurchaseRecord_nonManage() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
|
||||
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
|
||||
respVO.setId(1L);
|
||||
respVO.setOrganId(1L);
|
||||
|
||||
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(false);
|
||||
mocked.when(SecurityFrameworkUtils::getUserOrganId).thenReturn(1L);
|
||||
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
|
||||
pageResult.setTotal(1L);
|
||||
pageResult.setList(List.of(respVO));
|
||||
|
||||
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
|
||||
respVO.setId(1L);
|
||||
respVO.setOrganId(1L);
|
||||
when(purchaseService.getPurchaseRecord(any()))
|
||||
.thenReturn(pageResult);
|
||||
|
||||
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
|
||||
pageResult.setTotal(1L);
|
||||
pageResult.setList(List.of(respVO));
|
||||
mockMvc.perform(get("/system/purchase/export")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
when(purchaseService.getPurchaseRecord(any()))
|
||||
.thenReturn(pageResult);
|
||||
|
||||
mockMvc.perform(get("/system/purchase/export")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
verify(purchaseService, times(1))
|
||||
.getPurchaseRecord(any());
|
||||
}
|
||||
verify(purchaseService, times(1))
|
||||
.getPurchaseRecord(any());
|
||||
}
|
||||
//
|
||||
|
||||
/**
|
||||
* 管理端:导出购买记录
|
||||
*/
|
||||
@Test
|
||||
@WithMockLoginUser(userType = 2)
|
||||
void testExportPurchaseRecord_manage() throws Exception {
|
||||
try (MockedStatic<SecurityFrameworkUtils> mocked = Mockito.mockStatic(SecurityFrameworkUtils.class)) {
|
||||
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
|
||||
respVO.setId(1L);
|
||||
|
||||
mocked.when(SecurityFrameworkUtils::isManageEndPoint).thenReturn(true);
|
||||
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
|
||||
pageResult.setTotal(1L);
|
||||
pageResult.setList(List.of(respVO));
|
||||
|
||||
PurchaseRecordRespVO respVO = new PurchaseRecordRespVO();
|
||||
respVO.setId(1L);
|
||||
when(purchaseService.getPurchaseRecord(any()))
|
||||
.thenReturn(pageResult);
|
||||
|
||||
PageResult<PurchaseRecordRespVO> pageResult = new PageResult<>();
|
||||
pageResult.setTotal(1L);
|
||||
pageResult.setList(List.of(respVO));
|
||||
mockMvc.perform(get("/system/purchase/export")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
when(purchaseService.getPurchaseRecord(any()))
|
||||
.thenReturn(pageResult);
|
||||
|
||||
mockMvc.perform(get("/system/purchase/export")
|
||||
.contentType(MediaType.APPLICATION_JSON))
|
||||
.andExpect(status().isOk());
|
||||
|
||||
verify(purchaseService, times(1))
|
||||
.getPurchaseRecord(any());
|
||||
}
|
||||
verify(purchaseService, times(1))
|
||||
.getPurchaseRecord(any());
|
||||
}
|
||||
}
|
||||
|
||||
+340
@@ -0,0 +1,340 @@
|
||||
package com.cf.imes.module.system.controller.admin.permission;
|
||||
|
||||
import com.cf.imes.framework.common.enums.CommonStatusEnum;
|
||||
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
|
||||
import com.cf.imes.framework.web.config.ChenfengWebAutoConfiguration;
|
||||
import com.cf.imes.module.infra.api.logger.ApiErrorLogApi;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.permission.vo.menu.*;
|
||||
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.cf.imes.module.system.enums.permission.MenuSourceTypeEnum;
|
||||
import com.cf.imes.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.cf.imes.module.system.service.permission.MenuService;
|
||||
import com.cf.imes.module.system.service.permission.PermissionService;
|
||||
import com.cf.imes.module.system.service.permission.RoleService;
|
||||
import com.cf.imes.module.system.service.user.AdminUserService;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
/**
|
||||
* 菜单管理单元测试
|
||||
*
|
||||
* @author Gqr
|
||||
* @since 2026/1/26 16:40
|
||||
*/
|
||||
@WebMvcTest(controllers = MenuController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
@Import(ChenfengWebAutoConfiguration.class)
|
||||
@TestPropertySource(properties = {
|
||||
"spring.application.name=test-app"
|
||||
})
|
||||
class MenuControllerTest extends BaseWebUnitTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockitoBean
|
||||
private MenuService menuService;
|
||||
|
||||
@MockitoBean
|
||||
private PermissionService permissionService;
|
||||
|
||||
@MockitoBean
|
||||
private AdminUserService userService;
|
||||
|
||||
@MockitoBean
|
||||
private RoleService roleService;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@MockitoBean
|
||||
private ApiErrorLogApi apiErrorLogApi;
|
||||
|
||||
@Test
|
||||
void createMenu_success() throws Exception {
|
||||
MenuSaveVO reqVO = new MenuSaveVO();
|
||||
reqVO.setName("新增菜单");
|
||||
reqVO.setParentId(0L);
|
||||
reqVO.setType(MenuTypeEnum.MENU.getType());
|
||||
reqVO.setSort(1);
|
||||
reqVO.setParentId(MenuDO.ID_ROOT);
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setSourceType(MenuSourceTypeEnum.PRODUCTION.getType());
|
||||
|
||||
when(menuService.createMenu(any(MenuSaveVO.class)))
|
||||
.thenReturn(100L);
|
||||
|
||||
mockMvc.perform(post("/admin-api/system/menu/create")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(reqVO)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(100L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateMenu_success() throws Exception {
|
||||
MenuSaveVO reqVO = new MenuSaveVO();
|
||||
reqVO.setId(1L);
|
||||
reqVO.setName("更新菜单");
|
||||
reqVO.setType(MenuTypeEnum.MENU.getType());
|
||||
reqVO.setSort(1);
|
||||
reqVO.setParentId(MenuDO.ID_ROOT);
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setSourceType(MenuSourceTypeEnum.PRODUCTION.getType());
|
||||
|
||||
mockMvc.perform(put("/admin-api/system/menu/update")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(reqVO)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(true));
|
||||
|
||||
verify(menuService).updateMenu(any(MenuSaveVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteMenu_success() throws Exception {
|
||||
mockMvc.perform(delete("/admin-api/system/menu/delete")
|
||||
.param("id", "1"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(true));
|
||||
|
||||
verify(menuService).deleteMenu(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L)
|
||||
void getCustomMenuList_success() throws Exception {
|
||||
// 准备模拟数据
|
||||
List<MenuDO> menuList = Arrays.asList(createMenuDO(1L, CommonStatusEnum.ENABLE.getStatus()));
|
||||
|
||||
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
|
||||
Set<Long> roleIds = new HashSet<>();
|
||||
roleIds.add(1L);
|
||||
|
||||
List<RoleDO> roles = Arrays.asList(createRoleDO(1L, CommonStatusEnum.ENABLE.getStatus()));
|
||||
|
||||
Set<Long> menuIds = new HashSet<>();
|
||||
menuIds.add(1L);
|
||||
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
when(roleService.getRoleList1(roleIds)).thenReturn(roles);
|
||||
when(permissionService.getRoleMenuListByRoleId2(any(Set.class), eq(100L))).thenReturn(menuIds);
|
||||
when(menuService.getCustomEndPointMenuList(menuIds)).thenReturn(menuList);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/custom/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray());
|
||||
|
||||
verify(userService).getUser(1L);
|
||||
verify(permissionService).getUserRoleIdListByUserId(1L);
|
||||
verify(roleService).getRoleList1(roleIds);
|
||||
verify(permissionService).getRoleMenuListByRoleId2(any(Set.class), eq(100L));
|
||||
verify(menuService).getCustomEndPointMenuList(menuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L, isSuperAdmin = true)
|
||||
void getMenuList_superAdmin_success() throws Exception {
|
||||
// 准备模拟数据
|
||||
List<MenuDO> menuList = Arrays.asList(createMenuDO(1L, CommonStatusEnum.ENABLE.getStatus()));
|
||||
|
||||
when(menuService.getMenuList(any(MenuListReqVO.class))).thenReturn(menuList);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray());
|
||||
|
||||
verify(menuService).getMenuList(any(MenuListReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L)
|
||||
void getMenuList_notsuperAdmin_getUserNull() throws Exception {
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
when(userService.getUser(loginUserId)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L)
|
||||
void getMenuList_notsuperAdmin_getRolesEmpty() throws Exception {
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
when(userService.getUser(loginUserId)).thenReturn(new AdminUserDO());
|
||||
|
||||
when(permissionService.getUserRoleIdListByUserId(loginUserId)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser(userId = 1L, organId = 100L)
|
||||
void getMenuList_normalUser_success() throws Exception {
|
||||
// 准备模拟数据
|
||||
List<MenuDO> menuList = Arrays.asList(createMenuDO(1L, CommonStatusEnum.ENABLE.getStatus()));
|
||||
|
||||
AdminUserDO user = new AdminUserDO();
|
||||
user.setId(1L);
|
||||
|
||||
Set<Long> roleIds = new HashSet<>();
|
||||
roleIds.add(1L);
|
||||
|
||||
List<RoleDO> roles = Arrays.asList(createRoleDO(1L, CommonStatusEnum.ENABLE.getStatus()));
|
||||
|
||||
Set<Long> menuIds = new HashSet<>();
|
||||
menuIds.add(1L);
|
||||
|
||||
when(userService.getUser(1L)).thenReturn(user);
|
||||
when(permissionService.getUserRoleIdListByUserId(1L)).thenReturn(roleIds);
|
||||
when(roleService.getRoleList1(roleIds)).thenReturn(roles);
|
||||
when(permissionService.getRoleMenuListByRoleId2(any(Set.class), eq(100L))).thenReturn(menuIds);
|
||||
when(menuService.getMenuList1(menuIds)).thenReturn(menuList);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray());
|
||||
|
||||
verify(userService).getUser(1L);
|
||||
verify(permissionService).getUserRoleIdListByUserId(1L);
|
||||
verify(roleService).getRoleList1(roleIds);
|
||||
verify(permissionService).getRoleMenuListByRoleId2(any(Set.class), eq(100L));
|
||||
verify(menuService).getMenuList1(menuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMenuList_noLoginUser_failure() throws Exception {
|
||||
mockMvc.perform(get("/admin-api/system/menu/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(GlobalErrorCodeConstants.UNAUTHORIZED.getCode()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCustomMenuList_noLoginUser_failure() throws Exception {
|
||||
mockMvc.perform(get("/admin-api/system/menu/custom/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(GlobalErrorCodeConstants.UNAUTHORIZED.getCode()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getCustomMenuList_getUserNull() throws Exception {
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
when(userService.getUser(loginUserId)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/custom/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void getCustomMenuList_getRolesEmpty() throws Exception {
|
||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||
when(userService.getUser(loginUserId)).thenReturn(new AdminUserDO());
|
||||
|
||||
when(permissionService.getUserRoleIdListByUserId(loginUserId)).thenReturn(null);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/custom/list"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSimpleMenuList_success() throws Exception {
|
||||
List<MenuDO> menuList = Arrays.asList(createMenuDO(1L, CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(menuService.getMenuListByOrgan(any(MenuListReqVO.class))).thenReturn(menuList);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/list-all-simple"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").isArray());
|
||||
|
||||
verify(menuService).getMenuListByOrgan(any(MenuListReqVO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMenu_success() throws Exception {
|
||||
MenuDO menuDO = createMenuDO(1L, CommonStatusEnum.ENABLE.getStatus());
|
||||
when(menuService.getMenu(1L)).thenReturn(menuDO);
|
||||
|
||||
mockMvc.perform(get("/admin-api/system/menu/get")
|
||||
.param("id", "1"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data.id").value(1L));
|
||||
|
||||
verify(menuService).getMenu(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void trans_success() throws Exception {
|
||||
MenuTransReqVO reqVO = new MenuTransReqVO();
|
||||
reqVO.setTargetLanguage("en");
|
||||
|
||||
mockMvc.perform(post("/admin-api/system/menu/trans")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(reqVO)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(0))
|
||||
.andExpect(jsonPath("$.data").value(true));
|
||||
|
||||
verify(menuService).trans(any(MenuTransReqVO.class));
|
||||
}
|
||||
|
||||
// 辅助方法:创建MenuDO实例
|
||||
private MenuDO createMenuDO(Long id, Integer status) {
|
||||
MenuDO menuDO = new MenuDO();
|
||||
menuDO.setId(id);
|
||||
menuDO.setStatus(status);
|
||||
menuDO.setName("测试菜单");
|
||||
menuDO.setSort(0);
|
||||
return menuDO;
|
||||
}
|
||||
|
||||
// 辅助方法:创建RoleDO实例
|
||||
private RoleDO createRoleDO(Long id, Integer status) {
|
||||
RoleDO roleDO = new RoleDO();
|
||||
roleDO.setId(id);
|
||||
roleDO.setStatus(status);
|
||||
return roleDO;
|
||||
}
|
||||
}
|
||||
+445
-89
@@ -1,74 +1,189 @@
|
||||
package com.cf.imes.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.cf.imes.framework.common.enums.CommonStatusEnum;
|
||||
import com.cf.imes.framework.test.core.ut.BaseDbUnitTest;
|
||||
import com.cf.imes.framework.common.exception.ServiceException;
|
||||
import com.cf.imes.framework.security.test.WithMockLoginUser;
|
||||
import com.cf.imes.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import com.cf.imes.module.system.common.WithMockLoginUserExtension;
|
||||
import com.cf.imes.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||
import com.cf.imes.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
|
||||
import com.cf.imes.module.system.controller.admin.permission.vo.menu.MenuTransReqVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.cf.imes.module.system.dal.dataobject.permission.MenuI18nDO;
|
||||
import com.cf.imes.module.system.dal.mysql.permission.MenuI18nMapper;
|
||||
import com.cf.imes.module.system.dal.mysql.permission.MenuMapper;
|
||||
import com.cf.imes.module.system.enums.common.LanguageEnum;
|
||||
import com.cf.imes.module.system.enums.permission.MenuSourceTypeEnum;
|
||||
import com.cf.imes.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.cf.imes.module.system.framework.trans.config.TransApi;
|
||||
import com.cf.imes.module.system.framework.trans.config.TransProperties;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.cf.imes.framework.common.util.collection.SetUtils.asSet;
|
||||
import static com.cf.imes.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static com.cf.imes.framework.test.core.util.RandomUtils.*;
|
||||
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(MenuServiceImpl.class)
|
||||
public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
@ExtendWith(WithMockLoginUserExtension.class)
|
||||
class MenuServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@Resource
|
||||
@InjectMocks
|
||||
private MenuServiceImpl menuService;
|
||||
|
||||
@Resource
|
||||
@Mock
|
||||
private MenuMapper menuMapper;
|
||||
|
||||
@MockBean
|
||||
@Mock
|
||||
private PermissionService permissionService;
|
||||
@MockBean
|
||||
private OrganService tenantService;
|
||||
|
||||
@Mock
|
||||
private OrganService organService;
|
||||
|
||||
@Mock
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Mock
|
||||
private Cursor<String> cursor;
|
||||
|
||||
@Mock
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
|
||||
@Mock
|
||||
private MenuI18nMapper menuI18nMapper;
|
||||
|
||||
@Mock
|
||||
private TransProperties transProperties;
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateMenu_success() {
|
||||
@WithMockLoginUser(organId = 1L)
|
||||
void testCreateMenu_success() {
|
||||
// mock 数据(构造父菜单)
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU,
|
||||
"parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
Long parentId = menuDO.getId();
|
||||
when(menuMapper.selectById(parentId)).thenReturn(menuDO);
|
||||
|
||||
// 校验自己
|
||||
when(menuMapper.selectByParentIdAndNameAndSourceType(any(), any(), any())).thenReturn(null);
|
||||
|
||||
// 模拟 Mapper 插入时生成 ID
|
||||
doAnswer(invocation -> {
|
||||
MenuDO mdo = invocation.getArgument(0);
|
||||
mdo.setId(100L); // 模拟自增主键
|
||||
return null;
|
||||
}).when(menuMapper).insert(any(MenuDO.class));
|
||||
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
|
||||
o.setParentId(parentId);
|
||||
o.setName("testSonName");
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
o.setType(MenuTypeEnum.BUTTON.getType());
|
||||
}).setId(null); // 防止 id 被赋值
|
||||
|
||||
// redis mock
|
||||
when(redisTemplate.scan(any())).thenReturn(cursor);
|
||||
when(cursor.hasNext()).thenReturn(true, false);
|
||||
|
||||
// mock executor
|
||||
doAnswer((InvocationOnMock invocation) -> {
|
||||
((Runnable) invocation.getArguments()[0]).run();
|
||||
return null;
|
||||
}).when(threadPoolTaskExecutor).execute(any(Runnable.class));
|
||||
|
||||
Long menuId = menuService.createMenu(reqVO);
|
||||
|
||||
// 校验记录的属性是否正确
|
||||
MenuDO dbMenu = menuMapper.selectById(menuId);
|
||||
assertPojoEquals(reqVO, dbMenu, "id");
|
||||
// 断言
|
||||
assertEquals(100L, menuId);
|
||||
verify(redisTemplate, times(1)).convertAndSend(com.cf.imes.framework.redis.constants.RedisKeyConstants.PERMISSION_REFRESH, "");
|
||||
verify(redisTemplate, times(2)).scan(any());
|
||||
verify(menuMapper).insert(argThat((MenuDO menuArg) ->
|
||||
ObjectUtil.equals(menuArg.getName(), reqVO.getName())
|
||||
&& ObjectUtil.equals(menuArg.getPermission(), reqVO.getPermission())
|
||||
&& ObjectUtil.equals(menuArg.getType(), reqVO.getType())
|
||||
&& ObjectUtil.equals(menuArg.getSort(), reqVO.getSort())
|
||||
&& ObjectUtil.equals(menuArg.getParentId(), reqVO.getParentId())
|
||||
&& ObjectUtil.equals("", menuArg.getPath())
|
||||
&& ObjectUtil.equals("", menuArg.getIcon())
|
||||
&& ObjectUtil.equals("", menuArg.getComponent())
|
||||
&& ObjectUtil.equals("", menuArg.getComponentName())
|
||||
&& ObjectUtil.equals(menuArg.getStatus(), reqVO.getStatus())
|
||||
&& ObjectUtil.equals(menuArg.getVisible(), reqVO.getVisible())
|
||||
&& ObjectUtil.equals(menuArg.getKeepAlive(), reqVO.getKeepAlive())
|
||||
&& ObjectUtil.equals(menuArg.getAlwaysShow(), reqVO.getAlwaysShow())
|
||||
&& ObjectUtil.equals(menuArg.getDescription(), reqVO.getDescription())
|
||||
&& ObjectUtil.equals(menuArg.getSourceType(), reqVO.getSourceType())
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMenu_success() {
|
||||
@WithMockLoginUser
|
||||
void testCreateMenu_fail_sourceTypePermissionError() {
|
||||
// mock 数据(构造父菜单)
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU,
|
||||
"parent", 0L);
|
||||
Long parentId = menuDO.getId();
|
||||
when(menuMapper.selectById(parentId)).thenReturn(menuDO);
|
||||
|
||||
// 校验自己
|
||||
when(menuMapper.selectByParentIdAndNameAndSourceType(any(), any(), any())).thenReturn(null);
|
||||
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
|
||||
o.setParentId(parentId);
|
||||
o.setSourceType(MenuSourceTypeEnum.MANAGEMENT.getType());
|
||||
}).setId(null); // 防止 id 被赋值
|
||||
|
||||
assertServiceException(() -> menuService.createMenu(reqVO), MANAGEMENT_MENU_OPERATION_PERMISSION_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void testUpdateMenu_success() {
|
||||
// 校验父级
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU,
|
||||
"parent", 0L);
|
||||
|
||||
// mock 数据(构造父子菜单)
|
||||
MenuDO sonMenuDO = createParentAndSonMenu();
|
||||
MenuDO sonMenuDO = buildMenuDO(MenuTypeEnum.MENU, "testSonName",
|
||||
menuDO.getParentId());
|
||||
when(menuMapper.selectById(any())).thenReturn(sonMenuDO).thenReturn(menuDO);
|
||||
when(menuMapper.selectByParentIdAndNameAndSourceType(any(), any(), any())).thenReturn(sonMenuDO);
|
||||
|
||||
Long sonId = sonMenuDO.getId();
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
|
||||
@@ -76,17 +191,67 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
o.setName("testSonName"); // 修改名字
|
||||
o.setParentId(sonMenuDO.getParentId());
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
o.setPermission(null);
|
||||
});
|
||||
|
||||
// redis mock
|
||||
when(redisTemplate.scan(any())).thenReturn(cursor);
|
||||
when(cursor.hasNext()).thenReturn(true, false);
|
||||
|
||||
// mock executor
|
||||
doAnswer((InvocationOnMock invocation) -> {
|
||||
((Runnable) invocation.getArguments()[0]).run();
|
||||
return null;
|
||||
}).when(threadPoolTaskExecutor).execute(any(Runnable.class));
|
||||
|
||||
|
||||
// 调用
|
||||
menuService.updateMenu(reqVO);
|
||||
|
||||
// 校验记录的属性是否正确
|
||||
verify(menuMapper, times(1)).updateById(any(MenuDO.class));
|
||||
verify(redisTemplate, times(2)).scan(any());
|
||||
verify(redisTemplate, times(1)).convertAndSend(com.cf.imes.framework.redis.constants.RedisKeyConstants.PERMISSION_REFRESH, "");
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithMockLoginUser
|
||||
void testUpdateMenu_success_flushCache() {
|
||||
// 校验父级
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU,
|
||||
"parent", 0L);
|
||||
|
||||
// mock 数据(构造父子菜单)
|
||||
MenuDO sonMenuDO = buildMenuDO(MenuTypeEnum.MENU, "testSonName",
|
||||
menuDO.getParentId());
|
||||
// same permission
|
||||
sonMenuDO.setPermission("permission");
|
||||
|
||||
when(menuMapper.selectById(any())).thenReturn(sonMenuDO).thenReturn(menuDO);
|
||||
when(menuMapper.selectByParentIdAndNameAndSourceType(any(), any(), any())).thenReturn(sonMenuDO);
|
||||
|
||||
Long sonId = sonMenuDO.getId();
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
|
||||
o.setId(sonId);
|
||||
o.setName("testSonName"); // 修改名字
|
||||
o.setParentId(sonMenuDO.getParentId());
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
// same permission
|
||||
o.setPermission("permission");
|
||||
});
|
||||
|
||||
// 调用
|
||||
menuService.updateMenu(reqVO);
|
||||
|
||||
// 校验记录的属性是否正确
|
||||
MenuDO dbMenu = menuMapper.selectById(sonId);
|
||||
assertPojoEquals(reqVO, dbMenu);
|
||||
verify(menuMapper, times(1)).updateById(any(MenuDO.class));
|
||||
verify(redisTemplate, never()).scan(any());
|
||||
verify(redisTemplate, never()).convertAndSend(anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMenu_sonIdNotExist() {
|
||||
void testUpdateMenu_sonIdNotExist() {
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class);
|
||||
// 调用,并断言异常
|
||||
@@ -94,46 +259,44 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_success() {
|
||||
@WithMockLoginUser
|
||||
void testDeleteMenu_success() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menuDO);
|
||||
// 准备参数
|
||||
Long id = menuDO.getId();
|
||||
when(menuMapper.selectCountByParentId(id)).thenReturn(0L);
|
||||
when(menuMapper.selectById(id)).thenReturn(menuDO);
|
||||
|
||||
// 调用
|
||||
menuService.deleteMenu(id);
|
||||
// 断言
|
||||
MenuDO dbMenuDO = menuMapper.selectById(id);
|
||||
assertNull(dbMenuDO);
|
||||
verify(permissionService).processMenuDeleted(id);
|
||||
verify(menuMapper, times(1)).deleteById(id);
|
||||
verify(permissionService, times(1)).processMenuDeleted(id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_menuNotExist() {
|
||||
void testDeleteMenu_menuNotExist() {
|
||||
assertServiceException(() -> menuService.deleteMenu(randomLongId()),
|
||||
MENU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_existChildren() {
|
||||
// mock 数据(构造父子菜单)
|
||||
MenuDO sonMenu = createParentAndSonMenu();
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
void testDeleteMenu_existChildren() {
|
||||
Long menuId = 100L;
|
||||
when(menuMapper.selectCountByParentId(menuId)).thenReturn(1L);
|
||||
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
|
||||
assertServiceException(() -> menuService.deleteMenu(menuId), MENU_EXISTS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuList_all() {
|
||||
void testGetMenuList_all() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu101);
|
||||
// 准备参数
|
||||
|
||||
when(menuMapper.selectList()).thenReturn(List.of(menu100, menu101));
|
||||
|
||||
// 调用
|
||||
List<MenuDO> list = menuService.getMenuList();
|
||||
@@ -144,16 +307,13 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuList() {
|
||||
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());
|
||||
when(menuMapper.selectList(reqVO)).thenReturn(List.of(menuDO));
|
||||
|
||||
// 调用
|
||||
List<MenuDO> result = menuService.getMenuList(reqVO);
|
||||
@@ -163,22 +323,21 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuListByTenant() {
|
||||
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).handleOrganMenu(argThat(handler -> {
|
||||
Set<Long> menuIds = asSet(100L);
|
||||
doNothing().when(organService).handleOrganMenu(argThat(handler -> {
|
||||
handler.handle(menuIds);
|
||||
return true;
|
||||
}));
|
||||
// 准备参数
|
||||
MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
when(menuMapper.selectList(reqVO)).thenReturn(new ArrayList<>(Arrays.asList(menu100, menu101, menu102)));
|
||||
|
||||
// 调用
|
||||
List<MenuDO> result = menuService.getMenuListByOrgan(reqVO);
|
||||
@@ -188,15 +347,32 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuIdListByPermissionFromCache() {
|
||||
void testGetMenuList1_empty() {
|
||||
List<MenuDO> menuList1 = menuService.getMenuList1(Collections.emptyList());
|
||||
|
||||
assertEquals(0, menuList1.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetMenuList1_success() {
|
||||
MenuDO menuDO = randomPojo(MenuDO.class);
|
||||
Set<Long> ids = Collections.singleton(menuDO.getId());
|
||||
when(menuMapper.selectByIds(ids)).thenReturn(List.of(menuDO));
|
||||
|
||||
List<MenuDO> menuList1 = menuService.getMenuList1(ids);
|
||||
|
||||
assertEquals(menuDO, menuList1.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetMenuIdListByPermissionFromCache() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu101);
|
||||
// 准备参数
|
||||
String permission = menu100.getPermission();
|
||||
|
||||
when(menuMapper.selectListByPermission(menu100.getPermission())).thenReturn(List.of(menu100));
|
||||
|
||||
// 调用
|
||||
List<Long> ids = menuService.getMenuIdListByPermissionFromCache(permission);
|
||||
// 断言
|
||||
@@ -205,14 +381,13 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuList_ids() {
|
||||
void testGetMenuList_ids() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu101);
|
||||
|
||||
// 准备参数
|
||||
Collection<Long> ids = Collections.singleton(menu100.getId());
|
||||
when(menuMapper.selectByIds(ids)).thenReturn(List.of(menu100));
|
||||
|
||||
// 调用
|
||||
List<MenuDO> list = menuService.getMenuList(ids);
|
||||
@@ -222,12 +397,13 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenu() {
|
||||
void testGetMenu() {
|
||||
// mock 数据
|
||||
MenuDO menu = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu);
|
||||
|
||||
// 准备参数
|
||||
Long id = menu.getId();
|
||||
when(menuMapper.selectById(id)).thenReturn(menu);
|
||||
|
||||
// 调用
|
||||
MenuDO dbMenu = menuService.getMenu(id);
|
||||
@@ -236,38 +412,41 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_success() {
|
||||
void testValidateParentMenu_success() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
|
||||
// 准备参数
|
||||
Long parentId = menuDO.getId();
|
||||
when(menuMapper.selectById(parentId)).thenReturn(menuDO);
|
||||
|
||||
// 调用,无需断言
|
||||
menuService.validateParentMenu(parentId, null);
|
||||
menuService.validateParentMenu(null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_canNotSetSelfToBeParent() {
|
||||
void testValidateParentMenu_canNotSetSelfToBeParent() {
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateParentMenu(1L, 1L),
|
||||
MENU_PARENT_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_parentNotExist() {
|
||||
void testValidateParentMenu_parentNotExist() {
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateParentMenu(randomLongId(), null),
|
||||
MENU_PARENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_parentTypeError() {
|
||||
void testValidateParentMenu_parentTypeError() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.BUTTON, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
|
||||
// 准备参数
|
||||
Long parentId = menuDO.getId();
|
||||
when(menuMapper.selectById(parentId)).thenReturn(menuDO);
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateParentMenu(parentId, null),
|
||||
@@ -275,9 +454,9 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMenu_success() {
|
||||
void testValidateMenu_success() {
|
||||
// mock 父子菜单
|
||||
MenuDO sonMenu = createParentAndSonMenu();
|
||||
MenuDO sonMenu = randomPojo(MenuDO.class);
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
Long otherSonMenuId = randomLongId();
|
||||
@@ -288,44 +467,221 @@ public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMenu_sonMenuNameDuplicate() {
|
||||
void testValidateMenu_sonMenuNameDuplicate() {
|
||||
// mock 父子菜单
|
||||
MenuDO sonMenu = createParentAndSonMenu();
|
||||
MenuDO sonMenu = randomPojo(MenuDO.class);
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
Long otherSonMenuId = randomLongId();
|
||||
String otherSonMenuName = sonMenu.getName(); //相同名称
|
||||
|
||||
when(menuMapper.selectByParentIdAndNameAndSourceType(parentId, otherSonMenuName, MenuSourceTypeEnum.PRODUCTION.getType())).thenReturn(sonMenu);
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, otherSonMenuId, MenuSourceTypeEnum.PRODUCTION.getType()),
|
||||
MENU_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
// ====================== 初始化方法 ======================
|
||||
@Test
|
||||
void testValidateMenu_sonMenuNameDuplicate_whenNull() {
|
||||
// mock 父子菜单
|
||||
MenuDO sonMenu = randomPojo(MenuDO.class);
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
String otherSonMenuName = sonMenu.getName(); //相同名称
|
||||
|
||||
/**
|
||||
* 插入父子菜单,返回子菜单
|
||||
*
|
||||
* @return 子菜单
|
||||
*/
|
||||
private MenuDO createParentAndSonMenu() {
|
||||
// 构造父子菜单
|
||||
MenuDO parentMenuDO = buildMenuDO(MenuTypeEnum.MENU, "parent", MenuDO.ID_ROOT);
|
||||
menuMapper.insert(parentMenuDO);
|
||||
// 构建子菜单
|
||||
MenuDO sonMenuDO = buildMenuDO(MenuTypeEnum.MENU, "testSonName",
|
||||
parentMenuDO.getParentId());
|
||||
menuMapper.insert(sonMenuDO);
|
||||
return sonMenuDO;
|
||||
when(menuMapper.selectByParentIdAndNameAndSourceType(parentId, otherSonMenuName, MenuSourceTypeEnum.PRODUCTION.getType())).thenReturn(sonMenu);
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateMenu(parentId, otherSonMenuName, null, MenuSourceTypeEnum.PRODUCTION.getType()),
|
||||
MENU_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testGetManageEndPointMenuList() {
|
||||
List<MenuDO> mockList = List.of(new MenuDO());
|
||||
|
||||
when(menuMapper.selectListIn(
|
||||
anyCollection(),
|
||||
eq(true),
|
||||
anyString()
|
||||
)).thenReturn(mockList);
|
||||
|
||||
List<MenuDO> result = menuService.getManageEndPointMenuList(List.of(1L, 2L));
|
||||
|
||||
assertSame(mockList, result);
|
||||
|
||||
verify(menuMapper).selectListIn(
|
||||
anyCollection(),
|
||||
eq(true),
|
||||
anyString()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetCustomEndPointMenuList() {
|
||||
List<MenuDO> mockList = List.of(new MenuDO());
|
||||
|
||||
when(menuMapper.selectListIn(
|
||||
anyCollection(),
|
||||
eq(false),
|
||||
anyString()
|
||||
)).thenReturn(mockList);
|
||||
|
||||
List<MenuDO> result = menuService.getCustomEndPointMenuList(List.of(1L, 2L));
|
||||
|
||||
assertSame(mockList, result);
|
||||
|
||||
verify(menuMapper).selectListIn(
|
||||
anyCollection(),
|
||||
eq(false),
|
||||
anyString()
|
||||
);
|
||||
}
|
||||
|
||||
// ====================== 初始化方法 ======================
|
||||
|
||||
private MenuDO buildMenuDO(MenuTypeEnum type, String name, Long parentId) {
|
||||
return buildMenuDO(type, name, parentId, randomCommonStatus());
|
||||
}
|
||||
|
||||
private MenuDO buildMenuDO(MenuTypeEnum type, String name, Long parentId, Integer status) {
|
||||
return randomPojo(MenuDO.class, o -> o.setId(null).setName(name).setParentId(parentId)
|
||||
return randomPojo(MenuDO.class, o -> o.setName(name).setParentId(parentId)
|
||||
.setType(type.getType()).setStatus(status));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTrans_errorCode() {
|
||||
// mock properties
|
||||
when(transProperties.getAppId()).thenReturn("appId");
|
||||
when(transProperties.getSecurityKey()).thenReturn("key");
|
||||
when(transProperties.getApiHost()).thenReturn("host");
|
||||
|
||||
MenuTransReqVO req = new MenuTransReqVO();
|
||||
req.setTargetLanguage("en");
|
||||
|
||||
when(menuMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(List.of(randomPojo(MenuDO.class)));
|
||||
|
||||
String errorJson = """
|
||||
{
|
||||
"error_code": "54001"
|
||||
}
|
||||
""";
|
||||
|
||||
try (MockedConstruction<TransApi> mocked =
|
||||
Mockito.mockConstruction(TransApi.class,
|
||||
(mock, context) -> when(mock.getTransResult(any(), any(), any()))
|
||||
.thenReturn(errorJson))) {
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> menuService.trans(req));
|
||||
}
|
||||
|
||||
verify(menuI18nMapper, never()).insertBatch(any());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testTrans_success_en() {
|
||||
// mock properties
|
||||
when(transProperties.getAppId()).thenReturn("appId");
|
||||
when(transProperties.getSecurityKey()).thenReturn("key");
|
||||
when(transProperties.getApiHost()).thenReturn("host");
|
||||
|
||||
MenuTransReqVO req = new MenuTransReqVO();
|
||||
req.setTargetLanguage("en");
|
||||
|
||||
when(menuMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(List.of(randomPojo(MenuDO.class, o -> {
|
||||
o.setName("系统管理");
|
||||
})));
|
||||
|
||||
String okJson = """
|
||||
{
|
||||
"trans_result": [
|
||||
{ "src": "系统管理", "dst": "system management" }
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
try (MockedConstruction<TransApi> mocked =
|
||||
Mockito.mockConstruction(TransApi.class,
|
||||
(mock, context) -> when(mock.getTransResult(any(), any(), any()))
|
||||
.thenReturn(okJson))) {
|
||||
|
||||
menuService.trans(req);
|
||||
}
|
||||
|
||||
ArgumentCaptor<List<MenuI18nDO>> captor =
|
||||
ArgumentCaptor.forClass(List.class);
|
||||
|
||||
verify(menuI18nMapper).insertBatch(captor.capture());
|
||||
|
||||
MenuI18nDO i18n = captor.getValue().get(0);
|
||||
assertEquals("System Management", i18n.getMenuName());
|
||||
assertEquals("en", i18n.getLocale());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTrans_srcNotMatch() {
|
||||
MenuTransReqVO req = new MenuTransReqVO();
|
||||
req.setTargetLanguage("en");
|
||||
|
||||
when(menuMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(List.of(randomPojo(MenuDO.class, o -> {
|
||||
o.setName("系统管理");
|
||||
})));
|
||||
|
||||
String json = """
|
||||
{
|
||||
"trans_result": [
|
||||
{ "src": "用户管理", "dst": "user management" }
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
try (MockedConstruction<TransApi> mocked =
|
||||
Mockito.mockConstruction(TransApi.class,
|
||||
(mock, context) -> when(mock.getTransResult(any(), any(), any()))
|
||||
.thenReturn(json))) {
|
||||
|
||||
menuService.trans(req);
|
||||
}
|
||||
|
||||
verify(menuI18nMapper, never()).insertBatch(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testTrans_partialSuccess() {
|
||||
MenuTransReqVO req = new MenuTransReqVO();
|
||||
req.setTargetLanguage(LanguageEnum.ZH.getLanguage());
|
||||
|
||||
when(menuMapper.selectList(any(LambdaQueryWrapper.class))).thenReturn(
|
||||
List.of(
|
||||
randomPojo(MenuDO.class, o -> o.setName("系统管理")),
|
||||
randomPojo(MenuDO.class, o -> o.setName("用户管理"))
|
||||
)
|
||||
);
|
||||
|
||||
String json = """
|
||||
{
|
||||
"trans_result": [
|
||||
{ "src": "系统管理", "dst": "system management" },
|
||||
{ "src": "角色管理", "dst": "role management" }
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
try (MockedConstruction<TransApi> mocked =
|
||||
Mockito.mockConstruction(TransApi.class,
|
||||
(mock, context) -> when(mock.getTransResult(any(), any(), any()))
|
||||
.thenReturn(json))) {
|
||||
menuService.trans(req);
|
||||
}
|
||||
|
||||
ArgumentCaptor<List<MenuI18nDO>> captor =
|
||||
ArgumentCaptor.forClass(List.class);
|
||||
|
||||
verify(menuI18nMapper).insertBatch(captor.capture());
|
||||
assertEquals(1, captor.getValue().size());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user