mangadex_api/v5/upload/upload_session_id/batch/
delete.rs1use std::borrow::Cow;
46
47use derive_builder::Builder;
48use mangadex_api_schema::{Endpoint, Limited, NoData};
49use serde::Serialize;
50use uuid::Uuid;
51
52use crate::HttpClientRef;
53use mangadex_api_types::error::Result;
54
55#[cfg_attr(
56 feature = "deserializable-endpoint",
57 derive(serde::Deserialize, getset::Getters, getset::Setters)
58)]
59#[derive(Debug, Serialize, Clone, Builder)]
60#[serde(rename_all = "camelCase")]
61#[builder(
62 setter(into, strip_option),
63 build_fn(error = "mangadex_api_types::error::BuilderError")
64)]
65pub struct DeleteImages {
66 #[doc(hidden)]
68 #[serde(skip)]
69 #[builder(pattern = "immutable")]
70 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
71 pub http_client: HttpClientRef,
72
73 #[serde(skip_serializing)]
74 pub session_id: Uuid,
75 #[builder(setter(each = "add_session_file_id"))]
76 pub session_file_ids: Vec<Uuid>,
77}
78
79impl Endpoint for DeleteImages {
81 type Query = ();
82 type Body = Vec<Uuid>;
83 type Response = NoData;
84
85 fn path(&self) -> Cow<str> {
86 Cow::Owned(format!("/upload/{}/batch", self.session_id))
87 }
88
89 fn method(&self) -> reqwest::Method {
90 reqwest::Method::DELETE
91 }
92
93 fn require_auth(&self) -> bool {
94 true
95 }
96
97 fn body(&self) -> Option<&Vec<Uuid>> {
98 Some(&self.session_file_ids)
99 }
100}
101
102impl DeleteImages {
103 pub async fn send(&self) -> Result<Limited<NoData>> {
104 #[cfg(all(
105 not(feature = "multi-thread"),
106 not(feature = "tokio-multi-thread"),
107 not(feature = "rw-multi-thread")
108 ))]
109 {
110 self.http_client
111 .try_borrow()?
112 .send_request_with_rate_limit(self)
113 .await
114 }
115 #[cfg(any(feature = "multi-thread", feature = "tokio-multi-thread"))]
116 {
117 self.http_client
118 .lock()
119 .await
120 .send_request_with_rate_limit(self)
121 .await
122 }
123 #[cfg(feature = "rw-multi-thread")]
124 {
125 self.http_client
126 .read()
127 .await
128 .send_request_with_rate_limit(self)
129 .await
130 }
131 }
132}
133
134builder_send! {
135 #[builder] DeleteImagesBuilder,
136 #[rate_limited] NoData
137}
138
139#[cfg(test)]
140mod tests {
141 use serde_json::json;
142 use url::Url;
143 use uuid::Uuid;
144 use wiremock::matchers::{body_json, header, method, path_regex};
145 use wiremock::{Mock, MockServer, ResponseTemplate};
146
147 use crate::v5::AuthTokens;
148 use crate::{HttpClient, MangaDexClient};
149
150 #[tokio::test]
151 async fn delete_images_fires_a_request_to_base_url() -> anyhow::Result<()> {
152 let mock_server = MockServer::start().await;
153 let http_client = HttpClient::builder()
154 .base_url(Url::parse(&mock_server.uri())?)
155 .auth_tokens(AuthTokens {
156 session: "sessiontoken".to_string(),
157 refresh: "refreshtoken".to_string(),
158 })
159 .build()?;
160 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
161
162 let session_id = Uuid::new_v4();
163 let session_file_id = Uuid::new_v4();
164 let expected_body = json!([session_file_id]);
165 let response_body = json!({
166 "result": "ok",
167 });
168
169 Mock::given(method("DELETE"))
170 .and(path_regex(r"/upload/[0-9a-fA-F-]+/batch"))
171 .and(header("Authorization", "Bearer sessiontoken"))
172 .and(body_json(expected_body))
173 .respond_with(
174 ResponseTemplate::new(200)
175 .insert_header("x-ratelimit-retry-after", "1698723860")
176 .insert_header("x-ratelimit-limit", "40")
177 .insert_header("x-ratelimit-remaining", "39")
178 .set_body_json(response_body),
179 )
180 .expect(1)
181 .mount(&mock_server)
182 .await;
183
184 let _ = mangadex_client
185 .upload()
186 .upload_session_id(session_id)
187 .batch()
188 .delete()
189 .add_session_file_id(session_file_id)
190 .send()
191 .await?;
192
193 Ok(())
194 }
195}