system微服务util单元测试完善

This commit is contained in:
gaoqr
2025-12-12 14:51:35 +08:00
parent 3d0e42f4eb
commit 26cfc538ae
8 changed files with 1022 additions and 17 deletions
@@ -80,23 +80,23 @@ public class AsymmetricAlgorithmUtil {
return keys;
}
public static void main(String[] args) {
LinkedList<String> priKeyAndPubKey = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey = priKeyAndPubKey.get(0);
String publicKey = priKeyAndPubKey.get(1);
String text = "HelloWorld";
String encryptByPublic = AsymmetricAlgorithmUtil.encryptByPublic(text, publicKey);
System.out.println(encryptByPublic);
String s = AsymmetricAlgorithmUtil.decryptByPrivate(encryptByPublic, privateKey);
System.out.println("公钥加密私钥解密:"+s);
String encryptByPrivate = AsymmetricAlgorithmUtil.encryptByPrivate(text, privateKey);
System.out.println(encryptByPrivate);
String s1 = AsymmetricAlgorithmUtil.decryptByPublic(encryptByPrivate,publicKey);
System.out.println("私钥加密公钥解密:"+s1);
}
// public static void main(String[] args) {
//
// LinkedList<String> priKeyAndPubKey = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
// String privateKey = priKeyAndPubKey.get(0);
// String publicKey = priKeyAndPubKey.get(1);
// String text = "HelloWorld";
//
// String encryptByPublic = AsymmetricAlgorithmUtil.encryptByPublic(text, publicKey);
// System.out.println(encryptByPublic);
// String s = AsymmetricAlgorithmUtil.decryptByPrivate(encryptByPublic, privateKey);
// System.out.println("公钥加密私钥解密:"+s);
//
// String encryptByPrivate = AsymmetricAlgorithmUtil.encryptByPrivate(text, privateKey);
// System.out.println(encryptByPrivate);
// String s1 = AsymmetricAlgorithmUtil.decryptByPublic(encryptByPrivate,publicKey);
// System.out.println("私钥加密公钥解密:"+s1);
// }
}
@@ -0,0 +1,222 @@
package com.cf.imes.module.system.util.collection;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link SimpleTrie} 的单元测试
*/
public class SimpleTrieTest {
private SimpleTrie simpleTrie;
@BeforeEach
public void setUp() {
List<String> sensitiveWords = Arrays.asList("敏感词", "测试", "ABC", "暴力", "暴力行为");
simpleTrie = new SimpleTrie(sensitiveWords);
}
@Test
public void testConstructorWithEmptyCollection() {
// 测试空集合构造
SimpleTrie trie = new SimpleTrie(Collections.emptyList());
assertTrue(trie.isValid("任何文本"));
assertTrue(trie.validate("任何文本").isEmpty());
}
@Test
public void testIsValidWithValidText() {
// 测试不包含敏感词的文本
assertTrue(simpleTrie.isValid("这是一段正常的文本"));
assertTrue(simpleTrie.isValid(""));
assertTrue(simpleTrie.isValid(" "));
}
@Test
public void testIsValidWithInvalidText() {
// 测试包含敏感词的文本
assertFalse(simpleTrie.isValid("这段文本包含敏感词"));
assertFalse(simpleTrie.isValid("测试文本"));
assertFalse(simpleTrie.isValid("ABC"));
assertFalse(simpleTrie.isValid("暴力行为"));
}
@Test
public void testIsValidWithPartialMatch() {
// 测试部分匹配的情况
assertTrue(simpleTrie.isValid("敏感情")); // "敏感情"不包含敏感词"敏感词"
assertTrue(simpleTrie.isValid("测验")); // "测验"不包含敏感词"测试"
assertFalse(simpleTrie.isValid("ABCD")); // "ABCD"包含敏感词"ABC"
assertFalse(simpleTrie.isValid("暴力事件")); // "暴力事件"包含敏感词"暴力"
}
@Test
public void testValidateWithValidText() {
// 测试不包含敏感词的文本
List<String> result = simpleTrie.validate("这是一段正常的文本");
assertTrue(result.isEmpty());
result = simpleTrie.validate("");
assertTrue(result.isEmpty());
result = simpleTrie.validate(" ");
assertTrue(result.isEmpty());
}
@Test
public void testValidateWithSingleSensitiveWord() {
// 测试包含单个敏感词的文本
List<String> result = simpleTrie.validate("这段文本包含敏感词");
assertEquals(1, result.size());
assertTrue(result.contains("敏感词"));
result = simpleTrie.validate("测试文本");
assertEquals(1, result.size());
assertTrue(result.contains("测试"));
result = simpleTrie.validate("ABC");
assertEquals(1, result.size());
assertTrue(result.contains("ABC"));
}
@Test
public void testValidateWithMultipleSensitiveWords() {
// 测试包含多个敏感词的文本
List<String> result = simpleTrie.validate("这段文本包含敏感词和测试内容");
assertEquals(2, result.size());
assertTrue(result.contains("敏感词"));
assertTrue(result.contains("测试"));
}
@Test
public void testValidateWithOverlappingSensitiveWords() {
// 测试包含重叠敏感词的文本(最短匹配原则)
List<String> result = simpleTrie.validate("暴力行为测试");
assertEquals(2, result.size());
assertTrue(result.contains("暴力")); // 最短匹配
assertTrue(result.contains("测试"));
// 验证不会同时返回"暴力"和"暴力行为"
assertFalse(result.contains("暴力") && result.contains("暴力行为"));
}
@Test
public void testValidateWithRepeatedSensitiveWords() {
// 测试重复敏感词的情况
List<String> result = simpleTrie.validate("测试测试测试");
assertEquals(1, result.size()); // 应该去重
assertTrue(result.contains("测试"));
}
@Test
public void testShortestMatchPrinciple() {
// 测试最短匹配原则
List<String> words = Arrays.asList("煞笔", "煞笔二货");
SimpleTrie trie = new SimpleTrie(words);
List<String> result = trie.validate("这个人是个煞笔二货");
assertEquals(1, result.size());
assertTrue(result.contains("煞笔")); // 应该只返回最短的匹配
assertFalse(result.contains("煞笔二货"));
}
@Test
public void testPrefixOptimization() {
// 测试前缀优化:如果已有较短敏感词,不应再添加更长的以相同前缀开始的词
List<String> words = Arrays.asList("吃饭", "吃饭啊");
SimpleTrie trie = new SimpleTrie(words);
// 验证"吃饭啊"实际上没有被完全添加(因为已经有"吃饭")
// 但"吃饭"已经被添加,所以包含"吃饭"的文本应该验证失败
assertFalse(trie.isValid("我要吃饭")); // 应该不通过验证,因为包含"吃饭"
assertFalse(trie.isValid("我要吃饭啊")); // 应该不通过验证,因为包含"吃饭"
// 但如果直接添加"吃饭啊"应该能检测到
List<String> words2 = Arrays.asList("吃饭啊", "吃饭");
SimpleTrie trie2 = new SimpleTrie(words2);
assertFalse(trie2.isValid("我要吃饭啊"));
}
@Test
public void testRecursionEndCondition() {
// 测试递归结束条件:到达文本末尾
List<String> words = Arrays.asList("a");
SimpleTrie trie = new SimpleTrie(words);
assertFalse(trie.isValid("a")); // 单字符匹配,应该不通过验证
List<String> result = trie.validate("a");
assertEquals(1, result.size());
assertTrue(result.contains("a"));
}
@Test
public void testRecursionEndAtTextEnd() {
// 测试递归结束条件:到达文本末尾且未匹配到敏感词
List<String> words = Arrays.asList("ab");
SimpleTrie trie = new SimpleTrie(words);
// 测试文本"a"只匹配了敏感词"ab"的第一个字符,但没有完整的匹配
// 这会触发recursion方法中index == text.length()的条件,返回true
assertTrue(trie.isValid("a"));
// 测试文本"ac"第一个字符就不匹配
assertTrue(trie.isValid("ac"));
}
@Test
public void testSpecialCharacters() {
// 测试特殊字符
List<String> words = Arrays.asList("特殊$符号", "换行\n符", "制表\t符");
SimpleTrie trie = new SimpleTrie(words);
assertFalse(trie.isValid("包含特殊$符号的文本"));
assertFalse(trie.isValid("包含换行\n符的文本"));
assertFalse(trie.isValid("包含制表\t符的文本"));
List<String> result = trie.validate("特殊$符号和换行\n符和制表\t符");
assertEquals(3, result.size());
assertTrue(result.contains("特殊$符号"));
assertTrue(result.contains("换行\n符"));
assertTrue(result.contains("制表\t符"));
}
@Test
public void testUnicodeCharacters() {
// 测试Unicode字符
List<String> words = Arrays.asList("中文", "English", "数字123", "表情😀");
SimpleTrie trie = new SimpleTrie(words);
assertFalse(trie.isValid("包含中文的文本"));
assertFalse(trie.isValid("Contains English words"));
assertFalse(trie.isValid("包含数字123的内容"));
assertFalse(trie.isValid("包含表情😀的文本"));
List<String> result = trie.validate("混合中文English数字123和表情😀");
assertEquals(4, result.size());
assertTrue(result.contains("中文"));
assertTrue(result.contains("English"));
assertTrue(result.contains("数字123"));
assertTrue(result.contains("表情😀"));
}
@Test
public void testValidateWithoutSensitiveWords() {
// 测试没有敏感词的情况,覆盖validate方法中!ok为false的分支
List<String> result = simpleTrie.validate("正常文本内容");
assertTrue(result.isEmpty());
// 测试部分匹配但不完整的敏感词情况
List<String> words = Arrays.asList("abcd");
SimpleTrie trie = new SimpleTrie(words);
result = trie.validate("abc"); // 只匹配了部分,没有完整匹配
assertTrue(result.isEmpty());
// 测试在recursionWithResult中child==null的情况
result = trie.validate("abe"); // "ab"匹配但'e'不匹配,触发child==null的分支
assertTrue(result.isEmpty());
}
}
@@ -0,0 +1,145 @@
package com.cf.imes.module.system.util.locale;
import com.cf.imes.module.system.controller.admin.dict.vo.data.DictDataSimpleRespVO;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link DictDataI18nCacheUtils} 的单元测试
*/
public class DictDataI18nCacheUtilsTest {
@BeforeEach
public void setUp() {
// 测试前清理缓存
DictDataI18nCacheUtils.clearCache();
}
@AfterEach
public void tearDown() {
// 测试后清理缓存
DictDataI18nCacheUtils.clearCache();
}
@Test
public void testPutCacheAndGetCache() {
// 准备测试数据
Map<String, List<DictDataSimpleRespVO>> testData = new HashMap<>();
List<DictDataSimpleRespVO> dataList = new ArrayList<>();
DictDataSimpleRespVO vo = new DictDataSimpleRespVO();
vo.setDictType("gender");
vo.setValue("1");
vo.setLabel("");
dataList.add(vo);
testData.put("gender", dataList);
// 测试putCache方法
DictDataI18nCacheUtils.putCache(testData);
// 验证getCache方法
Map<String, List<DictDataSimpleRespVO>> cache = DictDataI18nCacheUtils.getCache();
assertNotNull(cache);
assertEquals(1, cache.size());
assertTrue(cache.containsKey("gender"));
assertEquals(1, cache.get("gender").size());
assertEquals("", cache.get("gender").get(0).getLabel());
}
@Test
public void testGetCacheReturnsUnmodifiableMap() {
// 准备测试数据
Map<String, List<DictDataSimpleRespVO>> testData = new HashMap<>();
List<DictDataSimpleRespVO> dataList = new ArrayList<>();
DictDataSimpleRespVO vo = new DictDataSimpleRespVO();
vo.setDictType("status");
vo.setValue("1");
vo.setLabel("启用");
dataList.add(vo);
testData.put("status", dataList);
// 添加数据到缓存
DictDataI18nCacheUtils.putCache(testData);
// 获取缓存并尝试修改
Map<String, List<DictDataSimpleRespVO>> cache = DictDataI18nCacheUtils.getCache();
// 验证返回的是不可修改的Map
assertThrows(UnsupportedOperationException.class, () -> {
cache.put("newKey", new ArrayList<>());
});
}
@Test
public void testClearCache() {
// 准备测试数据
Map<String, List<DictDataSimpleRespVO>> testData = new HashMap<>();
List<DictDataSimpleRespVO> dataList = new ArrayList<>();
DictDataSimpleRespVO vo = new DictDataSimpleRespVO();
vo.setDictType("type");
vo.setValue("1");
vo.setLabel("标签");
dataList.add(vo);
testData.put("type", dataList);
// 添加数据到缓存
DictDataI18nCacheUtils.putCache(testData);
// 验证缓存中有数据
Map<String, List<DictDataSimpleRespVO>> cache = DictDataI18nCacheUtils.getCache();
assertFalse(cache.isEmpty());
// 清除缓存
DictDataI18nCacheUtils.clearCache();
// 验证缓存已清空
cache = DictDataI18nCacheUtils.getCache();
assertTrue(cache.isEmpty());
}
@Test
public void testPutCacheMultipleTimes() {
// 测试多次添加缓存数据
Map<String, List<DictDataSimpleRespVO>> testData1 = new HashMap<>();
List<DictDataSimpleRespVO> dataList1 = new ArrayList<>();
DictDataSimpleRespVO vo1 = new DictDataSimpleRespVO();
vo1.setDictType("type1");
vo1.setValue("1");
vo1.setLabel("标签1");
dataList1.add(vo1);
testData1.put("key1", dataList1);
DictDataI18nCacheUtils.putCache(testData1);
Map<String, List<DictDataSimpleRespVO>> testData2 = new HashMap<>();
List<DictDataSimpleRespVO> dataList2 = new ArrayList<>();
DictDataSimpleRespVO vo2 = new DictDataSimpleRespVO();
vo2.setDictType("type2");
vo2.setValue("2");
vo2.setLabel("标签2");
dataList2.add(vo2);
testData2.put("key2", dataList2);
DictDataI18nCacheUtils.putCache(testData2);
// 验证两个键都存在于缓存中
Map<String, List<DictDataSimpleRespVO>> cache = DictDataI18nCacheUtils.getCache();
assertEquals(2, cache.size());
assertTrue(cache.containsKey("key1"));
assertTrue(cache.containsKey("key2"));
}
@Test
public void testGetCacheWhenEmpty() {
// 测试缓存为空时的情况
Map<String, List<DictDataSimpleRespVO>> cache = DictDataI18nCacheUtils.getCache();
assertNotNull(cache);
assertTrue(cache.isEmpty());
}
}
@@ -0,0 +1,104 @@
package com.cf.imes.module.system.util.locale;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.Locale;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link LocaleUtils} 的单元测试
*/
public class LocaleUtilsTest {
private MockedStatic<LocaleContextHolder> mockedLocaleContextHolder;
@BeforeEach
public void setUp() {
// Mock静态类LocaleContextHolder
mockedLocaleContextHolder = mockStatic(LocaleContextHolder.class);
}
@AfterEach
public void tearDown() {
// 关闭静态mock
if (mockedLocaleContextHolder != null) {
mockedLocaleContextHolder.close();
}
}
@Test
public void testGetLocaleWhenLocaleIsNull() {
// 模拟getLocale返回null
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(null);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertNull(result);
}
@Test
public void testGetLocaleWhenLocaleIsChinese() {
// 模拟getLocale返回中文环境
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(Locale.CHINESE);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertNull(result);
}
@Test
public void testGetLocaleWhenLocaleIsChineseVariant() {
// 模拟getLocale返回中文环境变体
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(Locale.SIMPLIFIED_CHINESE);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertEquals("zh", result);
}
@Test
public void testGetLocaleWhenLocaleIsEnglish() {
// 模拟getLocale返回英文环境
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(Locale.ENGLISH);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertEquals("en", result);
}
@Test
public void testGetLocaleWhenLocaleIsFrench() {
// 模拟getLocale返回法文环境
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(Locale.FRENCH);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertEquals("fr", result);
}
@Test
public void testGetLocaleWhenLocaleIsGerman() {
// 模拟getLocale返回德文环境
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(Locale.GERMAN);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertEquals("de", result);
}
@Test
public void testGetLocaleWhenLocaleIsJapan() {
// 模拟getLocale返回日文环境
mockedLocaleContextHolder.when(LocaleContextHolder::getLocale).thenReturn(Locale.JAPANESE);
// 调用方法并验证结果
String result = LocaleUtils.getLocale();
assertEquals("ja", result);
}
}
@@ -0,0 +1,217 @@
package com.cf.imes.module.system.util.oauth2;
import org.junit.jupiter.api.Test;
import java.time.LocalDateTime;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link OAuth2Utils} 的单元测试
*/
public class OAuth2UtilsTest {
@Test
public void testBuildAuthorizationCodeRedirectUri() {
// 测试构建授权码模式下的重定向URI
String redirectUri = "https://example.com/callback";
String authorizationCode = "auth-code-12345";
String state = "state-value";
String result = OAuth2Utils.buildAuthorizationCodeRedirectUri(redirectUri, authorizationCode, state);
assertTrue(result.contains("https://example.com/callback"));
assertTrue(result.contains("code=auth-code-12345"));
assertTrue(result.contains("state=state-value"));
}
@Test
public void testBuildAuthorizationCodeRedirectUriWithoutState() {
// 测试构建授权码模式下的重定向URI(不包含state参数)
String redirectUri = "https://example.com/callback";
String authorizationCode = "auth-code-12345";
String state = null;
String result = OAuth2Utils.buildAuthorizationCodeRedirectUri(redirectUri, authorizationCode, state);
assertTrue(result.contains("https://example.com/callback"));
assertTrue(result.contains("code=auth-code-12345"));
assertFalse(result.contains("state="));
}
@Test
public void testBuildImplicitRedirectUri() {
// 测试构建简化模式下的重定向URI
String redirectUri = "https://example.com/callback";
String accessToken = "access-token-12345";
String state = "state-value";
LocalDateTime expireTime = LocalDateTime.now().plusHours(1);
Collection<String> scopes = Arrays.asList("read", "write");
Map<String, Object> additionalInformation = new HashMap<>();
additionalInformation.put("user_id", "user-123");
additionalInformation.put("client_id", "client-456");
additionalInformation.put("extra_test_1", null);
additionalInformation.put("extra_test_2", "2");
String result = OAuth2Utils.buildImplicitRedirectUri(redirectUri, accessToken, state, expireTime, scopes, additionalInformation);
assertTrue(result.contains("https://example.com/callback"));
assertTrue(result.contains("access_token=access-token-12345"));
assertTrue(result.contains("token_type=bearer"));
assertTrue(result.contains("state=state-value"));
assertTrue(result.contains("expires_in="));
assertTrue(result.contains("scope=read%20write"));
// 验证extra_前缀是否正确处理
assertTrue(result.contains("user_id=user-123"));
assertTrue(result.contains("client_id=client-456"));
// 确保原始的extra_前缀key没有出现在结果中
assertFalse(result.contains("extra_user_id="));
assertFalse(result.contains("extra_client_id="));
assertFalse(result.contains("extra_test_1=null"));
assertTrue(result.contains("extra_test_2=2"));
}
@Test
public void testBuildImplicitRedirectUriWithMinimalParameters() {
// 测试构建简化模式下的重定向URI(最小参数)
String redirectUri = "https://example.com/callback";
String accessToken = "access-token-12345";
String state = null;
LocalDateTime expireTime = null;
Collection<String> scopes = null;
Map<String, Object> additionalInformation = null;
String result = OAuth2Utils.buildImplicitRedirectUri(redirectUri, accessToken, state, expireTime, scopes, additionalInformation);
assertTrue(result.contains("https://example.com/callback"));
assertTrue(result.contains("access_token=access-token-12345"));
assertTrue(result.contains("token_type=bearer"));
assertFalse(result.contains("state="));
assertFalse(result.contains("expires_in="));
assertFalse(result.contains("scope="));
}
@Test
public void testBuildUnsuccessfulRedirect() {
// 测试构建失败重定向URI
String redirectUri = "https://example.com/callback";
String responseType = "code";
String state = "state-value";
String error = "invalid_request";
String description = "The request is missing a required parameter";
String result = OAuth2Utils.buildUnsuccessfulRedirect(redirectUri, responseType, state, error, description);
assertTrue(result.contains("https://example.com/callback"));
assertTrue(result.contains("error=invalid_request"));
assertTrue(result.contains("error_description=The%20request%20is%20missing%20a%20required%20parameter"));
assertTrue(result.contains("state=state-value"));
}
@Test
public void testBuildUnsuccessfulRedirectWithoutState() {
// 测试构建失败重定向URI(不包含state参数)
String redirectUri = "https://example.com/callback";
String responseType = "token";
String state = null;
String error = "invalid_request";
String description = "The request is missing a required parameter";
String result = OAuth2Utils.buildUnsuccessfulRedirect(redirectUri, responseType, state, error, description);
assertTrue(result.contains("https://example.com/callback"));
assertTrue(result.contains("error=invalid_request"));
assertTrue(result.contains("error_description=The%20request%20is%20missing%20a%20required%20parameter"));
assertFalse(result.contains("state="));
}
@Test
public void testGetExpiresIn() {
// 测试获取过期时间
LocalDateTime futureTime = LocalDateTime.now().plusSeconds(3600);
long expiresIn = OAuth2Utils.getExpiresIn(futureTime);
// 验证过期时间在合理范围内
assertTrue(expiresIn > 0);
assertTrue(expiresIn <= 3600);
}
@Test
public void testBuildScopeStr() {
// 测试构建scope字符串
Collection<String> scopes = Arrays.asList("read", "write", "profile");
String result = OAuth2Utils.buildScopeStr(scopes);
assertEquals("read write profile", result);
}
@Test
public void testBuildScopeStrWithEmptyScopes() {
// 测试构建scope字符串(空集合)
Collection<String> scopes = new ArrayList<>();
String result = OAuth2Utils.buildScopeStr(scopes);
assertEquals("", result);
}
@Test
public void testBuildScopeStrWithNullScopes() {
// 测试构建scope字符串(null
Collection<String> scopes = null;
String result = OAuth2Utils.buildScopeStr(scopes);
assertNull(result);
}
@Test
public void testBuildScopes() {
// 测试解析scope字符串
String scope = "read write profile";
List<String> result = OAuth2Utils.buildScopes(scope);
assertEquals(3, result.size());
assertTrue(result.contains("read"));
assertTrue(result.contains("write"));
assertTrue(result.contains("profile"));
}
@Test
public void testBuildScopesWithSingleScope() {
// 测试解析scope字符串(单个scope)
String scope = "read";
List<String> result = OAuth2Utils.buildScopes(scope);
assertEquals(1, result.size());
assertTrue(result.contains("read"));
}
@Test
public void testBuildScopesWithEmptyString() {
// 测试解析scope字符串(空字符串)
String scope = "";
List<String> result = OAuth2Utils.buildScopes(scope);
// 空字符串split后会返回包含一个空字符串的列表
assertEquals(1, result.size());
assertEquals("", result.get(0));
}
@Test
public void testBuildScopesWithNull() {
// 测试解析scope字符串(null
String scope = null;
List<String> result = OAuth2Utils.buildScopes(scope);
// null值split后会返回空列表
assertTrue(result.isEmpty());
}
}
@@ -0,0 +1,28 @@
package com.cf.imes.module.system.util.organ;
import com.cf.imes.module.system.constants.permission.InternalRoleConstants;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link OrganUtils} 的单元测试
*/
public class OrganUtilsTest {
@Test
public void testIsOrgRoleWithOrganAdminRoleId() {
// 测试组织管理员角色ID
Long organAdminRoleId = InternalRoleConstants.ORGAN_ADMIN_ROLE_ID;
boolean result = OrganUtils.isOrgRole(organAdminRoleId);
assertTrue(result, "组织管理员角色ID应该返回true");
}
@Test
public void testIsOrgRoleWithOrganStaffRoleId() {
// 测试组织员工角色ID
Long organStaffRoleId = InternalRoleConstants.ORGAN_STAFF_ROLE_ID;
boolean result = OrganUtils.isOrgRole(organStaffRoleId);
assertTrue(result, "组织员工角色ID应该返回true");
}
}
@@ -0,0 +1,111 @@
package com.cf.imes.module.system.util.redis;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.test.core.ut.BaseRedisUnitTest;
import com.cf.imes.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;
import static com.cf.imes.module.system.dal.redis.RedisKeyConstants.OAUTH2_ACCESS_TOKEN;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link SystemRedisUtils} 的单元测试
*
* 使用 BaseRedisUnitTest 基类,利用真实的 Redis 环境进行测试
*/
public class SystemRedisUtilsTest extends BaseRedisUnitTest {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Test
public void testScanAndCompareDeptAndDelTokenWithMatchingDeptId() {
// 准备测试数据
Long deptId = 100L;
// 创建OAuth2AccessTokenDO对象
OAuth2AccessTokenDO token1 = new OAuth2AccessTokenDO();
token1.setDeptId(100L); // 匹配的部门ID
OAuth2AccessTokenDO token2 = new OAuth2AccessTokenDO();
token2.setDeptId(200L); // 不匹配的部门ID
// 构造Redis key
String key1 = String.format(OAUTH2_ACCESS_TOKEN, "token1");
String key2 = String.format(OAUTH2_ACCESS_TOKEN, "token2");
// 将数据存入Redis
stringRedisTemplate.opsForValue().set(key1, JsonUtils.toJsonString(token1), 3600, TimeUnit.SECONDS);
stringRedisTemplate.opsForValue().set(key2, JsonUtils.toJsonString(token2), 3600, TimeUnit.SECONDS);
// 创建SystemRedisUtils实例
SystemRedisUtils systemRedisUtils = new SystemRedisUtils(stringRedisTemplate);
// 执行方法
systemRedisUtils.scanAndCompareDeptAndDelToken(deptId);
// 验证匹配的token已被删除
Boolean hasKey1 = stringRedisTemplate.hasKey(key1);
Boolean hasKey2 = stringRedisTemplate.hasKey(key2);
assertFalse(hasKey1, "匹配部门ID的token应该被删除");
assertTrue(hasKey2, "不匹配部门ID的token不应该被删除");
}
@Test
public void testScanAndCompareDeptAndDelTokenWithNoMatchingDeptId() {
// 准备测试数据
Long deptId = 100L;
// 创建OAuth2AccessTokenDO对象,都不匹配
OAuth2AccessTokenDO token1 = new OAuth2AccessTokenDO();
token1.setDeptId(200L);
OAuth2AccessTokenDO token2 = new OAuth2AccessTokenDO();
token2.setDeptId(300L);
// 构造Redis key
String key1 = String.format(OAUTH2_ACCESS_TOKEN, "token1");
String key2 = String.format(OAUTH2_ACCESS_TOKEN, "token2");
// 将数据存入Redis
stringRedisTemplate.opsForValue().set(key1, JsonUtils.toJsonString(token1), 3600, TimeUnit.SECONDS);
stringRedisTemplate.opsForValue().set(key2, JsonUtils.toJsonString(token2), 3600, TimeUnit.SECONDS);
// 创建SystemRedisUtils实例
SystemRedisUtils systemRedisUtils = new SystemRedisUtils(stringRedisTemplate);
// 执行方法
systemRedisUtils.scanAndCompareDeptAndDelToken(deptId);
// 验证所有token都未被删除
Boolean hasKey1 = stringRedisTemplate.hasKey(key1);
Boolean hasKey2 = stringRedisTemplate.hasKey(key2);
assertTrue(hasKey1, "不匹配部门ID的token不应该被删除");
assertTrue(hasKey2, "不匹配部门ID的token不应该被删除");
}
@Test
public void testScanAndCompareDeptAndDelTokenWithEmptyKeys() {
// 准备测试数据
Long deptId = 100L;
// 确保Redis中没有任何匹配的key
// 清理可能存在的相关key
stringRedisTemplate.getConnectionFactory().getConnection().flushAll();
// 创建SystemRedisUtils实例
SystemRedisUtils systemRedisUtils = new SystemRedisUtils(stringRedisTemplate);
// 执行方法
systemRedisUtils.scanAndCompareDeptAndDelToken(deptId);
// 验证没有异常抛出,方法正常执行完毕
assertTrue(true, "方法应该正常执行完毕,即使没有匹配的key");
}
}
@@ -0,0 +1,178 @@
package com.cf.imes.module.system.util.rsa;
import org.junit.jupiter.api.Test;
import java.util.LinkedList;
import static org.junit.jupiter.api.Assertions.*;
/**
* {@link AsymmetricAlgorithmUtil} 的单元测试
*/
public class AsymmetricAlgorithmUtilTest {
@Test
public void testGetPriKeyAndPubKey() {
// 测试获取公私钥集合
LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
assertNotNull(keys);
assertEquals(2, keys.size());
assertNotNull(keys.get(0)); // 私钥
assertNotNull(keys.get(1)); // 公钥
assertNotEquals(keys.get(0), keys.get(1)); // 私钥和公钥应该不同
}
@Test
public void testEncryptByPublicAndDecryptByPrivate() {
// 测试公钥加密私钥解密
LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey = keys.get(0);
String publicKey = keys.get(1);
String plainText = "Hello World! 你好世界!";
// 公钥加密
String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey);
assertNotNull(encryptedText);
assertNotEquals(plainText, encryptedText); // 加密后的文本应该与原文不同
// 私钥解密
String decryptedText = AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey);
assertEquals(plainText, decryptedText); // 解密后的文本应该与原文相同
}
@Test
public void testEncryptByPrivateAndDecryptByPublic() {
// 测试私钥加密公钥解密
LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey = keys.get(0);
String publicKey = keys.get(1);
String plainText = "Hello World! 你好世界!";
// 私钥加密
String encryptedText = AsymmetricAlgorithmUtil.encryptByPrivate(plainText, privateKey);
assertNotNull(encryptedText);
assertNotEquals(plainText, encryptedText); // 加密后的文本应该与原文不同
// 公钥解密
String decryptedText = AsymmetricAlgorithmUtil.decryptByPublic(encryptedText, publicKey);
assertEquals(plainText, decryptedText); // 解密后的文本应该与原文相同
}
@Test
public void testEncryptAndDecryptWithEmptyString() {
// 测试空字符串的加解密
LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey = keys.get(0);
String publicKey = keys.get(1);
String plainText = "";
// 公钥加密空字符串
String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey);
assertNotNull(encryptedText);
// 私钥解密
String decryptedText = AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey);
assertEquals(plainText, decryptedText);
}
@Test
public void testEncryptAndDecryptWithSpecialCharacters() {
// 测试特殊字符的加解密
LinkedList<String> keys = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey = keys.get(0);
String publicKey = keys.get(1);
String plainText = "Hello\nWorld!\t你好\r世界!@#$%^&*()";
// 公钥加密
String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey);
assertNotNull(encryptedText);
assertNotEquals(plainText, encryptedText);
// 私钥解密
String decryptedText = AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey);
assertEquals(plainText, decryptedText);
}
@Test
public void testEncryptByPublicWithInvalidKey() {
// 测试使用无效公钥加密
String plainText = "Hello World";
String invalidPublicKey = "invalid-public-key";
assertThrows(Exception.class, () -> {
AsymmetricAlgorithmUtil.encryptByPublic(plainText, invalidPublicKey);
});
}
@Test
public void testDecryptByPrivateWithInvalidKey() {
// 测试使用无效私钥解密
String encryptedText = "some-encrypted-text";
String invalidPrivateKey = "invalid-private-key";
assertThrows(Exception.class, () -> {
AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, invalidPrivateKey);
});
}
@Test
public void testEncryptByPrivateWithInvalidKey() {
// 测试使用无效私钥加密
String plainText = "Hello World";
String invalidPrivateKey = "invalid-private-key";
assertThrows(Exception.class, () -> {
AsymmetricAlgorithmUtil.encryptByPrivate(plainText, invalidPrivateKey);
});
}
@Test
public void testDecryptByPublicWithInvalidKey() {
// 测试使用无效公钥解密
String encryptedText = "some-encrypted-text";
String invalidPublicKey = "invalid-public-key";
assertThrows(Exception.class, () -> {
AsymmetricAlgorithmUtil.decryptByPublic(encryptedText, invalidPublicKey);
});
}
@Test
public void testDecryptByPrivateWithWrongKey() {
// 测试使用不匹配的私钥解密
LinkedList<String> keys1 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String publicKey1 = keys1.get(1);
String plainText = "Hello World";
// 使用第一组密钥加密
String encryptedText = AsymmetricAlgorithmUtil.encryptByPublic(plainText, publicKey1);
// 使用第二组密钥解密(不匹配的私钥)
LinkedList<String> keys2 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey2 = keys2.get(0);
assertThrows(Exception.class, () -> {
AsymmetricAlgorithmUtil.decryptByPrivate(encryptedText, privateKey2);
});
}
@Test
public void testDecryptByPublicWithWrongKey() {
// 测试使用不匹配的公钥解密
LinkedList<String> keys1 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String privateKey1 = keys1.get(0);
String plainText = "Hello World";
// 使用第一组密钥加密
String encryptedText = AsymmetricAlgorithmUtil.encryptByPrivate(plainText, privateKey1);
// 使用第二组密钥解密(不匹配的公钥)
LinkedList<String> keys2 = AsymmetricAlgorithmUtil.getPriKeyAndPubKey();
String publicKey2 = keys2.get(1);
assertThrows(Exception.class, () -> {
AsymmetricAlgorithmUtil.decryptByPublic(encryptedText, publicKey2);
});
}
}