1 jest.setTimeout(180000);
3 import { PostResponse } from "lemmy-js-client/dist/types/PostResponse";
34 import { CommentView } from "lemmy-js-client/dist/types/CommentView";
36 let postRes: PostResponse;
38 beforeAll(async () => {
41 await followBeta(alpha);
42 await followBeta(gamma);
43 let betaCommunity = (await resolveBetaCommunity(alpha)).community;
45 postRes = await createPost(alpha, betaCommunity.community.id);
49 afterAll(async () => {
53 function assertCommentFederation(
54 commentOne?: CommentView,
55 commentTwo?: CommentView,
57 expect(commentOne?.comment.ap_id).toBe(commentTwo?.comment.ap_id);
58 expect(commentOne?.comment.content).toBe(commentTwo?.comment.content);
59 expect(commentOne?.creator.name).toBe(commentTwo?.creator.name);
60 expect(commentOne?.community.actor_id).toBe(commentTwo?.community.actor_id);
61 expect(commentOne?.comment.published).toBe(commentTwo?.comment.published);
62 expect(commentOne?.comment.updated).toBe(commentOne?.comment.updated);
63 expect(commentOne?.comment.deleted).toBe(commentOne?.comment.deleted);
64 expect(commentOne?.comment.removed).toBe(commentOne?.comment.removed);
67 test("Create a comment", async () => {
68 let commentRes = await createComment(alpha, postRes.post_view.post.id);
69 expect(commentRes.comment_view.comment.content).toBeDefined();
70 expect(commentRes.comment_view.community.local).toBe(false);
71 expect(commentRes.comment_view.creator.local).toBe(true);
72 expect(commentRes.comment_view.counts.score).toBe(1);
74 // Make sure that comment is liked on beta
76 await resolveComment(beta, commentRes.comment_view.comment)
78 expect(betaComment).toBeDefined();
79 expect(betaComment?.community.local).toBe(true);
80 expect(betaComment?.creator.local).toBe(false);
81 expect(betaComment?.counts.score).toBe(1);
82 assertCommentFederation(betaComment, commentRes.comment_view);
85 test("Create a comment in a non-existent post", async () => {
86 let commentRes = (await createComment(alpha, -1)) as any;
87 expect(commentRes.error).toBe("couldnt_find_post");
90 test("Update a comment", async () => {
91 let commentRes = await createComment(alpha, postRes.post_view.post.id);
92 // Federate the comment first
94 await resolveComment(beta, commentRes.comment_view.comment)
96 assertCommentFederation(betaComment, commentRes.comment_view);
98 let updateCommentRes = await editComment(
100 commentRes.comment_view.comment.id,
102 expect(updateCommentRes.comment_view.comment.content).toBe(
103 "A jest test federated comment update",
105 expect(updateCommentRes.comment_view.community.local).toBe(false);
106 expect(updateCommentRes.comment_view.creator.local).toBe(true);
108 // Make sure that post is updated on beta
109 let betaCommentUpdated = (
110 await resolveComment(beta, commentRes.comment_view.comment)
112 assertCommentFederation(betaCommentUpdated, updateCommentRes.comment_view);
115 test("Delete a comment", async () => {
116 let commentRes = await createComment(alpha, postRes.post_view.post.id);
118 let deleteCommentRes = await deleteComment(
121 commentRes.comment_view.comment.id,
123 expect(deleteCommentRes.comment_view.comment.deleted).toBe(true);
125 // Make sure that comment is undefined on beta
126 let betaCommentRes = (await resolveComment(
128 commentRes.comment_view.comment,
130 expect(betaCommentRes.error).toBe("couldnt_find_object");
132 let undeleteCommentRes = await deleteComment(
135 commentRes.comment_view.comment.id,
137 expect(undeleteCommentRes.comment_view.comment.deleted).toBe(false);
139 // Make sure that comment is undeleted on beta
141 await resolveComment(beta, commentRes.comment_view.comment)
143 expect(betaComment2?.comment.deleted).toBe(false);
144 assertCommentFederation(betaComment2, undeleteCommentRes.comment_view);
147 test("Remove a comment from admin and community on the same instance", async () => {
148 let commentRes = await createComment(alpha, postRes.post_view.post.id);
150 // Get the id for beta
151 let betaCommentId = (
152 await resolveComment(beta, commentRes.comment_view.comment)
153 ).comment?.comment.id;
155 if (!betaCommentId) {
156 throw "beta comment id is missing";
159 // The beta admin removes it (the community lives on beta)
160 let removeCommentRes = await removeComment(beta, true, betaCommentId);
161 expect(removeCommentRes.comment_view.comment.removed).toBe(true);
163 // Make sure that comment is removed on alpha (it gets pushed since an admin from beta removed it)
164 let refetchedPostComments = await getPersonDetails(
166 commentRes.comment_view.comment.creator_id,
168 console.log(refetchedPostComments.comments[0].comment);
169 expect(refetchedPostComments.comments[0].comment.removed).toBe(true);
171 let unremoveCommentRes = await removeComment(beta, false, betaCommentId);
172 expect(unremoveCommentRes.comment_view.comment.removed).toBe(false);
174 // Make sure that comment is unremoved on beta
175 let refetchedPostComments2 = await getComments(
177 postRes.post_view.post.id,
179 expect(refetchedPostComments2.comments[0].comment.removed).toBe(false);
180 assertCommentFederation(
181 refetchedPostComments2.comments[0],
182 unremoveCommentRes.comment_view,
186 test("Remove a comment from admin and community on different instance", async () => {
187 let alpha_user = await registerUser(alpha);
188 let newAlphaApi: API = {
189 client: alpha.client,
190 auth: alpha_user.jwt ?? "",
193 // New alpha user creates a community, post, and comment.
194 let newCommunity = await createCommunity(newAlphaApi);
195 let newPost = await createPost(
197 newCommunity.community_view.community.id,
199 let commentRes = await createComment(newAlphaApi, newPost.post_view.post.id);
200 expect(commentRes.comment_view.comment.content).toBeDefined();
202 // Beta searches that to cache it, then removes it
204 await resolveComment(beta, commentRes.comment_view.comment)
208 throw "beta comment missing";
211 let removeCommentRes = await removeComment(
214 betaComment.comment.id,
216 expect(removeCommentRes.comment_view.comment.removed).toBe(true);
218 // Make sure its not removed on alpha
219 let refetchedPostComments = await getComments(
221 newPost.post_view.post.id,
223 expect(refetchedPostComments.comments[0].comment.removed).toBe(false);
224 assertCommentFederation(
225 refetchedPostComments.comments[0],
226 commentRes.comment_view,
230 test("Unlike a comment", async () => {
231 let commentRes = await createComment(alpha, postRes.post_view.post.id);
232 let unlike = await likeComment(alpha, 0, commentRes.comment_view.comment);
233 expect(unlike.comment_view.counts.score).toBe(0);
235 // Make sure that post is unliked on beta
237 await resolveComment(beta, commentRes.comment_view.comment)
239 expect(betaComment).toBeDefined();
240 expect(betaComment?.community.local).toBe(true);
241 expect(betaComment?.creator.local).toBe(false);
242 expect(betaComment?.counts.score).toBe(0);
245 test("Federated comment like", async () => {
246 let commentRes = await createComment(alpha, postRes.post_view.post.id);
248 // Find the comment on beta
250 await resolveComment(beta, commentRes.comment_view.comment)
254 throw "Missing beta comment";
257 let like = await likeComment(beta, 1, betaComment.comment);
258 expect(like.comment_view.counts.score).toBe(2);
260 // Get the post from alpha, check the likes
261 let postComments = await getComments(alpha, postRes.post_view.post.id);
262 expect(postComments.comments[0].counts.score).toBe(2);
265 test("Reply to a comment", async () => {
266 // Create a comment on alpha, find it on beta
267 let commentRes = await createComment(alpha, postRes.post_view.post.id);
269 await resolveComment(beta, commentRes.comment_view.comment)
273 throw "Missing beta comment";
276 // find that comment id on beta
279 let replyRes = await createComment(
282 betaComment.comment.id,
284 expect(replyRes.comment_view.comment.content).toBeDefined();
285 expect(replyRes.comment_view.community.local).toBe(true);
286 expect(replyRes.comment_view.creator.local).toBe(true);
287 expect(getCommentParentId(replyRes.comment_view.comment)).toBe(
288 betaComment.comment.id,
290 expect(replyRes.comment_view.counts.score).toBe(1);
292 // Make sure that comment is seen on alpha
293 // TODO not sure why, but a searchComment back to alpha, for the ap_id of betas
294 // comment, isn't working.
295 // let searchAlpha = await searchComment(alpha, replyRes.comment);
296 let postComments = await getComments(alpha, postRes.post_view.post.id);
297 let alphaComment = postComments.comments[0];
298 expect(alphaComment.comment.content).toBeDefined();
299 expect(getCommentParentId(alphaComment.comment)).toBe(
300 postComments.comments[1].comment.id,
302 expect(alphaComment.community.local).toBe(false);
303 expect(alphaComment.creator.local).toBe(false);
304 expect(alphaComment.counts.score).toBe(1);
305 assertCommentFederation(alphaComment, replyRes.comment_view);
308 test("Mention beta", async () => {
309 // Create a mention on alpha
310 let mentionContent = "A test mention of @lemmy_beta@lemmy-beta:8551";
311 let commentRes = await createComment(alpha, postRes.post_view.post.id);
312 let mentionRes = await createComment(
314 postRes.post_view.post.id,
315 commentRes.comment_view.comment.id,
318 expect(mentionRes.comment_view.comment.content).toBeDefined();
319 expect(mentionRes.comment_view.community.local).toBe(false);
320 expect(mentionRes.comment_view.creator.local).toBe(true);
321 expect(mentionRes.comment_view.counts.score).toBe(1);
323 let mentionsRes = await getMentions(beta);
324 expect(mentionsRes.mentions[0].comment.content).toBeDefined();
325 expect(mentionsRes.mentions[0].community.local).toBe(true);
326 expect(mentionsRes.mentions[0].creator.local).toBe(false);
327 expect(mentionsRes.mentions[0].counts.score).toBe(1);
330 test("Comment Search", async () => {
331 let commentRes = await createComment(alpha, postRes.post_view.post.id);
333 await resolveComment(beta, commentRes.comment_view.comment)
335 assertCommentFederation(betaComment, commentRes.comment_view);
338 test("A and G subscribe to B (center) A posts, G mentions B, it gets announced to A", async () => {
339 // Create a local post
340 let alphaCommunity = (await resolveCommunity(alpha, "!main@lemmy-alpha:8541"))
343 if (!alphaCommunity) {
344 throw "Missing alpha community";
347 let alphaPost = await createPost(alpha, alphaCommunity.community.id);
348 expect(alphaPost.post_view.community.local).toBe(true);
350 // Make sure gamma sees it
351 let gammaPost = (await resolvePost(gamma, alphaPost.post_view.post)).post;
354 throw "Missing gamma post";
358 "A jest test federated comment announce, lets mention @lemmy_beta@lemmy-beta:8551";
359 let commentRes = await createComment(
365 expect(commentRes.comment_view.comment.content).toBe(commentContent);
366 expect(commentRes.comment_view.community.local).toBe(false);
367 expect(commentRes.comment_view.creator.local).toBe(true);
368 expect(commentRes.comment_view.counts.score).toBe(1);
370 // Make sure alpha sees it
371 let alphaPostComments2 = await getComments(
373 alphaPost.post_view.post.id,
375 expect(alphaPostComments2.comments[0].comment.content).toBe(commentContent);
376 expect(alphaPostComments2.comments[0].community.local).toBe(true);
377 expect(alphaPostComments2.comments[0].creator.local).toBe(false);
378 expect(alphaPostComments2.comments[0].counts.score).toBe(1);
379 assertCommentFederation(
380 alphaPostComments2.comments[0],
381 commentRes.comment_view,
384 // Make sure beta has mentions
385 let mentionsRes = await getMentions(beta);
386 expect(mentionsRes.mentions[0].comment.content).toBe(commentContent);
387 expect(mentionsRes.mentions[0].community.local).toBe(false);
388 expect(mentionsRes.mentions[0].creator.local).toBe(false);
389 // TODO this is failing because fetchInReplyTos aren't getting score
390 // expect(mentionsRes.mentions[0].score).toBe(1);
393 test("Check that activity from another instance is sent to third instance", async () => {
394 // Alpha and gamma users follow beta community
395 let alphaFollow = await followBeta(alpha);
396 expect(alphaFollow.community_view.community.local).toBe(false);
397 expect(alphaFollow.community_view.community.name).toBe("main");
399 let gammaFollow = await followBeta(gamma);
400 expect(gammaFollow.community_view.community.local).toBe(false);
401 expect(gammaFollow.community_view.community.name).toBe("main");
403 // Create a post on beta
404 let betaPost = await createPost(beta, 2);
405 expect(betaPost.post_view.community.local).toBe(true);
407 // Make sure gamma and alpha see it
408 let gammaPost = (await resolvePost(gamma, betaPost.post_view.post)).post;
410 throw "Missing gamma post";
412 expect(gammaPost.post).toBeDefined();
414 let alphaPost = (await resolvePost(alpha, betaPost.post_view.post)).post;
416 throw "Missing alpha post";
418 expect(alphaPost.post).toBeDefined();
420 // The bug: gamma comments, and alpha should see it.
421 let commentContent = "Comment from gamma";
422 let commentRes = await createComment(
428 expect(commentRes.comment_view.comment.content).toBe(commentContent);
429 expect(commentRes.comment_view.community.local).toBe(false);
430 expect(commentRes.comment_view.creator.local).toBe(true);
431 expect(commentRes.comment_view.counts.score).toBe(1);
433 // Make sure alpha sees it
434 let alphaPostComments2 = await getComments(alpha, alphaPost.post.id);
435 expect(alphaPostComments2.comments[0].comment.content).toBe(commentContent);
436 expect(alphaPostComments2.comments[0].community.local).toBe(false);
437 expect(alphaPostComments2.comments[0].creator.local).toBe(false);
438 expect(alphaPostComments2.comments[0].counts.score).toBe(1);
439 assertCommentFederation(
440 alphaPostComments2.comments[0],
441 commentRes.comment_view,
444 await unfollowRemotes(alpha);
445 await unfollowRemotes(gamma);
448 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 () => {
449 // Unfollow all remote communities
450 let site = await unfollowRemotes(alpha);
452 site.my_user?.follows.filter(c => c.community.local == false).length,
455 // B creates a post, and two comments, should be invisible to A
456 let postRes = await createPost(beta, 2);
457 expect(postRes.post_view.post.name).toBeDefined();
459 let parentCommentContent = "An invisible top level comment from beta";
460 let parentCommentRes = await createComment(
462 postRes.post_view.post.id,
464 parentCommentContent,
466 expect(parentCommentRes.comment_view.comment.content).toBe(
467 parentCommentContent,
470 // B creates a comment, then a child one of that.
471 let childCommentContent = "An invisible child comment from beta";
472 let childCommentRes = await createComment(
474 postRes.post_view.post.id,
475 parentCommentRes.comment_view.comment.id,
478 expect(childCommentRes.comment_view.comment.content).toBe(
483 let follow = await followBeta(alpha);
484 expect(follow.community_view.community.local).toBe(false);
485 expect(follow.community_view.community.name).toBe("main");
487 // An update to the child comment on beta, should push the post, parent, and child to alpha now
488 let updatedCommentContent = "An update child comment from beta";
489 let updateRes = await editComment(
491 childCommentRes.comment_view.comment.id,
492 updatedCommentContent,
494 expect(updateRes.comment_view.comment.content).toBe(updatedCommentContent);
496 // Get the post from alpha
497 let alphaPostB = (await resolvePost(alpha, postRes.post_view.post)).post;
499 throw "Missing alpha post B";
502 let alphaPost = await getPost(alpha, alphaPostB.post.id);
503 let alphaPostComments = await getComments(alpha, alphaPostB.post.id);
504 expect(alphaPost.post_view.post.name).toBeDefined();
505 assertCommentFederation(
506 alphaPostComments.comments[1],
507 parentCommentRes.comment_view,
509 assertCommentFederation(
510 alphaPostComments.comments[0],
511 updateRes.comment_view,
513 expect(alphaPost.post_view.community.local).toBe(false);
514 expect(alphaPost.post_view.creator.local).toBe(false);
516 await unfollowRemotes(alpha);
519 test("Report a comment", async () => {
520 let betaCommunity = (await resolveBetaCommunity(beta)).community;
521 if (!betaCommunity) {
522 throw "Missing beta community";
524 let postRes = (await createPost(beta, betaCommunity.community.id)).post_view
526 expect(postRes).toBeDefined();
527 let commentRes = (await createComment(beta, postRes.id)).comment_view.comment;
528 expect(commentRes).toBeDefined();
530 let alphaComment = (await resolveComment(alpha, commentRes)).comment?.comment;
532 throw "Missing alpha comment";
536 await reportComment(alpha, alphaComment.id, randomString(10))
537 ).comment_report_view.comment_report;
539 let betaReport = (await listCommentReports(beta)).comment_reports[0]
541 expect(betaReport).toBeDefined();
542 expect(betaReport.resolved).toBe(false);
543 expect(betaReport.original_comment_text).toBe(
544 alphaReport.original_comment_text,
546 expect(betaReport.reason).toBe(alphaReport.reason);