]> Untitled Git - lemmy.git/blob - api_tests/src/comment.spec.ts
Update prettier to 3.0.0 (#3509)
[lemmy.git] / api_tests / src / comment.spec.ts
1 jest.setTimeout(180000);
2
3 import { PostResponse } from "lemmy-js-client/dist/types/PostResponse";
4 import {
5   alpha,
6   beta,
7   gamma,
8   setupLogins,
9   createPost,
10   getPost,
11   resolveComment,
12   likeComment,
13   followBeta,
14   resolveBetaCommunity,
15   createComment,
16   editComment,
17   deleteComment,
18   removeComment,
19   getMentions,
20   resolvePost,
21   unfollowRemotes,
22   createCommunity,
23   registerUser,
24   reportComment,
25   listCommentReports,
26   randomString,
27   API,
28   unfollows,
29   getComments,
30   getCommentParentId,
31   resolveCommunity,
32 } from "./shared";
33 import { CommentView } from "lemmy-js-client/dist/types/CommentView";
34
35 let postRes: PostResponse;
36
37 beforeAll(async () => {
38   await setupLogins();
39   await unfollows();
40   await followBeta(alpha);
41   await followBeta(gamma);
42   let betaCommunity = (await resolveBetaCommunity(alpha)).community;
43   if (betaCommunity) {
44     postRes = await createPost(alpha, betaCommunity.community.id);
45   }
46 });
47
48 afterAll(async () => {
49   await unfollows();
50 });
51
52 function assertCommentFederation(
53   commentOne?: CommentView,
54   commentTwo?: CommentView,
55 ) {
56   expect(commentOne?.comment.ap_id).toBe(commentTwo?.comment.ap_id);
57   expect(commentOne?.comment.content).toBe(commentTwo?.comment.content);
58   expect(commentOne?.creator.name).toBe(commentTwo?.creator.name);
59   expect(commentOne?.community.actor_id).toBe(commentTwo?.community.actor_id);
60   expect(commentOne?.comment.published).toBe(commentTwo?.comment.published);
61   expect(commentOne?.comment.updated).toBe(commentOne?.comment.updated);
62   expect(commentOne?.comment.deleted).toBe(commentOne?.comment.deleted);
63   expect(commentOne?.comment.removed).toBe(commentOne?.comment.removed);
64 }
65
66 test("Create a comment", async () => {
67   let commentRes = await createComment(alpha, postRes.post_view.post.id);
68   expect(commentRes.comment_view.comment.content).toBeDefined();
69   expect(commentRes.comment_view.community.local).toBe(false);
70   expect(commentRes.comment_view.creator.local).toBe(true);
71   expect(commentRes.comment_view.counts.score).toBe(1);
72
73   // Make sure that comment is liked on beta
74   let betaComment = (
75     await resolveComment(beta, commentRes.comment_view.comment)
76   ).comment;
77   expect(betaComment).toBeDefined();
78   expect(betaComment?.community.local).toBe(true);
79   expect(betaComment?.creator.local).toBe(false);
80   expect(betaComment?.counts.score).toBe(1);
81   assertCommentFederation(betaComment, commentRes.comment_view);
82 });
83
84 test("Create a comment in a non-existent post", async () => {
85   let commentRes = (await createComment(alpha, -1)) as any;
86   expect(commentRes.error).toBe("couldnt_find_post");
87 });
88
89 test("Update a comment", async () => {
90   let commentRes = await createComment(alpha, postRes.post_view.post.id);
91   // Federate the comment first
92   let betaComment = (
93     await resolveComment(beta, commentRes.comment_view.comment)
94   ).comment;
95   assertCommentFederation(betaComment, commentRes.comment_view);
96
97   let updateCommentRes = await editComment(
98     alpha,
99     commentRes.comment_view.comment.id,
100   );
101   expect(updateCommentRes.comment_view.comment.content).toBe(
102     "A jest test federated comment update",
103   );
104   expect(updateCommentRes.comment_view.community.local).toBe(false);
105   expect(updateCommentRes.comment_view.creator.local).toBe(true);
106
107   // Make sure that post is updated on beta
108   let betaCommentUpdated = (
109     await resolveComment(beta, commentRes.comment_view.comment)
110   ).comment;
111   assertCommentFederation(betaCommentUpdated, updateCommentRes.comment_view);
112 });
113
114 test("Delete a comment", async () => {
115   let commentRes = await createComment(alpha, postRes.post_view.post.id);
116
117   let deleteCommentRes = await deleteComment(
118     alpha,
119     true,
120     commentRes.comment_view.comment.id,
121   );
122   expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
123
124   // Make sure that comment is undefined on beta
125   let betaCommentRes = (await resolveComment(
126     beta,
127     commentRes.comment_view.comment,
128   )) as any;
129   expect(betaCommentRes.error).toBe("couldnt_find_object");
130
131   let undeleteCommentRes = await deleteComment(
132     alpha,
133     false,
134     commentRes.comment_view.comment.id,
135   );
136   expect(undeleteCommentRes.comment_view.comment.deleted).toBe(false);
137
138   // Make sure that comment is undeleted on beta
139   let betaComment2 = (
140     await resolveComment(beta, commentRes.comment_view.comment)
141   ).comment;
142   expect(betaComment2?.comment.deleted).toBe(false);
143   assertCommentFederation(betaComment2, undeleteCommentRes.comment_view);
144 });
145
146 test("Remove a comment from admin and community on the same instance", async () => {
147   let commentRes = await createComment(alpha, postRes.post_view.post.id);
148
149   // Get the id for beta
150   let betaCommentId = (
151     await resolveComment(beta, commentRes.comment_view.comment)
152   ).comment?.comment.id;
153
154   if (!betaCommentId) {
155     throw "beta comment id is missing";
156   }
157
158   // The beta admin removes it (the community lives on beta)
159   let removeCommentRes = await removeComment(beta, true, betaCommentId);
160   expect(removeCommentRes.comment_view.comment.removed).toBe(true);
161
162   // Make sure that comment is removed on alpha (it gets pushed since an admin from beta removed it)
163   let refetchedPostComments = await getComments(
164     alpha,
165     postRes.post_view.post.id,
166   );
167   expect(refetchedPostComments.comments[0].comment.removed).toBe(true);
168
169   let unremoveCommentRes = await removeComment(beta, false, betaCommentId);
170   expect(unremoveCommentRes.comment_view.comment.removed).toBe(false);
171
172   // Make sure that comment is unremoved on beta
173   let refetchedPostComments2 = await getComments(
174     alpha,
175     postRes.post_view.post.id,
176   );
177   expect(refetchedPostComments2.comments[0].comment.removed).toBe(false);
178   assertCommentFederation(
179     refetchedPostComments2.comments[0],
180     unremoveCommentRes.comment_view,
181   );
182 });
183
184 test("Remove a comment from admin and community on different instance", async () => {
185   let alpha_user = await registerUser(alpha);
186   let newAlphaApi: API = {
187     client: alpha.client,
188     auth: alpha_user.jwt ?? "",
189   };
190
191   // New alpha user creates a community, post, and comment.
192   let newCommunity = await createCommunity(newAlphaApi);
193   let newPost = await createPost(
194     newAlphaApi,
195     newCommunity.community_view.community.id,
196   );
197   let commentRes = await createComment(newAlphaApi, newPost.post_view.post.id);
198   expect(commentRes.comment_view.comment.content).toBeDefined();
199
200   // Beta searches that to cache it, then removes it
201   let betaComment = (
202     await resolveComment(beta, commentRes.comment_view.comment)
203   ).comment;
204
205   if (!betaComment) {
206     throw "beta comment missing";
207   }
208
209   let removeCommentRes = await removeComment(
210     beta,
211     true,
212     betaComment.comment.id,
213   );
214   expect(removeCommentRes.comment_view.comment.removed).toBe(true);
215
216   // Make sure its not removed on alpha
217   let refetchedPostComments = await getComments(
218     alpha,
219     newPost.post_view.post.id,
220   );
221   expect(refetchedPostComments.comments[0].comment.removed).toBe(false);
222   assertCommentFederation(
223     refetchedPostComments.comments[0],
224     commentRes.comment_view,
225   );
226 });
227
228 test("Unlike a comment", async () => {
229   let commentRes = await createComment(alpha, postRes.post_view.post.id);
230   let unlike = await likeComment(alpha, 0, commentRes.comment_view.comment);
231   expect(unlike.comment_view.counts.score).toBe(0);
232
233   // Make sure that post is unliked on beta
234   let betaComment = (
235     await resolveComment(beta, commentRes.comment_view.comment)
236   ).comment;
237   expect(betaComment).toBeDefined();
238   expect(betaComment?.community.local).toBe(true);
239   expect(betaComment?.creator.local).toBe(false);
240   expect(betaComment?.counts.score).toBe(0);
241 });
242
243 test("Federated comment like", async () => {
244   let commentRes = await createComment(alpha, postRes.post_view.post.id);
245
246   // Find the comment on beta
247   let betaComment = (
248     await resolveComment(beta, commentRes.comment_view.comment)
249   ).comment;
250
251   if (!betaComment) {
252     throw "Missing beta comment";
253   }
254
255   let like = await likeComment(beta, 1, betaComment.comment);
256   expect(like.comment_view.counts.score).toBe(2);
257
258   // Get the post from alpha, check the likes
259   let postComments = await getComments(alpha, postRes.post_view.post.id);
260   expect(postComments.comments[0].counts.score).toBe(2);
261 });
262
263 test("Reply to a comment", async () => {
264   // Create a comment on alpha, find it on beta
265   let commentRes = await createComment(alpha, postRes.post_view.post.id);
266   let betaComment = (
267     await resolveComment(beta, commentRes.comment_view.comment)
268   ).comment;
269
270   if (!betaComment) {
271     throw "Missing beta comment";
272   }
273
274   // find that comment id on beta
275
276   // Reply from beta
277   let replyRes = await createComment(
278     beta,
279     betaComment.post.id,
280     betaComment.comment.id,
281   );
282   expect(replyRes.comment_view.comment.content).toBeDefined();
283   expect(replyRes.comment_view.community.local).toBe(true);
284   expect(replyRes.comment_view.creator.local).toBe(true);
285   expect(getCommentParentId(replyRes.comment_view.comment)).toBe(
286     betaComment.comment.id,
287   );
288   expect(replyRes.comment_view.counts.score).toBe(1);
289
290   // Make sure that comment is seen on alpha
291   // TODO not sure why, but a searchComment back to alpha, for the ap_id of betas
292   // comment, isn't working.
293   // let searchAlpha = await searchComment(alpha, replyRes.comment);
294   let postComments = await getComments(alpha, postRes.post_view.post.id);
295   let alphaComment = postComments.comments[0];
296   expect(alphaComment.comment.content).toBeDefined();
297   expect(getCommentParentId(alphaComment.comment)).toBe(
298     postComments.comments[1].comment.id,
299   );
300   expect(alphaComment.community.local).toBe(false);
301   expect(alphaComment.creator.local).toBe(false);
302   expect(alphaComment.counts.score).toBe(1);
303   assertCommentFederation(alphaComment, replyRes.comment_view);
304 });
305
306 test("Mention beta", async () => {
307   // Create a mention on alpha
308   let mentionContent = "A test mention of @lemmy_beta@lemmy-beta:8551";
309   let commentRes = await createComment(alpha, postRes.post_view.post.id);
310   let mentionRes = await createComment(
311     alpha,
312     postRes.post_view.post.id,
313     commentRes.comment_view.comment.id,
314     mentionContent,
315   );
316   expect(mentionRes.comment_view.comment.content).toBeDefined();
317   expect(mentionRes.comment_view.community.local).toBe(false);
318   expect(mentionRes.comment_view.creator.local).toBe(true);
319   expect(mentionRes.comment_view.counts.score).toBe(1);
320
321   let mentionsRes = await getMentions(beta);
322   expect(mentionsRes.mentions[0].comment.content).toBeDefined();
323   expect(mentionsRes.mentions[0].community.local).toBe(true);
324   expect(mentionsRes.mentions[0].creator.local).toBe(false);
325   expect(mentionsRes.mentions[0].counts.score).toBe(1);
326 });
327
328 test("Comment Search", async () => {
329   let commentRes = await createComment(alpha, postRes.post_view.post.id);
330   let betaComment = (
331     await resolveComment(beta, commentRes.comment_view.comment)
332   ).comment;
333   assertCommentFederation(betaComment, commentRes.comment_view);
334 });
335
336 test("A and G subscribe to B (center) A posts, G mentions B, it gets announced to A", async () => {
337   // Create a local post
338   let alphaCommunity = (await resolveCommunity(alpha, "!main@lemmy-alpha:8541"))
339     .community;
340
341   if (!alphaCommunity) {
342     throw "Missing alpha community";
343   }
344
345   let alphaPost = await createPost(alpha, alphaCommunity.community.id);
346   expect(alphaPost.post_view.community.local).toBe(true);
347
348   // Make sure gamma sees it
349   let gammaPost = (await resolvePost(gamma, alphaPost.post_view.post)).post;
350
351   if (!gammaPost) {
352     throw "Missing gamma post";
353   }
354
355   let commentContent =
356     "A jest test federated comment announce, lets mention @lemmy_beta@lemmy-beta:8551";
357   let commentRes = await createComment(
358     gamma,
359     gammaPost.post.id,
360     undefined,
361     commentContent,
362   );
363   expect(commentRes.comment_view.comment.content).toBe(commentContent);
364   expect(commentRes.comment_view.community.local).toBe(false);
365   expect(commentRes.comment_view.creator.local).toBe(true);
366   expect(commentRes.comment_view.counts.score).toBe(1);
367
368   // Make sure alpha sees it
369   let alphaPostComments2 = await getComments(
370     alpha,
371     alphaPost.post_view.post.id,
372   );
373   expect(alphaPostComments2.comments[0].comment.content).toBe(commentContent);
374   expect(alphaPostComments2.comments[0].community.local).toBe(true);
375   expect(alphaPostComments2.comments[0].creator.local).toBe(false);
376   expect(alphaPostComments2.comments[0].counts.score).toBe(1);
377   assertCommentFederation(
378     alphaPostComments2.comments[0],
379     commentRes.comment_view,
380   );
381
382   // Make sure beta has mentions
383   let mentionsRes = await getMentions(beta);
384   expect(mentionsRes.mentions[0].comment.content).toBe(commentContent);
385   expect(mentionsRes.mentions[0].community.local).toBe(false);
386   expect(mentionsRes.mentions[0].creator.local).toBe(false);
387   // TODO this is failing because fetchInReplyTos aren't getting score
388   // expect(mentionsRes.mentions[0].score).toBe(1);
389 });
390
391 test("Check that activity from another instance is sent to third instance", async () => {
392   // Alpha and gamma users follow beta community
393   let alphaFollow = await followBeta(alpha);
394   expect(alphaFollow.community_view.community.local).toBe(false);
395   expect(alphaFollow.community_view.community.name).toBe("main");
396
397   let gammaFollow = await followBeta(gamma);
398   expect(gammaFollow.community_view.community.local).toBe(false);
399   expect(gammaFollow.community_view.community.name).toBe("main");
400
401   // Create a post on beta
402   let betaPost = await createPost(beta, 2);
403   expect(betaPost.post_view.community.local).toBe(true);
404
405   // Make sure gamma and alpha see it
406   let gammaPost = (await resolvePost(gamma, betaPost.post_view.post)).post;
407   if (!gammaPost) {
408     throw "Missing gamma post";
409   }
410   expect(gammaPost.post).toBeDefined();
411
412   let alphaPost = (await resolvePost(alpha, betaPost.post_view.post)).post;
413   if (!alphaPost) {
414     throw "Missing alpha post";
415   }
416   expect(alphaPost.post).toBeDefined();
417
418   // The bug: gamma comments, and alpha should see it.
419   let commentContent = "Comment from gamma";
420   let commentRes = await createComment(
421     gamma,
422     gammaPost.post.id,
423     undefined,
424     commentContent,
425   );
426   expect(commentRes.comment_view.comment.content).toBe(commentContent);
427   expect(commentRes.comment_view.community.local).toBe(false);
428   expect(commentRes.comment_view.creator.local).toBe(true);
429   expect(commentRes.comment_view.counts.score).toBe(1);
430
431   // Make sure alpha sees it
432   let alphaPostComments2 = await getComments(alpha, alphaPost.post.id);
433   expect(alphaPostComments2.comments[0].comment.content).toBe(commentContent);
434   expect(alphaPostComments2.comments[0].community.local).toBe(false);
435   expect(alphaPostComments2.comments[0].creator.local).toBe(false);
436   expect(alphaPostComments2.comments[0].counts.score).toBe(1);
437   assertCommentFederation(
438     alphaPostComments2.comments[0],
439     commentRes.comment_view,
440   );
441
442   await unfollowRemotes(alpha);
443   await unfollowRemotes(gamma);
444 });
445
446 test("Fetch in_reply_tos: A is unsubbed from B, B makes a post, and some embedded comments, A subs to B, B updates the lowest level comment, A fetches both the post and all the inreplyto comments for that post.", async () => {
447   // Unfollow all remote communities
448   let site = await unfollowRemotes(alpha);
449   expect(
450     site.my_user?.follows.filter(c => c.community.local == false).length,
451   ).toBe(0);
452
453   // B creates a post, and two comments, should be invisible to A
454   let postRes = await createPost(beta, 2);
455   expect(postRes.post_view.post.name).toBeDefined();
456
457   let parentCommentContent = "An invisible top level comment from beta";
458   let parentCommentRes = await createComment(
459     beta,
460     postRes.post_view.post.id,
461     undefined,
462     parentCommentContent,
463   );
464   expect(parentCommentRes.comment_view.comment.content).toBe(
465     parentCommentContent,
466   );
467
468   // B creates a comment, then a child one of that.
469   let childCommentContent = "An invisible child comment from beta";
470   let childCommentRes = await createComment(
471     beta,
472     postRes.post_view.post.id,
473     parentCommentRes.comment_view.comment.id,
474     childCommentContent,
475   );
476   expect(childCommentRes.comment_view.comment.content).toBe(
477     childCommentContent,
478   );
479
480   // Follow beta again
481   let follow = await followBeta(alpha);
482   expect(follow.community_view.community.local).toBe(false);
483   expect(follow.community_view.community.name).toBe("main");
484
485   // An update to the child comment on beta, should push the post, parent, and child to alpha now
486   let updatedCommentContent = "An update child comment from beta";
487   let updateRes = await editComment(
488     beta,
489     childCommentRes.comment_view.comment.id,
490     updatedCommentContent,
491   );
492   expect(updateRes.comment_view.comment.content).toBe(updatedCommentContent);
493
494   // Get the post from alpha
495   let alphaPostB = (await resolvePost(alpha, postRes.post_view.post)).post;
496   if (!alphaPostB) {
497     throw "Missing alpha post B";
498   }
499
500   let alphaPost = await getPost(alpha, alphaPostB.post.id);
501   let alphaPostComments = await getComments(alpha, alphaPostB.post.id);
502   expect(alphaPost.post_view.post.name).toBeDefined();
503   assertCommentFederation(
504     alphaPostComments.comments[1],
505     parentCommentRes.comment_view,
506   );
507   assertCommentFederation(
508     alphaPostComments.comments[0],
509     updateRes.comment_view,
510   );
511   expect(alphaPost.post_view.community.local).toBe(false);
512   expect(alphaPost.post_view.creator.local).toBe(false);
513
514   await unfollowRemotes(alpha);
515 });
516
517 test("Report a comment", async () => {
518   let betaCommunity = (await resolveBetaCommunity(beta)).community;
519   if (!betaCommunity) {
520     throw "Missing beta community";
521   }
522   let postRes = (await createPost(beta, betaCommunity.community.id)).post_view
523     .post;
524   expect(postRes).toBeDefined();
525   let commentRes = (await createComment(beta, postRes.id)).comment_view.comment;
526   expect(commentRes).toBeDefined();
527
528   let alphaComment = (await resolveComment(alpha, commentRes)).comment?.comment;
529   if (!alphaComment) {
530     throw "Missing alpha comment";
531   }
532
533   let alphaReport = (
534     await reportComment(alpha, alphaComment.id, randomString(10))
535   ).comment_report_view.comment_report;
536
537   let betaReport = (await listCommentReports(beta)).comment_reports[0]
538     .comment_report;
539   expect(betaReport).toBeDefined();
540   expect(betaReport.resolved).toBe(false);
541   expect(betaReport.original_comment_text).toBe(
542     alphaReport.original_comment_text,
543   );
544   expect(betaReport.reason).toBe(alphaReport.reason);
545 });