houzhongyi
2024-07-11 e7c1260db32209a078a962aaa0ad5492c35774fb
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.system.service.mail;
H 2
3 import cn.hutool.core.map.MapUtil;
4 import cn.hutool.extra.mail.MailAccount;
5 import cn.hutool.extra.mail.MailUtil;
6 import com.iailab.framework.common.enums.CommonStatusEnum;
7 import com.iailab.framework.common.enums.UserTypeEnum;
8 import com.iailab.framework.test.core.ut.BaseMockitoUnitTest;
9 import com.iailab.framework.test.core.util.RandomUtils;
10 import com.iailab.module.system.dal.dataobject.mail.MailAccountDO;
11 import com.iailab.module.system.dal.dataobject.mail.MailTemplateDO;
12 import com.iailab.module.system.dal.dataobject.user.AdminUserDO;
13 import com.iailab.module.system.mq.message.mail.MailSendMessage;
14 import com.iailab.module.system.mq.producer.mail.MailProducer;
15 import com.iailab.module.system.service.member.MemberService;
16 import com.iailab.module.system.service.user.AdminUserService;
17 import org.assertj.core.util.Lists;
18 import org.junit.jupiter.api.Disabled;
19 import org.junit.jupiter.api.Test;
20 import org.mockito.InjectMocks;
21 import org.mockito.Mock;
22 import org.mockito.MockedStatic;
23
24 import java.util.HashMap;
25 import java.util.Map;
26
27 import static cn.hutool.core.util.RandomUtil.randomEle;
28 import static com.iailab.framework.test.core.util.AssertUtils.assertServiceException;
29 import static com.iailab.framework.test.core.util.RandomUtils.*;
30 import static com.iailab.module.system.enums.ErrorCodeConstants.*;
31 import static org.junit.jupiter.api.Assertions.assertEquals;
32 import static org.junit.jupiter.api.Assertions.assertTrue;
33 import static org.mockito.ArgumentMatchers.eq;
34 import static org.mockito.Mockito.*;
35
36 public class MailSendServiceImplTest extends BaseMockitoUnitTest {
37
38     @InjectMocks
39     private MailSendServiceImpl mailSendService;
40
41     @Mock
42     private AdminUserService adminUserService;
43     @Mock
44     private MemberService memberService;
45     @Mock
46     private MailAccountService mailAccountService;
47     @Mock
48     private MailTemplateService mailTemplateService;
49     @Mock
50     private MailLogService mailLogService;
51     @Mock
52     private MailProducer mailProducer;
53
54     /**
55      * 用于快速测试你的邮箱账号是否正常
56      */
57     @Test
58     @Disabled
59     public void testDemo() {
60         MailAccount mailAccount = new MailAccount()
61 //                .setFrom("奥特曼 <ydym_test@163.com>")
62                 .setFrom("ydym_test@163.com") // 邮箱地址
63                 .setHost("smtp.163.com").setPort(465).setSslEnable(true) // SMTP 服务器
64                 .setAuth(true).setUser("ydym_test@163.com").setPass("WBZTEINMIFVRYSOE"); // 登录账号密码
65         String messageId = MailUtil.send(mailAccount, "7685413@qq.com", "主题", "内容", false);
66         System.out.println("发送结果:" + messageId);
67     }
68
69     @Test
70     public void testSendSingleMailToAdmin() {
71         // 准备参数
72         Long userId = randomLongId();
73         String templateCode = RandomUtils.randomString();
74         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
75                 .put("op", "login").build();
76         // mock adminUserService 的方法
77         AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setMobile("15601691300"));
78         when(adminUserService.getUser(eq(userId))).thenReturn(user);
79
80         // mock MailTemplateService 的方法
81         MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
82             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
83             o.setContent("验证码为{code}, 操作为{op}");
84             o.setParams(Lists.newArrayList("code", "op"));
85         });
86         when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
87         String title = RandomUtils.randomString();
88         when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
89                 .thenReturn(title);
90         String content = RandomUtils.randomString();
91         when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
92                 .thenReturn(content);
93         // mock MailAccountService 的方法
94         MailAccountDO account = randomPojo(MailAccountDO.class);
95         when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
96         // mock MailLogService 的方法
97         Long mailLogId = randomLongId();
98         when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.ADMIN.getValue()), eq(user.getEmail()),
99                 eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
100
101         // 调用
102         Long resultMailLogId = mailSendService.sendSingleMailToAdmin(null, userId, templateCode, templateParams);
103         // 断言
104         assertEquals(mailLogId, resultMailLogId);
105         // 断言调用
106         verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(user.getEmail()),
107                 eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
108     }
109
110     @Test
111     public void testSendSingleMailToMember() {
112         // 准备参数
113         Long userId = randomLongId();
114         String templateCode = RandomUtils.randomString();
115         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
116                 .put("op", "login").build();
117         // mock memberService 的方法
118         String mail = randomEmail();
119         when(memberService.getMemberUserEmail(eq(userId))).thenReturn(mail);
120
121         // mock MailTemplateService 的方法
122         MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
123             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
124             o.setContent("验证码为{code}, 操作为{op}");
125             o.setParams(Lists.newArrayList("code", "op"));
126         });
127         when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
128         String title = RandomUtils.randomString();
129         when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
130                 .thenReturn(title);
131         String content = RandomUtils.randomString();
132         when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
133                 .thenReturn(content);
134         // mock MailAccountService 的方法
135         MailAccountDO account = randomPojo(MailAccountDO.class);
136         when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
137         // mock MailLogService 的方法
138         Long mailLogId = randomLongId();
139         when(mailLogService.createMailLog(eq(userId), eq(UserTypeEnum.MEMBER.getValue()), eq(mail),
140                 eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
141
142         // 调用
143         Long resultMailLogId = mailSendService.sendSingleMailToMember(null, userId, templateCode, templateParams);
144         // 断言
145         assertEquals(mailLogId, resultMailLogId);
146         // 断言调用
147         verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail),
148                 eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
149     }
150
151     /**
152      * 发送成功,当短信模板开启时
153      */
154     @Test
155     public void testSendSingleMail_successWhenMailTemplateEnable() {
156         // 准备参数
157         String mail = randomEmail();
158         Long userId = randomLongId();
159         Integer userType = randomEle(UserTypeEnum.values()).getValue();
160         String templateCode = RandomUtils.randomString();
161         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
162                 .put("op", "login").build();
163         // mock MailTemplateService 的方法
164         MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
165             o.setStatus(CommonStatusEnum.ENABLE.getStatus());
166             o.setContent("验证码为{code}, 操作为{op}");
167             o.setParams(Lists.newArrayList("code", "op"));
168         });
169         when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
170         String title = RandomUtils.randomString();
171         when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
172                 .thenReturn(title);
173         String content = RandomUtils.randomString();
174         when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
175                 .thenReturn(content);
176         // mock MailAccountService 的方法
177         MailAccountDO account = randomPojo(MailAccountDO.class);
178         when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
179         // mock MailLogService 的方法
180         Long mailLogId = randomLongId();
181         when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail),
182                 eq(account), eq(template), eq(content), eq(templateParams), eq(true))).thenReturn(mailLogId);
183
184         // 调用
185         Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams);
186         // 断言
187         assertEquals(mailLogId, resultMailLogId);
188         // 断言调用
189         verify(mailProducer).sendMailSendMessage(eq(mailLogId), eq(mail),
190                 eq(account.getId()), eq(template.getNickname()), eq(title), eq(content));
191     }
192
193     /**
194      * 发送成功,当短信模板关闭时
195      */
196     @Test
197     public void testSendSingleMail_successWhenSmsTemplateDisable() {
198         // 准备参数
199         String mail = randomEmail();
200         Long userId = randomLongId();
201         Integer userType = randomEle(UserTypeEnum.values()).getValue();
202         String templateCode = RandomUtils.randomString();
203         Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
204                 .put("op", "login").build();
205         // mock MailTemplateService 的方法
206         MailTemplateDO template = randomPojo(MailTemplateDO.class, o -> {
207             o.setStatus(CommonStatusEnum.DISABLE.getStatus());
208             o.setContent("验证码为{code}, 操作为{op}");
209             o.setParams(Lists.newArrayList("code", "op"));
210         });
211         when(mailTemplateService.getMailTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
212         String title = RandomUtils.randomString();
213         when(mailTemplateService.formatMailTemplateContent(eq(template.getTitle()), eq(templateParams)))
214                 .thenReturn(title);
215         String content = RandomUtils.randomString();
216         when(mailTemplateService.formatMailTemplateContent(eq(template.getContent()), eq(templateParams)))
217                 .thenReturn(content);
218         // mock MailAccountService 的方法
219         MailAccountDO account = randomPojo(MailAccountDO.class);
220         when(mailAccountService.getMailAccountFromCache(eq(template.getAccountId()))).thenReturn(account);
221         // mock MailLogService 的方法
222         Long mailLogId = randomLongId();
223         when(mailLogService.createMailLog(eq(userId), eq(userType), eq(mail),
224                 eq(account), eq(template), eq(content), eq(templateParams), eq(false))).thenReturn(mailLogId);
225
226         // 调用
227         Long resultMailLogId = mailSendService.sendSingleMail(mail, userId, userType, templateCode, templateParams);
228         // 断言
229         assertEquals(mailLogId, resultMailLogId);
230         // 断言调用
231         verify(mailProducer, times(0)).sendMailSendMessage(anyLong(), anyString(),
232                 anyLong(), anyString(), anyString(), anyString());
233     }
234
235     @Test
236     public void testValidateMailTemplateValid_notExists() {
237         // 准备参数
238         String templateCode = RandomUtils.randomString();
239         // mock 方法
240
241         // 调用,并断言异常
242         assertServiceException(() -> mailSendService.validateMailTemplate(templateCode),
243                 MAIL_TEMPLATE_NOT_EXISTS);
244     }
245
246     @Test
247     public void testValidateTemplateParams_paramMiss() {
248         // 准备参数
249         MailTemplateDO template = randomPojo(MailTemplateDO.class,
250                 o -> o.setParams(Lists.newArrayList("code")));
251         Map<String, Object> templateParams = new HashMap<>();
252         // mock 方法
253
254         // 调用,并断言异常
255         assertServiceException(() -> mailSendService.validateTemplateParams(template, templateParams),
256                 MAIL_SEND_TEMPLATE_PARAM_MISS, "code");
257     }
258
259     @Test
260     public void testValidateMail_notExists() {
261         // 准备参数
262         // mock 方法
263
264         // 调用,并断言异常
265         assertServiceException(() -> mailSendService.validateMail(null),
266                 MAIL_SEND_MAIL_NOT_EXISTS);
267     }
268
269     @Test
270     public void testDoSendMail_success() {
271         try (MockedStatic<MailUtil> mailUtilMock = mockStatic(MailUtil.class)) {
272             // 准备参数
273             MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("iailab"));
274             // mock 方法(获得邮箱账号)
275             MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com"));
276             when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId())))
277                     .thenReturn(account);
278
279             // mock 方法(发送邮件)
280             String messageId = randomString();
281             mailUtilMock.when(() -> MailUtil.send(
282                     argThat(mailAccount -> {
283                         assertEquals("iailab <7685@qq.com>", mailAccount.getFrom());
284                         assertTrue(mailAccount.isAuth());
285                         assertEquals(account.getUsername(), mailAccount.getUser());
286                         assertEquals(account.getPassword(), mailAccount.getPass());
287                         assertEquals(account.getHost(), mailAccount.getHost());
288                         assertEquals(account.getPort(), mailAccount.getPort());
289                         assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
290                         return true;
291                     }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true)))
292                     .thenReturn(messageId);
293
294             // 调用
295             mailSendService.doSendMail(message);
296             // 断言
297             verify(mailLogService).updateMailSendResult(eq(message.getLogId()), eq(messageId), isNull());
298         }
299     }
300
301     @Test
302     public void testDoSendMail_exception() {
303         try (MockedStatic<MailUtil> mailUtilMock = mockStatic(MailUtil.class)) {
304             // 准备参数
305             MailSendMessage message = randomPojo(MailSendMessage.class, o -> o.setNickname("iailab"));
306             // mock 方法(获得邮箱账号)
307             MailAccountDO account = randomPojo(MailAccountDO.class, o -> o.setMail("7685@qq.com"));
308             when(mailAccountService.getMailAccountFromCache(eq(message.getAccountId())))
309                     .thenReturn(account);
310
311             // mock 方法(发送邮件)
312             Exception e = new NullPointerException("啦啦啦");
313             mailUtilMock.when(() -> MailUtil.send(argThat(mailAccount -> {
314                         assertEquals("iailab <7685@qq.com>", mailAccount.getFrom());
315                         assertTrue(mailAccount.isAuth());
316                         assertEquals(account.getUsername(), mailAccount.getUser());
317                         assertEquals(account.getPassword(), mailAccount.getPass());
318                         assertEquals(account.getHost(), mailAccount.getHost());
319                         assertEquals(account.getPort(), mailAccount.getPort());
320                         assertEquals(account.getSslEnable(), mailAccount.isSslEnable());
321                         return true;
322                     }), eq(message.getMail()), eq(message.getTitle()), eq(message.getContent()), eq(true)))
323                     .thenThrow(e);
324
325             // 调用
326             mailSendService.doSendMail(message);
327             // 断言
328             verify(mailLogService).updateMailSendResult(eq(message.getLogId()), isNull(), same(e));
329         }
330     }
331
332 }