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