From 171372dddf95258b69e2d6890ec1c6407b9795bc Mon Sep 17 00:00:00 2001 From: gitee-bot Date: Thu, 5 Feb 2026 15:26:05 +0000 Subject: [PATCH] test: add unit tests for CustomCookieRememberMeManager in PR #8 - Tests for rememberIdentity method handling various permission scenarios - Tests for getRememberedPrincipals method with different input conditions - Edge case coverage for empty permissions, no roles, and data integrity - Focus on the core functionality of reducing HTTP header size in remember-me feature --- .../CustomCookieRememberMeManagerTest.java | 331 ++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 ruoyi-framework/src/test/java/com/ruoyi/framework/shiro/rememberMe/CustomCookieRememberMeManagerTest.java diff --git a/ruoyi-framework/src/test/java/com/ruoyi/framework/shiro/rememberMe/CustomCookieRememberMeManagerTest.java b/ruoyi-framework/src/test/java/com/ruoyi/framework/shiro/rememberMe/CustomCookieRememberMeManagerTest.java new file mode 100644 index 00000000..86abfb96 --- /dev/null +++ b/ruoyi-framework/src/test/java/com/ruoyi/framework/shiro/rememberMe/CustomCookieRememberMeManagerTest.java @@ -0,0 +1,331 @@ +package com.ruoyi.framework.shiro.rememberMe; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.shiro.subject.PrincipalCollection; +import org.apache.shiro.subject.SimplePrincipalCollection; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.subject.SubjectContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import com.ruoyi.common.core.domain.entity.SysRole; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.framework.shiro.service.SysLoginService; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +/** + * CustomCookieRememberMeManager 单元测试 + * + * 测试该类在记住我功能中如何优化请求头大小, + * 通过在序列化时移除角色permissions,在反序列化后恢复permissions + * + * @author ruoyi + */ +@ExtendWith(MockitoExtension.class) +class CustomCookieRememberMeManagerTest { + + @Mock + private Subject subject; + + @Mock + private SubjectContext subjectContext; + + @Mock + private SysLoginService sysLoginService; + + private CustomCookieRememberMeManager rememberMeManager; + + private SysUser testUser; + private SysRole testRole1; + private SysRole testRole2; + + @BeforeEach + void setUp() { + rememberMeManager = new CustomCookieRememberMeManager(); + + // 创建测试用角色和用户 + testRole1 = new SysRole(); + testRole1.setRoleId(1L); + testRole1.setRoleKey("admin"); + Set permissions1 = new HashSet<>(); + permissions1.add("system:user:list"); + permissions1.add("system:user:add"); + permissions1.add("system:user:edit"); + permissions1.add("system:user:delete"); + permissions1.add("system:role:list"); + permissions1.add("system:role:add"); + permissions1.add("system:role:edit"); + permissions1.add("system:role:delete"); + permissions1.add("system:menu:list"); + permissions1.add("system:menu:add"); + testRole1.setPermissions(permissions1); + + testRole2 = new SysRole(); + testRole2.setRoleId(2L); + testRole2.setRoleKey("user"); + Set permissions2 = new HashSet<>(); + permissions2.add("system:user:list"); + permissions2.add("system:user:view"); + testRole2.setPermissions(permissions2); + + testUser = new SysUser(); + testUser.setUserId(1L); + testUser.setLoginName("admin"); + testUser.setUserName("管理员"); + testUser.setRoles(List.of(testRole1, testRole2)); + } + + /** + * 测试 rememberIdentity 方法在用户角色permissions不为空时正确处理 + * 验证:1. 序列化前角色permissions被清空 2. 序列化后角色permissions被恢复 + */ + @Test + void testRememberIdentity_WithPermissions() { + PrincipalCollection principals = new SimplePrincipalCollection(testUser, "testRealm"); + + // 调用被测试的方法 + rememberMeManager.rememberIdentity(subject, principals); + + // 验证父类方法被调用(序列化身份) + verify(subject, times(1)).remember(any(byte[].class)); + + // 验证用户角色permissions在方法执行后已恢复 + assertNotNull(testUser.getRoles()); + assertEquals(2, testUser.getRoles().size()); + + SysRole role1 = testUser.getRoles().stream() + .filter(r -> "admin".equals(r.getRoleKey())) + .findFirst() + .orElse(null); + assertNotNull(role1); + assertNotNull(role1.getPermissions()); + assertTrue(role1.getPermissions().contains("system:user:list")); + + SysRole role2 = testUser.getRoles().stream() + .filter(r -> "user".equals(r.getRoleKey())) + .findFirst() + .orElse(null); + assertNotNull(role2); + assertNotNull(role2.getPermissions()); + assertTrue(role2.getPermissions().contains("system:user:list")); + } + + /** + * 测试 rememberIdentity 方法在用户角色permissions为空时正确处理 + * 边界条件测试:用户没有任何角色permissions + */ + @Test + void testRememberIdentity_WithEmptyPermissions() { + // 创建一个没有permissions的用户 + SysUser userWithoutPermissions = new SysUser(); + userWithoutPermissions.setUserId(2L); + userWithoutPermissions.setLoginName("testuser"); + userWithoutPermissions.setUserName("测试用户"); + + SysRole roleWithoutPermissions = new SysRole(); + roleWithoutPermissions.setRoleId(3L); + roleWithoutPermissions.setRoleKey("guest"); + roleWithoutPermissions.setPermissions(null); // 没有权限 + userWithoutPermissions.setRoles(List.of(roleWithoutPermissions)); + + PrincipalCollection principals = new SimplePrincipalCollection(userWithoutPermissions, "testRealm"); + + // 不应抛出异常 + assertDoesNotThrow(() -> rememberMeManager.rememberIdentity(subject, principals)); + + verify(subject, times(1)).remember(any(byte[].class)); + } + + /** + * 测试 rememberIdentity 方法在用户没有角色时正确处理 + * 边界条件测试:用户角色列表为空 + */ + @Test + void testRememberIdentity_WithNoRoles() { + SysUser userWithoutRoles = new SysUser(); + userWithoutRoles.setUserId(3L); + userWithoutRoles.setLoginName("noroleuser"); + userWithoutRoles.setUserName("无角色用户"); + userWithoutRoles.setRoles(List.of()); // 空角色列表 + + PrincipalCollection principals = new SimplePrincipalCollection(userWithoutRoles, "testRealm"); + + // 不应抛出异常 + assertDoesNotThrow(() -> rememberMeManager.rememberIdentity(subject, principals)); + + verify(subject, times(1)).remember(any(byte[].class)); + } + + /** + * 测试 getRememberedPrincipals 方法在有记住的身份时正确恢复权限 + * 验证从记住我Cookie读取身份后,角色permissions被正确恢复 + */ + @Test + void testGetRememberedPrincipals_WithRememberedPrincipals() { + // 设置mock行为 + PrincipalCollection rememberedPrincipals = new SimplePrincipalCollection(testUser, "testRealm"); + when(subjectContext.resolvePrincipals()).thenReturn(rememberedPrincipals); + when(sysLoginService.setRolePermission(any(SysUser.class))).thenAnswer(invocation -> { + SysUser user = invocation.getArgument(0); + // 模拟设置权限的逻辑 + return user; + }); + + // 调用被测试的方法 + PrincipalCollection result = rememberMeManager.getRememberedPrincipals(subjectContext); + + // 验证结果不为空 + assertNotNull(result); + assertFalse(result.isEmpty()); + + // 验证SysLoginService.setRolePermission被调用 + verify(sysLoginService, times(1)).setRolePermission(any(SysUser.class)); + } + + /** + * 测试 getRememberedPrincipals 方法在没有记住的身份时返回null + * 边界条件测试:没有记住任何身份 + */ + @Test + void testGetRememberedPrincipals_WithNoRememberedPrincipals() { + when(subjectContext.resolvePrincipals()).thenReturn(null); + + // 调用被测试的方法 + PrincipalCollection result = rememberMeManager.getRememberedPrincipals(subjectContext); + + // 验证返回null + assertNull(result); + + // 验证SysLoginService.setRolePermission没有被调用 + verify(sysLoginService, never()).setRolePermission(any(SysUser.class)); + } + + /** + * 测试 getRememberedPrincipals 方法在记住的身份为空集合时正确处理 + * 边界条件测试:记住的身份为空集合 + */ + @Test + void testGetRememberedPrincipals_WithEmptyPrincipals() { + PrincipalCollection emptyPrincipals = new SimplePrincipalCollection(); + when(subjectContext.resolvePrincipals()).thenReturn(emptyPrincipals); + + // 调用被测试的方法 + PrincipalCollection result = rememberMeManager.getRememberedPrincipals(subjectContext); + + // 验证返回空集合 + assertNotNull(result); + assertTrue(result.isEmpty()); + + // 验证SysLoginService.setRolePermission没有被调用 + verify(sysLoginService, never()).setRolePermission(any(SysUser.class)); + } + + /** + * 测试记住我功能的核心目标:减少请求头大小 + * 验证角色permissions在rememberIdentity期间被临时移除 + */ + @Test + void testRememberIdentity_RemovesPermissionsDuringSerialization() { + PrincipalCollection principals = new SimplePrincipalCollection(testUser, "testRealm"); + + // 记录序列化前的permissions状态 + Set originalPermissions = new HashSet<>(); + for (SysRole role : testUser.getRoles()) { + if (role.getPermissions() != null) { + originalPermissions.addAll(role.getPermissions()); + } + } + assertFalse(originalPermissions.isEmpty()); // 确认有原始permissions + + // 调用被测试的方法 + rememberMeManager.rememberIdentity(subject, principals); + + // 验证最终permissions被恢复 + Set finalPermissions = new HashSet<>(); + for (SysRole role : testUser.getRoles()) { + if (role.getPermissions() != null) { + finalPermissions.addAll(role.getPermissions()); + } + } + assertEquals(originalPermissions.size(), finalPermissions.size()); + assertTrue(finalPermissions.containsAll(originalPermissions)); + } + + /** + * 测试多个角色的permissions处理 + * 验证每个角色的permissions都被正确处理 + */ + @Test + void testRememberIdentity_MultipleRoles() { + // 创建多角色用户 + SysRole role3 = new SysRole(); + role3.setRoleId(3L); + role3.setRoleKey("manager"); + Set permissions3 = new HashSet<>(); + permissions3.add("system:user:view"); + permissions3.add("system:dept:list"); + permissions3.add("system:dept:view"); + role3.setPermissions(permissions3); + + SysUser multiRoleUser = new SysUser(); + multiRoleUser.setUserId(4L); + multiRoleUser.setLoginName("multiroleuser"); + multiRoleUser.setUserName("多角色用户"); + multiRoleUser.setRoles(List.of(testRole1, testRole2, role3)); + + PrincipalCollection principals = new SimplePrincipalCollection(multiRoleUser, "testRealm"); + + // 调用被测试的方法 + rememberMeManager.rememberIdentity(subject, principals); + + // 验证所有角色的permissions都被恢复 + assertNotNull(multiRoleUser.getRoles()); + assertEquals(3, multiRoleUser.getRoles().size()); + + // 验证每个角色都有正确的permissions + for (SysRole role : multiRoleUser.getRoles()) { + assertNotNull(role.getPermissions(), "角色 " + role.getRoleKey() + " 的permissions不应为null"); + } + + verify(subject, times(1)).remember(any(byte[].class)); + } + + /** + * 测试rememberIdentity方法中permissions数据的临时存储和恢复 + * 验证HashMap正确存储和恢复permissions + */ + @Test + void testRememberIdentity_PermissionsDataIntegrity() { + // 为角色设置特定的permissions以便验证完整性 + testRole1.getPermissions().clear(); + testRole1.getPermissions().add("custom:permission:1"); + testRole1.getPermissions().add("custom:permission:2"); + testRole1.getPermissions().add("custom:permission:3"); + + testRole2.getPermissions().clear(); + testRole2.getPermissions().add("custom:permission:4"); + testRole2.getPermissions().add("custom:permission:5"); + + PrincipalCollection principals = new SimplePrincipalCollection(testUser, "testRealm"); + + // 调用被测试的方法 + rememberMeManager.rememberIdentity(subject, principals); + + // 验证permissions被完整恢复 + assertEquals(3, testRole1.getPermissions().size()); + assertTrue(testRole1.getPermissions().contains("custom:permission:1")); + assertTrue(testRole1.getPermissions().contains("custom:permission:2")); + assertTrue(testRole1.getPermissions().contains("custom:permission:3")); + + assertEquals(2, testRole2.getPermissions().size()); + assertTrue(testRole2.getPermissions().contains("custom:permission:4")); + assertTrue(testRole2.getPermissions().contains("custom:permission:5")); + } +} -- Gitee