open_lark/service/contact/v3/
group_member.rs

1use crate::{
2    core::{
3        api_req::ApiRequest, api_resp::ApiResponseTrait, config::Config,
4        constants::AccessTokenType, endpoints::EndpointBuilder, http::Transport,
5    },
6    service::contact::models::*,
7};
8use serde::{Deserialize, Serialize};
9
10/// 用户组成员服务
11#[derive(Debug)]
12pub struct GroupMemberService {
13    config: Config,
14}
15
16impl GroupMemberService {
17    pub fn new(config: Config) -> Self {
18        Self { config }
19    }
20
21    /// 添加用户组成员
22    pub async fn add(
23        &self,
24        group_id: &str,
25        req: &AddGroupMemberRequest,
26    ) -> crate::core::SDKResult<AddGroupMemberResponse> {
27        let api_req = ApiRequest {
28            http_method: reqwest::Method::POST,
29            api_path: EndpointBuilder::replace_param(
30                crate::core::endpoints::contact::CONTACT_V3_GROUP_MEMBERS_ADD,
31                "group_id",
32                group_id,
33            ),
34            supported_access_token_types: vec![AccessTokenType::Tenant],
35            body: serde_json::to_vec(req)?,
36            ..Default::default()
37        };
38
39        let resp =
40            Transport::<AddGroupMemberResponse>::request(api_req, &self.config, None).await?;
41        Ok(resp.data.unwrap_or_default())
42    }
43
44    /// 批量添加用户组成员
45    pub async fn batch_add(
46        &self,
47        group_id: &str,
48        req: &BatchAddGroupMembersRequest,
49    ) -> crate::core::SDKResult<BatchAddGroupMembersResponse> {
50        let api_req = ApiRequest {
51            http_method: reqwest::Method::POST,
52            api_path: EndpointBuilder::replace_param(
53                crate::core::endpoints::contact::CONTACT_V3_GROUP_MEMBERS_BATCH_ADD,
54                "group_id",
55                group_id,
56            ),
57            supported_access_token_types: vec![AccessTokenType::Tenant],
58            body: serde_json::to_vec(req)?,
59            ..Default::default()
60        };
61
62        let resp =
63            Transport::<BatchAddGroupMembersResponse>::request(api_req, &self.config, None).await?;
64        Ok(resp.data.unwrap_or_default())
65    }
66
67    /// 查询用户组成员列表
68    pub async fn simplelist(
69        &self,
70        group_id: &str,
71        _req: &ListGroupMembersRequest,
72    ) -> crate::core::SDKResult<ListGroupMembersResponse> {
73        let api_req = ApiRequest {
74            http_method: reqwest::Method::GET,
75            api_path: EndpointBuilder::replace_param(
76                crate::core::endpoints::contact::CONTACT_V3_GROUP_MEMBERS_SIMPLELIST,
77                "group_id",
78                group_id,
79            ),
80            supported_access_token_types: vec![AccessTokenType::Tenant],
81            body: Vec::new(),
82            query_params: std::collections::HashMap::new(),
83            ..Default::default()
84        };
85
86        let resp =
87            Transport::<ListGroupMembersResponse>::request(api_req, &self.config, None).await?;
88        Ok(resp.data.unwrap_or_default())
89    }
90
91    /// 移除用户组成员
92    pub async fn remove(
93        &self,
94        group_id: &str,
95        req: &RemoveGroupMemberRequest,
96    ) -> crate::core::SDKResult<RemoveGroupMemberResponse> {
97        let api_req = ApiRequest {
98            http_method: reqwest::Method::POST,
99            api_path: EndpointBuilder::replace_param(
100                crate::core::endpoints::contact::CONTACT_V3_GROUP_MEMBERS_REMOVE,
101                "group_id",
102                group_id,
103            ),
104            supported_access_token_types: vec![AccessTokenType::Tenant],
105            body: serde_json::to_vec(req)?,
106            ..Default::default()
107        };
108
109        let resp =
110            Transport::<RemoveGroupMemberResponse>::request(api_req, &self.config, None).await?;
111        Ok(resp.data.unwrap_or_default())
112    }
113
114    /// 批量移除用户组成员
115    pub async fn batch_remove(
116        &self,
117        group_id: &str,
118        req: &BatchRemoveGroupMembersRequest,
119    ) -> crate::core::SDKResult<BatchRemoveGroupMembersResponse> {
120        let api_req = ApiRequest {
121            http_method: reqwest::Method::POST,
122            api_path: EndpointBuilder::replace_param(
123                crate::core::endpoints::contact::CONTACT_V3_GROUP_MEMBERS_BATCH_REMOVE,
124                "group_id",
125                group_id,
126            ),
127            supported_access_token_types: vec![AccessTokenType::Tenant],
128            body: serde_json::to_vec(req)?,
129            ..Default::default()
130        };
131
132        let resp =
133            Transport::<BatchRemoveGroupMembersResponse>::request(api_req, &self.config, None)
134                .await?;
135        Ok(resp.data.unwrap_or_default())
136    }
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct AddGroupMemberRequest {
141    pub member_id: String,
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub member_id_type: Option<String>,
144    #[serde(skip_serializing_if = "Option::is_none")]
145    pub member_type: Option<String>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize, Default)]
149pub struct AddGroupMemberResponse {}
150
151impl ApiResponseTrait for AddGroupMemberResponse {
152    fn data_format() -> crate::core::api_resp::ResponseFormat {
153        crate::core::api_resp::ResponseFormat::Data
154    }
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct BatchAddGroupMembersRequest {
159    pub members: Vec<GroupMemberInfo>,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, Default)]
163pub struct BatchAddGroupMembersResponse {
164    pub results: Vec<GroupMemberResult>,
165}
166
167impl ApiResponseTrait for BatchAddGroupMembersResponse {
168    fn data_format() -> crate::core::api_resp::ResponseFormat {
169        crate::core::api_resp::ResponseFormat::Data
170    }
171}
172
173#[derive(Debug, Clone, Default, Serialize, Deserialize)]
174pub struct ListGroupMembersRequest {
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub member_id_type: Option<String>,
177    #[serde(skip_serializing_if = "Option::is_none")]
178    pub member_type: Option<String>,
179    #[serde(skip_serializing_if = "Option::is_none")]
180    pub page_size: Option<i32>,
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub page_token: Option<String>,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize, Default)]
186pub struct ListGroupMembersResponse {
187    pub memberlist: Vec<GroupMember>,
188    #[serde(skip_serializing_if = "Option::is_none")]
189    pub has_more: Option<bool>,
190    #[serde(skip_serializing_if = "Option::is_none")]
191    pub page_token: Option<String>,
192}
193
194impl ApiResponseTrait for ListGroupMembersResponse {
195    fn data_format() -> crate::core::api_resp::ResponseFormat {
196        crate::core::api_resp::ResponseFormat::Data
197    }
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct RemoveGroupMemberRequest {
202    pub member_id: String,
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub member_id_type: Option<String>,
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub member_type: Option<String>,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize, Default)]
210pub struct RemoveGroupMemberResponse {}
211
212impl ApiResponseTrait for RemoveGroupMemberResponse {
213    fn data_format() -> crate::core::api_resp::ResponseFormat {
214        crate::core::api_resp::ResponseFormat::Data
215    }
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct BatchRemoveGroupMembersRequest {
220    pub members: Vec<GroupMemberInfo>,
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize, Default)]
224pub struct BatchRemoveGroupMembersResponse {
225    pub results: Vec<GroupMemberResult>,
226}
227
228impl ApiResponseTrait for BatchRemoveGroupMembersResponse {
229    fn data_format() -> crate::core::api_resp::ResponseFormat {
230        crate::core::api_resp::ResponseFormat::Data
231    }
232}
233
234#[cfg(test)]
235mod tests {
236    use super::*;
237    use crate::core::config::Config;
238
239    #[test]
240    fn test_group_member_service_creation() {
241        let config = Config::default();
242        let service = GroupMemberService::new(config);
243        assert!(!format!("{:?}", service).is_empty());
244    }
245
246    #[test]
247    fn test_group_member_service_creation_with_custom_config() {
248        let config = Config::builder()
249            .app_id("test_app_id")
250            .app_secret("test_secret")
251            .build();
252        let service = GroupMemberService::new(config);
253        assert!(!format!("{:?}", service).is_empty());
254    }
255
256    #[test]
257    fn test_add_group_member_request_construction() {
258        let request = AddGroupMemberRequest {
259            member_id: "user123".to_string(),
260            member_id_type: Some("user_id".to_string()),
261            member_type: Some("user".to_string()),
262        };
263        assert_eq!(request.member_id, "user123");
264        assert_eq!(request.member_id_type, Some("user_id".to_string()));
265        assert_eq!(request.member_type, Some("user".to_string()));
266    }
267
268    #[test]
269    fn test_add_group_member_request_with_none_values() {
270        let request = AddGroupMemberRequest {
271            member_id: "user456".to_string(),
272            member_id_type: None,
273            member_type: None,
274        };
275        assert_eq!(request.member_id, "user456");
276        assert_eq!(request.member_id_type, None);
277        assert_eq!(request.member_type, None);
278    }
279
280    #[test]
281    fn test_add_group_member_request_with_empty_id() {
282        let request = AddGroupMemberRequest {
283            member_id: "".to_string(),
284            member_id_type: Some("user_id".to_string()),
285            member_type: Some("user".to_string()),
286        };
287        assert_eq!(request.member_id, "");
288    }
289
290    #[test]
291    fn test_add_group_member_request_with_long_values() {
292        let long_id = "a".repeat(1000);
293        let long_type = "b".repeat(500);
294        let request = AddGroupMemberRequest {
295            member_id: long_id.clone(),
296            member_id_type: Some(long_type.clone()),
297            member_type: Some("user".to_string()),
298        };
299        assert_eq!(request.member_id, long_id);
300        assert_eq!(request.member_id_type, Some(long_type));
301    }
302
303    #[test]
304    fn test_add_group_member_response_default() {
305        let response = AddGroupMemberResponse::default();
306        assert!(!format!("{:?}", response).is_empty());
307    }
308
309    #[test]
310    fn test_add_group_member_response_data_format() {
311        assert_eq!(
312            AddGroupMemberResponse::data_format(),
313            crate::core::api_resp::ResponseFormat::Data
314        );
315    }
316
317    #[test]
318    fn test_batch_add_group_members_request_construction() {
319        let members = vec![
320            GroupMemberInfo {
321                member_id: "user1".to_string(),
322                member_id_type: Some("user_id".to_string()),
323                member_type: Some("user".to_string()),
324            },
325            GroupMemberInfo {
326                member_id: "user2".to_string(),
327                member_id_type: Some("user_id".to_string()),
328                member_type: Some("user".to_string()),
329            },
330        ];
331        let request = BatchAddGroupMembersRequest { members };
332        assert_eq!(request.members.len(), 2);
333        assert_eq!(request.members[0].member_id, "user1");
334        assert_eq!(request.members[1].member_id, "user2");
335    }
336
337    #[test]
338    fn test_batch_add_group_members_request_with_empty_members() {
339        let request = BatchAddGroupMembersRequest {
340            members: Vec::new(),
341        };
342        assert_eq!(request.members.len(), 0);
343    }
344
345    #[test]
346    fn test_batch_add_group_members_request_with_large_list() {
347        let mut members = Vec::new();
348        for i in 0..1000 {
349            members.push(GroupMemberInfo {
350                member_id: format!("user_{}", i),
351                member_id_type: Some("user_id".to_string()),
352                member_type: Some("user".to_string()),
353            });
354        }
355        let request = BatchAddGroupMembersRequest { members };
356        assert_eq!(request.members.len(), 1000);
357    }
358
359    #[test]
360    fn test_batch_add_group_members_response_default() {
361        let response = BatchAddGroupMembersResponse::default();
362        assert_eq!(response.results.len(), 0);
363    }
364
365    #[test]
366    fn test_batch_add_group_members_response_data_format() {
367        assert_eq!(
368            BatchAddGroupMembersResponse::data_format(),
369            crate::core::api_resp::ResponseFormat::Data
370        );
371    }
372
373    #[test]
374    fn test_list_group_members_request_default() {
375        let request = ListGroupMembersRequest::default();
376        assert_eq!(request.member_id_type, None);
377        assert_eq!(request.member_type, None);
378        assert_eq!(request.page_size, None);
379        assert_eq!(request.page_token, None);
380    }
381
382    #[test]
383    fn test_list_group_members_request_with_pagination() {
384        let request = ListGroupMembersRequest {
385            member_id_type: Some("user_id".to_string()),
386            member_type: Some("user".to_string()),
387            page_size: Some(50),
388            page_token: Some("token123".to_string()),
389        };
390        assert_eq!(request.member_id_type, Some("user_id".to_string()));
391        assert_eq!(request.member_type, Some("user".to_string()));
392        assert_eq!(request.page_size, Some(50));
393        assert_eq!(request.page_token, Some("token123".to_string()));
394    }
395
396    #[test]
397    fn test_list_group_members_request_with_large_page_size() {
398        let request = ListGroupMembersRequest {
399            member_id_type: None,
400            member_type: None,
401            page_size: Some(10000),
402            page_token: None,
403        };
404        assert_eq!(request.page_size, Some(10000));
405    }
406
407    #[test]
408    fn test_list_group_members_request_with_negative_page_size() {
409        let request = ListGroupMembersRequest {
410            member_id_type: None,
411            member_type: None,
412            page_size: Some(-1),
413            page_token: None,
414        };
415        assert_eq!(request.page_size, Some(-1));
416    }
417
418    #[test]
419    fn test_list_group_members_request_with_empty_values() {
420        let request = ListGroupMembersRequest {
421            member_id_type: Some("".to_string()),
422            member_type: Some("".to_string()),
423            page_size: Some(0),
424            page_token: Some("".to_string()),
425        };
426        assert_eq!(request.member_id_type, Some("".to_string()));
427        assert_eq!(request.member_type, Some("".to_string()));
428        assert_eq!(request.page_size, Some(0));
429        assert_eq!(request.page_token, Some("".to_string()));
430    }
431
432    #[test]
433    fn test_list_group_members_response_default() {
434        let response = ListGroupMembersResponse::default();
435        assert_eq!(response.memberlist.len(), 0);
436        assert_eq!(response.has_more, None);
437        assert_eq!(response.page_token, None);
438    }
439
440    #[test]
441    fn test_list_group_members_response_with_members() {
442        let members = vec![
443            GroupMember {
444                member_id: Some("member1".to_string()),
445                member_type: Some("user".to_string()),
446                member_id_type: Some("user_id".to_string()),
447            },
448            GroupMember {
449                member_id: Some("member2".to_string()),
450                member_type: Some("user".to_string()),
451                member_id_type: Some("user_id".to_string()),
452            },
453        ];
454        let response = ListGroupMembersResponse {
455            memberlist: members,
456            has_more: Some(true),
457            page_token: Some("next_page".to_string()),
458        };
459        assert_eq!(response.memberlist.len(), 2);
460        assert_eq!(response.has_more, Some(true));
461        assert_eq!(response.page_token, Some("next_page".to_string()));
462    }
463
464    #[test]
465    fn test_list_group_members_response_data_format() {
466        assert_eq!(
467            ListGroupMembersResponse::data_format(),
468            crate::core::api_resp::ResponseFormat::Data
469        );
470    }
471
472    #[test]
473    fn test_remove_group_member_request_construction() {
474        let request = RemoveGroupMemberRequest {
475            member_id: "user789".to_string(),
476            member_id_type: Some("user_id".to_string()),
477            member_type: Some("user".to_string()),
478        };
479        assert_eq!(request.member_id, "user789");
480        assert_eq!(request.member_id_type, Some("user_id".to_string()));
481        assert_eq!(request.member_type, Some("user".to_string()));
482    }
483
484    #[test]
485    fn test_remove_group_member_request_with_none_values() {
486        let request = RemoveGroupMemberRequest {
487            member_id: "user101".to_string(),
488            member_id_type: None,
489            member_type: None,
490        };
491        assert_eq!(request.member_id, "user101");
492        assert_eq!(request.member_id_type, None);
493        assert_eq!(request.member_type, None);
494    }
495
496    #[test]
497    fn test_remove_group_member_response_default() {
498        let response = RemoveGroupMemberResponse::default();
499        assert!(!format!("{:?}", response).is_empty());
500    }
501
502    #[test]
503    fn test_remove_group_member_response_data_format() {
504        assert_eq!(
505            RemoveGroupMemberResponse::data_format(),
506            crate::core::api_resp::ResponseFormat::Data
507        );
508    }
509
510    #[test]
511    fn test_batch_remove_group_members_request_construction() {
512        let members = vec![
513            GroupMemberInfo {
514                member_id: "user1".to_string(),
515                member_id_type: Some("user_id".to_string()),
516                member_type: Some("user".to_string()),
517            },
518            GroupMemberInfo {
519                member_id: "user2".to_string(),
520                member_id_type: Some("user_id".to_string()),
521                member_type: Some("user".to_string()),
522            },
523        ];
524        let request = BatchRemoveGroupMembersRequest { members };
525        assert_eq!(request.members.len(), 2);
526        assert_eq!(request.members[0].member_id, "user1");
527        assert_eq!(request.members[1].member_id, "user2");
528    }
529
530    #[test]
531    fn test_batch_remove_group_members_request_with_empty_members() {
532        let request = BatchRemoveGroupMembersRequest {
533            members: Vec::new(),
534        };
535        assert_eq!(request.members.len(), 0);
536    }
537
538    #[test]
539    fn test_batch_remove_group_members_response_default() {
540        let response = BatchRemoveGroupMembersResponse::default();
541        assert_eq!(response.results.len(), 0);
542    }
543
544    #[test]
545    fn test_batch_remove_group_members_response_data_format() {
546        assert_eq!(
547            BatchRemoveGroupMembersResponse::data_format(),
548            crate::core::api_resp::ResponseFormat::Data
549        );
550    }
551
552    #[test]
553    fn test_config_independence() {
554        let config1 = Config::default();
555        let config2 = Config::default();
556        let service1 = GroupMemberService::new(config1);
557        let service2 = GroupMemberService::new(config2);
558        assert!(!format!("{:?}", service1).is_empty());
559        assert!(!format!("{:?}", service2).is_empty());
560    }
561
562    #[test]
563    fn test_all_structs_debug_trait() {
564        let add_request = AddGroupMemberRequest {
565            member_id: "test".to_string(),
566            member_id_type: Some("test".to_string()),
567            member_type: Some("test".to_string()),
568        };
569        let batch_add_request = BatchAddGroupMembersRequest {
570            members: vec![GroupMemberInfo {
571                member_id: "test".to_string(),
572                member_id_type: Some("test".to_string()),
573                member_type: Some("test".to_string()),
574            }],
575        };
576        let list_request = ListGroupMembersRequest::default();
577        let remove_request = RemoveGroupMemberRequest {
578            member_id: "test".to_string(),
579            member_id_type: Some("test".to_string()),
580            member_type: Some("test".to_string()),
581        };
582        let batch_remove_request = BatchRemoveGroupMembersRequest {
583            members: vec![GroupMemberInfo {
584                member_id: "test".to_string(),
585                member_id_type: Some("test".to_string()),
586                member_type: Some("test".to_string()),
587            }],
588        };
589
590        assert!(format!("{:?}", add_request).contains("test"));
591        assert!(format!("{:?}", batch_add_request).contains("test"));
592        assert!(!format!("{:?}", list_request).is_empty());
593        assert!(format!("{:?}", remove_request).contains("test"));
594        assert!(format!("{:?}", batch_remove_request).contains("test"));
595
596        let add_response = AddGroupMemberResponse::default();
597        let batch_add_response = BatchAddGroupMembersResponse::default();
598        let list_response = ListGroupMembersResponse::default();
599        let remove_response = RemoveGroupMemberResponse::default();
600        let batch_remove_response = BatchRemoveGroupMembersResponse::default();
601
602        assert!(!format!("{:?}", add_response).is_empty());
603        assert!(!format!("{:?}", batch_add_response).is_empty());
604        assert!(!format!("{:?}", list_response).is_empty());
605        assert!(!format!("{:?}", remove_response).is_empty());
606        assert!(!format!("{:?}", batch_remove_response).is_empty());
607    }
608}