mangadex_api/v5/rating/manga_id/
delete.rs1use derive_builder::Builder;
48use serde::Serialize;
49use uuid::Uuid;
50
51use crate::HttpClientRef;
52use mangadex_api_schema::NoData;
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 DeleteMangaRating {
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 manga_id: Uuid,
75}
76
77endpoint! {
78 DELETE ("/rating/{}", manga_id),
79 #[no_data auth] DeleteMangaRating,
80 #[discard_result] Result<NoData>,
81 DeleteMangaRatingBuilder
82}
83
84#[cfg(test)]
85mod tests {
86 use serde_json::json;
87 use url::Url;
88 use uuid::Uuid;
89 use wiremock::matchers::{header, method, path_regex};
90 use wiremock::{Mock, MockServer, ResponseTemplate};
91
92 use crate::v5::AuthTokens;
93 use crate::{HttpClient, MangaDexClient};
94 use mangadex_api_types::error::Error;
95
96 #[tokio::test]
97 async fn delete_manga_rating_fires_a_request_to_base_url() -> anyhow::Result<()> {
98 let mock_server = MockServer::start().await;
99 let http_client = HttpClient::builder()
100 .base_url(Url::parse(&mock_server.uri())?)
101 .auth_tokens(AuthTokens {
102 session: "sessiontoken".to_string(),
103 refresh: "refreshtoken".to_string(),
104 })
105 .build()?;
106 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
107
108 let manga_id = Uuid::new_v4();
109 let response_body = json!({
110 "result": "ok",
111 });
112
113 Mock::given(method("DELETE"))
114 .and(path_regex(r"/rating/[0-9a-fA-F-]+"))
115 .and(header("Authorization", "Bearer sessiontoken"))
116 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
117 .expect(1)
118 .mount(&mock_server)
119 .await;
120
121 mangadex_client
122 .rating()
123 .manga_id(manga_id)
124 .delete()
125 .send()
126 .await?;
127
128 Ok(())
129 }
130
131 #[tokio::test]
132 async fn delete_manga_rating_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 manga_id = Uuid::new_v4();
140 let error_id = Uuid::new_v4();
141 let response_body = json!({
142 "result": "error",
143 "errors": [{
144 "id": error_id.to_string(),
145 "status": 403,
146 "title": "Forbidden",
147 "detail": "You must be logged in to continue."
148 }]
149 });
150
151 Mock::given(method("DELETE"))
152 .and(path_regex(r"/rating/[0-9a-fA-F-]+/relation"))
153 .and(header("Content-Type", "application/json"))
154 .respond_with(ResponseTemplate::new(403).set_body_json(response_body))
155 .expect(0)
156 .mount(&mock_server)
157 .await;
158
159 let res = mangadex_client
160 .rating()
161 .manga_id(manga_id)
162 .delete()
163 .send()
164 .await
165 .expect_err("expected error");
166
167 match res {
168 Error::MissingTokens => {}
169 _ => panic!("unexpected error: {:#?}", res),
170 }
171
172 Ok(())
173 }
174}