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