mangadex_api/v5/manga/manga_id/relation/
get.rs1use derive_builder::Builder;
32use serde::Serialize;
33use uuid::Uuid;
34
35use crate::HttpClientRef;
36use mangadex_api_schema::v5::MangaRelationListResponse;
37use mangadex_api_types::ReferenceExpansionResource;
38
39#[cfg_attr(
40 feature = "deserializable-endpoint",
41 derive(serde::Deserialize, getset::Getters, getset::Setters)
42)]
43#[derive(Debug, Serialize, Clone, Builder)]
44#[serde(rename_all = "camelCase")]
45#[builder(
46 setter(into, strip_option),
47 build_fn(error = "mangadex_api_types::error::BuilderError")
48)]
49pub struct ListMangaRelations {
50 #[doc(hidden)]
52 #[serde(skip)]
53 #[builder(pattern = "immutable")]
54 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
55 pub http_client: HttpClientRef,
56
57 #[serde(skip_serializing)]
58 pub manga_id: Uuid,
59
60 #[builder(setter(each = "include"), default)]
61 pub includes: Vec<ReferenceExpansionResource>,
62}
63
64endpoint! {
65 GET ("/manga/{}/relation", manga_id),
66 #[query] ListMangaRelations,
67 #[flatten_result] MangaRelationListResponse,
68 ListMangaRelationsBuilder
69}
70
71#[cfg(test)]
72mod tests {
73 use serde_json::json;
74 use url::Url;
75 use uuid::Uuid;
76 use wiremock::matchers::{method, path_regex};
77 use wiremock::{Mock, MockServer, ResponseTemplate};
78
79 use crate::{HttpClient, MangaDexClient};
80 use mangadex_api_types::{MangaRelation, RelationshipType, ResponseType};
81
82 #[tokio::test]
83 async fn get_manga_fires_a_request_to_base_url() -> anyhow::Result<()> {
84 let mock_server = MockServer::start().await;
85 let http_client = HttpClient::builder()
86 .base_url(Url::parse(&mock_server.uri())?)
87 .build()?;
88 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
89
90 let manga_id = Uuid::new_v4();
91 let response_body = json!({
92 "result": "ok",
93 "response": "collection",
94 "data": [
95 {
96 "id": "0b92f446-4ee0-4c15-9e5c-6ae1211e785b",
97 "type": "manga_relation",
98 "attributes": {
99 "relation": "doujinshi",
100 "version": 1
101 },
102 "relationships": [
103 {
104 "id": "7944cc53-86e6-4135-898f-47c5c8d0647c",
105 "type": "manga"
106 }
107 ]
108 },
109 {
110 "id": "31b831b7-aac5-4797-b3eb-a41575cd4399",
111 "type": "manga_relation",
112 "attributes": {
113 "relation": "doujinshi",
114 "version": 1
115 },
116 "relationships": [
117 {
118 "id": "119327ab-9b32-4841-9068-02264c15e118",
119 "type": "manga"
120 }
121 ]
122 },
123 {
124 "id": "53815c02-b357-4e23-b8e7-0d6d114ea420",
125 "type": "manga_relation",
126 "attributes": {
127 "relation": "doujinshi",
128 "version": 1
129 },
130 "relationships": [
131 {
132 "id": "25e26436-7eb7-4505-8711-6e014bb16fd7",
133 "type": "manga"
134 }
135 ]
136 },
137 {
138 "id": "6958767b-54c5-4b4c-8f0f-579a36389f68",
139 "type": "manga_relation",
140 "attributes": {
141 "relation": "doujinshi",
142 "version": 1
143 },
144 "relationships": [
145 {
146 "id": "0736a46a-1a34-4411-b665-a1e45ebf54a9",
147 "type": "manga"
148 }
149 ]
150 },
151 {
152 "id": "b358b2f5-beab-484a-9daf-880ad6085225",
153 "type": "manga_relation",
154 "attributes": {
155 "relation": "spin_off",
156 "version": 1
157 },
158 "relationships": [
159 {
160 "id": "1e4deefe-9eb8-4183-837a-f24002adb318",
161 "type": "manga"
162 }
163 ]
164 }
165 ],
166 "limit": 5,
167 "offset": 0,
168 "total": 5
169 });
170
171 Mock::given(method("GET"))
172 .and(path_regex(r"/manga/[0-9a-fA-F-]+/relation"))
173 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
174 .expect(1)
175 .mount(&mock_server)
176 .await;
177
178 let res = mangadex_client
179 .manga()
180 .manga_id(manga_id)
181 .relation()
182 .get()
183 .send()
184 .await?;
185
186 let related = &res.data[0];
187 assert_eq!(res.response, ResponseType::Collection);
188 assert_eq!(related.type_, RelationshipType::MangaRelation);
189 assert_eq!(related.attributes.relation, MangaRelation::Doujinshi);
190 assert_eq!(related.attributes.version, 1);
191 assert_eq!(related.relationships[0].type_, RelationshipType::Manga);
192 assert!(related.relationships[0].related.is_none());
193 assert!(related.relationships[0].attributes.is_none());
194
195 Ok(())
196 }
197}