rustyroblox/
lib.rs

1pub mod groups;
2pub mod thumbnails;
3pub mod users;
4pub mod util;
5
6#[cfg(test)]
7mod tests {
8    use std::fs;
9
10    use crate::{groups::GroupSearchProps, util::paging::PageLimit};
11
12    use super::*;
13
14    async fn authenticated_jar() -> util::jar::RequestJar {
15        // Read credentials from file
16        let contents = fs::read_to_string("roblosecurity.txt").unwrap();
17        let roblosecurity = contents.trim().to_string();
18        let mut jar = util::jar::RequestJar::new().await;
19        jar.set_roblosecurity(roblosecurity).await.unwrap();
20
21        // If the file proxy.txt exists, use it as a proxy
22        if fs::metadata("proxy.txt").is_ok() {
23            let contents = fs::read_to_string("proxy.txt").unwrap();
24            let proxy = contents.trim().to_string();
25            jar.set_proxy(proxy);
26        }
27
28        jar
29    }
30
31    async fn unauthenticated_jar() -> util::jar::RequestJar {
32        let mut jar = util::jar::RequestJar::new().await;
33
34        // If the file proxy.txt exists, use it as a proxy
35        if fs::metadata("proxy.txt").is_ok() {
36            let contents = fs::read_to_string("proxy.txt").unwrap();
37            let proxy = contents.trim().to_string();
38            jar.set_proxy(proxy);
39        }
40
41        jar
42    }
43
44    #[tokio::test]
45    async fn whoami() {
46        let mut jar = unauthenticated_jar().await;
47        let user = crate::users::whoami(&mut jar).await.unwrap();
48        println!("{:#?}", user);
49    }
50
51    #[tokio::test]
52    async fn user_by_id() {
53        let mut jar = unauthenticated_jar().await;
54        let user = crate::users::user_by_id(&mut jar, 375760054).await.unwrap();
55        println!("{:#?}", user);
56    }
57
58    // Display names
59
60    #[tokio::test]
61    async fn validate_display_name_fail() {
62        let mut jar = unauthenticated_jar().await;
63        let display_name = crate::users::validate_display_name(&mut jar, "shit".to_string())
64            .await
65            .unwrap();
66
67        // Panic if it's valid
68        match display_name {
69            crate::users::ValidateDisplayNameResponseEnum::Success(_) => {
70                panic!("Display name is valid when it shouldn't be")
71            }
72            _ => {}
73        }
74    }
75
76    #[tokio::test]
77    async fn validate_display_name_success() {
78        let mut jar = unauthenticated_jar().await;
79        let display_name = crate::users::validate_display_name(&mut jar, "test".to_string())
80            .await
81            .unwrap();
82
83        // Panic if it's valid
84        match display_name {
85            crate::users::ValidateDisplayNameResponseEnum::Failed(_) => {
86                panic!("Display name is invalid when it shouldn't be")
87            }
88            _ => {}
89        }
90    }
91
92    #[tokio::test]
93    async fn validate_display_name_for_user() {
94        let mut jar = unauthenticated_jar().await;
95        let user_id = crate::users::whoami(&mut jar).await.unwrap().id;
96
97        if user_id != 4205503041 {
98            return; // This account gets used for CI, we only want to run this test on that account bc ratelimits
99        }
100
101        let display_name =
102            crate::users::validate_display_name_for_user(&mut jar, "test".to_string(), user_id)
103                .await
104                .unwrap();
105
106        // Panic if it's valid
107        match display_name {
108            crate::users::ValidateDisplayNameResponseEnum::Failed(_) => {
109                panic!("Display name is invalid when it shouldn't be")
110            }
111            _ => {}
112        }
113    }
114
115    //#[tokio::test]
116    //async fn set_display_name() {
117    //    let mut jar = authenticated_jar().await;
118    //    crate::users::set_display_name(&mut jar, "notest".to_string())
119    //        .await
120    //        .unwrap();
121    //    let whoami1 = crate::users::whoami(&mut jar).await.unwrap();
122    //    crate::users::set_display_name(&mut jar, "test".to_string())
123    //        .await
124    //        .unwrap();
125    //
126    //    let whoami2 = crate::users::whoami(&mut jar).await.unwrap();
127    //
128    //    assert_ne!(whoami1.display_name, whoami2.display_name);
129    //    assert_eq!(whoami2.display_name, "test".to_string());
130    //}
131    // This test cant work as the display name can only be changed once every 7 days!
132
133    #[tokio::test]
134    async fn get_age_bracket() {
135        let mut jar = unauthenticated_jar().await;
136        let age_bracket = crate::users::age_bracket(&mut jar).await.unwrap();
137        assert_eq!(age_bracket.age_bracket, 0);
138    }
139
140    #[tokio::test]
141    async fn get_country_code() {
142        let mut jar = unauthenticated_jar().await;
143        let country_code = crate::users::country_code(&mut jar).await.unwrap();
144        assert_eq!(country_code.country_code, "NL");
145    }
146
147    #[tokio::test]
148    async fn get_roles() {
149        let mut jar = unauthenticated_jar().await;
150        let roles = crate::users::roles(&mut jar).await.unwrap();
151        let empty_vec: Vec<String> = Vec::new();
152        assert_eq!(roles.roles, empty_vec);
153    }
154
155    #[tokio::test]
156    async fn bulk_users_by_username() {
157        let mut jar = unauthenticated_jar().await;
158        let users = crate::users::bulk_users_by_username(
159            &mut jar,
160            vec!["piano1029".to_string(), "ClannyBot".to_string()],
161        )
162        .await
163        .unwrap();
164
165        assert_eq!(users.len(), 2);
166        assert_eq!(users[0].name, "piano1029".to_string());
167        assert_eq!(users[0].id, 375760054);
168    }
169
170    #[tokio::test]
171    async fn bulk_users_by_id() {
172        let mut jar = unauthenticated_jar().await;
173        let users = crate::users::bulk_users_by_id(&mut jar, vec![375760054, 1444131924])
174            .await
175            .unwrap();
176
177        println!("{:#?}", users);
178
179        assert_eq!(users.len(), 2);
180        assert_eq!(users[0].name, "piano1029".to_string());
181    }
182
183    #[tokio::test]
184    async fn username_history() {
185        let mut jar = unauthenticated_jar().await;
186        let users = crate::users::username_history(&mut jar, 375760054)
187            .await
188            .unwrap();
189
190        println!("{:#?}", users);
191
192        assert_eq!(users.len(), 0);
193    }
194
195    #[tokio::test]
196    async fn username_search() {
197        let mut jar = unauthenticated_jar().await;
198        let users = crate::users::username_search(
199            &mut jar,
200            "miemper".to_string(),
201            util::paging::PageLimit::Limit10,
202        )
203        .await;
204
205        match users {
206            Ok(users) => {
207                assert_eq!(users.len(), 10);
208                assert_eq!(users[0].name, "miemper".to_string());
209            }
210            Err(e) => match *e {
211                crate::util::Error::RateLimited => {
212                    // This is fine, it just means we're being rate limited
213                }
214                _ => {
215                    // This isn't
216                    panic!("Unexpected error: {:?}", e);
217                }
218            },
219        }
220    }
221
222    #[tokio::test]
223    async fn get_group() {
224        let mut jar = unauthenticated_jar().await;
225        let group = crate::groups::group_by_id(&mut jar, 7370273).await.unwrap();
226
227        println!("{:#?}", group);
228
229        assert_eq!(group.id, 7370273);
230        assert_eq!(group.name, "Clanny Systems".to_string());
231        assert_eq!(group.owner.username, "ClannyBot".to_string())
232    }
233
234    // TODO: Create test for audit log, but that requires a group (which requires robux)
235
236    #[tokio::test]
237    async fn get_group_name_history() {
238        let mut jar = unauthenticated_jar().await;
239        let group_name_history = crate::groups::name_history(
240            &mut jar,
241            7370273,
242            util::paging::PageLimit::All,
243            Some(util::paging::SortOrder::Asc),
244        )
245        .await
246        .unwrap();
247
248        println!("{:#?}", group_name_history);
249
250        assert_eq!(group_name_history.len(), 0);
251    }
252
253    // TODO: Re-enable this test when we got a test group
254    //#[tokio::test]
255    //async fn get_group_settings() {
256    //    let mut jar = unauthenticated_jar().await;
257    //    let group_settings = crate::groups::settings(&mut jar, 7370273)
258    //        .await
259    //        .unwrap();
260    //
261    //    println!("{:#?}", group_settings);
262    //
263    //    assert_eq!(group_settings.is_approval_required, false)
264    //}
265
266    // TODO: Create test for updating group settings, but that requires a group (which requires robux)
267
268    #[tokio::test]
269    async fn group_configuration_metadata() {
270        let mut jar = unauthenticated_jar().await;
271        let group_configuration_metadata = crate::groups::config_metadata(&mut jar).await.unwrap();
272
273        println!("{:#?}", group_configuration_metadata);
274
275        assert_eq!(group_configuration_metadata.role_configuration.min_rank, 0);
276    }
277
278    #[tokio::test]
279    async fn group_metadata() {
280        let mut jar = unauthenticated_jar().await;
281        let group_metadata = crate::groups::metadata(&mut jar).await.unwrap();
282
283        println!("{:#?}", group_metadata);
284
285        assert_eq!(group_metadata.show_previous_group_names, true);
286    }
287
288    #[tokio::test]
289    async fn group_compliance() {
290        let mut jar = unauthenticated_jar().await;
291        let group_compliance = crate::groups::compliance(&mut jar, vec![7370273])
292            .await
293            .unwrap();
294
295        println!("{:#?}", group_compliance);
296
297        assert_eq!(group_compliance.groups.len(), 1);
298        assert_eq!(group_compliance.groups[0].can_view_group, true);
299        assert_eq!(group_compliance.groups[0].group_id, 7370273);
300    }
301
302    // TODO: Create test for updating group description, but that requires a group (which requires robux)
303    // We will not be having a test for updating group name cus that requires robux
304
305    // TODO: Create tests for join requests, but that requires a group (which requires robux)
306
307    #[tokio::test]
308    async fn group_membership() {
309        let mut jar = unauthenticated_jar().await;
310        let group_membership = crate::groups::membership(&mut jar, 7370273).await.unwrap();
311
312        println!("{:#?}", group_membership);
313
314        assert_eq!(group_membership.group_id, 7370273);
315        assert_eq!(group_membership.are_group_funds_visible, false);
316        assert_eq!(group_membership.can_configure, false);
317    }
318
319    #[tokio::test]
320    async fn group_roles() {
321        let mut jar = unauthenticated_jar().await;
322        let group_roles = crate::groups::roles(&mut jar, 7370273).await.unwrap();
323
324        println!("{:#?}", group_roles);
325
326        assert_eq!(group_roles.len(), 10);
327        assert_eq!(group_roles[0].name, "Guest".to_string());
328        assert_eq!(
329            group_roles[group_roles.len() - 1].name,
330            "Clanny".to_string()
331        );
332    }
333
334    #[tokio::test]
335    async fn group_role_members() {
336        let mut jar = unauthenticated_jar().await;
337        let group_roles = crate::groups::roles(&mut jar, 7370273).await.unwrap();
338
339        let clanny_role_id = group_roles[group_roles.len() - 1].id;
340
341        let group_role_members = crate::groups::users_on_role(
342            &mut jar,
343            7370273,
344            clanny_role_id,
345            util::paging::PageLimit::Limit10,
346            None,
347        )
348        .await
349        .unwrap();
350
351        println!("{:#?}", group_role_members);
352
353        assert_eq!(group_role_members.len(), 1);
354        assert_eq!(group_role_members[0].username, "ClannyBot".to_string());
355    }
356
357    #[tokio::test]
358    async fn group_members() {
359        let mut jar = unauthenticated_jar().await;
360        let group_members = crate::groups::members(
361            &mut jar,
362            7370273,
363            util::paging::PageLimit::Limit10,
364            Some(util::paging::SortOrder::Asc),
365        )
366        .await
367        .unwrap();
368
369        println!("{:#?}", group_members);
370
371        assert_eq!(group_members.len(), 10);
372        assert_eq!(group_members[0].user.username, "ClannyBot".to_string());
373    }
374
375    #[tokio::test]
376    async fn pending_requests() {
377        let mut jar = unauthenticated_jar().await;
378        let pending_requests = crate::groups::pending_requests(&mut jar).await.unwrap();
379
380        println!("{:#?}", pending_requests);
381
382        assert_eq!(pending_requests.len(), 0);
383    }
384
385    #[tokio::test]
386    async fn friend_groups() {
387        let mut jar = unauthenticated_jar().await;
388
389        let friend_groups = crate::groups::friend_groups(&mut jar).await.unwrap();
390
391        println!("{:#?}", friend_groups);
392
393        assert_eq!(friend_groups.len(), 0);
394    }
395
396    #[tokio::test]
397    async fn user_group_memberships() {
398        let mut jar = unauthenticated_jar().await;
399        let user_group_memberships = crate::groups::user_memberships(&mut jar, 375760054)
400            .await
401            .unwrap();
402
403        // Filter where group_id is 7370273
404        let clanny_group_membership = user_group_memberships
405            .into_iter()
406            .find(|group_membership| group_membership.group.id == 7370273)
407            .unwrap();
408
409        println!("{:#?}", clanny_group_membership);
410
411        assert_eq!(clanny_group_membership.group.id, 7370273);
412        assert_eq!(clanny_group_membership.role.rank, 254);
413        // This is no longer provided with v2 of the group membership API ):
414        // v1 has been replaced with v2 in this package due to it sending malformed JSON
415        // assert_eq!(clanny_group_membership.is_primary_group.is_some(), true);
416        // assert_eq!(clanny_group_membership.is_primary_group.unwrap(), true);
417    }
418
419    // TODO: Add test for change_owner, but that requires a group (which requires robux)
420    // TODO: Add test for remove_user, but that requires a group (which requires robux)
421    // TODO: Add test for promote, but that requires a group (which requires robux)
422    // TODO: Add test for demote, but that requires a group (which requires robux)
423    // TODO: Add test for set_role, but that requires a group (which requires robux)
424    // TODO: Add test for set_rank, but that requires a group (which requires robux)
425    // TODO: Add test for modify_rank_by_amount, but that requires a group (which requires robux)
426
427    #[tokio::test]
428    async fn user_role() {
429        let mut jar = unauthenticated_jar().await;
430        //let group = crate::groups::group_by_id(&mut jar, 7370273).await.unwrap();
431        let user_role = crate::groups::user_role(&mut jar, 7370273, 1444131924)
432            .await
433            .unwrap();
434
435        println!("{:#?}", user_role);
436
437        assert_eq!(user_role.rank, 255);
438        assert_eq!(user_role.name, "Clanny".to_string());
439    }
440
441    #[tokio::test]
442    async fn group_relationships() {
443        // TODO: Improve this test
444        let mut jar = unauthenticated_jar().await;
445        let group_relationships =
446            crate::groups::relationships(&mut jar, 7370273, groups::RelationshipType::All)
447                .await
448                .unwrap();
449
450        println!("{:#?}", group_relationships);
451
452        assert_eq!(group_relationships.groups.len(), 0);
453    }
454
455    #[tokio::test]
456    async fn group_enemies() {
457        // TODO: Improve this test
458        let mut jar = unauthenticated_jar().await;
459        let group_relationships =
460            crate::groups::relationships(&mut jar, 7370273, groups::RelationshipType::Enemy)
461                .await
462                .unwrap();
463
464        println!("{:#?}", group_relationships);
465
466        assert_eq!(group_relationships.groups.len(), 0);
467    }
468
469    #[tokio::test]
470    async fn group_enemies_easy() {
471        // TODO: Improve this test
472        let mut jar = unauthenticated_jar().await;
473        let group_relationships = crate::groups::enemies(&mut jar, 7370273).await.unwrap();
474
475        println!("{:#?}", group_relationships);
476
477        assert_eq!(group_relationships.groups.len(), 0);
478    }
479
480    #[tokio::test]
481    async fn group_allies() {
482        // TODO: Improve this test
483        let mut jar = unauthenticated_jar().await;
484        let group_relationships =
485            crate::groups::relationships(&mut jar, 7370273, groups::RelationshipType::Ally)
486                .await
487                .unwrap();
488
489        println!("{:#?}", group_relationships);
490
491        assert_eq!(group_relationships.groups.len(), 0);
492    }
493
494    #[tokio::test]
495    async fn group_allies_easy() {
496        // TODO: Improve this test
497        let mut jar = unauthenticated_jar().await;
498        let group_relationships = crate::groups::allies(&mut jar, 7370273).await.unwrap();
499
500        println!("{:#?}", group_relationships);
501
502        assert_eq!(group_relationships.groups.len(), 0);
503    }
504
505    // TODO: Add tests for group relationships, but that requires a group (which requires robux)
506    // TODO: Add test for role_permissions, but that requires a group (which requires robux)
507    // TODO: Add test for update_role_permissions, but that requires a group (which requires robux)
508    // TODO: Add test for guest_permissions, but that requires a group (which requires robux)
509    // TODO: Add test for permissions, but that requires a group (which requires robux)
510
511    #[tokio::test]
512    async fn social_links() {
513        let mut jar = unauthenticated_jar().await;
514        let social_links = crate::groups::social_links(&mut jar, 7370273)
515            .await
516            .unwrap();
517
518        println!("{:#?}", social_links);
519
520        assert_eq!(social_links.len(), 0);
521    }
522
523    // TODO: Add test for add_social_link, but that requires a group (which requires robux)
524    // TODO: Add test for delete_social_link, but that requires a group (which requires robux)
525    // TODO: Add test for update_social_link, but that requires a group (which requires robux)
526
527    #[tokio::test]
528    async fn read_group_wall() {
529        let mut jar = unauthenticated_jar().await;
530        let wall = crate::groups::wall(&mut jar, 7370273, util::paging::PageLimit::All, None)
531            .await
532            .unwrap();
533
534        println!("{:#?}", wall);
535
536        // Panic if wall does not include a post from piano1029
537        wall.iter()
538            .find(|post| post.poster.user_id == 375760054)
539            .unwrap();
540
541        println!("{:#?}", wall);
542
543        assert_ne!(wall.len(), 0);
544    }
545
546    // TODO: Add test for deleting group wall posts, but that requires a group (which requires robux)
547
548    #[tokio::test]
549    async fn group_search() {
550        let mut jar = unauthenticated_jar().await;
551        let search_results = crate::groups::search(
552            &mut jar,
553            "Clanny Systems".to_string(),
554            Some(GroupSearchProps {
555                prioritize_exact_match: Some(true),
556                limit: Some(PageLimit::Limit10),
557                cursor: None,
558            }),
559        )
560        .await
561        .unwrap();
562
563        println!("{:#?}", search_results);
564
565        assert_eq!(search_results.results[0].name, "Clanny Systems");
566        assert_eq!(search_results.results[0].id, 7370273);
567        assert_eq!(search_results.keyword, "Clanny Systems");
568
569        assert_ne!(search_results.results.len(), 0);
570    }
571
572    #[tokio::test]
573    async fn group_exact_search() {
574        let mut jar = unauthenticated_jar().await;
575        let search_results = crate::groups::exact_search(&mut jar, "Clanny Systems".to_string())
576            .await
577            .unwrap();
578
579        println!("{:#?}", search_results);
580
581        assert_eq!(search_results[0].name, "Clanny Systems");
582        assert_eq!(search_results[0].id, 7370273);
583
584        assert_ne!(search_results.len(), 0);
585    }
586
587    #[tokio::test]
588    async fn group_roles_by_id() {
589        let mut jar = unauthenticated_jar().await;
590        let group_roles = crate::groups::roles(&mut jar, 7370273).await.unwrap();
591
592        println!("{:#?}", group_roles);
593
594        let test_role = &group_roles[0];
595        let role_by_id = crate::groups::roles_by_id(&mut jar, vec![test_role.id])
596            .await
597            .unwrap();
598
599        println!("{:#?}", role_by_id);
600
601        assert_eq!(role_by_id[0].id, test_role.id);
602        assert_eq!(role_by_id[0].name, test_role.name);
603    }
604
605    #[tokio::test]
606    async fn primary_group() {
607        let mut jar = unauthenticated_jar().await;
608        let primary_group = crate::groups::primary_group(&mut jar, 375760054)
609            .await
610            .unwrap();
611
612        println!("{:#?}", primary_group);
613
614        assert_eq!(primary_group.group.id, 7370273);
615        assert_eq!(primary_group.group.name, "Clanny Systems");
616        assert_eq!(primary_group.role.name, "Developer");
617    }
618
619    // TODO: Add test for removing and setting primary group
620
621    // TODO: Add tests for thumbnails!
622}