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.ModuleRegistryService; 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.HashMap; 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、不连库)。 * *

注册表是模块元数据的唯一来源,这里锁住四件对外可观察的事: * 启用清单只留启用项且保持 SQL 的排序(排序只在 SQL 里做一次)、 * 模块集合包含已停用模块(停用模块的历史数据仍要能撤回/作废)、 * has_college 决定审批人解析是否读学院上下文、标题回退只有一份实现。 * * @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 listEnabledReturnsOnlyEnabledModulesInSqlOrder() { // SQL 已按 sort_number 升序返回;服务只负责过滤,不再二次排序 when(moduleRegistryMapper.selectList(any())).thenReturn(Arrays.asList( module("gxmu_sjqn", "十佳青年岗位能手", 1, 1, 1), module("gxmu_sjtbzbsj", "十佳团支部书记", 0, 2, 0), module("gxmu_qmgc_form", "青马工程", 1, 8, 1))); List enabled = moduleRegistryService.listEnabled(); assertEquals(Arrays.asList("gxmu_sjqn", "gxmu_qmgc_form"), enabled.stream().map(ModuleRegistry::getModule).collect(Collectors.toList())); } @Test void titleMapCoversDisabledModulesSoHistoricalRowsKeepTitles() { when(moduleRegistryMapper.selectList(any())).thenReturn(Arrays.asList( module("gxmu_sjqn", "十佳青年岗位能手", 1, 1, 1), module("gxmu_yxgqty", "优秀共青团员", 0, 6, 0))); Map 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, 1), module("gxmu_yxgqty", "优秀共青团员", 0, 6, 0))); assertTrue(moduleRegistryService.containsModule("gxmu_yxgqty")); assertFalse(moduleRegistryService.containsModule("gxmu_unknown")); assertFalse(moduleRegistryService.containsModule(null)); } @Test void hasCollegeFollowsTheRegistryFlag() { when(moduleRegistryMapper.selectOne(any())).thenReturn(module("gxmu_sjqn", "十佳青年岗位能手", 1, 1, 1)); assertTrue(moduleRegistryService.hasCollege("gxmu_sjqn")); } @Test void hasCollegeIsFalseForDisabledOrMissingFlag() { when(moduleRegistryMapper.selectOne(any())).thenReturn(module("gxmu_tygl", "团员管理", 0, 12, 0)); assertFalse(moduleRegistryService.hasCollege("gxmu_tygl")); assertFalse(moduleRegistryService.hasCollege(null)); } @Test void titleOfUsesRegistryTitleWhenPresent() { Map titles = new HashMap<>(); titles.put("gxmu_tzbcy_form", "挑战杯"); assertEquals("挑战杯", ModuleRegistryService.titleOf(titles, "gxmu_tzbcy_form")); } @Test void titleOfFallsBackToModuleStringWhenNotRegistered() { assertEquals("cms_legacy_module", ModuleRegistryService.titleOf(new HashMap<>(), "cms_legacy_module")); assertEquals("cms_legacy_module", ModuleRegistryService.titleOf(null, "cms_legacy_module")); } @Test void titleOfKeepsNullModuleNull() { assertNull(ModuleRegistryService.titleOf(new HashMap<>(), null)); } private ModuleRegistry module(String name, String title, int enabled, int sortNumber, int hasCollege) { ModuleRegistry item = new ModuleRegistry(); item.setModule(name); item.setTableName(name); item.setTitle(title); item.setDetailKey(name); item.setEnabled(enabled); item.setSortNumber(sortNumber); item.setHasCollege(hasCollege); item.setDeleted(0); return item; } }