多模块重构 4:system 模块的创建,以及将相关的代码先进行迁移
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
package cn.iocoder.yudao.module.system.service.auth;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.auth.vo.auth.SysAuthLoginReqVO;
|
||||
import cn.iocoder.yudao.module.system.enums.logger.SysLoginLogTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.logger.SysLoginResultEnum;
|
||||
import cn.iocoder.yudao.module.system.service.common.SysCaptchaService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.SysPostService;
|
||||
import cn.iocoder.yudao.module.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.module.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreService;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.DisabledException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static java.util.Collections.singleton;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import(SysAuthServiceImpl.class)
|
||||
public class SysAuthServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysAuthServiceImpl authService;
|
||||
|
||||
@MockBean
|
||||
private SysUserService userService;
|
||||
@MockBean
|
||||
private SysUserCoreService userCoreService;
|
||||
@MockBean
|
||||
private SysPermissionService permissionService;
|
||||
@MockBean
|
||||
private AuthenticationManager authenticationManager;
|
||||
@MockBean
|
||||
private Authentication authentication;
|
||||
@MockBean
|
||||
private SysCaptchaService captchaService;
|
||||
@MockBean
|
||||
private SysLoginLogCoreService loginLogCoreService;
|
||||
@MockBean
|
||||
private SysUserSessionCoreService userSessionCoreService;
|
||||
@MockBean
|
||||
private SysSocialCoreService socialService;
|
||||
@MockBean
|
||||
private SysPostService postService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(captchaService.isCaptchaEnable()).thenReturn(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadUserByUsername_success() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
// mock 方法
|
||||
SysUserDO user = randomPojo(SysUserDO.class, o -> o.setUsername(username));
|
||||
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
||||
|
||||
// 调用
|
||||
LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
|
||||
// 校验
|
||||
AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadUserByUsername_userNotFound() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
// mock 方法
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
|
||||
() -> authService.loadUserByUsername(username),
|
||||
username); // 异常提示为 username
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMockLogin_success() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
// mock 方法 01
|
||||
SysUserDO user = randomPojo(SysUserDO.class, o -> o.setId(userId));
|
||||
when(userCoreService.getUser(eq(userId))).thenReturn(user);
|
||||
// mock 方法 02
|
||||
Set<Long> roleIds = randomSet(Long.class);
|
||||
when(permissionService.getUserRoleIds(eq(userId), eq(singleton(CommonStatusEnum.ENABLE.getStatus()))))
|
||||
.thenReturn(roleIds);
|
||||
|
||||
// 调用
|
||||
LoginUser loginUser = authService.mockLogin(userId);
|
||||
// 断言
|
||||
AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
|
||||
assertEquals(roleIds, loginUser.getRoleIds());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMockLogin_userNotFound() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
// mock 方法
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
|
||||
() -> authService.mockLogin(userId),
|
||||
String.valueOf(userId)); // 异常提示为 userId
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_captchaNotFound() {
|
||||
// 准备参数
|
||||
SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
|
||||
String userIp = randomString();
|
||||
String userAgent = randomString();
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_CAPTCHA_NOT_FOUND);
|
||||
// 校验调用参数
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.CAPTCHA_NOT_FOUND.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_captchaCodeError() {
|
||||
// 准备参数
|
||||
String userIp = randomString();
|
||||
String userAgent = randomString();
|
||||
String code = randomString();
|
||||
SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
|
||||
// mock 验证码不正确
|
||||
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(code);
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_CAPTCHA_CODE_ERROR);
|
||||
// 校验调用参数
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_badCredentials() {
|
||||
// 准备参数
|
||||
String userIp = randomString();
|
||||
String userAgent = randomString();
|
||||
SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
|
||||
// mock 验证码正确
|
||||
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
||||
// mock 抛出异常
|
||||
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
||||
.thenThrow(new BadCredentialsException("测试账号或密码不正确"));
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_BAD_CREDENTIALS);
|
||||
// 校验调用参数
|
||||
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.BAD_CREDENTIALS.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_userDisabled() {
|
||||
// 准备参数
|
||||
String userIp = randomString();
|
||||
String userAgent = randomString();
|
||||
SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
|
||||
// mock 验证码正确
|
||||
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
||||
// mock 抛出异常
|
||||
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
||||
.thenThrow(new DisabledException("测试用户被禁用"));
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_USER_DISABLED);
|
||||
// 校验调用参数
|
||||
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.USER_DISABLED.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_unknownError() {
|
||||
// 准备参数
|
||||
String userIp = randomString();
|
||||
String userAgent = randomString();
|
||||
SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
|
||||
// mock 验证码正确
|
||||
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
||||
// mock 抛出异常
|
||||
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
||||
.thenThrow(new AuthenticationException("测试未知异常") {});
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_FAIL_UNKNOWN);
|
||||
// 校验调用参数
|
||||
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.UNKNOWN_ERROR.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_success() {
|
||||
// 准备参数
|
||||
String userIp = randomString();
|
||||
String userAgent = randomString();
|
||||
Long userId = randomLongId();
|
||||
Set<Long> userRoleIds = randomSet(Long.class);
|
||||
String sessionId = randomString();
|
||||
SysAuthLoginReqVO reqVO = randomPojo(SysAuthLoginReqVO.class);
|
||||
LoginUser loginUser = randomPojo(LoginUser.class, o -> {
|
||||
o.setId(userId);
|
||||
o.setRoleIds(userRoleIds);
|
||||
});
|
||||
// mock 验证码正确
|
||||
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
||||
// mock authentication
|
||||
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
||||
.thenReturn(authentication);
|
||||
when(authentication.getPrincipal()).thenReturn(loginUser);
|
||||
// mock 获得 User 拥有的角色编号数组
|
||||
when(permissionService.getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()))).thenReturn(userRoleIds);
|
||||
// mock 缓存登录用户到 Redis
|
||||
when(userSessionCoreService.createUserSession(loginUser, userIp, userAgent)).thenReturn(sessionId);
|
||||
// 调用, 并断言异常
|
||||
String login = authService.login(reqVO, userIp, userAgent);
|
||||
assertEquals(sessionId, login);
|
||||
// 校验调用参数
|
||||
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.SUCCESS.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogout_success() {
|
||||
// 准备参数
|
||||
String token = randomString();
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock
|
||||
when(userSessionCoreService.getLoginUser(token)).thenReturn(loginUser);
|
||||
// 调用
|
||||
authService.logout(token);
|
||||
// 校验调用参数
|
||||
verify(userSessionCoreService, times(1)).deleteUserSession(token);
|
||||
verify(loginLogCoreService, times(1)).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(SysLoginLogTypeEnum.LOGOUT_SELF.getType())
|
||||
&& o.getResult().equals(SysLoginResultEnum.SUCCESS.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package cn.iocoder.yudao.module.system.service.auth;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.iocoder.yudao.module.system.controller.auth.vo.session.SysUserSessionPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.auth.SysUserSessionMapper;
|
||||
import cn.iocoder.yudao.module.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.auth.SysUserSessionDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.redis.auth.SysLoginUserCoreRedisDAO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.common.SysSexEnum;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbAndRedisUnitTest;
|
||||
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.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link SysUserSessionServiceImpl} 的单元测试
|
||||
*
|
||||
* @author Lyon
|
||||
*/
|
||||
@Import({SysUserSessionServiceImpl.class})
|
||||
public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysUserSessionServiceImpl userSessionService;
|
||||
|
||||
@Resource
|
||||
private SysUserSessionMapper userSessionMapper;
|
||||
|
||||
@MockBean
|
||||
private SysUserService userService;
|
||||
@MockBean
|
||||
private SysLoginLogCoreService loginLogCoreService;
|
||||
@MockBean
|
||||
private SysLoginUserCoreRedisDAO loginUserCoreRedisDAO;
|
||||
|
||||
@Test
|
||||
public void testGetUserSessionPage_success() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomPojo(SysUserDO.class, o -> {
|
||||
o.setSex(randomEle(SysSexEnum.values()).getSex());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(userService.getUsersByUsername(eq(dbUser.getUsername()))).thenReturn(singletonList(dbUser));
|
||||
// 插入可被查询到的数据
|
||||
String userIp = randomString();
|
||||
SysUserSessionDO dbSession = randomPojo(SysUserSessionDO.class, o -> {
|
||||
o.setUserId(dbUser.getId());
|
||||
o.setUserType(randomEle(UserTypeEnum.values()).getValue());
|
||||
o.setUserIp(userIp);
|
||||
});
|
||||
userSessionMapper.insert(dbSession);
|
||||
// 测试 username 不匹配
|
||||
userSessionMapper.insert(ObjectUtils.cloneIgnoreId(dbSession, o -> {
|
||||
o.setId(randomString());
|
||||
o.setUserId(123456L);
|
||||
}));
|
||||
// 测试 userIp 不匹配
|
||||
userSessionMapper.insert(ObjectUtils.cloneIgnoreId(dbSession, o -> {
|
||||
o.setId(randomString());
|
||||
o.setUserIp("testUserIp");
|
||||
}));
|
||||
// 准备参数
|
||||
SysUserSessionPageReqVO reqVO = new SysUserSessionPageReqVO();
|
||||
reqVO.setUsername(dbUser.getUsername());
|
||||
reqVO.setUserIp(userIp);
|
||||
|
||||
// 调用
|
||||
PageResult<SysUserSessionDO> pageResult = userSessionService.getUserSessionPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSession, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
// TODO 芋艿:单测写的有问题
|
||||
@Test
|
||||
public void testClearSessionTimeout_success() {
|
||||
// 准备超时数据 120 条, 在线用户 1 条
|
||||
int expectedTimeoutCount = 120, expectedTotal = 1;
|
||||
|
||||
// 准备数据
|
||||
List<SysUserSessionDO> prepareData = Stream
|
||||
.iterate(0, i -> i)
|
||||
.limit(expectedTimeoutCount)
|
||||
.map(i -> randomPojo(SysUserSessionDO.class, o -> {
|
||||
o.setUserType(randomEle(UserTypeEnum.values()).getValue());
|
||||
o.setSessionTimeout(DateUtil.offsetSecond(new Date(), -1));
|
||||
}))
|
||||
.collect(Collectors.toList());
|
||||
SysUserSessionDO sessionDO = randomPojo(SysUserSessionDO.class, o -> {
|
||||
o.setUserType(randomEle(UserTypeEnum.values()).getValue());
|
||||
o.setSessionTimeout(DateUtil.offsetMinute(new Date(), 30));
|
||||
});
|
||||
prepareData.add(sessionDO);
|
||||
prepareData.forEach(userSessionMapper::insert);
|
||||
|
||||
// 清空超时数据
|
||||
long actualTimeoutCount = userSessionService.clearSessionTimeout();
|
||||
// 校验
|
||||
assertEquals(expectedTimeoutCount, actualTimeoutCount);
|
||||
List<SysUserSessionDO> userSessionDOS = userSessionMapper.selectList();
|
||||
assertEquals(expectedTotal, userSessionDOS.size());
|
||||
assertPojoEquals(sessionDO, userSessionDOS.get(0), "updateTime");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package cn.iocoder.yudao.module.system.service.common;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.common.vo.SysCaptchaImageRespVO;
|
||||
import cn.iocoder.yudao.module.system.dal.redis.common.SysCaptchaRedisDAO;
|
||||
import cn.iocoder.yudao.module.system.framework.captcha.config.CaptchaProperties;
|
||||
import cn.iocoder.yudao.module.system.test.BaseRedisUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Import({SysCaptchaServiceImpl.class, CaptchaProperties.class, SysCaptchaRedisDAO.class})
|
||||
public class SysCaptchaServiceTest extends BaseRedisUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysCaptchaServiceImpl captchaService;
|
||||
|
||||
@Resource
|
||||
private SysCaptchaRedisDAO captchaRedisDAO;
|
||||
@Resource
|
||||
private CaptchaProperties captchaProperties;
|
||||
|
||||
@Test
|
||||
public void testGetCaptchaImage() {
|
||||
// 调用
|
||||
SysCaptchaImageRespVO respVO = captchaService.getCaptchaImage();
|
||||
// 断言
|
||||
assertNotNull(respVO.getUuid());
|
||||
assertNotNull(respVO.getImg());
|
||||
String captchaCode = captchaRedisDAO.get(respVO.getUuid());
|
||||
assertNotNull(captchaCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCaptchaCode() {
|
||||
// 准备参数
|
||||
String uuid = randomString();
|
||||
String code = randomString();
|
||||
// mock 数据
|
||||
captchaRedisDAO.set(uuid, code, captchaProperties.getTimeout());
|
||||
|
||||
// 调用
|
||||
String resultCode = captchaService.getCaptchaCode(uuid);
|
||||
// 断言
|
||||
assertEquals(code, resultCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteCaptchaCode() {
|
||||
// 准备参数
|
||||
String uuid = randomString();
|
||||
String code = randomString();
|
||||
// mock 数据
|
||||
captchaRedisDAO.set(uuid, code, captchaProperties.getTimeout());
|
||||
|
||||
// 调用
|
||||
captchaService.deleteCaptchaCode(uuid);
|
||||
// 断言
|
||||
assertNull(captchaRedisDAO.get(uuid));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
package cn.iocoder.yudao.module.system.service.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.dept.SysDeptCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.dept.SysDeptListReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.dept.SysDeptUpdateReqVO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.SysDeptMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.dept.SysDeptProducer;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.bean.BeanUtil.getFieldValue;
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
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 org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* {@link SysDeptServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author niudehua
|
||||
*/
|
||||
@Import(SysDeptServiceImpl.class)
|
||||
class SysDeptServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysDeptServiceImpl deptService;
|
||||
@Resource
|
||||
private SysDeptMapper deptMapper;
|
||||
@MockBean
|
||||
private SysDeptProducer deptProducer;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void testInitLocalCache() {
|
||||
// mock 数据
|
||||
SysDeptDO deptDO1 = randomDeptDO();
|
||||
deptMapper.insert(deptDO1);
|
||||
SysDeptDO deptDO2 = randomDeptDO();
|
||||
deptMapper.insert(deptDO2);
|
||||
|
||||
// 调用
|
||||
deptService.initLocalCache();
|
||||
// 断言 deptCache 缓存
|
||||
Map<Long, SysDeptDO> deptCache = (Map<Long, SysDeptDO>) getFieldValue(deptService, "deptCache");
|
||||
assertEquals(2, deptCache.size());
|
||||
assertPojoEquals(deptDO1, deptCache.get(deptDO1.getId()));
|
||||
assertPojoEquals(deptDO2, deptCache.get(deptDO2.getId()));
|
||||
// 断言 parentDeptCache 缓存
|
||||
Multimap<Long, SysDeptDO> parentDeptCache = (Multimap<Long, SysDeptDO>) getFieldValue(deptService, "parentDeptCache");
|
||||
assertEquals(2, parentDeptCache.size());
|
||||
assertPojoEquals(deptDO1, parentDeptCache.get(deptDO1.getParentId()));
|
||||
assertPojoEquals(deptDO2, parentDeptCache.get(deptDO2.getParentId()));
|
||||
// 断言 maxUpdateTime 缓存
|
||||
Date maxUpdateTime = (Date) getFieldValue(deptService, "maxUpdateTime");
|
||||
assertEquals(ObjectUtils.max(deptDO1.getUpdateTime(), deptDO2.getUpdateTime()), maxUpdateTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testListDepts() {
|
||||
// mock 数据
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> { // 等会查询到
|
||||
o.setName("开发部");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
deptMapper.insert(dept);
|
||||
// 测试 name 不匹配
|
||||
deptMapper.insert(ObjectUtils.cloneIgnoreId(dept, o -> o.setName("发")));
|
||||
// 测试 status 不匹配
|
||||
deptMapper.insert(ObjectUtils.cloneIgnoreId(dept, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
SysDeptListReqVO reqVO = new SysDeptListReqVO();
|
||||
reqVO.setName("开");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
// 调用
|
||||
List<SysDeptDO> sysDeptDOS = deptService.getSimpleDepts(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, sysDeptDOS.size());
|
||||
assertPojoEquals(dept, sysDeptDOS.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateDept_success() {
|
||||
// 准备参数
|
||||
SysDeptCreateReqVO reqVO = randomPojo(SysDeptCreateReqVO.class,
|
||||
o -> {
|
||||
o.setParentId(DeptIdEnum.ROOT.getId());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// 调用
|
||||
Long deptId = deptService.createDept(reqVO);
|
||||
// 断言
|
||||
assertNotNull(deptId);
|
||||
// 校验记录的属性是否正确
|
||||
SysDeptDO deptDO = deptMapper.selectById(deptId);
|
||||
assertPojoEquals(reqVO, deptDO);
|
||||
// 校验调用
|
||||
verify(deptProducer, times(1)).sendDeptRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdateDept_success() {
|
||||
// mock 数据
|
||||
SysDeptDO dbDeptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class, o -> {
|
||||
// 设置更新的 ID
|
||||
o.setParentId(DeptIdEnum.ROOT.getId());
|
||||
o.setId(dbDeptDO.getId());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// 调用
|
||||
deptService.updateDept(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysDeptDO deptDO = deptMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, deptDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeleteDept_success() {
|
||||
// mock 数据
|
||||
SysDeptDO dbDeptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDeptDO.getId();
|
||||
// 调用
|
||||
deptService.deleteDept(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(deptMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_nameDuplicateForUpdate() {
|
||||
// mock 数据
|
||||
SysDeptDO deptDO = randomDeptDO();
|
||||
// 设置根节点部门
|
||||
deptDO.setParentId(DeptIdEnum.ROOT.getId());
|
||||
deptMapper.insert(deptDO);
|
||||
// mock 数据 稍后模拟重复它的 name
|
||||
SysDeptDO nameDeptDO = randomDeptDO();
|
||||
// 设置根节点部门
|
||||
nameDeptDO.setParentId(DeptIdEnum.ROOT.getId());
|
||||
deptMapper.insert(nameDeptDO);
|
||||
// 准备参数
|
||||
SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class,
|
||||
o -> {
|
||||
// 设置根节点部门
|
||||
o.setParentId(DeptIdEnum.ROOT.getId());
|
||||
// 设置更新的 ID
|
||||
o.setId(deptDO.getId());
|
||||
// 模拟 name 重复
|
||||
o.setName(nameDeptDO.getName());
|
||||
});
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.updateDept(reqVO), DEPT_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_parentNotExitsForCreate() {
|
||||
SysDeptCreateReqVO reqVO = randomPojo(SysDeptCreateReqVO.class,
|
||||
o -> o.setStatus(randomCommonStatus()));
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> deptService.createDept(reqVO), DEPT_PARENT_NOT_EXITS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_notFoundForDelete() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.deleteDept(id), DEPT_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_exitsChildrenForDelete() {
|
||||
// mock 数据
|
||||
SysDeptDO parentDept = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
deptMapper.insert(parentDept);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysDeptDO childrenDeptDO = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setParentId(parentDept.getId());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// 插入子部门
|
||||
deptMapper.insert(childrenDeptDO);
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.deleteDept(parentDept.getId()), DEPT_EXITS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_parentErrorForUpdate() {
|
||||
// mock 数据
|
||||
SysDeptDO dbDeptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
deptMapper.insert(dbDeptDO);
|
||||
// 准备参数
|
||||
SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class,
|
||||
o -> {
|
||||
// 设置自己为父部门
|
||||
o.setParentId(dbDeptDO.getId());
|
||||
// 设置更新的 ID
|
||||
o.setId(dbDeptDO.getId());
|
||||
});
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.updateDept(reqVO), DEPT_PARENT_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_notEnableForCreate() {
|
||||
// mock 数据
|
||||
SysDeptDO deptDO = randomPojo(SysDeptDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
deptMapper.insert(deptDO);
|
||||
// 准备参数
|
||||
SysDeptCreateReqVO reqVO = randomPojo(SysDeptCreateReqVO.class,
|
||||
o -> {
|
||||
// 设置未启用的部门为副部门
|
||||
o.setParentId(deptDO.getId());
|
||||
});
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.createDept(reqVO), DEPT_NOT_ENABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckDept_parentIsChildForUpdate() {
|
||||
// mock 数据
|
||||
SysDeptDO parentDept = randomPojo(SysDeptDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
deptMapper.insert(parentDept);
|
||||
SysDeptDO childDept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setParentId(parentDept.getId());
|
||||
});
|
||||
deptMapper.insert(childDept);
|
||||
// 初始化本地缓存
|
||||
deptService.initLocalCache();
|
||||
// 准备参数
|
||||
SysDeptUpdateReqVO reqVO = randomPojo(SysDeptUpdateReqVO.class,
|
||||
o -> {
|
||||
// 设置自己的子部门为父部门
|
||||
o.setParentId(childDept.getId());
|
||||
// 设置更新的 ID
|
||||
o.setId(parentDept.getId());
|
||||
});
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.updateDept(reqVO), DEPT_PARENT_IS_CHILD);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static SysDeptDO randomDeptDO(Consumer<SysDeptDO>... consumers) {
|
||||
Consumer<SysDeptDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(SysDeptDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package cn.iocoder.yudao.module.system.service.dept;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dept.SysPostDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.post.SysPostCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.post.SysPostExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.post.SysPostPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dept.vo.post.SysPostUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.SysPostMapper;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
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.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link SysPostServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author niudehua
|
||||
*/
|
||||
@Import(SysPostServiceImpl.class)
|
||||
class SysPostServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysPostServiceImpl postService;
|
||||
@Resource
|
||||
private SysPostMapper postMapper;
|
||||
|
||||
@Test
|
||||
void testPagePosts() {
|
||||
// mock 数据
|
||||
SysPostDO postDO = randomPojo(SysPostDO.class, o -> {
|
||||
o.setName("码仔");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
postMapper.insert(postDO);
|
||||
// 测试 name 不匹配
|
||||
postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setName("程序员")));
|
||||
// 测试 status 不匹配
|
||||
postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
|
||||
// 准备参数
|
||||
SysPostPageReqVO reqVO = new SysPostPageReqVO();
|
||||
reqVO.setName("码");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<SysPostDO> pageResult = postService.getPostPage(reqVO);
|
||||
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(postDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testListPosts() {
|
||||
// mock 数据
|
||||
SysPostDO postDO = randomPojo(SysPostDO.class, o -> {
|
||||
o.setName("码仔");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
postMapper.insert(postDO);
|
||||
// 测试 name 不匹配
|
||||
postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setName("程序员")));
|
||||
// 测试 status 不匹配
|
||||
postMapper.insert(ObjectUtils.cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
SysPostExportReqVO reqVO = new SysPostExportReqVO();
|
||||
reqVO.setName("码");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
List<SysPostDO> list = postService.getPosts(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(postDO, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetPost() {
|
||||
// mock 数据
|
||||
SysPostDO dbPostDO = randomPostDO();
|
||||
postMapper.insert(dbPostDO);
|
||||
// 准备参数
|
||||
Long id = dbPostDO.getId();
|
||||
// 调用
|
||||
SysPostDO post = postService.getPost(id);
|
||||
// 断言
|
||||
assertNotNull(post);
|
||||
assertPojoEquals(dbPostDO, post);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreatePost_success() {
|
||||
// 准备参数
|
||||
SysPostCreateReqVO reqVO = randomPojo(SysPostCreateReqVO.class,
|
||||
o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()));
|
||||
// 调用
|
||||
Long postId = postService.createPost(reqVO);
|
||||
// 断言
|
||||
assertNotNull(postId);
|
||||
// 校验记录的属性是否正确
|
||||
SysPostDO post = postMapper.selectById(postId);
|
||||
assertPojoEquals(reqVO, post);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUpdatePost_success() {
|
||||
// mock 数据
|
||||
SysPostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysPostUpdateReqVO reqVO = randomPojo(SysPostUpdateReqVO.class,
|
||||
o -> {
|
||||
// 设置更新的 ID
|
||||
o.setId(postDO.getId());
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus());
|
||||
});
|
||||
// 调用
|
||||
postService.updatePost(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysPostDO post = postMapper.selectById(reqVO.getId());// 获取最新的
|
||||
assertPojoEquals(reqVO, post);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeletePost_success() {
|
||||
// mock 数据
|
||||
SysPostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);
|
||||
// 准备参数
|
||||
Long id = postDO.getId();
|
||||
// 调用
|
||||
postService.deletePost(id);
|
||||
assertNull(postMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckPost_notFoundForDelete() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> postService.deletePost(id), POST_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckPost_nameDuplicateForCreate() {
|
||||
// mock 数据
|
||||
SysPostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysPostCreateReqVO reqVO = randomPojo(SysPostCreateReqVO.class,
|
||||
// 模拟 name 重复
|
||||
o -> o.setName(postDO.getName()));
|
||||
assertServiceException(() -> postService.createPost(reqVO), POST_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCheckPost_codeDuplicateForUpdate() {
|
||||
// mock 数据
|
||||
SysPostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);
|
||||
// mock 数据 稍后模拟重复它的 code
|
||||
SysPostDO codePostDO = randomPostDO();
|
||||
postMapper.insert(codePostDO);
|
||||
// 准备参数
|
||||
SysPostUpdateReqVO reqVO = randomPojo(SysPostUpdateReqVO.class,
|
||||
o -> {
|
||||
// 设置更新的 ID
|
||||
o.setId(postDO.getId());
|
||||
// 模拟 code 重复
|
||||
o.setCode(codePostDO.getCode());
|
||||
});
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> postService.updatePost(reqVO), POST_CODE_DUPLICATE);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static SysPostDO randomPostDO(Consumer<SysPostDO>... consumers) {
|
||||
Consumer<SysPostDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(SysPostDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
package cn.iocoder.yudao.module.system.service.dict;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dict.SysDictDataDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.data.SysDictDataCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.data.SysDictDataExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.data.SysDictDataPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.data.SysDictDataUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.SysDictTypeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dict.SysDictDataMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.dict.SysDictDataProducer;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
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 org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link SysDictDataServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(SysDictDataServiceImpl.class)
|
||||
public class SysDictDataServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysDictDataServiceImpl dictDataService;
|
||||
|
||||
@Resource
|
||||
private SysDictDataMapper dictDataMapper;
|
||||
@MockBean
|
||||
private SysDictTypeService dictTypeService;
|
||||
@MockBean
|
||||
private SysDictDataProducer dictDataProducer;
|
||||
|
||||
@Test
|
||||
public void testGetDictDataPage() {
|
||||
// mock 数据
|
||||
SysDictDataDO dbDictData = randomPojo(SysDictDataDO.class, o -> { // 等会查询到
|
||||
o.setLabel("芋艿");
|
||||
o.setDictType("yunai");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
dictDataMapper.insert(dbDictData);
|
||||
// 测试 label 不匹配
|
||||
dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setLabel("艿")));
|
||||
// 测试 dictType 不匹配
|
||||
dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setDictType("nai")));
|
||||
// 测试 status 不匹配
|
||||
dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
SysDictDataPageReqVO reqVO = new SysDictDataPageReqVO();
|
||||
reqVO.setLabel("芋");
|
||||
reqVO.setDictType("yu");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<SysDictDataDO> pageResult = dictDataService.getDictDataPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbDictData, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictDataList() {
|
||||
// mock 数据
|
||||
SysDictDataDO dbDictData = randomPojo(SysDictDataDO.class, o -> { // 等会查询到
|
||||
o.setLabel("芋艿");
|
||||
o.setDictType("yunai");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
dictDataMapper.insert(dbDictData);
|
||||
// 测试 label 不匹配
|
||||
dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setLabel("艿")));
|
||||
// 测试 dictType 不匹配
|
||||
dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setDictType("nai")));
|
||||
// 测试 status 不匹配
|
||||
dictDataMapper.insert(ObjectUtils.cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
SysDictDataExportReqVO reqVO = new SysDictDataExportReqVO();
|
||||
reqVO.setLabel("芋");
|
||||
reqVO.setDictType("yu");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
List<SysDictDataDO> list = dictDataService.getDictDatas(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbDictData, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDictData_success() {
|
||||
// 准备参数
|
||||
SysDictDataCreateReqVO reqVO = randomPojo(SysDictDataCreateReqVO.class,
|
||||
o -> o.setStatus(randomCommonStatus()));
|
||||
// mock 方法
|
||||
when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
|
||||
|
||||
// 调用
|
||||
Long dictDataId = dictDataService.createDictData(reqVO);
|
||||
// 断言
|
||||
assertNotNull(dictDataId);
|
||||
// 校验记录的属性是否正确
|
||||
SysDictDataDO dictData = dictDataMapper.selectById(dictDataId);
|
||||
assertPojoEquals(reqVO, dictData);
|
||||
// 校验调用
|
||||
verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDictData_success() {
|
||||
// mock 数据
|
||||
SysDictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysDictDataUpdateReqVO reqVO = randomPojo(SysDictDataUpdateReqVO.class, o -> {
|
||||
o.setId(dbDictData.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// mock 方法,字典类型
|
||||
when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
|
||||
|
||||
// 调用
|
||||
dictDataService.updateDictData(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysDictDataDO dictData = dictDataMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, dictData);
|
||||
// 校验调用
|
||||
verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDictData_success() {
|
||||
// mock 数据
|
||||
SysDictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDictData.getId();
|
||||
|
||||
// 调用
|
||||
dictDataService.deleteDictData(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(dictDataMapper.selectById(id));
|
||||
// 校验调用
|
||||
verify(dictDataProducer, times(1)).sendDictDataRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataExists_success() {
|
||||
// mock 数据
|
||||
SysDictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用成功
|
||||
dictDataService.checkDictDataExists(dbDictData.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataExists_notExists() {
|
||||
assertServiceException(() -> dictDataService.checkDictDataExists(randomLongId()), DICT_DATA_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeValid_success() {
|
||||
// mock 方法,数据类型被禁用
|
||||
String type = randomString();
|
||||
when(dictTypeService.getDictType(eq(type))).thenReturn(randomDictTypeDO(type));
|
||||
|
||||
// 调用, 成功
|
||||
dictDataService.checkDictTypeValid(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeValid_notExists() {
|
||||
assertServiceException(() -> dictDataService.checkDictTypeValid(randomString()), DICT_TYPE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeValid_notEnable() {
|
||||
// mock 方法,数据类型被禁用
|
||||
String dictType = randomString();
|
||||
when(dictTypeService.getDictType(eq(dictType))).thenReturn(
|
||||
randomPojo(SysDictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> dictDataService.checkDictTypeValid(dictType), DICT_TYPE_NOT_ENABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataValueUnique_success() {
|
||||
// 调用,成功
|
||||
dictDataService.checkDictDataValueUnique(randomLongId(), randomString(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataValueUnique_valueDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String dictType = randomString();
|
||||
String value = randomString();
|
||||
// mock 数据
|
||||
dictDataMapper.insert(randomDictDataDO(o -> {
|
||||
o.setDictType(dictType);
|
||||
o.setValue(value);
|
||||
}));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictDataService.checkDictDataValueUnique(null, dictType, value),
|
||||
DICT_DATA_VALUE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataValueUnique_valueDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String dictType = randomString();
|
||||
String value = randomString();
|
||||
// mock 数据
|
||||
dictDataMapper.insert(randomDictDataDO(o -> {
|
||||
o.setDictType(dictType);
|
||||
o.setValue(value);
|
||||
}));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictDataService.checkDictDataValueUnique(id, dictType, value),
|
||||
DICT_DATA_VALUE_DUPLICATE);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysDictDataDO randomDictDataDO(Consumer<SysDictDataDO>... consumers) {
|
||||
Consumer<SysDictDataDO> consumer = (o) -> {
|
||||
o.setStatus(randomCommonStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(SysDictDataDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成一个有效的字典类型
|
||||
*
|
||||
* @param type 字典类型
|
||||
* @return SysDictTypeDO 对象
|
||||
*/
|
||||
private static SysDictTypeDO randomDictTypeDO(String type) {
|
||||
return randomPojo(SysDictTypeDO.class, o -> {
|
||||
o.setType(type);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 是开启
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
package cn.iocoder.yudao.module.system.service.dict;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.type.SysDictTypeCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.type.SysDictTypeExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.type.SysDictTypePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.dict.vo.type.SysDictTypeUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.SysDictTypeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dict.SysDictTypeMapper;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
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.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(SysDictTypeServiceImpl.class)
|
||||
public class SysDictTypeServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysDictTypeServiceImpl dictTypeService;
|
||||
|
||||
@Resource
|
||||
private SysDictTypeMapper dictTypeMapper;
|
||||
@MockBean
|
||||
private SysDictDataService dictDataService;
|
||||
|
||||
@Test
|
||||
public void testGetDictTypePage() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomPojo(SysDictTypeDO.class, o -> { // 等会查询到
|
||||
o.setName("yunai");
|
||||
o.setType("芋艿");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2021, 1, 15));
|
||||
});
|
||||
dictTypeMapper.insert(dbDictType);
|
||||
// 测试 name 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setName("tudou")));
|
||||
// 测试 type 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setType("土豆")));
|
||||
// 测试 status 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
|
||||
// 准备参数
|
||||
SysDictTypePageReqVO reqVO = new SysDictTypePageReqVO();
|
||||
reqVO.setName("nai");
|
||||
reqVO.setType("艿");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginCreateTime(buildTime(2021, 1, 10));
|
||||
reqVO.setEndCreateTime(buildTime(2021, 1, 20));
|
||||
|
||||
// 调用
|
||||
PageResult<SysDictTypeDO> pageResult = dictTypeService.getDictTypePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbDictType, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictTypeList() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomPojo(SysDictTypeDO.class, o -> { // 等会查询到
|
||||
o.setName("yunai");
|
||||
o.setType("芋艿");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2021, 1, 15));
|
||||
});
|
||||
dictTypeMapper.insert(dbDictType);
|
||||
// 测试 name 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setName("tudou")));
|
||||
// 测试 type 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setType("土豆")));
|
||||
// 测试 status 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
dictTypeMapper.insert(ObjectUtils.cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
|
||||
// 准备参数
|
||||
SysDictTypeExportReqVO reqVO = new SysDictTypeExportReqVO();
|
||||
reqVO.setName("nai");
|
||||
reqVO.setType("艿");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginCreateTime(buildTime(2021, 1, 10));
|
||||
reqVO.setEndCreateTime(buildTime(2021, 1, 20));
|
||||
|
||||
// 调用
|
||||
List<SysDictTypeDO> list = dictTypeService.getDictTypeList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbDictType, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictType() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);
|
||||
// 准备参数
|
||||
String type = dbDictType.getType();
|
||||
|
||||
// 调用
|
||||
SysDictTypeDO dictType = dictTypeService.getDictType(type);
|
||||
// 断言
|
||||
assertNotNull(dictType);
|
||||
assertPojoEquals(dbDictType, dictType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDictType_success() {
|
||||
// 准备参数
|
||||
SysDictTypeCreateReqVO reqVO = randomPojo(SysDictTypeCreateReqVO.class,
|
||||
o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()));
|
||||
|
||||
// 调用
|
||||
Long dictTypeId = dictTypeService.createDictType(reqVO);
|
||||
// 断言
|
||||
assertNotNull(dictTypeId);
|
||||
// 校验记录的属性是否正确
|
||||
SysDictTypeDO dictType = dictTypeMapper.selectById(dictTypeId);
|
||||
assertPojoEquals(reqVO, dictType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDictType_success() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysDictTypeUpdateReqVO reqVO = randomPojo(SysDictTypeUpdateReqVO.class, o -> {
|
||||
o.setId(dbDictType.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
dictTypeService.updateDictType(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysDictTypeDO dictType = dictTypeMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, dictType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDictType_success() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDictType.getId();
|
||||
|
||||
// 调用
|
||||
dictTypeService.deleteDictType(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(dictTypeMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDictType_hasChildren() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDictType.getId();
|
||||
// mock 方法
|
||||
when(dictDataService.countByDictType(eq(dbDictType.getType()))).thenReturn(1);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> dictTypeService.deleteDictType(id), DICT_TYPE_HAS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataExists_success() {
|
||||
// mock 数据
|
||||
SysDictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用成功
|
||||
dictTypeService.checkDictTypeExists(dbDictType.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataExists_notExists() {
|
||||
assertServiceException(() -> dictTypeService.checkDictTypeExists(randomLongId()), DICT_TYPE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeUnique_success() {
|
||||
// 调用,成功
|
||||
dictTypeService.checkDictTypeUnique(randomLongId(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeUnique_valueDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String type = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.checkDictTypeUnique(null, type),
|
||||
DICT_TYPE_TYPE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeUnique_valueDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String type = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.checkDictTypeUnique(id, type),
|
||||
DICT_TYPE_TYPE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypNameUnique_success() {
|
||||
// 调用,成功
|
||||
dictTypeService.checkDictTypeNameUnique(randomLongId(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeNameUnique_nameDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String name = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.checkDictTypeNameUnique(null, name),
|
||||
DICT_TYPE_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictTypeNameUnique_nameDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String name = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.checkDictTypeNameUnique(id, name),
|
||||
DICT_TYPE_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysDictTypeDO randomDictTypeDO(Consumer<SysDictTypeDO>... consumers) {
|
||||
Consumer<SysDictTypeDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(SysDictTypeDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
package cn.iocoder.yudao.module.system.service.errorcode;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.framework.errorcode.core.dto.ErrorCodeAutoGenerateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.errorcode.vo.SysErrorCodeCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.errorcode.vo.SysErrorCodeExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.errorcode.vo.SysErrorCodePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.errorcode.vo.SysErrorCodeUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.errorcode.SysErrorCodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.errorcode.SysErrorCodeMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.errorcode.SysErrorCodeTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.slf4j.Logger;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.ERROR_CODE_DUPLICATE;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.ERROR_CODE_NOT_EXISTS;
|
||||
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.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Import(SysErrorCodeServiceImpl.class)
|
||||
public class SysErrorCodeServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysErrorCodeServiceImpl errorCodeService;
|
||||
|
||||
@Resource
|
||||
private SysErrorCodeMapper errorCodeMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateErrorCode_success() {
|
||||
// 准备参数
|
||||
SysErrorCodeCreateReqVO reqVO = randomPojo(SysErrorCodeCreateReqVO.class);
|
||||
|
||||
// 调用
|
||||
Long errorCodeId = errorCodeService.createErrorCode(reqVO);
|
||||
// 断言
|
||||
assertNotNull(errorCodeId);
|
||||
// 校验记录的属性是否正确
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectById(errorCodeId);
|
||||
assertPojoEquals(reqVO, errorCode);
|
||||
assertEquals(SysErrorCodeTypeEnum.MANUAL_OPERATION.getType(), errorCode.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateErrorCode_success() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO();
|
||||
errorCodeMapper.insert(dbErrorCode);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysErrorCodeUpdateReqVO reqVO = randomPojo(SysErrorCodeUpdateReqVO.class, o -> {
|
||||
o.setId(dbErrorCode.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
errorCodeService.updateErrorCode(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, errorCode);
|
||||
assertEquals(SysErrorCodeTypeEnum.MANUAL_OPERATION.getType(), errorCode.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteErrorCode_success() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO();
|
||||
errorCodeMapper.insert(dbErrorCode);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbErrorCode.getId();
|
||||
|
||||
// 调用
|
||||
errorCodeService.deleteErrorCode(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(errorCodeMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetErrorCodePage() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = initGetErrorCodePage();
|
||||
// 准备参数
|
||||
SysErrorCodePageReqVO reqVO = new SysErrorCodePageReqVO();
|
||||
reqVO.setType(SysErrorCodeTypeEnum.AUTO_GENERATION.getType());
|
||||
reqVO.setApplicationName("yudao");
|
||||
reqVO.setCode(1);
|
||||
reqVO.setMessage("yu");
|
||||
reqVO.setBeginCreateTime(buildTime(2020, 11, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2020, 11, 30));
|
||||
|
||||
// 调用
|
||||
PageResult<SysErrorCodeDO> pageResult = errorCodeService.getErrorCodePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbErrorCode, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 getErrorCodePage 方法的测试数据
|
||||
*/
|
||||
private SysErrorCodeDO initGetErrorCodePage() {
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> { // 等会查询到
|
||||
o.setType(SysErrorCodeTypeEnum.AUTO_GENERATION.getType());
|
||||
o.setApplicationName("yudaoyuanma");
|
||||
o.setCode(1);
|
||||
o.setMessage("yudao");
|
||||
o.setCreateTime(buildTime(2020, 11, 11));
|
||||
});
|
||||
errorCodeMapper.insert(dbErrorCode);
|
||||
// 测试 type 不匹配
|
||||
errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setType(SysErrorCodeTypeEnum.MANUAL_OPERATION.getType())));
|
||||
// 测试 applicationName 不匹配
|
||||
errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setApplicationName("yunai")));
|
||||
// 测试 code 不匹配
|
||||
errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setCode(2)));
|
||||
// 测试 message 不匹配
|
||||
errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setMessage("nai")));
|
||||
// 测试 createTime 不匹配
|
||||
errorCodeMapper.insert(ObjectUtils.cloneIgnoreId(dbErrorCode, o -> o.setCreateTime(buildTime(2020, 12, 12))));
|
||||
return dbErrorCode;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetErrorCodeList() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = initGetErrorCodePage();
|
||||
// 准备参数
|
||||
SysErrorCodeExportReqVO reqVO = new SysErrorCodeExportReqVO();
|
||||
reqVO.setType(SysErrorCodeTypeEnum.AUTO_GENERATION.getType());
|
||||
reqVO.setApplicationName("yudao");
|
||||
reqVO.setCode(1);
|
||||
reqVO.setMessage("yu");
|
||||
reqVO.setBeginCreateTime(buildTime(2020, 11, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2020, 11, 30));
|
||||
|
||||
// 调用
|
||||
List<SysErrorCodeDO> list = errorCodeService.getErrorCodeList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbErrorCode, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCodeDuplicate_codeDuplicateForCreate() {
|
||||
// 准备参数
|
||||
Integer code = randomInteger();
|
||||
// mock 数据
|
||||
errorCodeMapper.insert(randomInfErrorCodeDO(o -> o.setCode(code)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> errorCodeService.validateCodeDuplicate(code, null),
|
||||
ERROR_CODE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCodeDuplicate_codeDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
Integer code = randomInteger();
|
||||
// mock 数据
|
||||
errorCodeMapper.insert(randomInfErrorCodeDO(o -> o.setCode(code)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> errorCodeService.validateCodeDuplicate(code, id),
|
||||
ERROR_CODE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateErrorCodeExists_notExists() {
|
||||
assertServiceException(() -> errorCodeService.validateErrorCodeExists(null),
|
||||
ERROR_CODE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况 1,错误码不存在的情况
|
||||
*/
|
||||
@Test
|
||||
public void testAutoGenerateErrorCodes_01() {
|
||||
// 准备参数
|
||||
ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
errorCodeService.autoGenerateErrorCodes(Lists.newArrayList(generateReqDTO));
|
||||
// 断言
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectOne(null);
|
||||
assertPojoEquals(generateReqDTO, errorCode);
|
||||
assertEquals(SysErrorCodeTypeEnum.AUTO_GENERATION.getType(), errorCode.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况 2.1,错误码存在,但是是 SysErrorCodeTypeEnum.MANUAL_OPERATION 类型
|
||||
*/
|
||||
@Test
|
||||
public void testAutoGenerateErrorCodes_021() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(SysErrorCodeTypeEnum.MANUAL_OPERATION.getType()));
|
||||
errorCodeMapper.insert(dbErrorCode);
|
||||
// 准备参数
|
||||
ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class,
|
||||
o -> o.setCode(dbErrorCode.getCode()));
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
errorCodeService.autoGenerateErrorCodes(Lists.newArrayList(generateReqDTO));
|
||||
// 断言,相等,说明不会更新
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectById(dbErrorCode.getId());
|
||||
assertPojoEquals(dbErrorCode, errorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况 2.2,错误码存在,但是是 applicationName 不匹配
|
||||
*/
|
||||
@Test
|
||||
public void testAutoGenerateErrorCodes_022() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(SysErrorCodeTypeEnum.AUTO_GENERATION.getType()));
|
||||
errorCodeMapper.insert(dbErrorCode);
|
||||
// 准备参数
|
||||
ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class,
|
||||
o -> o.setCode(dbErrorCode.getCode()).setApplicationName(randomString()));
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
errorCodeService.autoGenerateErrorCodes(Lists.newArrayList(generateReqDTO));
|
||||
// 断言,相等,说明不会更新
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectById(dbErrorCode.getId());
|
||||
assertPojoEquals(dbErrorCode, errorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况 2.3,错误码存在,但是是 message 相同
|
||||
*/
|
||||
@Test
|
||||
public void testAutoGenerateErrorCodes_023() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(SysErrorCodeTypeEnum.AUTO_GENERATION.getType()));
|
||||
errorCodeMapper.insert(dbErrorCode);
|
||||
// 准备参数
|
||||
ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class,
|
||||
o -> o.setCode(dbErrorCode.getCode()).setApplicationName(dbErrorCode.getApplicationName())
|
||||
.setMessage(dbErrorCode.getMessage()));
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
errorCodeService.autoGenerateErrorCodes(Lists.newArrayList(generateReqDTO));
|
||||
// 断言,相等,说明不会更新
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectById(dbErrorCode.getId());
|
||||
assertPojoEquals(dbErrorCode, errorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况 2.3,错误码存在,但是是 message 不同,则进行更新
|
||||
*/
|
||||
@Test
|
||||
public void testAutoGenerateErrorCodes_024() {
|
||||
// mock 数据
|
||||
SysErrorCodeDO dbErrorCode = randomInfErrorCodeDO(o -> o.setType(SysErrorCodeTypeEnum.AUTO_GENERATION.getType()));
|
||||
errorCodeMapper.insert(dbErrorCode);
|
||||
// 准备参数
|
||||
ErrorCodeAutoGenerateReqDTO generateReqDTO = randomPojo(ErrorCodeAutoGenerateReqDTO.class,
|
||||
o -> o.setCode(dbErrorCode.getCode()).setApplicationName(dbErrorCode.getApplicationName()));
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
errorCodeService.autoGenerateErrorCodes(Lists.newArrayList(generateReqDTO));
|
||||
// 断言,匹配
|
||||
SysErrorCodeDO errorCode = errorCodeMapper.selectById(dbErrorCode.getId());
|
||||
assertPojoEquals(generateReqDTO, errorCode);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysErrorCodeDO randomInfErrorCodeDO(Consumer<SysErrorCodeDO>... consumers) {
|
||||
Consumer<SysErrorCodeDO> consumer = (o) -> {
|
||||
o.setType(randomEle(SysErrorCodeTypeEnum.values()).getType()); // 保证 key 的范围
|
||||
};
|
||||
return randomPojo(SysErrorCodeDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package cn.iocoder.yudao.module.system.service.logger;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.logger.SysLoginLogDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.logger.vo.loginlog.SysLoginLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.logger.vo.loginlog.SysLoginLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.logger.SysLoginLogMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.logger.SysLoginLogTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.logger.SysLoginResultEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@Import(SysLoginLogServiceImpl.class)
|
||||
public class SysLoginLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysLoginLogServiceImpl sysLoginLogService;
|
||||
|
||||
@Resource
|
||||
private SysLoginLogMapper loginLogMapper;
|
||||
|
||||
@Test
|
||||
public void testGetLoginLogPage() {
|
||||
// 构造测试数据
|
||||
// 登录成功的
|
||||
SysLoginLogDO loginLogDO = RandomUtils.randomPojo(SysLoginLogDO.class, logDO -> {
|
||||
logDO.setLogType(RandomUtil.randomEle(SysLoginLogTypeEnum.values()).getType());
|
||||
logDO.setTraceId(TracerUtils.getTraceId());
|
||||
logDO.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue());
|
||||
|
||||
logDO.setUserIp("192.168.199.16");
|
||||
logDO.setUsername("wangkai");
|
||||
logDO.setCreateTime(buildTime(2021, 3, 6));
|
||||
logDO.setResult(SysLoginResultEnum.SUCCESS.getResult());
|
||||
});
|
||||
loginLogMapper.insert(loginLogDO);
|
||||
|
||||
// 下面几个都是不匹配的数据
|
||||
// 登录失败的
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setResult(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult())));
|
||||
// 不同ip段的
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18")));
|
||||
// 不同username
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUsername("yunai")));
|
||||
// 构造一个早期时间 2021-02-06 00:00:00
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6))));
|
||||
|
||||
|
||||
// 构造调用参数
|
||||
SysLoginLogPageReqVO reqVO = new SysLoginLogPageReqVO();
|
||||
reqVO.setUsername("wangkai");
|
||||
reqVO.setUserIp("192.168.199");
|
||||
reqVO.setStatus(true);
|
||||
reqVO.setBeginTime(buildTime(2021, 3, 5));
|
||||
reqVO.setEndTime(buildTime(2021, 3, 7));
|
||||
|
||||
// 调用service方法
|
||||
PageResult<SysLoginLogDO> pageResult = sysLoginLogService.getLoginLogPage(reqVO);
|
||||
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(loginLogDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLoginLogList() {
|
||||
// 构造测试数据
|
||||
|
||||
// 登录成功的
|
||||
SysLoginLogDO loginLogDO = RandomUtils.randomPojo(SysLoginLogDO.class, logDO -> {
|
||||
logDO.setLogType(RandomUtil.randomEle(SysLoginLogTypeEnum.values()).getType());
|
||||
logDO.setTraceId(TracerUtils.getTraceId());
|
||||
logDO.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue());
|
||||
|
||||
logDO.setUserIp("192.168.111.16");
|
||||
logDO.setUsername("wangxiaokai");
|
||||
logDO.setCreateTime(buildTime(2021, 3, 6));
|
||||
logDO.setResult(SysLoginResultEnum.SUCCESS.getResult());
|
||||
});
|
||||
loginLogMapper.insert(loginLogDO);
|
||||
|
||||
// 下面几个都是不匹配的数据
|
||||
// 登录失败的
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setResult(SysLoginResultEnum.CAPTCHA_CODE_ERROR.getResult())));
|
||||
// 不同ip段的
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUserIp("192.168.128.18")));
|
||||
// 不同username
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setUsername("yunai")));
|
||||
// 构造一个早期时间 2021-02-06 00:00:00
|
||||
loginLogMapper.insert(ObjectUtils.cloneIgnoreId(loginLogDO, logDO -> logDO.setCreateTime(buildTime(2021, 2, 6))));
|
||||
|
||||
|
||||
// 构造调用参数
|
||||
SysLoginLogExportReqVO reqVO = new SysLoginLogExportReqVO();
|
||||
reqVO.setUsername("wangxiaokai");
|
||||
reqVO.setUserIp("192.168.111");
|
||||
reqVO.setStatus(true);
|
||||
reqVO.setBeginTime(buildTime(2021, 3, 5));
|
||||
reqVO.setEndTime(buildTime(2021, 3, 7));
|
||||
|
||||
|
||||
// 调用service方法
|
||||
List<SysLoginLogDO> loginLogList = sysLoginLogService.getLoginLogList(reqVO);
|
||||
|
||||
// 断言
|
||||
assertEquals(1, loginLogList.size());
|
||||
assertPojoEquals(loginLogDO, loginLogList.get(0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package cn.iocoder.yudao.module.system.service.logger;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.module.system.controller.logger.vo.operatelog.SysOperateLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.logger.vo.operatelog.SysOperateLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.logger.SysOperateLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.logger.SysOperateLogMapper;
|
||||
import cn.iocoder.yudao.module.system.service.user.SysUserService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.common.SysSexEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import({SysOperateLogServiceImpl.class})
|
||||
public class SysOperateLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysOperateLogService operateLogServiceImpl;
|
||||
|
||||
@Resource
|
||||
private SysOperateLogMapper operateLogMapper;
|
||||
|
||||
@MockBean
|
||||
private SysUserService userService;
|
||||
|
||||
@Test
|
||||
public void testCreateOperateLogAsync() throws InterruptedException, ExecutionException {
|
||||
String traceId = TracerUtils.getTraceId();
|
||||
OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class, o -> {
|
||||
o.setTraceId(traceId);
|
||||
o.setUserId(randomLongId());
|
||||
o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
|
||||
});
|
||||
|
||||
// 执行service方法
|
||||
Future<Boolean> future = operateLogServiceImpl.createOperateLogAsync(reqVO);
|
||||
future.get();
|
||||
// 断言插入是否正确
|
||||
SysOperateLogDO sysOperateLogDO = operateLogMapper.selectOne("trace_id", traceId);
|
||||
assertPojoEquals(reqVO, sysOperateLogDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOperateLogPage() {
|
||||
// 构造测试数据
|
||||
// 先构造用户
|
||||
SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
|
||||
o.setNickname("wangkai");
|
||||
o.setSex(SysSexEnum.MALE.getSex());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
|
||||
Long userId = user.getId();
|
||||
// 构造操作日志
|
||||
SysOperateLogDO sysOperateLogDO = RandomUtils.randomPojo(SysOperateLogDO.class, o -> {
|
||||
o.setUserId(userId);
|
||||
o.setModule("order");
|
||||
o.setType(OperateTypeEnum.CREATE.getType());
|
||||
o.setStartTime(buildTime(2021, 3, 6));
|
||||
o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
|
||||
o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
|
||||
});
|
||||
operateLogMapper.insert(sysOperateLogDO);
|
||||
|
||||
// 下面几个是不匹配的数据
|
||||
// 随机 userId
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
|
||||
// module 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setModule("user")));
|
||||
// type 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
|
||||
// createTime 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
|
||||
// resultCode 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
|
||||
|
||||
// 构造调用参数
|
||||
SysOperateLogPageReqVO reqVO = new SysOperateLogPageReqVO();
|
||||
reqVO.setUserNickname("wangkai");
|
||||
reqVO.setModule("order");
|
||||
reqVO.setType(OperateTypeEnum.CREATE.getType());
|
||||
reqVO.setBeginTime(buildTime(2021, 3, 5));
|
||||
reqVO.setEndTime(buildTime(2021, 3, 7));
|
||||
reqVO.setSuccess(true);
|
||||
|
||||
// 调用service方法
|
||||
PageResult<SysOperateLogDO> pageResult = operateLogServiceImpl.getOperateLogPage(reqVO);
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(sysOperateLogDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOperateLogs() {
|
||||
// 构造测试数据
|
||||
// 先构造用户
|
||||
SysUserDO user = RandomUtils.randomPojo(SysUserDO.class, o -> {
|
||||
o.setNickname("wangkai");
|
||||
o.setSex(SysSexEnum.MALE.getSex());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(userService.getUsersByNickname("wangkai")).thenReturn(Collections.singletonList(user));
|
||||
Long userId = user.getId();
|
||||
// 构造操作日志
|
||||
SysOperateLogDO sysOperateLogDO = RandomUtils.randomPojo(SysOperateLogDO.class, o -> {
|
||||
o.setUserId(userId);
|
||||
o.setModule("order");
|
||||
o.setType(OperateTypeEnum.CREATE.getType());
|
||||
o.setStartTime(buildTime(2021, 3, 6));
|
||||
o.setResultCode(GlobalErrorCodeConstants.SUCCESS.getCode());
|
||||
o.setExts(MapUtil.<String, Object>builder("orderId", randomLongId()).build());
|
||||
});
|
||||
operateLogMapper.insert(sysOperateLogDO);
|
||||
|
||||
// 下面几个是不匹配的数据
|
||||
// 随机 userId
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setUserId(userId + 1)));
|
||||
// module 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setModule("user")));
|
||||
// type 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setType(OperateTypeEnum.IMPORT.getType())));
|
||||
// createTime 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setStartTime(buildTime(2021, 2, 6))));
|
||||
// resultCode 不同
|
||||
operateLogMapper.insert(ObjectUtils.cloneIgnoreId(sysOperateLogDO, logDO -> logDO.setResultCode(GlobalErrorCodeConstants.BAD_REQUEST.getCode())));
|
||||
|
||||
// 构造调用参数
|
||||
SysOperateLogExportReqVO reqVO = new SysOperateLogExportReqVO();
|
||||
reqVO.setUserNickname("wangkai");
|
||||
reqVO.setModule("order");
|
||||
reqVO.setType(OperateTypeEnum.CREATE.getType());
|
||||
reqVO.setBeginTime(buildTime(2021, 3, 5));
|
||||
reqVO.setEndTime(buildTime(2021, 3, 7));
|
||||
reqVO.setSuccess(true);
|
||||
|
||||
// 调用 service 方法
|
||||
List<SysOperateLogDO> list = operateLogServiceImpl.getOperateLogs(reqVO);
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(sysOperateLogDO, list.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package cn.iocoder.yudao.module.system.service.notice;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.controller.notice.vo.SysNoticeCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.notice.vo.SysNoticePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.notice.vo.SysNoticeUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.notice.SysNoticeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.notice.SysNoticeMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.notice.SysNoticeTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.NOTICE_NOT_FOUND;
|
||||
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.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Import(SysNoticeServiceImpl.class)
|
||||
class SysNoticeServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysNoticeServiceImpl sysNoticeService;
|
||||
|
||||
@Resource
|
||||
private SysNoticeMapper sysNoticeMapper;
|
||||
|
||||
@Test
|
||||
public void testPageNotices_success() {
|
||||
// 插入前置数据
|
||||
SysNoticeDO dbNotice = randomPojo(SysNoticeDO.class, o -> {
|
||||
o.setTitle("尼古拉斯赵四来啦!");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setType(randomEle(SysNoticeTypeEnum.values()).getType());
|
||||
});
|
||||
sysNoticeMapper.insert(dbNotice);
|
||||
|
||||
// 测试 title 不匹配
|
||||
sysNoticeMapper.insert(ObjectUtils.cloneIgnoreId(dbNotice, o -> o.setTitle("尼古拉斯凯奇也来啦!")));
|
||||
// 测试 status 不匹配
|
||||
sysNoticeMapper.insert(ObjectUtils.cloneIgnoreId(dbNotice, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
|
||||
|
||||
// 查询
|
||||
SysNoticePageReqVO reqVO = new SysNoticePageReqVO();
|
||||
reqVO.setTitle("尼古拉斯赵四来啦!");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
PageResult<SysNoticeDO> pageResult = sysNoticeService.pageNotices(reqVO);
|
||||
|
||||
// 验证查询结果经过筛选
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbNotice, pageResult.getList().get(0));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotice_success() {
|
||||
// 插入前置数据
|
||||
SysNoticeDO dbNotice = randomSysNoticeDO();
|
||||
sysNoticeMapper.insert(dbNotice);
|
||||
|
||||
// 查询
|
||||
SysNoticeDO notice = sysNoticeService.getNotice(dbNotice.getId());
|
||||
|
||||
// 验证插入与读取对象是否一致
|
||||
assertNotNull(notice);
|
||||
assertPojoEquals(dbNotice, notice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNotice_success() {
|
||||
// 准备参数
|
||||
SysNoticeCreateReqVO reqVO = randomSysNoticeCreateReqVO();
|
||||
|
||||
// 校验插入是否成功
|
||||
Long noticeId = sysNoticeService.createNotice(reqVO);
|
||||
assertNotNull(noticeId);
|
||||
|
||||
// 校验插入属性是否正确
|
||||
SysNoticeDO notice = sysNoticeMapper.selectById(noticeId);
|
||||
assertPojoEquals(reqVO, notice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotice_success() {
|
||||
// 插入前置数据
|
||||
SysNoticeDO dbNoticeDO = randomSysNoticeDO();
|
||||
sysNoticeMapper.insert(dbNoticeDO);
|
||||
|
||||
// 准备更新参数
|
||||
SysNoticeUpdateReqVO reqVO = randomSysNoticeUpdateReqVO(o -> o.setId(dbNoticeDO.getId()));
|
||||
|
||||
// 更新
|
||||
sysNoticeService.updateNotice(reqVO);
|
||||
|
||||
// 检验是否更新成功
|
||||
SysNoticeDO notice = sysNoticeMapper.selectById(reqVO.getId());
|
||||
assertPojoEquals(reqVO, notice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNotice_success() {
|
||||
// 插入前置数据
|
||||
SysNoticeDO dbNotice = randomSysNoticeDO();
|
||||
sysNoticeMapper.insert(dbNotice);
|
||||
|
||||
// 删除
|
||||
sysNoticeService.deleteNotice(dbNotice.getId());
|
||||
|
||||
// 检查是否删除成功
|
||||
assertNull(sysNoticeMapper.selectById(dbNotice.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkNoticeExists_success() {
|
||||
// 插入前置数据
|
||||
SysNoticeDO dbNotice = randomSysNoticeDO();
|
||||
sysNoticeMapper.insert(dbNotice);
|
||||
|
||||
// 成功调用
|
||||
sysNoticeService.checkNoticeExists(dbNotice.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkNoticeExists_noExists() {
|
||||
assertServiceException(() -> sysNoticeService.checkNoticeExists(randomLongId()), NOTICE_NOT_FOUND);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static SysNoticeDO randomSysNoticeDO(Consumer<SysNoticeDO>... consumers) {
|
||||
SysNoticeDO notice = randomPojo(SysNoticeDO.class, consumers);
|
||||
notice.setType(randomEle(SysNoticeTypeEnum.values()).getType());
|
||||
notice.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return notice;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static SysNoticeUpdateReqVO randomSysNoticeUpdateReqVO(Consumer<SysNoticeUpdateReqVO>... consumers) {
|
||||
SysNoticeUpdateReqVO reqVO = randomPojo(SysNoticeUpdateReqVO.class, consumers);
|
||||
reqVO.setType(randomEle(SysNoticeTypeEnum.values()).getType());
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return reqVO;
|
||||
}
|
||||
|
||||
private static SysNoticeCreateReqVO randomSysNoticeCreateReqVO() {
|
||||
SysNoticeCreateReqVO reqVO = randomPojo(SysNoticeCreateReqVO.class);
|
||||
reqVO.setType(randomEle(SysNoticeTypeEnum.values()).getType());
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
return reqVO;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,365 @@
|
||||
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.module.system.controller.permission.vo.menu.SysMenuCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.permission.vo.menu.SysMenuListReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.permission.vo.menu.SysMenuUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.SysMenuDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.SysMenuMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.permission.SysMenuProducer;
|
||||
import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
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.module.system.enums.SysErrorCodeConstants.*;
|
||||
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 org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@Import(SysMenuServiceImpl.class)
|
||||
public class SysMenuServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysMenuServiceImpl sysMenuService;
|
||||
|
||||
@MockBean
|
||||
private SysPermissionService sysPermissionService;
|
||||
|
||||
@MockBean
|
||||
private SysMenuProducer sysMenuProducer;
|
||||
|
||||
@Resource
|
||||
private SysMenuMapper menuMapper;
|
||||
|
||||
@Test
|
||||
public void testInitLocalCache_success() throws Exception {
|
||||
SysMenuDO menuDO1 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
|
||||
menuMapper.insert(menuDO1);
|
||||
SysMenuDO menuDO2 = createMenuDO(MenuTypeEnum.MENU, "xxxx", 0L);
|
||||
menuMapper.insert(menuDO2);
|
||||
|
||||
// 调用
|
||||
sysMenuService.initLocalCache();
|
||||
|
||||
// 获取代理对象
|
||||
SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
|
||||
|
||||
Map<Long, SysMenuDO> menuCache =
|
||||
(Map<Long, SysMenuDO>) BeanUtil.getFieldValue(target, "menuCache");
|
||||
Assert.isTrue(menuCache.size() == 2);
|
||||
assertPojoEquals(menuDO1, menuCache.get(menuDO1.getId()));
|
||||
assertPojoEquals(menuDO2, menuCache.get(menuDO2.getId()));
|
||||
|
||||
Multimap<String, SysMenuDO> permissionMenuCache =
|
||||
(Multimap<String, SysMenuDO>) BeanUtil.getFieldValue(target, "permissionMenuCache");
|
||||
Assert.isTrue(permissionMenuCache.size() == 2);
|
||||
assertPojoEquals(menuDO1, permissionMenuCache.get(menuDO1.getPermission()));
|
||||
assertPojoEquals(menuDO2, permissionMenuCache.get(menuDO2.getPermission()));
|
||||
|
||||
Date maxUpdateTime = (Date) BeanUtil.getFieldValue(target, "maxUpdateTime");
|
||||
assertEquals(ObjectUtils.max(menuDO1.getUpdateTime(), menuDO2.getUpdateTime()), maxUpdateTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateMenu_success() {
|
||||
//构造父目录
|
||||
SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
Long parentId = menuDO.getId();
|
||||
|
||||
//调用
|
||||
SysMenuCreateReqVO vo = randomPojo(SysMenuCreateReqVO.class, o -> {
|
||||
o.setParentId(parentId);
|
||||
o.setName("testSonName");
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
Long menuId = sysMenuService.createMenu(vo);
|
||||
|
||||
//断言
|
||||
assertNotNull(menuId);
|
||||
// 校验记录的属性是否正确
|
||||
SysMenuDO ret = menuMapper.selectById(menuId);
|
||||
assertPojoEquals(vo, ret);
|
||||
// 校验调用
|
||||
verify(sysMenuProducer).sendMenuRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMenu_success() {
|
||||
//构造父子目录
|
||||
SysMenuDO sonMenuDO = initParentAndSonMenuDO();
|
||||
Long sonId = sonMenuDO.getId();
|
||||
Long parentId = sonMenuDO.getParentId();
|
||||
|
||||
//调用
|
||||
SysMenuUpdateReqVO vo = randomPojo(SysMenuUpdateReqVO.class, o -> {
|
||||
o.setId(sonId);
|
||||
o.setParentId(parentId);
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setName("pppppp"); //修改名字
|
||||
});
|
||||
sysMenuService.updateMenu(vo);
|
||||
|
||||
//断言
|
||||
// 校验记录的属性是否正确
|
||||
SysMenuDO ret = menuMapper.selectById(sonId);
|
||||
assertPojoEquals(vo, ret);
|
||||
// 校验调用
|
||||
verify(sysMenuProducer).sendMenuRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMenu_sonIdNotExist() {
|
||||
Long sonId = 99999L;
|
||||
Long parentId = 10000L;
|
||||
|
||||
//调用
|
||||
SysMenuUpdateReqVO vo = randomPojo(SysMenuUpdateReqVO.class, o -> {
|
||||
o.setId(sonId);
|
||||
o.setParentId(parentId);
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
//断言
|
||||
assertServiceException(() -> sysMenuService.updateMenu(vo), MENU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_success() {
|
||||
SysMenuDO sonMenuDO = initParentAndSonMenuDO();
|
||||
Long sonId = sonMenuDO.getId();
|
||||
|
||||
// 调用
|
||||
sysMenuService.deleteMenu(sonId);
|
||||
|
||||
// 断言
|
||||
SysMenuDO menuDO = menuMapper.selectById(sonId);
|
||||
assertNull(menuDO);
|
||||
verify(sysPermissionService).processMenuDeleted(sonId);
|
||||
verify(sysMenuProducer).sendMenuRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_menuNotExist() {
|
||||
Long sonId = 99999L;
|
||||
|
||||
assertServiceException(() -> sysMenuService.deleteMenu(sonId), MENU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_existChildren() {
|
||||
SysMenuDO sonMenu = initParentAndSonMenuDO();
|
||||
Long parentId = sonMenu.getParentId();
|
||||
|
||||
assertServiceException(() -> sysMenuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenus_success() {
|
||||
Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
|
||||
SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
idMenuMap.put(menuDO.getId(), menuDO);
|
||||
|
||||
SysMenuDO sonMenu = createMenuDO(MenuTypeEnum.MENU, "son", menuDO.getId());
|
||||
menuMapper.insert(sonMenu);
|
||||
idMenuMap.put(sonMenu.getId(), sonMenu);
|
||||
|
||||
// 调用
|
||||
List<SysMenuDO> menuDOS = sysMenuService.getMenus();
|
||||
|
||||
// 断言
|
||||
assertEquals(menuDOS.size(), idMenuMap.size());
|
||||
menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenusReqVo_success() {
|
||||
Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
|
||||
// 用于验证可以模糊搜索名称包含"name",状态为1的menu
|
||||
SysMenuDO 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);
|
||||
|
||||
// 调用
|
||||
SysMenuListReqVO reqVO = new SysMenuListReqVO();
|
||||
reqVO.setStatus(1);
|
||||
reqVO.setName("name");
|
||||
List<SysMenuDO> menuDOS = sysMenuService.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, SysMenuDO> mockCacheMap = new HashMap<>();
|
||||
// 获取代理对象
|
||||
SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
|
||||
BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
|
||||
|
||||
Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
|
||||
// 用于验证搜索类型为MENU,状态为1的menu
|
||||
SysMenuDO 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<SysMenuDO> menuDOS = sysMenuService.listMenusFromCache(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, SysMenuDO> mockCacheMap = new HashMap<>();
|
||||
// 获取代理对象
|
||||
SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
|
||||
BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
|
||||
|
||||
Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
|
||||
// 验证搜索id为1, 类型为MENU, 状态为1 的menu
|
||||
SysMenuDO 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<SysMenuDO> menuDOS = sysMenuService.listMenusFromCache(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() {
|
||||
SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
Long parentId = menuDO.getId();
|
||||
|
||||
sysMenuService.checkParentResource(parentId, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckParentResource_canNotSetSelfToBeParent() {
|
||||
assertServiceException(() -> sysMenuService.checkParentResource(1L, 1L), MENU_PARENT_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckParentResource_parentNotExist() {
|
||||
assertServiceException(() -> sysMenuService.checkParentResource(randomLongId(), null), MENU_PARENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckParentResource_parentTypeError() {
|
||||
SysMenuDO menuDO = createMenuDO(MenuTypeEnum.BUTTON, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
Long parentId = menuDO.getId();
|
||||
|
||||
assertServiceException(() -> sysMenuService.checkParentResource(parentId, null), MENU_PARENT_NOT_DIR_OR_MENU);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckResource_success() {
|
||||
SysMenuDO sonMenu = initParentAndSonMenuDO();
|
||||
Long parentId = sonMenu.getParentId();
|
||||
|
||||
Long otherSonMenuId = randomLongId();
|
||||
String otherSonMenuName = randomString();
|
||||
|
||||
sysMenuService.checkResource(parentId, otherSonMenuName, otherSonMenuId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckResource_sonMenuNameDuplicate(){
|
||||
SysMenuDO sonMenu=initParentAndSonMenuDO();
|
||||
Long parentId=sonMenu.getParentId();
|
||||
|
||||
Long otherSonMenuId=randomLongId();
|
||||
String otherSonMenuName=sonMenu.getName(); //相同名称
|
||||
|
||||
assertServiceException(() -> sysMenuService.checkResource(parentId, otherSonMenuName, otherSonMenuId), MENU_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造父子目录,返回子目录
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private SysMenuDO initParentAndSonMenuDO() {
|
||||
//构造父子目录
|
||||
SysMenuDO menuDO = createMenuDO(MenuTypeEnum.MENU, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
Long parentId = menuDO.getId();
|
||||
|
||||
SysMenuDO sonMenuDO = createMenuDO(MenuTypeEnum.MENU, "testSonName", parentId);
|
||||
menuMapper.insert(sonMenuDO);
|
||||
return sonMenuDO;
|
||||
}
|
||||
|
||||
private SysMenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId) {
|
||||
return createMenuDO(typeEnum, menuName, parentId, randomCommonStatus());
|
||||
}
|
||||
|
||||
private SysMenuDO createMenuDO(MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) {
|
||||
return createMenuDO(null, typeEnum, menuName, parentId, status);
|
||||
}
|
||||
|
||||
private SysMenuDO createMenuDO(Long id, MenuTypeEnum typeEnum, String menuName, Long parentId, Integer status) {
|
||||
return randomPojo(SysMenuDO.class, o -> {
|
||||
o.setId(id);
|
||||
o.setParentId(parentId);
|
||||
o.setType(typeEnum.getType());
|
||||
o.setStatus(status);
|
||||
o.setName(menuName);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
package cn.iocoder.yudao.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.permission.SysRoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.SysRoleMenuDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.permission.SysUserRoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.SysRoleMenuMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.SysUserRoleMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.permission.SysPermissionProducer;
|
||||
import cn.iocoder.yudao.module.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(SysPermissionServiceImpl.class)
|
||||
public class SysPermissionServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysPermissionServiceImpl permissionService;
|
||||
|
||||
@Resource
|
||||
private SysRoleMenuMapper roleMenuMapper;
|
||||
@Resource
|
||||
private SysUserRoleMapper userRoleMapper;
|
||||
|
||||
@MockBean
|
||||
private SysRoleService roleService;
|
||||
@MockBean
|
||||
private SysMenuService menuService;
|
||||
@MockBean
|
||||
private SysDeptService deptService;
|
||||
|
||||
@MockBean
|
||||
private SysPermissionProducer permissionProducer;
|
||||
|
||||
@Test
|
||||
public void testProcessRoleDeleted() {
|
||||
// 准备参数
|
||||
Long roleId = randomLongId();
|
||||
// mock 数据 UserRole
|
||||
SysUserRoleDO userRoleDO01 = randomPojo(SysUserRoleDO.class, o -> o.setRoleId(roleId)); // 被删除
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
SysUserRoleDO userRoleDO02 = randomPojo(SysUserRoleDO.class); // 不被删除
|
||||
userRoleMapper.insert(userRoleDO02);
|
||||
// mock 数据 RoleMenu
|
||||
SysRoleMenuDO roleMenuDO01 = randomPojo(SysRoleMenuDO.class, o -> o.setRoleId(roleId)); // 被删除
|
||||
roleMenuMapper.insert(roleMenuDO01);
|
||||
SysRoleMenuDO roleMenuDO02 = randomPojo(SysRoleMenuDO.class); // 不被删除
|
||||
roleMenuMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
permissionService.processRoleDeleted(roleId);
|
||||
// 断言数据 RoleMenuDO
|
||||
List<SysRoleMenuDO> dbRoleMenus = roleMenuMapper.selectList();
|
||||
assertEquals(1, dbRoleMenus.size());
|
||||
assertPojoEquals(dbRoleMenus.get(0), roleMenuDO02);
|
||||
// 断言数据 UserRoleDO
|
||||
List<SysUserRoleDO> dbUserRoles = userRoleMapper.selectList();
|
||||
assertEquals(1, dbUserRoles.size());
|
||||
assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
|
||||
// 断言调用
|
||||
verify(permissionProducer).sendRoleMenuRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMenuDeleted() {
|
||||
// 准备参数
|
||||
Long menuId = randomLongId();
|
||||
// mock 数据
|
||||
SysRoleMenuDO roleMenuDO01 = randomPojo(SysRoleMenuDO.class, o -> o.setMenuId(menuId)); // 被删除
|
||||
roleMenuMapper.insert(roleMenuDO01);
|
||||
SysRoleMenuDO roleMenuDO02 = randomPojo(SysRoleMenuDO.class); // 不被删除
|
||||
roleMenuMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
permissionService.processMenuDeleted(menuId);
|
||||
// 断言数据
|
||||
List<SysRoleMenuDO> dbRoleMenus = roleMenuMapper.selectList();
|
||||
assertEquals(1, dbRoleMenus.size());
|
||||
assertPojoEquals(dbRoleMenus.get(0), roleMenuDO02);
|
||||
// 断言调用
|
||||
verify(permissionProducer).sendRoleMenuRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessUserDeleted() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
// mock 数据
|
||||
SysUserRoleDO userRoleDO01 = randomPojo(SysUserRoleDO.class, o -> o.setUserId(userId)); // 被删除
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
SysUserRoleDO userRoleDO02 = randomPojo(SysUserRoleDO.class); // 不被删除
|
||||
userRoleMapper.insert(userRoleDO02);
|
||||
|
||||
// 调用
|
||||
permissionService.processUserDeleted(userId);
|
||||
// 断言数据
|
||||
List<SysUserRoleDO> dbUserRoles = userRoleMapper.selectList();
|
||||
assertEquals(1, dbUserRoles.size());
|
||||
assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
|
||||
}
|
||||
|
||||
@Test // 测试从 context 获取的场景
|
||||
public void testGetDeptDataPermission_fromContext() {
|
||||
// 准备参数
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock 方法
|
||||
DeptDataPermissionRespDTO respDTO = new DeptDataPermissionRespDTO();
|
||||
loginUser.setContext(SysPermissionServiceImpl.CONTEXT_KEY, respDTO);
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);
|
||||
// 断言
|
||||
assertSame(respDTO, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_All() {
|
||||
// 准备参数
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock 方法
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> o.setDataScope(DataScopeEnum.ALL.getScope()));
|
||||
when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);
|
||||
// 断言
|
||||
assertTrue(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertTrue(CollUtil.isEmpty(result.getDeptIds()));
|
||||
assertSame(result, loginUser.getContext(SysPermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_DeptCustom() {
|
||||
// 准备参数
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock 方法
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope()));
|
||||
when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertEquals(roleDO.getDataScopeDeptIds().size() + 1, result.getDeptIds().size());
|
||||
assertTrue(CollUtil.containsAll(result.getDeptIds(), roleDO.getDataScopeDeptIds()));
|
||||
assertTrue(CollUtil.contains(result.getDeptIds(), loginUser.getDeptId()));
|
||||
assertSame(result, loginUser.getContext(SysPermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_DeptOnly() {
|
||||
// 准备参数
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock 方法
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_ONLY.getScope()));
|
||||
when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertEquals(1, result.getDeptIds().size());
|
||||
assertTrue(CollUtil.contains(result.getDeptIds(), loginUser.getDeptId()));
|
||||
assertSame(result, loginUser.getContext(SysPermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_DeptAndChild() {
|
||||
// 准备参数
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock 方法(角色)
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope()));
|
||||
when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO));
|
||||
// mock 方法(部门)
|
||||
SysDeptDO deptDO = randomPojo(SysDeptDO.class);
|
||||
when(deptService.getDeptsByParentIdFromCache(eq(loginUser.getDeptId()), eq(true)))
|
||||
.thenReturn(singletonList(deptDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertEquals(1, result.getDeptIds().size());
|
||||
assertTrue(CollUtil.contains(result.getDeptIds(), deptDO.getId()));
|
||||
assertSame(result, loginUser.getContext(SysPermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_Self() {
|
||||
// 准备参数
|
||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
||||
// mock 方法
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> o.setDataScope(DataScopeEnum.SELF.getScope()));
|
||||
when(roleService.getRolesFromCache(same(loginUser.getRoleIds()))).thenReturn(singletonList(roleDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(loginUser);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertTrue(result.getSelf());
|
||||
assertTrue(CollUtil.isEmpty(result.getDeptIds()));
|
||||
assertSame(result, loginUser.getContext(SysPermissionServiceImpl.CONTEXT_KEY, DeptDataPermissionRespDTO.class));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package cn.iocoder.yudao.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.security.core.enums.DataScopeEnum;
|
||||
import cn.iocoder.yudao.module.system.controller.permission.vo.role.SysRoleCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.permission.vo.role.SysRolePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.permission.vo.role.SysRoleUpdateReqVO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.permission.SysRoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.SysRoleMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.SysRoleTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.permission.SysRoleProducer;
|
||||
import cn.iocoder.yudao.framework.common.util.spring.SpringAopUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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 java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
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.common.util.object.ObjectUtils.max;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@Import(SysRoleServiceImpl.class)
|
||||
public class SysRoleServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysRoleServiceImpl sysRoleService;
|
||||
|
||||
@Resource
|
||||
private SysRoleMapper roleMapper;
|
||||
|
||||
@MockBean
|
||||
private SysPermissionService sysPermissionService;
|
||||
|
||||
@MockBean
|
||||
private SysRoleProducer sysRoleProducer;
|
||||
|
||||
@Test
|
||||
public void testInitLocalCache_success() throws Exception {
|
||||
SysRoleDO roleDO1 = createRoleDO("role1", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO1);
|
||||
SysRoleDO roleDO2 = createRoleDO("role2", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO2);
|
||||
|
||||
//调用
|
||||
sysRoleService.initLocalCache();
|
||||
|
||||
//断言
|
||||
//获取代理对象
|
||||
SysRoleServiceImpl target = (SysRoleServiceImpl) SpringAopUtils.getTarget(sysRoleService);
|
||||
|
||||
Map<Long, SysRoleDO> roleCache = (Map<Long, SysRoleDO>) BeanUtil.getFieldValue(target, "roleCache");
|
||||
assertPojoEquals(roleDO1, roleCache.get(roleDO1.getId()));
|
||||
assertPojoEquals(roleDO2, roleCache.get(roleDO2.getId()));
|
||||
|
||||
Date maxUpdateTime = (Date) BeanUtil.getFieldValue(target, "maxUpdateTime");
|
||||
assertEquals(max(roleDO1.getUpdateTime(), roleDO2.getUpdateTime()), maxUpdateTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRole_success() {
|
||||
SysRoleCreateReqVO reqVO = randomPojo(SysRoleCreateReqVO.class, o -> {
|
||||
o.setCode("role_code");
|
||||
o.setName("role_name");
|
||||
o.setRemark("remark");
|
||||
o.setType(SysRoleTypeEnum.CUSTOM.getType());
|
||||
o.setSort(1);
|
||||
});
|
||||
Long roleId = sysRoleService.createRole(reqVO);
|
||||
|
||||
//断言
|
||||
assertNotNull(roleId);
|
||||
SysRoleDO roleDO = roleMapper.selectById(roleId);
|
||||
assertPojoEquals(reqVO, roleDO);
|
||||
|
||||
verify(sysRoleProducer).sendRoleRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRole_success() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO);
|
||||
Long roleId = roleDO.getId();
|
||||
|
||||
//调用
|
||||
SysRoleUpdateReqVO reqVO = randomPojo(SysRoleUpdateReqVO.class, o -> {
|
||||
o.setId(roleId);
|
||||
o.setCode("role_code");
|
||||
o.setName("update_name");
|
||||
o.setType(SysRoleTypeEnum.SYSTEM.getType());
|
||||
o.setSort(999);
|
||||
});
|
||||
sysRoleService.updateRole(reqVO);
|
||||
|
||||
//断言
|
||||
SysRoleDO newRoleDO = roleMapper.selectById(roleId);
|
||||
assertPojoEquals(reqVO, newRoleDO);
|
||||
|
||||
verify(sysRoleProducer).sendRoleRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRoleStatus_success() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, CommonStatusEnum.ENABLE.getStatus());
|
||||
roleMapper.insert(roleDO);
|
||||
Long roleId = roleDO.getId();
|
||||
|
||||
//调用
|
||||
sysRoleService.updateRoleStatus(roleId, CommonStatusEnum.DISABLE.getStatus());
|
||||
|
||||
//断言
|
||||
SysRoleDO newRoleDO = roleMapper.selectById(roleId);
|
||||
assertEquals(CommonStatusEnum.DISABLE.getStatus(), newRoleDO.getStatus());
|
||||
|
||||
verify(sysRoleProducer).sendRoleRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRoleDataScope_success() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO);
|
||||
Long roleId = roleDO.getId();
|
||||
|
||||
//调用
|
||||
Set<Long> deptIdSet = Arrays.asList(1L, 2L, 3L, 4L, 5L).stream().collect(Collectors.toSet());
|
||||
sysRoleService.updateRoleDataScope(roleId, DataScopeEnum.DEPT_CUSTOM.getScope(), deptIdSet);
|
||||
|
||||
//断言
|
||||
SysRoleDO newRoleDO = roleMapper.selectById(roleId);
|
||||
assertEquals(DataScopeEnum.DEPT_CUSTOM.getScope(), newRoleDO.getDataScope());
|
||||
|
||||
Set<Long> newDeptIdSet = newRoleDO.getDataScopeDeptIds();
|
||||
assertTrue(deptIdSet.size() == newDeptIdSet.size());
|
||||
deptIdSet.stream().forEach(d -> assertTrue(newDeptIdSet.contains(d)));
|
||||
|
||||
verify(sysRoleProducer).sendRoleRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRole_success() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO);
|
||||
Long roleId = roleDO.getId();
|
||||
|
||||
//调用
|
||||
sysRoleService.deleteRole(roleId);
|
||||
|
||||
//断言
|
||||
SysRoleDO newRoleDO = roleMapper.selectById(roleId);
|
||||
assertNull(newRoleDO);
|
||||
|
||||
verify(sysRoleProducer).sendRoleRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoles_success() {
|
||||
Map<Long, SysRoleDO> idRoleMap = new HashMap<>();
|
||||
// 验证查询状态为1的角色
|
||||
SysRoleDO roleDO1 = createRoleDO("role1", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1);
|
||||
roleMapper.insert(roleDO1);
|
||||
idRoleMap.put(roleDO1.getId(), roleDO1);
|
||||
|
||||
SysRoleDO roleDO2 = createRoleDO("role2", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1);
|
||||
roleMapper.insert(roleDO2);
|
||||
idRoleMap.put(roleDO2.getId(), roleDO2);
|
||||
|
||||
// 以下是排除的角色
|
||||
SysRoleDO roleDO3 = createRoleDO("role3", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 2);
|
||||
roleMapper.insert(roleDO3);
|
||||
|
||||
//调用
|
||||
List<SysRoleDO> roles = sysRoleService.getRoles(Arrays.asList(1));
|
||||
|
||||
//断言
|
||||
assertEquals(2, roles.size());
|
||||
roles.stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRolePage_success() {
|
||||
Map<Long, SysRoleDO> idRoleMap = new HashMap<>();
|
||||
// 验证名称包含"role", 状态为1,code为"code"的角色
|
||||
// 第一页
|
||||
SysRoleDO roleDO = createRoleDO("role1", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "code");
|
||||
roleMapper.insert(roleDO);
|
||||
idRoleMap.put(roleDO.getId(), roleDO);
|
||||
// 第二页
|
||||
roleDO = createRoleDO("role2", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "code");
|
||||
roleMapper.insert(roleDO);
|
||||
|
||||
// 以下是排除的角色
|
||||
roleDO = createRoleDO("role3", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 2, "code");
|
||||
roleMapper.insert(roleDO);
|
||||
roleDO = createRoleDO("role4", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL, 1, "xxxxx");
|
||||
roleMapper.insert(roleDO);
|
||||
|
||||
//调用
|
||||
SysRolePageReqVO reqVO = randomPojo(SysRolePageReqVO.class, o -> {
|
||||
o.setName("role");
|
||||
o.setCode("code");
|
||||
o.setStatus(1);
|
||||
o.setPageNo(1);
|
||||
o.setPageSize(1);
|
||||
o.setBeginTime(null);
|
||||
o.setEndTime(null);
|
||||
});
|
||||
PageResult<SysRoleDO> result = sysRoleService.getRolePage(reqVO);
|
||||
assertEquals(2, result.getTotal());
|
||||
result.getList().stream().forEach(r -> assertPojoEquals(idRoleMap.get(r.getId()), r));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDuplicateRole_success() {
|
||||
sysRoleService.checkDuplicateRole(randomString(), randomString(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDuplicateRole_nameDuplicate() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO);
|
||||
|
||||
String duplicateName = "role_name";
|
||||
|
||||
assertServiceException(() -> sysRoleService.checkDuplicateRole(duplicateName, randomString(), null), ROLE_NAME_DUPLICATE, duplicateName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDuplicateRole_codeDuplicate() {
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> {
|
||||
o.setName("role_999");
|
||||
o.setCode("code");
|
||||
o.setType(SysRoleTypeEnum.CUSTOM.getType());
|
||||
o.setStatus(1);
|
||||
o.setDataScope(DataScopeEnum.ALL.getScope());
|
||||
});
|
||||
roleMapper.insert(roleDO);
|
||||
|
||||
String randomName = randomString();
|
||||
String duplicateCode = "code";
|
||||
|
||||
assertServiceException(() -> sysRoleService.checkDuplicateRole(randomName, duplicateCode, null), ROLE_CODE_DUPLICATE, duplicateCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUpdateRole_success() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.CUSTOM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO);
|
||||
Long roleId = roleDO.getId();
|
||||
|
||||
sysRoleService.checkUpdateRole(roleId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUpdateRole_roleIdNotExist() {
|
||||
assertServiceException(() -> sysRoleService.checkUpdateRole(randomLongId()), ROLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUpdateRole_systemRoleCanNotBeUpdate() {
|
||||
SysRoleDO roleDO = createRoleDO("role_name", SysRoleTypeEnum.SYSTEM, DataScopeEnum.ALL);
|
||||
roleMapper.insert(roleDO);
|
||||
Long roleId = roleDO.getId();
|
||||
|
||||
assertServiceException(() -> sysRoleService.checkUpdateRole(roleId), ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
|
||||
}
|
||||
|
||||
private SysRoleDO createRoleDO(String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status) {
|
||||
return createRoleDO( name, typeEnum, scopeEnum, status, randomString());
|
||||
}
|
||||
|
||||
private SysRoleDO createRoleDO(String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) {
|
||||
return createRoleDO(null, name, typeEnum, scopeEnum, status, code);
|
||||
}
|
||||
|
||||
private SysRoleDO createRoleDO(String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum) {
|
||||
return createRoleDO(null, name, typeEnum, scopeEnum, randomCommonStatus(), randomString());
|
||||
}
|
||||
|
||||
private SysRoleDO createRoleDO(Long id, String name, SysRoleTypeEnum typeEnum, DataScopeEnum scopeEnum, Integer status, String code) {
|
||||
SysRoleDO roleDO = randomPojo(SysRoleDO.class, o -> {
|
||||
o.setId(id);
|
||||
o.setName(name);
|
||||
o.setType(typeEnum.getType());
|
||||
o.setStatus(status);
|
||||
o.setDataScope(scopeEnum.getScope());
|
||||
o.setCode(code);
|
||||
});
|
||||
return roleDO;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.channel.SysSmsChannelCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.channel.SysSmsChannelPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.channel.SysSmsChannelUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SysSmsChannelMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.sms.SysSmsProducer;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
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.Date;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import(SysSmsChannelServiceImpl.class)
|
||||
public class SysSmsChannelServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysSmsChannelServiceImpl smsChannelService;
|
||||
|
||||
@Resource
|
||||
private SysSmsChannelMapper smsChannelMapper;
|
||||
|
||||
@MockBean
|
||||
private SmsClientFactory smsClientFactory;
|
||||
@MockBean
|
||||
private SysSmsTemplateService smsTemplateService;
|
||||
@MockBean
|
||||
private SysSmsProducer smsProducer;
|
||||
|
||||
@Test
|
||||
public void testInitLocalCache_success() {
|
||||
// mock 数据
|
||||
SysSmsChannelDO smsChannelDO01 = randomSmsChannelDO();
|
||||
smsChannelMapper.insert(smsChannelDO01);
|
||||
SysSmsChannelDO smsChannelDO02 = randomSmsChannelDO();
|
||||
smsChannelMapper.insert(smsChannelDO02);
|
||||
|
||||
// 调用
|
||||
smsChannelService.initSmsClients();
|
||||
// 校验 maxUpdateTime 属性
|
||||
Date maxUpdateTime = (Date) BeanUtil.getFieldValue(smsChannelService, "maxUpdateTime");
|
||||
assertEquals(max(smsChannelDO01.getUpdateTime(), smsChannelDO02.getUpdateTime()), maxUpdateTime);
|
||||
// 校验调用
|
||||
verify(smsClientFactory, times(1)).createOrUpdateSmsClient(
|
||||
argThat(properties -> isPojoEquals(smsChannelDO01, properties)));
|
||||
verify(smsClientFactory, times(1)).createOrUpdateSmsClient(
|
||||
argThat(properties -> isPojoEquals(smsChannelDO02, properties)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSmsChannel_success() {
|
||||
// 准备参数
|
||||
SysSmsChannelCreateReqVO reqVO = randomPojo(SysSmsChannelCreateReqVO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
|
||||
// 调用
|
||||
Long smsChannelId = smsChannelService.createSmsChannel(reqVO);
|
||||
// 断言
|
||||
assertNotNull(smsChannelId);
|
||||
// 校验记录的属性是否正确
|
||||
SysSmsChannelDO smsChannel = smsChannelMapper.selectById(smsChannelId);
|
||||
assertPojoEquals(reqVO, smsChannel);
|
||||
// 校验调用
|
||||
verify(smsProducer, times(1)).sendSmsChannelRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsChannel_success() {
|
||||
// mock 数据
|
||||
SysSmsChannelDO dbSmsChannel = randomSmsChannelDO();
|
||||
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysSmsChannelUpdateReqVO reqVO = randomPojo(SysSmsChannelUpdateReqVO.class, o -> {
|
||||
o.setId(dbSmsChannel.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setCallbackUrl(randomString());
|
||||
});
|
||||
|
||||
// 调用
|
||||
smsChannelService.updateSmsChannel(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysSmsChannelDO smsChannel = smsChannelMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, smsChannel);
|
||||
// 校验调用
|
||||
verify(smsProducer, times(1)).sendSmsChannelRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsChannel_notExists() {
|
||||
// 准备参数
|
||||
SysSmsChannelUpdateReqVO reqVO = randomPojo(SysSmsChannelUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsChannelService.updateSmsChannel(reqVO), SMS_CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsChannel_success() {
|
||||
// mock 数据
|
||||
SysSmsChannelDO dbSmsChannel = randomSmsChannelDO();
|
||||
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsChannel.getId();
|
||||
|
||||
// 调用
|
||||
smsChannelService.deleteSmsChannel(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(smsChannelMapper.selectById(id));
|
||||
// 校验调用
|
||||
verify(smsProducer, times(1)).sendSmsChannelRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsChannel_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsChannelService.deleteSmsChannel(id), SMS_CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsChannel_hasChildren() {
|
||||
// mock 数据
|
||||
SysSmsChannelDO dbSmsChannel = randomSmsChannelDO();
|
||||
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsChannel.getId();
|
||||
// mock 方法
|
||||
when(smsTemplateService.countByChannelId(eq(id))).thenReturn(10);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsChannelService.deleteSmsChannel(id), SMS_CHANNEL_HAS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsChannelPage() {
|
||||
// mock 数据
|
||||
SysSmsChannelDO dbSmsChannel = randomPojo(SysSmsChannelDO.class, o -> { // 等会查询到
|
||||
o.setSignature("芋道源码");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2020, 12, 12));
|
||||
});
|
||||
smsChannelMapper.insert(dbSmsChannel);
|
||||
// 测试 signature 不匹配
|
||||
smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setSignature("源码")));
|
||||
// 测试 status 不匹配
|
||||
smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
smsChannelMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11))));
|
||||
// 准备参数
|
||||
SysSmsChannelPageReqVO reqVO = new SysSmsChannelPageReqVO();
|
||||
reqVO.setSignature("芋道");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginCreateTime(buildTime(2020, 12, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2020, 12, 24));
|
||||
|
||||
// 调用
|
||||
PageResult<SysSmsChannelDO> pageResult = smsChannelService.getSmsChannelPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSmsChannel, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysSmsChannelDO randomSmsChannelDO(Consumer<SysSmsChannelDO>... consumers) {
|
||||
Consumer<SysSmsChannelDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(SysSmsChannelDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.log.SysSmsLogExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.log.SysSmsLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SysSmsLogMapper;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsLogDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.sms.SysSmsReceiveStatusEnum;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.sms.SysSmsSendStatusEnum;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.sms.SysSmsTemplateTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@Import(SysSmsLogServiceImpl.class)
|
||||
public class SysSmsLogServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysSmsLogServiceImpl smsLogService;
|
||||
|
||||
@Resource
|
||||
private SysSmsLogMapper smsLogMapper;
|
||||
|
||||
@Test
|
||||
public void testGetSmsLogPage() {
|
||||
// mock 数据
|
||||
SysSmsLogDO dbSmsLog = randomSmsLogDO(o -> { // 等会查询到
|
||||
o.setChannelId(1L);
|
||||
o.setTemplateId(10L);
|
||||
o.setMobile("15601691300");
|
||||
o.setSendStatus(SysSmsSendStatusEnum.INIT.getStatus());
|
||||
o.setSendTime(buildTime(2020, 11, 11));
|
||||
o.setReceiveStatus(SysSmsReceiveStatusEnum.INIT.getStatus());
|
||||
o.setReceiveTime(buildTime(2021, 11, 11));
|
||||
});
|
||||
smsLogMapper.insert(dbSmsLog);
|
||||
// 测试 channelId 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L)));
|
||||
// 测试 templateId 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L)));
|
||||
// 测试 mobile 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999")));
|
||||
// 测试 sendStatus 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SysSmsSendStatusEnum.IGNORE.getStatus())));
|
||||
// 测试 sendTime 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
|
||||
// 测试 receiveStatus 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SysSmsReceiveStatusEnum.SUCCESS.getStatus())));
|
||||
// 测试 receiveTime 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SysSmsLogPageReqVO reqVO = new SysSmsLogPageReqVO();
|
||||
reqVO.setChannelId(1L);
|
||||
reqVO.setTemplateId(10L);
|
||||
reqVO.setMobile("156");
|
||||
reqVO.setSendStatus(SysSmsSendStatusEnum.INIT.getStatus());
|
||||
reqVO.setBeginSendTime(buildTime(2020, 11, 1));
|
||||
reqVO.setEndSendTime(buildTime(2020, 11, 30));
|
||||
reqVO.setReceiveStatus(SysSmsReceiveStatusEnum.INIT.getStatus());
|
||||
reqVO.setBeginReceiveTime(buildTime(2021, 11, 1));
|
||||
reqVO.setEndReceiveTime(buildTime(2021, 11, 30));
|
||||
|
||||
// 调用
|
||||
PageResult<SysSmsLogDO> pageResult = smsLogService.getSmsLogPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSmsLog, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsLogList() {
|
||||
// mock 数据
|
||||
SysSmsLogDO dbSmsLog = randomSmsLogDO(o -> { // 等会查询到
|
||||
o.setChannelId(1L);
|
||||
o.setTemplateId(10L);
|
||||
o.setMobile("15601691300");
|
||||
o.setSendStatus(SysSmsSendStatusEnum.INIT.getStatus());
|
||||
o.setSendTime(buildTime(2020, 11, 11));
|
||||
o.setReceiveStatus(SysSmsReceiveStatusEnum.INIT.getStatus());
|
||||
o.setReceiveTime(buildTime(2021, 11, 11));
|
||||
});
|
||||
smsLogMapper.insert(dbSmsLog);
|
||||
// 测试 channelId 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L)));
|
||||
// 测试 templateId 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L)));
|
||||
// 测试 mobile 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999")));
|
||||
// 测试 sendStatus 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SysSmsSendStatusEnum.IGNORE.getStatus())));
|
||||
// 测试 sendTime 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
|
||||
// 测试 receiveStatus 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SysSmsReceiveStatusEnum.SUCCESS.getStatus())));
|
||||
// 测试 receiveTime 不匹配
|
||||
smsLogMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SysSmsLogExportReqVO reqVO = new SysSmsLogExportReqVO();
|
||||
reqVO.setChannelId(1L);
|
||||
reqVO.setTemplateId(10L);
|
||||
reqVO.setMobile("156");
|
||||
reqVO.setSendStatus(SysSmsSendStatusEnum.INIT.getStatus());
|
||||
reqVO.setBeginSendTime(buildTime(2020, 11, 1));
|
||||
reqVO.setEndSendTime(buildTime(2020, 11, 30));
|
||||
reqVO.setReceiveStatus(SysSmsReceiveStatusEnum.INIT.getStatus());
|
||||
reqVO.setBeginReceiveTime(buildTime(2021, 11, 1));
|
||||
reqVO.setEndReceiveTime(buildTime(2021, 11, 30));
|
||||
|
||||
// 调用
|
||||
List<SysSmsLogDO> list = smsLogService.getSmsLogList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbSmsLog, list.get(0));
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysSmsLogDO randomSmsLogDO(Consumer<SysSmsLogDO>... consumers) {
|
||||
Consumer<SysSmsLogDO> consumer = (o) -> {
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
o.setTemplateType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 templateType 的范围
|
||||
o.setUserType(randomEle(UserTypeEnum.values()).getValue()); // 保证 userType 的范围
|
||||
o.setSendStatus(randomEle(SysSmsSendStatusEnum.values()).getStatus()); // 保证 sendStatus 的范围
|
||||
o.setReceiveStatus(randomEle(SysSmsReceiveStatusEnum.values()).getStatus()); // 保证 receiveStatus 的范围
|
||||
};
|
||||
return randomPojo(SysSmsLogDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
|
||||
private static Map<String, Object> randomTemplateParams() {
|
||||
return MapUtil.<String, Object>builder().put(randomString(), randomString())
|
||||
.put(randomString(), randomString()).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.template.SysSmsTemplateCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.template.SysSmsTemplateExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.template.SysSmsTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.sms.vo.template.SysSmsTemplateUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SysSmsTemplateMapper;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.sms.SysSmsProducer;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsChannelDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.sms.SysSmsTemplateDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.sms.SysSmsTemplateTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.sms.core.client.SmsClient;
|
||||
import cn.iocoder.yudao.framework.sms.core.client.SmsClientFactory;
|
||||
import cn.iocoder.yudao.framework.sms.core.client.SmsCommonResult;
|
||||
import cn.iocoder.yudao.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import com.google.common.collect.Lists;
|
||||
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.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
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 org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import(SysSmsTemplateServiceImpl.class)
|
||||
public class SysSmsTemplateServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysSmsTemplateServiceImpl smsTemplateService;
|
||||
|
||||
@Resource
|
||||
private SysSmsTemplateMapper smsTemplateMapper;
|
||||
|
||||
@MockBean
|
||||
private SysSmsChannelService smsChannelService;
|
||||
@MockBean
|
||||
private SmsClientFactory smsClientFactory;
|
||||
@MockBean
|
||||
private SmsClient smsClient;
|
||||
@MockBean
|
||||
private SysSmsProducer smsProducer;
|
||||
|
||||
@Test
|
||||
public void testParseTemplateContentParams() {
|
||||
// 准备参数
|
||||
String content = "正在进行登录操作{operation},您的验证码是{code}";
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
List<String> params = smsTemplateService.parseTemplateContentParams(content);
|
||||
// 断言
|
||||
assertEquals(Lists.newArrayList("operation", "code"), params);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testCreateSmsTemplate_success() {
|
||||
// 准备参数
|
||||
SysSmsTemplateCreateReqVO reqVO = randomPojo(SysSmsTemplateCreateReqVO.class, o -> {
|
||||
o.setContent("正在进行登录操作{operation},您的验证码是{code}");
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 type 的 范围
|
||||
});
|
||||
// mock Channel 的方法
|
||||
SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> {
|
||||
o.setId(reqVO.getChannelId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO);
|
||||
// mock 获得 API 短信模板成功
|
||||
when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient);
|
||||
when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class,
|
||||
o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode())));
|
||||
|
||||
// 调用
|
||||
Long smsTemplateId = smsTemplateService.createSmsTemplate(reqVO);
|
||||
// 断言
|
||||
assertNotNull(smsTemplateId);
|
||||
// 校验记录的属性是否正确
|
||||
SysSmsTemplateDO smsTemplate = smsTemplateMapper.selectById(smsTemplateId);
|
||||
assertPojoEquals(reqVO, smsTemplate);
|
||||
assertEquals(Lists.newArrayList("operation", "code"), smsTemplate.getParams());
|
||||
assertEquals(channelDO.getCode(), smsTemplate.getChannelCode());
|
||||
// 校验调用
|
||||
verify(smsProducer, times(1)).sendSmsTemplateRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUpdateSmsTemplate_success() {
|
||||
// mock 数据
|
||||
SysSmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
|
||||
smsTemplateMapper.insert(dbSmsTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysSmsTemplateUpdateReqVO reqVO = randomPojo(SysSmsTemplateUpdateReqVO.class, o -> {
|
||||
o.setId(dbSmsTemplate.getId()); // 设置更新的 ID
|
||||
o.setContent("正在进行登录操作{operation},您的验证码是{code}");
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 type 的 范围
|
||||
});
|
||||
// mock 方法
|
||||
SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> {
|
||||
o.setId(reqVO.getChannelId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO);
|
||||
// mock 获得 API 短信模板成功
|
||||
when(smsClientFactory.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient);
|
||||
when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(randomPojo(SmsCommonResult.class, SmsTemplateRespDTO.class,
|
||||
o -> o.setCode(GlobalErrorCodeConstants.SUCCESS.getCode())));
|
||||
|
||||
// 调用
|
||||
smsTemplateService.updateSmsTemplate(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysSmsTemplateDO smsTemplate = smsTemplateMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, smsTemplate);
|
||||
assertEquals(Lists.newArrayList("operation", "code"), smsTemplate.getParams());
|
||||
assertEquals(channelDO.getCode(), smsTemplate.getChannelCode());
|
||||
// 校验调用
|
||||
verify(smsProducer, times(1)).sendSmsTemplateRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsTemplate_notExists() {
|
||||
// 准备参数
|
||||
SysSmsTemplateUpdateReqVO reqVO = randomPojo(SysSmsTemplateUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsTemplateService.updateSmsTemplate(reqVO), SMS_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsTemplate_success() {
|
||||
// mock 数据
|
||||
SysSmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
|
||||
smsTemplateMapper.insert(dbSmsTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsTemplate.getId();
|
||||
|
||||
// 调用
|
||||
smsTemplateService.deleteSmsTemplate(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(smsTemplateMapper.selectById(id));
|
||||
// 校验调用
|
||||
verify(smsProducer, times(1)).sendSmsTemplateRefreshMessage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsTemplate_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsTemplateService.deleteSmsTemplate(id), SMS_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplatePage() {
|
||||
// mock 数据
|
||||
SysSmsTemplateDO dbSmsTemplate = randomPojo(SysSmsTemplateDO.class, o -> { // 等会查询到
|
||||
o.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCode("yudaoyuanma");
|
||||
o.setContent("芋道源码");
|
||||
o.setApiTemplateId("yunai");
|
||||
o.setChannelId(1L);
|
||||
o.setCreateTime(buildTime(2021, 11, 11));
|
||||
});
|
||||
smsTemplateMapper.insert(dbSmsTemplate);
|
||||
// 测试 type 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setType(SysSmsTemplateTypeEnum.VERIFICATION_CODE.getType())));
|
||||
// 测试 status 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 code 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCode("yuanma")));
|
||||
// 测试 content 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setContent("源码")));
|
||||
// 测试 apiTemplateId 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setApiTemplateId("nai")));
|
||||
// 测试 channelId 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setChannelId(2L)));
|
||||
// 测试 createTime 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCreateTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SysSmsTemplatePageReqVO reqVO = new SysSmsTemplatePageReqVO();
|
||||
reqVO.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCode("yudao");
|
||||
reqVO.setContent("芋道");
|
||||
reqVO.setApiTemplateId("yu");
|
||||
reqVO.setChannelId(1L);
|
||||
reqVO.setBeginCreateTime(buildTime(2021, 11, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2021, 12, 1));
|
||||
|
||||
// 调用
|
||||
PageResult<SysSmsTemplateDO> pageResult = smsTemplateService.getSmsTemplatePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSmsTemplate, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplateList() {
|
||||
// mock 数据
|
||||
SysSmsTemplateDO dbSmsTemplate = randomPojo(SysSmsTemplateDO.class, o -> { // 等会查询到
|
||||
o.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCode("yudaoyuanma");
|
||||
o.setContent("芋道源码");
|
||||
o.setApiTemplateId("yunai");
|
||||
o.setChannelId(1L);
|
||||
o.setCreateTime(buildTime(2021, 11, 11));
|
||||
});
|
||||
smsTemplateMapper.insert(dbSmsTemplate);
|
||||
// 测试 type 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setType(SysSmsTemplateTypeEnum.VERIFICATION_CODE.getType())));
|
||||
// 测试 status 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 code 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCode("yuanma")));
|
||||
// 测试 content 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setContent("源码")));
|
||||
// 测试 apiTemplateId 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setApiTemplateId("nai")));
|
||||
// 测试 channelId 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setChannelId(2L)));
|
||||
// 测试 createTime 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setCreateTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SysSmsTemplateExportReqVO reqVO = new SysSmsTemplateExportReqVO();
|
||||
reqVO.setType(SysSmsTemplateTypeEnum.PROMOTION.getType());
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCode("yudao");
|
||||
reqVO.setContent("芋道");
|
||||
reqVO.setApiTemplateId("yu");
|
||||
reqVO.setChannelId(1L);
|
||||
reqVO.setBeginCreateTime(buildTime(2021, 11, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2021, 12, 1));
|
||||
|
||||
// 调用
|
||||
List<SysSmsTemplateDO> list = smsTemplateService.getSmsTemplateList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbSmsTemplate, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSmsChannel_success() {
|
||||
// 准备参数
|
||||
Long channelId = randomLongId();
|
||||
// mock 方法
|
||||
SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> {
|
||||
o.setId(channelId);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelId))).thenReturn(channelDO);
|
||||
|
||||
// 调用
|
||||
SysSmsChannelDO returnChannelDO = smsTemplateService.checkSmsChannel(channelId);
|
||||
// 断言
|
||||
assertPojoEquals(returnChannelDO, channelDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSmsChannel_notExists() {
|
||||
// 准备参数
|
||||
Long channelId = randomLongId();
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.checkSmsChannel(channelId),
|
||||
SMS_CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSmsChannel_disable() {
|
||||
// 准备参数
|
||||
Long channelId = randomLongId();
|
||||
// mock 方法
|
||||
SysSmsChannelDO channelDO = randomPojo(SysSmsChannelDO.class, o -> {
|
||||
o.setId(channelId);
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus()); // 保证 status 禁用,触发失败
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelId))).thenReturn(channelDO);
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.checkSmsChannel(channelId),
|
||||
SMS_CHANNEL_DISABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataValueUnique_success() {
|
||||
// 调用,成功
|
||||
smsTemplateService.checkSmsTemplateCodeDuplicate(randomLongId(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSmsTemplateCodeDuplicate_valueDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String code = randomString();
|
||||
// mock 数据
|
||||
smsTemplateMapper.insert(randomSmsTemplateDO(o -> o.setCode(code)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.checkSmsTemplateCodeDuplicate(null, code),
|
||||
SMS_TEMPLATE_CODE_DUPLICATE, code);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDictDataValueUnique_valueDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String code = randomString();
|
||||
// mock 数据
|
||||
smsTemplateMapper.insert(randomSmsTemplateDO(o -> o.setCode(code)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.checkSmsTemplateCodeDuplicate(id, code),
|
||||
SMS_TEMPLATE_CODE_DUPLICATE, code);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysSmsTemplateDO randomSmsTemplateDO(Consumer<SysSmsTemplateDO>... consumers) {
|
||||
Consumer<SysSmsTemplateDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setType(randomEle(SysSmsTemplateTypeEnum.values()).getType()); // 保证 type 的 范围
|
||||
};
|
||||
return randomPojo(SysSmsTemplateDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package cn.iocoder.yudao.module.system.service.tenant;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.tenant.vo.SysTenantCreateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.tenant.vo.SysTenantExportReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.tenant.vo.SysTenantPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.tenant.vo.SysTenantUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.tenant.SysTenantMapper;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.tenant.SysTenantDO;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.TENANT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
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 org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link SysTenantServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(SysTenantServiceImpl.class)
|
||||
public class SysTenantServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysTenantServiceImpl tenantService;
|
||||
|
||||
@Resource
|
||||
private SysTenantMapper tenantMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateTenant_success() {
|
||||
// 准备参数
|
||||
SysTenantCreateReqVO reqVO = randomPojo(SysTenantCreateReqVO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
|
||||
// 调用
|
||||
Long tenantId = tenantService.createTenant(reqVO);
|
||||
// 断言
|
||||
assertNotNull(tenantId);
|
||||
// 校验记录的属性是否正确
|
||||
SysTenantDO tenant = tenantMapper.selectById(tenantId);
|
||||
assertPojoEquals(reqVO, tenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_success() {
|
||||
// mock 数据
|
||||
SysTenantDO dbTenant = randomPojo(SysTenantDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SysTenantUpdateReqVO reqVO = randomPojo(SysTenantUpdateReqVO.class, o -> {
|
||||
o.setId(dbTenant.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
tenantService.updateTenant(reqVO);
|
||||
// 校验是否更新正确
|
||||
SysTenantDO tenant = tenantMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, tenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_notExists() {
|
||||
// 准备参数
|
||||
SysTenantUpdateReqVO reqVO = randomPojo(SysTenantUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenant_success() {
|
||||
// mock 数据
|
||||
SysTenantDO dbTenant = randomPojo(SysTenantDO.class,
|
||||
o -> o.setStatus(randomCommonStatus()));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenant.getId();
|
||||
|
||||
// 调用
|
||||
tenantService.deleteTenant(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(tenantMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenant_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantService.deleteTenant(id), TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPage() {
|
||||
// mock 数据
|
||||
SysTenantDO dbTenant = randomPojo(SysTenantDO.class, o -> { // 等会查询到
|
||||
o.setName("芋道源码");
|
||||
o.setContactName("芋艿");
|
||||
o.setContactMobile("15601691300");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2020, 12, 12));
|
||||
});
|
||||
tenantMapper.insert(dbTenant);
|
||||
// 测试 name 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setName(randomString())));
|
||||
// 测试 contactName 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactName(randomString())));
|
||||
// 测试 contactMobile 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactMobile(randomString())));
|
||||
// 测试 status 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setCreateTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SysTenantPageReqVO reqVO = new SysTenantPageReqVO();
|
||||
reqVO.setName("芋道");
|
||||
reqVO.setContactName("艿");
|
||||
reqVO.setContactMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginCreateTime(buildTime(2020, 12, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2020, 12, 24));
|
||||
|
||||
// 调用
|
||||
PageResult<SysTenantDO> pageResult = tenantService.getTenantPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbTenant, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantList() {
|
||||
// mock 数据
|
||||
SysTenantDO dbTenant = randomPojo(SysTenantDO.class, o -> { // 等会查询到
|
||||
o.setName("芋道源码");
|
||||
o.setContactName("芋艿");
|
||||
o.setContactMobile("15601691300");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2020, 12, 12));
|
||||
});
|
||||
tenantMapper.insert(dbTenant);
|
||||
// 测试 name 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setName(randomString())));
|
||||
// 测试 contactName 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactName(randomString())));
|
||||
// 测试 contactMobile 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setContactMobile(randomString())));
|
||||
// 测试 status 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
tenantMapper.insert(cloneIgnoreId(dbTenant, o -> o.setCreateTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SysTenantExportReqVO reqVO = new SysTenantExportReqVO();
|
||||
reqVO.setName("芋道");
|
||||
reqVO.setContactName("艿");
|
||||
reqVO.setContactMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginCreateTime(buildTime(2020, 12, 1));
|
||||
reqVO.setEndCreateTime(buildTime(2020, 12, 24));
|
||||
|
||||
// 调用
|
||||
List<SysTenantDO> list = tenantService.getTenantList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbTenant, list.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
package cn.iocoder.yudao.module.system.service.user;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.module.system.controller.user.vo.profile.SysUserProfileUpdatePasswordReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.user.vo.profile.SysUserProfileUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.user.vo.user.*;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dept.SysDeptDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.dept.SysPostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.user.SysUserMapper;
|
||||
import cn.iocoder.yudao.module.system.service.dept.SysDeptService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.SysPostService;
|
||||
import cn.iocoder.yudao.module.system.service.permission.SysPermissionService;
|
||||
import cn.iocoder.yudao.coreservice.modules.infra.service.file.InfFileCoreService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.enums.common.SysSexEnum;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.dept.SysDeptCoreService;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.module.system.test.BaseDbUnitTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomBytes;
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.module.system.enums.SysErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
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 org.assertj.core.util.Lists.newArrayList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link SysUserService} 的单元测试类
|
||||
*
|
||||
* @author zxl
|
||||
*/
|
||||
@Import(SysUserServiceImpl.class)
|
||||
public class SysUserServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SysUserServiceImpl userService;
|
||||
|
||||
@Resource
|
||||
private SysUserMapper userMapper;
|
||||
|
||||
@MockBean
|
||||
private SysDeptService deptService;
|
||||
|
||||
@MockBean
|
||||
private SysDeptCoreService deptCoreService;
|
||||
@MockBean
|
||||
private SysPostService postService;
|
||||
@MockBean
|
||||
private SysPermissionService permissionService;
|
||||
@MockBean
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@MockBean
|
||||
private InfFileCoreService fileService;
|
||||
|
||||
@Test
|
||||
public void testCreatUser_success() {
|
||||
// 准备参数
|
||||
SysUserCreateReqVO reqVO = randomPojo(SysUserCreateReqVO.class, o -> {
|
||||
o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
|
||||
o.setMobile(randomString());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setId(reqVO.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptCoreService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock postService 的方法
|
||||
List<SysPostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
|
||||
randomPojo(SysPostDO.class, o -> {
|
||||
o.setId(postId);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}));
|
||||
when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
|
||||
// mock passwordEncoder 的方法
|
||||
when(passwordEncoder.encode(eq(reqVO.getPassword()))).thenReturn("yudaoyuanma");
|
||||
|
||||
// 调用
|
||||
Long userId = userService.createUser(reqVO);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(userId);
|
||||
assertPojoEquals(reqVO, user, "password");
|
||||
assertEquals("yudaoyuanma", user.getPassword());
|
||||
assertEquals(CommonStatusEnum.ENABLE.getStatus(), user.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUser_success() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
SysUserUpdateReqVO reqVO = randomPojo(SysUserUpdateReqVO.class, o -> {
|
||||
o.setId(dbUser.getId());
|
||||
o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
|
||||
o.setMobile(randomString());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setId(reqVO.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptCoreService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock postService 的方法
|
||||
List<SysPostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
|
||||
randomPojo(SysPostDO.class, o -> {
|
||||
o.setId(postId);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}));
|
||||
when(postService.getPosts(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
|
||||
|
||||
// 调用
|
||||
userService.updateUser(reqVO);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(reqVO.getId());
|
||||
assertPojoEquals(reqVO, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserProfile_success() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
SysUserProfileUpdateReqVO reqVO = randomPojo(SysUserProfileUpdateReqVO.class, o -> {
|
||||
o.setMobile(randomString());
|
||||
o.setSex(RandomUtil.randomEle(SysSexEnum.values()).getSex());
|
||||
});
|
||||
|
||||
// 调用
|
||||
userService.updateUserProfile(userId, reqVO);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(userId);
|
||||
assertPojoEquals(reqVO, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserPassword_success() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO(o -> o.setPassword("encode:yudao"));
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
SysUserProfileUpdatePasswordReqVO reqVO = randomPojo(SysUserProfileUpdatePasswordReqVO.class, o -> {
|
||||
o.setOldPassword("yudao");
|
||||
o.setNewPassword("yuanma");
|
||||
});
|
||||
// mock 方法
|
||||
when(passwordEncoder.encode(anyString())).then(
|
||||
(Answer<String>) invocationOnMock -> "encode:" + invocationOnMock.getArgument(0));
|
||||
when(passwordEncoder.matches(eq(reqVO.getOldPassword()), eq(dbUser.getPassword()))).thenReturn(true);
|
||||
|
||||
// 调用
|
||||
userService.updateUserPassword(userId, reqVO);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(userId);
|
||||
assertEquals("encode:yuanma", user.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserAvatar_success() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
byte[] avatarFileBytes = randomBytes(10);
|
||||
ByteArrayInputStream avatarFile = new ByteArrayInputStream(avatarFileBytes);
|
||||
// mock 方法
|
||||
String avatar = randomString();
|
||||
when(fileService.createFile(anyString(), eq(avatarFileBytes))).thenReturn(avatar);
|
||||
|
||||
// 调用
|
||||
userService.updateUserAvatar(userId, avatarFile);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(userId);
|
||||
assertEquals(avatar, user.getAvatar());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserPassword02_success() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
String password = "yudao";
|
||||
// mock 方法
|
||||
when(passwordEncoder.encode(anyString())).then(
|
||||
(Answer<String>) invocationOnMock -> "encode:" + invocationOnMock.getArgument(0));
|
||||
|
||||
// 调用
|
||||
userService.updateUserPassword(userId, password);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(userId);
|
||||
assertEquals("encode:" + password, user.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserStatus() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
Integer status = randomCommonStatus();
|
||||
|
||||
// 调用
|
||||
userService.updateUserStatus(userId, status);
|
||||
// 断言
|
||||
SysUserDO user = userMapper.selectById(userId);
|
||||
assertEquals(status, user.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteUser_success(){
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
|
||||
// 调用数据
|
||||
userService.deleteUser(userId);
|
||||
// 校验结果
|
||||
assertNull(userMapper.selectById(userId));
|
||||
// 校验调用次数
|
||||
verify(permissionService, times(1)).processUserDeleted(eq(userId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserPage() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = initGetUserPageData();
|
||||
// 准备参数
|
||||
SysUserPageReqVO reqVO = new SysUserPageReqVO();
|
||||
reqVO.setUsername("yudao");
|
||||
reqVO.setMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginTime(buildTime(2020, 12, 1));
|
||||
reqVO.setEndTime(buildTime(2020, 12, 24));
|
||||
reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门
|
||||
// mock 方法
|
||||
List<SysDeptDO> deptList = newArrayList(randomPojo(SysDeptDO.class, o -> o.setId(2L)));
|
||||
when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList);
|
||||
|
||||
// 调用
|
||||
PageResult<SysUserDO> pageResult = userService.getUserPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbUser, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUsers() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = initGetUserPageData();
|
||||
// 准备参数
|
||||
SysUserExportReqVO reqVO = new SysUserExportReqVO();
|
||||
reqVO.setUsername("yudao");
|
||||
reqVO.setMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setBeginTime(buildTime(2020, 12, 1));
|
||||
reqVO.setEndTime(buildTime(2020, 12, 24));
|
||||
reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门
|
||||
// mock 方法
|
||||
List<SysDeptDO> deptList = newArrayList(randomPojo(SysDeptDO.class, o -> o.setId(2L)));
|
||||
when(deptService.getDeptsByParentIdFromCache(eq(reqVO.getDeptId()), eq(true))).thenReturn(deptList);
|
||||
|
||||
// 调用
|
||||
List<SysUserDO> list = userService.getUsers(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbUser, list.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 getUserPage 方法的测试数据
|
||||
*/
|
||||
private SysUserDO initGetUserPageData() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO(o -> { // 等会查询到
|
||||
o.setUsername("yudaoyuanma");
|
||||
o.setMobile("15601691300");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2020, 12, 12));
|
||||
o.setDeptId(2L);
|
||||
});
|
||||
userMapper.insert(dbUser);
|
||||
// 测试 username 不匹配
|
||||
userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setUsername("yuanma")));
|
||||
// 测试 mobile 不匹配
|
||||
userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setMobile("18818260888")));
|
||||
// 测试 status 不匹配
|
||||
userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11))));
|
||||
// 测试 dept 不匹配
|
||||
userMapper.insert(ObjectUtils.cloneIgnoreId(dbUser, o -> o.setDeptId(0L)));
|
||||
return dbUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况一,校验不通过,导致插入失败
|
||||
*/
|
||||
@Test
|
||||
public void testImportUsers_01() {
|
||||
// 准备参数
|
||||
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
assertEquals(1, respVO.getFailureUsernames().size());
|
||||
assertEquals(DEPT_NOT_FOUND.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况二,不存在,进行插入
|
||||
*/
|
||||
@Test
|
||||
public void testImportUsers_02() {
|
||||
// 准备参数
|
||||
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
});
|
||||
// mock deptService 的方法
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptCoreService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock passwordEncoder 的方法
|
||||
when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java");
|
||||
|
||||
// 调用
|
||||
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(1, respVO.getCreateUsernames().size());
|
||||
SysUserDO user = userMapper.selectByUsername(respVO.getCreateUsernames().get(0));
|
||||
assertPojoEquals(importUser, user);
|
||||
assertEquals("java", user.getPassword());
|
||||
assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
assertEquals(0, respVO.getFailureUsernames().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况三,存在,但是不强制更新
|
||||
*/
|
||||
@Test
|
||||
public void testImportUsers_03() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setUsername(dbUser.getUsername());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptCoreService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用
|
||||
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), false);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(0, respVO.getUpdateUsernames().size());
|
||||
assertEquals(1, respVO.getFailureUsernames().size());
|
||||
assertEquals(USER_USERNAME_EXISTS.getMsg(), respVO.getFailureUsernames().get(importUser.getUsername()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况四,存在,强制更新
|
||||
*/
|
||||
@Test
|
||||
public void testImportUsers_04() {
|
||||
// mock 数据
|
||||
SysUserDO dbUser = randomSysUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
SysUserImportExcelVO importUser = randomPojo(SysUserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setUsername(dbUser.getUsername());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptCoreService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用
|
||||
SysUserImportRespVO respVO = userService.importUsers(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(1, respVO.getUpdateUsernames().size());
|
||||
SysUserDO user = userMapper.selectByUsername(respVO.getUpdateUsernames().get(0));
|
||||
assertPojoEquals(importUser, user);
|
||||
assertEquals(0, respVO.getFailureUsernames().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUserExists_notExists() {
|
||||
assertServiceException(() -> userService.checkUserExists(randomLongId()), USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUsernameUnique_usernameExistsForCreate() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomSysUserDO(o -> o.setUsername(username)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkUsernameUnique(null, username),
|
||||
USER_USERNAME_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckUsernameUnique_usernameExistsForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String username = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomSysUserDO(o -> o.setUsername(username)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkUsernameUnique(id, username),
|
||||
USER_USERNAME_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckEmailUnique_emailExistsForCreate() {
|
||||
// 准备参数
|
||||
String email = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomSysUserDO(o -> o.setEmail(email)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkEmailUnique(null, email),
|
||||
USER_EMAIL_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckEmailUnique_emailExistsForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String email = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomSysUserDO(o -> o.setEmail(email)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkEmailUnique(id, email),
|
||||
USER_EMAIL_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckMobileUnique_mobileExistsForCreate() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomSysUserDO(o -> o.setMobile(mobile)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkMobileUnique(null, mobile),
|
||||
USER_MOBILE_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckMobileUnique_mobileExistsForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String mobile = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomSysUserDO(o -> o.setMobile(mobile)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkMobileUnique(id, mobile),
|
||||
USER_MOBILE_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDeptEnable_notFound() {
|
||||
assertServiceException(() -> userService.checkDeptEnable(randomLongId()),
|
||||
DEPT_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckDeptEnable_notEnable() {
|
||||
// 准备参数
|
||||
Long deptId = randomLongId();
|
||||
// mock deptService 的方法
|
||||
SysDeptDO dept = randomPojo(SysDeptDO.class, o -> {
|
||||
o.setId(deptId);
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
});
|
||||
when(deptCoreService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkDeptEnable(deptId),
|
||||
DEPT_NOT_ENABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckPostEnable_notFound() {
|
||||
assertServiceException(() -> userService.checkPostEnable(randomSet(Long.class)),
|
||||
POST_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckPostEnable_notEnable() {
|
||||
// 准备参数
|
||||
Set<Long> postIds = randomSet(Long.class);
|
||||
// mock postService 的方法
|
||||
List<SysPostDO> posts = CollectionUtils.convertList(postIds, postId ->
|
||||
randomPojo(SysPostDO.class, o -> {
|
||||
o.setId(postId);
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
}));
|
||||
when(postService.getPosts(eq(postIds), isNull())).thenReturn(posts);
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkPostEnable(postIds),
|
||||
POST_NOT_ENABLE, CollUtil.getFirst(posts).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckOldPassword_notExists() {
|
||||
assertServiceException(() -> userService.checkOldPassword(randomLongId(), randomString()),
|
||||
USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckOldPassword_passwordFailed() {
|
||||
// mock 数据
|
||||
SysUserDO user = randomSysUserDO();
|
||||
userMapper.insert(user);
|
||||
// 准备参数
|
||||
Long id = user.getId();
|
||||
String oldPassword = user.getPassword();
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.checkOldPassword(id, oldPassword),
|
||||
USER_PASSWORD_FAILED);
|
||||
// 校验调用
|
||||
verify(passwordEncoder, times(1)).matches(eq(oldPassword), eq(user.getPassword()));
|
||||
}
|
||||
|
||||
// @Test //TODO jason 已经移到userCoreService.getUsersByPostIds
|
||||
// public void testUsersByPostIds() {
|
||||
// // 准备参数
|
||||
// Collection<Long> postIds = asSet(10L, 20L);
|
||||
// // mock 方法
|
||||
// SysUserDO user1 = randomSysUserDO(o -> o.setPostIds(asSet(10L, 30L)));
|
||||
// userMapper.insert(user1);
|
||||
// SysUserDO user2 = randomSysUserDO(o -> o.setPostIds(singleton(100L)));
|
||||
// userMapper.insert(user2);
|
||||
//
|
||||
// // 调用
|
||||
// List<SysUserDO> result = userService.getUsersByPostIds(postIds);
|
||||
// // 断言
|
||||
// assertEquals(1, result.size());
|
||||
// assertEquals(user1, result.get(0));
|
||||
// }
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SysUserDO randomSysUserDO(Consumer<SysUserDO>... consumers) {
|
||||
Consumer<SysUserDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SysSexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
};
|
||||
return randomPojo(SysUserDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package cn.iocoder.yudao.module.system.test;
|
||||
|
||||
import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
|
||||
import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
|
||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
||||
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
|
||||
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
|
||||
/**
|
||||
* 依赖内存 DB + Redis 的单元测试
|
||||
*
|
||||
* 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class)
|
||||
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
|
||||
@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
|
||||
public class BaseDbAndRedisUnitTest {
|
||||
|
||||
@Import({
|
||||
// DB 配置类
|
||||
YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
|
||||
DataSourceAutoConfiguration.class, // Spring DB 自动配置类
|
||||
DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
|
||||
DruidDataSourceAutoConfigure.class, // Druid 自动配置类
|
||||
// MyBatis 配置类
|
||||
YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
|
||||
MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
|
||||
// Redis 配置类
|
||||
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
||||
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
||||
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
|
||||
RedissonAutoConfiguration.class, // Redisson 自动高配置类
|
||||
})
|
||||
public static class Application {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.system.test;
|
||||
|
||||
import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
|
||||
import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
|
||||
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
|
||||
/**
|
||||
* 依赖内存 DB 的单元测试
|
||||
*
|
||||
* 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class)
|
||||
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
|
||||
@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB
|
||||
public class BaseDbUnitTest {
|
||||
|
||||
@Import({
|
||||
// DB 配置类
|
||||
YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
|
||||
DataSourceAutoConfiguration.class, // Spring DB 自动配置类
|
||||
DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
|
||||
DruidDataSourceAutoConfigure.class, // Druid 自动配置类
|
||||
// MyBatis 配置类
|
||||
YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
|
||||
MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
|
||||
})
|
||||
public static class Application {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.iocoder.yudao.module.system.test;
|
||||
|
||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||
import org.redisson.spring.starter.RedissonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
|
||||
/**
|
||||
* 依赖内存 Redis 的单元测试
|
||||
*
|
||||
* 相比 {@link BaseDbUnitTest} 来说,从内存 DB 改成了内存 Redis
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseRedisUnitTest.Application.class)
|
||||
@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件
|
||||
public class BaseRedisUnitTest {
|
||||
|
||||
@Import({
|
||||
// Redis 配置类
|
||||
RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer
|
||||
RedisAutoConfiguration.class, // Spring Redis 自动配置类
|
||||
YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
|
||||
RedissonAutoConfiguration.class, // Redisson 自动高配置类
|
||||
})
|
||||
public static class Application {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.system.test;
|
||||
|
||||
import com.github.fppt.jedismock.RedisServer;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Lazy(false) // 禁止延迟加载
|
||||
@EnableConfigurationProperties(RedisProperties.class)
|
||||
public class RedisTestConfiguration {
|
||||
|
||||
/**
|
||||
* 创建模拟的 Redis Server 服务器
|
||||
*/
|
||||
@Bean
|
||||
public RedisServer redisServer(RedisProperties properties) throws IOException {
|
||||
RedisServer redisServer = new RedisServer(properties.getPort());
|
||||
// TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。
|
||||
try {
|
||||
redisServer.start();
|
||||
} catch (Exception ignore) {}
|
||||
return redisServer;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user