1.分页限制修改为最大 1000条
This commit is contained in:
@@ -27,10 +27,10 @@ public class PageParam implements Serializable {
|
||||
@Min(value = 1, message = "页码最小值为 1")
|
||||
private Integer pageNo = PAGE_NO;
|
||||
|
||||
@Schema(description = "每页条数,最大值为 100", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@Schema(description = "每页条数,最大值为 1000", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||
@NotNull(message = "每页条数不能为空")
|
||||
@Min(value = 1, message = "每页条数最小值为 1")
|
||||
@Max(value = 100, message = "每页条数最大值为 100")
|
||||
@Max(value = 1000, message = "每页条数最大值为 1000")
|
||||
private Integer pageSize = PAGE_SIZE;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,337 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.oauth2;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2GrantTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ApproveService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2ClientService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2GrantService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2OpenController} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class OAuth2OpenControllerTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private OAuth2OpenController oauth2OpenController;
|
||||
|
||||
@Mock
|
||||
private OAuth2GrantService oauth2GrantService;
|
||||
@Mock
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
@Mock
|
||||
private OAuth2ApproveService oauth2ApproveService;
|
||||
@Mock
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_authorizationCode() {
|
||||
// 准备参数
|
||||
String granType = OAuth2GrantTypeEnum.AUTHORIZATION_CODE.getGrantType();
|
||||
String code = randomString();
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
HttpServletRequest request = mockRequest("test_client_id", "test_client_secret");
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("test_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("test_client_id"), eq("test_client_secret"), eq(granType), eq(new ArrayList<>()), eq(redirectUri))).thenReturn(client);
|
||||
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 30000L, ChronoUnit.MILLIS));
|
||||
when(oauth2GrantService.grantAuthorizationCodeForAccessToken(eq("test_client_id"),
|
||||
eq(code), eq(redirectUri), eq(state))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAccessTokenRespVO> result = oauth2OpenController.postAccessToken(request, granType,
|
||||
code, redirectUri, state, null, null, null, null);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertTrue(ObjectUtils.equalsAny(result.getData().getExpiresIn(), 29L, 30L)); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_password() {
|
||||
// 准备参数
|
||||
String granType = OAuth2GrantTypeEnum.PASSWORD.getGrantType();
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
String scope = "write read";
|
||||
HttpServletRequest request = mockRequest("test_client_id", "test_client_secret");
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("test_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("test_client_id"), eq("test_client_secret"),
|
||||
eq(granType), eq(Lists.newArrayList("write", "read")), isNull())).thenReturn(client);
|
||||
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 30000L, ChronoUnit.MILLIS));
|
||||
when(oauth2GrantService.grantPassword(eq(username), eq(password), eq("test_client_id"),
|
||||
eq(Lists.newArrayList("write", "read")))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAccessTokenRespVO> result = oauth2OpenController.postAccessToken(request, granType,
|
||||
null, null, null, username, password, scope, null);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertTrue(ObjectUtils.equalsAny(result.getData().getExpiresIn(), 29L, 30L)); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_refreshToken() {
|
||||
// 准备参数
|
||||
String granType = OAuth2GrantTypeEnum.REFRESH_TOKEN.getGrantType();
|
||||
String refreshToken = randomString();
|
||||
String password = randomString();
|
||||
HttpServletRequest request = mockRequest("test_client_id", "test_client_secret");
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("test_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("test_client_id"), eq("test_client_secret"),
|
||||
eq(granType), eq(Lists.newArrayList()), isNull())).thenReturn(client);
|
||||
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 30000L, ChronoUnit.MILLIS));
|
||||
when(oauth2GrantService.grantRefreshToken(eq(refreshToken), eq("test_client_id"))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAccessTokenRespVO> result = oauth2OpenController.postAccessToken(request, granType,
|
||||
null, null, null, null, password, null, refreshToken);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertTrue(ObjectUtils.equalsAny(result.getData().getExpiresIn(), 29L, 30L)); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostAccessToken_implicit() {
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2OpenController.postAccessToken(null,
|
||||
OAuth2GrantTypeEnum.IMPLICIT.getGrantType(), null, null, null,
|
||||
null, null, null, null),
|
||||
new ErrorCode(400, "Token 接口不支持 implicit 授权模式"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeToken() {
|
||||
// 准备参数
|
||||
HttpServletRequest request = mockRequest("demo_client_id", "demo_client_secret");
|
||||
String token = randomString();
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("demo_client_id");
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq("demo_client_id"),
|
||||
eq("demo_client_secret"), isNull(), isNull(), isNull())).thenReturn(client);
|
||||
// mock 方法(移除)
|
||||
when(oauth2GrantService.revokeToken(eq("demo_client_id"), eq(token))).thenReturn(true);
|
||||
|
||||
// 调用
|
||||
CommonResult<Boolean> result = oauth2OpenController.revokeToken(request, token);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertTrue(result.getData());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckToken() {
|
||||
// 准备参数
|
||||
HttpServletRequest request = mockRequest("demo_client_id", "demo_client_secret");
|
||||
String token = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setUserType(UserTypeEnum.ADMIN.getValue()).setExpiresTime(LocalDateTimeUtil.of(1653485731195L));
|
||||
when(oauth2TokenService.checkAccessToken(eq(token))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenCheckTokenRespVO> result = oauth2OpenController.checkToken(request, token);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(accessTokenDO, result.getData());
|
||||
assertEquals(1653485731L, result.getData().getExp()); // 执行过程会过去几毫秒
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorize() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("demo_client_id").setScopes(ListUtil.toList("read", "write", "all"));
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(client);
|
||||
// mock 方法(approve)
|
||||
List<OAuth2ApproveDO> approves = asList(
|
||||
randomPojo(OAuth2ApproveDO.class).setScope("read").setApproved(true),
|
||||
randomPojo(OAuth2ApproveDO.class).setScope("write").setApproved(false));
|
||||
when(oauth2ApproveService.getApproveList(isNull(), eq(UserTypeEnum.ADMIN.getValue()), eq(clientId))).thenReturn(approves);
|
||||
|
||||
// 调用
|
||||
CommonResult<OAuth2OpenAuthorizeInfoRespVO> result = oauth2OpenController.authorize(clientId);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertPojoEquals(client, result.getData().getClient());
|
||||
assertEquals(new KeyValue<>("read", true), result.getData().getScopes().get(0));
|
||||
assertEquals(new KeyValue<>("write", false), result.getData().getScopes().get(1));
|
||||
assertEquals(new KeyValue<>("all", false), result.getData().getScopes().get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproveOrDeny_grantTypeError() {
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2OpenController.approveOrDeny(randomString(), null,
|
||||
null, null, null, null),
|
||||
new ErrorCode(400, "response_type 参数值只允许 code 和 token"));
|
||||
}
|
||||
|
||||
@Test // autoApprove = true,但是不通过
|
||||
public void testApproveOrDeny_autoApproveNo() {
|
||||
// 准备参数
|
||||
String responseType = "code";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("authorization_code"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, true, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertNull(result.getData());
|
||||
}
|
||||
|
||||
@Test // autoApprove = false,但是不通过
|
||||
public void testApproveOrDeny_ApproveNo() {
|
||||
// 准备参数
|
||||
String responseType = "token";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = "https://www.iocoder.cn";
|
||||
String state = "test";
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("implicit"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, false, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertEquals("https://www.iocoder.cn#error=access_denied&error_description=User%20denied%20access&state=test", result.getData());
|
||||
}
|
||||
|
||||
@Test // autoApprove = true,通过 + token
|
||||
public void testApproveOrDeny_autoApproveWithToken() {
|
||||
// 准备参数
|
||||
String responseType = "token";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = "https://www.iocoder.cn";
|
||||
String state = "test";
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId(clientId).setAdditionalInformation(null);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("implicit"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
// mock 方法(场景一)
|
||||
when(oauth2ApproveService.checkForPreApproval(isNull(), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(SetUtils.asSet("read", "write")))).thenReturn(true);
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setAccessToken("test_access_token").setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 30010L, ChronoUnit.MILLIS));
|
||||
when(oauth2GrantService.grantImplicit(isNull(), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(ListUtil.toList("read")))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, true, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertThat(result.getData(), anyOf( // 29 和 30 都有一定概率,主要是时间计算
|
||||
is("https://www.iocoder.cn#access_token=test_access_token&token_type=bearer&state=test&expires_in=29&scope=read"),
|
||||
is("https://www.iocoder.cn#access_token=test_access_token&token_type=bearer&state=test&expires_in=30&scope=read")
|
||||
));
|
||||
}
|
||||
|
||||
@Test // autoApprove = false,通过 + code
|
||||
public void testApproveOrDeny_approveWithCode() {
|
||||
// 准备参数
|
||||
String responseType = "code";
|
||||
String clientId = randomString();
|
||||
String scope = "{\"read\": true, \"write\": false}";
|
||||
String redirectUri = "https://www.iocoder.cn";
|
||||
String state = "test";
|
||||
// mock 方法(client)
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId(clientId).setAdditionalInformation(null);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId), isNull(), eq("authorization_code"),
|
||||
eq(asSet("read", "write")), eq(redirectUri))).thenReturn(client);
|
||||
// mock 方法(场景二)
|
||||
when(oauth2ApproveService.updateAfterApproval(isNull(), eq(UserTypeEnum.ADMIN.getValue()), eq(clientId),
|
||||
eq(MapUtil.builder(new LinkedHashMap<String, Boolean>()).put("read", true).put("write", false).build())))
|
||||
.thenReturn(true);
|
||||
// mock 方法(访问令牌)
|
||||
String authorizationCode = "test_code";
|
||||
when(oauth2GrantService.grantAuthorizationCodeForCode(isNull(), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(ListUtil.toList("read")), eq(redirectUri), eq(state))).thenReturn(authorizationCode);
|
||||
|
||||
// 调用
|
||||
CommonResult<String> result = oauth2OpenController.approveOrDeny(responseType, clientId,
|
||||
scope, redirectUri, false, state);
|
||||
// 断言
|
||||
assertEquals(0, result.getCode());
|
||||
assertEquals("https://www.iocoder.cn?code=test_code&state=test", result.getData());
|
||||
}
|
||||
|
||||
private HttpServletRequest mockRequest(String clientId, String secret) {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
when(request.getParameter(eq("client_id"))).thenReturn(clientId);
|
||||
when(request.getParameter(eq("client_secret"))).thenReturn(secret);
|
||||
return request;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
/**
|
||||
* {@link cn.iocoder.yudao.module.system.framework.sms.core.client.impl.AliyunSmsClient} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class AliyunSmsClientTest extends BaseMockitoUnitTest {
|
||||
|
||||
private final SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(randomString()) // 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("芋道源码");
|
||||
|
||||
@InjectMocks
|
||||
private final AliyunSmsClient smsClient = new AliyunSmsClient(properties);
|
||||
|
||||
@Test
|
||||
public void tesSendSms_success() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"Message\":\"OK\",\"RequestId\":\"30067CE9-3710-5984-8881-909B21D8DB28\",\"Code\":\"OK\",\"BizId\":\"800025323183427988\"}");
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.encodeUtf8(anyString()))
|
||||
.then((Answer<String>) invocationOnMock -> (String) invocationOnMock.getArguments()[0]);
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertTrue(result.getSuccess());
|
||||
assertEquals("30067CE9-3710-5984-8881-909B21D8DB28", result.getApiRequestId());
|
||||
assertEquals("OK", result.getApiCode());
|
||||
assertEquals("OK", result.getApiMsg());
|
||||
assertEquals("800025323183427988", result.getSerialNo());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tesSendSms_fail() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("code", 1234), new KeyValue<>("op", "login"));
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"Message\":\"手机号码格式错误\",\"RequestId\":\"B7700B8E-227E-5886-9564-26036172F01F\",\"Code\":\"isv.MOBILE_NUMBER_ILLEGAL\"}");
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.encodeUtf8(anyString()))
|
||||
.then((Answer<String>) invocationOnMock -> (String) invocationOnMock.getArguments()[0]);
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertFalse(result.getSuccess());
|
||||
assertEquals("B7700B8E-227E-5886-9564-26036172F01F", result.getApiRequestId());
|
||||
assertEquals("isv.MOBILE_NUMBER_ILLEGAL", result.getApiCode());
|
||||
assertEquals("手机号码格式错误", result.getApiMsg());
|
||||
assertNull(result.getSerialNo());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSmsReceiveStatus() {
|
||||
// 准备参数
|
||||
String text = "[\n" +
|
||||
" {\n" +
|
||||
" \"phone_number\" : \"13900000001\",\n" +
|
||||
" \"send_time\" : \"2017-01-01 11:12:13\",\n" +
|
||||
" \"report_time\" : \"2017-02-02 22:23:24\",\n" +
|
||||
" \"success\" : true,\n" +
|
||||
" \"err_code\" : \"DELIVERED\",\n" +
|
||||
" \"err_msg\" : \"用户接收成功\",\n" +
|
||||
" \"sms_size\" : \"1\",\n" +
|
||||
" \"biz_id\" : \"12345\",\n" +
|
||||
" \"out_id\" : \"67890\"\n" +
|
||||
" }\n" +
|
||||
"]";
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
List<SmsReceiveRespDTO> statuses = smsClient.parseSmsReceiveStatus(text);
|
||||
// 断言
|
||||
assertEquals(1, statuses.size());
|
||||
assertTrue(statuses.get(0).getSuccess());
|
||||
assertEquals("DELIVERED", statuses.get(0).getErrorCode());
|
||||
assertEquals("用户接收成功", statuses.get(0).getErrorMsg());
|
||||
assertEquals("13900000001", statuses.get(0).getMobile());
|
||||
assertEquals(LocalDateTime.of(2017, 2, 2, 22, 23, 24),
|
||||
statuses.get(0).getReceiveTime());
|
||||
assertEquals("12345", statuses.get(0).getSerialNo());
|
||||
assertEquals(67890L, statuses.get(0).getLogId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplate() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
String apiTemplateId = randomString();
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"TemplateCode\":\"SMS_207945135\",\"RequestId\":\"6F4CC077-29C8-5BA5-AB62-5FF95068A5AC\",\"Message\":\"OK\",\"TemplateContent\":\"您的验证码${code},该验证码5分钟内有效,请勿泄漏于他人!\",\"TemplateName\":\"公告通知\",\"TemplateType\":0,\"Code\":\"OK\",\"CreateDate\":\"2020-12-23 17:34:42\",\"Reason\":\"无审批备注\",\"TemplateStatus\":1}");
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.encodeUtf8(anyString()))
|
||||
.then((Answer<String>) invocationOnMock -> (String) invocationOnMock.getArguments()[0]);
|
||||
|
||||
// 调用
|
||||
SmsTemplateRespDTO result = smsClient.getSmsTemplate(apiTemplateId);
|
||||
// 断言
|
||||
assertEquals("SMS_207945135", result.getId());
|
||||
assertEquals("您的验证码${code},该验证码5分钟内有效,请勿泄漏于他人!", result.getContent());
|
||||
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getAuditStatus());
|
||||
assertEquals("无审批备注", result.getAuditReason());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertSmsTemplateAuditStatus() {
|
||||
assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus(0));
|
||||
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus(1));
|
||||
assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus(2));
|
||||
assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus(3),
|
||||
"未知审核状态(3)");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
/**
|
||||
* {@link HuaweiSmsClient} 的单元测试
|
||||
*
|
||||
* @author scholar
|
||||
*/
|
||||
public class HuaweiSmsClientTest extends BaseMockitoUnitTest {
|
||||
|
||||
private final SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("芋道源码");
|
||||
|
||||
@InjectMocks
|
||||
private HuaweiSmsClient smsClient = new HuaweiSmsClient(properties);
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_success() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString() + " " + randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"result\":[{\"originTo\":\"+86155****5678\",\"createTime\":\"2018-05-25T16:34:34Z\",\"from\":\"1069********0012\",\"smsMsgId\":\"d6e3cdd0-522b-4692-8304-a07553cdf591_8539659\",\"status\":\"000000\",\"countryId\":\"CN\",\"total\":2}],\"code\":\"000000\",\"description\":\"Success\"}\n");
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertTrue(result.getSuccess());
|
||||
assertEquals("d6e3cdd0-522b-4692-8304-a07553cdf591_8539659", result.getSerialNo());
|
||||
assertEquals("000000", result.getApiCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_fail_01() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString() + " " + randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"result\":[{\"total\":1,\"originTo\":\"17321315478\",\"createTime\":\"2024-08-18T11:32:20Z\",\"from\":\"x8824060312575\",\"smsMsgId\":\"06e4b966-ad87-479f-8b74-f57fb7aafb60_304613461\",\"countryId\":\"CN\",\"status\":\"E200033\"}],\"code\":\"E000510\",\"description\":\"The SMS fails to be sent. For details, see status.\"}");
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertFalse(result.getSuccess());
|
||||
assertEquals("06e4b966-ad87-479f-8b74-f57fb7aafb60_304613461", result.getSerialNo());
|
||||
assertEquals("E200033", result.getApiCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_fail_02() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString() + " " + randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"code\":\"E000102\",\"description\":\"Invalid app_key.\"}");
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertFalse(result.getSuccess());
|
||||
assertEquals("E000102", result.getApiCode());
|
||||
assertEquals("Invalid app_key.", result.getApiMsg());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSmsReceiveStatus() {
|
||||
// 准备参数
|
||||
String text = "sequence=1&total=1&statusDesc=%E7%94%A8%E6%88%B7%E5%B7%B2%E6%88%90%E5%8A%9F%E6%94%B6%E5%88%B0%E7%9F%AD%E4%BF%A1&updateTime=2024-08-15T03%3A00%3A34Z&source=2&smsMsgId=70207ed7-1d02-41b0-8537-bb25fd1c2364_143684459&status=DELIVRD&extend=176";
|
||||
|
||||
// 调用
|
||||
List<SmsReceiveRespDTO> statuses = smsClient.parseSmsReceiveStatus(text);
|
||||
// 断言
|
||||
assertEquals(1, statuses.size());
|
||||
SmsReceiveRespDTO status = statuses.get(0);
|
||||
assertTrue(status.getSuccess());
|
||||
assertEquals("DELIVRD", status.getErrorCode());
|
||||
assertEquals(LocalDateTime.of(2024, 8, 15, 3, 0, 34), status.getReceiveTime());
|
||||
assertEquals("70207ed7-1d02-41b0-8537-bb25fd1c2364_143684459", status.getSerialNo());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
/**
|
||||
* {@link QiniuSmsClient} 的单元测试
|
||||
*
|
||||
* @author scholar
|
||||
*/
|
||||
public class QiniuSmsClientTest extends BaseMockitoUnitTest {
|
||||
|
||||
private final SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(randomString())// 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("芋道源码");
|
||||
|
||||
@InjectMocks
|
||||
private QiniuSmsClient smsClient = new QiniuSmsClient(properties);
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_success() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString() + " " + randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"message_id\":\"17245678901\"}");
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertTrue(result.getSuccess());
|
||||
assertEquals("17245678901", result.getSerialNo());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_fail() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString() + " " + randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"error\":\"BadToken\",\"message\":\"Your authorization token is invalid\",\"request_id\":\"etziWcJFo1C8Ne8X\"}");
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertFalse(result.getSuccess());
|
||||
assertEquals("BadToken", result.getApiCode());
|
||||
assertEquals("Your authorization token is invalid", result.getApiMsg());
|
||||
assertEquals("etziWcJFo1C8Ne8X", result.getApiRequestId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplate() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
String apiTemplateId = randomString();
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.get(anyString(), anyMap()))
|
||||
.thenReturn("{\"audit_status\":\"passed\",\"created_at\":1724231187,\"description\":\"\",\"disable_broadcast\":false,\"disable_broadcast_reason\":\"\",\"disable_reason\":\"\",\"disabled\":false,\"id\":\"1826184073773596672\",\"is_oversea\":false,\"name\":\"dd\",\"parameters\":[\"code\"],\"reject_reason\":\"\",\"signature_id\":\"1826099896017498112\",\"signature_text\":\"yudao\",\"template\":\"您的验证码为:${code}\",\"type\":\"verification\",\"uid\":1383022432,\"updated_at\":1724288561,\"variable_count\":0}");
|
||||
// 调用
|
||||
SmsTemplateRespDTO result = smsClient.getSmsTemplate(apiTemplateId);
|
||||
// 断言
|
||||
assertEquals("1826184073773596672", result.getId());
|
||||
assertEquals("您的验证码为:${code}", result.getContent());
|
||||
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getAuditStatus());
|
||||
assertEquals("", result.getAuditReason());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSmsReceiveStatus() {
|
||||
// 准备参数
|
||||
String text = "{\"items\":[{\"mobile\":\"18881234567\",\"message_id\":\"10135515063508004167\",\"status\":\"DELIVRD\",\"delivrd_at\":1724591666,\"error\":\"DELIVRD\",\"seq\":\"123\"}]}";
|
||||
// 调用
|
||||
List<SmsReceiveRespDTO> statuses = smsClient.parseSmsReceiveStatus(text);
|
||||
// 断言
|
||||
assertEquals(1, statuses.size());
|
||||
SmsReceiveRespDTO status = statuses.get(0);
|
||||
assertTrue(status.getSuccess());
|
||||
assertEquals("DELIVRD", status.getErrorMsg());
|
||||
assertEquals(LocalDateTime.of(2024, 8, 25, 21, 14, 26), status.getReceiveTime());
|
||||
assertEquals("18881234567", status.getMobile());
|
||||
assertEquals("10135515063508004167", status.getSerialNo());
|
||||
assertEquals(123, status.getLogId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertSmsTemplateAuditStatus() {
|
||||
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus("passed"));
|
||||
assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus("reviewing"));
|
||||
assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus("rejected"));
|
||||
assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus("unknown"),
|
||||
"未知审核状态(3)");
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.SmsClient;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 各种 {@link SmsClient} 的集成测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class SmsClientTests {
|
||||
|
||||
// ========== 阿里云 ==========
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testAliyunSmsClient_getSmsTemplate() throws Throwable {
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(System.getenv("SMS_ALIYUN_ACCESS_KEY"))
|
||||
.setApiSecret(System.getenv("SMS_ALIYUN_SECRET_KEY"));
|
||||
AliyunSmsClient client = new AliyunSmsClient(properties);
|
||||
// 准备参数
|
||||
String apiTemplateId = "SMS_207945135";
|
||||
// 调用
|
||||
SmsTemplateRespDTO template = client.getSmsTemplate(apiTemplateId);
|
||||
// 打印结果
|
||||
System.out.println(template);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testAliyunSmsClient_sendSms() throws Throwable {
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(System.getenv("SMS_ALIYUN_ACCESS_KEY"))
|
||||
.setApiSecret(System.getenv("SMS_ALIYUN_SECRET_KEY"))
|
||||
.setSignature("Ballcat");
|
||||
AliyunSmsClient client = new AliyunSmsClient(properties);
|
||||
// 准备参数
|
||||
Long sendLogId = System.currentTimeMillis();
|
||||
String mobile = "15601691323";
|
||||
String apiTemplateId = "SMS_207945135";
|
||||
// 调用
|
||||
SmsSendRespDTO sendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, ListUtil.of(new KeyValue<>("code", "1024")));
|
||||
// 打印结果
|
||||
System.out.println(sendRespDTO);
|
||||
}
|
||||
|
||||
// ========== 腾讯云 ==========
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testTencentSmsClient_sendSms() throws Throwable {
|
||||
String sdkAppId = "1400500458";
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(System.getenv("SMS_TENCENT_ACCESS_KEY") + " " + sdkAppId)
|
||||
.setApiSecret(System.getenv("SMS_TENCENT_SECRET_KEY"))
|
||||
.setSignature("芋道源码");
|
||||
TencentSmsClient client = new TencentSmsClient(properties);
|
||||
// 准备参数
|
||||
Long sendLogId = System.currentTimeMillis();
|
||||
String mobile = "15601691323";
|
||||
String apiTemplateId = "358212";
|
||||
// 调用
|
||||
SmsSendRespDTO sendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, ListUtil.of(new KeyValue<>("code", "1024")));
|
||||
// 打印结果
|
||||
System.out.println(sendRespDTO);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testTencentSmsClient_getSmsTemplate() throws Throwable {
|
||||
String sdkAppId = "1400500458";
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(System.getenv("SMS_TENCENT_ACCESS_KEY") + " " + sdkAppId)
|
||||
.setApiSecret(System.getenv("SMS_TENCENT_SECRET_KEY"))
|
||||
.setSignature("芋道源码");
|
||||
TencentSmsClient client = new TencentSmsClient(properties);
|
||||
// 准备参数
|
||||
String apiTemplateId = "358212";
|
||||
// 调用
|
||||
SmsTemplateRespDTO template = client.getSmsTemplate(apiTemplateId);
|
||||
// 打印结果
|
||||
System.out.println(template);
|
||||
}
|
||||
|
||||
// ========== 华为云 ==========
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testHuaweiSmsClient_sendSms() throws Throwable {
|
||||
String sender = "x8824060312575";
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(System.getenv("SMS_HUAWEI_ACCESS_KEY") + " " + sender)
|
||||
.setApiSecret(System.getenv("SMS_HUAWEI_SECRET_KEY"))
|
||||
.setSignature("runpu");
|
||||
HuaweiSmsClient client = new HuaweiSmsClient(properties);
|
||||
// 准备参数
|
||||
Long sendLogId = System.currentTimeMillis();
|
||||
String mobile = "17321315478";
|
||||
String apiTemplateId = "3644cdab863546a3b718d488659a99ef";
|
||||
List<KeyValue<String, Object>> templateParams = ListUtil.of(new KeyValue<>("code", "1024"));
|
||||
// 调用
|
||||
SmsSendRespDTO smsSendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
|
||||
// 打印结果
|
||||
System.out.println(smsSendRespDTO);
|
||||
}
|
||||
|
||||
// ========== 七牛云 ==========
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testQiniuSmsClient_sendSms() throws Throwable {
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey("SMS_QINIU_ACCESS_KEY")
|
||||
.setApiSecret("SMS_QINIU_SECRET_KEY");
|
||||
QiniuSmsClient client = new QiniuSmsClient(properties);
|
||||
// 准备参数
|
||||
Long sendLogId = System.currentTimeMillis();
|
||||
String mobile = "17321315478";
|
||||
String apiTemplateId = "3644cdab863546a3b718d488659a99ef";
|
||||
List<KeyValue<String, Object>> templateParams = ListUtil.of(new KeyValue<>("code", "1122"));
|
||||
// 调用
|
||||
SmsSendRespDTO smsSendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
|
||||
// 打印结果
|
||||
System.out.println(smsSendRespDTO);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testQiniuSmsClient_getSmsTemplate() throws Throwable {
|
||||
SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey("SMS_QINIU_ACCESS_KEY")
|
||||
.setApiSecret("SMS_QINIU_SECRET_KEY");
|
||||
QiniuSmsClient client = new QiniuSmsClient(properties);
|
||||
// 准备参数
|
||||
String apiTemplateId = "3644cdab863546a3b718d488659a99ef";
|
||||
// 调用
|
||||
SmsTemplateRespDTO template = client.getSmsTemplate(apiTemplateId);
|
||||
// 打印结果
|
||||
System.out.println(template);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,218 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
/**
|
||||
* {@link TencentSmsClient} 的单元测试
|
||||
*
|
||||
* @author shiwp
|
||||
*/
|
||||
public class TencentSmsClientTest extends BaseMockitoUnitTest {
|
||||
|
||||
private final SmsChannelProperties properties = new SmsChannelProperties()
|
||||
.setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey,避免构建报错
|
||||
.setApiSecret(randomString()) // 随机一个 apiSecret,避免构建报错
|
||||
.setSignature("芋道源码");
|
||||
|
||||
@InjectMocks
|
||||
private TencentSmsClient smsClient = new TencentSmsClient(properties);
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_success() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\n" +
|
||||
" \"Response\": {\n" +
|
||||
" \"SendStatusSet\": [\n" +
|
||||
" {\n" +
|
||||
" \"SerialNo\": \"5000:1045710669157053657849499619\",\n" +
|
||||
" \"PhoneNumber\": \"+8618511122233\",\n" +
|
||||
" \"Fee\": 1,\n" +
|
||||
" \"SessionContext\": \"test\",\n" +
|
||||
" \"Code\": \"Ok\",\n" +
|
||||
" \"Message\": \"send success\",\n" +
|
||||
" \"IsoCode\": \"CN\"\n" +
|
||||
" },\n" +
|
||||
" ],\n" +
|
||||
" \"RequestId\": \"a0aabda6-cf91-4f3e-a81f-9198114a2279\"\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertTrue(result.getSuccess());
|
||||
assertEquals("5000:1045710669157053657849499619", result.getSerialNo());
|
||||
assertEquals("a0aabda6-cf91-4f3e-a81f-9198114a2279", result.getApiRequestId());
|
||||
assertEquals("send success", result.getApiMsg());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_fail_01() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\n" +
|
||||
" \"Response\": {\n" +
|
||||
" \"SendStatusSet\": [\n" +
|
||||
" {\n" +
|
||||
" \"SerialNo\": \"5000:1045710669157053657849499619\",\n" +
|
||||
" \"PhoneNumber\": \"+8618511122233\",\n" +
|
||||
" \"Fee\": 1,\n" +
|
||||
" \"SessionContext\": \"test\",\n" +
|
||||
" \"Code\": \"ERROR\",\n" +
|
||||
" \"Message\": \"send success\",\n" +
|
||||
" \"IsoCode\": \"CN\"\n" +
|
||||
" },\n" +
|
||||
" ],\n" +
|
||||
" \"RequestId\": \"a0aabda6-cf91-4f3e-a81f-9198114a2279\"\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertFalse(result.getSuccess());
|
||||
assertEquals("5000:1045710669157053657849499619", result.getSerialNo());
|
||||
assertEquals("a0aabda6-cf91-4f3e-a81f-9198114a2279", result.getApiRequestId());
|
||||
assertEquals("send success", result.getApiMsg());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendSms_fail_02() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
Long sendLogId = randomLongId();
|
||||
String mobile = randomString();
|
||||
String apiTemplateId = randomString();
|
||||
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
|
||||
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
|
||||
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{\"Response\":{\"Error\":{\"Code\":\"AuthFailure.SecretIdNotFound\",\"Message\":\"The SecretId is not found, please ensure that your SecretId is correct.\"},\"RequestId\":\"2a88f82a-261c-4ac6-9fa9-c7d01aaa486a\"}}");
|
||||
|
||||
// 调用
|
||||
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile,
|
||||
apiTemplateId, templateParams);
|
||||
// 断言
|
||||
assertFalse(result.getSuccess());
|
||||
assertEquals("2a88f82a-261c-4ac6-9fa9-c7d01aaa486a", result.getApiRequestId());
|
||||
assertEquals("AuthFailure.SecretIdNotFound", result.getApiCode());
|
||||
assertEquals("The SecretId is not found, please ensure that your SecretId is correct.", result.getApiMsg());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSmsReceiveStatus() {
|
||||
// 准备参数
|
||||
String text = "[\n" +
|
||||
" {\n" +
|
||||
" \"user_receive_time\": \"2015-10-17 08:03:04\",\n" +
|
||||
" \"nationcode\": \"86\",\n" +
|
||||
" \"mobile\": \"13900000001\",\n" +
|
||||
" \"report_status\": \"SUCCESS\",\n" +
|
||||
" \"errmsg\": \"DELIVRD\",\n" +
|
||||
" \"description\": \"用户短信送达成功\",\n" +
|
||||
" \"sid\": \"12345\",\n" +
|
||||
" \"ext\": {\"logId\":\"67890\"}\n" +
|
||||
" }\n" +
|
||||
"]";
|
||||
|
||||
// 调用
|
||||
List<SmsReceiveRespDTO> statuses = smsClient.parseSmsReceiveStatus(text);
|
||||
// 断言
|
||||
assertEquals(1, statuses.size());
|
||||
assertTrue(statuses.get(0).getSuccess());
|
||||
assertEquals("DELIVRD", statuses.get(0).getErrorCode());
|
||||
assertEquals("13900000001", statuses.get(0).getMobile());
|
||||
assertEquals(LocalDateTime.of(2015, 10, 17, 8, 3, 4), statuses.get(0).getReceiveTime());
|
||||
assertEquals("12345", statuses.get(0).getSerialNo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplate() throws Throwable {
|
||||
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
|
||||
// 准备参数
|
||||
String apiTemplateId = "1122";
|
||||
|
||||
// mock 方法
|
||||
httpUtilsMockedStatic.when(() -> HttpUtils.post(anyString(), anyMap(), anyString()))
|
||||
.thenReturn("{ \"Response\": {\n" +
|
||||
" \"DescribeTemplateStatusSet\": [\n" +
|
||||
" {\n" +
|
||||
" \"TemplateName\": \"验证码\",\n" +
|
||||
" \"TemplateId\": 1122,\n" +
|
||||
" \"International\": 0,\n" +
|
||||
" \"ReviewReply\": \"审批备注\",\n" +
|
||||
" \"CreateTime\": 1617379200,\n" +
|
||||
" \"TemplateContent\": \"您的验证码是{1}\",\n" +
|
||||
" \"StatusCode\": 0\n" +
|
||||
" },\n" +
|
||||
" \n" +
|
||||
" ],\n" +
|
||||
" \"RequestId\": \"f36e4f00-605e-49b1-ad0d-bfaba81c7325\"\n" +
|
||||
" }}");
|
||||
|
||||
// 调用
|
||||
SmsTemplateRespDTO result = smsClient.getSmsTemplate(apiTemplateId);
|
||||
// 断言
|
||||
assertEquals("1122", result.getId());
|
||||
assertEquals("您的验证码是{1}", result.getContent());
|
||||
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getAuditStatus());
|
||||
assertEquals("审批备注", result.getAuditReason());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertSmsTemplateAuditStatus() {
|
||||
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus(0));
|
||||
assertEquals(SmsTemplateAuditStatusEnum.CHECKING.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus(1));
|
||||
assertEquals(SmsTemplateAuditStatusEnum.FAIL.getStatus(),
|
||||
smsClient.convertSmsTemplateAuditStatus(-1));
|
||||
assertThrows(IllegalArgumentException.class, () -> smsClient.convertSmsTemplateAuditStatus(3),
|
||||
"未知审核状态(3)");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,356 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.auth;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
|
||||
import cn.iocoder.yudao.module.system.service.member.MemberService;
|
||||
import cn.iocoder.yudao.module.system.service.oauth2.OAuth2TokenService;
|
||||
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import com.anji.captcha.model.common.ResponseModel;
|
||||
import com.anji.captcha.service.CaptchaService;
|
||||
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 javax.annotation.Resource;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
|
||||
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.randomPojo;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import(AdminAuthServiceImpl.class)
|
||||
public class AdminAuthServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private AdminAuthServiceImpl authService;
|
||||
|
||||
@MockBean
|
||||
private AdminUserService userService;
|
||||
@MockBean
|
||||
private CaptchaService captchaService;
|
||||
@MockBean
|
||||
private LoginLogService loginLogService;
|
||||
@MockBean
|
||||
private SmsCodeApi smsCodeApi;
|
||||
@MockBean
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
@MockBean
|
||||
private MemberService memberService;
|
||||
@MockBean
|
||||
private Validator validator;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
authService.setCaptchaEnable(true);
|
||||
// 注入一个 Validator 对象
|
||||
ReflectUtil.setFieldValue(authService, "validator",
|
||||
Validation.buildDefaultValidatorFactory().getValidator());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticate_success() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
// mock user 数据
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username)
|
||||
.setPassword(password).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
||||
// mock password 匹配
|
||||
when(userService.isPasswordMatch(eq(password), eq(user.getPassword()))).thenReturn(true);
|
||||
|
||||
// 调用
|
||||
AdminUserDO loginUser = authService.authenticate(username, password);
|
||||
// 校验
|
||||
assertPojoEquals(user, loginUser);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticate_userNotFound() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.authenticate(username, password),
|
||||
AUTH_LOGIN_BAD_CREDENTIALS);
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.BAD_CREDENTIALS.getResult())
|
||||
&& o.getUserId() == null)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticate_badCredentials() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
// mock user 数据
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username)
|
||||
.setPassword(password).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.authenticate(username, password),
|
||||
AUTH_LOGIN_BAD_CREDENTIALS);
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.BAD_CREDENTIALS.getResult())
|
||||
&& o.getUserId().equals(user.getId()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticate_userDisabled() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
// mock user 数据
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username)
|
||||
.setPassword(password).setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
||||
// mock password 匹配
|
||||
when(userService.isPasswordMatch(eq(password), eq(user.getPassword()))).thenReturn(true);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.authenticate(username, password),
|
||||
AUTH_LOGIN_USER_DISABLED);
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.USER_DISABLED.getResult())
|
||||
&& o.getUserId().equals(user.getId()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin_success() {
|
||||
// 准备参数
|
||||
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class, o ->
|
||||
o.setUsername("test_username").setPassword("test_password")
|
||||
.setSocialType(randomEle(SocialTypeEnum.values()).getType()));
|
||||
|
||||
// mock 验证码正确
|
||||
authService.setCaptchaEnable(false);
|
||||
// mock user 数据
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L).setUsername("test_username")
|
||||
.setPassword("test_password").setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(userService.getUserByUsername(eq("test_username"))).thenReturn(user);
|
||||
// mock password 匹配
|
||||
when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true);
|
||||
// mock 缓存登录用户到 Redis
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull()))
|
||||
.thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并校验
|
||||
AuthLoginRespVO loginRespVO = authService.login(reqVO);
|
||||
assertPojoEquals(accessTokenDO, loginRespVO);
|
||||
// 校验调用参数
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult())
|
||||
&& o.getUserId().equals(user.getId()))
|
||||
);
|
||||
verify(socialUserService).bindSocialUser(eq(new SocialUserBindReqDTO(
|
||||
user.getId(), UserTypeEnum.ADMIN.getValue(),
|
||||
reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSmsCode() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
Integer scene = SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene();
|
||||
AuthSmsSendReqVO reqVO = new AuthSmsSendReqVO(mobile, scene);
|
||||
// mock 方法(用户信息)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class);
|
||||
when(userService.getUserByMobile(eq(mobile))).thenReturn(user);
|
||||
|
||||
// 调用
|
||||
authService.sendSmsCode(reqVO);
|
||||
// 断言
|
||||
verify(smsCodeApi).sendSmsCode(argThat(sendReqDTO -> {
|
||||
assertEquals(mobile, sendReqDTO.getMobile());
|
||||
assertEquals(scene, sendReqDTO.getScene());
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmsLogin_success() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
String code = randomString();
|
||||
AuthSmsLoginReqVO reqVO = new AuthSmsLoginReqVO(mobile, code);
|
||||
// mock 方法(验证码)
|
||||
doNothing().when(smsCodeApi).useSmsCode((argThat(smsCodeUseReqDTO -> {
|
||||
assertEquals(mobile, smsCodeUseReqDTO.getMobile());
|
||||
assertEquals(code, smsCodeUseReqDTO.getCode());
|
||||
assertEquals(SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene(), smsCodeUseReqDTO.getScene());
|
||||
return true;
|
||||
})));
|
||||
// mock 方法(用户信息)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L));
|
||||
when(userService.getUserByMobile(eq(mobile))).thenReturn(user);
|
||||
// mock 缓存登录用户到 Redis
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull()))
|
||||
.thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
AuthLoginRespVO loginRespVO = authService.smsLogin(reqVO);
|
||||
assertPojoEquals(accessTokenDO, loginRespVO);
|
||||
// 断言调用
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_MOBILE.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult())
|
||||
&& o.getUserId().equals(user.getId()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSocialLogin_success() {
|
||||
// 准备参数
|
||||
AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class);
|
||||
// mock 方法(绑定的用户编号)
|
||||
Long userId = 1L;
|
||||
when(socialUserService.getSocialUserByCode(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()),
|
||||
eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), randomString(), randomString(), userId));
|
||||
// mock(用户)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId));
|
||||
when(userService.getUser(eq(userId))).thenReturn(user);
|
||||
// mock 缓存登录用户到 Redis
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq("default"), isNull()))
|
||||
.thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
AuthLoginRespVO loginRespVO = authService.socialLogin(reqVO);
|
||||
assertPojoEquals(accessTokenDO, loginRespVO);
|
||||
// 断言调用
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_SOCIAL.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult())
|
||||
&& o.getUserId().equals(user.getId()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCaptcha_successWithEnable() {
|
||||
// 准备参数
|
||||
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
||||
|
||||
// mock 验证通过
|
||||
when(captchaService.verification(argThat(captchaVO -> {
|
||||
assertEquals(reqVO.getCaptchaVerification(), captchaVO.getCaptchaVerification());
|
||||
return true;
|
||||
}))).thenReturn(ResponseModel.success());
|
||||
|
||||
// 调用,无需断言
|
||||
authService.validateCaptcha(reqVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateCaptcha_successWithDisable() {
|
||||
// 准备参数
|
||||
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
||||
|
||||
// mock 验证码关闭
|
||||
authService.setCaptchaEnable(false);
|
||||
|
||||
// 调用,无需断言
|
||||
authService.validateCaptcha(reqVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaptcha_fail() {
|
||||
// 准备参数
|
||||
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
||||
|
||||
// mock 验证通过
|
||||
when(captchaService.verification(argThat(captchaVO -> {
|
||||
assertEquals(reqVO.getCaptchaVerification(), captchaVO.getCaptchaVerification());
|
||||
return true;
|
||||
}))).thenReturn(ResponseModel.errorMsg("就是不对"));
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> authService.validateCaptcha(reqVO), AUTH_LOGIN_CAPTCHA_CODE_ERROR, "就是不对");
|
||||
// 校验调用参数
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.CAPTCHA_CODE_ERROR.getResult()))
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshToken() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.refreshAccessToken(eq(refreshToken), eq("default")))
|
||||
.thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
AuthLoginRespVO loginRespVO = authService.refreshToken(refreshToken);
|
||||
// 断言
|
||||
assertPojoEquals(accessTokenDO, loginRespVO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogout_success() {
|
||||
// 准备参数
|
||||
String token = randomString();
|
||||
// mock
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||
when(oauth2TokenService.removeAccessToken(eq(token))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用
|
||||
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
|
||||
// 校验调用参数
|
||||
verify(loginLogService).createLoginLog(
|
||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
|
||||
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
|
||||
);
|
||||
// 调用,并校验
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogout_fail() {
|
||||
// 准备参数
|
||||
String token = randomString();
|
||||
|
||||
// 调用
|
||||
authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
|
||||
// 校验调用参数
|
||||
verify(loginLogService, never()).createLoginLog(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link DeptServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author niudehua
|
||||
*/
|
||||
@Import(DeptServiceImpl.class)
|
||||
public class DeptServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private DeptServiceImpl deptService;
|
||||
@Resource
|
||||
private DeptMapper deptMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateDept() {
|
||||
// 准备参数
|
||||
DeptSaveReqVO reqVO = randomPojo(DeptSaveReqVO.class, o -> {
|
||||
o.setId(null); // 防止 id 被设置
|
||||
o.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
Long deptId = deptService.createDept(reqVO);
|
||||
// 断言
|
||||
assertNotNull(deptId);
|
||||
// 校验记录的属性是否正确
|
||||
DeptDO deptDO = deptMapper.selectById(deptId);
|
||||
assertPojoEquals(reqVO, deptDO, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDept() {
|
||||
// mock 数据
|
||||
DeptDO dbDeptDO = randomPojo(DeptDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
DeptSaveReqVO reqVO = randomPojo(DeptSaveReqVO.class, o -> {
|
||||
// 设置更新的 ID
|
||||
o.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||
o.setId(dbDeptDO.getId());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
deptService.updateDept(reqVO);
|
||||
// 校验是否更新正确
|
||||
DeptDO deptDO = deptMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, deptDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDept_success() {
|
||||
// mock 数据
|
||||
DeptDO dbDeptDO = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(dbDeptDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDeptDO.getId();
|
||||
|
||||
// 调用
|
||||
deptService.deleteDept(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(deptMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDept_exitsChildren() {
|
||||
// mock 数据
|
||||
DeptDO parentDept = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(parentDept);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
DeptDO childrenDeptDO = randomPojo(DeptDO.class, o -> {
|
||||
o.setParentId(parentDept.getId());
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// 插入子部门
|
||||
deptMapper.insert(childrenDeptDO);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.deleteDept(parentDept.getId()), DEPT_EXITS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDeptExists_notFound() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.validateDeptExists(id), DEPT_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentDept_parentError() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.validateParentDept(id, id),
|
||||
DEPT_PARENT_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentDept_parentIsChild() {
|
||||
// mock 数据(父节点)
|
||||
DeptDO parentDept = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(parentDept);
|
||||
// mock 数据(子节点)
|
||||
DeptDO childDept = randomPojo(DeptDO.class, o -> {
|
||||
o.setParentId(parentDept.getId());
|
||||
});
|
||||
deptMapper.insert(childDept);
|
||||
|
||||
// 准备参数
|
||||
Long id = parentDept.getId();
|
||||
Long parentId = childDept.getId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.validateParentDept(id, parentId), DEPT_PARENT_IS_CHILD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateNameUnique_duplicate() {
|
||||
// mock 数据
|
||||
DeptDO deptDO = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(deptDO);
|
||||
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
Long parentId = deptDO.getParentId();
|
||||
String name = deptDO.getName();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.validateDeptNameUnique(id, parentId, name),
|
||||
DEPT_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDept() {
|
||||
// mock 数据
|
||||
DeptDO deptDO = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(deptDO);
|
||||
// 准备参数
|
||||
Long id = deptDO.getId();
|
||||
|
||||
// 调用
|
||||
DeptDO dbDept = deptService.getDept(id);
|
||||
// 断言
|
||||
assertEquals(deptDO, dbDept);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptList_ids() {
|
||||
// mock 数据
|
||||
DeptDO deptDO01 = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(deptDO01);
|
||||
DeptDO deptDO02 = randomPojo(DeptDO.class);
|
||||
deptMapper.insert(deptDO02);
|
||||
// 准备参数
|
||||
List<Long> ids = Arrays.asList(deptDO01.getId(), deptDO02.getId());
|
||||
|
||||
// 调用
|
||||
List<DeptDO> deptDOList = deptService.getDeptList(ids);
|
||||
// 断言
|
||||
assertEquals(2, deptDOList.size());
|
||||
assertEquals(deptDO01, deptDOList.get(0));
|
||||
assertEquals(deptDO02, deptDOList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptList_reqVO() {
|
||||
// mock 数据
|
||||
DeptDO dept = randomPojo(DeptDO.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())));
|
||||
// 准备参数
|
||||
DeptListReqVO reqVO = new DeptListReqVO();
|
||||
reqVO.setName("开");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
List<DeptDO> sysDeptDOS = deptService.getDeptList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, sysDeptDOS.size());
|
||||
assertPojoEquals(dept, sysDeptDOS.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChildDeptList() {
|
||||
// mock 数据(1 级别子节点)
|
||||
DeptDO dept1 = randomPojo(DeptDO.class, o -> o.setName("1"));
|
||||
deptMapper.insert(dept1);
|
||||
DeptDO dept2 = randomPojo(DeptDO.class, o -> o.setName("2"));
|
||||
deptMapper.insert(dept2);
|
||||
// mock 数据(2 级子节点)
|
||||
DeptDO dept1a = randomPojo(DeptDO.class, o -> o.setName("1-a").setParentId(dept1.getId()));
|
||||
deptMapper.insert(dept1a);
|
||||
DeptDO dept2a = randomPojo(DeptDO.class, o -> o.setName("2-a").setParentId(dept2.getId()));
|
||||
deptMapper.insert(dept2a);
|
||||
// 准备参数
|
||||
Long id = dept1.getParentId();
|
||||
|
||||
// 调用
|
||||
List<DeptDO> result = deptService.getChildDeptList(id);
|
||||
// 断言
|
||||
assertEquals(result.size(), 2);
|
||||
assertPojoEquals(dept1, result.get(0));
|
||||
assertPojoEquals(dept1a, result.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChildDeptListFromCache() {
|
||||
// mock 数据(1 级别子节点)
|
||||
DeptDO dept1 = randomPojo(DeptDO.class, o -> o.setName("1"));
|
||||
deptMapper.insert(dept1);
|
||||
DeptDO dept2 = randomPojo(DeptDO.class, o -> o.setName("2"));
|
||||
deptMapper.insert(dept2);
|
||||
// mock 数据(2 级子节点)
|
||||
DeptDO dept1a = randomPojo(DeptDO.class, o -> o.setName("1-a").setParentId(dept1.getId()));
|
||||
deptMapper.insert(dept1a);
|
||||
DeptDO dept2a = randomPojo(DeptDO.class, o -> o.setName("2-a").setParentId(dept2.getId()));
|
||||
deptMapper.insert(dept2a);
|
||||
// 准备参数
|
||||
Long id = dept1.getParentId();
|
||||
|
||||
// 调用
|
||||
Set<Long> result = deptService.getChildDeptIdListFromCache(id);
|
||||
// 断言
|
||||
assertEquals(result.size(), 2);
|
||||
assertTrue(result.contains(dept1.getId()));
|
||||
assertTrue(result.contains(dept1a.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDeptList_success() {
|
||||
// mock 数据
|
||||
DeptDO deptDO = randomPojo(DeptDO.class).setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
deptMapper.insert(deptDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(deptDO.getId());
|
||||
|
||||
// 调用,无需断言
|
||||
deptService.validateDeptList(ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDeptList_notFound() {
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(randomLongId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.validateDeptList(ids), DEPT_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDeptList_notEnable() {
|
||||
// mock 数据
|
||||
DeptDO deptDO = randomPojo(DeptDO.class).setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
deptMapper.insert(deptDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(deptDO.getId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> deptService.validateDeptList(ids), DEPT_NOT_ENABLE, deptDO.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,248 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.dept;
|
||||
|
||||
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.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.PostMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link PostServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author niudehua
|
||||
*/
|
||||
@Import(PostServiceImpl.class)
|
||||
public class PostServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private PostServiceImpl postService;
|
||||
|
||||
@Resource
|
||||
private PostMapper postMapper;
|
||||
|
||||
@Test
|
||||
public void testCreatePost_success() {
|
||||
// 准备参数
|
||||
PostSaveReqVO reqVO = randomPojo(PostSaveReqVO.class,
|
||||
o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()))
|
||||
.setId(null); // 防止 id 被设置
|
||||
// 调用
|
||||
Long postId = postService.createPost(reqVO);
|
||||
|
||||
// 断言
|
||||
assertNotNull(postId);
|
||||
// 校验记录的属性是否正确
|
||||
PostDO post = postMapper.selectById(postId);
|
||||
assertPojoEquals(reqVO, post, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePost_success() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
PostSaveReqVO reqVO = randomPojo(PostSaveReqVO.class, o -> {
|
||||
// 设置更新的 ID
|
||||
o.setId(postDO.getId());
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
postService.updatePost(reqVO);
|
||||
// 校验是否更新正确
|
||||
PostDO post = postMapper.selectById(reqVO.getId());
|
||||
assertPojoEquals(reqVO, post);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeletePost_success() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);
|
||||
// 准备参数
|
||||
Long id = postDO.getId();
|
||||
|
||||
// 调用
|
||||
postService.deletePost(id);
|
||||
assertNull(postMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidatePost_notFoundForDelete() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> postService.deletePost(id), POST_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidatePost_nameDuplicateForCreate() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
PostSaveReqVO reqVO = randomPojo(PostSaveReqVO.class,
|
||||
// 模拟 name 重复
|
||||
o -> o.setName(postDO.getName()));
|
||||
assertServiceException(() -> postService.createPost(reqVO), POST_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidatePost_codeDuplicateForUpdate() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPostDO();
|
||||
postMapper.insert(postDO);
|
||||
// mock 数据:稍后模拟重复它的 code
|
||||
PostDO codePostDO = randomPostDO();
|
||||
postMapper.insert(codePostDO);
|
||||
// 准备参数
|
||||
PostSaveReqVO reqVO = randomPojo(PostSaveReqVO.class, o -> {
|
||||
// 设置更新的 ID
|
||||
o.setId(postDO.getId());
|
||||
// 模拟 code 重复
|
||||
o.setCode(codePostDO.getCode());
|
||||
});
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> postService.updatePost(reqVO), POST_CODE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPostPage() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPojo(PostDO.class, o -> {
|
||||
o.setName("码仔");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
postMapper.insert(postDO);
|
||||
// 测试 name 不匹配
|
||||
postMapper.insert(cloneIgnoreId(postDO, o -> o.setName("程序员")));
|
||||
// 测试 status 不匹配
|
||||
postMapper.insert(cloneIgnoreId(postDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
PostPageReqVO reqVO = new PostPageReqVO();
|
||||
reqVO.setName("码");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<PostDO> pageResult = postService.getPostPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(postDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPostList() {
|
||||
// mock 数据
|
||||
PostDO postDO01 = randomPojo(PostDO.class);
|
||||
postMapper.insert(postDO01);
|
||||
// 测试 id 不匹配
|
||||
PostDO postDO02 = randomPojo(PostDO.class);
|
||||
postMapper.insert(postDO02);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(postDO01.getId());
|
||||
|
||||
// 调用
|
||||
List<PostDO> list = postService.getPostList(ids);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(postDO01, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPostList_idsAndStatus() {
|
||||
// mock 数据
|
||||
PostDO postDO01 = randomPojo(PostDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
postMapper.insert(postDO01);
|
||||
// 测试 status 不匹配
|
||||
PostDO postDO02 = randomPojo(PostDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
postMapper.insert(postDO02);
|
||||
// 准备参数
|
||||
List<Long> ids = Arrays.asList(postDO01.getId(), postDO02.getId());
|
||||
|
||||
// 调用
|
||||
List<PostDO> list = postService.getPostList(ids, singletonList(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(postDO01, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPost() {
|
||||
// mock 数据
|
||||
PostDO dbPostDO = randomPostDO();
|
||||
postMapper.insert(dbPostDO);
|
||||
// 准备参数
|
||||
Long id = dbPostDO.getId();
|
||||
// 调用
|
||||
PostDO post = postService.getPost(id);
|
||||
// 断言
|
||||
assertNotNull(post);
|
||||
assertPojoEquals(dbPostDO, post);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidatePostList_success() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPostDO().setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
postMapper.insert(postDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(postDO.getId());
|
||||
|
||||
// 调用,无需断言
|
||||
postService.validatePostList(ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidatePostList_notFound() {
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(randomLongId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> postService.validatePostList(ids), POST_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidatePostList_notEnable() {
|
||||
// mock 数据
|
||||
PostDO postDO = randomPostDO().setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
postMapper.insert(postDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(postDO.getId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> postService.validatePostList(ids), POST_NOT_ENABLE,
|
||||
postDO.getName());
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private static PostDO randomPostDO(Consumer<PostDO>... consumers) {
|
||||
Consumer<PostDO> consumer = (o) -> {
|
||||
o.setStatus(randomCommonStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(PostDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
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.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
|
||||
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.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(DictDataServiceImpl.class)
|
||||
public class DictDataServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private DictDataServiceImpl dictDataService;
|
||||
|
||||
@Resource
|
||||
private DictDataMapper dictDataMapper;
|
||||
@MockBean
|
||||
private DictTypeService dictTypeService;
|
||||
|
||||
@Test
|
||||
public void testGetDictDataList() {
|
||||
// mock 数据
|
||||
DictDataDO dictDataDO01 = randomDictDataDO().setDictType("yunai").setSort(2)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
dictDataMapper.insert(dictDataDO01);
|
||||
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setSort(1)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
dictDataMapper.insert(dictDataDO02);
|
||||
DictDataDO dictDataDO03 = randomDictDataDO().setDictType("yunai").setSort(3)
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
dictDataMapper.insert(dictDataDO03);
|
||||
DictDataDO dictDataDO04 = randomDictDataDO().setDictType("yunai2").setSort(3)
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
dictDataMapper.insert(dictDataDO04);
|
||||
// 准备参数
|
||||
Integer status = CommonStatusEnum.ENABLE.getStatus();
|
||||
String dictType = "yunai";
|
||||
|
||||
// 调用
|
||||
List<DictDataDO> dictDataDOList = dictDataService.getDictDataList(status, dictType);
|
||||
// 断言
|
||||
assertEquals(2, dictDataDOList.size());
|
||||
assertPojoEquals(dictDataDO02, dictDataDOList.get(0));
|
||||
assertPojoEquals(dictDataDO01, dictDataDOList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictDataPage() {
|
||||
// mock 数据
|
||||
DictDataDO dbDictData = randomPojo(DictDataDO.class, o -> { // 等会查询到
|
||||
o.setLabel("芋艿");
|
||||
o.setDictType("yunai");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
dictDataMapper.insert(dbDictData);
|
||||
// 测试 label 不匹配
|
||||
dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setLabel("艿")));
|
||||
// 测试 dictType 不匹配
|
||||
dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setDictType("nai")));
|
||||
// 测试 status 不匹配
|
||||
dictDataMapper.insert(cloneIgnoreId(dbDictData, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
DictDataPageReqVO reqVO = new DictDataPageReqVO();
|
||||
reqVO.setLabel("芋");
|
||||
reqVO.setDictType("yunai");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<DictDataDO> pageResult = dictDataService.getDictDataPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbDictData, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictData() {
|
||||
// mock 数据
|
||||
DictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);
|
||||
// 准备参数
|
||||
Long id = dbDictData.getId();
|
||||
|
||||
// 调用
|
||||
DictDataDO dictData = dictDataService.getDictData(id);
|
||||
// 断言
|
||||
assertPojoEquals(dbDictData, dictData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDictData_success() {
|
||||
// 准备参数
|
||||
DictDataSaveReqVO reqVO = randomPojo(DictDataSaveReqVO.class,
|
||||
o -> o.setStatus(randomCommonStatus()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
// mock 方法
|
||||
when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
|
||||
|
||||
// 调用
|
||||
Long dictDataId = dictDataService.createDictData(reqVO);
|
||||
// 断言
|
||||
assertNotNull(dictDataId);
|
||||
// 校验记录的属性是否正确
|
||||
DictDataDO dictData = dictDataMapper.selectById(dictDataId);
|
||||
assertPojoEquals(reqVO, dictData, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDictData_success() {
|
||||
// mock 数据
|
||||
DictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
DictDataSaveReqVO reqVO = randomPojo(DictDataSaveReqVO.class, o -> {
|
||||
o.setId(dbDictData.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// mock 方法,字典类型
|
||||
when(dictTypeService.getDictType(eq(reqVO.getDictType()))).thenReturn(randomDictTypeDO(reqVO.getDictType()));
|
||||
|
||||
// 调用
|
||||
dictDataService.updateDictData(reqVO);
|
||||
// 校验是否更新正确
|
||||
DictDataDO dictData = dictDataMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, dictData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDictData_success() {
|
||||
// mock 数据
|
||||
DictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDictData.getId();
|
||||
|
||||
// 调用
|
||||
dictDataService.deleteDictData(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(dictDataMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataExists_success() {
|
||||
// mock 数据
|
||||
DictDataDO dbDictData = randomDictDataDO();
|
||||
dictDataMapper.insert(dbDictData);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用成功
|
||||
dictDataService.validateDictDataExists(dbDictData.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataExists_notExists() {
|
||||
assertServiceException(() -> dictDataService.validateDictDataExists(randomLongId()), DICT_DATA_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeExists_success() {
|
||||
// mock 方法,数据类型被禁用
|
||||
String type = randomString();
|
||||
when(dictTypeService.getDictType(eq(type))).thenReturn(randomDictTypeDO(type));
|
||||
|
||||
// 调用, 成功
|
||||
dictDataService.validateDictTypeExists(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeExists_notExists() {
|
||||
assertServiceException(() -> dictDataService.validateDictTypeExists(randomString()), DICT_TYPE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeExists_notEnable() {
|
||||
// mock 方法,数据类型被禁用
|
||||
String dictType = randomString();
|
||||
when(dictTypeService.getDictType(eq(dictType))).thenReturn(
|
||||
randomPojo(DictTypeDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> dictDataService.validateDictTypeExists(dictType), DICT_TYPE_NOT_ENABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataValueUnique_success() {
|
||||
// 调用,成功
|
||||
dictDataService.validateDictDataValueUnique(randomLongId(), randomString(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataValueUnique_valueDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String dictType = randomString();
|
||||
String value = randomString();
|
||||
// mock 数据
|
||||
dictDataMapper.insert(randomDictDataDO(o -> {
|
||||
o.setDictType(dictType);
|
||||
o.setValue(value);
|
||||
}));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictDataService.validateDictDataValueUnique(null, dictType, value),
|
||||
DICT_DATA_VALUE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataValueUnique_valueDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String dictType = randomString();
|
||||
String value = randomString();
|
||||
// mock 数据
|
||||
dictDataMapper.insert(randomDictDataDO(o -> {
|
||||
o.setDictType(dictType);
|
||||
o.setValue(value);
|
||||
}));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictDataService.validateDictDataValueUnique(id, dictType, value),
|
||||
DICT_DATA_VALUE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictDataCountByDictType() {
|
||||
// mock 数据
|
||||
dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("yunai")));
|
||||
dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("tudou")));
|
||||
dictDataMapper.insert(randomDictDataDO(o -> o.setDictType("yunai")));
|
||||
// 准备参数
|
||||
String dictType = "yunai";
|
||||
|
||||
// 调用
|
||||
long count = dictDataService.getDictDataCountByDictType(dictType);
|
||||
// 校验
|
||||
assertEquals(2L, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataList_success() {
|
||||
// mock 数据
|
||||
DictDataDO dictDataDO = randomDictDataDO().setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
dictDataMapper.insert(dictDataDO);
|
||||
// 准备参数
|
||||
String dictType = dictDataDO.getDictType();
|
||||
List<String> values = singletonList(dictDataDO.getValue());
|
||||
|
||||
// 调用,无需断言
|
||||
dictDataService.validateDictDataList(dictType, values);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataList_notFound() {
|
||||
// 准备参数
|
||||
String dictType = randomString();
|
||||
List<String> values = singletonList(randomString());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> dictDataService.validateDictDataList(dictType, values), DICT_DATA_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataList_notEnable() {
|
||||
// mock 数据
|
||||
DictDataDO dictDataDO = randomDictDataDO().setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
dictDataMapper.insert(dictDataDO);
|
||||
// 准备参数
|
||||
String dictType = dictDataDO.getDictType();
|
||||
List<String> values = singletonList(dictDataDO.getValue());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> dictDataService.validateDictDataList(dictType, values),
|
||||
DICT_DATA_NOT_ENABLE, dictDataDO.getLabel());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictData_dictType() {
|
||||
// mock 数据
|
||||
DictDataDO dictDataDO = randomDictDataDO().setDictType("yunai").setValue("1");
|
||||
dictDataMapper.insert(dictDataDO);
|
||||
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setValue("2");
|
||||
dictDataMapper.insert(dictDataDO02);
|
||||
// 准备参数
|
||||
String dictType = "yunai";
|
||||
String value = "1";
|
||||
|
||||
// 调用
|
||||
DictDataDO dbDictData = dictDataService.getDictData(dictType, value);
|
||||
// 断言
|
||||
assertEquals(dictDataDO, dbDictData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDictData() {
|
||||
// mock 数据
|
||||
DictDataDO dictDataDO = randomDictDataDO().setDictType("yunai").setLabel("1");
|
||||
dictDataMapper.insert(dictDataDO);
|
||||
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setLabel("2");
|
||||
dictDataMapper.insert(dictDataDO02);
|
||||
// 准备参数
|
||||
String dictType = "yunai";
|
||||
String label = "1";
|
||||
|
||||
// 调用
|
||||
DictDataDO dbDictData = dictDataService.parseDictData(dictType, label);
|
||||
// 断言
|
||||
assertEquals(dictDataDO, dbDictData);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static DictDataDO randomDictDataDO(Consumer<DictDataDO>... consumers) {
|
||||
Consumer<DictDataDO> consumer = (o) -> {
|
||||
o.setStatus(randomCommonStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(DictDataDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成一个有效的字典类型
|
||||
*
|
||||
* @param type 字典类型
|
||||
* @return DictTypeDO 对象
|
||||
*/
|
||||
private static DictTypeDO randomDictTypeDO(String type) {
|
||||
return randomPojo(DictTypeDO.class, o -> {
|
||||
o.setType(type);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 是开启
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
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.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictTypeMapper;
|
||||
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.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(DictTypeServiceImpl.class)
|
||||
public class DictTypeServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private DictTypeServiceImpl dictTypeService;
|
||||
|
||||
@Resource
|
||||
private DictTypeMapper dictTypeMapper;
|
||||
@MockBean
|
||||
private DictDataService dictDataService;
|
||||
|
||||
@Test
|
||||
public void testGetDictTypePage() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomPojo(DictTypeDO.class, o -> { // 等会查询到
|
||||
o.setName("yunai");
|
||||
o.setType("芋艿");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2021, 1, 15));
|
||||
});
|
||||
dictTypeMapper.insert(dbDictType);
|
||||
// 测试 name 不匹配
|
||||
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setName("tudou")));
|
||||
// 测试 type 不匹配
|
||||
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setType("土豆")));
|
||||
// 测试 status 不匹配
|
||||
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
dictTypeMapper.insert(cloneIgnoreId(dbDictType, o -> o.setCreateTime(buildTime(2021, 1, 1))));
|
||||
// 准备参数
|
||||
DictTypePageReqVO reqVO = new DictTypePageReqVO();
|
||||
reqVO.setName("nai");
|
||||
reqVO.setType("艿");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2021, 1, 10, 2021, 1, 20));
|
||||
|
||||
// 调用
|
||||
PageResult<DictTypeDO> pageResult = dictTypeService.getDictTypePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbDictType, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictType_id() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);
|
||||
// 准备参数
|
||||
Long id = dbDictType.getId();
|
||||
|
||||
// 调用
|
||||
DictTypeDO dictType = dictTypeService.getDictType(id);
|
||||
// 断言
|
||||
assertNotNull(dictType);
|
||||
assertPojoEquals(dbDictType, dictType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictType_type() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);
|
||||
// 准备参数
|
||||
String type = dbDictType.getType();
|
||||
|
||||
// 调用
|
||||
DictTypeDO dictType = dictTypeService.getDictType(type);
|
||||
// 断言
|
||||
assertNotNull(dictType);
|
||||
assertPojoEquals(dbDictType, dictType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDictType_success() {
|
||||
// 准备参数
|
||||
DictTypeSaveReqVO reqVO = randomPojo(DictTypeSaveReqVO.class,
|
||||
o -> o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()))
|
||||
.setId(null); // 避免 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long dictTypeId = dictTypeService.createDictType(reqVO);
|
||||
// 断言
|
||||
assertNotNull(dictTypeId);
|
||||
// 校验记录的属性是否正确
|
||||
DictTypeDO dictType = dictTypeMapper.selectById(dictTypeId);
|
||||
assertPojoEquals(reqVO, dictType, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateDictType_success() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
DictTypeSaveReqVO reqVO = randomPojo(DictTypeSaveReqVO.class, o -> {
|
||||
o.setId(dbDictType.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
dictTypeService.updateDictType(reqVO);
|
||||
// 校验是否更新正确
|
||||
DictTypeDO dictType = dictTypeMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, dictType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDictType_success() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDictType.getId();
|
||||
|
||||
// 调用
|
||||
dictTypeService.deleteDictType(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(dictTypeMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDictType_hasChildren() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbDictType.getId();
|
||||
// mock 方法
|
||||
when(dictDataService.getDictDataCountByDictType(eq(dbDictType.getType()))).thenReturn(1L);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> dictTypeService.deleteDictType(id), DICT_TYPE_HAS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDictTypeList() {
|
||||
// 准备参数
|
||||
DictTypeDO dictTypeDO01 = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dictTypeDO01);
|
||||
DictTypeDO dictTypeDO02 = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dictTypeDO02);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
List<DictTypeDO> dictTypeDOList = dictTypeService.getDictTypeList();
|
||||
// 断言
|
||||
assertEquals(2, dictTypeDOList.size());
|
||||
assertPojoEquals(dictTypeDO01, dictTypeDOList.get(0));
|
||||
assertPojoEquals(dictTypeDO02, dictTypeDOList.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataExists_success() {
|
||||
// mock 数据
|
||||
DictTypeDO dbDictType = randomDictTypeDO();
|
||||
dictTypeMapper.insert(dbDictType);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用成功
|
||||
dictTypeService.validateDictTypeExists(dbDictType.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataExists_notExists() {
|
||||
assertServiceException(() -> dictTypeService.validateDictTypeExists(randomLongId()), DICT_TYPE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeUnique_success() {
|
||||
// 调用,成功
|
||||
dictTypeService.validateDictTypeUnique(randomLongId(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeUnique_valueDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String type = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.validateDictTypeUnique(null, type),
|
||||
DICT_TYPE_TYPE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeUnique_valueDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String type = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setType(type)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.validateDictTypeUnique(id, type),
|
||||
DICT_TYPE_TYPE_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypNameUnique_success() {
|
||||
// 调用,成功
|
||||
dictTypeService.validateDictTypeNameUnique(randomLongId(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeNameUnique_nameDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String name = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(null, name),
|
||||
DICT_TYPE_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictTypeNameUnique_nameDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String name = randomString();
|
||||
// mock 数据
|
||||
dictTypeMapper.insert(randomDictTypeDO(o -> o.setName(name)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> dictTypeService.validateDictTypeNameUnique(id, name),
|
||||
DICT_TYPE_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static DictTypeDO randomDictTypeDO(Consumer<DictTypeDO>... consumers) {
|
||||
Consumer<DictTypeDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
};
|
||||
return randomPojo(DictTypeDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.logger;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.loginlog.LoginLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.logger.LoginLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.logger.LoginLogMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum.CAPTCHA_CODE_ERROR;
|
||||
import static cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum.SUCCESS;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@Import(LoginLogServiceImpl.class)
|
||||
public class LoginLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private LoginLogServiceImpl loginLogService;
|
||||
|
||||
@Resource
|
||||
private LoginLogMapper loginLogMapper;
|
||||
|
||||
@Test
|
||||
public void testGetLoginLogPage() {
|
||||
// mock 数据
|
||||
LoginLogDO loginLogDO = randomPojo(LoginLogDO.class, o -> {
|
||||
o.setUserIp("192.168.199.16");
|
||||
o.setUsername("wang");
|
||||
o.setResult(SUCCESS.getResult());
|
||||
o.setCreateTime(buildTime(2021, 3, 6));
|
||||
});
|
||||
loginLogMapper.insert(loginLogDO);
|
||||
// 测试 status 不匹配
|
||||
loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setResult(CAPTCHA_CODE_ERROR.getResult())));
|
||||
// 测试 ip 不匹配
|
||||
loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setUserIp("192.168.128.18")));
|
||||
// 测试 username 不匹配
|
||||
loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setUsername("yunai")));
|
||||
// 测试 createTime 不匹配
|
||||
loginLogMapper.insert(cloneIgnoreId(loginLogDO, o -> o.setCreateTime(buildTime(2021, 2, 6))));
|
||||
// 构造调用参数
|
||||
LoginLogPageReqVO reqVO = new LoginLogPageReqVO();
|
||||
reqVO.setUsername("wang");
|
||||
reqVO.setUserIp("192.168.199");
|
||||
reqVO.setStatus(true);
|
||||
reqVO.setCreateTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7));
|
||||
|
||||
// 调用
|
||||
PageResult<LoginLogDO> pageResult = loginLogService.getLoginLogPage(reqVO);
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(loginLogDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateLoginLog() {
|
||||
LoginLogCreateReqDTO reqDTO = randomPojo(LoginLogCreateReqDTO.class);
|
||||
|
||||
// 调用
|
||||
loginLogService.createLoginLog(reqDTO);
|
||||
// 断言
|
||||
LoginLogDO loginLogDO = loginLogMapper.selectOne(null);
|
||||
assertPojoEquals(reqDTO, loginLogDO);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.logger;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
|
||||
import cn.iocoder.yudao.framework.common.biz.system.logger.dto.OperateLogCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogPageReqDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.logger.OperateLogMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
@Import({OperateLogServiceImpl.class})
|
||||
public class OperateLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OperateLogService operateLogServiceImpl;
|
||||
|
||||
@Resource
|
||||
private OperateLogMapper operateLogMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateOperateLog() {
|
||||
OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class);
|
||||
|
||||
// 调研
|
||||
operateLogServiceImpl.createOperateLog(reqVO);
|
||||
// 断言
|
||||
OperateLogDO operateLogDO = operateLogMapper.selectOne(null);
|
||||
assertPojoEquals(reqVO, operateLogDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOperateLogPage_vo() {
|
||||
// 构造操作日志
|
||||
OperateLogDO operateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> {
|
||||
o.setUserId(2048L);
|
||||
o.setBizId(999L);
|
||||
o.setType("订单");
|
||||
o.setSubType("创建订单");
|
||||
o.setAction("修改编号为 1 的用户信息");
|
||||
o.setCreateTime(buildTime(2021, 3, 6));
|
||||
});
|
||||
operateLogMapper.insert(operateLogDO);
|
||||
// 测试 userId 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(1024L)));
|
||||
// 测试 bizId 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setBizId(888L)));
|
||||
// 测试 type 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType("退款")));
|
||||
// 测试 subType 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setSubType("创建退款")));
|
||||
// 测试 action 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setAction("修改编号为 1 退款信息")));
|
||||
// 测试 createTime 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setCreateTime(buildTime(2021, 2, 6))));
|
||||
|
||||
// 构造调用参数
|
||||
OperateLogPageReqVO reqVO = new OperateLogPageReqVO();
|
||||
reqVO.setUserId(2048L);
|
||||
reqVO.setBizId(999L);
|
||||
reqVO.setType("订");
|
||||
reqVO.setSubType("订单");
|
||||
reqVO.setAction("用户信息");
|
||||
reqVO.setCreateTime(buildBetweenTime(2021, 3, 5, 2021, 3, 7));
|
||||
|
||||
// 调用
|
||||
PageResult<OperateLogDO> pageResult = operateLogServiceImpl.getOperateLogPage(reqVO);
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(operateLogDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOperateLogPage_dto() {
|
||||
// 构造操作日志
|
||||
OperateLogDO operateLogDO = RandomUtils.randomPojo(OperateLogDO.class, o -> {
|
||||
o.setUserId(2048L);
|
||||
o.setBizId(999L);
|
||||
o.setType("订单");
|
||||
});
|
||||
operateLogMapper.insert(operateLogDO);
|
||||
// 测试 userId 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setUserId(1024L)));
|
||||
// 测试 bizId 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setBizId(888L)));
|
||||
// 测试 type 不匹配
|
||||
operateLogMapper.insert(cloneIgnoreId(operateLogDO, o -> o.setType("退款")));
|
||||
|
||||
// 构造调用参数
|
||||
OperateLogPageReqDTO reqDTO = new OperateLogPageReqDTO();
|
||||
reqDTO.setUserId(2048L);
|
||||
reqDTO.setBizId(999L);
|
||||
reqDTO.setType("订单");
|
||||
|
||||
// 调用
|
||||
PageResult<OperateLogDO> pageResult = operateLogServiceImpl.getOperateLogPage(reqDTO);
|
||||
// 断言,只查到了一条符合条件的
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(operateLogDO, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
|
||||
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.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link MailAccountServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(MailAccountServiceImpl.class)
|
||||
public class MailAccountServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private MailAccountServiceImpl mailAccountService;
|
||||
|
||||
@Resource
|
||||
private MailAccountMapper mailAccountMapper;
|
||||
|
||||
@MockBean
|
||||
private MailTemplateService mailTemplateService;
|
||||
|
||||
@Test
|
||||
public void testCreateMailAccount_success() {
|
||||
// 准备参数
|
||||
MailAccountSaveReqVO reqVO = randomPojo(MailAccountSaveReqVO.class, o -> o.setMail(randomEmail()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long mailAccountId = mailAccountService.createMailAccount(reqVO);
|
||||
// 断言
|
||||
assertNotNull(mailAccountId);
|
||||
// 校验记录的属性是否正确
|
||||
MailAccountDO mailAccount = mailAccountMapper.selectById(mailAccountId);
|
||||
assertPojoEquals(reqVO, mailAccount, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMailAccount_success() {
|
||||
// mock 数据
|
||||
MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
|
||||
mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
MailAccountSaveReqVO reqVO = randomPojo(MailAccountSaveReqVO.class, o -> {
|
||||
o.setId(dbMailAccount.getId()); // 设置更新的 ID
|
||||
o.setMail(randomEmail());
|
||||
});
|
||||
|
||||
// 调用
|
||||
mailAccountService.updateMailAccount(reqVO);
|
||||
// 校验是否更新正确
|
||||
MailAccountDO mailAccount = mailAccountMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, mailAccount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMailAccount_notExists() {
|
||||
// 准备参数
|
||||
MailAccountSaveReqVO reqVO = randomPojo(MailAccountSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> mailAccountService.updateMailAccount(reqVO), MAIL_ACCOUNT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMailAccount_success() {
|
||||
// mock 数据
|
||||
MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
|
||||
mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbMailAccount.getId();
|
||||
// mock 方法(无关联模版)
|
||||
when(mailTemplateService.getMailTemplateCountByAccountId(eq(id))).thenReturn(0L);
|
||||
|
||||
// 调用
|
||||
mailAccountService.deleteMailAccount(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(mailAccountMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailAccountFromCache() {
|
||||
// mock 数据
|
||||
MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
|
||||
mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbMailAccount.getId();
|
||||
|
||||
// 调用
|
||||
MailAccountDO mailAccount = mailAccountService.getMailAccountFromCache(id);
|
||||
// 断言
|
||||
assertPojoEquals(dbMailAccount, mailAccount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMailAccount_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> mailAccountService.deleteMailAccount(id), MAIL_ACCOUNT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailAccountPage() {
|
||||
// mock 数据
|
||||
MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class, o -> { // 等会查询到
|
||||
o.setMail("768@qq.com");
|
||||
o.setUsername("yunai");
|
||||
});
|
||||
mailAccountMapper.insert(dbMailAccount);
|
||||
// 测试 mail 不匹配
|
||||
mailAccountMapper.insert(cloneIgnoreId(dbMailAccount, o -> o.setMail("788@qq.com")));
|
||||
// 测试 username 不匹配
|
||||
mailAccountMapper.insert(cloneIgnoreId(dbMailAccount, o -> o.setUsername("tudou")));
|
||||
// 准备参数
|
||||
MailAccountPageReqVO reqVO = new MailAccountPageReqVO();
|
||||
reqVO.setMail("768");
|
||||
reqVO.setUsername("yu");
|
||||
|
||||
// 调用
|
||||
PageResult<MailAccountDO> pageResult = mailAccountService.getMailAccountPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbMailAccount, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailAccount() {
|
||||
// mock 数据
|
||||
MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
|
||||
mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbMailAccount.getId();
|
||||
|
||||
// 调用
|
||||
MailAccountDO mailAccount = mailAccountService.getMailAccount(id);
|
||||
// 断言
|
||||
assertPojoEquals(dbMailAccount, mailAccount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailAccountList() {
|
||||
// mock 数据
|
||||
MailAccountDO dbMailAccount01 = randomPojo(MailAccountDO.class);
|
||||
mailAccountMapper.insert(dbMailAccount01);
|
||||
MailAccountDO dbMailAccount02 = randomPojo(MailAccountDO.class);
|
||||
mailAccountMapper.insert(dbMailAccount02);
|
||||
// 准备参数
|
||||
|
||||
// 调用
|
||||
List<MailAccountDO> list = mailAccountService.getMailAccountList();
|
||||
// 断言
|
||||
assertEquals(2, list.size());
|
||||
assertPojoEquals(dbMailAccount01, list.get(0));
|
||||
assertPojoEquals(dbMailAccount02, list.get(1));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.mail;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.log.MailLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.mail.MailLogMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.mail.MailSendStatusEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
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.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link MailLogServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(MailLogServiceImpl.class)
|
||||
public class MailLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private MailLogServiceImpl mailLogService;
|
||||
|
||||
@Resource
|
||||
private MailLogMapper mailLogMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateMailLog() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String toMail = randomEmail();
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class);
|
||||
MailTemplateDO template = randomPojo(MailTemplateDO.class);
|
||||
String templateContent = randomString();
|
||||
Map<String, Object> templateParams = randomTemplateParams();
|
||||
Boolean isSend = true;
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
Long logId = mailLogService.createMailLog(userId, userType, toMail, account, template, templateContent, templateParams, isSend);
|
||||
// 断言
|
||||
MailLogDO log = mailLogMapper.selectById(logId);
|
||||
assertNotNull(log);
|
||||
assertEquals(MailSendStatusEnum.INIT.getStatus(), log.getSendStatus());
|
||||
assertEquals(userId, log.getUserId());
|
||||
assertEquals(userType, log.getUserType());
|
||||
assertEquals(toMail, log.getToMail());
|
||||
assertEquals(account.getId(), log.getAccountId());
|
||||
assertEquals(account.getMail(), log.getFromMail());
|
||||
assertEquals(template.getId(), log.getTemplateId());
|
||||
assertEquals(template.getCode(), log.getTemplateCode());
|
||||
assertEquals(template.getNickname(), log.getTemplateNickname());
|
||||
assertEquals(template.getTitle(), log.getTemplateTitle());
|
||||
assertEquals(templateContent, log.getTemplateContent());
|
||||
assertEquals(templateParams, log.getTemplateParams());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMailSendResult_success() {
|
||||
// mock 数据
|
||||
MailLogDO log = randomPojo(MailLogDO.class, o -> {
|
||||
o.setSendStatus(MailSendStatusEnum.INIT.getStatus());
|
||||
o.setSendTime(null).setSendMessageId(null).setSendException(null)
|
||||
.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
mailLogMapper.insert(log);
|
||||
// 准备参数
|
||||
Long logId = log.getId();
|
||||
String messageId = randomString();
|
||||
|
||||
// 调用
|
||||
mailLogService.updateMailSendResult(logId, messageId, null);
|
||||
// 断言
|
||||
MailLogDO dbLog = mailLogMapper.selectById(logId);
|
||||
assertEquals(MailSendStatusEnum.SUCCESS.getStatus(), dbLog.getSendStatus());
|
||||
assertNotNull(dbLog.getSendTime());
|
||||
assertEquals(messageId, dbLog.getSendMessageId());
|
||||
assertNull(dbLog.getSendException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMailSendResult_exception() {
|
||||
// mock 数据
|
||||
MailLogDO log = randomPojo(MailLogDO.class, o -> {
|
||||
o.setSendStatus(MailSendStatusEnum.INIT.getStatus());
|
||||
o.setSendTime(null).setSendMessageId(null).setSendException(null)
|
||||
.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
mailLogMapper.insert(log);
|
||||
// 准备参数
|
||||
Long logId = log.getId();
|
||||
Exception exception = new NullPointerException("测试异常");
|
||||
|
||||
// 调用
|
||||
mailLogService.updateMailSendResult(logId, null, exception);
|
||||
// 断言
|
||||
MailLogDO dbLog = mailLogMapper.selectById(logId);
|
||||
assertEquals(MailSendStatusEnum.FAILURE.getStatus(), dbLog.getSendStatus());
|
||||
assertNotNull(dbLog.getSendTime());
|
||||
assertNull(dbLog.getSendMessageId());
|
||||
assertEquals("NullPointerException: 测试异常", dbLog.getSendException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailLog() {
|
||||
// mock 数据
|
||||
MailLogDO dbMailLog = randomPojo(MailLogDO.class, o -> o.setTemplateParams(randomTemplateParams()));
|
||||
mailLogMapper.insert(dbMailLog);
|
||||
// 准备参数
|
||||
Long id = dbMailLog.getId();
|
||||
|
||||
// 调用
|
||||
MailLogDO mailLog = mailLogService.getMailLog(id);
|
||||
// 断言
|
||||
assertPojoEquals(dbMailLog, mailLog);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailLogPage() {
|
||||
// mock 数据
|
||||
MailLogDO dbMailLog = randomPojo(MailLogDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setToMail("768@qq.com");
|
||||
o.setAccountId(10L);
|
||||
o.setTemplateId(100L);
|
||||
o.setSendStatus(MailSendStatusEnum.INIT.getStatus());
|
||||
o.setSendTime(buildTime(2023, 2, 10));
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
mailLogMapper.insert(dbMailLog);
|
||||
// 测试 userId 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 toMail 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setToMail("788@.qq.com")));
|
||||
// 测试 accountId 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setAccountId(11L)));
|
||||
// 测试 templateId 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setTemplateId(101L)));
|
||||
// 测试 sendStatus 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setSendStatus(MailSendStatusEnum.SUCCESS.getStatus())));
|
||||
// 测试 sendTime 不匹配
|
||||
mailLogMapper.insert(cloneIgnoreId(dbMailLog, o -> o.setSendTime(buildTime(2023, 3, 10))));
|
||||
// 准备参数
|
||||
MailLogPageReqVO reqVO = new MailLogPageReqVO();
|
||||
reqVO.setUserId(1L);
|
||||
reqVO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
reqVO.setToMail("768");
|
||||
reqVO.setAccountId(10L);
|
||||
reqVO.setTemplateId(100L);
|
||||
reqVO.setSendStatus(MailSendStatusEnum.INIT.getStatus());
|
||||
reqVO.setSendTime((buildBetweenTime(2023, 2, 1, 2023, 2, 15)));
|
||||
|
||||
// 调用
|
||||
PageResult<MailLogDO> pageResult = mailLogService.getMailLogPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbMailLog, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
private static Map<String, Object> randomTemplateParams() {
|
||||
return MapUtil.<String, Object>builder().put(randomString(), randomString())
|
||||
.put(randomString(), randomString()).build();
|
||||
}
|
||||
}
|
||||
@@ -1,329 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.mail;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.extra.mail.*;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.mq.message.mail.MailSendMessage;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
|
||||
import cn.iocoder.yudao.module.system.service.member.MemberService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private MailSendServiceImpl mailSendService;
|
||||
|
||||
@Mock
|
||||
private AdminUserService adminUserService;
|
||||
@Mock
|
||||
private MemberService memberService;
|
||||
@Mock
|
||||
private MailAccountService mailAccountService;
|
||||
@Mock
|
||||
private MailTemplateService mailTemplateService;
|
||||
@Mock
|
||||
private MailLogService mailLogService;
|
||||
@Mock
|
||||
private MailProducer mailProducer;
|
||||
|
||||
/**
|
||||
* 用于快速测试你的邮箱账号是否正常
|
||||
*/
|
||||
@Test
|
||||
@Disabled
|
||||
public void testDemo() {
|
||||
MailAccount mailAccount = new MailAccount()
|
||||
// .setFrom("奥特曼 <ydym_test@163.com>")
|
||||
.setFrom("ydym_test@163.com") // 邮箱地址
|
||||
.setHost("smtp.163.com").setPort(465).setSslEnable(true) // SMTP 服务器
|
||||
.setAuth(true).setUser("ydym_test@163.com").setPass("WBZTEINMIFVRYSOE"); // 登录账号密码
|
||||
String messageId = MailUtil.send(mailAccount, "7685413@qq.com", "主题", "内容", false);
|
||||
System.out.println("发送结果:" + messageId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSingleMailToAdmin() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
String templateCode = RandomUtils.randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock adminUserService 的方法
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300"));
|
||||
when(adminUserService.getUser(eq(userId))).thenReturn(user);
|
||||
|
||||
// mock MailTemplateService 的方法
|
||||
MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String title = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
|
||||
.thenReturn(title);
|
||||
String content = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock MailAccountService 的方法
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class);
|
||||
when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
|
||||
// mock MailLogService 的方法
|
||||
Long mailLogId = randomLongId();
|
||||
when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(user.getEmail()),
|
||||
eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMailToAdmin(null, userId, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(user.getEmail()),
|
||||
eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSingleMailToMember() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
String templateCode = RandomUtils.randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock memberService 的方法
|
||||
String mail = randomEmail();
|
||||
when(memberService.getMemberUserEmail(eq(userId))).thenReturn(mail);
|
||||
|
||||
// mock MailTemplateService 的方法
|
||||
MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String title = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
|
||||
.thenReturn(title);
|
||||
String content = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock MailAccountService 的方法
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class);
|
||||
when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
|
||||
// mock MailLogService 的方法
|
||||
Long mailLogId = randomLongId();
|
||||
when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(mail),
|
||||
eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMailToMember(null, userId, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail),
|
||||
eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成功,当短信模板开启时
|
||||
*/
|
||||
@Test
|
||||
public void testSendSingleMail_successWhenMailTemplateEnable() {
|
||||
// 准备参数
|
||||
String mail = randomEmail();
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String templateCode = RandomUtils.randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock MailTemplateService 的方法
|
||||
MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String title = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
|
||||
.thenReturn(title);
|
||||
String content = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock MailAccountService 的方法
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class);
|
||||
when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
|
||||
// mock MailLogService 的方法
|
||||
Long mailLogId = randomLongId();
|
||||
when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail),
|
||||
eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail),
|
||||
eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成功,当短信模板关闭时
|
||||
*/
|
||||
@Test
|
||||
public void testSendSingleMail_successWhenSmsTemplateDisable() {
|
||||
// 准备参数
|
||||
String mail = randomEmail();
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String templateCode = RandomUtils.randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock MailTemplateService 的方法
|
||||
MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String title = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
|
||||
.thenReturn(title);
|
||||
String content = RandomUtils.randomString();
|
||||
when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock MailAccountService 的方法
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class);
|
||||
when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
|
||||
// mock MailLogService 的方法
|
||||
Long mailLogId = randomLongId();
|
||||
when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail),
|
||||
eq(account), eq(template), eq(content), eq(templateParams), eq(false))).thenReturn(mailLogId);
|
||||
|
||||
// 调用
|
||||
Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(mailLogId, resultMailLogId);
|
||||
// 断言调用
|
||||
verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), anyString(),
|
||||
anyLong(), anyString(), anyString(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMailTemplateValid_notExists() {
|
||||
// 准备参数
|
||||
String templateCode = RandomUtils.randomString();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> mailSendService.validateMailTemplate(templateCode),
|
||||
MAIL_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateTemplateParams_paramMiss() {
|
||||
// 准备参数
|
||||
MailTemplateDO template = randomPojo(MailTemplateDO.class,
|
||||
o -> o.setParams(Lists.newArrayList("code")));
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> mailSendService.validateTemplateParams(template, templateParams),
|
||||
MAIL_SEND_TEMPLATE_PARAM_MISS, "code");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMail_notExists() {
|
||||
// 准备参数
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> mailSendService.validateMail(null),
|
||||
MAIL_SEND_MAIL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendMail_success() {
|
||||
try (final MockedStatic<MailUtil> mailUtilMock = mockStatic(MailUtil.class)) {
|
||||
// 准备参数
|
||||
MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("芋艿"));
|
||||
// mock 方法(获得邮箱账号)
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com"));
|
||||
when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId())))
|
||||
.thenReturn(account);
|
||||
|
||||
// mock 方法(发送邮件)
|
||||
String messageId = randomString();
|
||||
mailUtilMock.when(() -> MailUtil.send(
|
||||
argThat(mailAccount -> {
|
||||
assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom());
|
||||
assertTrue(mailAccount.isAuth());
|
||||
assertEquals(account.getUsername(), mailAccount.getUser());
|
||||
assertEquals(account.getPassword(), mailAccount.getPass());
|
||||
assertEquals(account.getHost(), mailAccount.getHost());
|
||||
assertEquals(account.getPort(), mailAccount.getPort());
|
||||
assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
|
||||
return true;
|
||||
}), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true)))
|
||||
.thenReturn(messageId);
|
||||
|
||||
// 调用
|
||||
mailSendService.doSendMail(message);
|
||||
// 断言
|
||||
verify(mailLogService).updateMailSendResult(eq(message.getLogId()), eq(messageId), isNull());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoSendMail_exception() {
|
||||
try (MockedStatic<MailUtil> mailUtilMock = mockStatic(MailUtil.class)) {
|
||||
// 准备参数
|
||||
MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("芋艿"));
|
||||
// mock 方法(获得邮箱账号)
|
||||
MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com"));
|
||||
when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId())))
|
||||
.thenReturn(account);
|
||||
|
||||
// mock 方法(发送邮件)
|
||||
Exception e = new NullPointerException("啦啦啦");
|
||||
mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> {
|
||||
assertEquals("芋艿 <7685@qq.com>", mailAccount.getFrom());
|
||||
assertTrue(mailAccount.isAuth());
|
||||
assertEquals(account.getUsername(), mailAccount.getUser());
|
||||
assertEquals(account.getPassword(), mailAccount.getPass());
|
||||
assertEquals(account.getHost(), mailAccount.getHost());
|
||||
assertEquals(account.getPort(), mailAccount.getPort());
|
||||
assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
|
||||
return true;
|
||||
}), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true))).thenThrow(e);
|
||||
|
||||
// 调用
|
||||
mailSendService.doSendMail(message);
|
||||
// 断言
|
||||
verify(mailLogService).updateMailSendResult(eq(message.getLogId()), isNull(), same(e));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,215 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.mail;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplateSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.mail.vo.template.MailTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.mail.MailTemplateMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_TEMPLATE_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link MailTemplateServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(MailTemplateServiceImpl.class)
|
||||
public class MailTemplateServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private MailTemplateServiceImpl mailTemplateService;
|
||||
|
||||
@Resource
|
||||
private MailTemplateMapper mailTemplateMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateMailTemplate_success() {
|
||||
// 准备参数
|
||||
MailTemplateSaveReqVO reqVO = randomPojo(MailTemplateSaveReqVO.class)
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long mailTemplateId = mailTemplateService.createMailTemplate(reqVO);
|
||||
// 断言
|
||||
assertNotNull(mailTemplateId);
|
||||
// 校验记录的属性是否正确
|
||||
MailTemplateDO mailTemplate = mailTemplateMapper.selectById(mailTemplateId);
|
||||
assertPojoEquals(reqVO, mailTemplate, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMailTemplate_success() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
MailTemplateSaveReqVO reqVO = randomPojo(MailTemplateSaveReqVO.class, o -> {
|
||||
o.setId(dbMailTemplate.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用
|
||||
mailTemplateService.updateMailTemplate(reqVO);
|
||||
// 校验是否更新正确
|
||||
MailTemplateDO mailTemplate = mailTemplateMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, mailTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMailTemplate_notExists() {
|
||||
// 准备参数
|
||||
MailTemplateSaveReqVO reqVO = randomPojo(MailTemplateSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> mailTemplateService.updateMailTemplate(reqVO), MAIL_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMailTemplate_success() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbMailTemplate.getId();
|
||||
|
||||
// 调用
|
||||
mailTemplateService.deleteMailTemplate(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(mailTemplateMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMailTemplate_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> mailTemplateService.deleteMailTemplate(id), MAIL_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailTemplatePage() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class, o -> { // 等会查询到
|
||||
o.setName("源码");
|
||||
o.setCode("test_01");
|
||||
o.setAccountId(1L);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2023, 2, 3));
|
||||
});
|
||||
mailTemplateMapper.insert(dbMailTemplate);
|
||||
// 测试 name 不匹配
|
||||
mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setName("芋道")));
|
||||
// 测试 code 不匹配
|
||||
mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setCode("test_02")));
|
||||
// 测试 accountId 不匹配
|
||||
mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setAccountId(2L)));
|
||||
// 测试 status 不匹配
|
||||
mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setCreateTime(buildTime(2023, 1, 5))));
|
||||
// 准备参数
|
||||
MailTemplatePageReqVO reqVO = new MailTemplatePageReqVO();
|
||||
reqVO.setName("源");
|
||||
reqVO.setCode("est_01");
|
||||
reqVO.setAccountId(1L);
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 5));
|
||||
|
||||
// 调用
|
||||
PageResult<MailTemplateDO> pageResult = mailTemplateService.getMailTemplatePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbMailTemplate, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailTemplateList() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate01 = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate01);
|
||||
MailTemplateDO dbMailTemplate02 = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate02);
|
||||
|
||||
// 调用
|
||||
List<MailTemplateDO> list = mailTemplateService.getMailTemplateList();
|
||||
// 断言
|
||||
assertEquals(2, list.size());
|
||||
assertEquals(dbMailTemplate01, list.get(0));
|
||||
assertEquals(dbMailTemplate02, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailTemplate() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate);
|
||||
// 准备参数
|
||||
Long id = dbMailTemplate.getId();
|
||||
|
||||
// 调用
|
||||
MailTemplateDO mailTemplate = mailTemplateService.getMailTemplate(id);
|
||||
// 断言
|
||||
assertPojoEquals(dbMailTemplate, mailTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMailTemplateByCodeFromCache() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate);
|
||||
// 准备参数
|
||||
String code = dbMailTemplate.getCode();
|
||||
|
||||
// 调用
|
||||
MailTemplateDO mailTemplate = mailTemplateService.getMailTemplateByCodeFromCache(code);
|
||||
// 断言
|
||||
assertPojoEquals(dbMailTemplate, mailTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatMailTemplateContent() {
|
||||
// 准备参数
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("name", "小红");
|
||||
params.put("what", "饭");
|
||||
|
||||
// 调用,并断言
|
||||
assertEquals("小红,你好,饭吃了吗?",
|
||||
mailTemplateService.formatMailTemplateContent("{name},你好,{what}吃了吗?", params));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCountByAccountId() {
|
||||
// mock 数据
|
||||
MailTemplateDO dbMailTemplate = randomPojo(MailTemplateDO.class);
|
||||
mailTemplateMapper.insert(dbMailTemplate);
|
||||
// 测试 accountId 不匹配
|
||||
mailTemplateMapper.insert(cloneIgnoreId(dbMailTemplate, o -> o.setAccountId(2L)));
|
||||
// 准备参数
|
||||
Long accountId = dbMailTemplate.getAccountId();
|
||||
|
||||
// 调用
|
||||
long count = mailTemplateService.getMailTemplateCountByAccountId(accountId);
|
||||
// 断言
|
||||
assertEquals(1, count);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
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.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.notice.vo.NoticeSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.notice.NoticeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.notice.NoticeMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
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.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@Import(NoticeServiceImpl.class)
|
||||
class NoticeServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private NoticeServiceImpl noticeService;
|
||||
|
||||
@Resource
|
||||
private NoticeMapper noticeMapper;
|
||||
|
||||
@Test
|
||||
public void testGetNoticePage_success() {
|
||||
// 插入前置数据
|
||||
NoticeDO dbNotice = randomPojo(NoticeDO.class, o -> {
|
||||
o.setTitle("尼古拉斯赵四来啦!");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
noticeMapper.insert(dbNotice);
|
||||
// 测试 title 不匹配
|
||||
noticeMapper.insert(cloneIgnoreId(dbNotice, o -> o.setTitle("尼古拉斯凯奇也来啦!")));
|
||||
// 测试 status 不匹配
|
||||
noticeMapper.insert(cloneIgnoreId(dbNotice, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
NoticePageReqVO reqVO = new NoticePageReqVO();
|
||||
reqVO.setTitle("尼古拉斯赵四来啦!");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<NoticeDO> pageResult = noticeService.getNoticePage(reqVO);
|
||||
// 验证查询结果经过筛选
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbNotice, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotice_success() {
|
||||
// 插入前置数据
|
||||
NoticeDO dbNotice = randomPojo(NoticeDO.class);
|
||||
noticeMapper.insert(dbNotice);
|
||||
|
||||
// 查询
|
||||
NoticeDO notice = noticeService.getNotice(dbNotice.getId());
|
||||
|
||||
// 验证插入与读取对象是否一致
|
||||
assertNotNull(notice);
|
||||
assertPojoEquals(dbNotice, notice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNotice_success() {
|
||||
// 准备参数
|
||||
NoticeSaveReqVO reqVO = randomPojo(NoticeSaveReqVO.class)
|
||||
.setId(null); // 避免 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long noticeId = noticeService.createNotice(reqVO);
|
||||
// 校验插入属性是否正确
|
||||
assertNotNull(noticeId);
|
||||
NoticeDO notice = noticeMapper.selectById(noticeId);
|
||||
assertPojoEquals(reqVO, notice, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotice_success() {
|
||||
// 插入前置数据
|
||||
NoticeDO dbNoticeDO = randomPojo(NoticeDO.class);
|
||||
noticeMapper.insert(dbNoticeDO);
|
||||
|
||||
// 准备更新参数
|
||||
NoticeSaveReqVO reqVO = randomPojo(NoticeSaveReqVO.class, o -> o.setId(dbNoticeDO.getId()));
|
||||
|
||||
// 更新
|
||||
noticeService.updateNotice(reqVO);
|
||||
// 检验是否更新成功
|
||||
NoticeDO notice = noticeMapper.selectById(reqVO.getId());
|
||||
assertPojoEquals(reqVO, notice);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNotice_success() {
|
||||
// 插入前置数据
|
||||
NoticeDO dbNotice = randomPojo(NoticeDO.class);
|
||||
noticeMapper.insert(dbNotice);
|
||||
|
||||
// 删除
|
||||
noticeService.deleteNotice(dbNotice.getId());
|
||||
|
||||
// 检查是否删除成功
|
||||
assertNull(noticeMapper.selectById(dbNotice.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateNoticeExists_success() {
|
||||
// 插入前置数据
|
||||
NoticeDO dbNotice = randomPojo(NoticeDO.class);
|
||||
noticeMapper.insert(dbNotice);
|
||||
|
||||
// 成功调用
|
||||
noticeService.validateNoticeExists(dbNotice.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateNoticeExists_noExists() {
|
||||
assertServiceException(() ->
|
||||
noticeService.validateNoticeExists(randomLongId()), NOTICE_NOT_FOUND);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.notify;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyMessageMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link NotifyMessageServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(NotifyMessageServiceImpl.class)
|
||||
public class NotifyMessageServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private NotifyMessageServiceImpl notifyMessageService;
|
||||
|
||||
@Resource
|
||||
private NotifyMessageMapper notifyMessageMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateNotifyMessage_success() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class);
|
||||
String templateContent = randomString();
|
||||
Map<String, Object> templateParams = randomTemplateParams();
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
Long messageId = notifyMessageService.createNotifyMessage(userId, userType,
|
||||
template, templateContent, templateParams);
|
||||
// 断言
|
||||
NotifyMessageDO message = notifyMessageMapper.selectById(messageId);
|
||||
assertNotNull(message);
|
||||
assertEquals(userId, message.getUserId());
|
||||
assertEquals(userType, message.getUserType());
|
||||
assertEquals(template.getId(), message.getTemplateId());
|
||||
assertEquals(template.getCode(), message.getTemplateCode());
|
||||
assertEquals(template.getType(), message.getTemplateType());
|
||||
assertEquals(template.getNickname(), message.getTemplateNickname());
|
||||
assertEquals(templateContent, message.getTemplateContent());
|
||||
assertEquals(templateParams, message.getTemplateParams());
|
||||
assertEquals(false, message.getReadStatus());
|
||||
assertNull(message.getReadTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotifyMessagePage() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setTemplateCode("test_01");
|
||||
o.setTemplateType(10);
|
||||
o.setCreateTime(buildTime(2022, 1, 2));
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 测试 userId 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 templateCode 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setTemplateCode("test_11")));
|
||||
// 测试 templateType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setTemplateType(20)));
|
||||
// 测试 createTime 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setCreateTime(buildTime(2022, 2, 1))));
|
||||
// 准备参数
|
||||
NotifyMessagePageReqVO reqVO = new NotifyMessagePageReqVO();
|
||||
reqVO.setUserId(1L);
|
||||
reqVO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
reqVO.setTemplateCode("est_01");
|
||||
reqVO.setTemplateType(10);
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 1, 1, 2022, 1, 10));
|
||||
|
||||
// 调用
|
||||
PageResult<NotifyMessageDO> pageResult = notifyMessageService.getNotifyMessagePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbNotifyMessage, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotifyMessage() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class,
|
||||
o -> o.setTemplateParams(randomTemplateParams()));
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 准备参数
|
||||
Long id = dbNotifyMessage.getId();
|
||||
|
||||
// 调用
|
||||
NotifyMessageDO notifyMessage = notifyMessageService.getNotifyMessage(id);
|
||||
assertPojoEquals(dbNotifyMessage, notifyMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMyNotifyMessagePage() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setReadStatus(true);
|
||||
o.setCreateTime(buildTime(2022, 1, 2));
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 测试 userId 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 readStatus 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(false)));
|
||||
// 测试 createTime 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setCreateTime(buildTime(2022, 2, 1))));
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
NotifyMessageMyPageReqVO reqVO = new NotifyMessageMyPageReqVO();
|
||||
reqVO.setReadStatus(true);
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 1, 1, 2022, 1, 10));
|
||||
|
||||
// 调用
|
||||
PageResult<NotifyMessageDO> pageResult = notifyMessageService.getMyMyNotifyMessagePage(reqVO, userId, userType);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbNotifyMessage, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnreadNotifyMessageList() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setReadStatus(false);
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 测试 userId 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 readStatus 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
Integer size = 10;
|
||||
|
||||
// 调用
|
||||
List<NotifyMessageDO> list = notifyMessageService.getUnreadNotifyMessageList(userId, userType, size);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbNotifyMessage, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUnreadNotifyMessageCount() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setReadStatus(false);
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 测试 userId 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 readStatus 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
|
||||
// 调用,并断言
|
||||
assertEquals(1, notifyMessageService.getUnreadNotifyMessageCount(userId, userType));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotifyMessageRead() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setReadStatus(false);
|
||||
o.setReadTime(null);
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 测试 userId 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 readStatus 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||
// 准备参数
|
||||
Collection<Long> ids = Arrays.asList(dbNotifyMessage.getId(), dbNotifyMessage.getId() + 1,
|
||||
dbNotifyMessage.getId() + 2, dbNotifyMessage.getId() + 3);
|
||||
Long userId = 1L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
|
||||
// 调用
|
||||
int updateCount = notifyMessageService.updateNotifyMessageRead(ids, userId, userType);
|
||||
// 断言
|
||||
assertEquals(1, updateCount);
|
||||
NotifyMessageDO notifyMessage = notifyMessageMapper.selectById(dbNotifyMessage.getId());
|
||||
assertTrue(notifyMessage.getReadStatus());
|
||||
assertNotNull(notifyMessage.getReadTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAllNotifyMessageRead() {
|
||||
// mock 数据
|
||||
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||
o.setUserId(1L);
|
||||
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||
o.setReadStatus(false);
|
||||
o.setReadTime(null);
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
});
|
||||
notifyMessageMapper.insert(dbNotifyMessage);
|
||||
// 测试 userId 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||
// 测试 userType 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||
// 测试 readStatus 不匹配
|
||||
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
|
||||
// 调用
|
||||
int updateCount = notifyMessageService.updateAllNotifyMessageRead(userId, userType);
|
||||
// 断言
|
||||
assertEquals(1, updateCount);
|
||||
NotifyMessageDO notifyMessage = notifyMessageMapper.selectById(dbNotifyMessage.getId());
|
||||
assertTrue(notifyMessage.getReadStatus());
|
||||
assertNotNull(notifyMessage.getReadTime());
|
||||
}
|
||||
|
||||
private static Map<String, Object> randomTemplateParams() {
|
||||
return MapUtil.<String, Object>builder().put(randomString(), randomString())
|
||||
.put(randomString(), randomString()).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.notify;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_SEND_TEMPLATE_PARAM_MISS;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class NotifySendServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private NotifySendServiceImpl notifySendService;
|
||||
|
||||
@Mock
|
||||
private NotifyTemplateService notifyTemplateService;
|
||||
@Mock
|
||||
private NotifyMessageService notifyMessageService;
|
||||
|
||||
@Test
|
||||
public void testSendSingleNotifyToAdmin() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock NotifyTemplateService 的方法
|
||||
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(notifyTemplateService.formatNotifyTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock NotifyMessageService 的方法
|
||||
Long messageId = randomLongId();
|
||||
when(notifyMessageService.createNotifyMessage(eq(userId), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(template), eq(content), eq(templateParams))).thenReturn(messageId);
|
||||
|
||||
// 调用
|
||||
Long resultMessageId = notifySendService.sendSingleNotifyToAdmin(userId, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(messageId, resultMessageId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSingleNotifyToMember() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock NotifyTemplateService 的方法
|
||||
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(notifyTemplateService.formatNotifyTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock NotifyMessageService 的方法
|
||||
Long messageId = randomLongId();
|
||||
when(notifyMessageService.createNotifyMessage(eq(userId), eq(UserTypeEnum.MEMBER.getValue()),
|
||||
eq(template), eq(content), eq(templateParams))).thenReturn(messageId);
|
||||
|
||||
// 调用
|
||||
Long resultMessageId = notifySendService.sendSingleNotifyToMember(userId, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(messageId, resultMessageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成功,当短信模板开启时
|
||||
*/
|
||||
@Test
|
||||
public void testSendSingleNotify_successWhenMailTemplateEnable() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock NotifyTemplateService 的方法
|
||||
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(notifyTemplateService.formatNotifyTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock NotifyMessageService 的方法
|
||||
Long messageId = randomLongId();
|
||||
when(notifyMessageService.createNotifyMessage(eq(userId), eq(userType),
|
||||
eq(template), eq(content), eq(templateParams))).thenReturn(messageId);
|
||||
|
||||
// 调用
|
||||
Long resultMessageId = notifySendService.sendSingleNotify(userId, userType, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(messageId, resultMessageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成功,当短信模板关闭时
|
||||
*/
|
||||
@Test
|
||||
public void testSendSingleMail_successWhenSmsTemplateDisable() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock NotifyTemplateService 的方法
|
||||
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
|
||||
// 调用
|
||||
Long resultMessageId = notifySendService.sendSingleNotify(userId, userType, templateCode, templateParams);
|
||||
// 断言
|
||||
assertNull(resultMessageId);
|
||||
verify(notifyTemplateService, never()).formatNotifyTemplateContent(anyString(), anyMap());
|
||||
verify(notifyMessageService, never()).createNotifyMessage(anyLong(), anyInt(), any(), anyString(), anyMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckMailTemplateValid_notExists() {
|
||||
// 准备参数
|
||||
String templateCode = randomString();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> notifySendService.validateNotifyTemplate(templateCode),
|
||||
NOTICE_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckTemplateParams_paramMiss() {
|
||||
// 准备参数
|
||||
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class,
|
||||
o -> o.setParams(Lists.newArrayList("code")));
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> notifySendService.validateTemplateParams(template, templateParams),
|
||||
NOTIFY_SEND_TEMPLATE_PARAM_MISS, "code");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBatchNotify() {
|
||||
// 准备参数
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
UnsupportedOperationException exception = Assertions.assertThrows(
|
||||
UnsupportedOperationException.class,
|
||||
() -> notifySendService.sendBatchNotify(null, null, null, null, null)
|
||||
);
|
||||
// 断言
|
||||
assertEquals("暂时不支持该操作,感兴趣可以实现该功能哟!", exception.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.notify;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyTemplateMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_TEMPLATE_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link NotifyTemplateServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(NotifyTemplateServiceImpl.class)
|
||||
public class NotifyTemplateServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private NotifyTemplateServiceImpl notifyTemplateService;
|
||||
|
||||
@Resource
|
||||
private NotifyTemplateMapper notifyTemplateMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateNotifyTemplate_success() {
|
||||
// 准备参数
|
||||
NotifyTemplateSaveReqVO reqVO = randomPojo(NotifyTemplateSaveReqVO.class,
|
||||
o -> o.setStatus(randomCommonStatus()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long notifyTemplateId = notifyTemplateService.createNotifyTemplate(reqVO);
|
||||
// 断言
|
||||
assertNotNull(notifyTemplateId);
|
||||
// 校验记录的属性是否正确
|
||||
NotifyTemplateDO notifyTemplate = notifyTemplateMapper.selectById(notifyTemplateId);
|
||||
assertPojoEquals(reqVO, notifyTemplate, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotifyTemplate_success() {
|
||||
// mock 数据
|
||||
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class);
|
||||
notifyTemplateMapper.insert(dbNotifyTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
NotifyTemplateSaveReqVO reqVO = randomPojo(NotifyTemplateSaveReqVO.class, o -> {
|
||||
o.setId(dbNotifyTemplate.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
|
||||
// 调用
|
||||
notifyTemplateService.updateNotifyTemplate(reqVO);
|
||||
// 校验是否更新正确
|
||||
NotifyTemplateDO notifyTemplate = notifyTemplateMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, notifyTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotifyTemplate_notExists() {
|
||||
// 准备参数
|
||||
NotifyTemplateSaveReqVO reqVO = randomPojo(NotifyTemplateSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> notifyTemplateService.updateNotifyTemplate(reqVO), NOTIFY_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNotifyTemplate_success() {
|
||||
// mock 数据
|
||||
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class);
|
||||
notifyTemplateMapper.insert(dbNotifyTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbNotifyTemplate.getId();
|
||||
|
||||
// 调用
|
||||
notifyTemplateService.deleteNotifyTemplate(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(notifyTemplateMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteNotifyTemplate_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> notifyTemplateService.deleteNotifyTemplate(id), NOTIFY_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotifyTemplatePage() {
|
||||
// mock 数据
|
||||
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class, o -> { // 等会查询到
|
||||
o.setName("芋头");
|
||||
o.setCode("test_01");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2022, 2, 3));
|
||||
});
|
||||
notifyTemplateMapper.insert(dbNotifyTemplate);
|
||||
// 测试 name 不匹配
|
||||
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setName("投")));
|
||||
// 测试 code 不匹配
|
||||
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setCode("test_02")));
|
||||
// 测试 status 不匹配
|
||||
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setCreateTime(buildTime(2022, 1, 5))));
|
||||
// 准备参数
|
||||
NotifyTemplatePageReqVO reqVO = new NotifyTemplatePageReqVO();
|
||||
reqVO.setName("芋");
|
||||
reqVO.setCode("est_01");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 5));
|
||||
|
||||
// 调用
|
||||
PageResult<NotifyTemplateDO> pageResult = notifyTemplateService.getNotifyTemplatePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbNotifyTemplate, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotifyTemplate() {
|
||||
// mock 数据
|
||||
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class);
|
||||
notifyTemplateMapper.insert(dbNotifyTemplate);
|
||||
// 准备参数
|
||||
Long id = dbNotifyTemplate.getId();
|
||||
|
||||
// 调用
|
||||
NotifyTemplateDO notifyTemplate = notifyTemplateService.getNotifyTemplate(id);
|
||||
// 断言
|
||||
assertPojoEquals(dbNotifyTemplate, notifyTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNotifyTemplateByCodeFromCache() {
|
||||
// mock 数据
|
||||
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class);
|
||||
notifyTemplateMapper.insert(dbNotifyTemplate);
|
||||
// 准备参数
|
||||
String code = dbNotifyTemplate.getCode();
|
||||
|
||||
// 调用
|
||||
NotifyTemplateDO notifyTemplate = notifyTemplateService.getNotifyTemplateByCodeFromCache(code);
|
||||
// 断言
|
||||
assertPojoEquals(dbNotifyTemplate, notifyTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatNotifyTemplateContent() {
|
||||
// 准备参数
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("name", "小红");
|
||||
params.put("what", "饭");
|
||||
|
||||
// 调用,并断言
|
||||
assertEquals("小红,你好,饭吃了吗?",
|
||||
notifyTemplateService.formatNotifyTemplateContent("{name},你好,{what}吃了吗?", params));
|
||||
}
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ApproveDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ApproveMapper;
|
||||
import org.assertj.core.util.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.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.*;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||
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;
|
||||
|
||||
/**
|
||||
* {@link OAuth2ApproveServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(OAuth2ApproveServiceImpl.class)
|
||||
public class OAuth2ApproveServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2ApproveServiceImpl oauth2ApproveService;
|
||||
|
||||
@Resource
|
||||
private OAuth2ApproveMapper oauth2ApproveMapper;
|
||||
|
||||
@MockBean
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
|
||||
@Test
|
||||
public void checkForPreApproval_clientAutoApprove() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> requestedScopes = Lists.newArrayList("read");
|
||||
// mock 方法
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId)))
|
||||
.thenReturn(randomPojo(OAuth2ClientDO.class).setAutoApproveScopes(requestedScopes));
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.checkForPreApproval(userId, userType,
|
||||
clientId, requestedScopes);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals("read", result.get(0).getScope());
|
||||
assertTrue(result.get(0).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(0).getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForPreApproval_approve() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> requestedScopes = Lists.newArrayList("read");
|
||||
// mock 方法
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId)))
|
||||
.thenReturn(randomPojo(OAuth2ClientDO.class).setAutoApproveScopes(null));
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class).setUserId(userId)
|
||||
.setUserType(userType).setClientId(clientId).setScope("read")
|
||||
.setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 1L, ChronoUnit.DAYS)).setApproved(true); // 同意
|
||||
oauth2ApproveMapper.insert(approve);
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.checkForPreApproval(userId, userType,
|
||||
clientId, requestedScopes);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkForPreApproval_reject() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> requestedScopes = Lists.newArrayList("read");
|
||||
// mock 方法
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId)))
|
||||
.thenReturn(randomPojo(OAuth2ClientDO.class).setAutoApproveScopes(null));
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class).setUserId(userId)
|
||||
.setUserType(userType).setClientId(clientId).setScope("read")
|
||||
.setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 1L, ChronoUnit.DAYS)).setApproved(false); // 拒绝
|
||||
oauth2ApproveMapper.insert(approve);
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.checkForPreApproval(userId, userType,
|
||||
clientId, requestedScopes);
|
||||
// 断言
|
||||
assertFalse(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAfterApproval_none() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.updateAfterApproval(userId, userType, clientId,
|
||||
null);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(0, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAfterApproval_approved() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
Map<String, Boolean> requestedScopes = new LinkedHashMap<>(); // 有序,方便判断
|
||||
requestedScopes.put("read", true);
|
||||
requestedScopes.put("write", false);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.updateAfterApproval(userId, userType, clientId,
|
||||
requestedScopes);
|
||||
// 断言
|
||||
assertTrue(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(2, result.size());
|
||||
// read
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals("read", result.get(0).getScope());
|
||||
assertTrue(result.get(0).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(0).getExpiresTime()));
|
||||
// write
|
||||
assertEquals(userId, result.get(1).getUserId());
|
||||
assertEquals(userType, result.get(1).getUserType());
|
||||
assertEquals(clientId, result.get(1).getClientId());
|
||||
assertEquals("write", result.get(1).getScope());
|
||||
assertFalse(result.get(1).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(1).getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAfterApproval_reject() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
Map<String, Boolean> requestedScopes = new LinkedHashMap<>();
|
||||
requestedScopes.put("write", false);
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
boolean success = oauth2ApproveService.updateAfterApproval(userId, userType, clientId,
|
||||
requestedScopes);
|
||||
// 断言
|
||||
assertFalse(success);
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
// write
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals("write", result.get(0).getScope());
|
||||
assertFalse(result.get(0).getApproved());
|
||||
assertFalse(DateUtils.isExpired(result.get(0).getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApproveList() {
|
||||
// 准备参数
|
||||
Long userId = 10L;
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
String clientId = randomString();
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class).setUserId(userId)
|
||||
.setUserType(userType).setClientId(clientId).setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), 1L, ChronoUnit.DAYS));
|
||||
oauth2ApproveMapper.insert(approve); // 未过期
|
||||
oauth2ApproveMapper.insert(ObjectUtil.clone(approve).setId(null)
|
||||
.setExpiresTime(LocalDateTimeUtil.offset(LocalDateTime.now(), -1L, ChronoUnit.DAYS))); // 已过期
|
||||
|
||||
// 调用
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveService.getApproveList(userId, userType, clientId);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(approve, result.get(0), "expiresTime");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveApprove_insert() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
String scope = randomString();
|
||||
Boolean approved = randomBoolean();
|
||||
LocalDateTime expireTime = LocalDateTime.ofInstant(randomDay(1, 30).toInstant(), ZoneId.systemDefault());
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
oauth2ApproveService.saveApprove(userId, userType, clientId,
|
||||
scope, approved, expireTime);
|
||||
// 断言
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals(scope, result.get(0).getScope());
|
||||
assertEquals(approved, result.get(0).getApproved());
|
||||
assertEquals(expireTime, result.get(0).getExpiresTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveApprove_update() {
|
||||
// mock 数据
|
||||
OAuth2ApproveDO approve = randomPojo(OAuth2ApproveDO.class);
|
||||
oauth2ApproveMapper.insert(approve);
|
||||
// 准备参数
|
||||
Long userId = approve.getUserId();
|
||||
Integer userType = approve.getUserType();
|
||||
String clientId = approve.getClientId();
|
||||
String scope = approve.getScope();
|
||||
Boolean approved = randomBoolean();
|
||||
LocalDateTime expireTime = LocalDateTime.ofInstant(randomDay(1, 30).toInstant(), ZoneId.systemDefault());
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
oauth2ApproveService.saveApprove(userId, userType, clientId,
|
||||
scope, approved, expireTime);
|
||||
// 断言
|
||||
List<OAuth2ApproveDO> result = oauth2ApproveMapper.selectList();
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(approve.getId(), result.get(0).getId());
|
||||
assertEquals(userId, result.get(0).getUserId());
|
||||
assertEquals(userType, result.get(0).getUserType());
|
||||
assertEquals(clientId, result.get(0).getClientId());
|
||||
assertEquals(scope, result.get(0).getScope());
|
||||
assertEquals(approved, result.get(0).getApproved());
|
||||
assertEquals(expireTime, result.get(0).getExpiresTime());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2ClientPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.client.OAuth2ClientSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2ClientMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
|
||||
/**
|
||||
* {@link OAuth2ClientServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(OAuth2ClientServiceImpl.class)
|
||||
public class OAuth2ClientServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2ClientServiceImpl oauth2ClientService;
|
||||
|
||||
@Resource
|
||||
private OAuth2ClientMapper oauth2ClientMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateOAuth2Client_success() {
|
||||
// 准备参数
|
||||
OAuth2ClientSaveReqVO reqVO = randomPojo(OAuth2ClientSaveReqVO.class,
|
||||
o -> o.setLogo(randomString()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long oauth2ClientId = oauth2ClientService.createOAuth2Client(reqVO);
|
||||
// 断言
|
||||
assertNotNull(oauth2ClientId);
|
||||
// 校验记录的属性是否正确
|
||||
OAuth2ClientDO oAuth2Client = oauth2ClientMapper.selectById(oauth2ClientId);
|
||||
assertPojoEquals(reqVO, oAuth2Client, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateOAuth2Client_success() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(dbOAuth2Client);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
OAuth2ClientSaveReqVO reqVO = randomPojo(OAuth2ClientSaveReqVO.class, o -> {
|
||||
o.setId(dbOAuth2Client.getId()); // 设置更新的 ID
|
||||
o.setLogo(randomString());
|
||||
});
|
||||
|
||||
// 调用
|
||||
oauth2ClientService.updateOAuth2Client(reqVO);
|
||||
// 校验是否更新正确
|
||||
OAuth2ClientDO oAuth2Client = oauth2ClientMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, oAuth2Client);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateOAuth2Client_notExists() {
|
||||
// 准备参数
|
||||
OAuth2ClientSaveReqVO reqVO = randomPojo(OAuth2ClientSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> oauth2ClientService.updateOAuth2Client(reqVO), OAUTH2_CLIENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteOAuth2Client_success() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(dbOAuth2Client);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbOAuth2Client.getId();
|
||||
|
||||
// 调用
|
||||
oauth2ClientService.deleteOAuth2Client(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(oauth2ClientMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteOAuth2Client_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> oauth2ClientService.deleteOAuth2Client(id), OAUTH2_CLIENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateClientIdExists_withId() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou");
|
||||
oauth2ClientMapper.insert(client);
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String clientId = "tudou";
|
||||
|
||||
// 调用,不会报错
|
||||
assertServiceException(() -> oauth2ClientService.validateClientIdExists(id, clientId), OAUTH2_CLIENT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateClientIdExists_noId() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("tudou");
|
||||
oauth2ClientMapper.insert(client);
|
||||
// 准备参数
|
||||
String clientId = "tudou";
|
||||
|
||||
// 调用,不会报错
|
||||
assertServiceException(() -> oauth2ClientService.validateClientIdExists(null, clientId), OAUTH2_CLIENT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOAuth2Client() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(clientDO);
|
||||
// 准备参数
|
||||
Long id = clientDO.getId();
|
||||
|
||||
// 调用,并断言
|
||||
OAuth2ClientDO dbClientDO = oauth2ClientService.getOAuth2Client(id);
|
||||
assertPojoEquals(clientDO, dbClientDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOAuth2ClientFromCache() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class);
|
||||
oauth2ClientMapper.insert(clientDO);
|
||||
// 准备参数
|
||||
String clientId = clientDO.getClientId();
|
||||
|
||||
// 调用,并断言
|
||||
OAuth2ClientDO dbClientDO = oauth2ClientService.getOAuth2ClientFromCache(clientId);
|
||||
assertPojoEquals(clientDO, dbClientDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOAuth2ClientPage() {
|
||||
// mock 数据
|
||||
OAuth2ClientDO dbOAuth2Client = randomPojo(OAuth2ClientDO.class, o -> { // 等会查询到
|
||||
o.setName("潜龙");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
oauth2ClientMapper.insert(dbOAuth2Client);
|
||||
// 测试 name 不匹配
|
||||
oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setName("凤凰")));
|
||||
// 测试 status 不匹配
|
||||
oauth2ClientMapper.insert(cloneIgnoreId(dbOAuth2Client, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 准备参数
|
||||
OAuth2ClientPageReqVO reqVO = new OAuth2ClientPageReqVO();
|
||||
reqVO.setName("龙");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
PageResult<OAuth2ClientDO> pageResult = oauth2ClientService.getOAuth2ClientPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbOAuth2Client, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidOAuthClientFromCache() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(OAuth2ClientServiceImpl.class)))
|
||||
.thenReturn(oauth2ClientService);
|
||||
|
||||
// mock 方法
|
||||
OAuth2ClientDO client = randomPojo(OAuth2ClientDO.class).setClientId("default")
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
oauth2ClientMapper.insert(client);
|
||||
OAuth2ClientDO client02 = randomPojo(OAuth2ClientDO.class).setClientId("disable")
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
oauth2ClientMapper.insert(client02);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache(randomString(),
|
||||
null, null, null, null), OAUTH2_CLIENT_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("disable",
|
||||
null, null, null, null), OAUTH2_CLIENT_DISABLE);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
randomString(), null, null, null), OAUTH2_CLIENT_CLIENT_SECRET_ERROR);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, randomString(), null, null), OAUTH2_CLIENT_AUTHORIZED_GRANT_TYPE_NOT_EXISTS);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, Collections.singleton(randomString()), null), OAUTH2_CLIENT_SCOPE_OVER);
|
||||
assertServiceException(() -> oauth2ClientService.validOAuthClientFromCache("default",
|
||||
null, null, null, "test"), OAUTH2_CLIENT_REDIRECT_URI_NOT_MATCH, "test");
|
||||
// 成功调用(1:参数完整)
|
||||
OAuth2ClientDO result = oauth2ClientService.validOAuthClientFromCache(client.getClientId(), client.getSecret(),
|
||||
client.getAuthorizedGrantTypes().get(0), client.getScopes(), client.getRedirectUris().get(0));
|
||||
assertPojoEquals(client, result);
|
||||
// 成功调用(2:只有 clientId 参数)
|
||||
result = oauth2ClientService.validOAuthClientFromCache(client.getClientId());
|
||||
assertPojoEquals(client, result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2CodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2CodeMapper;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CODE_EXPIRE;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.OAUTH2_CODE_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link OAuth2CodeServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(OAuth2CodeServiceImpl.class)
|
||||
class OAuth2CodeServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2CodeServiceImpl oauth2CodeService;
|
||||
|
||||
@Resource
|
||||
private OAuth2CodeMapper oauth2CodeMapper;
|
||||
|
||||
@Test
|
||||
public void testCreateAuthorizationCode() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = RandomUtil.randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
|
||||
// 调用
|
||||
OAuth2CodeDO codeDO = oauth2CodeService.createAuthorizationCode(userId, userType, clientId,
|
||||
scopes, redirectUri, state);
|
||||
// 断言
|
||||
OAuth2CodeDO dbCodeDO = oauth2CodeMapper.selectByCode(codeDO.getCode());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(codeDO, dbCodeDO, "expiresTime", "createTime", "updateTime", "deleted");
|
||||
assertEquals(userId, codeDO.getUserId());
|
||||
assertEquals(userType, codeDO.getUserType());
|
||||
assertEquals(clientId, codeDO.getClientId());
|
||||
assertEquals(scopes, codeDO.getScopes());
|
||||
assertEquals(redirectUri, codeDO.getRedirectUri());
|
||||
assertEquals(state, codeDO.getState());
|
||||
assertFalse(DateUtils.isExpired(codeDO.getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeAuthorizationCode_null() {
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2CodeService.consumeAuthorizationCode(randomString()),
|
||||
OAUTH2_CODE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeAuthorizationCode_expired() {
|
||||
// 准备参数
|
||||
String code = "test_code";
|
||||
// mock 数据
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class).setCode(code)
|
||||
.setExpiresTime(LocalDateTime.now().minusDays(1));
|
||||
oauth2CodeMapper.insert(codeDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2CodeService.consumeAuthorizationCode(code),
|
||||
OAUTH2_CODE_EXPIRE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsumeAuthorizationCode_success() {
|
||||
// 准备参数
|
||||
String code = "test_code";
|
||||
// mock 数据
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class).setCode(code)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1));
|
||||
oauth2CodeMapper.insert(codeDO);
|
||||
|
||||
// 调用
|
||||
OAuth2CodeDO result = oauth2CodeService.consumeAuthorizationCode(code);
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(codeDO, result, "expiresTime");
|
||||
assertNull(oauth2CodeMapper.selectByCode(code));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2CodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.*;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2GrantServiceImpl} 的单元测试
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private OAuth2GrantServiceImpl oauth2GrantService;
|
||||
|
||||
@Mock
|
||||
private OAuth2TokenService oauth2TokenService;
|
||||
@Mock
|
||||
private OAuth2CodeService oauth2CodeService;
|
||||
@Mock
|
||||
private AdminAuthService adminAuthService;
|
||||
|
||||
@Test
|
||||
public void testGrantImplicit() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.createAccessToken(eq(userId), eq(userType),
|
||||
eq(clientId), eq(scopes))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantImplicit(
|
||||
userId, userType, clientId, scopes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantAuthorizationCodeForCode() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class);
|
||||
when(oauth2CodeService.createAuthorizationCode(eq(userId), eq(userType),
|
||||
eq(clientId), eq(scopes), eq(redirectUri), eq(state))).thenReturn(codeDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertEquals(codeDO.getCode(), oauth2GrantService.grantAuthorizationCodeForCode(userId, userType,
|
||||
clientId, scopes, redirectUri, state));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantAuthorizationCodeForAccessToken() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
String code = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
String redirectUri = randomString();
|
||||
String state = randomString();
|
||||
// mock 方法(code)
|
||||
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class, o -> {
|
||||
o.setClientId(clientId);
|
||||
o.setRedirectUri(redirectUri);
|
||||
o.setState(state);
|
||||
o.setScopes(scopes);
|
||||
});
|
||||
when(oauth2CodeService.consumeAuthorizationCode(eq(code))).thenReturn(codeDO);
|
||||
// mock 方法(创建令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.createAccessToken(eq(codeDO.getUserId()), eq(codeDO.getUserType()),
|
||||
eq(codeDO.getClientId()), eq(codeDO.getScopes()))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantAuthorizationCodeForAccessToken(
|
||||
clientId, code, redirectUri, state));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantPassword() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
String password = randomString();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
// mock 方法(认证)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class);
|
||||
when(adminAuthService.authenticate(eq(username), eq(password))).thenReturn(user);
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.createAccessToken(eq(user.getId()), eq(UserTypeEnum.ADMIN.getValue()),
|
||||
eq(clientId), eq(scopes))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantPassword(
|
||||
username, password, clientId, scopes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantRefreshToken() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.refreshAccessToken(eq(refreshToken), eq(clientId)))
|
||||
.thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(accessTokenDO, oauth2GrantService.grantRefreshToken(
|
||||
refreshToken, clientId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantClientCredentials() {
|
||||
assertThrows(UnsupportedOperationException.class,
|
||||
() -> oauth2GrantService.grantClientCredentials(randomString(), emptyList()),
|
||||
"暂时不支持 client_credentials 授权模式");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeToken_clientIdError() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
String accessToken = randomString();
|
||||
// mock 方法
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
|
||||
when(oauth2TokenService.getAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertFalse(oauth2GrantService.revokeToken(clientId, accessToken));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevokeToken_success() {
|
||||
// 准备参数
|
||||
String clientId = randomString();
|
||||
String accessToken = randomString();
|
||||
// mock 方法(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setClientId(clientId);
|
||||
when(oauth2TokenService.getAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
|
||||
// mock 方法(移除)
|
||||
when(oauth2TokenService.removeAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertTrue(oauth2GrantService.revokeToken(clientId, accessToken));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,329 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.oauth2;
|
||||
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.oauth2.vo.token.OAuth2AccessTokenPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2ClientDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2RefreshTokenDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2AccessTokenMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.oauth2.OAuth2RefreshTokenMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.redis.oauth2.OAuth2AccessTokenRedisDAO;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import org.assertj.core.util.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.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
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.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link OAuth2TokenServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import({OAuth2TokenServiceImpl.class, OAuth2AccessTokenRedisDAO.class})
|
||||
public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||
|
||||
@Resource
|
||||
private OAuth2TokenServiceImpl oauth2TokenService;
|
||||
|
||||
@Resource
|
||||
private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
|
||||
@Resource
|
||||
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
|
||||
|
||||
@Resource
|
||||
private OAuth2AccessTokenRedisDAO oauth2AccessTokenRedisDAO;
|
||||
|
||||
@MockBean
|
||||
private OAuth2ClientService oauth2ClientService;
|
||||
@MockBean
|
||||
private AdminUserService adminUserService;
|
||||
|
||||
@Test
|
||||
public void testCreateAccessToken() {
|
||||
TenantContextHolder.setTenantId(0L);
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||
String clientId = randomString();
|
||||
List<String> scopes = Lists.newArrayList("read", "write");
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId)
|
||||
.setAccessTokenValiditySeconds(30).setRefreshTokenValiditySeconds(60);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(用户)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class);
|
||||
when(adminUserService.getUser(userId)).thenReturn(user);
|
||||
|
||||
// 调用
|
||||
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, userType, clientId, scopes);
|
||||
// 断言访问令牌
|
||||
OAuth2AccessTokenDO dbAccessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(accessTokenDO, dbAccessTokenDO, "expiresTime", "createTime", "updateTime", "deleted");
|
||||
assertEquals(userId, accessTokenDO.getUserId());
|
||||
assertEquals(userType, accessTokenDO.getUserType());
|
||||
assertEquals(2, accessTokenDO.getUserInfo().size());
|
||||
assertEquals(user.getNickname(), accessTokenDO.getUserInfo().get("nickname"));
|
||||
assertEquals(user.getDeptId().toString(), accessTokenDO.getUserInfo().get("deptId"));
|
||||
assertEquals(clientId, accessTokenDO.getClientId());
|
||||
assertEquals(scopes, accessTokenDO.getScopes());
|
||||
assertFalse(DateUtils.isExpired(accessTokenDO.getExpiresTime()));
|
||||
// 断言访问令牌的缓存
|
||||
OAuth2AccessTokenDO redisAccessTokenDO = oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(accessTokenDO, redisAccessTokenDO, "expiresTime", "createTime", "updateTime", "deleted");
|
||||
// 断言刷新令牌
|
||||
OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectList().get(0);
|
||||
assertPojoEquals(accessTokenDO, refreshTokenDO, "id", "expiresTime", "createTime", "updateTime", "deleted");
|
||||
assertFalse(DateUtils.isExpired(refreshTokenDO.getExpiresTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_null() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
|
||||
new ErrorCode(400, "无效的刷新令牌"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_clientIdError() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(refreshToken).setClientId("error");
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
|
||||
new ErrorCode(400, "刷新令牌的客户端编号不正确"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_expired() {
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(refreshToken).setClientId(clientId)
|
||||
.setExpiresTime(LocalDateTime.now().minusDays(1));
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
|
||||
// 调用,并断言
|
||||
assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
|
||||
new ErrorCode(401, "刷新令牌已过期"));
|
||||
assertEquals(0, oauth2AccessTokenMapper.selectCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshAccessToken_success() {
|
||||
TenantContextHolder.setTenantId(0L);
|
||||
// 准备参数
|
||||
String refreshToken = randomString();
|
||||
String clientId = randomString();
|
||||
// mock 方法
|
||||
OAuth2ClientDO clientDO = randomPojo(OAuth2ClientDO.class).setClientId(clientId)
|
||||
.setAccessTokenValiditySeconds(30);
|
||||
when(oauth2ClientService.validOAuthClientFromCache(eq(clientId))).thenReturn(clientDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class, o ->
|
||||
o.setRefreshToken(refreshToken).setClientId(clientId)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1))
|
||||
.setUserType(UserTypeEnum.ADMIN.getValue())
|
||||
.setTenantId(TenantContextHolder.getTenantId()));
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setRefreshToken(refreshToken)
|
||||
.setUserType(refreshTokenDO.getUserType());
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
oauth2AccessTokenRedisDAO.set(accessTokenDO);
|
||||
// mock 数据(用户)
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class);
|
||||
when(adminUserService.getUser(refreshTokenDO.getUserId())).thenReturn(user);
|
||||
|
||||
// 调用
|
||||
OAuth2AccessTokenDO newAccessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, clientId);
|
||||
// 断言,老的访问令牌被删除
|
||||
assertNull(oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken()));
|
||||
assertNull(oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken()));
|
||||
// 断言,新的访问令牌
|
||||
OAuth2AccessTokenDO dbAccessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(newAccessTokenDO.getAccessToken());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(newAccessTokenDO, dbAccessTokenDO, "expiresTime", "createTime", "updateTime", "deleted");
|
||||
assertPojoEquals(newAccessTokenDO, refreshTokenDO, "id", "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
assertFalse(DateUtils.isExpired(newAccessTokenDO.getExpiresTime()));
|
||||
// 断言,新的访问令牌的缓存
|
||||
OAuth2AccessTokenDO redisAccessTokenDO = oauth2AccessTokenRedisDAO.get(newAccessTokenDO.getAccessToken());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(newAccessTokenDO, redisAccessTokenDO, "expiresTime", "createTime", "updateTime", "deleted");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAccessToken() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = accessTokenDO.getAccessToken();
|
||||
|
||||
// 调用
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken);
|
||||
// 断言
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(accessTokenDO, result, "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(accessTokenDO, oauth2AccessTokenRedisDAO.get(accessToken), "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_null() {
|
||||
// 调研,并断言
|
||||
assertServiceException(() -> oauth2TokenService.checkAccessToken(randomString()),
|
||||
new ErrorCode(401, "访问令牌不存在"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_expired() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTime.now().minusDays(1));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = accessTokenDO.getAccessToken();
|
||||
|
||||
// 调研,并断言
|
||||
assertServiceException(() -> oauth2TokenService.checkAccessToken(accessToken),
|
||||
new ErrorCode(401, "访问令牌已过期"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_refreshToken() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1));
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = refreshTokenDO.getRefreshToken();
|
||||
|
||||
// 调研,并断言
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken);
|
||||
// 断言
|
||||
assertPojoEquals(refreshTokenDO, result, "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckAccessToken_success() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// 准备参数
|
||||
String accessToken = accessTokenDO.getAccessToken();
|
||||
|
||||
// 调研,并断言
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.getAccessToken(accessToken);
|
||||
// 断言
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(accessTokenDO, result, "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAccessToken_null() {
|
||||
// 调用,并断言
|
||||
assertNull(oauth2TokenService.removeAccessToken(randomString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAccessToken_success() {
|
||||
// mock 数据(访问令牌)
|
||||
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class)
|
||||
.setExpiresTime(LocalDateTime.now().plusDays(1));
|
||||
oauth2AccessTokenMapper.insert(accessTokenDO);
|
||||
// mock 数据(刷新令牌)
|
||||
OAuth2RefreshTokenDO refreshTokenDO = randomPojo(OAuth2RefreshTokenDO.class)
|
||||
.setRefreshToken(accessTokenDO.getRefreshToken());
|
||||
oauth2RefreshTokenMapper.insert(refreshTokenDO);
|
||||
// 调用
|
||||
OAuth2AccessTokenDO result = oauth2TokenService.removeAccessToken(accessTokenDO.getAccessToken());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(accessTokenDO, result, "expiresTime", "createTime", "updateTime", "deleted",
|
||||
"creator", "updater");
|
||||
// 断言数据
|
||||
assertNull(oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getAccessToken()));
|
||||
assertNull(oauth2RefreshTokenMapper.selectByRefreshToken(accessTokenDO.getRefreshToken()));
|
||||
assertNull(oauth2AccessTokenRedisDAO.get(accessTokenDO.getAccessToken()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testGetAccessTokenPage() {
|
||||
// mock 数据
|
||||
OAuth2AccessTokenDO dbAccessToken = randomPojo(OAuth2AccessTokenDO.class, o -> { // 等会查询到
|
||||
o.setUserId(10L);
|
||||
o.setUserType(1);
|
||||
o.setClientId("test_client");
|
||||
o.setExpiresTime(LocalDateTime.now().plusDays(1));
|
||||
});
|
||||
oauth2AccessTokenMapper.insert(dbAccessToken);
|
||||
// 测试 userId 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setUserId(20L)));
|
||||
// 测试 userType 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setUserType(2)));
|
||||
// 测试 userType 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setClientId("it_client")));
|
||||
// 测试 expireTime 不匹配
|
||||
oauth2AccessTokenMapper.insert(cloneIgnoreId(dbAccessToken, o -> o.setExpiresTime(LocalDateTimeUtil.now())));
|
||||
// 准备参数
|
||||
OAuth2AccessTokenPageReqVO reqVO = new OAuth2AccessTokenPageReqVO();
|
||||
reqVO.setUserId(10L);
|
||||
reqVO.setUserType(1);
|
||||
reqVO.setClientId("test");
|
||||
|
||||
// 调用
|
||||
PageResult<OAuth2AccessTokenDO> pageResult = oauth2TokenService.getAccessTokenPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
// TODO @芋艿:expiresTime 被屏蔽,仅 win11 会复现,建议后续修复。
|
||||
assertPojoEquals(dbAccessToken, pageResult.getList().get(0), "expiresTime");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,331 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.permission;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
|
||||
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.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@Import(MenuServiceImpl.class)
|
||||
public class MenuServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private MenuServiceImpl menuService;
|
||||
|
||||
@Resource
|
||||
private MenuMapper menuMapper;
|
||||
|
||||
@MockBean
|
||||
private PermissionService permissionService;
|
||||
@MockBean
|
||||
private TenantService tenantService;
|
||||
|
||||
@Test
|
||||
public void testCreateMenu_success() {
|
||||
// mock 数据(构造父菜单)
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU,
|
||||
"parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
Long parentId = menuDO.getId();
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
|
||||
o.setParentId(parentId);
|
||||
o.setName("testSonName");
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
}).setId(null); // 防止 id 被赋值
|
||||
Long menuId = menuService.createMenu(reqVO);
|
||||
|
||||
// 校验记录的属性是否正确
|
||||
MenuDO dbMenu = menuMapper.selectById(menuId);
|
||||
assertPojoEquals(reqVO, dbMenu, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMenu_success() {
|
||||
// mock 数据(构造父子菜单)
|
||||
MenuDO sonMenuDO = createParentAndSonMenu();
|
||||
Long sonId = sonMenuDO.getId();
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class, o -> {
|
||||
o.setId(sonId);
|
||||
o.setName("testSonName"); // 修改名字
|
||||
o.setParentId(sonMenuDO.getParentId());
|
||||
o.setType(MenuTypeEnum.MENU.getType());
|
||||
});
|
||||
|
||||
// 调用
|
||||
menuService.updateMenu(reqVO);
|
||||
// 校验记录的属性是否正确
|
||||
MenuDO dbMenu = menuMapper.selectById(sonId);
|
||||
assertPojoEquals(reqVO, dbMenu);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateMenu_sonIdNotExist() {
|
||||
// 准备参数
|
||||
MenuSaveVO reqVO = randomPojo(MenuSaveVO.class);
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.updateMenu(reqVO), MENU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_success() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menuDO);
|
||||
// 准备参数
|
||||
Long id = menuDO.getId();
|
||||
|
||||
// 调用
|
||||
menuService.deleteMenu(id);
|
||||
// 断言
|
||||
MenuDO dbMenuDO = menuMapper.selectById(id);
|
||||
assertNull(dbMenuDO);
|
||||
verify(permissionService).processMenuDeleted(id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_menuNotExist() {
|
||||
assertServiceException(() -> menuService.deleteMenu(randomLongId()),
|
||||
MENU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMenu_existChildren() {
|
||||
// mock 数据(构造父子菜单)
|
||||
MenuDO sonMenu = createParentAndSonMenu();
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
|
||||
// 调用并断言异常
|
||||
assertServiceException(() -> menuService.deleteMenu(parentId), MENU_EXISTS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuList_all() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu101);
|
||||
// 准备参数
|
||||
|
||||
// 调用
|
||||
List<MenuDO> list = menuService.getMenuList();
|
||||
// 断言
|
||||
assertEquals(2, list.size());
|
||||
assertPojoEquals(menu100, list.get(0));
|
||||
assertPojoEquals(menu101, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuList() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = randomPojo(MenuDO.class, o -> o.setName("芋艿").setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
menuMapper.insert(menuDO);
|
||||
// 测试 status 不匹配
|
||||
menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 name 不匹配
|
||||
menuMapper.insert(cloneIgnoreId(menuDO, o -> o.setName("艿")));
|
||||
// 准备参数
|
||||
MenuListReqVO reqVO = new MenuListReqVO().setName("芋").setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
List<MenuDO> result = menuService.getMenuList(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(menuDO, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuListByTenant() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class, o -> o.setId(100L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class, o -> o.setId(101L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
menuMapper.insert(menu101);
|
||||
MenuDO menu102 = randomPojo(MenuDO.class, o -> o.setId(102L).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
menuMapper.insert(menu102);
|
||||
// mock 过滤菜单
|
||||
Set<Long> menuIds = asSet(100L, 101L);
|
||||
doNothing().when(tenantService).handleTenantMenu(argThat(handler -> {
|
||||
handler.handle(menuIds);
|
||||
return true;
|
||||
}));
|
||||
// 准备参数
|
||||
MenuListReqVO reqVO = new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
|
||||
// 调用
|
||||
List<MenuDO> result = menuService.getMenuListByTenant(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(menu100, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuIdListByPermissionFromCache() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu101);
|
||||
// 准备参数
|
||||
String permission = menu100.getPermission();
|
||||
|
||||
// 调用
|
||||
List<Long> ids = menuService.getMenuIdListByPermissionFromCache(permission);
|
||||
// 断言
|
||||
assertEquals(1, ids.size());
|
||||
assertEquals(menu100.getId(), ids.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuList_ids() {
|
||||
// mock 数据
|
||||
MenuDO menu100 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu100);
|
||||
MenuDO menu101 = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu101);
|
||||
// 准备参数
|
||||
Collection<Long> ids = Collections.singleton(menu100.getId());
|
||||
|
||||
// 调用
|
||||
List<MenuDO> list = menuService.getMenuList(ids);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(menu100, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenu() {
|
||||
// mock 数据
|
||||
MenuDO menu = randomPojo(MenuDO.class);
|
||||
menuMapper.insert(menu);
|
||||
// 准备参数
|
||||
Long id = menu.getId();
|
||||
|
||||
// 调用
|
||||
MenuDO dbMenu = menuService.getMenu(id);
|
||||
// 断言
|
||||
assertPojoEquals(menu, dbMenu);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_success() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.MENU, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
// 准备参数
|
||||
Long parentId = menuDO.getId();
|
||||
|
||||
// 调用,无需断言
|
||||
menuService.validateParentMenu(parentId, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_canNotSetSelfToBeParent() {
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateParentMenu(1L, 1L),
|
||||
MENU_PARENT_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_parentNotExist() {
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateParentMenu(randomLongId(), null),
|
||||
MENU_PARENT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateParentMenu_parentTypeError() {
|
||||
// mock 数据
|
||||
MenuDO menuDO = buildMenuDO(MenuTypeEnum.BUTTON, "parent", 0L);
|
||||
menuMapper.insert(menuDO);
|
||||
// 准备参数
|
||||
Long parentId = menuDO.getId();
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateParentMenu(parentId, null),
|
||||
MENU_PARENT_NOT_DIR_OR_MENU);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMenu_Name_success() {
|
||||
// mock 父子菜单
|
||||
MenuDO sonMenu = createParentAndSonMenu();
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
Long otherSonMenuId = randomLongId();
|
||||
String otherSonMenuName = randomString();
|
||||
|
||||
// 调用,无需断言
|
||||
menuService.validateMenuName(parentId, otherSonMenuName, otherSonMenuId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMenu_sonMenuNameNameDuplicate() {
|
||||
// mock 父子菜单
|
||||
MenuDO sonMenu = createParentAndSonMenu();
|
||||
// 准备参数
|
||||
Long parentId = sonMenu.getParentId();
|
||||
Long otherSonMenuId = randomLongId();
|
||||
String otherSonMenuName = sonMenu.getName(); //相同名称
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> menuService.validateMenuName(parentId, otherSonMenuName, otherSonMenuId),
|
||||
MENU_NAME_DUPLICATE);
|
||||
}
|
||||
|
||||
// ====================== 初始化方法 ======================
|
||||
|
||||
/**
|
||||
* 插入父子菜单,返回子菜单
|
||||
*
|
||||
* @return 子菜单
|
||||
*/
|
||||
private MenuDO createParentAndSonMenu() {
|
||||
// 构造父子菜单
|
||||
MenuDO parentMenuDO = buildMenuDO(MenuTypeEnum.MENU, "parent", ID_ROOT);
|
||||
menuMapper.insert(parentMenuDO);
|
||||
// 构建子菜单
|
||||
MenuDO sonMenuDO = buildMenuDO(MenuTypeEnum.MENU, "testSonName",
|
||||
parentMenuDO.getParentId());
|
||||
menuMapper.insert(sonMenuDO);
|
||||
return sonMenuDO;
|
||||
}
|
||||
|
||||
private MenuDO buildMenuDO(MenuTypeEnum type, String name, Long parentId) {
|
||||
return buildMenuDO(type, name, parentId, randomCommonStatus());
|
||||
}
|
||||
|
||||
private MenuDO buildMenuDO(MenuTypeEnum type, String name, Long parentId, Integer status) {
|
||||
return randomPojo(MenuDO.class, o -> o.setId(null).setName(name).setParentId(parentId)
|
||||
.setType(type.getType()).setStatus(status));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,527 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.hutool.core.collection.ListUtil.toList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static java.util.Collections.singleton;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import({PermissionServiceImpl.class})
|
||||
public class PermissionServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private PermissionServiceImpl permissionService;
|
||||
|
||||
@Resource
|
||||
private RoleMenuMapper roleMenuMapper;
|
||||
@Resource
|
||||
private UserRoleMapper userRoleMapper;
|
||||
|
||||
@MockBean
|
||||
private RoleService roleService;
|
||||
@MockBean
|
||||
private MenuService menuService;
|
||||
@MockBean
|
||||
private DeptService deptService;
|
||||
@MockBean
|
||||
private AdminUserService userService;
|
||||
|
||||
@Test
|
||||
public void testHasAnyPermissions_superAdmin() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
String[] roles = new String[]{"system:user:query", "system:user:create"};
|
||||
// mock 用户登录的角色
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(100L));
|
||||
RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(100L)))).thenReturn(toList(role));
|
||||
// mock 其它方法
|
||||
when(roleService.hasAnySuperAdmin(eq(asSet(100L)))).thenReturn(true);
|
||||
|
||||
// 调用,并断言
|
||||
assertTrue(permissionService.hasAnyPermissions(userId, roles));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasAnyPermissions_normal() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
String[] roles = new String[]{"system:user:query", "system:user:create"};
|
||||
// mock 用户登录的角色
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(100L));
|
||||
RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(100L)))).thenReturn(toList(role));
|
||||
// mock 菜单
|
||||
Long menuId = 1000L;
|
||||
when(menuService.getMenuIdListByPermissionFromCache(
|
||||
eq("system:user:create"))).thenReturn(singletonList(menuId));
|
||||
roleMenuMapper.insert(randomPojo(RoleMenuDO.class).setRoleId(100L).setMenuId(1000L));
|
||||
|
||||
// 调用,并断言
|
||||
assertTrue(permissionService.hasAnyPermissions(userId, roles));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasAnyRoles() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
String[] roles = new String[]{"yunai", "tudou"};
|
||||
// mock 用户与角色的缓存
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(100L));
|
||||
RoleDO role = randomPojo(RoleDO.class, o -> o.setId(100L).setCode("tudou")
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(100L)))).thenReturn(toList(role));
|
||||
|
||||
// 调用,并断言
|
||||
assertTrue(permissionService.hasAnyRoles(userId, roles));
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 角色-菜单的相关方法 ==========
|
||||
|
||||
@Test
|
||||
public void testAssignRoleMenu() {
|
||||
// 准备参数
|
||||
Long roleId = 1L;
|
||||
Set<Long> menuIds = asSet(200L, 300L);
|
||||
// mock 数据
|
||||
RoleMenuDO roleMenu01 = randomPojo(RoleMenuDO.class).setRoleId(1L).setMenuId(100L);
|
||||
roleMenuMapper.insert(roleMenu01);
|
||||
RoleMenuDO roleMenu02 = randomPojo(RoleMenuDO.class).setRoleId(1L).setMenuId(200L);
|
||||
roleMenuMapper.insert(roleMenu02);
|
||||
|
||||
// 调用
|
||||
permissionService.assignRoleMenu(roleId, menuIds);
|
||||
// 断言
|
||||
List<RoleMenuDO> roleMenuList = roleMenuMapper.selectList();
|
||||
assertEquals(2, roleMenuList.size());
|
||||
assertEquals(1L, roleMenuList.get(0).getRoleId());
|
||||
assertEquals(200L, roleMenuList.get(0).getMenuId());
|
||||
assertEquals(1L, roleMenuList.get(1).getRoleId());
|
||||
assertEquals(300L, roleMenuList.get(1).getMenuId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessRoleDeleted() {
|
||||
// 准备参数
|
||||
Long roleId = randomLongId();
|
||||
// mock 数据 UserRole
|
||||
UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setRoleId(roleId)); // 被删除
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
UserRoleDO userRoleDO02 = randomPojo(UserRoleDO.class); // 不被删除
|
||||
userRoleMapper.insert(userRoleDO02);
|
||||
// mock 数据 RoleMenu
|
||||
RoleMenuDO roleMenuDO01 = randomPojo(RoleMenuDO.class, o -> o.setRoleId(roleId)); // 被删除
|
||||
roleMenuMapper.insert(roleMenuDO01);
|
||||
RoleMenuDO roleMenuDO02 = randomPojo(RoleMenuDO.class); // 不被删除
|
||||
roleMenuMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
permissionService.processRoleDeleted(roleId);
|
||||
// 断言数据 RoleMenuDO
|
||||
List<RoleMenuDO> dbRoleMenus = roleMenuMapper.selectList();
|
||||
assertEquals(1, dbRoleMenus.size());
|
||||
assertPojoEquals(dbRoleMenus.get(0), roleMenuDO02);
|
||||
// 断言数据 UserRoleDO
|
||||
List<UserRoleDO> dbUserRoles = userRoleMapper.selectList();
|
||||
assertEquals(1, dbUserRoles.size());
|
||||
assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessMenuDeleted() {
|
||||
// 准备参数
|
||||
Long menuId = randomLongId();
|
||||
// mock 数据
|
||||
RoleMenuDO roleMenuDO01 = randomPojo(RoleMenuDO.class, o -> o.setMenuId(menuId)); // 被删除
|
||||
roleMenuMapper.insert(roleMenuDO01);
|
||||
RoleMenuDO roleMenuDO02 = randomPojo(RoleMenuDO.class); // 不被删除
|
||||
roleMenuMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
permissionService.processMenuDeleted(menuId);
|
||||
// 断言数据
|
||||
List<RoleMenuDO> dbRoleMenus = roleMenuMapper.selectList();
|
||||
assertEquals(1, dbRoleMenus.size());
|
||||
assertPojoEquals(dbRoleMenus.get(0), roleMenuDO02);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleMenuIds_superAdmin() {
|
||||
// 准备参数
|
||||
Long roleId = 100L;
|
||||
// mock 方法
|
||||
when(roleService.hasAnySuperAdmin(eq(singleton(100L)))).thenReturn(true);
|
||||
List<MenuDO> menuList = singletonList(randomPojo(MenuDO.class).setId(1L));
|
||||
when(menuService.getMenuList()).thenReturn(menuList);
|
||||
|
||||
// 调用
|
||||
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(roleId);
|
||||
// 断言
|
||||
assertEquals(singleton(1L), menuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleMenuIds_normal() {
|
||||
// 准备参数
|
||||
Long roleId = 100L;
|
||||
// mock 数据
|
||||
RoleMenuDO roleMenu01 = randomPojo(RoleMenuDO.class).setRoleId(100L).setMenuId(1L);
|
||||
roleMenuMapper.insert(roleMenu01);
|
||||
RoleMenuDO roleMenu02 = randomPojo(RoleMenuDO.class).setRoleId(100L).setMenuId(2L);
|
||||
roleMenuMapper.insert(roleMenu02);
|
||||
|
||||
// 调用
|
||||
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(roleId);
|
||||
// 断言
|
||||
assertEquals(asSet(1L, 2L), menuIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMenuRoleIdListByMenuIdFromCache() {
|
||||
// 准备参数
|
||||
Long menuId = 1L;
|
||||
// mock 数据
|
||||
RoleMenuDO roleMenu01 = randomPojo(RoleMenuDO.class).setRoleId(100L).setMenuId(1L);
|
||||
roleMenuMapper.insert(roleMenu01);
|
||||
RoleMenuDO roleMenu02 = randomPojo(RoleMenuDO.class).setRoleId(200L).setMenuId(1L);
|
||||
roleMenuMapper.insert(roleMenu02);
|
||||
|
||||
// 调用
|
||||
Set<Long> roleIds = permissionService.getMenuRoleIdListByMenuIdFromCache(menuId);
|
||||
// 断言
|
||||
assertEquals(asSet(100L, 200L), roleIds);
|
||||
}
|
||||
|
||||
// ========== 用户-角色的相关方法 ==========
|
||||
|
||||
@Test
|
||||
public void testAssignUserRole() {
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
Set<Long> roleIds = asSet(200L, 300L);
|
||||
// mock 数据
|
||||
UserRoleDO userRole01 = randomPojo(UserRoleDO.class).setUserId(1L).setRoleId(100L);
|
||||
userRoleMapper.insert(userRole01);
|
||||
UserRoleDO userRole02 = randomPojo(UserRoleDO.class).setUserId(1L).setRoleId(200L);
|
||||
userRoleMapper.insert(userRole02);
|
||||
|
||||
// 调用
|
||||
permissionService.assignUserRole(userId, roleIds);
|
||||
// 断言
|
||||
List<UserRoleDO> userRoleDOList = userRoleMapper.selectList();
|
||||
assertEquals(2, userRoleDOList.size());
|
||||
assertEquals(1L, userRoleDOList.get(0).getUserId());
|
||||
assertEquals(200L, userRoleDOList.get(0).getRoleId());
|
||||
assertEquals(1L, userRoleDOList.get(1).getUserId());
|
||||
assertEquals(300L, userRoleDOList.get(1).getRoleId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessUserDeleted() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
// mock 数据
|
||||
UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(userId)); // 被删除
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
UserRoleDO userRoleDO02 = randomPojo(UserRoleDO.class); // 不被删除
|
||||
userRoleMapper.insert(userRoleDO02);
|
||||
|
||||
// 调用
|
||||
permissionService.processUserDeleted(userId);
|
||||
// 断言数据
|
||||
List<UserRoleDO> dbUserRoles = userRoleMapper.selectList();
|
||||
assertEquals(1, dbUserRoles.size());
|
||||
assertPojoEquals(dbUserRoles.get(0), userRoleDO02);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserRoleIdListByUserId() {
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 数据
|
||||
UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L));
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(20L));
|
||||
userRoleMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
Set<Long> result = permissionService.getUserRoleIdListByUserId(userId);
|
||||
// 断言
|
||||
assertEquals(asSet(10L, 20L), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserRoleIdListByUserIdFromCache() {
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 数据
|
||||
UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L));
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(20L));
|
||||
userRoleMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
Set<Long> result = permissionService.getUserRoleIdListByUserIdFromCache(userId);
|
||||
// 断言
|
||||
assertEquals(asSet(10L, 20L), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserRoleIdsFromCache() {
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 数据
|
||||
UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L));
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(20L));
|
||||
userRoleMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
Set<Long> result = permissionService.getUserRoleIdListByUserIdFromCache(userId);
|
||||
// 断言
|
||||
assertEquals(asSet(10L, 20L), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserRoleIdListByRoleId() {
|
||||
// 准备参数
|
||||
Collection<Long> roleIds = asSet(10L, 20L);
|
||||
// mock 数据
|
||||
UserRoleDO userRoleDO01 = randomPojo(UserRoleDO.class, o -> o.setUserId(1L).setRoleId(10L));
|
||||
userRoleMapper.insert(userRoleDO01);
|
||||
UserRoleDO roleMenuDO02 = randomPojo(UserRoleDO.class, o -> o.setUserId(2L).setRoleId(20L));
|
||||
userRoleMapper.insert(roleMenuDO02);
|
||||
|
||||
// 调用
|
||||
Set<Long> result = permissionService.getUserRoleIdListByRoleId(roleIds);
|
||||
// 断言
|
||||
assertEquals(asSet(1L, 2L), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnableUserRoleListByUserIdFromCache() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 用户登录的角色
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(100L));
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(200L));
|
||||
RoleDO role01 = randomPojo(RoleDO.class, o -> o.setId(100L)
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
RoleDO role02 = randomPojo(RoleDO.class, o -> o.setId(200L)
|
||||
.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(asSet(100L, 200L))))
|
||||
.thenReturn(toList(role01, role02));
|
||||
|
||||
// 调用
|
||||
List<RoleDO> result = permissionService.getEnableUserRoleListByUserIdFromCache(userId);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(role01, result.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 用户-部门的相关方法 ==========
|
||||
|
||||
@Test
|
||||
public void testAssignRoleDataScope() {
|
||||
// 准备参数
|
||||
Long roleId = 1L;
|
||||
Integer dataScope = 2;
|
||||
Set<Long> dataScopeDeptIds = asSet(10L, 20L);
|
||||
|
||||
// 调用
|
||||
permissionService.assignRoleDataScope(roleId, dataScope, dataScopeDeptIds);
|
||||
// 断言
|
||||
verify(roleService).updateRoleDataScope(eq(roleId), eq(dataScope), eq(dataScopeDeptIds));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_All() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 用户的角色编号
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
|
||||
// mock 获得用户的角色
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.ALL.getScope())
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
|
||||
// 断言
|
||||
assertTrue(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertTrue(CollUtil.isEmpty(result.getDeptIds()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_DeptCustom() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 用户的角色编号
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
|
||||
// mock 获得用户的角色
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_CUSTOM.getScope())
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
|
||||
// mock 部门的返回
|
||||
when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L),
|
||||
null, null); // 最后返回 null 的目的,看看会不会重复调用
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
|
||||
// 断言
|
||||
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(), 3L));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_DeptOnly() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 用户的角色编号
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
|
||||
// mock 获得用户的角色
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_ONLY.getScope())
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
|
||||
// mock 部门的返回
|
||||
when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L),
|
||||
null, null); // 最后返回 null 的目的,看看会不会重复调用
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertEquals(1, result.getDeptIds().size());
|
||||
assertTrue(CollUtil.contains(result.getDeptIds(), 3L));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_DeptAndChild() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 用户的角色编号
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
|
||||
// mock 获得用户的角色
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.DEPT_AND_CHILD.getScope())
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
|
||||
// mock 部门的返回
|
||||
when(userService.getUser(eq(1L))).thenReturn(new AdminUserDO().setDeptId(3L),
|
||||
null, null); // 最后返回 null 的目的,看看会不会重复调用
|
||||
// mock 方法(部门)
|
||||
DeptDO deptDO = randomPojo(DeptDO.class);
|
||||
when(deptService.getChildDeptIdListFromCache(eq(3L))).thenReturn(singleton(deptDO.getId()));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertFalse(result.getSelf());
|
||||
assertEquals(2, result.getDeptIds().size());
|
||||
assertTrue(CollUtil.contains(result.getDeptIds(), deptDO.getId()));
|
||||
assertTrue(CollUtil.contains(result.getDeptIds(), 3L));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDeptDataPermission_Self() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(PermissionServiceImpl.class)))
|
||||
.thenReturn(permissionService);
|
||||
|
||||
// 准备参数
|
||||
Long userId = 1L;
|
||||
// mock 用户的角色编号
|
||||
userRoleMapper.insert(randomPojo(UserRoleDO.class).setUserId(userId).setRoleId(2L));
|
||||
// mock 获得用户的角色
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setDataScope(DataScopeEnum.SELF.getScope())
|
||||
.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(roleService.getRoleListFromCache(eq(singleton(2L)))).thenReturn(toList(roleDO));
|
||||
|
||||
// 调用
|
||||
DeptDataPermissionRespDTO result = permissionService.getDeptDataPermission(userId);
|
||||
// 断言
|
||||
assertFalse(result.getAll());
|
||||
assertTrue(result.getSelf());
|
||||
assertTrue(CollUtil.isEmpty(result.getDeptIds()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.permission;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singleton;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@Import(RoleServiceImpl.class)
|
||||
public class RoleServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private RoleServiceImpl roleService;
|
||||
|
||||
@Resource
|
||||
private RoleMapper roleMapper;
|
||||
|
||||
@MockBean
|
||||
private PermissionService permissionService;
|
||||
|
||||
@Test
|
||||
public void testCreateRole() {
|
||||
// 准备参数
|
||||
RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class)
|
||||
.setId(null) // 防止 id 被赋值
|
||||
.setStatus(randomCommonStatus());
|
||||
|
||||
// 调用
|
||||
Long roleId = roleService.createRole(reqVO, null);
|
||||
// 断言
|
||||
RoleDO roleDO = roleMapper.selectById(roleId);
|
||||
assertPojoEquals(reqVO, roleDO, "id");
|
||||
assertEquals(RoleTypeEnum.CUSTOM.getType(), roleDO.getType());
|
||||
assertEquals(DataScopeEnum.ALL.getScope(), roleDO.getDataScope());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRole() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType()));
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
Long id = roleDO.getId();
|
||||
RoleSaveReqVO reqVO = randomPojo(RoleSaveReqVO.class, o -> o.setId(id)
|
||||
.setStatus(randomCommonStatus()));
|
||||
|
||||
// 调用
|
||||
roleService.updateRole(reqVO);
|
||||
// 断言
|
||||
RoleDO newRoleDO = roleMapper.selectById(id);
|
||||
assertPojoEquals(reqVO, newRoleDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateRoleDataScope() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType()));
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
Long id = roleDO.getId();
|
||||
Integer dataScope = randomEle(DataScopeEnum.values()).getScope();
|
||||
Set<Long> dataScopeRoleIds = randomSet(Long.class);
|
||||
|
||||
// 调用
|
||||
roleService.updateRoleDataScope(id, dataScope, dataScopeRoleIds);
|
||||
// 断言
|
||||
RoleDO dbRoleDO = roleMapper.selectById(id);
|
||||
assertEquals(dataScope, dbRoleDO.getDataScope());
|
||||
assertEquals(dataScopeRoleIds, dbRoleDO.getDataScopeDeptIds());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRole() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType()));
|
||||
roleMapper.insert(roleDO);
|
||||
// 参数准备
|
||||
Long id = roleDO.getId();
|
||||
|
||||
// 调用
|
||||
roleService.deleteRole(id);
|
||||
// 断言
|
||||
assertNull(roleMapper.selectById(id));
|
||||
// verify 删除相关数据
|
||||
verify(permissionService).processRoleDeleted(id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleDuplicate_success() {
|
||||
// 调用,不会抛异常
|
||||
roleService.validateRoleDuplicate(randomString(), randomString(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleDuplicate_nameDuplicate() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setName("role_name"));
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
String name = "role_name";
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> roleService.validateRoleDuplicate(name, randomString(), null),
|
||||
ROLE_NAME_DUPLICATE, name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleDuplicate_codeDuplicate() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setCode("code"));
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
String code = "code";
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> roleService.validateRoleDuplicate(randomString(), code, null),
|
||||
ROLE_CODE_DUPLICATE, code);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUpdateRole_success() {
|
||||
RoleDO roleDO = randomPojo(RoleDO.class);
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
Long id = roleDO.getId();
|
||||
|
||||
// 调用,无异常
|
||||
roleService.validateRoleForUpdate(id);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUpdateRole_roleIdNotExist() {
|
||||
assertServiceException(() -> roleService.validateRoleForUpdate(randomLongId()), ROLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUpdateRole_systemRoleCanNotBeUpdate() {
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.SYSTEM.getType()));
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
Long id = roleDO.getId();
|
||||
|
||||
assertServiceException(() -> roleService.validateRoleForUpdate(id),
|
||||
ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRole() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class);
|
||||
roleMapper.insert(roleDO);
|
||||
// 参数准备
|
||||
Long id = roleDO.getId();
|
||||
|
||||
// 调用
|
||||
RoleDO dbRoleDO = roleService.getRole(id);
|
||||
// 断言
|
||||
assertPojoEquals(roleDO, dbRoleDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleFromCache() {
|
||||
// mock 数据(缓存)
|
||||
RoleDO roleDO = randomPojo(RoleDO.class);
|
||||
roleMapper.insert(roleDO);
|
||||
// 参数准备
|
||||
Long id = roleDO.getId();
|
||||
|
||||
// 调用
|
||||
RoleDO dbRoleDO = roleService.getRoleFromCache(id);
|
||||
// 断言
|
||||
assertPojoEquals(roleDO, dbRoleDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleListByStatus() {
|
||||
// mock 数据
|
||||
RoleDO dbRole01 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
roleMapper.insert(dbRole01);
|
||||
RoleDO dbRole02 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
roleMapper.insert(dbRole02);
|
||||
|
||||
// 调用
|
||||
List<RoleDO> list = roleService.getRoleListByStatus(
|
||||
singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbRole01, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleList() {
|
||||
// mock 数据
|
||||
RoleDO dbRole01 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
roleMapper.insert(dbRole01);
|
||||
RoleDO dbRole02 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
roleMapper.insert(dbRole02);
|
||||
|
||||
// 调用
|
||||
List<RoleDO> list = roleService.getRoleList();
|
||||
// 断言
|
||||
assertEquals(2, list.size());
|
||||
assertPojoEquals(dbRole01, list.get(0));
|
||||
assertPojoEquals(dbRole02, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleList_ids() {
|
||||
// mock 数据
|
||||
RoleDO dbRole01 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
roleMapper.insert(dbRole01);
|
||||
RoleDO dbRole02 = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
roleMapper.insert(dbRole02);
|
||||
// 准备参数
|
||||
Collection<Long> ids = singleton(dbRole01.getId());
|
||||
|
||||
// 调用
|
||||
List<RoleDO> list = roleService.getRoleList(ids);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbRole01, list.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRoleListFromCache() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
|
||||
.thenReturn(roleService);
|
||||
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
roleMapper.insert(dbRole);
|
||||
// 测试 id 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> {}));
|
||||
// 准备参数
|
||||
Collection<Long> ids = singleton(dbRole.getId());
|
||||
|
||||
// 调用
|
||||
List<RoleDO> list = roleService.getRoleListFromCache(ids);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbRole, list.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRolePage() {
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class, o -> { // 等会查询到
|
||||
o.setName("土豆");
|
||||
o.setCode("tudou");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2022, 2, 8));
|
||||
});
|
||||
roleMapper.insert(dbRole);
|
||||
// 测试 name 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setName("红薯")));
|
||||
// 测试 code 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCode("hong")));
|
||||
// 测试 createTime 不匹配
|
||||
roleMapper.insert(cloneIgnoreId(dbRole, o -> o.setCreateTime(buildTime(2022, 2, 16))));
|
||||
// 准备参数
|
||||
RolePageReqVO reqVO = new RolePageReqVO();
|
||||
reqVO.setName("土豆");
|
||||
reqVO.setCode("tu");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 12));
|
||||
|
||||
// 调用
|
||||
PageResult<RoleDO> pageResult = roleService.getRolePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbRole, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasAnySuperAdmin_true() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
|
||||
.thenReturn(roleService);
|
||||
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class).setCode("super_admin");
|
||||
roleMapper.insert(dbRole);
|
||||
// 准备参数
|
||||
Long id = dbRole.getId();
|
||||
|
||||
// 调用,并调用
|
||||
assertTrue(roleService.hasAnySuperAdmin(singletonList(id)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasAnySuperAdmin_false() {
|
||||
try (MockedStatic<SpringUtil> springUtilMockedStatic = mockStatic(SpringUtil.class)) {
|
||||
springUtilMockedStatic.when(() -> SpringUtil.getBean(eq(RoleServiceImpl.class)))
|
||||
.thenReturn(roleService);
|
||||
|
||||
// mock 数据
|
||||
RoleDO dbRole = randomPojo(RoleDO.class).setCode("tenant_admin");
|
||||
roleMapper.insert(dbRole);
|
||||
// 准备参数
|
||||
Long id = dbRole.getId();
|
||||
|
||||
// 调用,并调用
|
||||
assertFalse(roleService.hasAnySuperAdmin(singletonList(id)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleList_success() {
|
||||
// mock 数据
|
||||
RoleDO roleDO = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
roleMapper.insert(roleDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(roleDO.getId());
|
||||
|
||||
// 调用,无需断言
|
||||
roleService.validateRoleList(ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleList_notFound() {
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(randomLongId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> roleService.validateRoleList(ids), ROLE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateRoleList_notEnable() {
|
||||
// mock 数据
|
||||
RoleDO RoleDO = randomPojo(RoleDO.class, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
roleMapper.insert(RoleDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(RoleDO.getId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> roleService.validateRoleList(ids), ROLE_IS_DISABLE, RoleDO.getName());
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.SmsClient;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.SmsClientFactory;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.property.SmsChannelProperties;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.channel.SmsChannelSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper;
|
||||
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.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_HAS_CHILDREN;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SMS_CHANNEL_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import(SmsChannelServiceImpl.class)
|
||||
public class SmsChannelServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SmsChannelServiceImpl smsChannelService;
|
||||
|
||||
@Resource
|
||||
private SmsChannelMapper smsChannelMapper;
|
||||
|
||||
@MockBean
|
||||
private SmsClientFactory smsClientFactory;
|
||||
@MockBean
|
||||
private SmsTemplateService smsTemplateService;
|
||||
|
||||
@Test
|
||||
public void testCreateSmsChannel_success() {
|
||||
// 准备参数
|
||||
SmsChannelSaveReqVO reqVO = randomPojo(SmsChannelSaveReqVO.class, o -> o.setStatus(randomCommonStatus()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long smsChannelId = smsChannelService.createSmsChannel(reqVO);
|
||||
// 断言
|
||||
assertNotNull(smsChannelId);
|
||||
// 校验记录的属性是否正确
|
||||
SmsChannelDO smsChannel = smsChannelMapper.selectById(smsChannelId);
|
||||
assertPojoEquals(reqVO, smsChannel, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsChannel_success() {
|
||||
// mock 数据
|
||||
SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SmsChannelSaveReqVO reqVO = randomPojo(SmsChannelSaveReqVO.class, o -> {
|
||||
o.setId(dbSmsChannel.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setCallbackUrl(randomString());
|
||||
});
|
||||
|
||||
// 调用
|
||||
smsChannelService.updateSmsChannel(reqVO);
|
||||
// 校验是否更新正确
|
||||
SmsChannelDO smsChannel = smsChannelMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, smsChannel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsChannel_notExists() {
|
||||
// 准备参数
|
||||
SmsChannelSaveReqVO reqVO = randomPojo(SmsChannelSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsChannelService.updateSmsChannel(reqVO), SMS_CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsChannel_success() {
|
||||
// mock 数据
|
||||
SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsChannel.getId();
|
||||
|
||||
// 调用
|
||||
smsChannelService.deleteSmsChannel(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(smsChannelMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsChannel_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsChannelService.deleteSmsChannel(id), SMS_CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsChannel_hasChildren() {
|
||||
// mock 数据
|
||||
SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(dbSmsChannel);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsChannel.getId();
|
||||
// mock 方法
|
||||
when(smsTemplateService.getSmsTemplateCountByChannelId(eq(id))).thenReturn(10L);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsChannelService.deleteSmsChannel(id), SMS_CHANNEL_HAS_CHILDREN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsChannel() {
|
||||
// mock 数据
|
||||
SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(dbSmsChannel); // @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsChannel.getId();
|
||||
|
||||
// 调用,并断言
|
||||
assertPojoEquals(dbSmsChannel, smsChannelService.getSmsChannel(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsChannelList() {
|
||||
// mock 数据
|
||||
SmsChannelDO dbSmsChannel01 = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(dbSmsChannel01);
|
||||
SmsChannelDO dbSmsChannel02 = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(dbSmsChannel02);
|
||||
// 准备参数
|
||||
|
||||
// 调用
|
||||
List<SmsChannelDO> list = smsChannelService.getSmsChannelList();
|
||||
// 断言
|
||||
assertEquals(2, list.size());
|
||||
assertPojoEquals(dbSmsChannel01, list.get(0));
|
||||
assertPojoEquals(dbSmsChannel02, list.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsChannelPage() {
|
||||
// mock 数据
|
||||
SmsChannelDO dbSmsChannel = randomPojo(SmsChannelDO.class, o -> { // 等会查询到
|
||||
o.setSignature("芋道源码");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2020, 12, 12));
|
||||
});
|
||||
smsChannelMapper.insert(dbSmsChannel);
|
||||
// 测试 signature 不匹配
|
||||
smsChannelMapper.insert(cloneIgnoreId(dbSmsChannel, o -> o.setSignature("源码")));
|
||||
// 测试 status 不匹配
|
||||
smsChannelMapper.insert(cloneIgnoreId(dbSmsChannel, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
smsChannelMapper.insert(cloneIgnoreId(dbSmsChannel, o -> o.setCreateTime(buildTime(2020, 11, 11))));
|
||||
// 准备参数
|
||||
SmsChannelPageReqVO reqVO = new SmsChannelPageReqVO();
|
||||
reqVO.setSignature("芋道");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24));
|
||||
|
||||
// 调用
|
||||
PageResult<SmsChannelDO> pageResult = smsChannelService.getSmsChannelPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSmsChannel, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsClient_id() {
|
||||
// mock 数据
|
||||
SmsChannelDO channel = randomPojo(SmsChannelDO.class);
|
||||
smsChannelMapper.insert(channel);
|
||||
// 准备参数
|
||||
Long id = channel.getId();
|
||||
// mock 方法
|
||||
SmsClient mockClient = mock(SmsClient.class);
|
||||
SmsChannelProperties properties = BeanUtils.toBean(channel, SmsChannelProperties.class);
|
||||
when(smsClientFactory.createOrUpdateSmsClient(eq(properties))).thenReturn(mockClient);
|
||||
|
||||
// 调用
|
||||
SmsClient client = smsChannelService.getSmsClient(id);
|
||||
// 断言
|
||||
assertSame(client, mockClient);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsClient_code() {
|
||||
// 准备参数
|
||||
String code = randomString();
|
||||
// mock 方法
|
||||
SmsClient mockClient = mock(SmsClient.class);
|
||||
when(smsClientFactory.getSmsClient(eq(code))).thenReturn(mockClient);
|
||||
|
||||
// 调用
|
||||
SmsClient client = smsChannelService.getSmsClient(code);
|
||||
// 断言
|
||||
assertSame(client, mockClient);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsCodeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsCodeMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.config.SmsCodeProperties;
|
||||
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 javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
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.randomPojo;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(SmsCodeServiceImpl.class)
|
||||
public class SmsCodeServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SmsCodeServiceImpl smsCodeService;
|
||||
|
||||
@Resource
|
||||
private SmsCodeMapper smsCodeMapper;
|
||||
|
||||
@MockBean
|
||||
private SmsCodeProperties smsCodeProperties;
|
||||
@MockBean
|
||||
private SmsSendService smsSendService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(smsCodeProperties.getExpireTimes()).thenReturn(Duration.ofMinutes(5));
|
||||
when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMinutes(1));
|
||||
when(smsCodeProperties.getSendMaximumQuantityPerDay()).thenReturn(10);
|
||||
when(smsCodeProperties.getBeginCode()).thenReturn(9999);
|
||||
when(smsCodeProperties.getEndCode()).thenReturn(9999);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendSmsCode_success() {
|
||||
// 准备参数
|
||||
SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
|
||||
});
|
||||
|
||||
// 调用
|
||||
smsCodeService.sendSmsCode(reqDTO);
|
||||
// 断言 code 验证码
|
||||
SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
|
||||
assertPojoEquals(reqDTO, smsCodeDO);
|
||||
assertEquals("9999", smsCodeDO.getCode());
|
||||
assertEquals(1, smsCodeDO.getTodayIndex());
|
||||
assertFalse(smsCodeDO.getUsed());
|
||||
// 断言调用
|
||||
verify(smsSendService).sendSingleSms(eq(reqDTO.getMobile()), isNull(), isNull(),
|
||||
eq("user-sms-login"), eq(MapUtil.of("code", "9999")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendSmsCode_tooFast() {
|
||||
// mock 数据
|
||||
SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
|
||||
o -> o.setMobile("15601691300").setTodayIndex(1));
|
||||
smsCodeMapper.insert(smsCodeDO);
|
||||
// 准备参数
|
||||
SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
|
||||
});
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
|
||||
SMS_CODE_SEND_TOO_FAST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendSmsCode_exceedDay() {
|
||||
// mock 数据
|
||||
SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
|
||||
o -> o.setMobile("15601691300").setTodayIndex(10).setCreateTime(LocalDateTime.now()));
|
||||
smsCodeMapper.insert(smsCodeDO);
|
||||
// 准备参数
|
||||
SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
|
||||
});
|
||||
when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMillis(0));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
|
||||
SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseSmsCode_success() {
|
||||
// 准备参数
|
||||
SmsCodeUseReqDTO reqDTO = randomPojo(SmsCodeUseReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
||||
});
|
||||
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> {
|
||||
o.setMobile(reqDTO.getMobile()).setScene(reqDTO.getScene())
|
||||
.setCode(reqDTO.getCode()).setUsed(false);
|
||||
}));
|
||||
|
||||
// 调用
|
||||
smsCodeService.useSmsCode(reqDTO);
|
||||
// 断言
|
||||
SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
|
||||
assertTrue(smsCodeDO.getUsed());
|
||||
assertNotNull(smsCodeDO.getUsedTime());
|
||||
assertEquals(reqDTO.getUsedIp(), smsCodeDO.getUsedIp());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSmsCode_success() {
|
||||
// 准备参数
|
||||
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
||||
});
|
||||
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
|
||||
.setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)));
|
||||
|
||||
// 调用
|
||||
smsCodeService.validateSmsCode(reqDTO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSmsCode_notFound() {
|
||||
// 准备参数
|
||||
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
||||
});
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
|
||||
SMS_CODE_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSmsCode_expired() {
|
||||
// 准备参数
|
||||
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
||||
});
|
||||
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
|
||||
.setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)
|
||||
.setCreateTime(LocalDateTime.now().minusMinutes(6))));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
|
||||
SMS_CODE_EXPIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateSmsCode_used() {
|
||||
// 准备参数
|
||||
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
||||
o.setMobile("15601691300");
|
||||
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
||||
});
|
||||
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
|
||||
.setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(true)
|
||||
.setCreateTime(LocalDateTime.now())));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
|
||||
SMS_CODE_USED);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
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.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.log.SmsLogPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsLogDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsLogMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsReceiveStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSendStatusEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsTemplateTypeEnum;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomBoolean;
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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.RandomUtils.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
@Import(SmsLogServiceImpl.class)
|
||||
public class SmsLogServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SmsLogServiceImpl smsLogService;
|
||||
|
||||
@Resource
|
||||
private SmsLogMapper smsLogMapper;
|
||||
|
||||
@Test
|
||||
public void testGetSmsLogPage() {
|
||||
// mock 数据
|
||||
SmsLogDO dbSmsLog = randomSmsLogDO(o -> { // 等会查询到
|
||||
o.setChannelId(1L);
|
||||
o.setTemplateId(10L);
|
||||
o.setMobile("15601691300");
|
||||
o.setSendStatus(SmsSendStatusEnum.INIT.getStatus());
|
||||
o.setSendTime(buildTime(2020, 11, 11));
|
||||
o.setReceiveStatus(SmsReceiveStatusEnum.INIT.getStatus());
|
||||
o.setReceiveTime(buildTime(2021, 11, 11));
|
||||
});
|
||||
smsLogMapper.insert(dbSmsLog);
|
||||
// 测试 channelId 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setChannelId(2L)));
|
||||
// 测试 templateId 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setTemplateId(20L)));
|
||||
// 测试 mobile 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setMobile("18818260999")));
|
||||
// 测试 sendStatus 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setSendStatus(SmsSendStatusEnum.IGNORE.getStatus())));
|
||||
// 测试 sendTime 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setSendTime(buildTime(2020, 12, 12))));
|
||||
// 测试 receiveStatus 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setReceiveStatus(SmsReceiveStatusEnum.SUCCESS.getStatus())));
|
||||
// 测试 receiveTime 不匹配
|
||||
smsLogMapper.insert(cloneIgnoreId(dbSmsLog, o -> o.setReceiveTime(buildTime(2021, 12, 12))));
|
||||
// 准备参数
|
||||
SmsLogPageReqVO reqVO = new SmsLogPageReqVO();
|
||||
reqVO.setChannelId(1L);
|
||||
reqVO.setTemplateId(10L);
|
||||
reqVO.setMobile("156");
|
||||
reqVO.setSendStatus(SmsSendStatusEnum.INIT.getStatus());
|
||||
reqVO.setSendTime(buildBetweenTime(2020, 11, 1, 2020, 11, 30));
|
||||
reqVO.setReceiveStatus(SmsReceiveStatusEnum.INIT.getStatus());
|
||||
reqVO.setReceiveTime(buildBetweenTime(2021, 11, 1, 2021, 11, 30));
|
||||
|
||||
// 调用
|
||||
PageResult<SmsLogDO> pageResult = smsLogService.getSmsLogPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSmsLog, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSmsLog() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
Boolean isSend = randomBoolean();
|
||||
SmsTemplateDO templateDO = randomPojo(SmsTemplateDO.class,
|
||||
o -> o.setType(randomEle(SmsTemplateTypeEnum.values()).getType()));
|
||||
String templateContent = randomString();
|
||||
Map<String, Object> templateParams = randomTemplateParams();
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
Long logId = smsLogService.createSmsLog(mobile, userId, userType, isSend,
|
||||
templateDO, templateContent, templateParams);
|
||||
// 断言
|
||||
SmsLogDO logDO = smsLogMapper.selectById(logId);
|
||||
assertEquals(isSend ? SmsSendStatusEnum.INIT.getStatus() : SmsSendStatusEnum.IGNORE.getStatus(),
|
||||
logDO.getSendStatus());
|
||||
assertEquals(mobile, logDO.getMobile());
|
||||
assertEquals(userType, logDO.getUserType());
|
||||
assertEquals(userId, logDO.getUserId());
|
||||
assertEquals(templateDO.getId(), logDO.getTemplateId());
|
||||
assertEquals(templateDO.getCode(), logDO.getTemplateCode());
|
||||
assertEquals(templateDO.getType(), logDO.getTemplateType());
|
||||
assertEquals(templateDO.getChannelId(), logDO.getChannelId());
|
||||
assertEquals(templateDO.getChannelCode(), logDO.getChannelCode());
|
||||
assertEquals(templateContent, logDO.getTemplateContent());
|
||||
assertEquals(templateParams, logDO.getTemplateParams());
|
||||
assertEquals(SmsReceiveStatusEnum.INIT.getStatus(), logDO.getReceiveStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsSendResult() {
|
||||
// mock 数据
|
||||
SmsLogDO dbSmsLog = randomSmsLogDO(
|
||||
o -> o.setSendStatus(SmsSendStatusEnum.IGNORE.getStatus()));
|
||||
smsLogMapper.insert(dbSmsLog);
|
||||
// 准备参数
|
||||
Long id = dbSmsLog.getId();
|
||||
Boolean success = randomBoolean();
|
||||
String apiSendCode = randomString();
|
||||
String apiSendMsg = randomString();
|
||||
String apiRequestId = randomString();
|
||||
String apiSerialNo = randomString();
|
||||
|
||||
// 调用
|
||||
smsLogService.updateSmsSendResult(id, success,
|
||||
apiSendCode, apiSendMsg, apiRequestId, apiSerialNo);
|
||||
// 断言
|
||||
dbSmsLog = smsLogMapper.selectById(id);
|
||||
assertEquals(success ? SmsSendStatusEnum.SUCCESS.getStatus() : SmsSendStatusEnum.FAILURE.getStatus(),
|
||||
dbSmsLog.getSendStatus());
|
||||
assertNotNull(dbSmsLog.getSendTime());
|
||||
assertEquals(apiSendCode, dbSmsLog.getApiSendCode());
|
||||
assertEquals(apiSendMsg, dbSmsLog.getApiSendMsg());
|
||||
assertEquals(apiRequestId, dbSmsLog.getApiRequestId());
|
||||
assertEquals(apiSerialNo, dbSmsLog.getApiSerialNo());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsReceiveResult() {
|
||||
// mock 数据
|
||||
SmsLogDO dbSmsLog = randomSmsLogDO(
|
||||
o -> o.setReceiveStatus(SmsReceiveStatusEnum.INIT.getStatus()));
|
||||
smsLogMapper.insert(dbSmsLog);
|
||||
// 准备参数
|
||||
Long id = dbSmsLog.getId();
|
||||
Boolean success = randomBoolean();
|
||||
LocalDateTime receiveTime = randomLocalDateTime();
|
||||
String apiReceiveCode = randomString();
|
||||
String apiReceiveMsg = randomString();
|
||||
|
||||
// 调用
|
||||
smsLogService.updateSmsReceiveResult(id, success, receiveTime, apiReceiveCode, apiReceiveMsg);
|
||||
// 断言
|
||||
dbSmsLog = smsLogMapper.selectById(id);
|
||||
assertEquals(success ? SmsReceiveStatusEnum.SUCCESS.getStatus()
|
||||
: SmsReceiveStatusEnum.FAILURE.getStatus(), dbSmsLog.getReceiveStatus());
|
||||
assertEquals(receiveTime, dbSmsLog.getReceiveTime());
|
||||
assertEquals(apiReceiveCode, dbSmsLog.getApiReceiveCode());
|
||||
assertEquals(apiReceiveMsg, dbSmsLog.getApiReceiveMsg());
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SmsLogDO randomSmsLogDO(Consumer<SmsLogDO>... consumers) {
|
||||
Consumer<SmsLogDO> consumer = (o) -> {
|
||||
o.setTemplateParams(randomTemplateParams());
|
||||
o.setTemplateType(randomEle(SmsTemplateTypeEnum.values()).getType()); // 保证 templateType 的范围
|
||||
o.setUserType(randomEle(UserTypeEnum.values()).getValue()); // 保证 userType 的范围
|
||||
o.setSendStatus(randomEle(SmsSendStatusEnum.values()).getStatus()); // 保证 sendStatus 的范围
|
||||
o.setReceiveStatus(randomEle(SmsReceiveStatusEnum.values()).getStatus()); // 保证 receiveStatus 的范围
|
||||
};
|
||||
return randomPojo(SmsLogDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
private static Map<String, Object> randomTemplateParams() {
|
||||
return MapUtil.<String, Object>builder().put(randomString(), randomString())
|
||||
.put(randomString(), randomString()).build();
|
||||
}
|
||||
}
|
||||
@@ -1,298 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.SmsClient;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.mq.message.sms.SmsSendMessage;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.sms.SmsProducer;
|
||||
import cn.iocoder.yudao.module.system.service.member.MemberService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class SmsSendServiceImplTest extends BaseMockitoUnitTest {
|
||||
|
||||
@InjectMocks
|
||||
private SmsSendServiceImpl smsSendService;
|
||||
|
||||
@Mock
|
||||
private AdminUserService adminUserService;
|
||||
@Mock
|
||||
private MemberService memberService;
|
||||
@Mock
|
||||
private SmsChannelService smsChannelService;
|
||||
@Mock
|
||||
private SmsTemplateService smsTemplateService;
|
||||
@Mock
|
||||
private SmsLogService smsLogService;
|
||||
@Mock
|
||||
private SmsProducer smsProducer;
|
||||
|
||||
@Test
|
||||
public void testSendSingleSmsToAdmin() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock adminUserService 的方法
|
||||
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300"));
|
||||
when(adminUserService.getUser(eq(userId))).thenReturn(user);
|
||||
|
||||
// mock SmsTemplateService 的方法
|
||||
SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock SmsChannelService 的方法
|
||||
SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
|
||||
// mock SmsLogService 的方法
|
||||
Long smsLogId = randomLongId();
|
||||
when(smsLogService.createSmsLog(eq(user.getMobile()), eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(Boolean.TRUE), eq(template),
|
||||
eq(content), eq(templateParams))).thenReturn(smsLogId);
|
||||
|
||||
// 调用
|
||||
Long resultSmsLogId = smsSendService.sendSingleSmsToAdmin(null, userId, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(smsLogId, resultSmsLogId);
|
||||
// 断言调用
|
||||
verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(user.getMobile()),
|
||||
eq(template.getChannelId()), eq(template.getApiTemplateId()),
|
||||
eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendSingleSmsToUser() {
|
||||
// 准备参数
|
||||
Long userId = randomLongId();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock memberService 的方法
|
||||
String mobile = "15601691300";
|
||||
when(memberService.getMemberUserMobile(eq(userId))).thenReturn(mobile);
|
||||
|
||||
// mock SmsTemplateService 的方法
|
||||
SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock SmsChannelService 的方法
|
||||
SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
|
||||
// mock SmsLogService 的方法
|
||||
Long smsLogId = randomLongId();
|
||||
when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(Boolean.TRUE), eq(template),
|
||||
eq(content), eq(templateParams))).thenReturn(smsLogId);
|
||||
|
||||
// 调用
|
||||
Long resultSmsLogId = smsSendService.sendSingleSmsToMember(null, userId, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(smsLogId, resultSmsLogId);
|
||||
// 断言调用
|
||||
verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(mobile),
|
||||
eq(template.getChannelId()), eq(template.getApiTemplateId()),
|
||||
eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login"))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成功,当短信模板开启时
|
||||
*/
|
||||
@Test
|
||||
public void testSendSingleSms_successWhenSmsTemplateEnable() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock SmsTemplateService 的方法
|
||||
SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock SmsChannelService 的方法
|
||||
SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
|
||||
// mock SmsLogService 的方法
|
||||
Long smsLogId = randomLongId();
|
||||
when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(userType), eq(Boolean.TRUE), eq(template),
|
||||
eq(content), eq(templateParams))).thenReturn(smsLogId);
|
||||
|
||||
// 调用
|
||||
Long resultSmsLogId = smsSendService.sendSingleSms(mobile, userId, userType, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(smsLogId, resultSmsLogId);
|
||||
// 断言调用
|
||||
verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(mobile),
|
||||
eq(template.getChannelId()), eq(template.getApiTemplateId()),
|
||||
eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login"))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送成功,当短信模板关闭时
|
||||
*/
|
||||
@Test
|
||||
public void testSendSingleSms_successWhenSmsTemplateDisable() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
Long userId = randomLongId();
|
||||
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||
String templateCode = randomString();
|
||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||
.put("op", "login").build();
|
||||
// mock SmsTemplateService 的方法
|
||||
SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
o.setContent("验证码为{code}, 操作为{op}");
|
||||
o.setParams(Lists.newArrayList("code", "op"));
|
||||
});
|
||||
when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||
String content = randomString();
|
||||
when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||
.thenReturn(content);
|
||||
// mock SmsChannelService 的方法
|
||||
SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
|
||||
// mock SmsLogService 的方法
|
||||
Long smsLogId = randomLongId();
|
||||
when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(userType), eq(Boolean.FALSE), eq(template),
|
||||
eq(content), eq(templateParams))).thenReturn(smsLogId);
|
||||
|
||||
// 调用
|
||||
Long resultSmsLogId = smsSendService.sendSingleSms(mobile, userId, userType, templateCode, templateParams);
|
||||
// 断言
|
||||
assertEquals(smsLogId, resultSmsLogId);
|
||||
// 断言调用
|
||||
verify(smsProducer, times(0)).sendSmsSendMessage(anyLong(), anyString(),
|
||||
anyLong(), any(), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckSmsTemplateValid_notExists() {
|
||||
// 准备参数
|
||||
String templateCode = randomString();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsSendService.validateSmsTemplate(templateCode),
|
||||
SMS_SEND_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildTemplateParams_paramMiss() {
|
||||
// 准备参数
|
||||
SmsTemplateDO template = randomPojo(SmsTemplateDO.class,
|
||||
o -> o.setParams(Lists.newArrayList("code")));
|
||||
Map<String, Object> templateParams = new HashMap<>();
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsSendService.buildTemplateParams(template, templateParams),
|
||||
SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS, "code");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckMobile_notExists() {
|
||||
// 准备参数
|
||||
// mock 方法
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> smsSendService.validateMobile(null),
|
||||
SMS_SEND_MOBILE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBatchNotify() {
|
||||
// 准备参数
|
||||
// mock 方法
|
||||
|
||||
// 调用
|
||||
UnsupportedOperationException exception = Assertions.assertThrows(
|
||||
UnsupportedOperationException.class,
|
||||
() -> smsSendService.sendBatchSms(null, null, null, null, null)
|
||||
);
|
||||
// 断言
|
||||
assertEquals("暂时不支持该操作,感兴趣可以实现该功能哟!", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testDoSendSms() throws Throwable {
|
||||
// 准备参数
|
||||
SmsSendMessage message = randomPojo(SmsSendMessage.class);
|
||||
// mock SmsClientFactory 的方法
|
||||
SmsClient smsClient = spy(SmsClient.class);
|
||||
when(smsChannelService.getSmsClient(eq(message.getChannelId()))).thenReturn(smsClient);
|
||||
// mock SmsClient 的方法
|
||||
SmsSendRespDTO sendResult = randomPojo(SmsSendRespDTO.class);
|
||||
when(smsClient.sendSms(eq(message.getLogId()), eq(message.getMobile()), eq(message.getApiTemplateId()),
|
||||
eq(message.getTemplateParams()))).thenReturn(sendResult);
|
||||
|
||||
// 调用
|
||||
smsSendService.doSendSms(message);
|
||||
// 断言
|
||||
verify(smsLogService).updateSmsSendResult(eq(message.getLogId()),
|
||||
eq(sendResult.getSuccess()), eq(sendResult.getApiCode()),
|
||||
eq(sendResult.getApiMsg()), eq(sendResult.getApiRequestId()), eq(sendResult.getSerialNo()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveSmsStatus() throws Throwable {
|
||||
// 准备参数
|
||||
String channelCode = randomString();
|
||||
String text = randomString();
|
||||
// mock SmsClientFactory 的方法
|
||||
SmsClient smsClient = spy(SmsClient.class);
|
||||
when(smsChannelService.getSmsClient(eq(channelCode))).thenReturn(smsClient);
|
||||
// mock SmsClient 的方法
|
||||
List<SmsReceiveRespDTO> receiveResults = randomPojoList(SmsReceiveRespDTO.class);
|
||||
|
||||
// 调用
|
||||
smsSendService.receiveSmsStatus(channelCode, text);
|
||||
// 断言
|
||||
receiveResults.forEach(result -> smsLogService.updateSmsReceiveResult(eq(result.getLogId()), eq(result.getSuccess()),
|
||||
eq(result.getReceiveTime()), eq(result.getErrorCode()), eq(result.getErrorCode())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,348 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.sms;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
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.framework.sms.core.client.SmsClient;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateRespDTO;
|
||||
import cn.iocoder.yudao.module.system.framework.sms.core.enums.SmsTemplateAuditStatusEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplatePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.sms.vo.template.SmsTemplateSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsChannelDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.sms.SmsTemplateMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsTemplateTypeEnum;
|
||||
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.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@Import(SmsTemplateServiceImpl.class)
|
||||
public class SmsTemplateServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private SmsTemplateServiceImpl smsTemplateService;
|
||||
|
||||
@Resource
|
||||
private SmsTemplateMapper smsTemplateMapper;
|
||||
|
||||
@MockBean
|
||||
private SmsChannelService smsChannelService;
|
||||
@MockBean
|
||||
private SmsClient smsClient;
|
||||
|
||||
@Test
|
||||
public void testFormatSmsTemplateContent() {
|
||||
// 准备参数
|
||||
String content = "正在进行登录操作{operation},您的验证码是{code}";
|
||||
Map<String, Object> params = MapUtil.<String, Object>builder("operation", "登录")
|
||||
.put("code", "1234").build();
|
||||
|
||||
// 调用
|
||||
String result = smsTemplateService.formatSmsTemplateContent(content, params);
|
||||
// 断言
|
||||
assertEquals("正在进行登录操作登录,您的验证码是1234", result);
|
||||
}
|
||||
|
||||
@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() throws Throwable {
|
||||
// 准备参数
|
||||
SmsTemplateSaveReqVO reqVO = randomPojo(SmsTemplateSaveReqVO.class, o -> {
|
||||
o.setContent("正在进行登录操作{operation},您的验证码是{code}");
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setType(randomEle(SmsTemplateTypeEnum.values()).getType()); // 保证 type 的 范围
|
||||
}).setId(null); // 防止 id 被赋值
|
||||
// mock Channel 的方法
|
||||
SmsChannelDO channelDO = randomPojo(SmsChannelDO.class, o -> {
|
||||
o.setId(reqVO.getChannelId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO);
|
||||
// mock 获得 API 短信模板成功
|
||||
when(smsChannelService.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient);
|
||||
when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(
|
||||
randomPojo(SmsTemplateRespDTO.class, o -> o.setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus())));
|
||||
|
||||
// 调用
|
||||
Long smsTemplateId = smsTemplateService.createSmsTemplate(reqVO);
|
||||
// 断言
|
||||
assertNotNull(smsTemplateId);
|
||||
// 校验记录的属性是否正确
|
||||
SmsTemplateDO smsTemplate = smsTemplateMapper.selectById(smsTemplateId);
|
||||
assertPojoEquals(reqVO, smsTemplate, "id");
|
||||
assertEquals(Lists.newArrayList("operation", "code"), smsTemplate.getParams());
|
||||
assertEquals(channelDO.getCode(), smsTemplate.getChannelCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUpdateSmsTemplate_success() throws Throwable {
|
||||
// mock 数据
|
||||
SmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
|
||||
smsTemplateMapper.insert(dbSmsTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
SmsTemplateSaveReqVO reqVO = randomPojo(SmsTemplateSaveReqVO.class, o -> {
|
||||
o.setId(dbSmsTemplate.getId()); // 设置更新的 ID
|
||||
o.setContent("正在进行登录操作{operation},您的验证码是{code}");
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setType(randomEle(SmsTemplateTypeEnum.values()).getType()); // 保证 type 的 范围
|
||||
});
|
||||
// mock 方法
|
||||
SmsChannelDO channelDO = randomPojo(SmsChannelDO.class, o -> {
|
||||
o.setId(reqVO.getChannelId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelDO.getId()))).thenReturn(channelDO);
|
||||
// mock 获得 API 短信模板成功
|
||||
when(smsChannelService.getSmsClient(eq(reqVO.getChannelId()))).thenReturn(smsClient);
|
||||
when(smsClient.getSmsTemplate(eq(reqVO.getApiTemplateId()))).thenReturn(
|
||||
randomPojo(SmsTemplateRespDTO.class, o -> o.setAuditStatus(SmsTemplateAuditStatusEnum.SUCCESS.getStatus())));
|
||||
|
||||
// 调用
|
||||
smsTemplateService.updateSmsTemplate(reqVO);
|
||||
// 校验是否更新正确
|
||||
SmsTemplateDO smsTemplate = smsTemplateMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, smsTemplate);
|
||||
assertEquals(Lists.newArrayList("operation", "code"), smsTemplate.getParams());
|
||||
assertEquals(channelDO.getCode(), smsTemplate.getChannelCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSmsTemplate_notExists() {
|
||||
// 准备参数
|
||||
SmsTemplateSaveReqVO reqVO = randomPojo(SmsTemplateSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsTemplateService.updateSmsTemplate(reqVO), SMS_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsTemplate_success() {
|
||||
// mock 数据
|
||||
SmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
|
||||
smsTemplateMapper.insert(dbSmsTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsTemplate.getId();
|
||||
|
||||
// 调用
|
||||
smsTemplateService.deleteSmsTemplate(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(smsTemplateMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSmsTemplate_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> smsTemplateService.deleteSmsTemplate(id), SMS_TEMPLATE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplate() {
|
||||
// mock 数据
|
||||
SmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
|
||||
smsTemplateMapper.insert(dbSmsTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSmsTemplate.getId();
|
||||
|
||||
// 调用
|
||||
SmsTemplateDO smsTemplate = smsTemplateService.getSmsTemplate(id);
|
||||
// 校验
|
||||
assertPojoEquals(dbSmsTemplate, smsTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplateByCodeFromCache() {
|
||||
// mock 数据
|
||||
SmsTemplateDO dbSmsTemplate = randomSmsTemplateDO();
|
||||
smsTemplateMapper.insert(dbSmsTemplate);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
String code = dbSmsTemplate.getCode();
|
||||
|
||||
// 调用
|
||||
SmsTemplateDO smsTemplate = smsTemplateService.getSmsTemplateByCodeFromCache(code);
|
||||
// 校验
|
||||
assertPojoEquals(dbSmsTemplate, smsTemplate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplatePage() {
|
||||
// mock 数据
|
||||
SmsTemplateDO dbSmsTemplate = randomPojo(SmsTemplateDO.class, o -> { // 等会查询到
|
||||
o.setType(SmsTemplateTypeEnum.PROMOTION.getType());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCode("tudou");
|
||||
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(SmsTemplateTypeEnum.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))));
|
||||
// 准备参数
|
||||
SmsTemplatePageReqVO reqVO = new SmsTemplatePageReqVO();
|
||||
reqVO.setType(SmsTemplateTypeEnum.PROMOTION.getType());
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCode("tu");
|
||||
reqVO.setContent("芋道");
|
||||
reqVO.setApiTemplateId("yu");
|
||||
reqVO.setChannelId(1L);
|
||||
reqVO.setCreateTime(buildBetweenTime(2021, 11, 1, 2021, 12, 1));
|
||||
|
||||
// 调用
|
||||
PageResult<SmsTemplateDO> pageResult = smsTemplateService.getSmsTemplatePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbSmsTemplate, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSmsTemplateCountByChannelId() {
|
||||
// mock 数据
|
||||
SmsTemplateDO dbSmsTemplate = randomPojo(SmsTemplateDO.class, o -> o.setChannelId(1L));
|
||||
smsTemplateMapper.insert(dbSmsTemplate);
|
||||
// 测试 channelId 不匹配
|
||||
smsTemplateMapper.insert(ObjectUtils.cloneIgnoreId(dbSmsTemplate, o -> o.setChannelId(2L)));
|
||||
// 准备参数
|
||||
Long channelId = 1L;
|
||||
|
||||
// 调用
|
||||
Long count = smsTemplateService.getSmsTemplateCountByChannelId(channelId);
|
||||
// 断言
|
||||
assertEquals(1, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateSmsChannel_success() {
|
||||
// 准备参数
|
||||
Long channelId = randomLongId();
|
||||
// mock 方法
|
||||
SmsChannelDO channelDO = randomPojo(SmsChannelDO.class, o -> {
|
||||
o.setId(channelId);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 保证 status 开启,创建必须处于这个状态
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelId))).thenReturn(channelDO);
|
||||
|
||||
// 调用
|
||||
SmsChannelDO returnChannelDO = smsTemplateService.validateSmsChannel(channelId);
|
||||
// 断言
|
||||
assertPojoEquals(returnChannelDO, channelDO);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateSmsChannel_notExists() {
|
||||
// 准备参数
|
||||
Long channelId = randomLongId();
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.validateSmsChannel(channelId),
|
||||
SMS_CHANNEL_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateSmsChannel_disable() {
|
||||
// 准备参数
|
||||
Long channelId = randomLongId();
|
||||
// mock 方法
|
||||
SmsChannelDO channelDO = randomPojo(SmsChannelDO.class, o -> {
|
||||
o.setId(channelId);
|
||||
o.setStatus(CommonStatusEnum.DISABLE.getStatus()); // 保证 status 禁用,触发失败
|
||||
});
|
||||
when(smsChannelService.getSmsChannel(eq(channelId))).thenReturn(channelDO);
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.validateSmsChannel(channelId),
|
||||
SMS_CHANNEL_DISABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataValueUnique_success() {
|
||||
// 调用,成功
|
||||
smsTemplateService.validateSmsTemplateCodeDuplicate(randomLongId(), randomString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateSmsTemplateCodeDuplicate_valueDuplicateForCreate() {
|
||||
// 准备参数
|
||||
String code = randomString();
|
||||
// mock 数据
|
||||
smsTemplateMapper.insert(randomSmsTemplateDO(o -> o.setCode(code)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.validateSmsTemplateCodeDuplicate(null, code),
|
||||
SMS_TEMPLATE_CODE_DUPLICATE, code);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateDictDataValueUnique_valueDuplicateForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String code = randomString();
|
||||
// mock 数据
|
||||
smsTemplateMapper.insert(randomSmsTemplateDO(o -> o.setCode(code)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> smsTemplateService.validateSmsTemplateCodeDuplicate(id, code),
|
||||
SMS_TEMPLATE_CODE_DUPLICATE, code);
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static SmsTemplateDO randomSmsTemplateDO(Consumer<SmsTemplateDO>... consumers) {
|
||||
Consumer<SmsTemplateDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setType(randomEle(SmsTemplateTypeEnum.values()).getType()); // 保证 type 的 范围
|
||||
};
|
||||
return randomPojo(SmsTemplateDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.tenant;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackagePageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.packages.TenantPackageSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantPackageMapper;
|
||||
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.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link TenantPackageServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(TenantPackageServiceImpl.class)
|
||||
public class TenantPackageServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private TenantPackageServiceImpl tenantPackageService;
|
||||
|
||||
@Resource
|
||||
private TenantPackageMapper tenantPackageMapper;
|
||||
|
||||
@MockBean
|
||||
private TenantService tenantService;
|
||||
|
||||
@Test
|
||||
public void testCreateTenantPackage_success() {
|
||||
// 准备参数
|
||||
TenantPackageSaveReqVO reqVO = randomPojo(TenantPackageSaveReqVO.class,
|
||||
o -> o.setStatus(randomCommonStatus()))
|
||||
.setId(null); // 防止 id 被赋值
|
||||
|
||||
// 调用
|
||||
Long tenantPackageId = tenantPackageService.createTenantPackage(reqVO);
|
||||
// 断言
|
||||
assertNotNull(tenantPackageId);
|
||||
// 校验记录的属性是否正确
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectById(tenantPackageId);
|
||||
assertPojoEquals(reqVO, tenantPackage, "id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenantPackage_success() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(randomCommonStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
TenantPackageSaveReqVO reqVO = randomPojo(TenantPackageSaveReqVO.class, o -> {
|
||||
o.setId(dbTenantPackage.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
});
|
||||
// mock 方法
|
||||
Long tenantId01 = randomLongId();
|
||||
Long tenantId02 = randomLongId();
|
||||
when(tenantService.getTenantListByPackageId(eq(reqVO.getId()))).thenReturn(
|
||||
asList(randomPojo(TenantDO.class, o -> o.setId(tenantId01)),
|
||||
randomPojo(TenantDO.class, o -> o.setId(tenantId02))));
|
||||
|
||||
// 调用
|
||||
tenantPackageService.updateTenantPackage(reqVO);
|
||||
// 校验是否更新正确
|
||||
TenantPackageDO tenantPackage = tenantPackageMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, tenantPackage);
|
||||
// 校验调用租户的菜单
|
||||
verify(tenantService).updateTenantRoleMenu(eq(tenantId01), eq(reqVO.getMenuIds()));
|
||||
verify(tenantService).updateTenantRoleMenu(eq(tenantId02), eq(reqVO.getMenuIds()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenantPackage_notExists() {
|
||||
// 准备参数
|
||||
TenantPackageSaveReqVO reqVO = randomPojo(TenantPackageSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.updateTenantPackage(reqVO), TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenantPackage_success() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenantPackage.getId();
|
||||
// mock 租户未使用该套餐
|
||||
when(tenantService.getTenantCountByPackageId(eq(id))).thenReturn(0L);
|
||||
|
||||
// 调用
|
||||
tenantPackageService.deleteTenantPackage(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(tenantPackageMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenantPackage_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.deleteTenantPackage(id), TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenantPackage_used() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenantPackage.getId();
|
||||
// mock 租户在使用该套餐
|
||||
when(tenantService.getTenantCountByPackageId(eq(id))).thenReturn(1L);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.deleteTenantPackage(id), TENANT_PACKAGE_USED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPackagePage() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class, o -> { // 等会查询到
|
||||
o.setName("芋道源码");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setRemark("源码解析");
|
||||
o.setCreateTime(buildTime(2022, 10, 10));
|
||||
});
|
||||
tenantPackageMapper.insert(dbTenantPackage);
|
||||
// 测试 name 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setName("源码")));
|
||||
// 测试 status 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 remark 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setRemark("解析")));
|
||||
// 测试 createTime 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage, o -> o.setCreateTime(buildTime(2022, 11, 11))));
|
||||
// 准备参数
|
||||
TenantPackagePageReqVO reqVO = new TenantPackagePageReqVO();
|
||||
reqVO.setName("芋道");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setRemark("源码");
|
||||
reqVO.setCreateTime(buildBetweenTime(2022, 10, 9, 2022, 10, 11));
|
||||
|
||||
// 调用
|
||||
PageResult<TenantPackageDO> pageResult = tenantPackageService.getTenantPackagePage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbTenantPackage, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenantPackage_success() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantPackageDO result = tenantPackageService.validTenantPackage(dbTenantPackage.getId());
|
||||
// 断言
|
||||
assertPojoEquals(dbTenantPackage, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenantPackage_notExists() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.validTenantPackage(id), TENANT_PACKAGE_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenantPackage_disable() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantPackageService.validTenantPackage(dbTenantPackage.getId()),
|
||||
TENANT_PACKAGE_DISABLE, dbTenantPackage.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPackage() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class);
|
||||
tenantPackageMapper.insert(dbTenantPackage);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantPackageDO result = tenantPackageService.getTenantPackage(dbTenantPackage.getId());
|
||||
// 断言
|
||||
assertPojoEquals(result, dbTenantPackage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPackageListByStatus() {
|
||||
// mock 数据
|
||||
TenantPackageDO dbTenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
tenantPackageMapper.insert(dbTenantPackage);
|
||||
// 测试 status 不匹配
|
||||
tenantPackageMapper.insert(cloneIgnoreId(dbTenantPackage,
|
||||
o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
|
||||
// 调用
|
||||
List<TenantPackageDO> list = tenantPackageService.getTenantPackageListByStatus(
|
||||
CommonStatusEnum.ENABLE.getStatus());
|
||||
assertEquals(1, list.size());
|
||||
assertPojoEquals(dbTenantPackage, list.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,458 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.tenant;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.tenant.config.TenantProperties;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
|
||||
import cn.iocoder.yudao.module.system.service.permission.MenuService;
|
||||
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
|
||||
import cn.iocoder.yudao.module.system.service.permission.RoleService;
|
||||
import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler;
|
||||
import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
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 javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO.PACKAGE_ID_SYSTEM;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singleton;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* {@link TenantServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(TenantServiceImpl.class)
|
||||
public class TenantServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private TenantServiceImpl tenantService;
|
||||
|
||||
@Resource
|
||||
private TenantMapper tenantMapper;
|
||||
|
||||
@MockBean
|
||||
private TenantProperties tenantProperties;
|
||||
@MockBean
|
||||
private TenantPackageService tenantPackageService;
|
||||
@MockBean
|
||||
private AdminUserService userService;
|
||||
@MockBean
|
||||
private RoleService roleService;
|
||||
@MockBean
|
||||
private MenuService menuService;
|
||||
@MockBean
|
||||
private PermissionService permissionService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
// 清理租户上下文
|
||||
TenantContextHolder.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantIdList() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
List<Long> result = tenantService.getTenantIdList();
|
||||
assertEquals(Collections.singletonList(1L), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_notExists() {
|
||||
assertServiceException(() -> tenantService.validTenant(randomLongId()), TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_disable() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
assertServiceException(() -> tenantService.validTenant(1L), TENANT_DISABLE, tenant.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_expired() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setExpireTime(buildTime(2020, 2, 2)));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
assertServiceException(() -> tenantService.validTenant(1L), TENANT_EXPIRE, tenant.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTenant_success() {
|
||||
// mock 数据
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setId(1L).setStatus(CommonStatusEnum.ENABLE.getStatus())
|
||||
.setExpireTime(LocalDateTime.now().plusDays(1)));
|
||||
tenantMapper.insert(tenant);
|
||||
|
||||
// 调用,并断言业务异常
|
||||
tenantService.validTenant(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTenant() {
|
||||
// mock 套餐 100L
|
||||
TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class, o -> o.setId(100L));
|
||||
when(tenantPackageService.validTenantPackage(eq(100L))).thenReturn(tenantPackage);
|
||||
// mock 角色 200L
|
||||
when(roleService.createRole(argThat(role -> {
|
||||
assertEquals(RoleCodeEnum.TENANT_ADMIN.getName(), role.getName());
|
||||
assertEquals(RoleCodeEnum.TENANT_ADMIN.getCode(), role.getCode());
|
||||
assertEquals(0, role.getSort());
|
||||
assertEquals("系统自动生成", role.getRemark());
|
||||
return true;
|
||||
}), eq(RoleTypeEnum.SYSTEM.getType()))).thenReturn(200L);
|
||||
// mock 用户 300L
|
||||
when(userService.createUser(argThat(user -> {
|
||||
assertEquals("yunai", user.getUsername());
|
||||
assertEquals("yuanma", user.getPassword());
|
||||
assertEquals("芋道", user.getNickname());
|
||||
assertEquals("15601691300", user.getMobile());
|
||||
return true;
|
||||
}))).thenReturn(300L);
|
||||
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
|
||||
o.setContactName("芋道");
|
||||
o.setContactMobile("15601691300");
|
||||
o.setPackageId(100L);
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setWebsite("https://www.iocoder.cn");
|
||||
o.setUsername("yunai");
|
||||
o.setPassword("yuanma");
|
||||
}).setId(null); // 设置为 null,方便后面校验
|
||||
|
||||
// 调用
|
||||
Long tenantId = tenantService.createTenant(reqVO);
|
||||
// 断言
|
||||
assertNotNull(tenantId);
|
||||
// 校验记录的属性是否正确
|
||||
TenantDO tenant = tenantMapper.selectById(tenantId);
|
||||
assertPojoEquals(reqVO, tenant, "id");
|
||||
assertEquals(300L, tenant.getContactUserId());
|
||||
// verify 分配权限
|
||||
verify(permissionService).assignRoleMenu(eq(200L), same(tenantPackage.getMenuIds()));
|
||||
// verify 分配角色
|
||||
verify(permissionService).assignUserRole(eq(300L), eq(singleton(200L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_success() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setStatus(randomCommonStatus()));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
|
||||
o.setId(dbTenant.getId()); // 设置更新的 ID
|
||||
o.setStatus(randomCommonStatus());
|
||||
o.setWebsite(randomString());
|
||||
});
|
||||
|
||||
// mock 套餐
|
||||
TenantPackageDO tenantPackage = randomPojo(TenantPackageDO.class,
|
||||
o -> o.setMenuIds(asSet(200L, 201L)));
|
||||
when(tenantPackageService.validTenantPackage(eq(reqVO.getPackageId()))).thenReturn(tenantPackage);
|
||||
// mock 所有角色
|
||||
RoleDO role100 = randomPojo(RoleDO.class, o -> o.setId(100L).setCode(RoleCodeEnum.TENANT_ADMIN.getCode()));
|
||||
role100.setTenantId(dbTenant.getId());
|
||||
RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L));
|
||||
role101.setTenantId(dbTenant.getId());
|
||||
when(roleService.getRoleList()).thenReturn(asList(role100, role101));
|
||||
// mock 每个角色的权限
|
||||
when(permissionService.getRoleMenuListByRoleId(eq(101L))).thenReturn(asSet(201L, 202L));
|
||||
|
||||
// 调用
|
||||
tenantService.updateTenant(reqVO);
|
||||
// 校验是否更新正确
|
||||
TenantDO tenant = tenantMapper.selectById(reqVO.getId()); // 获取最新的
|
||||
assertPojoEquals(reqVO, tenant);
|
||||
// verify 设置角色权限
|
||||
verify(permissionService).assignRoleMenu(eq(100L), eq(asSet(200L, 201L)));
|
||||
verify(permissionService).assignRoleMenu(eq(101L), eq(asSet(201L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_notExists() {
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateTenant_system() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
TenantSaveReqVO reqVO = randomPojo(TenantSaveReqVO.class, o -> {
|
||||
o.setId(dbTenant.getId()); // 设置更新的 ID
|
||||
});
|
||||
|
||||
// 调用,校验业务异常
|
||||
assertServiceException(() -> tenantService.updateTenant(reqVO), TENANT_CAN_NOT_UPDATE_SYSTEM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteTenant_success() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.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 testDeleteTenant_system() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenant.getId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> tenantService.deleteTenant(id), TENANT_CAN_NOT_UPDATE_SYSTEM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenant() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class);
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbTenant.getId();
|
||||
|
||||
// 调用
|
||||
TenantDO result = tenantService.getTenant(id);
|
||||
// 校验存在
|
||||
assertPojoEquals(result, dbTenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantPage() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.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))));
|
||||
// 准备参数
|
||||
TenantPageReqVO reqVO = new TenantPageReqVO();
|
||||
reqVO.setName("芋道");
|
||||
reqVO.setContactName("艿");
|
||||
reqVO.setContactMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24));
|
||||
|
||||
// 调用
|
||||
PageResult<TenantDO> pageResult = tenantService.getTenantPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbTenant, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantByName() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setName("芋道"));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantDO result = tenantService.getTenantByName("芋道");
|
||||
// 校验存在
|
||||
assertPojoEquals(result, dbTenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantByWebsite() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setWebsite("https://www.iocoder.cn"));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
TenantDO result = tenantService.getTenantByWebsite("https://www.iocoder.cn");
|
||||
// 校验存在
|
||||
assertPojoEquals(result, dbTenant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantListByPackageId() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
|
||||
tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
|
||||
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
|
||||
tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
List<TenantDO> result = tenantService.getTenantListByPackageId(1L);
|
||||
assertEquals(1, result.size());
|
||||
assertPojoEquals(dbTenant1, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTenantCountByPackageId() {
|
||||
// mock 数据
|
||||
TenantDO dbTenant1 = randomPojo(TenantDO.class, o -> o.setPackageId(1L));
|
||||
tenantMapper.insert(dbTenant1);// @Sql: 先插入出一条存在的数据
|
||||
TenantDO dbTenant2 = randomPojo(TenantDO.class, o -> o.setPackageId(2L));
|
||||
tenantMapper.insert(dbTenant2);// @Sql: 先插入出一条存在的数据
|
||||
|
||||
// 调用
|
||||
Long count = tenantService.getTenantCountByPackageId(1L);
|
||||
assertEquals(1, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTenantInfo_disable() {
|
||||
// 准备参数
|
||||
TenantInfoHandler handler = mock(TenantInfoHandler.class);
|
||||
// mock 禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(false);
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantInfo(handler);
|
||||
// 断言
|
||||
verify(handler, never()).handle(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTenantInfo_success() {
|
||||
// 准备参数
|
||||
TenantInfoHandler handler = mock(TenantInfoHandler.class);
|
||||
// mock 未禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(true);
|
||||
// mock 租户
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class);
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
TenantContextHolder.setTenantId(dbTenant.getId());
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantInfo(handler);
|
||||
// 断言
|
||||
verify(handler).handle(argThat(argument -> {
|
||||
assertPojoEquals(dbTenant, argument);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleTenantMenu_disable() {
|
||||
// 准备参数
|
||||
TenantMenuHandler handler = mock(TenantMenuHandler.class);
|
||||
// mock 禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(false);
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantMenu(handler);
|
||||
// 断言
|
||||
verify(handler, never()).handle(any());
|
||||
}
|
||||
|
||||
@Test // 系统租户的情况
|
||||
public void testHandleTenantMenu_system() {
|
||||
// 准备参数
|
||||
TenantMenuHandler handler = mock(TenantMenuHandler.class);
|
||||
// mock 未禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(true);
|
||||
// mock 租户
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(PACKAGE_ID_SYSTEM));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
TenantContextHolder.setTenantId(dbTenant.getId());
|
||||
// mock 菜单
|
||||
when(menuService.getMenuList()).thenReturn(Arrays.asList(randomPojo(MenuDO.class, o -> o.setId(100L)),
|
||||
randomPojo(MenuDO.class, o -> o.setId(101L))));
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantMenu(handler);
|
||||
// 断言
|
||||
verify(handler).handle(asSet(100L, 101L));
|
||||
}
|
||||
|
||||
@Test // 普通租户的情况
|
||||
public void testHandleTenantMenu_normal() {
|
||||
// 准备参数
|
||||
TenantMenuHandler handler = mock(TenantMenuHandler.class);
|
||||
// mock 未禁用
|
||||
when(tenantProperties.getEnable()).thenReturn(true);
|
||||
// mock 租户
|
||||
TenantDO dbTenant = randomPojo(TenantDO.class, o -> o.setPackageId(200L));
|
||||
tenantMapper.insert(dbTenant);// @Sql: 先插入出一条存在的数据
|
||||
TenantContextHolder.setTenantId(dbTenant.getId());
|
||||
// mock 菜单
|
||||
when(tenantPackageService.getTenantPackage(eq(200L))).thenReturn(randomPojo(TenantPackageDO.class,
|
||||
o -> o.setMenuIds(asSet(100L, 101L))));
|
||||
|
||||
// 调用
|
||||
tenantService.handleTenantMenu(handler);
|
||||
// 断言
|
||||
verify(handler).handle(asSet(100L, 101L));
|
||||
}
|
||||
}
|
||||
@@ -1,763 +0,0 @@
|
||||
package cn.iocoder.yudao.module.system.service.user;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
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.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.infra.api.config.ConfigApi;
|
||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
||||
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
|
||||
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
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.util.Collection;
|
||||
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.collection.SetUtils.asSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.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 cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static cn.iocoder.yudao.module.system.service.user.AdminUserServiceImpl.USER_INIT_PASSWORD_KEY;
|
||||
import static java.util.Collections.singleton;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.assertj.core.util.Lists.newArrayList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@Import(AdminUserServiceImpl.class)
|
||||
public class AdminUserServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private AdminUserServiceImpl userService;
|
||||
|
||||
@Resource
|
||||
private AdminUserMapper userMapper;
|
||||
@Resource
|
||||
private UserPostMapper userPostMapper;
|
||||
|
||||
@MockBean
|
||||
private DeptService deptService;
|
||||
@MockBean
|
||||
private PostService postService;
|
||||
@MockBean
|
||||
private PermissionService permissionService;
|
||||
@MockBean
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@MockBean
|
||||
private TenantService tenantService;
|
||||
@MockBean
|
||||
private FileApi fileApi;
|
||||
@MockBean
|
||||
private ConfigApi configApi;
|
||||
|
||||
@BeforeEach
|
||||
public void before() {
|
||||
// mock 初始化密码
|
||||
when(configApi.getConfigValueByKey(USER_INIT_PASSWORD_KEY)).thenReturn("yudaoyuanma");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatUser_success() {
|
||||
// 准备参数
|
||||
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class, o -> {
|
||||
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
|
||||
o.setMobile(randomString());
|
||||
o.setPostIds(asSet(1L, 2L));
|
||||
}).setId(null); // 避免 id 被赋值
|
||||
// mock 账户额度充足
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(1));
|
||||
doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
|
||||
handler.handle(tenant);
|
||||
return true;
|
||||
}));
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(reqVO.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock postService 的方法
|
||||
List<PostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
|
||||
randomPojo(PostDO.class, o -> {
|
||||
o.setId(postId);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}));
|
||||
when(postService.getPostList(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
|
||||
// mock passwordEncoder 的方法
|
||||
when(passwordEncoder.encode(eq(reqVO.getPassword()))).thenReturn("yudaoyuanma");
|
||||
|
||||
// 调用
|
||||
Long userId = userService.createUser(reqVO);
|
||||
// 断言
|
||||
AdminUserDO user = userMapper.selectById(userId);
|
||||
assertPojoEquals(reqVO, user, "password", "id");
|
||||
assertEquals("yudaoyuanma", user.getPassword());
|
||||
assertEquals(CommonStatusEnum.ENABLE.getStatus(), user.getStatus());
|
||||
// 断言关联岗位
|
||||
List<UserPostDO> userPosts = userPostMapper.selectListByUserId(user.getId());
|
||||
assertEquals(1L, userPosts.get(0).getPostId());
|
||||
assertEquals(2L, userPosts.get(1).getPostId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreatUser_max() {
|
||||
// 准备参数
|
||||
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class);
|
||||
// mock 账户额度不足
|
||||
TenantDO tenant = randomPojo(TenantDO.class, o -> o.setAccountCount(-1));
|
||||
doNothing().when(tenantService).handleTenantInfo(argThat(handler -> {
|
||||
handler.handle(tenant);
|
||||
return true;
|
||||
}));
|
||||
|
||||
// 调用,并断言异常
|
||||
assertServiceException(() -> userService.createUser(reqVO), USER_COUNT_MAX, -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUser_success() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO(o -> o.setPostIds(asSet(1L, 2L)));
|
||||
userMapper.insert(dbUser);
|
||||
userPostMapper.insert(new UserPostDO().setUserId(dbUser.getId()).setPostId(1L));
|
||||
userPostMapper.insert(new UserPostDO().setUserId(dbUser.getId()).setPostId(2L));
|
||||
// 准备参数
|
||||
UserSaveReqVO reqVO = randomPojo(UserSaveReqVO.class, o -> {
|
||||
o.setId(dbUser.getId());
|
||||
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
|
||||
o.setMobile(randomString());
|
||||
o.setPostIds(asSet(2L, 3L));
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(reqVO.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock postService 的方法
|
||||
List<PostDO> posts = CollectionUtils.convertList(reqVO.getPostIds(), postId ->
|
||||
randomPojo(PostDO.class, o -> {
|
||||
o.setId(postId);
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
}));
|
||||
when(postService.getPostList(eq(reqVO.getPostIds()), isNull())).thenReturn(posts);
|
||||
|
||||
// 调用
|
||||
userService.updateUser(reqVO);
|
||||
// 断言
|
||||
AdminUserDO user = userMapper.selectById(reqVO.getId());
|
||||
assertPojoEquals(reqVO, user, "password");
|
||||
// 断言关联岗位
|
||||
List<UserPostDO> userPosts = userPostMapper.selectListByUserId(user.getId());
|
||||
assertEquals(2L, userPosts.get(0).getPostId());
|
||||
assertEquals(3L, userPosts.get(1).getPostId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserLogin() {
|
||||
// mock 数据
|
||||
AdminUserDO user = randomAdminUserDO(o -> o.setLoginDate(null));
|
||||
userMapper.insert(user);
|
||||
// 准备参数
|
||||
Long id = user.getId();
|
||||
String loginIp = randomString();
|
||||
|
||||
// 调用
|
||||
userService.updateUserLogin(id, loginIp);
|
||||
// 断言
|
||||
AdminUserDO dbUser = userMapper.selectById(id);
|
||||
assertEquals(loginIp, dbUser.getLoginIp());
|
||||
assertNotNull(dbUser.getLoginDate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserProfile_success() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
UserProfileUpdateReqVO reqVO = randomPojo(UserProfileUpdateReqVO.class, o -> {
|
||||
o.setMobile(randomString());
|
||||
o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());
|
||||
o.setAvatar(randomURL());
|
||||
});
|
||||
|
||||
// 调用
|
||||
userService.updateUserProfile(userId, reqVO);
|
||||
// 断言
|
||||
AdminUserDO user = userMapper.selectById(userId);
|
||||
assertPojoEquals(reqVO, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserPassword_success() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO(o -> o.setPassword("encode:tudou"));
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
UserProfileUpdatePasswordReqVO reqVO = randomPojo(UserProfileUpdatePasswordReqVO.class, o -> {
|
||||
o.setOldPassword("tudou");
|
||||
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);
|
||||
// 断言
|
||||
AdminUserDO user = userMapper.selectById(userId);
|
||||
assertEquals("encode:yuanma", user.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserPassword02_success() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
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);
|
||||
// 断言
|
||||
AdminUserDO user = userMapper.selectById(userId);
|
||||
assertEquals("encode:" + password, user.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUserStatus() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
Integer status = randomCommonStatus();
|
||||
|
||||
// 调用
|
||||
userService.updateUserStatus(userId, status);
|
||||
// 断言
|
||||
AdminUserDO user = userMapper.selectById(userId);
|
||||
assertEquals(status, user.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteUser_success(){
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
|
||||
// 调用数据
|
||||
userService.deleteUser(userId);
|
||||
// 校验结果
|
||||
assertNull(userMapper.selectById(userId));
|
||||
// 校验调用次数
|
||||
verify(permissionService, times(1)).processUserDeleted(eq(userId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserByUsername() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
String username = dbUser.getUsername();
|
||||
|
||||
// 调用
|
||||
AdminUserDO user = userService.getUserByUsername(username);
|
||||
// 断言
|
||||
assertPojoEquals(dbUser, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserByMobile() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
String mobile = dbUser.getMobile();
|
||||
|
||||
// 调用
|
||||
AdminUserDO user = userService.getUserByMobile(mobile);
|
||||
// 断言
|
||||
assertPojoEquals(dbUser, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserPage() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = initGetUserPageData();
|
||||
// 准备参数
|
||||
UserPageReqVO reqVO = new UserPageReqVO();
|
||||
reqVO.setUsername("tu");
|
||||
reqVO.setMobile("1560");
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
reqVO.setCreateTime(buildBetweenTime(2020, 12, 1, 2020, 12, 24));
|
||||
reqVO.setDeptId(1L); // 其中,1L 是 2L 的父部门
|
||||
// mock 方法
|
||||
List<DeptDO> deptList = newArrayList(randomPojo(DeptDO.class, o -> o.setId(2L)));
|
||||
when(deptService.getChildDeptList(eq(reqVO.getDeptId()))).thenReturn(deptList);
|
||||
|
||||
// 调用
|
||||
PageResult<AdminUserDO> pageResult = userService.getUserPage(reqVO);
|
||||
// 断言
|
||||
assertEquals(1, pageResult.getTotal());
|
||||
assertEquals(1, pageResult.getList().size());
|
||||
assertPojoEquals(dbUser, pageResult.getList().get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 getUserPage 方法的测试数据
|
||||
*/
|
||||
private AdminUserDO initGetUserPageData() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO(o -> { // 等会查询到
|
||||
o.setUsername("tudou");
|
||||
o.setMobile("15601691300");
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
o.setCreateTime(buildTime(2020, 12, 12));
|
||||
o.setDeptId(2L);
|
||||
});
|
||||
userMapper.insert(dbUser);
|
||||
// 测试 username 不匹配
|
||||
userMapper.insert(cloneIgnoreId(dbUser, o -> o.setUsername("dou")));
|
||||
// 测试 mobile 不匹配
|
||||
userMapper.insert(cloneIgnoreId(dbUser, o -> o.setMobile("18818260888")));
|
||||
// 测试 status 不匹配
|
||||
userMapper.insert(cloneIgnoreId(dbUser, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||
// 测试 createTime 不匹配
|
||||
userMapper.insert(cloneIgnoreId(dbUser, o -> o.setCreateTime(buildTime(2020, 11, 11))));
|
||||
// 测试 dept 不匹配
|
||||
userMapper.insert(cloneIgnoreId(dbUser, o -> o.setDeptId(0L)));
|
||||
return dbUser;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUser() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
Long userId = dbUser.getId();
|
||||
|
||||
// 调用
|
||||
AdminUserDO user = userService.getUser(userId);
|
||||
// 断言
|
||||
assertPojoEquals(dbUser, user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserListByDeptIds() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO(o -> o.setDeptId(1L));
|
||||
userMapper.insert(dbUser);
|
||||
// 测试 deptId 不匹配
|
||||
userMapper.insert(cloneIgnoreId(dbUser, o -> o.setDeptId(2L)));
|
||||
// 准备参数
|
||||
Collection<Long> deptIds = singleton(1L);
|
||||
|
||||
// 调用
|
||||
List<AdminUserDO> list = userService.getUserListByDeptIds(deptIds);
|
||||
// 断言
|
||||
assertEquals(1, list.size());
|
||||
assertEquals(dbUser, list.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 情况一,校验不通过,导致插入失败
|
||||
*/
|
||||
@Test
|
||||
public void testImportUserList_01() {
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setEmail(randomEmail());
|
||||
o.setMobile(randomMobile());
|
||||
});
|
||||
// mock 方法,模拟失败
|
||||
doThrow(new ServiceException(DEPT_NOT_FOUND)).when(deptService).validateDeptList(any());
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(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 testImportUserList_02() {
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setEmail(randomEmail());
|
||||
o.setMobile(randomMobile());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
// mock passwordEncoder 的方法
|
||||
when(passwordEncoder.encode(eq("yudaoyuanma"))).thenReturn("java");
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(1, respVO.getCreateUsernames().size());
|
||||
AdminUserDO 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 testImportUserList_03() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setUsername(dbUser.getUsername());
|
||||
o.setEmail(randomEmail());
|
||||
o.setMobile(randomMobile());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(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 testImportUserList_04() {
|
||||
// mock 数据
|
||||
AdminUserDO dbUser = randomAdminUserDO();
|
||||
userMapper.insert(dbUser);
|
||||
// 准备参数
|
||||
UserImportExcelVO importUser = randomPojo(UserImportExcelVO.class, o -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
o.setUsername(dbUser.getUsername());
|
||||
o.setEmail(randomEmail());
|
||||
o.setMobile(randomMobile());
|
||||
});
|
||||
// mock deptService 的方法
|
||||
DeptDO dept = randomPojo(DeptDO.class, o -> {
|
||||
o.setId(importUser.getDeptId());
|
||||
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
});
|
||||
when(deptService.getDept(eq(dept.getId()))).thenReturn(dept);
|
||||
|
||||
// 调用
|
||||
UserImportRespVO respVO = userService.importUserList(newArrayList(importUser), true);
|
||||
// 断言
|
||||
assertEquals(0, respVO.getCreateUsernames().size());
|
||||
assertEquals(1, respVO.getUpdateUsernames().size());
|
||||
AdminUserDO user = userMapper.selectByUsername(respVO.getUpdateUsernames().get(0));
|
||||
assertPojoEquals(importUser, user);
|
||||
assertEquals(0, respVO.getFailureUsernames().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUserExists_notExists() {
|
||||
assertServiceException(() -> userService.validateUserExists(randomLongId()), USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUsernameUnique_usernameExistsForCreate() {
|
||||
// 准备参数
|
||||
String username = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setUsername(username)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateUsernameUnique(null, username),
|
||||
USER_USERNAME_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUsernameUnique_usernameExistsForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String username = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setUsername(username)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateUsernameUnique(id, username),
|
||||
USER_USERNAME_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateEmailUnique_emailExistsForCreate() {
|
||||
// 准备参数
|
||||
String email = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setEmail(email)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateEmailUnique(null, email),
|
||||
USER_EMAIL_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateEmailUnique_emailExistsForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String email = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setEmail(email)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateEmailUnique(id, email),
|
||||
USER_EMAIL_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMobileUnique_mobileExistsForCreate() {
|
||||
// 准备参数
|
||||
String mobile = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setMobile(mobile)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateMobileUnique(null, mobile),
|
||||
USER_MOBILE_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateMobileUnique_mobileExistsForUpdate() {
|
||||
// 准备参数
|
||||
Long id = randomLongId();
|
||||
String mobile = randomString();
|
||||
// mock 数据
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setMobile(mobile)));
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateMobileUnique(id, mobile),
|
||||
USER_MOBILE_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateOldPassword_notExists() {
|
||||
assertServiceException(() -> userService.validateOldPassword(randomLongId(), randomString()),
|
||||
USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateOldPassword_passwordFailed() {
|
||||
// mock 数据
|
||||
AdminUserDO user = randomAdminUserDO();
|
||||
userMapper.insert(user);
|
||||
// 准备参数
|
||||
Long id = user.getId();
|
||||
String oldPassword = user.getPassword();
|
||||
|
||||
// 调用,校验异常
|
||||
assertServiceException(() -> userService.validateOldPassword(id, oldPassword),
|
||||
USER_PASSWORD_FAILED);
|
||||
// 校验调用
|
||||
verify(passwordEncoder, times(1)).matches(eq(oldPassword), eq(user.getPassword()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserListByPostIds() {
|
||||
// 准备参数
|
||||
Collection<Long> postIds = asSet(10L, 20L);
|
||||
// mock user1 数据
|
||||
AdminUserDO user1 = randomAdminUserDO(o -> o.setPostIds(asSet(10L, 30L)));
|
||||
userMapper.insert(user1);
|
||||
userPostMapper.insert(new UserPostDO().setUserId(user1.getId()).setPostId(10L));
|
||||
userPostMapper.insert(new UserPostDO().setUserId(user1.getId()).setPostId(30L));
|
||||
// mock user2 数据
|
||||
AdminUserDO user2 = randomAdminUserDO(o -> o.setPostIds(singleton(100L)));
|
||||
userMapper.insert(user2);
|
||||
userPostMapper.insert(new UserPostDO().setUserId(user2.getId()).setPostId(100L));
|
||||
|
||||
// 调用
|
||||
List<AdminUserDO> result = userService.getUserListByPostIds(postIds);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(user1, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserList() {
|
||||
// mock 数据
|
||||
AdminUserDO user = randomAdminUserDO();
|
||||
userMapper.insert(user);
|
||||
// 测试 id 不匹配
|
||||
userMapper.insert(randomAdminUserDO());
|
||||
// 准备参数
|
||||
Collection<Long> ids = singleton(user.getId());
|
||||
|
||||
// 调用
|
||||
List<AdminUserDO> result = userService.getUserList(ids);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(user, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserMap() {
|
||||
// mock 数据
|
||||
AdminUserDO user = randomAdminUserDO();
|
||||
userMapper.insert(user);
|
||||
// 测试 id 不匹配
|
||||
userMapper.insert(randomAdminUserDO());
|
||||
// 准备参数
|
||||
Collection<Long> ids = singleton(user.getId());
|
||||
|
||||
// 调用
|
||||
Map<Long, AdminUserDO> result = userService.getUserMap(ids);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(user, result.get(user.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserListByNickname() {
|
||||
// mock 数据
|
||||
AdminUserDO user = randomAdminUserDO(o -> o.setNickname("芋头"));
|
||||
userMapper.insert(user);
|
||||
// 测试 nickname 不匹配
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setNickname("源码")));
|
||||
// 准备参数
|
||||
String nickname = "芋";
|
||||
|
||||
// 调用
|
||||
List<AdminUserDO> result = userService.getUserListByNickname(nickname);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(user, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserListByStatus() {
|
||||
// mock 数据
|
||||
AdminUserDO user = randomAdminUserDO(o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
||||
userMapper.insert(user);
|
||||
// 测试 status 不匹配
|
||||
userMapper.insert(randomAdminUserDO(o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus())));
|
||||
// 准备参数
|
||||
Integer status = CommonStatusEnum.DISABLE.getStatus();
|
||||
|
||||
// 调用
|
||||
List<AdminUserDO> result = userService.getUserListByStatus(status);
|
||||
// 断言
|
||||
assertEquals(1, result.size());
|
||||
assertEquals(user, result.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUserList_success() {
|
||||
// mock 数据
|
||||
AdminUserDO userDO = randomAdminUserDO().setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
userMapper.insert(userDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(userDO.getId());
|
||||
|
||||
// 调用,无需断言
|
||||
userService.validateUserList(ids);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUserList_notFound() {
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(randomLongId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> userService.validateUserList(ids), USER_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateUserList_notEnable() {
|
||||
// mock 数据
|
||||
AdminUserDO userDO = randomAdminUserDO().setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||
userMapper.insert(userDO);
|
||||
// 准备参数
|
||||
List<Long> ids = singletonList(userDO.getId());
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> userService.validateUserList(ids), USER_IS_DISABLE,
|
||||
userDO.getNickname());
|
||||
}
|
||||
|
||||
// ========== 随机对象 ==========
|
||||
|
||||
@SafeVarargs
|
||||
private static AdminUserDO randomAdminUserDO(Consumer<AdminUserDO>... consumers) {
|
||||
Consumer<AdminUserDO> consumer = (o) -> {
|
||||
o.setStatus(randomEle(CommonStatusEnum.values()).getStatus()); // 保证 status 的范围
|
||||
o.setSex(randomEle(SexEnum.values()).getSex()); // 保证 sex 的范围
|
||||
};
|
||||
return randomPojo(AdminUserDO.class, ArrayUtils.append(consumer, consumers));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user