1use crate::channels::channel::Channel;
2use crate::error::Error;
3use crate::http_client::{get_slack_url, ResponseMetadata, SlackWebAPIClient};
4use serde::{Deserialize, Serialize};
5use serde_with::skip_serializing_none;
6
7#[skip_serializing_none]
8#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
9pub struct ListRequest {
10 pub cursor: Option<String>,
11 pub exclude_archived: Option<bool>,
12 pub limit: Option<i32>,
13 pub team_id: Option<String>,
14 pub types: Option<String>,
15}
16
17#[skip_serializing_none]
18#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
19pub struct ListResponse {
20 pub ok: bool,
21 pub error: Option<String>,
22 pub response_metadata: Option<ResponseMetadata>,
23 pub channels: Option<Vec<Channel>>,
24}
25
26pub async fn list<T>(
27 client: &T,
28 param: &ListRequest,
29 bot_token: &str,
30) -> Result<ListResponse, Error>
31where
32 T: SlackWebAPIClient,
33{
34 let url = get_slack_url("conversations.list");
35 let json = serde_json::to_string(¶m)?;
36
37 client
38 .post_json(&url, &json, bot_token)
39 .await
40 .and_then(|result| {
41 serde_json::from_str::<ListResponse>(&result).map_err(Error::SerdeJsonError)
42 })
43}
44
45#[cfg(test)]
46mod test {
47 use super::*;
48 use crate::channels::channel::{Purpose, Topic};
49 use crate::http_client::MockSlackWebAPIClient;
50
51 #[test]
52 fn convert_request() {
53 let request = ListRequest {
54 cursor: Some("dXNlcjpVMDYxTkZUVDI=".to_string()),
55 exclude_archived: Some(true),
56 limit: Some(20),
57 team_id: Some("T1234567890".to_string()),
58 types: Some("public_channel,private_channel".to_string()),
59 };
60 let json = r##"{
61 "cursor": "dXNlcjpVMDYxTkZUVDI=",
62 "exclude_archived": true,
63 "limit": 20,
64 "team_id": "T1234567890",
65 "types": "public_channel,private_channel"
66}"##;
67
68 let j = serde_json::to_string_pretty(&request).unwrap();
69 assert_eq!(json, j);
70
71 let s = serde_json::from_str::<ListRequest>(json).unwrap();
72 assert_eq!(request, s);
73 }
74
75 #[test]
76 fn convert_response() {
77 let response = ListResponse {
78 ok: true,
79 channels: Some(vec![
80 Channel {
81 id: Some("C0EAQDV4Z".to_string()),
82 name: Some("endeavor".to_string()),
83 is_channel: Some(true),
84 created: Some(1504554479),
85 creator: Some("U0123456".to_string()),
86 is_archived: Some(false),
87 is_general: Some(false),
88 name_normalized: Some("endeavor".to_string()),
89 is_shared: Some(false),
90 is_org_shared: Some(false),
91 is_member: Some(false),
92 is_private: Some(false),
93 is_mpim: Some(false),
94 last_read: Some("0000000000.000000".to_string()),
95 unread_count: Some(0),
96 unread_count_display: Some(0),
97 topic: Some(Topic {
98 value: Some("".to_string()),
99 creator: Some("".to_string()),
100 last_set: Some(0),
101 }),
102 purpose: Some(Purpose {
103 value: Some("".to_string()),
104 creator: Some("".to_string()),
105 last_set: Some(0),
106 }),
107 previous_names: Some(vec![]),
108 priority: Some(0),
109 ..Default::default()
110 },
111 Channel {
112 id: Some("C0EAQDV4Z".to_string()),
113 name: Some("endeavor".to_string()),
114 is_channel: Some(true),
115 created: Some(1504554479),
116 creator: Some("U0123456".to_string()),
117 is_archived: Some(false),
118 is_general: Some(false),
119 name_normalized: Some("endeavor".to_string()),
120 is_shared: Some(false),
121 is_org_shared: Some(false),
122 is_member: Some(false),
123 is_private: Some(false),
124 is_mpim: Some(false),
125 last_read: Some("0000000000.000000".to_string()),
126 unread_count: Some(0),
127 unread_count_display: Some(0),
128 topic: Some(Topic {
129 value: Some("".to_string()),
130 creator: Some("".to_string()),
131 last_set: Some(0),
132 }),
133 purpose: Some(Purpose {
134 value: Some("".to_string()),
135 creator: Some("".to_string()),
136 last_set: Some(0),
137 }),
138 previous_names: Some(vec![]),
139 priority: Some(0),
140 ..Default::default()
141 },
142 ]),
143 ..Default::default()
144 };
145 let json = r##"{
146 "ok": true,
147 "channels": [
148 {
149 "id": "C0EAQDV4Z",
150 "name": "endeavor",
151 "is_channel": true,
152 "created": 1504554479,
153 "creator": "U0123456",
154 "is_archived": false,
155 "is_general": false,
156 "name_normalized": "endeavor",
157 "is_shared": false,
158 "is_org_shared": false,
159 "is_member": false,
160 "is_private": false,
161 "is_mpim": false,
162 "last_read": "0000000000.000000",
163 "unread_count": 0,
164 "unread_count_display": 0,
165 "topic": {
166 "value": "",
167 "creator": "",
168 "last_set": 0
169 },
170 "purpose": {
171 "value": "",
172 "creator": "",
173 "last_set": 0
174 },
175 "previous_names": [],
176 "priority": 0
177 },
178 {
179 "id": "C0EAQDV4Z",
180 "name": "endeavor",
181 "is_channel": true,
182 "created": 1504554479,
183 "creator": "U0123456",
184 "is_archived": false,
185 "is_general": false,
186 "name_normalized": "endeavor",
187 "is_shared": false,
188 "is_org_shared": false,
189 "is_member": false,
190 "is_private": false,
191 "is_mpim": false,
192 "last_read": "0000000000.000000",
193 "unread_count": 0,
194 "unread_count_display": 0,
195 "topic": {
196 "value": "",
197 "creator": "",
198 "last_set": 0
199 },
200 "purpose": {
201 "value": "",
202 "creator": "",
203 "last_set": 0
204 },
205 "previous_names": [],
206 "priority": 0
207 }
208 ]
209}"##;
210
211 let j = serde_json::to_string_pretty(&response).unwrap();
212 assert_eq!(json, j);
213
214 let s = serde_json::from_str::<ListResponse>(json).unwrap();
215 assert_eq!(response, s);
216 }
217
218 #[async_std::test]
219 async fn test_list() {
220 let param = ListRequest {
221 cursor: Some("dXNlcjpVMDYxTkZUVDI=".to_string()),
222 exclude_archived: Some(true),
223 limit: Some(20),
224 team_id: Some("T1234567890".to_string()),
225 types: Some("public_channel,private_channel".to_string()),
226 };
227
228 let mut mock = MockSlackWebAPIClient::new();
229 mock.expect_post_json().returning(|_, _, _| {
230 Ok(r##"{
231 "ok": true,
232 "channels": [
233 {
234 "id": "C0EAQDV4Z",
235 "name": "endeavor",
236 "is_channel": true,
237 "created": 1504554479,
238 "creator": "U0123456",
239 "is_archived": false,
240 "is_general": false,
241 "name_normalized": "endeavor",
242 "is_shared": false,
243 "is_org_shared": false,
244 "is_member": false,
245 "is_private": false,
246 "is_mpim": false,
247 "last_read": "0000000000.000000",
248 "unread_count": 0,
249 "unread_count_display": 0,
250 "topic": {
251 "value": "",
252 "creator": "",
253 "last_set": 0
254 },
255 "purpose": {
256 "value": "",
257 "creator": "",
258 "last_set": 0
259 },
260 "previous_names": [],
261 "priority": 0
262 },
263 {
264 "id": "C0EAQDV4Z",
265 "name": "endeavor",
266 "is_channel": true,
267 "created": 1504554479,
268 "creator": "U0123456",
269 "is_archived": false,
270 "is_general": false,
271 "name_normalized": "endeavor",
272 "is_shared": false,
273 "is_org_shared": false,
274 "is_member": false,
275 "is_private": false,
276 "is_mpim": false,
277 "last_read": "0000000000.000000",
278 "unread_count": 0,
279 "unread_count_display": 0,
280 "topic": {
281 "value": "",
282 "creator": "",
283 "last_set": 0
284 },
285 "purpose": {
286 "value": "",
287 "creator": "",
288 "last_set": 0
289 },
290 "previous_names": [],
291 "priority": 0
292 }
293 ]
294}"##
295 .to_string())
296 });
297
298 let response = list(&mock, ¶m, &"test_token".to_string())
299 .await
300 .unwrap();
301 let expect = ListResponse {
302 ok: true,
303 channels: Some(vec![
304 Channel {
305 id: Some("C0EAQDV4Z".to_string()),
306 name: Some("endeavor".to_string()),
307 is_channel: Some(true),
308 created: Some(1504554479),
309 creator: Some("U0123456".to_string()),
310 is_archived: Some(false),
311 is_general: Some(false),
312 name_normalized: Some("endeavor".to_string()),
313 is_shared: Some(false),
314 is_org_shared: Some(false),
315 is_member: Some(false),
316 is_private: Some(false),
317 is_mpim: Some(false),
318 last_read: Some("0000000000.000000".to_string()),
319 unread_count: Some(0),
320 unread_count_display: Some(0),
321 topic: Some(Topic {
322 value: Some("".to_string()),
323 creator: Some("".to_string()),
324 last_set: Some(0),
325 }),
326 purpose: Some(Purpose {
327 value: Some("".to_string()),
328 creator: Some("".to_string()),
329 last_set: Some(0),
330 }),
331 previous_names: Some(vec![]),
332 priority: Some(0),
333 ..Default::default()
334 },
335 Channel {
336 id: Some("C0EAQDV4Z".to_string()),
337 name: Some("endeavor".to_string()),
338 is_channel: Some(true),
339 created: Some(1504554479),
340 creator: Some("U0123456".to_string()),
341 is_archived: Some(false),
342 is_general: Some(false),
343 name_normalized: Some("endeavor".to_string()),
344 is_shared: Some(false),
345 is_org_shared: Some(false),
346 is_member: Some(false),
347 is_private: Some(false),
348 is_mpim: Some(false),
349 last_read: Some("0000000000.000000".to_string()),
350 unread_count: Some(0),
351 unread_count_display: Some(0),
352 topic: Some(Topic {
353 value: Some("".to_string()),
354 creator: Some("".to_string()),
355 last_set: Some(0),
356 }),
357 purpose: Some(Purpose {
358 value: Some("".to_string()),
359 creator: Some("".to_string()),
360 last_set: Some(0),
361 }),
362 previous_names: Some(vec![]),
363 priority: Some(0),
364 ..Default::default()
365 },
366 ]),
367 ..Default::default()
368 };
369
370 assert_eq!(expect, response);
371 }
372}