]> Untitled Git - lemmy.git/blob - api_tests/src/comment.spec.ts
be58ff000fd01089d197ac9f22cda3332d6b4ce5
[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 alpha_user = await registerUser(alpha);
174   let newAlphaApi: API = {
175     client: alpha.client,
176     auth: alpha_user.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 alphaCommunity = await createCommunity(alpha, "main");
294   let alphaPost = await createPost(alpha, alphaCommunity.community_view.community.id);
295   expect(alphaPost.post_view.community.local).toBe(true);
296
297   // Make sure gamma sees it
298   let gammaPost = (await resolvePost(gamma, alphaPost.post_view.post)).post;
299
300   let commentContent =
301     'A jest test federated comment announce, lets mention @lemmy_beta@lemmy-beta:8551';
302   let commentRes = await createComment(
303     gamma,
304     gammaPost.post.id,
305     undefined,
306     commentContent
307   );
308   expect(commentRes.comment_view.comment.content).toBe(commentContent);
309   expect(commentRes.comment_view.community.local).toBe(false);
310   expect(commentRes.comment_view.creator.local).toBe(true);
311   expect(commentRes.comment_view.counts.score).toBe(1);
312
313   // Make sure alpha sees it
314   let alphaPost2 = await getPost(alpha, alphaPost.post_view.post.id);
315   expect(alphaPost2.comments[0].comment.content).toBe(commentContent);
316   expect(alphaPost2.comments[0].community.local).toBe(true);
317   expect(alphaPost2.comments[0].creator.local).toBe(false);
318   expect(alphaPost2.comments[0].counts.score).toBe(1);
319   assertCommentFederation(alphaPost2.comments[0], commentRes.comment_view);
320
321   // Make sure beta has mentions
322   let mentionsRes = await getMentions(beta);
323   expect(mentionsRes.mentions[0].comment.content).toBe(commentContent);
324   expect(mentionsRes.mentions[0].community.local).toBe(false);
325   expect(mentionsRes.mentions[0].creator.local).toBe(false);
326   // TODO this is failing because fetchInReplyTos aren't getting score
327   // expect(mentionsRes.mentions[0].score).toBe(1);
328 });
329
330 test('Check that activity from another instance is sent to third instance', async () => {
331   // Alpha and gamma users follow beta community
332   let alphaFollow = await followBeta(alpha);
333   expect(alphaFollow.community_view.community.local).toBe(false);
334   expect(alphaFollow.community_view.community.name).toBe('main');
335
336   let gammaFollow = await followBeta(gamma);
337   expect(gammaFollow.community_view.community.local).toBe(false);
338   expect(gammaFollow.community_view.community.name).toBe('main');
339
340   // Create a post on beta
341   let betaPost = await createPost(beta, 2);
342   expect(betaPost.post_view.community.local).toBe(true);
343
344   // Make sure gamma and alpha see it
345   let gammaPost = (await resolvePost(gamma, betaPost.post_view.post)).post;
346   expect(gammaPost.post).toBeDefined();
347   let alphaPost = (await resolvePost(alpha, betaPost.post_view.post)).post;
348   expect(alphaPost.post).toBeDefined();
349
350   // The bug: gamma comments, and alpha should see it.
351   let commentContent = 'Comment from gamma';
352   let commentRes = await createComment(
353     gamma,
354     gammaPost.post.id,
355     undefined,
356     commentContent
357   );
358   expect(commentRes.comment_view.comment.content).toBe(commentContent);
359   expect(commentRes.comment_view.community.local).toBe(false);
360   expect(commentRes.comment_view.creator.local).toBe(true);
361   expect(commentRes.comment_view.counts.score).toBe(1);
362
363   // Make sure alpha sees it
364   let alphaPost2 = await getPost(alpha, alphaPost.post.id);
365   expect(alphaPost2.comments[0].comment.content).toBe(commentContent);
366   expect(alphaPost2.comments[0].community.local).toBe(false);
367   expect(alphaPost2.comments[0].creator.local).toBe(false);
368   expect(alphaPost2.comments[0].counts.score).toBe(1);
369   assertCommentFederation(alphaPost2.comments[0], commentRes.comment_view);
370
371   await unfollowRemotes(alpha);
372   await unfollowRemotes(gamma);
373 });
374
375 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 () => {
376   // Unfollow all remote communities
377   let site = await unfollowRemotes(alpha);
378   expect(
379     site.my_user.follows.filter(c => c.community.local == false).length
380   ).toBe(0);
381
382   // B creates a post, and two comments, should be invisible to A
383   let postRes = await createPost(beta, 2);
384   expect(postRes.post_view.post.name).toBeDefined();
385
386   let parentCommentContent = 'An invisible top level comment from beta';
387   let parentCommentRes = await createComment(
388     beta,
389     postRes.post_view.post.id,
390     undefined,
391     parentCommentContent
392   );
393   expect(parentCommentRes.comment_view.comment.content).toBe(
394     parentCommentContent
395   );
396
397   // B creates a comment, then a child one of that.
398   let childCommentContent = 'An invisible child comment from beta';
399   let childCommentRes = await createComment(
400     beta,
401     postRes.post_view.post.id,
402     parentCommentRes.comment_view.comment.id,
403     childCommentContent
404   );
405   expect(childCommentRes.comment_view.comment.content).toBe(
406     childCommentContent
407   );
408
409   // Follow beta again
410   let follow = await followBeta(alpha);
411   expect(follow.community_view.community.local).toBe(false);
412   expect(follow.community_view.community.name).toBe('main');
413
414   // An update to the child comment on beta, should push the post, parent, and child to alpha now
415   let updatedCommentContent = 'An update child comment from beta';
416   let updateRes = await editComment(
417     beta,
418     childCommentRes.comment_view.comment.id,
419     updatedCommentContent
420   );
421   expect(updateRes.comment_view.comment.content).toBe(updatedCommentContent);
422
423   // Get the post from alpha
424   let alphaPostB = (await resolvePost(alpha, postRes.post_view.post)).post;
425
426   let alphaPost = await getPost(alpha, alphaPostB.post.id);
427   expect(alphaPost.post_view.post.name).toBeDefined();
428   assertCommentFederation(alphaPost.comments[1], parentCommentRes.comment_view);
429   assertCommentFederation(alphaPost.comments[0], updateRes.comment_view);
430   expect(alphaPost.post_view.community.local).toBe(false);
431   expect(alphaPost.post_view.creator.local).toBe(false);
432
433   await unfollowRemotes(alpha);
434 });
435
436
437 test('Report a comment', async () => {
438   let betaCommunity = (await resolveBetaCommunity(beta)).community;
439   let postRes = (await createPost(beta, betaCommunity.community.id)).post_view.post;
440   expect(postRes).toBeDefined();
441   let commentRes = (await createComment(beta, postRes.id)).comment_view.comment;
442   expect(commentRes).toBeDefined();
443
444   let alphaComment = (await resolveComment(alpha, commentRes)).comment.comment;
445   let alphaReport = (await reportComment(alpha, alphaComment.id, randomString(10)))
446         .comment_report_view.comment_report;
447
448   let betaReport = (await listCommentReports(beta)).comment_reports[0].comment_report;
449   expect(betaReport).toBeDefined();
450   expect(betaReport.resolved).toBe(false);
451   expect(betaReport.original_comment_text).toBe(alphaReport.original_comment_text);
452   expect(betaReport.reason).toBe(alphaReport.reason);
453 });