feat(spec58): 模块注册表后端与模块硬编码收敛(#60)
- 新增 gxmu/module 包:ModuleRegistry 实体/Mapper/Service,listEnabled 按 sort_number 升序,titleOf 未注册回退 module 原串 - 新增 GET /api/gxmu/module-registry/list(需登录),返回启用模块元数据 - ReviewFlowConfigServiceImpl / ReviewListServiceImpl 的模块名映射改读注册表,查不到回退原串 - DeclareGuardServiceImpl 的模块集合改为注册表驱动,含 enabled=0(停用模块存量仍可撤回/作废) - 启动期一致性校验:table_name≠module 或业务表缺失即启动失败,gxmu.module-registry.strict=false 可关闭 - 单测 13 例:注册表加载与排序、titleOf 回退、启动校验、module 名回退
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
package com.gxwebsoft.gxmu.module;
|
||||
|
||||
import com.gxwebsoft.gxmu.module.entity.ModuleRegistry;
|
||||
import com.gxwebsoft.gxmu.module.mapper.ModuleRegistryMapper;
|
||||
import com.gxwebsoft.gxmu.module.service.impl.ModuleRegistryServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* 模块注册表服务的单元测试(mock 掉 Mapper,不启 Spring、不连库)。
|
||||
*
|
||||
* <p>注册表是模块元数据的唯一来源,这里锁住三件对外可观察的事:
|
||||
* 启用清单按 sort_number 升序、标题查询在未注册时回退 module 原串、
|
||||
* 模块集合包含已停用模块(停用模块的历史数据仍要能撤回/作废)。
|
||||
*
|
||||
* @author Codex
|
||||
* @since 2026-11-10
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class ModuleRegistryServiceImplTest {
|
||||
|
||||
@Mock
|
||||
private ModuleRegistryMapper moduleRegistryMapper;
|
||||
|
||||
@InjectMocks
|
||||
private ModuleRegistryServiceImpl moduleRegistryService;
|
||||
|
||||
@Test
|
||||
void listEnabledReturnsOnlyEnabledModulesOrderedBySortNumber() {
|
||||
when(moduleRegistryMapper.selectList(any())).thenReturn(Arrays.asList(
|
||||
module("gxmu_qmgc_form", "青马工程", 1, 8),
|
||||
module("gxmu_sjtbzbsj", "十佳团支部书记", 0, 2),
|
||||
module("gxmu_sjqn", "十佳青年岗位能手", 1, 1)));
|
||||
|
||||
List<ModuleRegistry> enabled = moduleRegistryService.listEnabled();
|
||||
|
||||
assertEquals(Arrays.asList("gxmu_sjqn", "gxmu_qmgc_form"),
|
||||
enabled.stream().map(ModuleRegistry::getModule).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleOfReturnsRegisteredTitle() {
|
||||
when(moduleRegistryMapper.selectOne(any())).thenReturn(module("gxmu_tzbcy_form", "挑战杯", 1, 7));
|
||||
|
||||
assertEquals("挑战杯", moduleRegistryService.titleOf("gxmu_tzbcy_form"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleOfFallsBackToModuleStringWhenNotRegistered() {
|
||||
when(moduleRegistryMapper.selectOne(any())).thenReturn(null);
|
||||
|
||||
assertEquals("cms_legacy_module", moduleRegistryService.titleOf("cms_legacy_module"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleOfKeepsNullModuleNull() {
|
||||
assertNull(moduleRegistryService.titleOf(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleMapCoversDisabledModulesSoHistoricalRowsKeepTitles() {
|
||||
when(moduleRegistryMapper.selectList(any())).thenReturn(Arrays.asList(
|
||||
module("gxmu_sjqn", "十佳青年岗位能手", 1, 1),
|
||||
module("gxmu_yxgqty", "优秀共青团员", 0, 6)));
|
||||
|
||||
Map<String, String> titles = moduleRegistryService.titleMap();
|
||||
|
||||
assertEquals("十佳青年岗位能手", titles.get("gxmu_sjqn"));
|
||||
assertEquals("优秀共青团员", titles.get("gxmu_yxgqty"));
|
||||
assertEquals(2, titles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void moduleSetContainsDisabledModules() {
|
||||
when(moduleRegistryMapper.selectList(any())).thenReturn(Arrays.asList(
|
||||
module("gxmu_sjqn", "十佳青年岗位能手", 1, 1),
|
||||
module("gxmu_yxgqty", "优秀共青团员", 0, 6)));
|
||||
|
||||
assertTrue(moduleRegistryService.containsModule("gxmu_yxgqty"));
|
||||
assertFalse(moduleRegistryService.containsModule("gxmu_unknown"));
|
||||
assertFalse(moduleRegistryService.containsModule(null));
|
||||
}
|
||||
|
||||
private ModuleRegistry module(String name, String title, int enabled, int sortNumber) {
|
||||
ModuleRegistry item = new ModuleRegistry();
|
||||
item.setModule(name);
|
||||
item.setTableName(name);
|
||||
item.setTitle(title);
|
||||
item.setDetailKey(name);
|
||||
item.setEnabled(enabled);
|
||||
item.setSortNumber(sortNumber);
|
||||
item.setDeleted(0);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user