Browse Source

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

YunaiV 2 years ago
parent
commit
0895ee7d98

+ 7 - 0
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;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import uk.co.jemos.podam.api.PodamFactory;
 import uk.co.jemos.podam.api.PodamFactoryImpl;
+import uk.co.jemos.podam.common.AttributeStrategy;
 
+import javax.validation.constraints.Email;
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.time.LocalDateTime;
 import java.util.Arrays;
@@ -95,6 +98,10 @@ public class RandomUtils {
         return RandomUtil.randomEle(CommonStatusEnum.values()).getStatus();
     }
 
+    public static String randomEmail() {
+        return randomString() + "@qq.com";
+    }
+
     @SafeVarargs
     public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
         T pojo = PODAM_FACTORY.manufacturePojo(clazz);

+ 1 - 1
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;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
-@Api(tags = "管理后台 - 邮账号")
+@Api(tags = "管理后台 - 邮账号")
 @RestController
 @RequestMapping("/system/mail-account")
 public class MailAccountController {

+ 4 - 4
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;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.mail.MailAccount;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountBaseVO;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountRespVO;
-import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountSimpleRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.*;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
@@ -17,7 +15,9 @@ public interface MailAccountConvert {
 
     MailAccountConvert INSTANCE = Mappers.getMapper(MailAccountConvert.class);
 
-    MailAccountDO convert(MailAccountBaseVO bean);
+    MailAccountDO convert(MailAccountCreateReqVO bean);
+
+    MailAccountDO convert(MailAccountUpdateReqVO bean);
 
     MailAccountRespVO convert(MailAccountDO bean);
 

+ 2 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/mail/MailAccountDO.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.system.dal.dataobject.mail;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -21,6 +22,7 @@ public class MailAccountDO extends BaseDO {
     /**
      * 主键
      */
+    @TableId
     private Long id;
     /**
      * 邮箱

+ 0 - 1
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<MailLogDO> {
                 .eqIfPresent(MailLogDO::getUserType, reqVO.getUserType())
                 .likeIfPresent(MailLogDO::getToMail, reqVO.getToMail())
                 .eqIfPresent(MailLogDO::getAccountId, reqVO.getAccountId())
-                .likeIfPresent(MailLogDO::getFromMail, reqVO.getFromMail())
                 .eqIfPresent(MailLogDO::getTemplateId, reqVO.getTemplateId())
                 .eqIfPresent(MailLogDO::getSendStatus, reqVO.getSendStatus())
                 .betweenIfPresent(MailLogDO::getSendTime, reqVO.getSendTime())

+ 2 - 0
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;
 import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
 import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
 import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
+import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -47,6 +48,7 @@ public class MailAccountServiceImpl implements MailAccountService {
      *
      * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
      */
+    @Getter
     private volatile Map<Long, MailAccountDO> mailAccountCache;
 
     @Override

+ 154 - 0
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/mail/MailAccountServiceImplTest.java

@@ -0,0 +1,154 @@
+package cn.iocoder.yudao.module.system.service.mail;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountCreateReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.mail.vo.account.MailAccountUpdateReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
+import cn.iocoder.yudao.module.system.dal.mysql.mail.MailAccountMapper;
+import cn.iocoder.yudao.module.system.mq.producer.mail.MailProducer;
+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.util.Map;
+
+import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
+import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAIL_ACCOUNT_NOT_EXISTS;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.verify;
+
+/**
+* {@link MailAccountServiceImpl} 的单元测试类
+*
+* @author 芋道源码
+*/
+@Import(MailAccountServiceImpl.class)
+public class MailAccountServiceImplTest extends BaseDbUnitTest {
+
+    @Resource
+    private MailAccountServiceImpl mailAccountService;
+
+    @Resource
+    private MailAccountMapper mailAccountMapper;
+
+    @MockBean
+    private MailTemplateService mailTemplateService;
+    @MockBean
+    private MailProducer mailProducer;
+
+    @Test
+    public void testInitLocalCache() {
+        MailAccountDO accountDO1 = randomPojo(MailAccountDO.class);
+        mailAccountMapper.insert(accountDO1);
+        MailAccountDO accountDO02 = randomPojo(MailAccountDO.class);
+        mailAccountMapper.insert(accountDO02);
+
+        // 调用
+        mailAccountService.initLocalCache();
+        // 断言 mailAccountCache 缓存
+        Map<Long, MailAccountDO> mailAccountCache = mailAccountService.getMailAccountCache();
+        assertPojoEquals(accountDO1, mailAccountCache.get(accountDO1.getId()));
+        assertPojoEquals(accountDO02, mailAccountCache.get(accountDO02.getId()));
+    }
+
+    @Test
+    public void testCreateMailAccount_success() {
+        // 准备参数
+        MailAccountCreateReqVO reqVO = randomPojo(MailAccountCreateReqVO.class, o -> o.setMail(randomEmail()));
+
+        // 调用
+        Long mailAccountId = mailAccountService.createMailAccount(reqVO);
+        // 断言
+        assertNotNull(mailAccountId);
+        // 校验记录的属性是否正确
+        MailAccountDO mailAccount = mailAccountMapper.selectById(mailAccountId);
+        assertPojoEquals(reqVO, mailAccount);
+        verify(mailProducer).sendMailAccountRefreshMessage();
+    }
+
+    @Test
+    public void testUpdateMailAccount_success() {
+        // mock 数据
+        MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
+        mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        MailAccountUpdateReqVO reqVO = randomPojo(MailAccountUpdateReqVO.class, o -> {
+            o.setId(dbMailAccount.getId()); // 设置更新的 ID
+            o.setMail(randomEmail());
+        });
+
+        // 调用
+        mailAccountService.updateMailAccount(reqVO);
+        // 校验是否更新正确
+        MailAccountDO mailAccount = mailAccountMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, mailAccount);
+        verify(mailProducer).sendMailAccountRefreshMessage();
+    }
+
+    @Test
+    public void testUpdateMailAccount_notExists() {
+        // 准备参数
+        MailAccountUpdateReqVO reqVO = randomPojo(MailAccountUpdateReqVO.class);
+
+        // 调用, 并断言异常
+        assertServiceException(() -> mailAccountService.updateMailAccount(reqVO), MAIL_ACCOUNT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testDeleteMailAccount_success() {
+        // mock 数据
+        MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class);
+        mailAccountMapper.insert(dbMailAccount);// @Sql: 先插入出一条存在的数据
+        // 准备参数
+        Long id = dbMailAccount.getId();
+
+        // 调用
+        mailAccountService.deleteMailAccount(id);
+       // 校验数据不存在了
+       assertNull(mailAccountMapper.selectById(id));
+        verify(mailProducer).sendMailAccountRefreshMessage();
+    }
+
+    @Test
+    public void testDeleteMailAccount_notExists() {
+        // 准备参数
+        Long id = randomLongId();
+
+        // 调用, 并断言异常
+        assertServiceException(() -> mailAccountService.deleteMailAccount(id), MAIL_ACCOUNT_NOT_EXISTS);
+    }
+
+    @Test
+    public void testGetMailAccountPage() {
+       // mock 数据
+       MailAccountDO dbMailAccount = randomPojo(MailAccountDO.class, o -> { // 等会查询到
+           o.setMail("768@qq.com");
+           o.setUsername("yunai");
+       });
+       mailAccountMapper.insert(dbMailAccount);
+       // 测试 mail 不匹配
+       mailAccountMapper.insert(cloneIgnoreId(dbMailAccount, o -> o.setMail("788@qq.com")));
+       // 测试 username 不匹配
+       mailAccountMapper.insert(cloneIgnoreId(dbMailAccount, o -> o.setUsername("tudou")));
+       // 准备参数
+       MailAccountPageReqVO reqVO = new MailAccountPageReqVO();
+       reqVO.setMail("768");
+       reqVO.setUsername("yu");
+
+       // 调用
+       PageResult<MailAccountDO> pageResult = mailAccountService.getMailAccountPage(reqVO);
+       // 断言
+       assertEquals(1, pageResult.getTotal());
+       assertEquals(1, pageResult.getList().size());
+       assertPojoEquals(dbMailAccount, pageResult.getList().get(0));
+    }
+
+}

+ 1 - 0
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql

@@ -25,3 +25,4 @@ DELETE FROM "system_oauth2_approve";
 DELETE FROM "system_oauth2_access_token";
 DELETE FROM "system_oauth2_refresh_token";
 DELETE FROM "system_oauth2_code";
+DELETE FROM "system_mail_account";

+ 16 - 0
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql

@@ -566,3 +566,19 @@ CREATE TABLE IF NOT EXISTS "system_oauth2_code" (
      "deleted" bit NOT NULL DEFAULT FALSE,
      PRIMARY KEY ("id")
 ) COMMENT 'OAuth2 刷新令牌';
+
+CREATE TABLE IF NOT EXISTS "system_mail_account" (
+     "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+     "mail" varchar NOT NULL,
+     "username" varchar NOT NULL,
+     "password" varchar NOT NULL,
+     "host" varchar NOT NULL,
+     "port" int NOT NULL,
+     "ssl_enable" bit NOT NULL,
+     "creator" varchar DEFAULT '',
+     "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+     "updater" varchar DEFAULT '',
+     "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+     "deleted" bit NOT NULL DEFAULT FALSE,
+     PRIMARY KEY ("id")
+) COMMENT '邮箱账号表';

+ 1 - 3
yudao-ui-admin/src/views/system/mail/account/index.vue

@@ -61,7 +61,7 @@
           <el-input v-model="form.mail" placeholder="请输入邮箱" />
         </el-form-item>
         <el-form-item label="用户名" prop="username">
-          <el-input v-model="form.username" placeholder="请输入用户名" />
+          <el-input v-model="form.username" placeholder="请输入用户名,一般和邮箱一致" />
         </el-form-item>
         <el-form-item label="密码" prop="password">
           <el-input v-model="form.password" placeholder="请输入密码" />
@@ -98,8 +98,6 @@ export default {
     return {
       // 遮罩层
       loading: true,
-      // 导出遮罩层
-      exportLoading: false,
       // 显示搜索条件
       showSearch: true,
       // 总条数