mangadex_api/v5/settings/template/
get.rs

1//! Builder for getting the latest Settings template.
2//!
3//! <https://api.mangadex.org/docs/swagger.html#/Settings/get-settings-template>
4//!
5//! ```rust
6//! use mangadex_api::MangaDexClient;
7//! // use mangadex_api_types::{Password, Username};
8//! use uuid::Uuid;
9//!
10//! # async fn run() -> anyhow::Result<()> {
11//! let client = MangaDexClient::default();
12//!
13//! /*
14//!
15//!     let _login_res = client
16//!         .auth()
17//!         .login()
18//!         .post()
19//!         .username(Username::parse("myusername")?)
20//!         .password(Password::parse("hunter23")?)
21//!         .send()
22//!         .await?;
23//!
24//!  */
25//!
26//! let res = client
27//!     .settings()
28//!     .template()
29//!     .get()
30//!     .send()
31//!     .await?;
32//!
33//! println!("Settings template: {:?}", res);
34//! # Ok(())
35//! # }
36//! ```
37
38use derive_builder::Builder;
39use serde::Serialize;
40
41use crate::HttpClientRef;
42use mangadex_api_schema::v5::UserSettingsTemplateResponse;
43
44/// Get the latest Settings template.
45///
46/// This requires authentication.
47///
48/// Makes a request to `GET /settings/template`.
49#[cfg_attr(
50    feature = "deserializable-endpoint",
51    derive(serde::Deserialize, getset::Getters, getset::Setters)
52)]
53#[derive(Debug, Serialize, Clone, Builder)]
54#[serde(rename_all = "camelCase")]
55#[builder(
56    setter(into, strip_option),
57    build_fn(error = "mangadex_api_types::error::BuilderError")
58)]
59#[cfg_attr(feature = "non_exhaustive", non_exhaustive)]
60pub struct GetLatestSettingsTemplate {
61    /// This should never be set manually as this is only for internal use.
62    #[doc(hidden)]
63    #[serde(skip)]
64    #[builder(pattern = "immutable")]
65    #[allow(unused)]
66    #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
67    pub http_client: HttpClientRef,
68}
69
70endpoint! {
71    GET "/settings/template",
72    #[no_data auth] GetLatestSettingsTemplate,
73    #[flatten_result] UserSettingsTemplateResponse,
74    GetLatestSettingsTemplateBuilder
75}
76
77#[cfg(test)]
78mod tests {
79    use mangadex_api_schema::v5::AuthTokens;
80    use serde_json::json;
81    use url::Url;
82    use uuid::Uuid;
83    use wiremock::matchers::{header, method, path_regex};
84    use wiremock::{Mock, MockServer, ResponseTemplate};
85
86    use crate::{HttpClient, MangaDexClient};
87    use mangadex_api_types::error::Error;
88
89    #[tokio::test]
90    async fn get_latest_settings_template() -> anyhow::Result<()> {
91        let mock_server = MockServer::start().await;
92        let http_client: HttpClient = HttpClient::builder()
93            .base_url(Url::parse(&mock_server.uri())?)
94            .auth_tokens(AuthTokens {
95                session: "sessiontoken".to_string(),
96                refresh: "refreshtoken".to_string(),
97            })
98            .build()?;
99        let mangadex_client = MangaDexClient::new_with_http_client(http_client);
100
101        let response_body = json!({
102            "result": "ok",
103            "response": "entity",
104            "data": {
105                "id": "f582e935-effb-4a39-821d-7a512e5b3f55",
106                "type": "settings_template",
107                "attributes": {
108                    "template": {
109                    },
110                    "createdAt": "2024-07-29T10:20:22+00:00",
111                    "updatedAt": "2024-07-29T10:20:22+00:00",
112                    "version": 1
113                },
114                "relationships": []
115            }
116        });
117
118        Mock::given(method("GET"))
119            .and(path_regex("/settings/template"))
120            .and(header("Authorization", "Bearer sessiontoken"))
121            .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
122            .expect(1)
123            .mount(&mock_server)
124            .await;
125
126        let res = mangadex_client.settings().template().get().send().await?;
127        assert_eq!(
128            res.data.attributes.template,
129            serde_json::Value::Object(Default::default())
130        );
131        Ok(())
132    }
133    #[tokio::test]
134    async fn get_latest_settings_template_requires_auth() -> anyhow::Result<()> {
135        let mock_server = MockServer::start().await;
136        let http_client: HttpClient = HttpClient::builder()
137            .base_url(Url::parse(&mock_server.uri())?)
138            .build()?;
139        let mangadex_client = MangaDexClient::new_with_http_client(http_client);
140
141        let error_id = Uuid::new_v4();
142        let response_body = json!({
143            "result": "error",
144            "errors": [{
145                "id": error_id.to_string(),
146                "status": 403,
147                "title": "Forbidden",
148                "detail": "You must be logged in to continue."
149            }]
150        });
151
152        Mock::given(method("GET"))
153            .and(path_regex("/settings/template"))
154            .respond_with(ResponseTemplate::new(403).set_body_json(response_body))
155            .expect(0)
156            .mount(&mock_server)
157            .await;
158
159        let res = mangadex_client
160            .settings()
161            .template()
162            .get()
163            .send()
164            .await
165            .expect_err("expected error");
166
167        match res {
168            Error::MissingTokens => {}
169            _ => panic!("unexpected error: {:#?}", res),
170        }
171
172        Ok(())
173    }
174}