🔀 合并票 07 单元测试

This commit is contained in:
2026-10-25 19:51:55 +08:00
@@ -18,6 +18,7 @@ import org.springblade.system.mapper.MpUserDataScopeMapper;
import org.springblade.system.mapper.MpUserMapper;
import org.springblade.system.pojo.entity.MpUser;
import org.springblade.system.pojo.entity.MpUserDataScope;
import org.springblade.system.pojo.vo.MpUserDataScopeVO;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -27,6 +28,7 @@ import java.util.function.Consumer;
import java.util.stream.Stream;
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.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -173,6 +175,30 @@ class MpUserServiceImplTest {
verify(mpUserDataScopeMapper, never()).insert(any(MpUserDataScope.class));
}
@Test
@DisplayName("显式传 level=1:层级改写为仅本级,范围与自定义组织保持库值,关联表一行都不动")
void updateWithExplicitLevelRewritesLevelOnly() {
when(mpUserMapper.selectById(USER_ID)).thenReturn(customScopeDbUser());
when(mpUserMapper.updateById(any(MpUser.class))).thenReturn(1);
when(mpUserDataScopeMapper.selectList(any())).thenReturn(scopes(SCOPE_DEPT_A, SCOPE_DEPT_B));
MpUser user = new MpUser();
user.setId(USER_ID);
user.setTenantId(TENANT_ID);
user.setIdentities("admin");
user.setDataLevelRange(1);
assertTrue(updateUser(user));
ArgumentCaptor<MpUser> captor = ArgumentCaptor.forClass(MpUser.class);
verify(mpUserMapper).updateById(captor.capture());
assertEquals(1, captor.getValue().getDataLevelRange(), "显式传的层级要落库");
assertEquals(3, captor.getValue().getDataScopeRange(), "未传范围时沿用库里的 3-自定义");
assertEquals(List.of(SCOPE_DEPT_A, SCOPE_DEPT_B), captor.getValue().getDataScopeDeptIds());
verify(mpUserDataScopeMapper, never()).delete(any());
verify(mpUserDataScopeMapper, never()).insert(any(MpUserDataScope.class));
}
@Test
@DisplayName("只显式传自定义组织列表:关联按新列表重建,范围沿用库里的 3-自定义")
void updateWithExplicitDeptIdsRebuildsScopes() {
@@ -218,6 +244,79 @@ class MpUserServiceImplTest {
verify(mpUserDataScopeMapper, times(2)).insert(any(MpUserDataScope.class));
}
// ------------------------------------------------------------ 注册路径不要求所属组织
@ParameterizedTest(name = "{1}")
@MethodSource("emptyDeptRegistrationCases")
@DisplayName("注册:司机 / 管理员 / 司机+管理员不选所属组织也能建号")
void submitAcceptsEmptyDeptForEveryIdentity(String identities, String label) {
when(mpUserMapper.selectOne(any(), anyBoolean())).thenReturn(null);
when(mpUserMapper.insert(any(MpUser.class))).thenAnswer(invocation -> {
invocation.getArgument(0, MpUser.class).setId(USER_ID);
return 1;
});
MpUser user = new MpUser();
user.setTenantId(TENANT_ID);
user.setPhone(PHONE);
user.setIdentities(identities);
try (MockedStatic<MpUserCache> ignored = mockStatic(MpUserCache.class)) {
assertTrue(service.submit(user), label + ":所属组织不是注册的准入门槛");
}
ArgumentCaptor<MpUser> captor = ArgumentCaptor.forClass(MpUser.class);
verify(mpUserMapper).insert(captor.capture());
assertNull(captor.getValue().getDeptId(), "未选组织时组织列保持 null,不写空串");
assertEquals(1, captor.getValue().getDataScopeRange(), "未选组织的账号按默认 1-仅所属组织落库");
}
static Stream<Arguments> emptyDeptRegistrationCases() {
return Stream.of(
Arguments.of("driver", "司机"),
Arguments.of("admin", "管理员"),
Arguments.of("driver,admin", "司机+管理员"));
}
// ------------------------------------------------------------ 空组织的解析结果是空集
@ParameterizedTest(name = "{2}")
@MethodSource("emptyScopeCases")
@DisplayName("数据权限解析:基础组织为空时得到空集,不退化成全部组织")
void resolveDataScopeIsEmptyWhenBaseDeptsEmpty(Integer dataScopeRange, Integer dataLevelRange, String label) {
MpUser user = dbUser();
user.setDeptId(null);
user.setDataScopeRange(dataScopeRange);
user.setDataLevelRange(dataLevelRange);
when(mpUserMapper.selectById(USER_ID)).thenReturn(user);
when(mpUserDataScopeMapper.selectList(any())).thenReturn(List.of());
MpUserDataScopeVO scope = service.resolveDataScope(USER_ID);
assertFalse(scope.isAllDept(), label + ":空集不是全部组织,allDept=true 表示不按组织过滤");
assertTrue(scope.getDeptIds().isEmpty());
}
static Stream<Arguments> emptyScopeCases() {
return Stream.of(
Arguments.of(null, null, "范围与层级都未设置"),
Arguments.of(1, 1, "1-仅所属组织 + 1-含下级,但没有组织"),
Arguments.of(3, 2, "3-自定义,但一条组织关联都没有"));
}
@Test
@DisplayName("数据权限解析:只有范围是 2-全部组织时才返回全部")
void resolveDataScopeIsAllOnlyForAllScope() {
MpUser user = dbUser();
user.setDeptId(null);
user.setDataScopeRange(2);
when(mpUserMapper.selectById(USER_ID)).thenReturn(user);
MpUserDataScopeVO scope = service.resolveDataScope(USER_ID);
assertTrue(scope.isAllDept());
}
// ------------------------------------------------------------ 夹具
/**