Commit 9d9836dea2e31ed719cad443ab20a8fa2b8c806f

Authored by YunaiV
1 parent 696756b3

完善敏感词的单元测试

sql/ruoyi-vue-pro.sql
No preview for this file type
yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImpl.java
... ... @@ -46,15 +46,6 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
46 46 private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
47 47  
48 48 /**
49   - * 敏感词缓存
50   - * key:敏感词编号 {@link SensitiveWordDO#getId()}
51   - * <p>
52   - * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
53   - */
54   - @Getter
55   - private volatile Map<Long, SensitiveWordDO> sensitiveWordCache = Collections.emptyMap();
56   -
57   - /**
58 49 * 敏感词标签缓存
59 50 * key:敏感词编号 {@link SensitiveWordDO#getId()}
60 51 * <p>
... ... @@ -78,14 +69,16 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
78 69 /**
79 70 * 默认的敏感词的字典树,包含所有敏感词
80 71 */
  72 + @Getter
81 73 private volatile SimpleTrie defaultSensitiveWordTrie = new SimpleTrie(Collections.emptySet());
82 74 /**
83 75 * 标签与敏感词的字段数的映射
84 76 */
  77 + @Getter
85 78 private volatile Map<String, SimpleTrie> tagSensitiveWordTries = Collections.emptyMap();
86 79  
87 80 /**
88   - * 初始化 {@link #sensitiveWordCache} 缓存
  81 + * 初始化缓存
89 82 */
90 83 @Override
91 84 @PostConstruct
... ... @@ -102,8 +95,7 @@ public class SensitiveWordServiceImpl implements SensitiveWordService {
102 95 sensitiveWordTagsCache = tags;
103 96 // 写入 defaultSensitiveWordTrie、tagSensitiveWordTries 缓存
104 97 initSensitiveWordTrie(sensitiveWordList);
105   - // 写入 sensitiveWordCache 缓存
106   - sensitiveWordCache = CollectionUtils.convertMap(sensitiveWordList, SensitiveWordDO::getId);
  98 + // 写入 maxUpdateTime 最大更新时间
107 99 maxUpdateTime = CollectionUtils.getMaxValue(sensitiveWordList, SensitiveWordDO::getUpdateTime);
108 100 log.info("[initLocalCache][初始化 敏感词 数量为 {}]", sensitiveWordList.size());
109 101 }
... ...
yudao-module-system/yudao-module-system-impl/src/test/java/cn/iocoder/yudao/module/system/service/sensitiveword/SensitiveWordServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.sensitiveword;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  6 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
  7 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  8 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordCreateReqVO;
  9 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordExportReqVO;
  10 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordPageReqVO;
  11 +import cn.iocoder.yudao.module.system.controller.admin.sensitiveword.vo.SensitiveWordUpdateReqVO;
  12 +import cn.iocoder.yudao.module.system.dal.dataobject.sensitiveword.SensitiveWordDO;
  13 +import cn.iocoder.yudao.module.system.dal.mysql.sensitiveword.SensitiveWordMapper;
  14 +import cn.iocoder.yudao.module.system.mq.producer.sensitiveword.SensitiveWordProducer;
  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.util.Arrays;
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  24 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.max;
  25 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  26 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
  27 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  28 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  29 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SENSITIVE_WORD_NOT_EXISTS;
  30 +import static java.util.Collections.singletonList;
  31 +import static org.junit.jupiter.api.Assertions.*;
  32 +import static org.mockito.Mockito.verify;
  33 +
  34 +/**
  35 + * {@link SensitiveWordServiceImpl} 的单元测试类
  36 + *
  37 + * @author 永不言败
  38 + */
  39 +@Import(SensitiveWordServiceImpl.class)
  40 +public class SensitiveWordServiceImplTest extends BaseDbUnitTest {
  41 +
  42 + @Resource
  43 + private SensitiveWordServiceImpl sensitiveWordService;
  44 +
  45 + @Resource
  46 + private SensitiveWordMapper sensitiveWordMapper;
  47 +
  48 + @MockBean
  49 + private SensitiveWordProducer sensitiveWordProducer;
  50 +
  51 + @Test
  52 + public void testInitLocalCache() {
  53 + SensitiveWordDO wordDO1 = randomPojo(SensitiveWordDO.class, o -> o.setName("傻瓜")
  54 + .setTags(singletonList("论坛")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
  55 + sensitiveWordMapper.insert(wordDO1);
  56 + SensitiveWordDO wordDO2 = randomPojo(SensitiveWordDO.class, o -> o.setName("笨蛋")
  57 + .setTags(singletonList("蔬菜")).setStatus(CommonStatusEnum.ENABLE.getStatus()));
  58 + sensitiveWordMapper.insert(wordDO2);
  59 +
  60 + // 调用
  61 + sensitiveWordService.initLocalCache();
  62 + // 断言 maxUpdateTime 缓存
  63 + assertEquals(max(wordDO1.getUpdateTime(), wordDO2.getUpdateTime()), sensitiveWordService.getMaxUpdateTime());
  64 + // 断言 sensitiveWordTagsCache 缓存
  65 + assertEquals(SetUtils.asSet("论坛", "蔬菜"), sensitiveWordService.getSensitiveWordTags());
  66 + // 断言 tagSensitiveWordTries 缓存
  67 + assertNotNull(sensitiveWordService.getDefaultSensitiveWordTrie());
  68 + assertEquals(2, sensitiveWordService.getTagSensitiveWordTries().size());
  69 + assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("论坛"));
  70 + assertNotNull(sensitiveWordService.getTagSensitiveWordTries().get("蔬菜"));
  71 + }
  72 +
  73 + @Test
  74 + public void testCreateSensitiveWord_success() {
  75 + // 准备参数
  76 + SensitiveWordCreateReqVO reqVO = randomPojo(SensitiveWordCreateReqVO.class);
  77 +
  78 + // 调用
  79 + Long sensitiveWordId = sensitiveWordService.createSensitiveWord(reqVO);
  80 + // 断言
  81 + assertNotNull(sensitiveWordId);
  82 + // 校验记录的属性是否正确
  83 + SensitiveWordDO sensitiveWord = sensitiveWordMapper.selectById(sensitiveWordId);
  84 + assertPojoEquals(reqVO, sensitiveWord);
  85 + verify(sensitiveWordProducer).sendSensitiveWordRefreshMessage();
  86 + }
  87 +
  88 + @Test
  89 + public void testUpdateSensitiveWord_success() {
  90 + // mock 数据
  91 + SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class);
  92 + sensitiveWordMapper.insert(dbSensitiveWord);// @Sql: 先插入出一条存在的数据
  93 + // 准备参数
  94 + SensitiveWordUpdateReqVO reqVO = randomPojo(SensitiveWordUpdateReqVO.class, o -> {
  95 + o.setId(dbSensitiveWord.getId()); // 设置更新的 ID
  96 + });
  97 +
  98 + // 调用
  99 + sensitiveWordService.updateSensitiveWord(reqVO);
  100 + // 校验是否更新正确
  101 + SensitiveWordDO sensitiveWord = sensitiveWordMapper.selectById(reqVO.getId()); // 获取最新的
  102 + assertPojoEquals(reqVO, sensitiveWord);
  103 + verify(sensitiveWordProducer).sendSensitiveWordRefreshMessage();
  104 + }
  105 +
  106 + @Test
  107 + public void testUpdateSensitiveWord_notExists() {
  108 + // 准备参数
  109 + SensitiveWordUpdateReqVO reqVO = randomPojo(SensitiveWordUpdateReqVO.class);
  110 +
  111 + // 调用, 并断言异常
  112 + assertServiceException(() -> sensitiveWordService.updateSensitiveWord(reqVO), SENSITIVE_WORD_NOT_EXISTS);
  113 + }
  114 +
  115 + @Test
  116 + public void testDeleteSensitiveWord_success() {
  117 + // mock 数据
  118 + SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class);
  119 + sensitiveWordMapper.insert(dbSensitiveWord);// @Sql: 先插入出一条存在的数据
  120 + // 准备参数
  121 + Long id = dbSensitiveWord.getId();
  122 +
  123 + // 调用
  124 + sensitiveWordService.deleteSensitiveWord(id);
  125 + // 校验数据不存在了
  126 + assertNull(sensitiveWordMapper.selectById(id));
  127 + verify(sensitiveWordProducer).sendSensitiveWordRefreshMessage();
  128 + }
  129 +
  130 + @Test
  131 + public void testDeleteSensitiveWord_notExists() {
  132 + // 准备参数
  133 + Long id = randomLongId();
  134 +
  135 + // 调用, 并断言异常
  136 + assertServiceException(() -> sensitiveWordService.deleteSensitiveWord(id), SENSITIVE_WORD_NOT_EXISTS);
  137 + }
  138 +
  139 + @Test
  140 + public void testGetSensitiveWordPage() {
  141 + // mock 数据
  142 + SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class, o -> { // 等会查询到
  143 + o.setName("笨蛋");
  144 + o.setTags(Arrays.asList("论坛", "蔬菜"));
  145 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  146 + o.setCreateTime(DateUtils.buildTime(2022, 2, 8));
  147 + });
  148 + sensitiveWordMapper.insert(dbSensitiveWord);
  149 + // 测试 name 不匹配
  150 + sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setName("傻瓜")));
  151 + // 测试 tags 不匹配
  152 + sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setTags(Arrays.asList("短信", "日用品"))));
  153 + // 测试 createTime 不匹配
  154 + sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setCreateTime(DateUtils.buildTime(2022, 2, 16))));
  155 + // 准备参数
  156 + SensitiveWordPageReqVO reqVO = new SensitiveWordPageReqVO();
  157 + reqVO.setName("笨");
  158 + reqVO.setTag("论坛");
  159 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  160 + reqVO.setBeginCreateTime(DateUtils.buildTime(2022, 2, 1));
  161 + reqVO.setEndCreateTime(DateUtils.buildTime(2022, 2, 12));
  162 +
  163 + // 调用
  164 + PageResult<SensitiveWordDO> pageResult = sensitiveWordService.getSensitiveWordPage(reqVO);
  165 + // 断言
  166 + assertEquals(1, pageResult.getTotal());
  167 + assertEquals(1, pageResult.getList().size());
  168 + assertPojoEquals(dbSensitiveWord, pageResult.getList().get(0));
  169 + }
  170 +
  171 + @Test
  172 + public void testGetSensitiveWordList() {
  173 + // mock 数据
  174 + SensitiveWordDO dbSensitiveWord = randomPojo(SensitiveWordDO.class, o -> { // 等会查询到
  175 + o.setName("笨蛋");
  176 + o.setTags(Arrays.asList("论坛", "蔬菜"));
  177 + o.setStatus(CommonStatusEnum.ENABLE.getStatus());
  178 + o.setCreateTime(DateUtils.buildTime(2022, 2, 8));
  179 + });
  180 + sensitiveWordMapper.insert(dbSensitiveWord);
  181 + // 测试 name 不匹配
  182 + sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setName("傻瓜")));
  183 + // 测试 tags 不匹配
  184 + sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setTags(Arrays.asList("短信", "日用品"))));
  185 + // 测试 createTime 不匹配
  186 + sensitiveWordMapper.insert(cloneIgnoreId(dbSensitiveWord, o -> o.setCreateTime(DateUtils.buildTime(2022, 2, 16))));
  187 + // 准备参数
  188 + SensitiveWordExportReqVO reqVO = new SensitiveWordExportReqVO();
  189 + reqVO.setName("笨");
  190 + reqVO.setTag("论坛");
  191 + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  192 + reqVO.setBeginCreateTime(DateUtils.buildTime(2022, 2, 1));
  193 + reqVO.setEndCreateTime(DateUtils.buildTime(2022, 2, 12));
  194 +
  195 + // 调用
  196 + List<SensitiveWordDO> list = sensitiveWordService.getSensitiveWordList(reqVO);
  197 + // 断言
  198 + assertEquals(1, list.size());
  199 + assertPojoEquals(dbSensitiveWord, list.get(0));
  200 + }
  201 +
  202 + @Test
  203 + public void testValidateText_noTag() {
  204 + testInitLocalCache();
  205 + // 准备参数
  206 + String text = "你是傻瓜,你是笨蛋";
  207 +
  208 + // 调用
  209 + List<String> result = sensitiveWordService.validateText(text, null);
  210 + // 断言
  211 + assertEquals(Arrays.asList("傻瓜", "笨蛋"), result);
  212 + }
  213 +
  214 + @Test
  215 + public void testValidateText_hasTag() {
  216 + testInitLocalCache();
  217 + // 准备参数
  218 + String text = "你是傻瓜,你是笨蛋";
  219 +
  220 + // 调用
  221 + List<String> result = sensitiveWordService.validateText(text, singletonList("论坛"));
  222 + // 断言
  223 + assertEquals(singletonList("傻瓜"), result);
  224 + }
  225 +
  226 + @Test
  227 + public void testIsTestValid_noTag() {
  228 + testInitLocalCache();
  229 + // 准备参数
  230 + String text = "你是傻瓜,你是笨蛋";
  231 +
  232 + // 调用,断言
  233 + assertFalse(sensitiveWordService.isTextValid(text, null));
  234 + }
  235 +
  236 + @Test
  237 + public void testIsTestValid_hasTag() {
  238 + testInitLocalCache();
  239 + // 准备参数
  240 + String text = "你是傻瓜,你是笨蛋";
  241 +
  242 + // 调用,断言
  243 + assertFalse(sensitiveWordService.isTextValid(text, singletonList("论坛")));
  244 + }
  245 +
  246 +}
... ...