1use crate::{
2 api_traits::{ApiOperation, UserInfo},
3 cmds::{project::Member, user::UserCliArgs},
4 error::GRError,
5 io::{HttpResponse, HttpRunner},
6 remote::{self, query},
7 Result,
8};
9
10use super::Gitlab;
11
12impl<R: HttpRunner<Response = HttpResponse>> UserInfo for Gitlab<R> {
13 fn get_auth_user(&self) -> Result<Member> {
14 let user = query::get::<_, (), _>(
15 &self.runner,
16 &self.base_current_user_url,
17 None,
18 self.headers(),
19 ApiOperation::Project,
20 |value| GitlabUserFields::from(value).into(),
21 )?;
22 Ok(user)
23 }
24
25 fn get(&self, args: &UserCliArgs) -> Result<Member> {
26 let url = format!("{}?username={}", self.base_users_url, args.username);
30 let list_args = remote::ListBodyArgs::builder()
33 .max_pages(1)
34 .get_args(args.get_args.clone())
35 .build()
36 .unwrap();
37 let user = query::paged::<_, Member>(
38 &self.runner,
39 &url,
40 Some(list_args),
41 self.headers(),
42 None,
43 ApiOperation::Project,
44 |value| GitlabUserFields::from(value).into(),
45 )?;
46 if user.is_empty() {
47 return Err(GRError::UserNotFound(args.username.clone()).into());
48 }
49 Ok(user[0].clone())
50 }
51}
52
53pub struct GitlabUserFields {
54 id: i64,
55 username: String,
56 name: String,
57}
58
59impl From<&serde_json::Value> for GitlabUserFields {
60 fn from(data: &serde_json::Value) -> Self {
61 GitlabUserFields {
62 id: data["id"].as_i64().unwrap(),
63 username: data["username"].as_str().unwrap().to_string(),
64 name: data["name"].as_str().unwrap().to_string(),
65 }
66 }
67}
68
69impl From<GitlabUserFields> for Member {
70 fn from(fields: GitlabUserFields) -> Self {
71 Member::builder()
72 .id(fields.id)
73 .name(fields.name)
74 .username(fields.username)
75 .build()
76 .unwrap()
77 }
78}
79
80#[cfg(test)]
81mod test {
82 use crate::{
83 api_traits::ApiOperation,
84 error, setup_client,
85 test::utils::{default_gitlab, ContractType, ResponseContracts},
86 };
87
88 use super::*;
89
90 #[test]
91 fn test_get_user_id() {
92 let contracts = ResponseContracts::new(ContractType::Gitlab).add_contract(
93 200,
94 "get_user_info.json",
95 None,
96 );
97 let (client, gitlab) = setup_client!(contracts, default_gitlab(), dyn UserInfo);
98 let user = gitlab.get_auth_user().unwrap();
99 assert_eq!(123456, user.id);
100 assert_eq!("jordilin", user.username);
101 assert_eq!("https://gitlab.com/api/v4/user", *client.url(),);
102 assert_eq!("1234", client.headers().get("PRIVATE-TOKEN").unwrap());
103 assert_eq!(Some(ApiOperation::Project), *client.api_operation.borrow());
104 }
105
106 #[test]
107 fn test_get_user_by_username_ok() {
108 let contracts = ResponseContracts::new(ContractType::Gitlab).add_contract(
109 200,
110 "get_user_by_username.json",
111 None,
112 );
113 let (client, gitlab) = setup_client!(contracts, default_gitlab(), dyn UserInfo);
114 let username = "tomsawyer";
115 let args = UserCliArgs::builder()
116 .username(username.to_string())
117 .get_args(remote::GetRemoteCliArgs::builder().build().unwrap())
118 .build()
119 .unwrap();
120 let user = gitlab.get(&args).unwrap();
121 assert_eq!(12345, user.id);
122 assert_eq!("tomsawyer", user.username);
123 assert_eq!(
124 "https://gitlab.com/api/v4/users?username=tomsawyer",
125 *client.url(),
126 );
127 assert_eq!("1234", client.headers().get("PRIVATE-TOKEN").unwrap());
128 assert_eq!(Some(ApiOperation::Project), *client.api_operation.borrow());
129 }
130
131 #[test]
132 fn test_username_not_found_is_error() {
133 let contracts = ResponseContracts::new(ContractType::Gitlab).add_body::<String>(
134 200,
135 Some("[]".to_string()),
136 None,
137 );
138 let (_, gitlab) = setup_client!(contracts, default_gitlab(), dyn UserInfo);
139 let username = "notfound";
140 let args = UserCliArgs::builder()
141 .username(username.to_string())
142 .get_args(remote::GetRemoteCliArgs::builder().build().unwrap())
143 .build()
144 .unwrap();
145 let result = gitlab.get(&args);
146 match result {
147 Err(err) => match err.downcast_ref::<error::GRError>() {
148 Some(error::GRError::UserNotFound(_)) => {}
149 _ => panic!("Expected user not found error"),
150 },
151 Ok(_) => panic!("Expected user not found error"),
152 }
153 }
154}