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