mangadex_api/v5/user/follows/group/
get.rs1use derive_builder::Builder;
44use serde::Serialize;
45
46use crate::HttpClientRef;
47use mangadex_api_schema::v5::GroupListResponse;
48use mangadex_api_types::ReferenceExpansionResource;
49
50#[cfg_attr(
51 feature = "deserializable-endpoint",
52 derive(serde::Deserialize, getset::Getters, getset::Setters)
53)]
54#[derive(Debug, Serialize, Clone, Builder, Default)]
55#[serde(rename_all = "camelCase")]
56#[builder(
57 setter(into, strip_option),
58 default,
59 build_fn(error = "mangadex_api_types::error::BuilderError")
60)]
61#[cfg_attr(
62 feature = "custom_list_v2",
63 deprecated(
64 since = "3.0.0-rc.1",
65 note = "After the introduction of the Subscription system, this endpoint will be removed in v3"
66 )
67)]
68pub struct FollowedGroups {
69 #[doc(hidden)]
71 #[serde(skip)]
72 #[builder(pattern = "immutable")]
73 #[cfg_attr(feature = "deserializable-endpoint", getset(set = "pub", get = "pub"))]
74 pub http_client: HttpClientRef,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub limit: Option<u32>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub offset: Option<u32>,
80 #[builder(setter(each = "include"), default)]
81 pub includes: Vec<ReferenceExpansionResource>,
82}
83
84endpoint! {
85 GET "/user/follows/group",
86 #[query auth] FollowedGroups,
87 #[flatten_result] GroupListResponse,
88 FollowedGroupsBuilder
89}
90
91#[cfg(test)]
92mod tests {
93 use serde_json::json;
94 use time::OffsetDateTime;
95 use url::Url;
96 use uuid::Uuid;
97 use wiremock::matchers::{header, method, path_regex};
98 use wiremock::{Mock, MockServer, ResponseTemplate};
99
100 use crate::v5::AuthTokens;
101 use crate::{HttpClient, MangaDexClient};
102 use mangadex_api_types::MangaDexDateTime;
103
104 #[tokio::test]
105 async fn get_followed_groups_fires_a_request_to_base_url_ungrouped() -> anyhow::Result<()> {
106 let mock_server = MockServer::start().await;
107 let http_client = HttpClient::builder()
108 .base_url(Url::parse(&mock_server.uri())?)
109 .auth_tokens(AuthTokens {
110 session: "sessiontoken".to_string(),
111 refresh: "refreshtoken".to_string(),
112 })
113 .build()?;
114 let mangadex_client = MangaDexClient::new_with_http_client(http_client);
115
116 let group_id = Uuid::new_v4();
117
118 let datetime = MangaDexDateTime::new(&OffsetDateTime::now_utc());
119
120 let response_body = json!({
121 "result": "ok",
122 "response": "collection",
123 "data": [
124 {
125 "id": group_id,
126 "type": "scanlation_group",
127 "attributes": {
128 "name": "Scanlation Group",
129 "altNames": [],
130 "website": "https://example.org",
131 "ircServer": null,
132 "ircChannel": null,
133 "discord": null,
134 "contactEmail": null,
135 "description": null,
136 "twitter": null,
137 "focusedLanguages": ["en"],
138 "locked": false,
139 "official": false,
140 "verified": false,
141 "inactive": false,
142 "publishDelay": "P6WT5M",
143 "version": 1,
144 "createdAt": datetime.to_string(),
145 "updatedAt": datetime.to_string(),
146 },
147 "relationships": []
148 }
149 ],
150 "limit": 1,
151 "offset": 0,
152 "total": 1
153 });
154
155 Mock::given(method("GET"))
156 .and(path_regex(r"/user/follows/group"))
157 .and(header("Authorization", "Bearer sessiontoken"))
158 .respond_with(ResponseTemplate::new(200).set_body_json(response_body))
159 .expect(1)
160 .mount(&mock_server)
161 .await;
162
163 let _ = mangadex_client
164 .user()
165 .follows()
166 .group()
167 .get()
168 .limit(1_u32)
169 .send()
170 .await?;
171
172 Ok(())
173 }
174}