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