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.mybatis.core.enums.SqlConstants;
5 import com.iailab.framework.test.core.ut.BaseDbUnitTest;
6 import com.iailab.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
7 import com.iailab.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
8 import com.iailab.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
9 import com.iailab.module.system.dal.dataobject.sms.SmsCodeDO;
10 import com.iailab.module.system.dal.mysql.sms.SmsCodeMapper;
11 import com.iailab.module.system.enums.sms.SmsSceneEnum;
12 import com.iailab.module.system.framework.sms.config.SmsCodeProperties;
13 import com.baomidou.mybatisplus.annotation.DbType;
14 import org.junit.jupiter.api.BeforeEach;
15 import org.junit.jupiter.api.Test;
16 import org.springframework.boot.test.mock.mockito.MockBean;
17 import org.springframework.context.annotation.Import;
18
19 import javax.annotation.Resource;
20 import java.time.Duration;
21 import java.time.LocalDateTime;
22
23 import static cn.hutool.core.util.RandomUtil.randomEle;
24 import static com.iailab.framework.test.core.util.AssertUtils.assertPojoEquals;
25 import static com.iailab.framework.test.core.util.AssertUtils.assertServiceException;
26 import static com.iailab.framework.test.core.util.RandomUtils.randomPojo;
27 import static com.iailab.module.system.enums.ErrorCodeConstants.*;
28 import static org.junit.jupiter.api.Assertions.*;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.ArgumentMatchers.isNull;
31 import static org.mockito.Mockito.verify;
32 import static org.mockito.Mockito.when;
33
34 @Import(SmsCodeServiceImpl.class)
35 public class SmsCodeServiceImplTest extends BaseDbUnitTest {
36
37     @Resource
38     private SmsCodeServiceImpl smsCodeService;
39
40     @Resource
41     private SmsCodeMapper smsCodeMapper;
42
43     @MockBean
44     private SmsCodeProperties smsCodeProperties;
45     @MockBean
46     private SmsSendService smsSendService;
47
48     @BeforeEach
49     public void setUp() {
50         when(smsCodeProperties.getExpireTimes()).thenReturn(Duration.ofMinutes(5));
51         when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMinutes(1));
52         when(smsCodeProperties.getSendMaximumQuantityPerDay()).thenReturn(10);
53         when(smsCodeProperties.getBeginCode()).thenReturn(9999);
54         when(smsCodeProperties.getEndCode()).thenReturn(9999);
55     }
56
57     @Test
58     public void sendSmsCode_success() {
59         // 准备参数
60         SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
61             o.setMobile("15601691300");
62             o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
63         });
64         // mock 方法
65         SqlConstants.init(DbType.MYSQL);
66
67         // 调用
68         smsCodeService.sendSmsCode(reqDTO);
69         // 断言 code 验证码
70         SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
71         assertPojoEquals(reqDTO, smsCodeDO);
72         assertEquals("9999", smsCodeDO.getCode());
73         assertEquals(1, smsCodeDO.getTodayIndex());
74         assertFalse(smsCodeDO.getUsed());
75         // 断言调用
76         verify(smsSendService).sendSingleSms(eq(reqDTO.getMobile()), isNull(), isNull(),
77                 eq("user-sms-login"), eq(MapUtil.of("code", "9999")));
78     }
79
80     @Test
81     public void sendSmsCode_tooFast() {
82         // mock 数据
83         SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
84                 o -> o.setMobile("15601691300").setTodayIndex(1));
85         smsCodeMapper.insert(smsCodeDO);
86         // 准备参数
87         SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
88             o.setMobile("15601691300");
89             o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
90         });
91         // mock 方法
92         SqlConstants.init(DbType.MYSQL);
93
94         // 调用,并断言异常
95         assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
96                 SMS_CODE_SEND_TOO_FAST);
97     }
98
99     @Test
100     public void sendSmsCode_exceedDay() {
101         // mock 数据
102         SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
103                 o -> o.setMobile("15601691300").setTodayIndex(10).setCreateTime(LocalDateTime.now()));
104         smsCodeMapper.insert(smsCodeDO);
105         // 准备参数
106         SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
107             o.setMobile("15601691300");
108             o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
109         });
110         // mock 方法
111         SqlConstants.init(DbType.MYSQL);
112         when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMillis(0));
113
114         // 调用,并断言异常
115         assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
116                 SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
117     }
118
119     @Test
120     public void testUseSmsCode_success() {
121         // 准备参数
122         SmsCodeUseReqDTO reqDTO = randomPojo(SmsCodeUseReqDTO.class, o -> {
123             o.setMobile("15601691300");
124             o.setScene(randomEle(SmsSceneEnum.values()).getScene());
125         });
126         // mock 数据
127         SqlConstants.init(DbType.MYSQL);
128         smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> {
129             o.setMobile(reqDTO.getMobile()).setScene(reqDTO.getScene())
130                     .setCode(reqDTO.getCode()).setUsed(false);
131         }));
132
133         // 调用
134         smsCodeService.useSmsCode(reqDTO);
135         // 断言
136         SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
137         assertTrue(smsCodeDO.getUsed());
138         assertNotNull(smsCodeDO.getUsedTime());
139         assertEquals(reqDTO.getUsedIp(), smsCodeDO.getUsedIp());
140     }
141
142     @Test
143     public void validateSmsCode_success() {
144         // 准备参数
145         SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
146             o.setMobile("15601691300");
147             o.setScene(randomEle(SmsSceneEnum.values()).getScene());
148         });
149         // mock 数据
150         SqlConstants.init(DbType.MYSQL);
151         smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
152                 .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)));
153
154         // 调用
155         smsCodeService.validateSmsCode(reqDTO);
156     }
157
158     @Test
159     public void validateSmsCode_notFound() {
160         // 准备参数
161         SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
162             o.setMobile("15601691300");
163             o.setScene(randomEle(SmsSceneEnum.values()).getScene());
164         });
165         // mock 数据
166         SqlConstants.init(DbType.MYSQL);
167
168         // 调用,并断言异常
169         assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
170                 SMS_CODE_NOT_FOUND);
171     }
172
173     @Test
174     public void validateSmsCode_expired() {
175         // 准备参数
176         SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
177             o.setMobile("15601691300");
178             o.setScene(randomEle(SmsSceneEnum.values()).getScene());
179         });
180         // mock 数据
181         SqlConstants.init(DbType.MYSQL);
182         smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
183                 .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)
184                 .setCreateTime(LocalDateTime.now().minusMinutes(6))));
185
186         // 调用,并断言异常
187         assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
188                 SMS_CODE_EXPIRED);
189     }
190
191     @Test
192     public void validateSmsCode_used() {
193         // 准备参数
194         SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
195             o.setMobile("15601691300");
196             o.setScene(randomEle(SmsSceneEnum.values()).getScene());
197         });
198         // mock 数据
199         SqlConstants.init(DbType.MYSQL);
200         smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
201                 .setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(true)
202                 .setCreateTime(LocalDateTime.now())));
203
204         // 调用,并断言异常
205         assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
206                 SMS_CODE_USED);
207     }
208
209 }