Commit 619a7b73c373e87ec9b0f7b427420eb51f67e208

Authored by YunaiV
1 parent 8278b657

增加 DeptDataPermissionRuleTest 单元测试

yudao-framework/yudao-spring-boot-starter-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRule.java
@@ -91,7 +91,8 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -91,7 +91,8 @@ public class DeptDataPermissionRule implements DataPermissionRule {
91 DeptDataPermissionRespDTO deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser); 91 DeptDataPermissionRespDTO deptDataPermission = deptDataPermissionService.getDeptDataPermission(loginUser);
92 if (deptDataPermission == null) { 92 if (deptDataPermission == null) {
93 log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser)); 93 log.error("[getExpression][LoginUser({}) 获取数据权限为 null]", JsonUtils.toJsonString(loginUser));
94 - return null; 94 + throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 未返回数据权限",
  95 + loginUser.getId(), tableName, tableAlias.getName()));
95 } 96 }
96 97
97 // 情况一,如果是 ALL 可查看全部,则无需拼接条件 98 // 情况一,如果是 ALL 可查看全部,则无需拼接条件
@@ -111,7 +112,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -111,7 +112,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
111 if (deptExpression == null && userExpression == null) { 112 if (deptExpression == null && userExpression == null) {
112 log.error("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]", 113 log.error("[getExpression][LoginUser({}) Table({}/{}) DeptDataPermission({}) 构建的条件为空]",
113 JsonUtils.toJsonString(loginUser), tableName, tableAlias, JsonUtils.toJsonString(deptDataPermission)); 114 JsonUtils.toJsonString(loginUser), tableName, tableAlias, JsonUtils.toJsonString(deptDataPermission));
114 - throw new NullPointerException(String.format("LoginUser(%d) tableName(%s) tableAlias(%s) 构建的条件为空", 115 + throw new NullPointerException(String.format("LoginUser(%d) Table(%s/%s) 构建的条件为空",
115 loginUser.getId(), tableName, tableAlias.getName())); 116 loginUser.getId(), tableName, tableAlias.getName()));
116 } 117 }
117 if (deptExpression == null) { 118 if (deptExpression == null) {
@@ -130,6 +131,10 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -130,6 +131,10 @@ public class DeptDataPermissionRule implements DataPermissionRule {
130 if (StrUtil.isEmpty(columnName)) { 131 if (StrUtil.isEmpty(columnName)) {
131 return null; 132 return null;
132 } 133 }
  134 + // 如果为空,则无条件
  135 + if (CollUtil.isEmpty(deptIds)) {
  136 + return null;
  137 + }
133 // 拼接条件 138 // 拼接条件
134 return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName), 139 return new InExpression(MyBatisUtils.buildColumn(tableName, tableAlias, columnName),
135 new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new))); 140 new ExpressionList(CollectionUtils.convertList(deptIds, LongValue::new)));
@@ -156,6 +161,10 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -156,6 +161,10 @@ public class DeptDataPermissionRule implements DataPermissionRule {
156 161
157 public void addDeptColumn(Class<? extends BaseDO> entityClass, String columnName) { 162 public void addDeptColumn(Class<? extends BaseDO> entityClass, String columnName) {
158 String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName(); 163 String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName();
  164 + addDeptColumn(tableName, columnName);
  165 + }
  166 +
  167 + public void addDeptColumn(String tableName, String columnName) {
159 deptColumns.put(tableName, columnName); 168 deptColumns.put(tableName, columnName);
160 TABLE_NAMES.add(tableName); 169 TABLE_NAMES.add(tableName);
161 } 170 }
@@ -166,6 +175,10 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -166,6 +175,10 @@ public class DeptDataPermissionRule implements DataPermissionRule {
166 175
167 public void addUserColumn(Class<? extends BaseDO> entityClass, String columnName) { 176 public void addUserColumn(Class<? extends BaseDO> entityClass, String columnName) {
168 String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName(); 177 String tableName = TableInfoHelper.getTableInfo(entityClass).getTableName();
  178 + addUserColumn(tableName, columnName);
  179 + }
  180 +
  181 + public void addUserColumn(String tableName, String columnName) {
169 userColumns.put(tableName, columnName); 182 userColumns.put(tableName, columnName);
170 TABLE_NAMES.add(tableName); 183 TABLE_NAMES.add(tableName);
171 } 184 }
yudao-framework/yudao-spring-boot-starter-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/dept/rule/DeptDataPermissionRuleTest.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.datapermission.core.dept.rule;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ReflectUtil;
  5 +import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
  6 +import cn.iocoder.yudao.framework.datapermission.core.dept.service.DeptDataPermissionFrameworkService;
  7 +import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
  8 +import cn.iocoder.yudao.framework.security.core.LoginUser;
  9 +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
  10 +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
  11 +import net.sf.jsqlparser.expression.Alias;
  12 +import net.sf.jsqlparser.expression.Expression;
  13 +import org.junit.jupiter.api.BeforeEach;
  14 +import org.junit.jupiter.api.Test;
  15 +import org.mockito.InjectMocks;
  16 +import org.mockito.Mock;
  17 +import org.mockito.MockedStatic;
  18 +
  19 +import java.util.Map;
  20 +
  21 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  22 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
  23 +import static org.junit.jupiter.api.Assertions.*;
  24 +import static org.mockito.ArgumentMatchers.same;
  25 +import static org.mockito.Mockito.mockStatic;
  26 +import static org.mockito.Mockito.when;
  27 +
  28 +/**
  29 + * {@link DeptDataPermissionRule} 的单元测试
  30 + *
  31 + * @author 芋道源码
  32 + */
  33 +class DeptDataPermissionRuleTest extends BaseMockitoUnitTest {
  34 +
  35 + @InjectMocks
  36 + private DeptDataPermissionRule rule;
  37 +
  38 + @Mock
  39 + private DeptDataPermissionFrameworkService deptDataPermissionFrameworkService;
  40 +
  41 + @BeforeEach
  42 + @SuppressWarnings("unchecked")
  43 + public void setUp() {
  44 + // 清空 rule
  45 + rule.getTableNames().clear();
  46 + ((Map<String, String>) ReflectUtil.getFieldValue(rule, "deptColumns")).clear();
  47 + ((Map<String, String>) ReflectUtil.getFieldValue(rule, "deptColumns")).clear();
  48 + }
  49 +
  50 + @Test // 无 LoginUser
  51 + public void testGetExpression_noLoginUser() {
  52 + // 准备参数
  53 + String tableName = randomString();
  54 + Alias tableAlias = new Alias(randomString());
  55 + // mock 方法
  56 +
  57 + // 调用
  58 + Expression expression = rule.getExpression(tableName, tableAlias);
  59 + // 断言
  60 + assertNull(expression);
  61 + }
  62 +
  63 + @Test // 无数据权限时
  64 + public void testGetExpression_noDeptDataPermission() {
  65 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  66 + = mockStatic(SecurityFrameworkUtils.class)) {
  67 + // 准备参数
  68 + String tableName = "t_user";
  69 + Alias tableAlias = new Alias("u");
  70 + // mock 方法
  71 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  72 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  73 +
  74 + // 调用
  75 + NullPointerException exception = assertThrows(NullPointerException.class,
  76 + () -> rule.getExpression(tableName, tableAlias));
  77 + // 断言
  78 + assertEquals("LoginUser(1) Table(t_user/u) 未返回数据权限", exception.getMessage());
  79 + }
  80 + }
  81 +
  82 + @Test // 全部数据权限
  83 + public void testGetExpression_allDeptDataPermission() {
  84 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  85 + = mockStatic(SecurityFrameworkUtils.class)) {
  86 + // 准备参数
  87 + String tableName = "t_user";
  88 + Alias tableAlias = new Alias("u");
  89 + // mock 方法(LoginUser)
  90 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  91 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  92 + // mock 方法(DeptDataPermissionRespDTO)
  93 + DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO().setAll(true);
  94 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
  95 +
  96 + // 调用
  97 + Expression expression = rule.getExpression(tableName, tableAlias);
  98 + // 断言
  99 + assertNull(expression);
  100 + }
  101 + }
  102 +
  103 + @Test // 即不能查看部门,又不能查看自己,则说明 100% 无权限
  104 + public void testGetExpression_noDept_noSelf() {
  105 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  106 + = mockStatic(SecurityFrameworkUtils.class)) {
  107 + // 准备参数
  108 + String tableName = "t_user";
  109 + Alias tableAlias = new Alias("u");
  110 + // mock 方法(LoginUser)
  111 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  112 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  113 + // mock 方法(DeptDataPermissionRespDTO)
  114 + DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO();
  115 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
  116 +
  117 + // 调用
  118 + Expression expression = rule.getExpression(tableName, tableAlias);
  119 + // 断言
  120 + assertEquals("null = null", expression.toString());
  121 + }
  122 + }
  123 +
  124 + @Test // 拼接 Dept 和 User 的条件(字段都不符合)
  125 + public void testGetExpression_noDeptColumn_noSelfColumn() {
  126 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  127 + = mockStatic(SecurityFrameworkUtils.class)) {
  128 + // 准备参数
  129 + String tableName = "t_user";
  130 + Alias tableAlias = new Alias("u");
  131 + // mock 方法(LoginUser)
  132 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  133 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  134 + // mock 方法(DeptDataPermissionRespDTO)
  135 + DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
  136 + .setDeptIds(SetUtils.asSet(10L, 20L)).setSelf(true);
  137 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
  138 +
  139 + // 调用
  140 + NullPointerException exception = assertThrows(NullPointerException.class,
  141 + () -> rule.getExpression(tableName, tableAlias));
  142 + // 断言
  143 + assertEquals("LoginUser(1) Table(t_user/u) 构建的条件为空", exception.getMessage());
  144 + }
  145 + }
  146 +
  147 + @Test // 拼接 Dept 和 User 的条件(self 符合)
  148 + public void testGetExpression_noDeptColumn_yesSelfColumn() {
  149 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  150 + = mockStatic(SecurityFrameworkUtils.class)) {
  151 + // 准备参数
  152 + String tableName = "t_user";
  153 + Alias tableAlias = new Alias("u");
  154 + // mock 方法(LoginUser)
  155 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  156 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  157 + // mock 方法(DeptDataPermissionRespDTO)
  158 + DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
  159 + .setSelf(true);
  160 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
  161 + // 添加 user 字段配置
  162 + rule.addUserColumn("t_user", "id");
  163 +
  164 + // 调用
  165 + Expression expression = rule.getExpression(tableName, tableAlias);
  166 + // 断言
  167 + assertEquals("u.id = 1", expression.toString());
  168 + }
  169 + }
  170 +
  171 + @Test // 拼接 Dept 和 User 的条件(dept 符合)
  172 + public void testGetExpression_yesDeptColumn_noSelfColumn() {
  173 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  174 + = mockStatic(SecurityFrameworkUtils.class)) {
  175 + // 准备参数
  176 + String tableName = "t_user";
  177 + Alias tableAlias = new Alias("u");
  178 + // mock 方法(LoginUser)
  179 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  180 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  181 + // mock 方法(DeptDataPermissionRespDTO)
  182 + DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
  183 + .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L));
  184 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
  185 + // 添加 dept 字段配置
  186 + rule.addDeptColumn("t_user", "dept_id");
  187 +
  188 + // 调用
  189 + Expression expression = rule.getExpression(tableName, tableAlias);
  190 + // 断言
  191 + assertEquals("u.dept_id IN (10, 20)", expression.toString());
  192 + }
  193 + }
  194 +
  195 + @Test // 拼接 Dept 和 User 的条件(dept + self 符合)
  196 + public void testGetExpression_yesDeptColumn_yesSelfColumn() {
  197 + try (MockedStatic<SecurityFrameworkUtils> securityFrameworkUtilsMock
  198 + = mockStatic(SecurityFrameworkUtils.class)) {
  199 + // 准备参数
  200 + String tableName = "t_user";
  201 + Alias tableAlias = new Alias("u");
  202 + // mock 方法(LoginUser)
  203 + LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(1L));
  204 + securityFrameworkUtilsMock.when(SecurityFrameworkUtils::getLoginUser).thenReturn(loginUser);
  205 + // mock 方法(DeptDataPermissionRespDTO)
  206 + DeptDataPermissionRespDTO deptDataPermission = new DeptDataPermissionRespDTO()
  207 + .setDeptIds(CollUtil.newLinkedHashSet(10L, 20L)).setSelf(true);
  208 + when(deptDataPermissionFrameworkService.getDeptDataPermission(same(loginUser))).thenReturn(deptDataPermission);
  209 + // 添加 user 字段配置
  210 + rule.addUserColumn("t_user", "id");
  211 + // 添加 dept 字段配置
  212 + rule.addDeptColumn("t_user", "dept_id");
  213 +
  214 + // 调用
  215 + Expression expression = rule.getExpression(tableName, tableAlias);
  216 + // 断言
  217 + assertEquals("u.dept_id IN (10, 20) OR u.id = 1", expression.toString());
  218 + }
  219 + }
  220 +
  221 +}