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