]> Untitled Git - lemmy.git/blob - api_tests/src/post.spec.ts
532841b13fe9b383e20c700e82969529bd99285f
[lemmy.git] / api_tests / src / post.spec.ts
1 jest.setTimeout(120000);
2
3 import { CommunityView } from "lemmy-js-client/dist/types/CommunityView";
4 import {
5   alpha,
6   beta,
7   gamma,
8   delta,
9   epsilon,
10   setupLogins,
11   createPost,
12   editPost,
13   featurePost,
14   lockPost,
15   resolvePost,
16   likePost,
17   followBeta,
18   resolveBetaCommunity,
19   createComment,
20   deletePost,
21   removePost,
22   getPost,
23   unfollowRemotes,
24   resolvePerson,
25   banPersonFromSite,
26   searchPostLocal,
27   followCommunity,
28   banPersonFromCommunity,
29   reportPost,
30   listPostReports,
31   randomString,
32   registerUser,
33   API,
34   getSite,
35   unfollows,
36   resolveCommunity,
37 } from "./shared";
38 import { PostView } from "lemmy-js-client/dist/types/PostView";
39
40 let betaCommunity: CommunityView | undefined;
41
42 beforeAll(async () => {
43   await setupLogins();
44   betaCommunity = (await resolveBetaCommunity(alpha)).community;
45   expect(betaCommunity).toBeDefined();
46   await unfollows();
47 });
48
49 afterAll(async () => {
50   await unfollows();
51 });
52
53 function assertPostFederation(postOne?: PostView, postTwo?: PostView) {
54   expect(postOne?.post.ap_id).toBe(postTwo?.post.ap_id);
55   expect(postOne?.post.name).toBe(postTwo?.post.name);
56   expect(postOne?.post.body).toBe(postTwo?.post.body);
57   // TODO url clears arent working
58   // expect(postOne?.post.url).toBe(postTwo?.post.url);
59   expect(postOne?.post.nsfw).toBe(postTwo?.post.nsfw);
60   expect(postOne?.post.embed_title).toBe(postTwo?.post.embed_title);
61   expect(postOne?.post.embed_description).toBe(postTwo?.post.embed_description);
62   expect(postOne?.post.embed_video_url).toBe(postTwo?.post.embed_video_url);
63   expect(postOne?.post.published).toBe(postTwo?.post.published);
64   expect(postOne?.community.actor_id).toBe(postTwo?.community.actor_id);
65   expect(postOne?.post.locked).toBe(postTwo?.post.locked);
66   expect(postOne?.post.removed).toBe(postTwo?.post.removed);
67   expect(postOne?.post.deleted).toBe(postTwo?.post.deleted);
68 }
69
70 test("Create a post", async () => {
71   if (!betaCommunity) {
72     throw "Missing beta community";
73   }
74
75   let postRes = await createPost(alpha, betaCommunity.community.id);
76   expect(postRes.post_view.post).toBeDefined();
77   expect(postRes.post_view.community.local).toBe(false);
78   expect(postRes.post_view.creator.local).toBe(true);
79   expect(postRes.post_view.counts.score).toBe(1);
80
81   // Make sure that post is liked on beta
82   let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
83
84   expect(betaPost).toBeDefined();
85   expect(betaPost?.community.local).toBe(true);
86   expect(betaPost?.creator.local).toBe(false);
87   expect(betaPost?.counts.score).toBe(1);
88   assertPostFederation(betaPost, postRes.post_view);
89
90   // Delta only follows beta, so it should not see an alpha ap_id
91   await expect(resolvePost(delta, postRes.post_view.post)).rejects.toBe(
92     "couldnt_find_object",
93   );
94
95   // Epsilon has alpha blocked, it should not see the alpha post
96   await expect(resolvePost(epsilon, postRes.post_view.post)).rejects.toBe(
97     "couldnt_find_object",
98   );
99 });
100
101 test("Create a post in a non-existent community", async () => {
102   await expect(createPost(alpha, -2)).rejects.toBe("couldnt_find_community");
103 });
104
105 test("Unlike a post", async () => {
106   if (!betaCommunity) {
107     throw "Missing beta community";
108   }
109   let postRes = await createPost(alpha, betaCommunity.community.id);
110   let unlike = await likePost(alpha, 0, postRes.post_view.post);
111   expect(unlike.post_view.counts.score).toBe(0);
112
113   // Try to unlike it again, make sure it stays at 0
114   let unlike2 = await likePost(alpha, 0, postRes.post_view.post);
115   expect(unlike2.post_view.counts.score).toBe(0);
116
117   // Make sure that post is unliked on beta
118   let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
119   expect(betaPost).toBeDefined();
120   expect(betaPost?.community.local).toBe(true);
121   expect(betaPost?.creator.local).toBe(false);
122   expect(betaPost?.counts.score).toBe(0);
123   assertPostFederation(betaPost, postRes.post_view);
124 });
125
126 test("Update a post", async () => {
127   if (!betaCommunity) {
128     throw "Missing beta community";
129   }
130   let postRes = await createPost(alpha, betaCommunity.community.id);
131
132   let updatedName = "A jest test federated post, updated";
133   let updatedPost = await editPost(alpha, postRes.post_view.post);
134   expect(updatedPost.post_view.post.name).toBe(updatedName);
135   expect(updatedPost.post_view.community.local).toBe(false);
136   expect(updatedPost.post_view.creator.local).toBe(true);
137
138   // Make sure that post is updated on beta
139   let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
140   if (!betaPost) {
141     throw "Missing beta post";
142   }
143   expect(betaPost.community.local).toBe(true);
144   expect(betaPost.creator.local).toBe(false);
145   expect(betaPost.post.name).toBe(updatedName);
146   assertPostFederation(betaPost, updatedPost.post_view);
147
148   // Make sure lemmy beta cannot update the post
149   await expect(editPost(beta, betaPost.post)).rejects.toBe(
150     "no_post_edit_allowed",
151   );
152 });
153
154 test("Sticky a post", async () => {
155   if (!betaCommunity) {
156     throw "Missing beta community";
157   }
158   let postRes = await createPost(alpha, betaCommunity.community.id);
159
160   let betaPost1 = (await resolvePost(beta, postRes.post_view.post)).post;
161   if (!betaPost1) {
162     throw "Missing beta post1";
163   }
164   let stickiedPostRes = await featurePost(beta, true, betaPost1.post);
165   expect(stickiedPostRes.post_view.post.featured_community).toBe(true);
166
167   // Make sure that post is stickied on beta
168   let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
169   expect(betaPost?.community.local).toBe(true);
170   expect(betaPost?.creator.local).toBe(false);
171   expect(betaPost?.post.featured_community).toBe(true);
172
173   // Unsticky a post
174   let unstickiedPost = await featurePost(beta, false, betaPost1.post);
175   expect(unstickiedPost.post_view.post.featured_community).toBe(false);
176
177   // Make sure that post is unstickied on beta
178   let betaPost2 = (await resolvePost(beta, postRes.post_view.post)).post;
179   expect(betaPost2?.community.local).toBe(true);
180   expect(betaPost2?.creator.local).toBe(false);
181   expect(betaPost2?.post.featured_community).toBe(false);
182
183   // Make sure that gamma cannot sticky the post on beta
184   let gammaPost = (await resolvePost(gamma, postRes.post_view.post)).post;
185   if (!gammaPost) {
186     throw "Missing gamma post";
187   }
188   let gammaTrySticky = await featurePost(gamma, true, gammaPost.post);
189   let betaPost3 = (await resolvePost(beta, postRes.post_view.post)).post;
190   expect(gammaTrySticky.post_view.post.featured_community).toBe(true);
191   expect(betaPost3?.post.featured_community).toBe(false);
192 });
193
194 test("Lock a post", async () => {
195   if (!betaCommunity) {
196     throw "Missing beta community";
197   }
198   await followCommunity(alpha, true, betaCommunity.community.id);
199   let postRes = await createPost(alpha, betaCommunity.community.id);
200
201   // Lock the post
202   let betaPost1 = (await resolvePost(beta, postRes.post_view.post)).post;
203   if (!betaPost1) {
204     throw "Missing beta post1";
205   }
206   let lockedPostRes = await lockPost(beta, true, betaPost1.post);
207   expect(lockedPostRes.post_view.post.locked).toBe(true);
208
209   // Make sure that post is locked on alpha
210   let searchAlpha = await searchPostLocal(alpha, postRes.post_view.post);
211   let alphaPost1 = searchAlpha.posts[0];
212   expect(alphaPost1.post.locked).toBe(true);
213
214   // Try to make a new comment there, on alpha
215   await expect(createComment(alpha, alphaPost1.post.id)).rejects.toBe("locked");
216
217   // Unlock a post
218   let unlockedPost = await lockPost(beta, false, betaPost1.post);
219   expect(unlockedPost.post_view.post.locked).toBe(false);
220
221   // Make sure that post is unlocked on alpha
222   let searchAlpha2 = await searchPostLocal(alpha, postRes.post_view.post);
223   let alphaPost2 = searchAlpha2.posts[0];
224   expect(alphaPost2.community.local).toBe(false);
225   expect(alphaPost2.creator.local).toBe(true);
226   expect(alphaPost2.post.locked).toBe(false);
227
228   // Try to create a new comment, on alpha
229   let commentAlpha = await createComment(alpha, alphaPost1.post.id);
230   expect(commentAlpha).toBeDefined();
231 });
232
233 test("Delete a post", async () => {
234   if (!betaCommunity) {
235     throw "Missing beta community";
236   }
237
238   let postRes = await createPost(alpha, betaCommunity.community.id);
239   expect(postRes.post_view.post).toBeDefined();
240
241   let deletedPost = await deletePost(alpha, true, postRes.post_view.post);
242   expect(deletedPost.post_view.post.deleted).toBe(true);
243   expect(deletedPost.post_view.post.name).toBe(postRes.post_view.post.name);
244
245   // Make sure lemmy beta sees post is deleted
246   // This will be undefined because of the tombstone
247   await expect(resolvePost(beta, postRes.post_view.post)).rejects.toBe(
248     "couldnt_find_object",
249   );
250
251   // Undelete
252   let undeletedPost = await deletePost(alpha, false, postRes.post_view.post);
253   expect(undeletedPost.post_view.post.deleted).toBe(false);
254
255   // Make sure lemmy beta sees post is undeleted
256   let betaPost2 = (await resolvePost(beta, postRes.post_view.post)).post;
257   if (!betaPost2) {
258     throw "Missing beta post 2";
259   }
260   expect(betaPost2.post.deleted).toBe(false);
261   assertPostFederation(betaPost2, undeletedPost.post_view);
262
263   // Make sure lemmy beta cannot delete the post
264   await expect(deletePost(beta, true, betaPost2.post)).rejects.toBe(
265     "no_post_edit_allowed",
266   );
267 });
268
269 test("Remove a post from admin and community on different instance", async () => {
270   if (!betaCommunity) {
271     throw "Missing beta community";
272   }
273
274   let gammaCommunity = (
275     await resolveCommunity(gamma, betaCommunity.community.actor_id)
276   ).community?.community;
277   if (!gammaCommunity) {
278     throw "Missing gamma community";
279   }
280   let postRes = await createPost(gamma, gammaCommunity.id);
281
282   let alphaPost = (await resolvePost(alpha, postRes.post_view.post)).post;
283   if (!alphaPost) {
284     throw "Missing alpha post";
285   }
286   let removedPost = await removePost(alpha, true, alphaPost.post);
287   expect(removedPost.post_view.post.removed).toBe(true);
288   expect(removedPost.post_view.post.name).toBe(postRes.post_view.post.name);
289
290   // Make sure lemmy beta sees post is NOT removed
291   let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
292   if (!betaPost) {
293     throw "Missing beta post";
294   }
295   expect(betaPost.post.removed).toBe(false);
296
297   // Undelete
298   let undeletedPost = await removePost(alpha, false, alphaPost.post);
299   expect(undeletedPost.post_view.post.removed).toBe(false);
300
301   // Make sure lemmy beta sees post is undeleted
302   let betaPost2 = (await resolvePost(beta, postRes.post_view.post)).post;
303   expect(betaPost2?.post.removed).toBe(false);
304   assertPostFederation(betaPost2, undeletedPost.post_view);
305 });
306
307 test("Remove a post from admin and community on same instance", async () => {
308   if (!betaCommunity) {
309     throw "Missing beta community";
310   }
311   await followBeta(alpha);
312   let postRes = await createPost(alpha, betaCommunity.community.id);
313   expect(postRes.post_view.post).toBeDefined();
314
315   // Get the id for beta
316   let searchBeta = await searchPostLocal(beta, postRes.post_view.post);
317   let betaPost = searchBeta.posts[0];
318   expect(betaPost).toBeDefined();
319
320   // The beta admin removes it (the community lives on beta)
321   let removePostRes = await removePost(beta, true, betaPost.post);
322   expect(removePostRes.post_view.post.removed).toBe(true);
323
324   // Make sure lemmy alpha sees post is removed
325   // let alphaPost = await getPost(alpha, postRes.post_view.post.id);
326   // expect(alphaPost.post_view.post.removed).toBe(true); // TODO this shouldn't be commented
327   // assertPostFederation(alphaPost.post_view, removePostRes.post_view);
328
329   // Undelete
330   let undeletedPost = await removePost(beta, false, betaPost.post);
331   expect(undeletedPost.post_view.post.removed).toBe(false);
332
333   // Make sure lemmy alpha sees post is undeleted
334   let alphaPost2 = await getPost(alpha, postRes.post_view.post.id);
335   expect(alphaPost2.post_view.post.removed).toBe(false);
336   assertPostFederation(alphaPost2.post_view, undeletedPost.post_view);
337   await unfollowRemotes(alpha);
338 });
339
340 test("Search for a post", async () => {
341   if (!betaCommunity) {
342     throw "Missing beta community";
343   }
344   await unfollowRemotes(alpha);
345   let postRes = await createPost(alpha, betaCommunity.community.id);
346   expect(postRes.post_view.post).toBeDefined();
347
348   let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
349   expect(betaPost?.post.name).toBeDefined();
350 });
351
352 test("Enforce site ban for federated user", async () => {
353   if (!betaCommunity) {
354     throw "Missing beta community";
355   }
356   // create a test user
357   let alphaUserJwt = await registerUser(alpha);
358   expect(alphaUserJwt).toBeDefined();
359   let alpha_user: API = {
360     client: alpha.client,
361     auth: alphaUserJwt.jwt ?? "",
362   };
363   let alphaUserActorId = (await getSite(alpha_user)).my_user?.local_user_view
364     .person.actor_id;
365   if (!alphaUserActorId) {
366     throw "Missing alpha user actor id";
367   }
368   expect(alphaUserActorId).toBeDefined();
369   let alphaPerson = (await resolvePerson(alpha_user, alphaUserActorId)).person;
370   if (!alphaPerson) {
371     throw "Missing alpha person";
372   }
373   expect(alphaPerson).toBeDefined();
374
375   // alpha makes post in beta community, it federates to beta instance
376   let postRes1 = await createPost(alpha_user, betaCommunity.community.id);
377   let searchBeta1 = await searchPostLocal(beta, postRes1.post_view.post);
378   expect(searchBeta1.posts[0]).toBeDefined();
379
380   // ban alpha from its instance
381   let banAlpha = await banPersonFromSite(
382     alpha,
383     alphaPerson.person.id,
384     true,
385     true,
386   );
387   expect(banAlpha.banned).toBe(true);
388
389   // alpha ban should be federated to beta
390   let alphaUserOnBeta1 = await resolvePerson(beta, alphaUserActorId);
391   expect(alphaUserOnBeta1.person?.person.banned).toBe(true);
392
393   // existing alpha post should be removed on beta
394   let searchBeta2 = await getPost(beta, searchBeta1.posts[0].post.id);
395   expect(searchBeta2.post_view.post.removed).toBe(true);
396
397   // Unban alpha
398   let unBanAlpha = await banPersonFromSite(
399     alpha,
400     alphaPerson.person.id,
401     false,
402     false,
403   );
404   expect(unBanAlpha.banned).toBe(false);
405
406   // alpha makes new post in beta community, it federates
407   let postRes2 = await createPost(alpha_user, betaCommunity.community.id);
408   let searchBeta3 = await searchPostLocal(beta, postRes2.post_view.post);
409   expect(searchBeta3.posts[0]).toBeDefined();
410
411   let alphaUserOnBeta2 = await resolvePerson(beta, alphaUserActorId);
412   expect(alphaUserOnBeta2.person?.person.banned).toBe(false);
413 });
414
415 test.skip("Enforce community ban for federated user", async () => {
416   if (!betaCommunity) {
417     throw "Missing beta community";
418   }
419   let alphaShortname = `@lemmy_alpha@lemmy-alpha:8541`;
420   let alphaPerson = (await resolvePerson(beta, alphaShortname)).person;
421   if (!alphaPerson) {
422     throw "Missing alpha person";
423   }
424   expect(alphaPerson).toBeDefined();
425
426   // make a post in beta, it goes through
427   let postRes1 = await createPost(alpha, betaCommunity.community.id);
428   let searchBeta1 = await searchPostLocal(beta, postRes1.post_view.post);
429   expect(searchBeta1.posts[0]).toBeDefined();
430
431   // ban alpha from beta community
432   let banAlpha = await banPersonFromCommunity(
433     beta,
434     alphaPerson.person.id,
435     2,
436     true,
437     true,
438   );
439   expect(banAlpha.banned).toBe(true);
440
441   // ensure that the post by alpha got removed
442   await expect(getPost(alpha, searchBeta1.posts[0].post.id)).rejects.toBe(
443     "unknown",
444   );
445
446   // Alpha tries to make post on beta, but it fails because of ban
447   await expect(createPost(alpha, betaCommunity.community.id)).rejects.toBe(
448     "banned_from_community",
449   );
450
451   // Unban alpha
452   let unBanAlpha = await banPersonFromCommunity(
453     beta,
454     alphaPerson.person.id,
455     2,
456     false,
457     false,
458   );
459   expect(unBanAlpha.banned).toBe(false);
460   let postRes3 = await createPost(alpha, betaCommunity.community.id);
461   expect(postRes3.post_view.post).toBeDefined();
462   expect(postRes3.post_view.community.local).toBe(false);
463   expect(postRes3.post_view.creator.local).toBe(true);
464   expect(postRes3.post_view.counts.score).toBe(1);
465
466   // Make sure that post makes it to beta community
467   let searchBeta2 = await searchPostLocal(beta, postRes3.post_view.post);
468   expect(searchBeta2.posts[0]).toBeDefined();
469 });
470
471 test("A and G subscribe to B (center) A posts, it gets announced to G", async () => {
472   if (!betaCommunity) {
473     throw "Missing beta community";
474   }
475   let postRes = await createPost(alpha, betaCommunity.community.id);
476   expect(postRes.post_view.post).toBeDefined();
477
478   let betaPost = (await resolvePost(gamma, postRes.post_view.post)).post;
479   expect(betaPost?.post.name).toBeDefined();
480 });
481
482 test("Report a post", async () => {
483   // Note, this is a different one from the setup
484   let betaCommunity = (await resolveBetaCommunity(beta)).community;
485   if (!betaCommunity) {
486     throw "Missing beta community";
487   }
488   let postRes = await createPost(beta, betaCommunity.community.id);
489   expect(postRes.post_view.post).toBeDefined();
490
491   let alphaPost = (await resolvePost(alpha, postRes.post_view.post)).post;
492   if (!alphaPost) {
493     throw "Missing alpha post";
494   }
495   let alphaReport = (
496     await reportPost(alpha, alphaPost.post.id, randomString(10))
497   ).post_report_view.post_report;
498
499   let betaReport = (await listPostReports(beta)).post_reports[0].post_report;
500   expect(betaReport).toBeDefined();
501   expect(betaReport.resolved).toBe(false);
502   expect(betaReport.original_post_name).toBe(alphaReport.original_post_name);
503   expect(betaReport.original_post_url).toBe(alphaReport.original_post_url);
504   expect(betaReport.original_post_body).toBe(alphaReport.original_post_body);
505   expect(betaReport.reason).toBe(alphaReport.reason);
506 });