mangadex_api/v5/custom_list/
get.rs1use derive_builder::Builder;
30use serde::Serialize;
31use uuid::Uuid;
32
33use crate::HttpClientRef;
34use mangadex_api_schema::v5::CustomListResponse;
35
36#[derive(Debug, Serialize, Clone, Builder)]
37#[serde(rename_all = "camelCase")]
38#[builder(setter(into, strip_option), pattern = "owned")]
39pub struct GetCustomList<'a> {
40 #[doc(hidden)]
42 #[serde(skip)]
43 #[builder(pattern = "immutable")]
44 pub(crate) http_client: HttpClientRef,
45
46 #[serde(skip)]
47 pub list_id: &'a Uuid,
48}
49
50endpoint! {
51 GET ("/list/{}", list_id),
52 #[query] GetCustomList<'_>,
53 #[flatten_result] CustomListResponse
54}
55
56#[cfg(test)]
57mod tests {
58 use fake::faker::name::en::Name;
59 use fake::Fake;
60 use serde_json::json;
61 use url::Url;
62 use uuid::Uuid;
63 use wiremock::matchers::{method, path_regex};
64 use wiremock::{Mock, MockServer, ResponseTemplate};
65
66 use crate::{HttpClient, MangaDexClient};
67 use mangadex_api_types::error::Error;
68 use mangadex_api_types::CustomListVisibility;
69
70 #[tokio::test]
71 async fn get_custom_list_fires_a_request_to_base_url() -> anyhow::Result<()> {
72 let mock_server = MockServer::start().await;
73 let http_client = HttpClient::builder()
74 .base_url(Url::parse(&mock_server.uri())?)
75 .build()?;
76 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
77
78 let list_id = Uuid::new_v4();
79 let list_name: String = Name().fake();
80 let response_body = json!({
81 "result": "ok",
82 "response": "entity",
83 "data": {
84 "id": list_id,
85 "type": "custom_list",
86 "attributes": {
87 "name": list_name,
88 "visibility": "private",
89 "version": 1
90 },
91 "relationships": []
92 }
93 });
94
95 Mock::given(method("GET"))
96 .and(path_regex(r"/list/[0-9a-fA-F-]+"))
97 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
98 .expect(1)
99 .mount(&mock_server)
100 .await;
101
102 let res = mangadex_client
103 .custom_list()
104 .get()
105 .list_id(&list_id)
106 .build()?
107 .send()
108 .await?;
109
110 assert_eq!(res.data.id, list_id);
111 assert_eq!(res.data.attributes.name, list_name);
112 assert_eq!(
113 res.data.attributes.visibility,
114 CustomListVisibility::Private
115 );
116 assert_eq!(res.data.attributes.version, 1);
117
118 Ok(())
119 }
120
121 #[tokio::test]
122 async fn get_custom_list_handles_404() -> anyhow::Result<()> {
123 let mock_server = MockServer::start().await;
124 let http_client: HttpClient = HttpClient::builder()
125 .base_url(Url::parse(&mock_server.uri())?)
126 .build()?;
127 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
128
129 let list_id = Uuid::new_v4();
130 let error_id = Uuid::new_v4();
131
132 let response_body = json!({
133 "result": "error",
134 "errors": [{
135 "id": error_id.to_string(),
136 "status": 404,
137 "title": "Not found",
138 "detail": "CustomList could not be found"
139 }]
140 });
141
142 Mock::given(method("GET"))
143 .and(path_regex(r"/list/[0-9a-fA-F-]+"))
144 .respond_with(ResponseTemplate::new(404).set_body_json(response_body))
145 .expect(1)
146 .mount(&mock_server)
147 .await;
148
149 let res = mangadex_client
150 .custom_list()
151 .get()
152 .list_id(&list_id)
153 .build()?
154 .send()
155 .await
156 .expect_err("expected error");
157
158 if let Error::Api(errors) = res {
159 assert_eq!(errors.errors.len(), 1);
160
161 assert_eq!(errors.errors[0].id, error_id);
162 assert_eq!(errors.errors[0].status, 404);
163 assert_eq!(errors.errors[0].title, Some("Not found".to_string()));
164 assert_eq!(
165 errors.errors[0].detail,
166 Some("CustomList could not be found".to_string())
167 );
168 }
169
170 Ok(())
171 }
172}