gr/github/
user.rs

1use super::Github;
2use crate::api_traits::{ApiOperation, UserInfo};
3use crate::cmds::project::Member;
4use crate::cmds::user::UserCliArgs;
5use crate::io::{HttpResponse, HttpRunner};
6use crate::remote::query;
7use crate::Result;
8
9impl<R: HttpRunner<Response = HttpResponse>> UserInfo for Github<R> {
10    fn get_auth_user(&self) -> Result<Member> {
11        let url = format!("{}/user", self.rest_api_basepath);
12        let user = query::get::<_, (), Member>(
13            &self.runner,
14            &url,
15            None,
16            self.request_headers(),
17            ApiOperation::Project,
18            |value| GithubUserFields::from(value).into(),
19        )?;
20        Ok(user)
21    }
22
23    fn get(&self, _args: &UserCliArgs) -> Result<Member> {
24        // https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-a-user
25        let url = format!("{}/users/{}", self.rest_api_basepath, _args.username);
26        let user = query::get::<_, (), Member>(
27            &self.runner,
28            &url,
29            None,
30            self.request_headers(),
31            ApiOperation::Project,
32            |value| GithubUserFields::from(value).into(),
33        )?;
34        Ok(user)
35    }
36}
37
38pub struct GithubUserFields {
39    id: i64,
40    login: String,
41    name: String,
42}
43
44impl From<&serde_json::Value> for GithubUserFields {
45    fn from(data: &serde_json::Value) -> Self {
46        GithubUserFields {
47            id: data["id"].as_i64().unwrap(),
48            login: data["login"].as_str().unwrap().to_string(),
49            name: data["name"].as_str().unwrap_or_default().to_string(),
50        }
51    }
52}
53
54impl From<GithubUserFields> for Member {
55    fn from(fields: GithubUserFields) -> Self {
56        Member::builder()
57            .id(fields.id)
58            .name(fields.name)
59            .username(fields.login)
60            .build()
61            .unwrap()
62    }
63}
64
65#[cfg(test)]
66mod test {
67
68    use crate::{
69        api_traits::ApiOperation,
70        remote, setup_client,
71        test::utils::{default_github, ContractType, ResponseContracts},
72    };
73
74    use super::*;
75
76    #[test]
77    fn test_get_user_id() {
78        let contracts = ResponseContracts::new(ContractType::Github).add_contract(
79            200,
80            "get_auth_user.json",
81            None,
82        );
83        let (client, github) = setup_client!(contracts, default_github(), dyn UserInfo);
84        let user = github.get_auth_user().unwrap();
85
86        assert_eq!(123456, user.id);
87        assert_eq!("jdoe", user.username);
88        assert_eq!("https://api.github.com/user", *client.url(),);
89        assert_eq!(Some(ApiOperation::Project), *client.api_operation.borrow());
90    }
91
92    #[test]
93    fn test_get_user_by_username() {
94        let contracts = ResponseContracts::new(ContractType::Github).add_contract(
95            200,
96            "get_user_by_username.json",
97            None,
98        );
99        let (client, github) = setup_client!(contracts, default_github(), dyn UserInfo);
100        let args = UserCliArgs::builder()
101            .username("octocat".to_string())
102            .get_args(remote::GetRemoteCliArgs::builder().build().unwrap())
103            .build()
104            .unwrap();
105        let user = github.get(&args).unwrap();
106
107        assert_eq!(1, user.id);
108        assert_eq!("octocat", user.username);
109        assert_eq!("https://api.github.com/users/octocat", *client.url(),);
110        assert_eq!(Some(ApiOperation::Project), *client.api_operation.borrow());
111    }
112}