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