package com.iailab.module.system.service.sms;
|
|
import cn.hutool.core.map.MapUtil;
|
import com.iailab.framework.mybatis.core.enums.SqlConstants;
|
import com.iailab.framework.test.core.ut.BaseDbUnitTest;
|
import com.iailab.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
|
import com.iailab.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
import com.iailab.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
|
import com.iailab.module.system.dal.dataobject.sms.SmsCodeDO;
|
import com.iailab.module.system.dal.mysql.sms.SmsCodeMapper;
|
import com.iailab.module.system.enums.sms.SmsSceneEnum;
|
import com.iailab.module.system.framework.sms.config.SmsCodeProperties;
|
import com.baomidou.mybatisplus.annotation.DbType;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.context.annotation.Import;
|
|
import javax.annotation.Resource;
|
import java.time.Duration;
|
import java.time.LocalDateTime;
|
|
import static cn.hutool.core.util.RandomUtil.randomEle;
|
import static com.iailab.framework.test.core.util.AssertUtils.assertPojoEquals;
|
import static com.iailab.framework.test.core.util.AssertUtils.assertServiceException;
|
import static com.iailab.framework.test.core.util.RandomUtils.randomPojo;
|
import static com.iailab.module.system.enums.ErrorCodeConstants.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.isNull;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
@Import(SmsCodeServiceImpl.class)
|
public class SmsCodeServiceImplTest extends BaseDbUnitTest {
|
|
@Resource
|
private SmsCodeServiceImpl smsCodeService;
|
|
@Resource
|
private SmsCodeMapper smsCodeMapper;
|
|
@MockBean
|
private SmsCodeProperties smsCodeProperties;
|
@MockBean
|
private SmsSendService smsSendService;
|
|
@BeforeEach
|
public void setUp() {
|
when(smsCodeProperties.getExpireTimes()).thenReturn(Duration.ofMinutes(5));
|
when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMinutes(1));
|
when(smsCodeProperties.getSendMaximumQuantityPerDay()).thenReturn(10);
|
when(smsCodeProperties.getBeginCode()).thenReturn(9999);
|
when(smsCodeProperties.getEndCode()).thenReturn(9999);
|
}
|
|
@Test
|
public void sendSmsCode_success() {
|
// 准备参数
|
SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
|
});
|
// mock 方法
|
SqlConstants.init(DbType.MYSQL);
|
|
// 调用
|
smsCodeService.sendSmsCode(reqDTO);
|
// 断言 code 验证码
|
SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
|
assertPojoEquals(reqDTO, smsCodeDO);
|
assertEquals("9999", smsCodeDO.getCode());
|
assertEquals(1, smsCodeDO.getTodayIndex());
|
assertFalse(smsCodeDO.getUsed());
|
// 断言调用
|
verify(smsSendService).sendSingleSms(eq(reqDTO.getMobile()), isNull(), isNull(),
|
eq("user-sms-login"), eq(MapUtil.of("code", "9999")));
|
}
|
|
@Test
|
public void sendSmsCode_tooFast() {
|
// mock 数据
|
SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
|
o -> o.setMobile("15601691300").setTodayIndex(1));
|
smsCodeMapper.insert(smsCodeDO);
|
// 准备参数
|
SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
|
});
|
// mock 方法
|
SqlConstants.init(DbType.MYSQL);
|
|
// 调用,并断言异常
|
assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
|
SMS_CODE_SEND_TOO_FAST);
|
}
|
|
@Test
|
public void sendSmsCode_exceedDay() {
|
// mock 数据
|
SmsCodeDO smsCodeDO = randomPojo(SmsCodeDO.class,
|
o -> o.setMobile("15601691300").setTodayIndex(10).setCreateTime(LocalDateTime.now()));
|
smsCodeMapper.insert(smsCodeDO);
|
// 准备参数
|
SmsCodeSendReqDTO reqDTO = randomPojo(SmsCodeSendReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(SmsSceneEnum.MEMBER_LOGIN.getScene());
|
});
|
// mock 方法
|
SqlConstants.init(DbType.MYSQL);
|
when(smsCodeProperties.getSendFrequency()).thenReturn(Duration.ofMillis(0));
|
|
// 调用,并断言异常
|
assertServiceException(() -> smsCodeService.sendSmsCode(reqDTO),
|
SMS_CODE_EXCEED_SEND_MAXIMUM_QUANTITY_PER_DAY);
|
}
|
|
@Test
|
public void testUseSmsCode_success() {
|
// 准备参数
|
SmsCodeUseReqDTO reqDTO = randomPojo(SmsCodeUseReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
});
|
// mock 数据
|
SqlConstants.init(DbType.MYSQL);
|
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> {
|
o.setMobile(reqDTO.getMobile()).setScene(reqDTO.getScene())
|
.setCode(reqDTO.getCode()).setUsed(false);
|
}));
|
|
// 调用
|
smsCodeService.useSmsCode(reqDTO);
|
// 断言
|
SmsCodeDO smsCodeDO = smsCodeMapper.selectOne(null);
|
assertTrue(smsCodeDO.getUsed());
|
assertNotNull(smsCodeDO.getUsedTime());
|
assertEquals(reqDTO.getUsedIp(), smsCodeDO.getUsedIp());
|
}
|
|
@Test
|
public void validateSmsCode_success() {
|
// 准备参数
|
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
});
|
// mock 数据
|
SqlConstants.init(DbType.MYSQL);
|
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
|
.setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)));
|
|
// 调用
|
smsCodeService.validateSmsCode(reqDTO);
|
}
|
|
@Test
|
public void validateSmsCode_notFound() {
|
// 准备参数
|
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
});
|
// mock 数据
|
SqlConstants.init(DbType.MYSQL);
|
|
// 调用,并断言异常
|
assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
|
SMS_CODE_NOT_FOUND);
|
}
|
|
@Test
|
public void validateSmsCode_expired() {
|
// 准备参数
|
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
});
|
// mock 数据
|
SqlConstants.init(DbType.MYSQL);
|
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
|
.setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(false)
|
.setCreateTime(LocalDateTime.now().minusMinutes(6))));
|
|
// 调用,并断言异常
|
assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
|
SMS_CODE_EXPIRED);
|
}
|
|
@Test
|
public void validateSmsCode_used() {
|
// 准备参数
|
SmsCodeValidateReqDTO reqDTO = randomPojo(SmsCodeValidateReqDTO.class, o -> {
|
o.setMobile("15601691300");
|
o.setScene(randomEle(SmsSceneEnum.values()).getScene());
|
});
|
// mock 数据
|
SqlConstants.init(DbType.MYSQL);
|
smsCodeMapper.insert(randomPojo(SmsCodeDO.class, o -> o.setMobile(reqDTO.getMobile())
|
.setScene(reqDTO.getScene()).setCode(reqDTO.getCode()).setUsed(true)
|
.setCreateTime(LocalDateTime.now())));
|
|
// 调用,并断言异常
|
assertServiceException(() -> smsCodeService.validateSmsCode(reqDTO),
|
SMS_CODE_USED);
|
}
|
|
}
|