sz_rust_orm_facade/data_scope/
ext.rs1use crate::data_scope::context::DataScopeContext;
7use crate::data_scope::error::DataScopeError;
8use crate::data_scope::evaluator::DataScopeEvaluator;
9use crate::data_scope::rule::DataScopeRule;
10use crate::repository::WhereCondition;
11
12#[async_trait::async_trait]
17pub trait DataScopeExt: Sized {
18 fn with_data_scope_conditions(self, conditions: &[WhereCondition]) -> Self;
20
21 async fn data_scope_async(
26 self,
27 ctx: &DataScopeContext,
28 rule: &DataScopeRule,
29 evaluator: &dyn DataScopeEvaluator,
30 ) -> Result<Self, DataScopeError> {
31 let conditions = evaluator.evaluate(ctx, rule).await?;
32 Ok(self.with_data_scope_conditions(&conditions))
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39 use crate::data_scope::cache::{DeptTreeCache, DeptTreeProvider};
40 use crate::data_scope::custom::CustomGeneratorRegistry;
41 use crate::data_scope::evaluator::DefaultDataScopeEvaluator;
42 use crate::data_scope::metrics::DataScopeMetrics;
43 use crate::data_scope::rule::DataScopeMode;
44 use crate::repository::WhereCondition;
45 use async_trait::async_trait;
46 use std::sync::Arc;
47
48 struct MockQueryBuilder {
49 conditions: Vec<WhereCondition>,
50 }
51
52 #[async_trait]
53 impl DataScopeExt for MockQueryBuilder {
54 fn with_data_scope_conditions(mut self, conditions: &[WhereCondition]) -> Self {
55 self.conditions = conditions.to_vec();
56 self
57 }
58 }
59
60 struct MockDeptProvider;
61
62 #[async_trait]
63 impl DeptTreeProvider for MockDeptProvider {
64 async fn sub_depts(&self, _dept_id: i64) -> Result<Vec<i64>, DataScopeError> {
65 Ok(vec![])
66 }
67 }
68
69 fn make_evaluator() -> DefaultDataScopeEvaluator {
70 DefaultDataScopeEvaluator::new(
71 Arc::new(DeptTreeCache::new(
72 Arc::new(MockDeptProvider),
73 std::time::Duration::from_secs(300),
74 )),
75 Arc::new(CustomGeneratorRegistry::new()),
76 Arc::new(DataScopeMetrics::new()),
77 )
78 }
79
80 #[tokio::test]
81 async fn test_data_scope_async_injects_conditions() {
82 let evaluator = make_evaluator();
83 let ctx = DataScopeContext::new(1, 5, false);
84 let rule = DataScopeRule::new("order", DataScopeMode::Dept).with_dept_field("dept_id");
85 let builder = MockQueryBuilder { conditions: vec![] };
86 let result = builder
87 .data_scope_async(&ctx, &rule, &evaluator)
88 .await
89 .unwrap();
90 assert_eq!(result.conditions.len(), 1);
91 }
92
93 #[tokio::test]
94 async fn test_data_scope_async_super_bypass_empty() {
95 let evaluator = make_evaluator();
96 let ctx = DataScopeContext::new(1, 5, true);
97 let rule = DataScopeRule::new("order", DataScopeMode::Dept).with_dept_field("dept_id");
98 let builder = MockQueryBuilder { conditions: vec![] };
99 let result = builder
100 .data_scope_async(&ctx, &rule, &evaluator)
101 .await
102 .unwrap();
103 assert!(result.conditions.is_empty());
104 }
105
106 #[tokio::test]
107 async fn test_data_scope_async_dept_and_sub() {
108 let evaluator = make_evaluator();
109 let ctx = DataScopeContext::new(1, 5, false);
110 let rule =
111 DataScopeRule::new("order", DataScopeMode::DeptAndSub).with_dept_field("dept_id");
112 let builder = MockQueryBuilder { conditions: vec![] };
113 let result = builder
114 .data_scope_async(&ctx, &rule, &evaluator)
115 .await
116 .unwrap();
117 assert_eq!(result.conditions.len(), 1);
118 }
119}