mangadex_api/v5/settings/
get.rs

1//! Builder for getting a user's Settings.
2//!
3//! <https://api.mangadex.org/docs/swagger.html#/Settings/get-settings>
4//!
5//! ```rust
6//! use mangadex_api::MangaDexClient;
7//! // use mangadex_api_types::{Password, Username};
8//!
9//! # async fn run() -> anyhow::Result<()> {
10//! let client = MangaDexClient::default();
11//!
12//! /*
13//!
14//!     let _login_res = client
15//!         .auth()
16//!         .login()
17//!         .post()
18//!         .username(Username::parse("myusername")?)
19//!         .password(Password::parse("hunter23")?)
20//!         .send()
21//!         .await?;
22//!
23//!  */
24//!
25//! let res = client
26//!     .settings()
27//!     .get()
28//!     .send()
29//!     .await?;
30//!
31//! println!("User Settings: {:?}", res);
32//! # Ok(())
33//! # }
34//! ```
35
36use derive_builder::Builder;
37use serde::Serialize;
38
39use crate::HttpClientRef;
40use mangadex_api_schema::v5::UserSettingsResponse;
41
42/// Getting a user's Settings.
43///
44/// This requires authentication.
45///
46/// Makes a request to `GET /settings`.
47#[cfg_attr(
48    feature = "deserializable-endpoint",
49    derive(serde::Deserialize, getset::Getters, getset::Setters)
50)]
51#[derive(Debug, Serialize, Clone, Builder)]
52#[serde(rename_all = "camelCase")]
53#[builder(
54    setter(into, strip_option),
55    build_fn(error = "mangadex_api_types::error::BuilderError")
56)]
57#[cfg_attr(feature = "non_exhaustive", non_exhaustive)]
58pub struct GetUserSettings {
59    /// This should never be set manually as this is only for internal use.
60    #[doc(hidden)]
61    #[serde(skip)]
62    #[builder(pattern = "immutable")]
63    #[allow(unused)]
64    #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
65    pub http_client: HttpClientRef,
66}
67
68endpoint! {
69    GET "/settings",
70    #[no_data auth] GetUserSettings,
71    #[flatten_result] UserSettingsResponse,
72    GetUserSettingsBuilder
73}
74
75#[cfg(test)]
76mod tests {
77    use serde_json::json;
78    use url::Url;
79    use uuid::Uuid;
80    use wiremock::matchers::{method, path};
81    use wiremock::{Mock, MockServer, ResponseTemplate};
82
83    use crate::{HttpClient, MangaDexClient};
84    use mangadex_api_types::error::Error;
85
86    #[tokio::test]
87    async fn get_user_settings_requires_auth() -> anyhow::Result<()> {
88        let mock_server = MockServer::start().await;
89        let http_client: HttpClient = HttpClient::builder()
90            .base_url(Url::parse(&mock_server.uri())?)
91            .build()?;
92        let mangadex_client = MangaDexClient::new_with_http_client(http_client);
93
94        let error_id = Uuid::new_v4();
95        let response_body = json!({
96            "result": "error",
97            "errors": [{
98                "id": error_id.to_string(),
99                "status": 403,
100                "title": "Forbidden",
101                "detail": "You must be logged in to continue."
102            }]
103        });
104
105        Mock::given(method("GET"))
106            .and(path("/settings"))
107            .respond_with(ResponseTemplate::new(403).set_body_json(response_body))
108            .expect(0)
109            .mount(&mock_server)
110            .await;
111
112        let res = mangadex_client
113            .settings()
114            .get()
115            .send()
116            .await
117            .expect_err("expected error");
118
119        match res {
120            Error::MissingTokens => {}
121            _ => panic!("unexpected error: {:#?}", res),
122        }
123
124        Ok(())
125    }
126}