]> Untitled Git - lemmy.git/blob - api_tests/src/comment.spec.ts
Blank out extra info for deleted or removed content. Fixes #1679 (#1680)
[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   searchComment,
10   likeComment,
11   followBeta,
12   searchForBetaCommunity,
13   createComment,
14   editComment,
15   deleteComment,
16   removeComment,
17   getMentions,
18   searchPost,
19   unfollowRemotes,
20   createCommunity,
21   registerUser,
22   API,
23 } from './shared';
24 import { CommentView } from 'lemmy-js-client';
25
26 import { PostResponse } from 'lemmy-js-client';
27
28 let postRes: PostResponse;
29
30 beforeAll(async () => {
31   await setupLogins();
32   await followBeta(alpha);
33   await followBeta(gamma);
34   let search = await searchForBetaCommunity(alpha);
35   postRes = await createPost(
36     alpha,
37     search.communities.find(c => c.community.local == false).community.id
38   );
39 });
40
41 afterAll(async () => {
42   await unfollowRemotes(alpha);
43   await unfollowRemotes(gamma);
44 });
45
46 function assertCommentFederation(
47   commentOne: CommentView,
48   commentTwo: CommentView
49 ) {
50   expect(commentOne.comment.ap_id).toBe(commentOne.comment.ap_id);
51   expect(commentOne.comment.content).toBe(commentTwo.comment.content);
52   expect(commentOne.creator.name).toBe(commentTwo.creator.name);
53   expect(commentOne.community.actor_id).toBe(commentTwo.community.actor_id);
54   expect(commentOne.comment.published).toBe(commentTwo.comment.published);
55   expect(commentOne.comment.updated).toBe(commentOne.comment.updated);
56   expect(commentOne.comment.deleted).toBe(commentOne.comment.deleted);
57   expect(commentOne.comment.removed).toBe(commentOne.comment.removed);
58 }
59
60 test('Create a comment', async () => {
61   let commentRes = await createComment(alpha, postRes.post_view.post.id);
62   expect(commentRes.comment_view.comment.content).toBeDefined();
63   expect(commentRes.comment_view.community.local).toBe(false);
64   expect(commentRes.comment_view.creator.local).toBe(true);
65   expect(commentRes.comment_view.counts.score).toBe(1);
66
67   // Make sure that comment is liked on beta
68   let searchBeta = await searchComment(beta, commentRes.comment_view.comment);
69   let betaComment = searchBeta.comments[0];
70   expect(betaComment).toBeDefined();
71   expect(betaComment.community.local).toBe(true);
72   expect(betaComment.creator.local).toBe(false);
73   expect(betaComment.counts.score).toBe(1);
74   assertCommentFederation(betaComment, commentRes.comment_view);
75 });
76
77 test('Create a comment in a non-existent post', async () => {
78   let commentRes = await createComment(alpha, -1);
79   expect(commentRes).toStrictEqual({ error: 'couldnt_find_post' });
80 });
81
82 test('Update a comment', async () => {
83   let commentRes = await createComment(alpha, postRes.post_view.post.id);
84   // Federate the comment first
85   let searchBeta = await searchComment(beta, commentRes.comment_view.comment);
86   assertCommentFederation(searchBeta.comments[0], commentRes.comment_view);
87
88   let updateCommentRes = await editComment(
89     alpha,
90     commentRes.comment_view.comment.id
91   );
92   expect(updateCommentRes.comment_view.comment.content).toBe(
93     'A jest test federated comment update'
94   );
95   expect(updateCommentRes.comment_view.community.local).toBe(false);
96   expect(updateCommentRes.comment_view.creator.local).toBe(true);
97
98   // Make sure that post is updated on beta
99   let searchBetaUpdated = await searchComment(
100     beta,
101     commentRes.comment_view.comment
102   );
103   assertCommentFederation(
104     searchBetaUpdated.comments[0],
105     updateCommentRes.comment_view
106   );
107 });
108
109 test('Delete a comment', async () => {
110   let commentRes = await createComment(alpha, postRes.post_view.post.id);
111
112   let deleteCommentRes = await deleteComment(
113     alpha,
114     true,
115     commentRes.comment_view.comment.id
116   );
117   expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
118   expect(deleteCommentRes.comment_view.comment.content).toBe("");
119
120   // Make sure that comment is undefined on beta
121   let searchBeta = await searchComment(beta, commentRes.comment_view.comment);
122   let betaComment = searchBeta.comments[0];
123   expect(betaComment).toBeUndefined();
124
125   let undeleteCommentRes = await deleteComment(
126     alpha,
127     false,
128     commentRes.comment_view.comment.id
129   );
130   expect(undeleteCommentRes.comment_view.comment.deleted).toBe(false);
131
132   // Make sure that comment is undeleted on beta
133   let searchBeta2 = await searchComment(beta, commentRes.comment_view.comment);
134   let betaComment2 = searchBeta2.comments[0];
135   expect(betaComment2.comment.deleted).toBe(false);
136   assertCommentFederation(
137     searchBeta2.comments[0],
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 searchComment(beta, commentRes.comment_view.comment)
148   ).comments[0].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 searchBeta = await searchComment(beta, commentRes.comment_view.comment);
189   let betaComment = searchBeta.comments[0];
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 searchBeta = await searchComment(beta, commentRes.comment_view.comment);
210   let betaComment = searchBeta.comments[0];
211   expect(betaComment).toBeDefined();
212   expect(betaComment.community.local).toBe(true);
213   expect(betaComment.creator.local).toBe(false);
214   expect(betaComment.counts.score).toBe(0);
215 });
216
217 test('Federated comment like', async () => {
218   let commentRes = await createComment(alpha, postRes.post_view.post.id);
219
220   // Find the comment on beta
221   let searchBeta = await searchComment(beta, commentRes.comment_view.comment);
222   let betaComment = searchBeta.comments[0];
223
224   let like = await likeComment(beta, 1, betaComment.comment);
225   expect(like.comment_view.counts.score).toBe(2);
226
227   // Get the post from alpha, check the likes
228   let post = await getPost(alpha, postRes.post_view.post.id);
229   expect(post.comments[0].counts.score).toBe(2);
230 });
231
232 test('Reply to a comment', async () => {
233   // Create a comment on alpha, find it on beta
234   let commentRes = await createComment(alpha, postRes.post_view.post.id);
235   let searchBeta = await searchComment(beta, commentRes.comment_view.comment);
236   let betaComment = searchBeta.comments[0];
237
238   // find that comment id on beta
239
240   // Reply from beta
241   let replyRes = await createComment(
242     beta,
243     betaComment.post.id,
244     betaComment.comment.id
245   );
246   expect(replyRes.comment_view.comment.content).toBeDefined();
247   expect(replyRes.comment_view.community.local).toBe(true);
248   expect(replyRes.comment_view.creator.local).toBe(true);
249   expect(replyRes.comment_view.comment.parent_id).toBe(betaComment.comment.id);
250   expect(replyRes.comment_view.counts.score).toBe(1);
251
252   // Make sure that comment is seen on alpha
253   // TODO not sure why, but a searchComment back to alpha, for the ap_id of betas
254   // comment, isn't working.
255   // let searchAlpha = await searchComment(alpha, replyRes.comment);
256   let post = await getPost(alpha, postRes.post_view.post.id);
257   let alphaComment = post.comments[0];
258   expect(alphaComment.comment.content).toBeDefined();
259   expect(alphaComment.comment.parent_id).toBe(post.comments[1].comment.id);
260   expect(alphaComment.community.local).toBe(false);
261   expect(alphaComment.creator.local).toBe(false);
262   expect(alphaComment.counts.score).toBe(1);
263   assertCommentFederation(alphaComment, replyRes.comment_view);
264 });
265
266 test('Mention beta', async () => {
267   // Create a mention on alpha
268   let mentionContent = 'A test mention of @lemmy_beta@lemmy-beta:8551';
269   let commentRes = await createComment(alpha, postRes.post_view.post.id);
270   let mentionRes = await createComment(
271     alpha,
272     postRes.post_view.post.id,
273     commentRes.comment_view.comment.id,
274     mentionContent
275   );
276   expect(mentionRes.comment_view.comment.content).toBeDefined();
277   expect(mentionRes.comment_view.community.local).toBe(false);
278   expect(mentionRes.comment_view.creator.local).toBe(true);
279   expect(mentionRes.comment_view.counts.score).toBe(1);
280
281   let mentionsRes = await getMentions(beta);
282   expect(mentionsRes.mentions[0].comment.content).toBeDefined();
283   expect(mentionsRes.mentions[0].community.local).toBe(true);
284   expect(mentionsRes.mentions[0].creator.local).toBe(false);
285   expect(mentionsRes.mentions[0].counts.score).toBe(1);
286 });
287
288 test('Comment Search', async () => {
289   let commentRes = await createComment(alpha, postRes.post_view.post.id);
290   let searchBeta = await searchComment(beta, commentRes.comment_view.comment);
291   assertCommentFederation(searchBeta.comments[0], commentRes.comment_view);
292 });
293
294 test('A and G subscribe to B (center) A posts, G mentions B, it gets announced to A', async () => {
295   // Create a local post
296   let alphaPost = await createPost(alpha, 2);
297   expect(alphaPost.post_view.community.local).toBe(true);
298
299   // Make sure gamma sees it
300   let search = await searchPost(gamma, alphaPost.post_view.post);
301   let gammaPost = search.posts[0];
302
303   let commentContent =
304     'A jest test federated comment announce, lets mention @lemmy_beta@lemmy-beta:8551';
305   let commentRes = await createComment(
306     gamma,
307     gammaPost.post.id,
308     undefined,
309     commentContent
310   );
311   expect(commentRes.comment_view.comment.content).toBe(commentContent);
312   expect(commentRes.comment_view.community.local).toBe(false);
313   expect(commentRes.comment_view.creator.local).toBe(true);
314   expect(commentRes.comment_view.counts.score).toBe(1);
315
316   // Make sure alpha sees it
317   let alphaPost2 = await getPost(alpha, alphaPost.post_view.post.id);
318   expect(alphaPost2.comments[0].comment.content).toBe(commentContent);
319   expect(alphaPost2.comments[0].community.local).toBe(true);
320   expect(alphaPost2.comments[0].creator.local).toBe(false);
321   expect(alphaPost2.comments[0].counts.score).toBe(1);
322   assertCommentFederation(alphaPost2.comments[0], commentRes.comment_view);
323
324   // Make sure beta has mentions
325   let mentionsRes = await getMentions(beta);
326   expect(mentionsRes.mentions[0].comment.content).toBe(commentContent);
327   expect(mentionsRes.mentions[0].community.local).toBe(false);
328   expect(mentionsRes.mentions[0].creator.local).toBe(false);
329   // TODO this is failing because fetchInReplyTos aren't getting score
330   // expect(mentionsRes.mentions[0].score).toBe(1);
331 });
332
333 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 () => {
334   // Unfollow all remote communities
335   let followed = await unfollowRemotes(alpha);
336   expect(
337     followed.communities.filter(c => c.community.local == false).length
338   ).toBe(0);
339
340   // B creates a post, and two comments, should be invisible to A
341   let postRes = await createPost(beta, 2);
342   expect(postRes.post_view.post.name).toBeDefined();
343
344   let parentCommentContent = 'An invisible top level comment from beta';
345   let parentCommentRes = await createComment(
346     beta,
347     postRes.post_view.post.id,
348     undefined,
349     parentCommentContent
350   );
351   expect(parentCommentRes.comment_view.comment.content).toBe(
352     parentCommentContent
353   );
354
355   // B creates a comment, then a child one of that.
356   let childCommentContent = 'An invisible child comment from beta';
357   let childCommentRes = await createComment(
358     beta,
359     postRes.post_view.post.id,
360     parentCommentRes.comment_view.comment.id,
361     childCommentContent
362   );
363   expect(childCommentRes.comment_view.comment.content).toBe(
364     childCommentContent
365   );
366
367   // Follow beta again
368   let follow = await followBeta(alpha);
369   expect(follow.community_view.community.local).toBe(false);
370   expect(follow.community_view.community.name).toBe('main');
371
372   // An update to the child comment on beta, should push the post, parent, and child to alpha now
373   let updatedCommentContent = 'An update child comment from beta';
374   let updateRes = await editComment(
375     beta,
376     childCommentRes.comment_view.comment.id,
377     updatedCommentContent
378   );
379   expect(updateRes.comment_view.comment.content).toBe(updatedCommentContent);
380
381   // Get the post from alpha
382   let search = await searchPost(alpha, postRes.post_view.post);
383   let alphaPostB = search.posts[0];
384
385   let alphaPost = await getPost(alpha, alphaPostB.post.id);
386   expect(alphaPost.post_view.post.name).toBeDefined();
387   assertCommentFederation(alphaPost.comments[1], parentCommentRes.comment_view);
388   assertCommentFederation(alphaPost.comments[0], updateRes.comment_view);
389   expect(alphaPost.post_view.community.local).toBe(false);
390   expect(alphaPost.post_view.creator.local).toBe(false);
391
392   await unfollowRemotes(alpha);
393 });