houzhongyi
2024-07-11 e7c1260db32209a078a962aaa0ad5492c35774fb
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.system.service.sms;
H 2
3 import cn.hutool.core.map.MapUtil;
4 import com.iailab.framework.common.core.KeyValue;
5 import com.iailab.framework.common.enums.CommonStatusEnum;
6 import com.iailab.framework.common.enums.UserTypeEnum;
7 import com.iailab.module.system.framework.sms.core.client.SmsClient;
8 import com.iailab.module.system.framework.sms.core.client.dto.SmsReceiveRespDTO;
9 import com.iailab.module.system.framework.sms.core.client.dto.SmsSendRespDTO;
10 import com.iailab.framework.test.core.ut.BaseMockitoUnitTest;
11 import com.iailab.module.system.dal.dataobject.sms.SmsChannelDO;
12 import com.iailab.module.system.dal.dataobject.sms.SmsTemplateDO;
13 import com.iailab.module.system.dal.dataobject.user.AdminUserDO;
14 import com.iailab.module.system.mq.message.sms.SmsSendMessage;
15 import com.iailab.module.system.mq.producer.sms.SmsProducer;
16 import com.iailab.module.system.service.member.MemberService;
17 import com.iailab.module.system.service.user.AdminUserService;
18 import org.assertj.core.util.Lists;
19 import org.junit.jupiter.api.Assertions;
20 import org.junit.jupiter.api.Test;
21 import org.mockito.InjectMocks;
22 import org.mockito.Mock;
23
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import static cn.hutool.core.util.RandomUtil.randomEle;
29 import static com.iailab.framework.test.core.util.AssertUtils.assertServiceException;
30 import static com.iailab.framework.test.core.util.RandomUtils.*;
31 import static com.iailab.module.system.enums.ErrorCodeConstants.*;
32 import static org.junit.jupiter.api.Assertions.assertEquals;
33 import static org.mockito.ArgumentMatchers.eq;
34 import static org.mockito.Mockito.*;
35
36 public class SmsSendServiceImplTest extends BaseMockitoUnitTest {
37
38     @InjectMocks
39     private SmsSendServiceImpl smsSendService;
40
41     @Mock
42     private AdminUserService adminUserService;
43     @Mock
44     private MemberService memberService;
45     @Mock
46     private SmsChannelService smsChannelService;
47     @Mock
48     private SmsTemplateService smsTemplateService;
49     @Mock
50     private SmsLogService smsLogService;
51     @Mock
52     private SmsProducer smsProducer;
53
54     @Test
55     public void testSendSingleSmsToAdmin() {
56         // 准备参数
57         Long userId = randomLongId();
58         String templateCode = randomString();
59         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
60                 .put("op", "login").build();
61         // mock adminUserService 的方法
62         AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300"));
63         when(adminUserService.getUser(eq(userId))).thenReturn(user);
64
65         // mock SmsTemplateService 的方法
66         SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
67             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
68             o.setContent("验证码为{code}, 操作为{op}");
69             o.setParams(Lists.newArrayList("code", "op"));
70         });
71         when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
72         String content = randomString();
73         when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
74                 .thenReturn(content);
75         // mock SmsChannelService 的方法
76         SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
77         when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
78         // mock SmsLogService 的方法
79         Long smsLogId = randomLongId();
80         when(smsLogService.createSmsLog(eq(user.getMobile()), eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(Boolean.TRUE), eq(template),
81                 eq(content), eq(templateParams))).thenReturn(smsLogId);
82
83         // 调用
84         Long resultSmsLogId = smsSendService.sendSingleSmsToAdmin(null, userId, templateCode, templateParams);
85         // 断言
86         assertEquals(smsLogId, resultSmsLogId);
87         // 断言调用
88         verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(user.getMobile()),
89                 eq(template.getChannelId()), eq(template.getApiTemplateId()),
90                 eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login"))));
91     }
92
93     @Test
94     public void testSendSingleSmsToUser() {
95         // 准备参数
96         Long userId = randomLongId();
97         String templateCode = randomString();
98         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
99                 .put("op", "login").build();
100         // mock memberService 的方法
101         String mobile = "15601691300";
102         when(memberService.getMemberUserMobile(eq(userId))).thenReturn(mobile);
103
104         // mock SmsTemplateService 的方法
105         SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
106             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
107             o.setContent("验证码为{code}, 操作为{op}");
108             o.setParams(Lists.newArrayList("code", "op"));
109         });
110         when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
111         String content = randomString();
112         when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
113                 .thenReturn(content);
114         // mock SmsChannelService 的方法
115         SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
116         when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
117         // mock SmsLogService 的方法
118         Long smsLogId = randomLongId();
119         when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(Boolean.TRUE), eq(template),
120                 eq(content), eq(templateParams))).thenReturn(smsLogId);
121
122         // 调用
123         Long resultSmsLogId = smsSendService.sendSingleSmsToMember(null, userId, templateCode, templateParams);
124         // 断言
125         assertEquals(smsLogId, resultSmsLogId);
126         // 断言调用
127         verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(mobile),
128                 eq(template.getChannelId()), eq(template.getApiTemplateId()),
129                 eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login"))));
130     }
131
132     /**
133      * 发送成功,当短信模板开启时
134      */
135     @Test
136     public void testSendSingleSms_successWhenSmsTemplateEnable() {
137         // 准备参数
138         String mobile = randomString();
139         Long userId = randomLongId();
140         Integer userType = randomEle(UserTypeEnum.values()).getValue();
141         String templateCode = randomString();
142         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
143                 .put("op", "login").build();
144         // mock SmsTemplateService 的方法
145         SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
146             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
147             o.setContent("验证码为{code}, 操作为{op}");
148             o.setParams(Lists.newArrayList("code", "op"));
149         });
150         when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
151         String content = randomString();
152         when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
153                 .thenReturn(content);
154         // mock SmsChannelService 的方法
155         SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
156         when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
157         // mock SmsLogService 的方法
158         Long smsLogId = randomLongId();
159         when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(userType), eq(Boolean.TRUE), eq(template),
160                 eq(content), eq(templateParams))).thenReturn(smsLogId);
161
162         // 调用
163         Long resultSmsLogId = smsSendService.sendSingleSms(mobile, userId, userType, templateCode, templateParams);
164         // 断言
165         assertEquals(smsLogId, resultSmsLogId);
166         // 断言调用
167         verify(smsProducer).sendSmsSendMessage(eq(smsLogId), eq(mobile),
168                 eq(template.getChannelId()), eq(template.getApiTemplateId()),
169                 eq(Lists.newArrayList(new KeyValue<>("code", "1234"), new KeyValue<>("op", "login"))));
170     }
171
172     /**
173      * 发送成功,当短信模板关闭时
174      */
175     @Test
176     public void testSendSingleSms_successWhenSmsTemplateDisable() {
177         // 准备参数
178         String mobile = randomString();
179         Long userId = randomLongId();
180         Integer userType = randomEle(UserTypeEnum.values()).getValue();
181         String templateCode = randomString();
182         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
183                 .put("op", "login").build();
184         // mock SmsTemplateService 的方法
185         SmsTemplateDO template = randomPojo(SmsTemplateDO.class, o -> {
186             o.setStatus(CommonStatusEnum.DISABLE.getStatus());
187             o.setContent("验证码为{code}, 操作为{op}");
188             o.setParams(Lists.newArrayList("code", "op"));
189         });
190         when(smsTemplateService.getSmsTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
191         String content = randomString();
192         when(smsTemplateService.formatSmsTemplateContent(eq(template.getContent()), eq(templateParams)))
193                 .thenReturn(content);
194         // mock SmsChannelService 的方法
195         SmsChannelDO smsChannel = randomPojo(SmsChannelDO.class, o -> o.setStatus(CommonStatusEnum.ENABLE.getStatus()));
196         when(smsChannelService.getSmsChannel(eq(template.getChannelId()))).thenReturn(smsChannel);
197         // mock SmsLogService 的方法
198         Long smsLogId = randomLongId();
199         when(smsLogService.createSmsLog(eq(mobile), eq(userId), eq(userType), eq(Boolean.FALSE), eq(template),
200                 eq(content), eq(templateParams))).thenReturn(smsLogId);
201
202         // 调用
203         Long resultSmsLogId = smsSendService.sendSingleSms(mobile, userId, userType, templateCode, templateParams);
204         // 断言
205         assertEquals(smsLogId, resultSmsLogId);
206         // 断言调用
207         verify(smsProducer, times(0)).sendSmsSendMessage(anyLong(), anyString(),
208                 anyLong(), any(), anyList());
209     }
210
211     @Test
212     public void testCheckSmsTemplateValid_notExists() {
213         // 准备参数
214         String templateCode = randomString();
215         // mock 方法
216
217         // 调用,并断言异常
218         assertServiceException(() -> smsSendService.validateSmsTemplate(templateCode),
219                 SMS_SEND_TEMPLATE_NOT_EXISTS);
220     }
221
222     @Test
223     public void testBuildTemplateParams_paramMiss() {
224         // 准备参数
225         SmsTemplateDO template = randomPojo(SmsTemplateDO.class,
226                 o -> o.setParams(Lists.newArrayList("code")));
227         Map<String, Object> templateParams = new HashMap<>();
228         // mock 方法
229
230         // 调用,并断言异常
231         assertServiceException(() -> smsSendService.buildTemplateParams(template, templateParams),
232                 SMS_SEND_MOBILE_TEMPLATE_PARAM_MISS, "code");
233     }
234
235     @Test
236     public void testCheckMobile_notExists() {
237         // 准备参数
238         // mock 方法
239
240         // 调用,并断言异常
241         assertServiceException(() -> smsSendService.validateMobile(null),
242                 SMS_SEND_MOBILE_NOT_EXISTS);
243     }
244
245     @Test
246     public void testSendBatchNotify() {
247         // 准备参数
248         // mock 方法
249
250         // 调用
251         UnsupportedOperationException exception = Assertions.assertThrows(
252                 UnsupportedOperationException.class,
253                 () -> smsSendService.sendBatchSms(null, null, null, null, null)
254         );
255         // 断言
256         assertEquals("暂时不支持该操作,感兴趣可以实现该功能哟!", exception.getMessage());
257     }
258
259     @Test
260     @SuppressWarnings("unchecked")
261     public void testDoSendSms() throws Throwable {
262         // 准备参数
263         SmsSendMessage message = randomPojo(SmsSendMessage.class);
264         // mock SmsClientFactory 的方法
265         SmsClient smsClient = spy(SmsClient.class);
266         when(smsChannelService.getSmsClient(eq(message.getChannelId()))).thenReturn(smsClient);
267         // mock SmsClient 的方法
268         SmsSendRespDTO sendResult = randomPojo(SmsSendRespDTO.class);
269         when(smsClient.sendSms(eq(message.getLogId()), eq(message.getMobile()), eq(message.getApiTemplateId()),
270                 eq(message.getTemplateParams()))).thenReturn(sendResult);
271
272         // 调用
273         smsSendService.doSendSms(message);
274         // 断言
275         verify(smsLogService).updateSmsSendResult(eq(message.getLogId()),
276                 eq(sendResult.getSuccess()), eq(sendResult.getApiCode()),
277                 eq(sendResult.getApiMsg()), eq(sendResult.getApiRequestId()), eq(sendResult.getSerialNo()));
278     }
279
280     @Test
281     public void testReceiveSmsStatus() throws Throwable {
282         // 准备参数
283         String channelCode = randomString();
284         String text = randomString();
285         // mock SmsClientFactory 的方法
286         SmsClient smsClient = spy(SmsClient.class);
287         when(smsChannelService.getSmsClient(eq(channelCode))).thenReturn(smsClient);
288         // mock SmsClient 的方法
289         List<SmsReceiveRespDTO> receiveResults = randomPojoList(SmsReceiveRespDTO.class);
290
291         // 调用
292         smsSendService.receiveSmsStatus(channelCode, text);
293         // 断言
294         receiveResults.forEach(result -> smsLogService.updateSmsReceiveResult(eq(result.getLogId()), eq(result.getSuccess()),
295                 eq(result.getReceiveTime()), eq(result.getErrorCode()), eq(result.getErrorCode())));
296     }
297
298 }