mangadex_api/v5/user/me/
get.rs

1//! Builder for the logged-in user details endpoint.
2//!
3//! <https://api.mangadex.org/swagger.html#/User/get-user-me>
4//!
5//! # Examples
6//!
7//! ```rust
8//! use mangadex_api::MangaDexClient;
9//! // use mangadex_api_types::{Password, Username};
10//!
11//! # async fn run() -> anyhow::Result<()> {
12//! let client = MangaDexClient::default();
13//!
14//! /*
15//!
16//!     let _login_res = client
17//!         .auth()
18//!         .login()
19//!         .get()
20//!         .username(Username::parse("myusername")?)
21//!         .password(Password::parse("hunter23")?)
22//!         .send()
23//!         .await?;
24//!  */
25//!
26//!
27//! let res = client
28//!     .user()
29//!     .me()
30//!     .get()
31//!     .send()
32//!     .await?;
33//!
34//! println!("me: {:?}", res);
35//! # Ok(())
36//! # }
37//! ```
38
39use derive_builder::Builder;
40use serde::Serialize;
41
42use crate::HttpClientRef;
43use mangadex_api_schema::v5::UserResponse;
44
45#[cfg_attr(
46    feature = "deserializable-endpoint",
47    derive(serde::Deserialize, getset::Getters, getset::Setters)
48)]
49#[derive(Debug, Serialize, Clone, Builder)]
50#[serde(rename_all = "camelCase")]
51#[builder(
52    setter(into, strip_option),
53    build_fn(error = "mangadex_api_types::error::BuilderError")
54)]
55pub struct GetMyUserDetails {
56    /// This should never be set manually as this is only for internal use.
57    #[doc(hidden)]
58    #[serde(skip)]
59    #[builder(pattern = "immutable")]
60    #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
61    pub http_client: HttpClientRef,
62}
63
64endpoint! {
65    GET "/user/me",
66    #[query auth] GetMyUserDetails,
67    #[flatten_result] UserResponse,
68    GetMyUserDetailsBuilder
69}
70
71#[cfg(test)]
72mod tests {
73    use mangadex_api_schema::v5::AuthTokens;
74    use serde_json::json;
75    use url::Url;
76    use uuid::Uuid;
77    use wiremock::matchers::{header, method, path};
78    use wiremock::{Mock, MockServer, ResponseTemplate};
79
80    use crate::{HttpClient, MangaDexClient};
81
82    #[tokio::test]
83    async fn get_my_details_fires_a_request_to_base_url() -> anyhow::Result<()> {
84        let mock_server = MockServer::start().await;
85        let http_client = HttpClient::builder()
86            .base_url(Url::parse(&mock_server.uri())?)
87            .auth_tokens(AuthTokens {
88                session: "sessiontoken".to_string(),
89                refresh: "refreshtoken".to_string(),
90            })
91            .build()?;
92        let mangadex_client = MangaDexClient::new_with_http_client(http_client);
93
94        let user_id = Uuid::new_v4();
95        let response_body = json!({
96            "result": "ok",
97            "response": "entity",
98            "data": {
99                "id": user_id,
100                "type": "user",
101                "attributes": {
102                    "username": "myusername",
103                    "roles": [
104                        "ROLE_MEMBER",
105                        "ROLE_GROUP_MEMBER",
106                        "ROLE_GROUP_LEADER"
107                    ],
108                    "version": 1,
109                },
110                "relationships": [
111                    {
112                        "id": "a3219a4f-73c0-4213-8730-05985130539a",
113                        "type": "scanlation_group"
114                    }
115                ]
116            }
117        });
118
119        Mock::given(method("GET"))
120            .and(path(r"/user/me"))
121            .and(header("Authorization", "Bearer sessiontoken"))
122            .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
123            .expect(1)
124            .mount(&mock_server)
125            .await;
126
127        let _ = mangadex_client.user().me().get().send().await?;
128
129        Ok(())
130    }
131}