mangadex_api/v5/rating/
get.rs

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