1,腾讯云短信实现优化,去除不必要VO;

2,增加腾讯云短信功能单测,和集成单测;
This commit is contained in:
scholar
2024-08-13 19:26:45 +08:00
parent 2f38261de8
commit 8242735d84
3 changed files with 284 additions and 310 deletions

View File

@@ -0,0 +1,139 @@
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
import cn.iocoder.yudao.framework.common.core.KeyValue;
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.property.SmsChannelProperties;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.List;
/**
* 各种 {@link SmsClientTests 集成测试
*
* @author 芋道源码
*/
public class SmsClientTests {
@Test
@Disabled
public void testHuaweiSmsClient_sendSms() throws Throwable {
SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey("123")
.setApiSecret("456")
.setSignature("runpu");
HuaweiSmsClient client = new HuaweiSmsClient(properties);
// 准备参数
Long sendLogId = System.currentTimeMillis();
String mobile = "15601691323";
String apiTemplateId = "xx test01";
List<KeyValue<String, Object>> templateParams = List.of(new KeyValue<>("code", "1024"));
// 调用
SmsSendRespDTO smsSendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
// 打印结果
System.out.println(smsSendRespDTO);
}
// ========== 阿里云 ==========
@Test
@Disabled
public void testAliyunSmsClient_getSmsTemplate() throws Throwable {
SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey("LTAI5tAicJAxaSFiZuGGeXHR")
.setApiSecret("Fdr9vadxnDvS6GJU0W1tijQ0VmLhYz");
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("LTAI5tAicJAxaSFiZuGGeXHR")
.setApiSecret("Fdr9vadxnDvS6GJU0W1tijQ0VmLhYz")
.setSignature("runpu");
AliyunSmsClient client = new AliyunSmsClient(properties);
// 准备参数
Long sendLogId = System.currentTimeMillis();
String mobile = "15601691323";
String apiTemplateId = "SMS_207945135";
// 调用
SmsSendRespDTO sendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, List.of(new KeyValue<>("code", "1024")));
// 打印结果
System.out.println(sendRespDTO);
}
@Test
@Disabled
public void testAliyunSmsClient_parseSmsReceiveStatus() {
SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey("LTAI5tAicJAxaSFiZuGGeXHR")
.setApiSecret("Fdr9vadxnDvS6GJU0W1tijQ0VmLhYz");
AliyunSmsClient client = new AliyunSmsClient(properties);
// 准备参数
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 = client.parseSmsReceiveStatus(text);
// 打印结果
System.out.println(statuses);
}
// ========== 腾讯云 ==========
@Test
@Disabled
public void testTencentSmsClient_sendSms() throws Throwable {
SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey("LTAI5tAicJAxaSFiZuGGeXHR 1428926523")
.setApiSecret("Fdr9vadxnDvS6GJU0W1tijQ0VmLhYz")
.setSignature("芋道源码");
TencentSmsClient client = new TencentSmsClient(properties);
// 准备参数
Long sendLogId = System.currentTimeMillis();
String mobile = "15601691323";
String apiTemplateId = "2136358";
// 调用
SmsSendRespDTO sendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, List.of(new KeyValue<>("code", "1024")));
// 打印结果
System.out.println(sendRespDTO);
}
@Test
@Disabled
public void testTencentSmsClient_getSmsTemplate() throws Throwable {
SmsChannelProperties properties = new SmsChannelProperties()
.setApiKey("LTAI5tAicJAxaSFiZuGGeXHR 1428926523")
.setApiSecret("Fdr9vadxnDvS6GJU0W1tijQ0VmLhYz")
.setSignature("芋道源码");
TencentSmsClient client = new TencentSmsClient(properties);
// 准备参数
String apiTemplateId = "2136358";
// 调用
SmsTemplateRespDTO template = client.getSmsTemplate(apiTemplateId);
// 打印结果
System.out.println(template);
}
}

View File

@@ -1,10 +1,7 @@
package cn.iocoder.yudao.module.system.framework.sms.core.client.impl;
import cn.hutool.core.util.ReflectUtil;
import cn.iocoder.yudao.framework.common.core.KeyValue;
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
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;
@@ -12,24 +9,19 @@ import cn.iocoder.yudao.module.system.framework.sms.core.client.dto.SmsTemplateR
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 com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.DescribeSmsTemplateListResponse;
import com.tencentcloudapi.sms.v20210111.models.DescribeTemplateListStatus;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import com.tencentcloudapi.sms.v20210111.models.SendStatus;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.when;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mockStatic;
/**
* {@link TencentSmsClient} 的单元测试
@@ -46,9 +38,6 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest {
@InjectMocks
private TencentSmsClient smsClient = new TencentSmsClient(properties);
@Mock
private SmsClient client;
@Test
public void testDoInit() {
// 准备参数
@@ -56,103 +45,92 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest {
// 调用
smsClient.doInit();
// 断言
assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "client"));
}
@Test
public void testRefresh() {
// 准备参数
SmsChannelProperties p = new SmsChannelProperties()
.setApiKey(randomString() + " " + randomString()) // 随机一个 apiKey避免构建报错
.setApiSecret(randomString()) // 随机一个 apiSecret避免构建报错
.setSignature("芋道源码");
// 调用
smsClient.refresh(p);
// 断言
assertNotSame(client, ReflectUtil.getFieldValue(smsClient, "client"));
}
@Test
public void testDoSendSms_success() throws Throwable {
// 准备参数
Long sendLogId = randomLongId();
String mobile = randomString();
String apiTemplateId = randomString();
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
String requestId = randomString();
String serialNo = randomString();
// mock 方法
SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> {
o.setRequestId(requestId);
SendStatus[] sendStatuses = new SendStatus[1];
o.setSendStatusSet(sendStatuses);
SendStatus sendStatus = new SendStatus();
sendStatuses[0] = sendStatus;
sendStatus.setCode(TencentSmsClient.API_CODE_SUCCESS);
sendStatus.setMessage("send success");
sendStatus.setSerialNo(serialNo);
});
when(client.SendSms(argThat(request -> {
assertEquals(mobile, request.getPhoneNumberSet()[0]);
assertEquals(properties.getSignature(), request.getSignName());
assertEquals(apiTemplateId, request.getTemplateId());
assertEquals(toJsonString(ArrayUtils.toArray(new ArrayList<>(MapUtils.convertMap(templateParams).values()), String::valueOf)),
toJsonString(request.getTemplateParamSet()));
assertEquals(sendLogId, ReflectUtil.getFieldValue(JsonUtils.parseObject(request.getSessionContext(), TencentSmsClient.SessionContext.class), "logId"));
return true;
}))).thenReturn(response);
// 调用
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
// 断言
assertTrue(result.getSuccess());
assertEquals(response.getRequestId(), result.getApiRequestId());
assertEquals(response.getSendStatusSet()[0].getCode(), result.getApiCode());
assertEquals(response.getSendStatusSet()[0].getMessage(), result.getApiMsg());
assertEquals(response.getSendStatusSet()[0].getSerialNo(), result.getSerialNo());
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() throws Throwable {
// 准备参数
Long sendLogId = randomLongId();
String mobile = randomString();
String apiTemplateId = randomString();
List<KeyValue<String, Object>> templateParams = Lists.newArrayList(
new KeyValue<>("1", 1234), new KeyValue<>("2", "login"));
String requestId = randomString();
String serialNo = randomString();
// mock 方法
SendSmsResponse response = randomPojo(SendSmsResponse.class, o -> {
o.setRequestId(requestId);
SendStatus[] sendStatuses = new SendStatus[1];
o.setSendStatusSet(sendStatuses);
SendStatus sendStatus = new SendStatus();
sendStatuses[0] = sendStatus;
sendStatus.setCode("ERROR");
sendStatus.setMessage("send success");
sendStatus.setSerialNo(serialNo);
});
when(client.SendSms(argThat(request -> {
assertEquals(mobile, request.getPhoneNumberSet()[0]);
assertEquals(properties.getSignature(), request.getSignName());
assertEquals(apiTemplateId, request.getTemplateId());
assertEquals(toJsonString(ArrayUtils.toArray(new ArrayList<>(MapUtils.convertMap(templateParams).values()), String::valueOf)),
toJsonString(request.getTemplateParamSet()));
assertEquals(sendLogId, ReflectUtil.getFieldValue(JsonUtils.parseObject(request.getSessionContext(), TencentSmsClient.SessionContext.class), "logId"));
return true;
}))).thenReturn(response);
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"));
// 调用
SmsSendRespDTO result = smsClient.sendSms(sendLogId, mobile, apiTemplateId, templateParams);
// 断言
assertFalse(result.getSuccess());
assertEquals(response.getRequestId(), result.getApiRequestId());
assertEquals(response.getSendStatusSet()[0].getCode(), result.getApiCode());
assertEquals(response.getSendStatusSet()[0].getMessage(), result.getApiMsg());
assertEquals(response.getSendStatusSet()[0].getSerialNo(), result.getSerialNo());
// 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
@@ -170,7 +148,6 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest {
" \"ext\": {\"logId\":\"67890\"}\n" +
" }\n" +
"]";
// mock 方法
// 调用
List<SmsReceiveRespDTO> statuses = smsClient.parseSmsReceiveStatus(text);
@@ -178,41 +155,45 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest {
assertEquals(1, statuses.size());
assertTrue(statuses.get(0).getSuccess());
assertEquals("DELIVRD", statuses.get(0).getErrorCode());
assertEquals("用户短信送达成功", statuses.get(0).getErrorMsg());
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());
assertEquals(67890L, statuses.get(0).getLogId());
}
@Test
public void testGetSmsTemplate() throws Throwable {
// 准备参数
Long apiTemplateId = randomLongId();
String requestId = randomString();
// mock 方法
DescribeSmsTemplateListResponse response = randomPojo(DescribeSmsTemplateListResponse.class, o -> {
DescribeTemplateListStatus[] describeTemplateListStatuses = new DescribeTemplateListStatus[1];
DescribeTemplateListStatus templateStatus = new DescribeTemplateListStatus();
templateStatus.setTemplateId(apiTemplateId);
templateStatus.setStatusCode(0L);// 设置模板通过
describeTemplateListStatuses[0] = templateStatus;
o.setDescribeTemplateStatusSet(describeTemplateListStatuses);
o.setRequestId(requestId);
});
when(client.DescribeSmsTemplateList(argThat(request -> {
assertEquals(apiTemplateId, request.getTemplateIdSet()[0]);
return true;
}))).thenReturn(response);
try (MockedStatic<HttpUtils> httpUtilsMockedStatic = mockStatic(HttpUtils.class)) {
// 调用
SmsTemplateRespDTO result = smsClient.getSmsTemplate(apiTemplateId.toString());
// 断言
assertEquals(response.getDescribeTemplateStatusSet()[0].getTemplateId().toString(), result.getId());
assertEquals(response.getDescribeTemplateStatusSet()[0].getTemplateContent(), result.getContent());
assertEquals(SmsTemplateAuditStatusEnum.SUCCESS.getStatus(), result.getAuditStatus());
assertEquals(response.getDescribeTemplateStatusSet()[0].getReviewReply(), result.getAuditReason());
// 准备参数
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