]> Untitled Git - lemmy.git/blob - api_tests/src/shared.ts
Moving settings to Database. (#2492)
[lemmy.git] / api_tests / src / shared.ts
1 import { None, Some, Option } from "@sniptt/monads";
2 import {
3   Login,
4   LoginResponse,
5   CreatePost,
6   EditPost,
7   CreateComment,
8   DeletePost,
9   RemovePost,
10   StickyPost,
11   LockPost,
12   PostResponse,
13   SearchResponse,
14   FollowCommunity,
15   CommunityResponse,
16   GetPostResponse,
17   Register,
18   Comment,
19   EditComment,
20   DeleteComment,
21   RemoveComment,
22   Search,
23   CommentResponse,
24   GetCommunity,
25   CreateCommunity,
26   DeleteCommunity,
27   RemoveCommunity,
28   GetPersonMentions,
29   CreateCommentLike,
30   CreatePostLike,
31   EditPrivateMessage,
32   DeletePrivateMessage,
33   GetPrivateMessages,
34   GetSite,
35   GetPost,
36   PrivateMessageResponse,
37   PrivateMessagesResponse,
38   GetPersonMentionsResponse,
39   SaveUserSettings,
40   SortType,
41   ListingType,
42   GetSiteResponse,
43   SearchType,
44   LemmyHttp,
45   BanPersonResponse,
46   BanPerson,
47   BanFromCommunity,
48   BanFromCommunityResponse,
49   Post,
50   CreatePrivateMessage,
51   ResolveObjectResponse,
52   ResolveObject,
53   CreatePostReport,
54   ListPostReports,
55   PostReportResponse,
56   ListPostReportsResponse,
57   CreateCommentReport,
58   CommentReportResponse,
59   ListCommentReports,
60   ListCommentReportsResponse,
61   DeleteAccount,
62   DeleteAccountResponse,
63   EditSite,
64   CommentSortType,
65   GetComments,
66   GetCommentsResponse,
67 } from "lemmy-js-client";
68
69 export interface API {
70   client: LemmyHttp;
71   auth: Option<string>;
72 }
73
74 export let alpha: API = {
75   client: new LemmyHttp("http://127.0.0.1:8541"),
76   auth: None,
77 };
78
79 export let beta: API = {
80   client: new LemmyHttp("http://127.0.0.1:8551"),
81   auth: None,
82 };
83
84 export let gamma: API = {
85   client: new LemmyHttp("http://127.0.0.1:8561"),
86   auth: None,
87 };
88
89 export let delta: API = {
90   client: new LemmyHttp("http://127.0.0.1:8571"),
91   auth: None,
92 };
93
94 export let epsilon: API = {
95   client: new LemmyHttp("http://127.0.0.1:8581"),
96   auth: None,
97 };
98
99 const password = "lemmylemmy";
100
101 export async function setupLogins() {
102   let formAlpha = new Login({
103     username_or_email: "lemmy_alpha",
104     password,
105   });
106   let resAlpha = alpha.client.login(formAlpha);
107
108   let formBeta = new Login({
109     username_or_email: "lemmy_beta",
110     password,
111   });
112   let resBeta = beta.client.login(formBeta);
113
114   let formGamma = new Login({
115     username_or_email: "lemmy_gamma",
116     password,
117   });
118   let resGamma = gamma.client.login(formGamma);
119
120   let formDelta = new Login({
121     username_or_email: "lemmy_delta",
122     password,
123   });
124   let resDelta = delta.client.login(formDelta);
125
126   let formEpsilon = new Login({
127     username_or_email: "lemmy_epsilon",
128     password,
129   });
130   let resEpsilon = epsilon.client.login(formEpsilon);
131
132   let res = await Promise.all([
133     resAlpha,
134     resBeta,
135     resGamma,
136     resDelta,
137     resEpsilon,
138   ]);
139
140   alpha.auth = res[0].jwt;
141   beta.auth = res[1].jwt;
142   gamma.auth = res[2].jwt;
143   delta.auth = res[3].jwt;
144   epsilon.auth = res[4].jwt;
145
146   // Registration applications are now enabled by default, need to disable them
147   let editSiteForm = new EditSite({
148     require_application: Some(false),
149     federation_debug: Some(true),
150     name: None,
151     sidebar: None,
152     description: None,
153     icon: None,
154     banner: None,
155     enable_downvotes: None,
156     open_registration: None,
157     enable_nsfw: None,
158     community_creation_admin_only: None,
159     require_email_verification: None,
160     application_question: None,
161     private_instance: None,
162     default_theme: None,
163     default_post_listing_type: None,
164     legal_information: None,
165     application_email_admins: None,
166     hide_modlog_mod_names: None,
167     discussion_languages: None,
168     slur_filter_regex: None,
169     actor_name_max_length: None,
170     rate_limit_message: Some(999),
171     rate_limit_message_per_second: None,
172     rate_limit_post: Some(999),
173     rate_limit_post_per_second: None,
174     rate_limit_register: Some(999),
175     rate_limit_register_per_second: None,
176     rate_limit_image: Some(999),
177     rate_limit_image_per_second: None,
178     rate_limit_comment: Some(999),
179     rate_limit_comment_per_second: None,
180     rate_limit_search: Some(999),
181     rate_limit_search_per_second: None,
182     federation_enabled: None,
183     federation_strict_allowlist: None,
184     federation_http_fetch_retry_limit: None,
185     federation_worker_count: None,
186     captcha_enabled: None,
187     captcha_difficulty: None,
188     allowed_instances: None,
189     blocked_instances: None,
190     auth: "",
191   });
192
193   // Set the blocks and auths for each
194   editSiteForm.auth = alpha.auth.unwrap();
195   editSiteForm.allowed_instances = Some([
196     "lemmy-beta",
197     "lemmy-gamma",
198     "lemmy-delta",
199     "lemmy-epsilon",
200   ]);
201   await alpha.client.editSite(editSiteForm);
202
203   editSiteForm.auth = beta.auth.unwrap();
204   editSiteForm.allowed_instances = Some([
205     "lemmy-alpha",
206     "lemmy-gamma",
207     "lemmy-delta",
208     "lemmy-epsilon",
209   ]);
210   await beta.client.editSite(editSiteForm);
211
212   editSiteForm.auth = gamma.auth.unwrap();
213   editSiteForm.allowed_instances = Some([
214     "lemmy-alpha",
215     "lemmy-beta",
216     "lemmy-delta",
217     "lemmy-epsilon",
218   ]);
219   await gamma.client.editSite(editSiteForm);
220
221   editSiteForm.allowed_instances = Some(["lemmy-beta"]);
222   editSiteForm.auth = delta.auth.unwrap();
223   await delta.client.editSite(editSiteForm);
224
225   editSiteForm.auth = epsilon.auth.unwrap();
226   editSiteForm.allowed_instances = Some([]);
227   editSiteForm.blocked_instances = Some(["lemmy-alpha"]);
228   await epsilon.client.editSite(editSiteForm);
229
230   // Create the main alpha/beta communities
231   await createCommunity(alpha, "main");
232   await createCommunity(beta, "main");
233 }
234
235 export async function createPost(
236   api: API,
237   community_id: number
238 ): Promise<PostResponse> {
239   let name = randomString(5);
240   let body = Some(randomString(10));
241   let url = Some("https://google.com/");
242   let form = new CreatePost({
243     name,
244     url,
245     body,
246     auth: api.auth.unwrap(),
247     community_id,
248     nsfw: None,
249     honeypot: None,
250     language_id: None,
251   });
252   return api.client.createPost(form);
253 }
254
255 export async function editPost(api: API, post: Post): Promise<PostResponse> {
256   let name = Some("A jest test federated post, updated");
257   let form = new EditPost({
258     name,
259     post_id: post.id,
260     auth: api.auth.unwrap(),
261     nsfw: None,
262     url: None,
263     body: None,
264     language_id: None,
265   });
266   return api.client.editPost(form);
267 }
268
269 export async function deletePost(
270   api: API,
271   deleted: boolean,
272   post: Post
273 ): Promise<PostResponse> {
274   let form = new DeletePost({
275     post_id: post.id,
276     deleted: deleted,
277     auth: api.auth.unwrap(),
278   });
279   return api.client.deletePost(form);
280 }
281
282 export async function removePost(
283   api: API,
284   removed: boolean,
285   post: Post
286 ): Promise<PostResponse> {
287   let form = new RemovePost({
288     post_id: post.id,
289     removed,
290     auth: api.auth.unwrap(),
291     reason: None,
292   });
293   return api.client.removePost(form);
294 }
295
296 export async function stickyPost(
297   api: API,
298   stickied: boolean,
299   post: Post
300 ): Promise<PostResponse> {
301   let form = new StickyPost({
302     post_id: post.id,
303     stickied,
304     auth: api.auth.unwrap(),
305   });
306   return api.client.stickyPost(form);
307 }
308
309 export async function lockPost(
310   api: API,
311   locked: boolean,
312   post: Post
313 ): Promise<PostResponse> {
314   let form = new LockPost({
315     post_id: post.id,
316     locked,
317     auth: api.auth.unwrap(),
318   });
319   return api.client.lockPost(form);
320 }
321
322 export async function resolvePost(
323   api: API,
324   post: Post
325 ): Promise<ResolveObjectResponse> {
326   let form = new ResolveObject({
327     q: post.ap_id,
328     auth: api.auth,
329   });
330   return api.client.resolveObject(form);
331 }
332
333 export async function searchPostLocal(
334   api: API,
335   post: Post
336 ): Promise<SearchResponse> {
337   let form = new Search({
338     q: post.name,
339     type_: Some(SearchType.Posts),
340     sort: Some(SortType.TopAll),
341     community_id: None,
342     community_name: None,
343     creator_id: None,
344     listing_type: None,
345     page: None,
346     limit: None,
347     auth: api.auth,
348   });
349   return api.client.search(form);
350 }
351
352 export async function getPost(
353   api: API,
354   post_id: number
355 ): Promise<GetPostResponse> {
356   let form = new GetPost({
357     id: Some(post_id),
358     comment_id: None,
359     auth: api.auth,
360   });
361   return api.client.getPost(form);
362 }
363
364 export async function getComments(
365   api: API,
366   post_id: number
367 ): Promise<GetCommentsResponse> {
368   let form = new GetComments({
369     post_id: Some(post_id),
370     type_: Some(ListingType.All),
371     sort: Some(CommentSortType.New), // TODO this sort might be wrong
372     max_depth: None,
373     page: None,
374     limit: None,
375     community_id: None,
376     community_name: None,
377     saved_only: None,
378     parent_id: None,
379     auth: api.auth,
380   });
381   return api.client.getComments(form);
382 }
383
384 export async function resolveComment(
385   api: API,
386   comment: Comment
387 ): Promise<ResolveObjectResponse> {
388   let form = new ResolveObject({
389     q: comment.ap_id,
390     auth: api.auth,
391   });
392   return api.client.resolveObject(form);
393 }
394
395 export async function resolveBetaCommunity(
396   api: API
397 ): Promise<ResolveObjectResponse> {
398   // Use short-hand search url
399   let form = new ResolveObject({
400     q: "!main@lemmy-beta:8551",
401     auth: api.auth,
402   });
403   return api.client.resolveObject(form);
404 }
405
406 export async function resolveCommunity(
407   api: API,
408   q: string
409 ): Promise<ResolveObjectResponse> {
410   let form = new ResolveObject({
411     q,
412     auth: api.auth,
413   });
414   return api.client.resolveObject(form);
415 }
416
417 export async function resolvePerson(
418   api: API,
419   apShortname: string
420 ): Promise<ResolveObjectResponse> {
421   let form = new ResolveObject({
422     q: apShortname,
423     auth: api.auth,
424   });
425   return api.client.resolveObject(form);
426 }
427
428 export async function banPersonFromSite(
429   api: API,
430   person_id: number,
431   ban: boolean,
432   remove_data: boolean
433 ): Promise<BanPersonResponse> {
434   // Make sure lemmy-beta/c/main is cached on lemmy_alpha
435   let form = new BanPerson({
436     person_id,
437     ban,
438     remove_data: Some(remove_data),
439     auth: api.auth.unwrap(),
440     reason: None,
441     expires: None,
442   });
443   return api.client.banPerson(form);
444 }
445
446 export async function banPersonFromCommunity(
447   api: API,
448   person_id: number,
449   community_id: number,
450   remove_data: boolean,
451   ban: boolean
452 ): Promise<BanFromCommunityResponse> {
453   let form = new BanFromCommunity({
454     person_id,
455     community_id,
456     remove_data: Some(remove_data),
457     ban,
458     reason: None,
459     expires: None,
460     auth: api.auth.unwrap(),
461   });
462   return api.client.banFromCommunity(form);
463 }
464
465 export async function followCommunity(
466   api: API,
467   follow: boolean,
468   community_id: number
469 ): Promise<CommunityResponse> {
470   let form = new FollowCommunity({
471     community_id,
472     follow,
473     auth: api.auth.unwrap(),
474   });
475   return api.client.followCommunity(form);
476 }
477
478 export async function likePost(
479   api: API,
480   score: number,
481   post: Post
482 ): Promise<PostResponse> {
483   let form = new CreatePostLike({
484     post_id: post.id,
485     score: score,
486     auth: api.auth.unwrap(),
487   });
488
489   return api.client.likePost(form);
490 }
491
492 export async function createComment(
493   api: API,
494   post_id: number,
495   parent_id: Option<number>,
496   content = "a jest test comment"
497 ): Promise<CommentResponse> {
498   let form = new CreateComment({
499     content,
500     post_id,
501     parent_id,
502     form_id: None,
503     language_id: None,
504     auth: api.auth.unwrap(),
505   });
506   return api.client.createComment(form);
507 }
508
509 export async function editComment(
510   api: API,
511   comment_id: number,
512   content = Some("A jest test federated comment update")
513 ): Promise<CommentResponse> {
514   let form = new EditComment({
515     content,
516     comment_id,
517     form_id: None,
518     language_id: None,
519     distinguished: None,
520     auth: api.auth.unwrap(),
521   });
522   return api.client.editComment(form);
523 }
524
525 export async function deleteComment(
526   api: API,
527   deleted: boolean,
528   comment_id: number
529 ): Promise<CommentResponse> {
530   let form = new DeleteComment({
531     comment_id,
532     deleted,
533     auth: api.auth.unwrap(),
534   });
535   return api.client.deleteComment(form);
536 }
537
538 export async function removeComment(
539   api: API,
540   removed: boolean,
541   comment_id: number
542 ): Promise<CommentResponse> {
543   let form = new RemoveComment({
544     comment_id,
545     removed,
546     reason: None,
547     auth: api.auth.unwrap(),
548   });
549   return api.client.removeComment(form);
550 }
551
552 export async function getMentions(
553   api: API
554 ): Promise<GetPersonMentionsResponse> {
555   let form = new GetPersonMentions({
556     sort: Some(CommentSortType.New),
557     unread_only: Some(false),
558     auth: api.auth.unwrap(),
559     page: None,
560     limit: None,
561   });
562   return api.client.getPersonMentions(form);
563 }
564
565 export async function likeComment(
566   api: API,
567   score: number,
568   comment: Comment
569 ): Promise<CommentResponse> {
570   let form = new CreateCommentLike({
571     comment_id: comment.id,
572     score,
573     auth: api.auth.unwrap(),
574   });
575   return api.client.likeComment(form);
576 }
577
578 export async function createCommunity(
579   api: API,
580   name_: string = randomString(5)
581 ): Promise<CommunityResponse> {
582   let description = Some("a sample description");
583   let form = new CreateCommunity({
584     name: name_,
585     title: name_,
586     description,
587     nsfw: None,
588     icon: None,
589     banner: None,
590     posting_restricted_to_mods: None,
591     auth: api.auth.unwrap(),
592   });
593   return api.client.createCommunity(form);
594 }
595
596 export async function getCommunity(
597   api: API,
598   id: number
599 ): Promise<CommunityResponse> {
600   let form = new GetCommunity({
601     id: Some(id),
602     name: None,
603     auth: api.auth,
604   });
605   return api.client.getCommunity(form);
606 }
607
608 export async function deleteCommunity(
609   api: API,
610   deleted: boolean,
611   community_id: number
612 ): Promise<CommunityResponse> {
613   let form = new DeleteCommunity({
614     community_id,
615     deleted,
616     auth: api.auth.unwrap(),
617   });
618   return api.client.deleteCommunity(form);
619 }
620
621 export async function removeCommunity(
622   api: API,
623   removed: boolean,
624   community_id: number
625 ): Promise<CommunityResponse> {
626   let form = new RemoveCommunity({
627     community_id,
628     removed,
629     reason: None,
630     expires: None,
631     auth: api.auth.unwrap(),
632   });
633   return api.client.removeCommunity(form);
634 }
635
636 export async function createPrivateMessage(
637   api: API,
638   recipient_id: number
639 ): Promise<PrivateMessageResponse> {
640   let content = "A jest test federated private message";
641   let form = new CreatePrivateMessage({
642     content,
643     recipient_id,
644     auth: api.auth.unwrap(),
645   });
646   return api.client.createPrivateMessage(form);
647 }
648
649 export async function editPrivateMessage(
650   api: API,
651   private_message_id: number
652 ): Promise<PrivateMessageResponse> {
653   let updatedContent = "A jest test federated private message edited";
654   let form = new EditPrivateMessage({
655     content: updatedContent,
656     private_message_id,
657     auth: api.auth.unwrap(),
658   });
659   return api.client.editPrivateMessage(form);
660 }
661
662 export async function deletePrivateMessage(
663   api: API,
664   deleted: boolean,
665   private_message_id: number
666 ): Promise<PrivateMessageResponse> {
667   let form = new DeletePrivateMessage({
668     deleted,
669     private_message_id,
670     auth: api.auth.unwrap(),
671   });
672   return api.client.deletePrivateMessage(form);
673 }
674
675 export async function registerUser(
676   api: API,
677   username: string = randomString(5)
678 ): Promise<LoginResponse> {
679   let form = new Register({
680     username,
681     password,
682     password_verify: password,
683     show_nsfw: true,
684     email: None,
685     captcha_uuid: None,
686     captcha_answer: None,
687     honeypot: None,
688     answer: None,
689   });
690   return api.client.register(form);
691 }
692
693 export async function saveUserSettingsBio(api: API): Promise<LoginResponse> {
694   let form = new SaveUserSettings({
695     show_nsfw: Some(true),
696     theme: Some("darkly"),
697     default_sort_type: Some(Object.keys(SortType).indexOf(SortType.Active)),
698     default_listing_type: Some(
699       Object.keys(ListingType).indexOf(ListingType.All)
700     ),
701     interface_language: Some("en"),
702     show_avatars: Some(true),
703     send_notifications_to_email: Some(false),
704     bio: Some("a changed bio"),
705     avatar: None,
706     banner: None,
707     display_name: None,
708     email: None,
709     matrix_user_id: None,
710     show_scores: None,
711     show_read_posts: None,
712     show_bot_accounts: None,
713     show_new_post_notifs: None,
714     bot_account: None,
715     discussion_languages: None,
716     auth: api.auth.unwrap(),
717   });
718   return saveUserSettings(api, form);
719 }
720
721 export async function saveUserSettingsFederated(
722   api: API
723 ): Promise<LoginResponse> {
724   let avatar = Some("https://image.flaticon.com/icons/png/512/35/35896.png");
725   let banner = Some("https://image.flaticon.com/icons/png/512/36/35896.png");
726   let bio = Some("a changed bio");
727   let form = new SaveUserSettings({
728     show_nsfw: Some(false),
729     theme: Some(""),
730     default_sort_type: Some(Object.keys(SortType).indexOf(SortType.Hot)),
731     default_listing_type: Some(
732       Object.keys(ListingType).indexOf(ListingType.All)
733     ),
734     interface_language: Some(""),
735     avatar,
736     banner,
737     display_name: Some("user321"),
738     show_avatars: Some(false),
739     send_notifications_to_email: Some(false),
740     bio,
741     email: None,
742     show_scores: None,
743     show_read_posts: None,
744     matrix_user_id: None,
745     bot_account: None,
746     show_bot_accounts: None,
747     show_new_post_notifs: None,
748     discussion_languages: None,
749     auth: api.auth.unwrap(),
750   });
751   return await saveUserSettings(alpha, form);
752 }
753
754 export async function saveUserSettings(
755   api: API,
756   form: SaveUserSettings
757 ): Promise<LoginResponse> {
758   return api.client.saveUserSettings(form);
759 }
760
761 export async function deleteUser(api: API): Promise<DeleteAccountResponse> {
762   let form = new DeleteAccount({
763     auth: api.auth.unwrap(),
764     password,
765   });
766   return api.client.deleteAccount(form);
767 }
768
769 export async function getSite(api: API): Promise<GetSiteResponse> {
770   let form = new GetSite({
771     auth: api.auth,
772   });
773   return api.client.getSite(form);
774 }
775
776 export async function listPrivateMessages(
777   api: API
778 ): Promise<PrivateMessagesResponse> {
779   let form = new GetPrivateMessages({
780     auth: api.auth.unwrap(),
781     unread_only: Some(false),
782     page: None,
783     limit: None,
784   });
785   return api.client.getPrivateMessages(form);
786 }
787
788 export async function unfollowRemotes(api: API): Promise<GetSiteResponse> {
789   // Unfollow all remote communities
790   let site = await getSite(api);
791   let remoteFollowed = site.my_user
792     .unwrap()
793     .follows.filter(c => c.community.local == false);
794   for (let cu of remoteFollowed) {
795     await followCommunity(api, false, cu.community.id);
796   }
797   let siteRes = await getSite(api);
798   return siteRes;
799 }
800
801 export async function followBeta(api: API): Promise<CommunityResponse> {
802   let betaCommunity = (await resolveBetaCommunity(api)).community;
803   if (betaCommunity.isSome()) {
804     let follow = await followCommunity(
805       api,
806       true,
807       betaCommunity.unwrap().community.id
808     );
809     return follow;
810   } else {
811     return Promise.reject("no community worked");
812   }
813 }
814
815 export async function reportPost(
816   api: API,
817   post_id: number,
818   reason: string
819 ): Promise<PostReportResponse> {
820   let form = new CreatePostReport({
821     post_id,
822     reason,
823     auth: api.auth.unwrap(),
824   });
825   return api.client.createPostReport(form);
826 }
827
828 export async function listPostReports(
829   api: API
830 ): Promise<ListPostReportsResponse> {
831   let form = new ListPostReports({
832     auth: api.auth.unwrap(),
833     page: None,
834     limit: None,
835     community_id: None,
836     unresolved_only: None,
837   });
838   return api.client.listPostReports(form);
839 }
840
841 export async function reportComment(
842   api: API,
843   comment_id: number,
844   reason: string
845 ): Promise<CommentReportResponse> {
846   let form = new CreateCommentReport({
847     comment_id,
848     reason,
849     auth: api.auth.unwrap(),
850   });
851   return api.client.createCommentReport(form);
852 }
853
854 export async function listCommentReports(
855   api: API
856 ): Promise<ListCommentReportsResponse> {
857   let form = new ListCommentReports({
858     page: None,
859     limit: None,
860     community_id: None,
861     unresolved_only: None,
862     auth: api.auth.unwrap(),
863   });
864   return api.client.listCommentReports(form);
865 }
866
867 export function delay(millis = 500) {
868   return new Promise(resolve => setTimeout(resolve, millis));
869 }
870
871 export function longDelay() {
872   return delay(10000);
873 }
874
875 export function wrapper(form: any): string {
876   return JSON.stringify(form);
877 }
878
879 export function randomString(length: number): string {
880   var result = "";
881   var characters =
882     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
883   var charactersLength = characters.length;
884   for (var i = 0; i < length; i++) {
885     result += characters.charAt(Math.floor(Math.random() * charactersLength));
886   }
887   return result;
888 }
889
890 export async function unfollows() {
891   await unfollowRemotes(alpha);
892   await unfollowRemotes(gamma);
893   await unfollowRemotes(delta);
894   await unfollowRemotes(epsilon);
895 }
896
897 export function getCommentParentId(comment: Comment): Option<number> {
898   let split = comment.path.split(".");
899   // remove the 0
900   split.shift();
901
902   if (split.length > 1) {
903     return Some(Number(split[split.length - 2]));
904   } else {
905     return None;
906   }
907 }