mangadex_api/v5/settings/template/version/
get.rs

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