mangadex_api/v5/cover/cover_id/
get.rs1use derive_builder::Builder;
29use serde::Serialize;
30use uuid::Uuid;
31
32use crate::HttpClientRef;
33use mangadex_api_schema::v5::CoverResponse;
34use mangadex_api_types::ReferenceExpansionResource;
35
36#[cfg_attr(
37 feature = "deserializable-endpoint",
38 derive(serde::Deserialize, getset::Getters, getset::Setters)
39)]
40#[derive(Debug, Serialize, Clone, Builder)]
41#[serde(rename_all = "camelCase")]
42#[builder(
43 setter(into, strip_option),
44 build_fn(error = "mangadex_api_types::error::BuilderError")
45)]
46pub struct GetCover {
47 #[doc(hidden)]
49 #[serde(skip)]
50 #[builder(pattern = "immutable")]
51 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
52 pub http_client: HttpClientRef,
53
54 #[serde(skip_serializing)]
56 pub cover_id: Uuid,
57
58 #[builder(setter(each = "include"), default)]
59 pub includes: Vec<ReferenceExpansionResource>,
60}
61
62endpoint! {
63 GET ("/cover/{}", cover_id),
64 #[query] GetCover,
65 #[flatten_result] CoverResponse,
66 GetCoverBuilder
67}
68
69#[cfg(test)]
70mod tests {
71 use fake::faker::lorem::en::Sentence;
72 use fake::Fake;
73 use serde_json::json;
74 use time::OffsetDateTime;
75 use url::Url;
76 use uuid::Uuid;
77 use wiremock::matchers::{method, path_regex};
78 use wiremock::{Mock, MockServer, ResponseTemplate};
79
80 use crate::{HttpClient, MangaDexClient};
81 use mangadex_api_types::error::Error;
82 use mangadex_api_types::{Language, MangaDexDateTime};
83
84 #[tokio::test]
85 async fn get_cover_fires_a_request_to_base_url() -> anyhow::Result<()> {
86 let mock_server = MockServer::start().await;
87 let http_client = HttpClient::builder()
88 .base_url(Url::parse(&mock_server.uri())?)
89 .build()?;
90 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
91
92 let cover_id = Uuid::new_v4();
93 let description: String = Sentence(1..3).fake();
94
95 let datetime = MangaDexDateTime::new(&OffsetDateTime::now_utc());
96
97 let response_body = json!({
98 "result": "ok",
99 "response": "entity",
100 "data": {
101 "id": cover_id,
102 "type": "cover_art",
103 "attributes": {
104 "volume": "1",
105 "fileName": "1.jpg",
106 "description": description,
107 "locale": "en",
108 "version": 1,
109 "createdAt": datetime.to_string(),
110 "updatedAt": datetime.to_string(),
111
112 },
113 "relationships": []
114 }
115 });
116
117 Mock::given(method("GET"))
118 .and(path_regex(r"/cover/[0-9a-fA-F-]+"))
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
125 .cover()
126 .cover_id(cover_id)
127 .get()
128 .send()
129 .await?;
130
131 assert_eq!(res.data.id, cover_id);
132 assert_eq!(res.data.attributes.volume, Some("1".to_string()));
133 assert_eq!(res.data.attributes.file_name, "1.jpg".to_string());
134 assert_eq!(res.data.attributes.description, description);
135 assert_eq!(res.data.attributes.locale, Some(Language::English));
136 assert_eq!(res.data.attributes.version, 1);
137 assert_eq!(
138 res.data.attributes.created_at.to_string(),
139 datetime.to_string()
140 );
141 assert_eq!(
142 res.data.attributes.updated_at.as_ref().unwrap().to_string(),
143 datetime.to_string()
144 );
145
146 Ok(())
147 }
148
149 #[tokio::test]
150 async fn get_chapter_handles_404() -> anyhow::Result<()> {
151 let mock_server = MockServer::start().await;
152 let http_client: HttpClient = HttpClient::builder()
153 .base_url(Url::parse(&mock_server.uri())?)
154 .build()?;
155 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
156
157 let cover_id = Uuid::new_v4();
158 let error_id = Uuid::new_v4();
159
160 let response_body = json!({
161 "result": "error",
162 "errors": [{
163 "id": error_id.to_string(),
164 "status": 404,
165 "title": "Not found",
166 "detail": "Cover could not be found"
167 }]
168 });
169
170 Mock::given(method("GET"))
171 .and(path_regex(r"/cover/[0-9a-fA-F-]+"))
172 .respond_with(ResponseTemplate::new(404).set_body_json(response_body))
173 .expect(1)
174 .mount(&mock_server)
175 .await;
176
177 let res = mangadex_client
178 .cover()
179 .cover_id(cover_id)
180 .get()
181 .send()
182 .await
183 .expect_err("expected error");
184
185 if let Error::Api(errors) = res {
186 assert_eq!(errors.errors.len(), 1);
187
188 assert_eq!(errors.errors[0].id, error_id);
189 assert_eq!(errors.errors[0].status, 404);
190 assert_eq!(errors.errors[0].title, Some("Not found".to_string()));
191 assert_eq!(
192 errors.errors[0].detail,
193 Some("Cover could not be found".to_string())
194 );
195 }
196
197 Ok(())
198 }
199}