Commit 0895ee7d988e40c856844ce7e1ca34ad8d32752c

Authored by YunaiV
1 parent 525078ab

邮箱模块:完善 account 的单元测试

yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java
... ... @@ -7,7 +7,10 @@ import cn.hutool.core.util.StrUtil;
7 7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
8 8 import uk.co.jemos.podam.api.PodamFactory;
9 9 import uk.co.jemos.podam.api.PodamFactoryImpl;
  10 +import uk.co.jemos.podam.common.AttributeStrategy;
10 11  
  12 +import javax.validation.constraints.Email;
  13 +import java.lang.annotation.Annotation;
11 14 import java.lang.reflect.Type;
12 15 import java.time.LocalDateTime;
13 16 import java.util.Arrays;
... ... @@ -95,6 +98,10 @@ public class RandomUtils {
95 98 return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
96 99 }
97 100  
  101 + public static String randomEmail() {
  102 + return randomString() + "@qq.com";
  103 + }
  104 +
98 105 @SafeVarargs
99 106 public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
100 107 T pojo = PODAM_FACTORY.manufacturePojo(clazz);
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/mail/MailAccountController.java
... ... @@ -20,7 +20,7 @@ import java.util.List;
20 20  
21 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
22 22  
23   -@Api(tags = "管理后台 - 邮件账号")
  23 +@Api(tags = "管理后台 - 邮箱账号")
24 24 @RestController
25 25 @RequestMapping("/system/mail-account")
26 26 public class MailAccountController {
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/mail/MailAccountConvert.java
... ... @@ -3,9 +3,7 @@ package cn.iocoder.yudao.module.system.convert.mail;
3 3 import cn.hutool.core.util.StrUtil;
4 4 import cn.hutool.extra.mail.MailAccount;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6   -import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountBaseVO;
7   -import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountRespVO;
8   -import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountSimpleRespVO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.*;
9 7 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
10 8 import org.mapstruct.Mapper;
11 9 import org.mapstruct.factory.Mappers;
... ... @@ -17,7 +15,9 @@ public interface MailAccountConvert {
17 15  
18 16 MailAccountConvert INSTANCE = Mappers.getMapper(MailAccountConvert.class);
19 17  
20   - MailAccountDO convert(MailAccountBaseVO bean);
  18 + MailAccountDO convert(MailAccountCreateReqVO bean);
  19 +
  20 + MailAccountDO convert(MailAccountUpdateReqVO bean);
21 21  
22 22 MailAccountRespVO convert(MailAccountDO bean);
23 23  
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailAccountDO.java
1 1 package cn.iocoder.yudao.module.system.dal.dataobject.mail;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.TableId;
4 5 import com.baomidou.mybatisplus.annotation.TableName;
5 6 import lombok.Data;
6 7 import lombok.EqualsAndHashCode;
... ... @@ -21,6 +22,7 @@ public class MailAccountDO extends BaseDO {
21 22 /**
22 23 * 主键
23 24 */
  25 + @TableId
24 26 private Long id;
25 27 /**
26 28 * 邮箱
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/mail/MailLogMapper.java
... ... @@ -16,7 +16,6 @@ public interface MailLogMapper extends BaseMapperX&lt;MailLogDO&gt; {
16 16 .eqIfPresent(MailLogDO::getUserType, reqVO.getUserType())
17 17 .likeIfPresent(MailLogDO::getToMail, reqVO.getToMail())
18 18 .eqIfPresent(MailLogDO::getAccountId, reqVO.getAccountId())
19   - .likeIfPresent(MailLogDO::getFromMail, reqVO.getFromMail())
20 19 .eqIfPresent(MailLogDO::getTemplateId, reqVO.getTemplateId())
21 20 .eqIfPresent(MailLogDO::getSendStatus, reqVO.getSendStatus())
22 21 .betweenIfPresent(MailLogDO::getSendTime, reqVO.getSendTime())
... ...
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImpl.java
... ... @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.convert.mail.MailAccountConvert;
8 8 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
9 9 import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
10 10 import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
  11 +import lombok.Getter;
11 12 import lombok.extern.slf4j.Slf4j;
12 13 import org.springframework.stereotype.Service;
13 14 import org.springframework.validation.annotation.Validated;
... ... @@ -47,6 +48,7 @@ public class MailAccountServiceImpl implements MailAccountService {
47 48 *
48 49 * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
49 50 */
  51 + @Getter
50 52 private volatile Map<Long, MailAccountDO> mailAccountCache;
51 53  
52 54 @Override
... ...
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImplTest.java 0 → 100755
  1 +package cn.iocoder.yudao.module.system.service.mail;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountCreateReqVO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
  7 +import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountUpdateReqVO;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
  9 +import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
  10 +import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
  11 +import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.springframework.boot.test.mock.mockito.MockBean;
  14 +import org.springframework.context.annotation.Import;
  15 +
  16 +import javax.annotation.Resource;
  17 +
  18 +import java.util.Map;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  21 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  22 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  23 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
  24 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS;
  25 +import static org.junit.jupiter.api.Assertions.*;
  26 +import static org.mockito.Mockito.verify;
  27 +
  28 +/**
  29 +* {@link MailAccountServiceImpl} 的单元测试类
  30 +*
  31 +* @author 芋道源码
  32 +*/
  33 +@Import(MailAccountServiceImpl.class)
  34 +public class MailAccountServiceImplTest extends BaseDbUnitTest {
  35 +
  36 + @Resource
  37 + private MailAccountServiceImpl mailAccountService;
  38 +
  39 + @Resource
  40 + private MailAccountMapper mailAccountMapper;
  41 +
  42 + @MockBean
  43 + private MailTemplateService mailTemplateService;
  44 + @MockBean
  45 + private MailProducer mailProducer;
  46 +
  47 + @Test
  48 + public void testInitLocalCache() {
  49 + MailAccountDO accountDO1 = randomPojo(MailAccountDO.class);
  50 + mailAccountMapper.insert(accountDO1);
  51 + MailAccountDO accountDO02 = randomPojo(MailAccountDO.class);
  52 + mailAccountMapper.insert(accountDO02);
  53 +
  54 + // 调用
  55 + mailAccountService.initLocalCache();
  56 + // 断言 mailAccountCache 缓存
  57 + Map<Long, MailAccountDO> mailAccountCache = mailAccountService.getMailAccountCache();
  58 + assertPojoEquals(accountDO1, mailAccountCache.get(accountDO1.getId()));
  59 + assertPojoEquals(accountDO02, mailAccountCache.get(accountDO02.getId()));
  60 + }
  61 +
  62 + @Test
  63 + public void testCreateMailAccount_success() {
  64 + // 准备参数
  65 + MailAccountCreateReqVO reqVO = randomPojo(MailAccountCreateReqVO.class, o -> o.setMail(randomEmail()));
  66 +
  67 + // 调用
  68 + Long mailAccountId = mailAccountService.createMailAccount(reqVO);
  69 + // 断言
  70 + assertNotNull(mailAccountId);
  71 + // 校验记录的属性是否正确
  72 + MailAccountDO mailAccount = mailAccountMapper.selectById(mailAccountId);
  73 + assertPojoEquals(reqVO, mailAccount);
  74 + verify(mailProducer).sendMailAccountRefreshMessage();
  75 + }
  76 +
  77 + @Test
  78 + public void testUpdateMailAccount_success() {
  79 + // mock 数据
  80 + MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
  81 + mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
  82 + // 准备参数
  83 + MailAccountUpdateReqVO reqVO = randomPojo(MailAccountUpdateReqVO.class, o -> {
  84 + o.setId(dbMailAccount.getId()); // 设置更新的 ID
  85 + o.setMail(randomEmail());
  86 + });
  87 +
  88 + // 调用
  89 + mailAccountService.updateMailAccount(reqVO);
  90 + // 校验是否更新正确
  91 + MailAccountDO mailAccount = mailAccountMapper.selectById(reqVO.getId()); // 获取最新的
  92 + assertPojoEquals(reqVO, mailAccount);
  93 + verify(mailProducer).sendMailAccountRefreshMessage();
  94 + }
  95 +
  96 + @Test
  97 + public void testUpdateMailAccount_notExists() {
  98 + // 准备参数
  99 + MailAccountUpdateReqVO reqVO = randomPojo(MailAccountUpdateReqVO.class);
  100 +
  101 + // 调用, 并断言异常
  102 + assertServiceException(() -> mailAccountService.updateMailAccount(reqVO), MAIL_ACCOUNT_NOT_EXISTS);
  103 + }
  104 +
  105 + @Test
  106 + public void testDeleteMailAccount_success() {
  107 + // mock 数据
  108 + MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
  109 + mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
  110 + // 准备参数
  111 + Long id = dbMailAccount.getId();
  112 +
  113 + // 调用
  114 + mailAccountService.deleteMailAccount(id);
  115 + // 校验数据不存在了
  116 + assertNull(mailAccountMapper.selectById(id));
  117 + verify(mailProducer).sendMailAccountRefreshMessage();
  118 + }
  119 +
  120 + @Test
  121 + public void testDeleteMailAccount_notExists() {
  122 + // 准备参数
  123 + Long id = randomLongId();
  124 +
  125 + // 调用, 并断言异常
  126 + assertServiceException(() -> mailAccountService.deleteMailAccount(id), MAIL_ACCOUNT_NOT_EXISTS);
  127 + }
  128 +
  129 + @Test
  130 + public void testGetMailAccountPage() {
  131 + // mock 数据
  132 + MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class, o -> { // 等会查询到
  133 + o.setMail("768@qq.com");
  134 + o.setUsername("yunai");
  135 + });
  136 + mailAccountMapper.insert(dbMailAccount);
  137 + // 测试 mail 不匹配
  138 + mailAccountMapper.insert(cloneIgnoreId(dbMailAccount, o -> o.setMail("788@qq.com")));
  139 + // 测试 username 不匹配
  140 + mailAccountMapper.insert(cloneIgnoreId(dbMailAccount, o -> o.setUsername("tudou")));
  141 + // 准备参数
  142 + MailAccountPageReqVO reqVO = new MailAccountPageReqVO();
  143 + reqVO.setMail("768");
  144 + reqVO.setUsername("yu");
  145 +
  146 + // 调用
  147 + PageResult<MailAccountDO> pageResult = mailAccountService.getMailAccountPage(reqVO);
  148 + // 断言
  149 + assertEquals(1, pageResult.getTotal());
  150 + assertEquals(1, pageResult.getList().size());
  151 + assertPojoEquals(dbMailAccount, pageResult.getList().get(0));
  152 + }
  153 +
  154 +}
... ...
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql
... ... @@ -25,3 +25,4 @@ DELETE FROM &quot;system_oauth2_approve&quot;;
25 25 DELETE FROM "system_oauth2_access_token";
26 26 DELETE FROM "system_oauth2_refresh_token";
27 27 DELETE FROM "system_oauth2_code";
  28 +DELETE FROM "system_mail_account";
... ...
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql
... ... @@ -566,3 +566,19 @@ CREATE TABLE IF NOT EXISTS &quot;system_oauth2_code&quot; (
566 566 "deleted" bit NOT NULL DEFAULT FALSE,
567 567 PRIMARY KEY ("id")
568 568 ) COMMENT 'OAuth2 刷新令牌';
  569 +
  570 +CREATE TABLE IF NOT EXISTS "system_mail_account" (
  571 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  572 + "mail" varchar NOT NULL,
  573 + "username" varchar NOT NULL,
  574 + "password" varchar NOT NULL,
  575 + "host" varchar NOT NULL,
  576 + "port" int NOT NULL,
  577 + "ssl_enable" bit NOT NULL,
  578 + "creator" varchar DEFAULT '',
  579 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  580 + "updater" varchar DEFAULT '',
  581 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  582 + "deleted" bit NOT NULL DEFAULT FALSE,
  583 + PRIMARY KEY ("id")
  584 +) COMMENT '邮箱账号表';
... ...
yudao-ui-admin/src/views/system/mail/account/index.vue
... ... @@ -61,7 +61,7 @@
61 61 <el-input v-model="form.mail" placeholder="请输入邮箱" />
62 62 </el-form-item>
63 63 <el-form-item label="用户名" prop="username">
64   - <el-input v-model="form.username" placeholder="请输入用户名" />
  64 + <el-input v-model="form.username" placeholder="请输入用户名,一般和邮箱一致" />
65 65 </el-form-item>
66 66 <el-form-item label="密码" prop="password">
67 67 <el-input v-model="form.password" placeholder="请输入密码" />
... ... @@ -98,8 +98,6 @@ export default {
98 98 return {
99 99 // 遮罩层
100 100 loading: true,
101   - // 导出遮罩层
102   - exportLoading: false,
103 101 // 显示搜索条件
104 102 showSearch: true,
105 103 // 总条数
... ...