mangadex_api/v5/manga/read/
get.rs1use derive_builder::Builder;
31use serde::Serialize;
32use uuid::Uuid;
33
34use crate::HttpClientRef;
35use mangadex_api_schema::v5::MangaReadMarkersResponse;
36
37#[cfg_attr(
38 feature = "deserializable-endpoint",
39 derive(serde::Deserialize, getset::Getters, getset::Setters)
40)]
41#[derive(Debug, Serialize, Clone, Builder)]
42#[serde(rename_all = "camelCase")]
43#[builder(
44 setter(into, strip_option),
45 build_fn(error = "mangadex_api_types::error::BuilderError")
46)]
47pub struct GetReadChapters {
48 #[doc(hidden)]
50 #[serde(skip)]
51 #[builder(pattern = "immutable")]
52 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
53 pub http_client: HttpClientRef,
54
55 #[builder(setter(each = "add_manga_id"))]
56 #[serde(rename = "ids")]
57 pub manga_ids: Vec<Uuid>,
58
59 #[builder(default)]
65 pub grouped: bool,
66}
67
68endpoint! {
69 GET "/manga/read",
70 #[query auth] GetReadChapters,
71 #[flatten_result] MangaReadMarkersResponse,
72 GetReadChaptersBuilder
73}
74
75#[cfg(test)]
76mod tests {
77 use serde_json::json;
78 use url::Url;
79 use uuid::Uuid;
80 use wiremock::matchers::{header, method, path_regex};
81 use wiremock::{Mock, MockServer, ResponseTemplate};
82
83 use crate::v5::AuthTokens;
84 use crate::{HttpClient, MangaDexClient};
85 use mangadex_api_schema::v5::MangaReadMarkers;
86
87 #[tokio::test]
88 async fn get_read_markers_fires_a_request_to_base_url_ungrouped() -> anyhow::Result<()> {
89 let mock_server = MockServer::start().await;
90 let http_client = HttpClient::builder()
91 .base_url(Url::parse(&mock_server.uri())?)
92 .auth_tokens(AuthTokens {
93 session: "sessiontoken".to_string(),
94 refresh: "refreshtoken".to_string(),
95 })
96 .build()?;
97 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
98
99 let manga_id = Uuid::new_v4();
100 let chapter_ids = [
101 Uuid::parse_str("00057883-357b-4734-9469-52967e59ef4c")?,
102 Uuid::parse_str("000b7978-d9bd-49ec-a8f6-a0737368415f")?,
103 Uuid::parse_str("0015b621-a175-47f5-81fb-5976c88e18c4")?,
104 ];
105 let response_body = json!({
106 "result": "ok",
107 "data": chapter_ids
108 });
109
110 Mock::given(method("GET"))
111 .and(path_regex(r"/manga/read"))
112 .and(header("Authorization", "Bearer sessiontoken"))
113 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
114 .expect(1)
115 .mount(&mock_server)
116 .await;
117
118 let res = mangadex_client
119 .manga()
120 .read()
121 .get()
122 .add_manga_id(manga_id)
123 .send()
124 .await?;
125
126 if let MangaReadMarkers::Grouped(_) = res {
127 panic!("unexpected grouped response");
128 }
129
130 Ok(())
131 }
132
133 #[tokio::test]
134 async fn get_read_markers_fires_a_request_to_base_url_grouped() -> anyhow::Result<()> {
135 let mock_server = MockServer::start().await;
136 let http_client = HttpClient::builder()
137 .base_url(Url::parse(&mock_server.uri())?)
138 .auth_tokens(AuthTokens {
139 session: "sessiontoken".to_string(),
140 refresh: "refreshtoken".to_string(),
141 })
142 .build()?;
143 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
144
145 let manga_id = Uuid::new_v4();
146 let chapter_ids = [
147 Uuid::parse_str("00057883-357b-4734-9469-52967e59ef4c")?,
148 Uuid::parse_str("000b7978-d9bd-49ec-a8f6-a0737368415f")?,
149 Uuid::parse_str("0015b621-a175-47f5-81fb-5976c88e18c4")?,
150 ];
151 let response_body = json!({
152 "result": "ok",
153 "data": {
154 manga_id.to_string(): chapter_ids
155 }
156 });
157
158 Mock::given(method("GET"))
159 .and(path_regex(r"/manga/read"))
160 .and(header("Authorization", "Bearer sessiontoken"))
161 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
162 .expect(1)
163 .mount(&mock_server)
164 .await;
165
166 let res = mangadex_client
167 .manga()
168 .read()
169 .get()
170 .add_manga_id(manga_id)
171 .grouped(true)
172 .send()
173 .await?;
174
175 if let MangaReadMarkers::Ungrouped(_) = res {
176 panic!("unexpected ungrouped response");
177 }
178
179 Ok(())
180 }
181}