mangadex_api/v5/statistics/chapter/
get.rs1use derive_builder::Builder;
34use mangadex_api_schema::v5::statistics::chapter::ChapterStatisticsObject;
35use serde::Serialize;
36use uuid::Uuid;
37
38use crate::HttpClientRef;
39
40#[cfg_attr(
41 feature = "deserializable-endpoint",
42 derive(serde::Deserialize, getset::Getters, getset::Setters)
43)]
44#[derive(Debug, Serialize, Clone, Builder, Default)]
45#[serde(rename_all = "camelCase")]
46#[builder(
47 setter(into, strip_option),
48 build_fn(error = "crate::error::BuilderError"),
49 default
50)]
51#[non_exhaustive]
52pub struct FindChapterStatistics {
53 #[doc(hidden)]
54 #[serde(skip)]
55 #[builder(pattern = "immutable")]
56 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
57 pub http_client: HttpClientRef,
58
59 #[builder(setter(each = "chapter_id"))]
60 #[serde(skip_serializing_if = "Vec::is_empty")]
61 pub chapter: Vec<Uuid>,
62}
63
64endpoint! {
65 GET "/statistics/chapter",
66 #[query] FindChapterStatistics,
69 #[flatten_result] crate::Result<ChapterStatisticsObject>,
70 FindChapterStatisticsBuilder
71}
72
73#[cfg(test)]
74mod tests {
75 use serde_json::json;
76 use url::Url;
77 use uuid::Uuid;
78 use wiremock::matchers::{method, path};
79 use wiremock::{Mock, MockServer, ResponseTemplate};
80
81 use crate::{HttpClient, MangaDexClient};
82
83 #[tokio::test]
84 async fn find_group_statistics_fires_a_request_to_base_url() -> anyhow::Result<()> {
85 let mock_server = MockServer::start().await;
86 let http_client = HttpClient::builder()
87 .base_url(Url::parse(&mock_server.uri())?)
88 .build()?;
89 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
90
91 let manga_id = Uuid::new_v4();
92
93 let thread_id = 4756728;
94 let replies_count = 12;
95
96 let response_body = json!({
97 "result": "ok",
98 "statistics": {
99 manga_id.to_string(): {
100 "comments": {
101 "threadId": thread_id,
102 "repliesCount": replies_count
103 }
104 }
105 }
106 });
107
108 Mock::given(method("GET"))
109 .and(path("/statistics/chapter"))
110 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
111 .expect(1)
112 .mount(&mock_server)
113 .await;
114
115 let res = mangadex_client
116 .statistics()
117 .chapter()
118 .get()
119 .chapter_id(&manga_id)
120 .send()
121 .await?;
122 let ctt = res.statistics.get(&manga_id).ok_or(std::io::Error::new(
123 std::io::ErrorKind::NotFound,
124 "This id is not found",
125 ))?;
126 let comments = ctt.comments.ok_or(std::io::Error::new(
127 std::io::ErrorKind::NotFound,
128 "The comment is not found",
129 ))?;
130 assert_eq!(comments.thread_id, thread_id);
131 assert_eq!(comments.replies_count, replies_count);
132 Ok(())
133 }
134}