mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	Merge branch 'develop' of https://gitee.com/scholarli/ruoyi-vue-pro_1 into develop
# Conflicts: # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClient.java # yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/SmsClientTests.java # yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClientTest.java
This commit is contained in:
		| @@ -2,38 +2,30 @@ package cn.iocoder.yudao.module.system.framework.sms.core.client.impl; | ||||
|  | ||||
| import cn.hutool.core.lang.Assert; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import cn.hutool.http.HttpRequest; | ||||
| import cn.hutool.http.HttpResponse; | ||||
| import cn.hutool.json.JSONArray; | ||||
| import cn.hutool.json.JSONObject; | ||||
| import cn.hutool.json.JSONUtil; | ||||
| import cn.iocoder.yudao.framework.common.core.KeyValue; | ||||
| import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | ||||
| import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | ||||
| 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.fasterxml.jackson.annotation.JsonFormat; | ||||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||||
| import com.google.common.annotations.VisibleForTesting; | ||||
| import jakarta.xml.bind.DatatypeConverter; | ||||
| import lombok.Data; | ||||
|  | ||||
| import javax.crypto.Mac; | ||||
| import javax.crypto.spec.SecretKeySpec; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.*; | ||||
|  | ||||
| import static cn.hutool.crypto.digest.DigestUtil.sha256Hex; | ||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||||
| import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||||
| import static cn.iocoder.yudao.framework.common.util.date.DateUtils.TIME_ZONE_DEFAULT; | ||||
|  | ||||
| // TODO @scholar 建议参考 AliyunSmsClient 优化下 | ||||
|  | ||||
| /** | ||||
|  * 腾讯云短信功能实现 | ||||
|  * | ||||
| @@ -104,14 +96,15 @@ public class TencentSmsClient extends AbstractSmsClient { | ||||
|         body.put("TemplateId",apiTemplateId); | ||||
|         body.put("TemplateParamSet",ArrayUtils.toArray(templateParams, e -> String.valueOf(e.getValue()))); | ||||
|  | ||||
|         JSONObject JsonResponse = sendSmsRequest(body,"SendSms","2021-01-11","ap-guangzhou"); | ||||
|         SmsResponse smsResponse = getSmsSendResponse(JsonResponse); | ||||
|  | ||||
|         return new SmsSendRespDTO().setSuccess(smsResponse.success).setApiMsg(smsResponse.data.toString()); | ||||
|         JSONObject JsonResponse = request(body,"SendSms","2021-01-11","ap-guangzhou"); | ||||
|  | ||||
|         return new SmsSendRespDTO().setSuccess(API_CODE_SUCCESS.equals(JsonResponse.getJSONObject("Response").getJSONArray("SendStatusSet").getJSONObject(0).getStr("Code"))) | ||||
|                 .setApiRequestId(JsonResponse.getJSONObject("Response").getStr("RequestId")) | ||||
|                 .setSerialNo(JsonResponse.getJSONObject("Response").getJSONArray("SendStatusSet").getJSONObject(0).getStr("SerialNo")) | ||||
|                 .setApiMsg(JsonResponse.getJSONObject("Response").getJSONArray("SendStatusSet").getJSONObject(0).getStr("Message")); | ||||
|     } | ||||
|  | ||||
|     JSONObject sendSmsRequest(TreeMap<String, Object> body,String action,String version,String region) throws Exception { | ||||
|     JSONObject request(TreeMap<String, Object> body,String action,String version,String region) throws Exception { | ||||
|  | ||||
|         String timestamp = String.valueOf(System.currentTimeMillis() / 1000); | ||||
|         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | ||||
| @@ -156,12 +149,9 @@ public class TencentSmsClient extends AbstractSmsClient { | ||||
|         headers.put("X-TC-Version", version); | ||||
|         headers.put("X-TC-Region", region); | ||||
|  | ||||
|         HttpResponse response = HttpRequest.post("https://"+host) | ||||
|                 .addHeaders(headers) | ||||
|                 .body(JSONUtil.toJsonStr(body)) | ||||
|                 .execute(); | ||||
|         String responseBody = HttpUtils.post("https://"+host, headers, JSONUtil.toJsonStr(body)); | ||||
|  | ||||
|         return JSONUtil.parseObj(response.body()); | ||||
|         return JSONUtil.parseObj(responseBody); | ||||
|     } | ||||
|  | ||||
|     public static byte[] hmac256(byte[] key, String msg) throws Exception { | ||||
| @@ -171,22 +161,20 @@ public class TencentSmsClient extends AbstractSmsClient { | ||||
|         return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8)); | ||||
|     } | ||||
|  | ||||
|     private SmsResponse getSmsSendResponse(JSONObject resJson) { | ||||
|         SmsResponse smsResponse = new SmsResponse(); | ||||
|         JSONArray statusJson =resJson.getJSONObject("Response").getJSONArray("SendStatusSet"); | ||||
|         smsResponse.setSuccess("Ok".equals(statusJson.getJSONObject(0).getStr("Code"))); | ||||
|         smsResponse.setData(resJson); | ||||
|         return smsResponse; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<SmsReceiveRespDTO> parseSmsReceiveStatus(String text) { | ||||
|         List<SmsReceiveStatus> callback = JsonUtils.parseArray(text, SmsReceiveStatus.class); | ||||
|         return convertList(callback, status -> new SmsReceiveRespDTO() | ||||
|                 .setSuccess(SmsReceiveStatus.SUCCESS_CODE.equalsIgnoreCase(status.getStatus())) | ||||
|                 .setErrorCode(status.getErrCode()).setErrorMsg(status.getDescription()) | ||||
|                 .setMobile(status.getMobile()).setReceiveTime(status.getReceiveTime()) | ||||
|                 .setSerialNo(status.getSerialNo()).setLogId(status.getSessionContext().getLogId())); | ||||
|  | ||||
|         JSONArray statuses = JSONUtil.parseArray(text); | ||||
|         // 字段参考 | ||||
|         return convertList(statuses, status -> { | ||||
|             JSONObject statusObj = (JSONObject) status; | ||||
|             return new SmsReceiveRespDTO() | ||||
|                     .setSuccess("SUCCESS".equals(statusObj.getStr("report_status"))) // 是否接收成功 | ||||
|                     .setErrorCode(statusObj.getStr("errmsg")) // 状态报告编码 | ||||
|                     .setMobile(statusObj.getStr("mobile")) // 手机号 | ||||
|                     .setReceiveTime(statusObj.getLocalDateTime("user_receive_time", null)) // 状态报告时间 | ||||
|                     .setSerialNo(statusObj.getStr("sid")); // 发送序列号 | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -194,48 +182,22 @@ public class TencentSmsClient extends AbstractSmsClient { | ||||
|  | ||||
|         // 构建请求 | ||||
|         TreeMap<String, Object> body = new TreeMap<>(); | ||||
|         body.put("International",0); | ||||
|         body.put("International",INTERNATIONAL_CHINA); | ||||
|         Integer[] templateIds = {Integer.valueOf(apiTemplateId)}; | ||||
|         body.put("TemplateIdSet",templateIds); | ||||
|  | ||||
|         JSONObject JsonResponse = sendSmsRequest(body,"DescribeSmsTemplateList","2021-01-11","ap-guangzhou"); | ||||
|         QuerySmsTemplateResponse smsTemplateResponse = getSmsTemplateResponse(JsonResponse); | ||||
|         String templateId = Integer.toString(smsTemplateResponse.getDescribeTemplateStatusSet().get(0).getTemplateId()); | ||||
|         String content = smsTemplateResponse.getDescribeTemplateStatusSet().get(0).getTemplateContent(); | ||||
|         Integer templateStatus = smsTemplateResponse.getDescribeTemplateStatusSet().get(0).getStatusCode(); | ||||
|         String auditReason = smsTemplateResponse.getDescribeTemplateStatusSet().get(0).getReviewReply(); | ||||
|         JSONObject JsonResponse = request(body,"DescribeSmsTemplateList","2021-01-11","ap-guangzhou"); | ||||
|         System.out.println("JsonResponse======"+JsonResponse); | ||||
|  | ||||
|         return new SmsTemplateRespDTO().setId(templateId).setContent(content) | ||||
|         JSONObject TemplateStatusSet = JsonResponse.getJSONObject("Response").getJSONArray("DescribeTemplateStatusSet").getJSONObject(0); | ||||
|         String content = TemplateStatusSet.get("TemplateContent").toString(); | ||||
|         int templateStatus = Integer.parseInt(TemplateStatusSet.get("StatusCode").toString()); | ||||
|         String auditReason = TemplateStatusSet.get("ReviewReply").toString(); | ||||
|  | ||||
|         return new SmsTemplateRespDTO().setId(apiTemplateId).setContent(content) | ||||
|                 .setAuditStatus(convertSmsTemplateAuditStatus(templateStatus)).setAuditReason(auditReason); | ||||
|     } | ||||
|  | ||||
|     private QuerySmsTemplateResponse getSmsTemplateResponse(JSONObject resJson) { | ||||
|  | ||||
|         QuerySmsTemplateResponse smsTemplateResponse = new QuerySmsTemplateResponse(); | ||||
|  | ||||
|         smsTemplateResponse.setRequestId(resJson.getJSONObject("Response").getStr("RequestId")); | ||||
|  | ||||
|         smsTemplateResponse.setDescribeTemplateStatusSet(new ArrayList<>()); | ||||
|  | ||||
|         QuerySmsTemplateResponse.TemplateInfo templateInfo = new QuerySmsTemplateResponse.TemplateInfo(); | ||||
|  | ||||
|         Object statusObject = resJson.getJSONObject("Response").getJSONArray("DescribeTemplateStatusSet").get(0); | ||||
|  | ||||
|         JSONObject statusJSON = new JSONObject(statusObject); | ||||
|  | ||||
|         templateInfo.setTemplateContent(statusJSON.get("TemplateContent").toString()); | ||||
|  | ||||
|         templateInfo.setStatusCode(Integer.parseInt(statusJSON.get("StatusCode").toString())); | ||||
|  | ||||
|         templateInfo.setReviewReply(statusJSON.get("ReviewReply").toString()); | ||||
|  | ||||
|         templateInfo.setTemplateId(Integer.parseInt(statusJSON.get("TemplateId").toString())); | ||||
|  | ||||
|         smsTemplateResponse.getDescribeTemplateStatusSet().add(templateInfo); | ||||
|  | ||||
|         return smsTemplateResponse; | ||||
|     } | ||||
|  | ||||
|     @VisibleForTesting | ||||
|     Integer convertSmsTemplateAuditStatus(int templateStatus) { | ||||
|         switch (templateStatus) { | ||||
| @@ -245,113 +207,4 @@ public class TencentSmsClient extends AbstractSmsClient { | ||||
|             default: throw new IllegalArgumentException(String.format("未知审核状态(%d)", templateStatus)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Data | ||||
|     public static class SmsResponse { | ||||
|  | ||||
|         /** | ||||
|          * 是否成功 | ||||
|          */ | ||||
|         private boolean success; | ||||
|  | ||||
|         /** | ||||
|          * 厂商原返回体 | ||||
|          */ | ||||
|         private Object data; | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * <p>类名: QuerySmsTemplateResponse | ||||
|      * <p>说明:  sms模板查询返回信息 | ||||
|      * | ||||
|      * @author :scholar | ||||
|      * 2024/07/17  0:25 | ||||
|      **/ | ||||
|     @Data | ||||
|     public static class QuerySmsTemplateResponse { | ||||
|         private List<TemplateInfo> DescribeTemplateStatusSet; | ||||
|         private String RequestId; | ||||
|         @Data | ||||
|         static class TemplateInfo { | ||||
|             private String TemplateName; | ||||
|             private Integer TemplateId; | ||||
|             private Integer International; | ||||
|             private String ReviewReply; | ||||
|             private long CreateTime; | ||||
|             private String TemplateContent; | ||||
|             private Integer StatusCode; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Data | ||||
|     private static class SmsReceiveStatus { | ||||
|  | ||||
|         /** | ||||
|          * 短信接受成功 code | ||||
|          */ | ||||
|         public static final String SUCCESS_CODE = "SUCCESS"; | ||||
|  | ||||
|         /** | ||||
|          * 用户实际接收到短信的时间 | ||||
|          */ | ||||
|         @JsonProperty("user_receive_time") | ||||
|         @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND, timezone = TIME_ZONE_DEFAULT) | ||||
|         private LocalDateTime receiveTime; | ||||
|  | ||||
|         /** | ||||
|          * 国家(或地区)码 | ||||
|          */ | ||||
|         @JsonProperty("nationcode") | ||||
|         private String nationCode; | ||||
|  | ||||
|         /** | ||||
|          * 手机号码 | ||||
|          */ | ||||
|         private String mobile; | ||||
|  | ||||
|         /** | ||||
|          * 实际是否收到短信接收状态,SUCCESS(成功)、FAIL(失败) | ||||
|          */ | ||||
|         @JsonProperty("report_status") | ||||
|         private String status; | ||||
|  | ||||
|         /** | ||||
|          * 用户接收短信状态码错误信息 | ||||
|          */ | ||||
|         @JsonProperty("errmsg") | ||||
|         private String errCode; | ||||
|  | ||||
|         /** | ||||
|          * 用户接收短信状态描述 | ||||
|          */ | ||||
|         @JsonProperty("description") | ||||
|         private String description; | ||||
|  | ||||
|         /** | ||||
|          * 本次发送标识 ID(与发送接口返回的SerialNo对应) | ||||
|          */ | ||||
|         @JsonProperty("sid") | ||||
|         private String serialNo; | ||||
|  | ||||
|         /** | ||||
|          * 用户的 session 内容(与发送接口的请求参数 SessionContext 一致) | ||||
|          */ | ||||
|         @JsonProperty("ext") | ||||
|         private SessionContext sessionContext; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @VisibleForTesting | ||||
|     @Data | ||||
|     static class SessionContext { | ||||
|  | ||||
|         /** | ||||
|          * 发送短信记录id | ||||
|          */ | ||||
|         private Long logId; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
| @@ -22,7 +22,8 @@ public class SmsClientTests { | ||||
|     public void testHuaweiSmsClient_sendSms() throws Throwable { | ||||
|         SmsChannelProperties properties = new SmsChannelProperties() | ||||
|                 .setApiKey("123") | ||||
|                 .setApiSecret("456"); | ||||
|                 .setApiSecret("456") | ||||
|                 .setSignature("runpu"); | ||||
|         HuaweiSmsClient client = new HuaweiSmsClient(properties); | ||||
|         // 准备参数 | ||||
|         Long sendLogId = System.currentTimeMillis(); | ||||
| @@ -58,11 +59,11 @@ public class SmsClientTests { | ||||
|         SmsChannelProperties properties = new SmsChannelProperties() | ||||
|                 .setApiKey("LTAI5tAicJAxaSFiZuGGeXHR") | ||||
|                 .setApiSecret("Fdr9vadxnDvS6GJU0W1tijQ0VmLhYz") | ||||
|                 .setSignature("Ballcat"); | ||||
|                 .setSignature("runpu"); | ||||
|         AliyunSmsClient client = new AliyunSmsClient(properties); | ||||
|         // 准备参数 | ||||
|         Long sendLogId = System.currentTimeMillis(); | ||||
|         String mobile = "173213154791"; | ||||
|         String mobile = "15601691323"; | ||||
|         String apiTemplateId = "SMS_207945135"; | ||||
|         // 调用 | ||||
|         SmsSendRespDTO sendRespDTO = client.sendSms(sendLogId, mobile, apiTemplateId, List.of(new KeyValue<>("code", "1024"))); | ||||
| @@ -99,4 +100,40 @@ public class SmsClientTests { | ||||
|         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); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,22 +1,28 @@ | ||||
| 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.http.HttpUtils; | ||||
| import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; | ||||
| 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.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.Mock; | ||||
| import org.mockito.MockedStatic; | ||||
|  | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
|  | ||||
| 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.*; | ||||
| import static org.mockito.ArgumentMatchers.anyString; | ||||
| import static org.mockito.Mockito.mockStatic; | ||||
|  | ||||
| // TODO @芋艿:补全单测 | ||||
| /** | ||||
|  * {@link TencentSmsClient} 的单元测试 | ||||
|  * | ||||
| @@ -32,9 +38,6 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest { | ||||
|     @InjectMocks | ||||
|     private TencentSmsClient smsClient = new TencentSmsClient(properties); | ||||
|  | ||||
|     @Mock | ||||
|     private SmsClient client; | ||||
|  | ||||
|     @Test | ||||
|     public void testDoInit() { | ||||
|         // 准备参数 | ||||
| @@ -42,104 +45,93 @@ 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")); | ||||
|     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_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()); | ||||
| //    } | ||||
|     @Test | ||||
|     public void testDoSendSms_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<>("1", 1234), new KeyValue<>("2", "login")); | ||||
|  | ||||
| //    @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); | ||||
| // | ||||
| //        // 调用 | ||||
| //        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 | ||||
|     public void testParseSmsReceiveStatus() { | ||||
| @@ -156,7 +148,6 @@ public class TencentSmsClientTest extends BaseMockitoUnitTest { | ||||
|                 "        \"ext\": {\"logId\":\"67890\"}\n" + | ||||
|                 "    }\n" + | ||||
|                 "]"; | ||||
|         // mock 方法 | ||||
|  | ||||
|         // 调用 | ||||
|         List<SmsReceiveRespDTO> statuses = smsClient.parseSmsReceiveStatus(text); | ||||
| @@ -164,42 +155,46 @@ 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); | ||||
| // | ||||
| //        // 调用 | ||||
| //        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()); | ||||
| //    } | ||||
|     @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() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV