diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClient.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClient.java index ff3e5ca96..91f4c3f6b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClient.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClient.java @@ -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 body,String action,String version,String region) throws Exception { + JSONObject request(TreeMap 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 parseSmsReceiveStatus(String text) { - List 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 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; - - } - - - /** - *

类名: QuerySmsTemplateResponse - *

说明: sms模板查询返回信息 - * - * @author :scholar - * 2024/07/17 0:25 - **/ - @Data - public static class QuerySmsTemplateResponse { - private List 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; - - } - -} +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/SmsClientTests.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/SmsClientTests.java index a5f31b4a2..b22f0f3f0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/SmsClientTests.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/SmsClientTests.java @@ -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); + } } + diff --git a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClientTest.java b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClientTest.java index 6d621e170..66cb8250e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClientTest.java +++ b/yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/framework/sms/core/client/impl/TencentSmsClientTest.java @@ -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 httpUtilsMockedStatic = mockStatic(HttpUtils.class)) { + // 准备参数 + Long sendLogId = randomLongId(); + String mobile = randomString(); + String apiTemplateId = randomString(); + List> 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> 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 httpUtilsMockedStatic = mockStatic(HttpUtils.class)) { + // 准备参数 + Long sendLogId = randomLongId(); + String mobile = randomString(); + String apiTemplateId = randomString(); + List> 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> 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 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 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() {