fa8171eabc4f5495a865ce72bd15993571138d3b
[akkoma] / test / pleroma / web / activity_pub / side_effects_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
6 use Oban.Testing, repo: Pleroma.Repo
7 use Pleroma.DataCase
8
9 alias Pleroma.Activity
10 alias Pleroma.Notification
11 alias Pleroma.Object
12 alias Pleroma.Repo
13 alias Pleroma.Tests.ObanHelpers
14 alias Pleroma.User
15 alias Pleroma.Web.ActivityPub.ActivityPub
16 alias Pleroma.Web.ActivityPub.Builder
17 alias Pleroma.Web.ActivityPub.SideEffects
18 alias Pleroma.Web.ActivityPub.Utils
19 alias Pleroma.Web.CommonAPI
20
21 import Mock
22 import Pleroma.Factory
23
24 describe "handle_after_transaction" do
25 test "it streams out notifications and streams" do
26 author = insert(:user, local: true)
27 recipient = insert(:user, local: true)
28
29 {:ok, note_data, _meta} =
30 Builder.note(%Pleroma.Web.CommonAPI.ActivityDraft{
31 user: author,
32 to: [recipient.ap_id],
33 mentions: [recipient],
34 content_html: "hey",
35 extra: %{"id" => Utils.generate_object_id()}
36 })
37
38 {:ok, create_activity_data, _meta} =
39 Builder.create(author, note_data["id"], [recipient.ap_id])
40
41 {:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
42
43 {:ok, _create_activity, meta} =
44 SideEffects.handle(create_activity, local: false, object_data: note_data)
45
46 assert [notification] = meta[:notifications]
47
48 with_mocks([
49 {
50 Pleroma.Web.Streamer,
51 [],
52 [
53 stream: fn _, _ -> nil end
54 ]
55 },
56 {
57 Pleroma.Web.Push,
58 [],
59 [
60 send: fn _ -> nil end
61 ]
62 }
63 ]) do
64 SideEffects.handle_after_transaction(meta)
65
66 assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
67 assert called(Pleroma.Web.Push.send(notification))
68 end
69 end
70 end
71
72 describe "blocking users" do
73 setup do
74 user = insert(:user)
75 blocked = insert(:user)
76 User.follow(blocked, user)
77 User.follow(user, blocked)
78
79 {:ok, block_data, []} = Builder.block(user, blocked)
80 {:ok, block, _meta} = ActivityPub.persist(block_data, local: true)
81
82 %{user: user, blocked: blocked, block: block}
83 end
84
85 test "it unfollows and blocks", %{user: user, blocked: blocked, block: block} do
86 assert User.following?(user, blocked)
87 assert User.following?(blocked, user)
88
89 {:ok, _, _} = SideEffects.handle(block)
90
91 refute User.following?(user, blocked)
92 refute User.following?(blocked, user)
93 assert User.blocks?(user, blocked)
94 end
95
96 test "it updates following relationship", %{user: user, blocked: blocked, block: block} do
97 {:ok, _, _} = SideEffects.handle(block)
98
99 refute Pleroma.FollowingRelationship.get(user, blocked)
100 assert User.get_follow_state(user, blocked) == nil
101 assert User.get_follow_state(blocked, user) == nil
102 assert User.get_follow_state(user, blocked, nil) == nil
103 assert User.get_follow_state(blocked, user, nil) == nil
104 end
105
106 test "it blocks but does not unfollow if the relevant setting is set", %{
107 user: user,
108 blocked: blocked,
109 block: block
110 } do
111 clear_config([:activitypub, :unfollow_blocked], false)
112 assert User.following?(user, blocked)
113 assert User.following?(blocked, user)
114
115 {:ok, _, _} = SideEffects.handle(block)
116
117 refute User.following?(user, blocked)
118 assert User.following?(blocked, user)
119 assert User.blocks?(user, blocked)
120 end
121 end
122
123 describe "update users" do
124 setup do
125 user = insert(:user, local: false)
126
127 {:ok, update_data, []} =
128 Builder.update(user, %{"id" => user.ap_id, "type" => "Person", "name" => "new name!"})
129
130 {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
131
132 %{user: user, update_data: update_data, update: update}
133 end
134
135 test "it updates the user", %{user: user, update: update} do
136 {:ok, _, _} = SideEffects.handle(update)
137 user = User.get_by_id(user.id)
138 assert user.name == "new name!"
139 end
140
141 test "it uses a given changeset to update", %{user: user, update: update} do
142 changeset = Ecto.Changeset.change(user, %{default_scope: "direct"})
143
144 assert user.default_scope == "public"
145 {:ok, _, _} = SideEffects.handle(update, user_update_changeset: changeset)
146 user = User.get_by_id(user.id)
147 assert user.default_scope == "direct"
148 end
149 end
150
151 describe "update notes" do
152 setup do
153 make_time = fn ->
154 Pleroma.Web.ActivityPub.Utils.make_date()
155 end
156
157 user = insert(:user)
158 note = insert(:note, user: user, data: %{"published" => make_time.()})
159 _note_activity = insert(:note_activity, note: note)
160
161 updated_note =
162 note.data
163 |> Map.put("summary", "edited summary")
164 |> Map.put("content", "edited content")
165 |> Map.put("updated", make_time.())
166
167 {:ok, update_data, []} = Builder.update(user, updated_note)
168 {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
169
170 %{
171 user: user,
172 note: note,
173 object_id: note.id,
174 update_data: update_data,
175 update: update,
176 updated_note: updated_note
177 }
178 end
179
180 test "it updates the note", %{
181 object_id: object_id,
182 update: update,
183 updated_note: updated_note
184 } do
185 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
186 updated_time = updated_note["updated"]
187
188 new_note = Pleroma.Object.get_by_id(object_id)
189
190 assert %{
191 "summary" => "edited summary",
192 "content" => "edited content",
193 "updated" => ^updated_time
194 } = new_note.data
195 end
196
197 test "it rejects updates with no updated attribute in object", %{
198 object_id: object_id,
199 update: update,
200 updated_note: updated_note
201 } do
202 old_note = Pleroma.Object.get_by_id(object_id)
203 updated_note = Map.drop(updated_note, ["updated"])
204 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
205 new_note = Pleroma.Object.get_by_id(object_id)
206 assert old_note.data == new_note.data
207 end
208
209 test "it rejects updates with updated attribute older than what we have in the original object",
210 %{
211 object_id: object_id,
212 update: update,
213 updated_note: updated_note
214 } do
215 old_note = Pleroma.Object.get_by_id(object_id)
216 {:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
217
218 updated_note =
219 Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, -10)))
220
221 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
222 new_note = Pleroma.Object.get_by_id(object_id)
223 assert old_note.data == new_note.data
224 end
225
226 test "it rejects updates with updated attribute older than the last Update", %{
227 object_id: object_id,
228 update: update,
229 updated_note: updated_note
230 } do
231 old_note = Pleroma.Object.get_by_id(object_id)
232 {:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
233
234 updated_note =
235 Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, +10)))
236
237 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
238
239 old_note = Pleroma.Object.get_by_id(object_id)
240 {:ok, update_time, _} = DateTime.from_iso8601(old_note.data["updated"])
241
242 updated_note =
243 Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(update_time, -5)))
244
245 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
246
247 new_note = Pleroma.Object.get_by_id(object_id)
248 assert old_note.data == new_note.data
249 end
250
251 test "it updates using object_data", %{
252 object_id: object_id,
253 update: update,
254 updated_note: updated_note
255 } do
256 updated_note = Map.put(updated_note, "summary", "mew mew")
257 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
258 new_note = Pleroma.Object.get_by_id(object_id)
259 assert %{"summary" => "mew mew", "content" => "edited content"} = new_note.data
260 end
261
262 test "it records the original note in formerRepresentations", %{
263 note: note,
264 object_id: object_id,
265 update: update,
266 updated_note: updated_note
267 } do
268 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
269 %{data: new_note} = Pleroma.Object.get_by_id(object_id)
270 assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
271
272 assert [Map.drop(note.data, ["id", "formerRepresentations"])] ==
273 new_note["formerRepresentations"]["orderedItems"]
274
275 assert new_note["formerRepresentations"]["totalItems"] == 1
276 end
277
278 test "it puts the original note at the front of formerRepresentations", %{
279 user: user,
280 note: note,
281 object_id: object_id,
282 update: update,
283 updated_note: updated_note
284 } do
285 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
286 %{data: first_edit} = Pleroma.Object.get_by_id(object_id)
287
288 second_updated_note =
289 note.data
290 |> Map.put("summary", "edited summary 2")
291 |> Map.put("content", "edited content 2")
292 |> Map.put(
293 "updated",
294 first_edit["updated"]
295 |> DateTime.from_iso8601()
296 |> elem(1)
297 |> DateTime.add(10)
298 |> DateTime.to_iso8601()
299 )
300
301 {:ok, second_update_data, []} = Builder.update(user, second_updated_note)
302 {:ok, update, _meta} = ActivityPub.persist(second_update_data, local: true)
303 {:ok, _, _} = SideEffects.handle(update, object_data: second_updated_note)
304 %{data: new_note} = Pleroma.Object.get_by_id(object_id)
305 assert %{"summary" => "edited summary 2", "content" => "edited content 2"} = new_note
306
307 original_version = Map.drop(note.data, ["id", "formerRepresentations"])
308 first_edit = Map.drop(first_edit, ["id", "formerRepresentations"])
309
310 assert [first_edit, original_version] ==
311 new_note["formerRepresentations"]["orderedItems"]
312
313 assert new_note["formerRepresentations"]["totalItems"] == 2
314 end
315
316 test "it does not prepend to formerRepresentations if no actual changes are made", %{
317 note: note,
318 object_id: object_id,
319 update: update,
320 updated_note: updated_note
321 } do
322 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
323 %{data: first_edit} = Pleroma.Object.get_by_id(object_id)
324
325 updated_note =
326 updated_note
327 |> Map.put(
328 "updated",
329 first_edit["updated"]
330 |> DateTime.from_iso8601()
331 |> elem(1)
332 |> DateTime.add(10)
333 |> DateTime.to_iso8601()
334 )
335
336 {:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
337 %{data: new_note} = Pleroma.Object.get_by_id(object_id)
338 assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
339
340 original_version = Map.drop(note.data, ["id", "formerRepresentations"])
341
342 assert [original_version] ==
343 new_note["formerRepresentations"]["orderedItems"]
344
345 assert new_note["formerRepresentations"]["totalItems"] == 1
346 end
347 end
348
349 describe "update questions" do
350 setup do
351 user = insert(:user)
352
353 question =
354 insert(:question,
355 user: user,
356 data: %{"published" => Pleroma.Web.ActivityPub.Utils.make_date()}
357 )
358
359 %{user: user, data: question.data, id: question.id}
360 end
361
362 test "allows updating choice count without generating edit history", %{
363 user: user,
364 data: data,
365 id: id
366 } do
367 new_choices =
368 data["oneOf"]
369 |> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
370
371 updated_question =
372 data
373 |> Map.put("oneOf", new_choices)
374 |> Map.put("updated", Pleroma.Web.ActivityPub.Utils.make_date())
375
376 {:ok, update_data, []} = Builder.update(user, updated_question)
377 {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
378
379 {:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
380
381 %{data: new_question} = Pleroma.Object.get_by_id(id)
382
383 assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
384 new_question["oneOf"]
385
386 refute Map.has_key?(new_question, "formerRepresentations")
387 end
388
389 test "allows updating choice count without updated field", %{
390 user: user,
391 data: data,
392 id: id
393 } do
394 new_choices =
395 data["oneOf"]
396 |> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
397
398 updated_question =
399 data
400 |> Map.put("oneOf", new_choices)
401
402 {:ok, update_data, []} = Builder.update(user, updated_question)
403 {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
404
405 {:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
406
407 %{data: new_question} = Pleroma.Object.get_by_id(id)
408
409 assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
410 new_question["oneOf"]
411
412 refute Map.has_key?(new_question, "formerRepresentations")
413 end
414
415 test "allows updating choice count with updated field same as the creation date", %{
416 user: user,
417 data: data,
418 id: id
419 } do
420 new_choices =
421 data["oneOf"]
422 |> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
423
424 updated_question =
425 data
426 |> Map.put("oneOf", new_choices)
427 |> Map.put("updated", data["published"])
428
429 {:ok, update_data, []} = Builder.update(user, updated_question)
430 {:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
431
432 {:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
433
434 %{data: new_question} = Pleroma.Object.get_by_id(id)
435
436 assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
437 new_question["oneOf"]
438
439 refute Map.has_key?(new_question, "formerRepresentations")
440 end
441 end
442
443 describe "EmojiReact objects" do
444 setup do
445 poster = insert(:user)
446 user = insert(:user)
447
448 {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
449
450 {:ok, emoji_react_data, []} = Builder.emoji_react(user, post.object, "👌")
451 {:ok, emoji_react, _meta} = ActivityPub.persist(emoji_react_data, local: true)
452
453 %{emoji_react: emoji_react, user: user, poster: poster}
454 end
455
456 test "adds the reaction to the object", %{emoji_react: emoji_react, user: user} do
457 {:ok, emoji_react, _} = SideEffects.handle(emoji_react)
458 object = Object.get_by_ap_id(emoji_react.data["object"])
459
460 assert object.data["reaction_count"] == 1
461 assert ["👌", [user.ap_id], nil] in object.data["reactions"]
462 end
463
464 test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
465 {:ok, emoji_react, _} = SideEffects.handle(emoji_react)
466 assert Repo.get_by(Notification, user_id: poster.id, activity_id: emoji_react.id)
467 end
468 end
469
470 describe "Question objects" do
471 setup do
472 user = insert(:user)
473 question = build(:question, user: user)
474 question_activity = build(:question_activity, question: question)
475 activity_data = Map.put(question_activity.data, "object", question.data["id"])
476 meta = [object_data: question.data, local: false]
477
478 {:ok, activity, meta} = ActivityPub.persist(activity_data, meta)
479
480 %{activity: activity, meta: meta}
481 end
482
483 test "enqueues the poll end", %{activity: activity, meta: meta} do
484 {:ok, activity, meta} = SideEffects.handle(activity, meta)
485
486 assert_enqueued(
487 worker: Pleroma.Workers.PollWorker,
488 args: %{op: "poll_end", activity_id: activity.id},
489 scheduled_at: NaiveDateTime.from_iso8601!(meta[:object_data]["closed"])
490 )
491 end
492 end
493
494 describe "delete users with confirmation pending" do
495 setup do
496 user = insert(:user, is_confirmed: false)
497 {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
498 {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
499 {:ok, delete: delete_user, user: user}
500 end
501
502 test "when activation is required", %{delete: delete, user: user} do
503 clear_config([:instance, :account_activation_required], true)
504 {:ok, _, _} = SideEffects.handle(delete)
505 ObanHelpers.perform_all()
506
507 refute User.get_cached_by_id(user.id)
508 end
509 end
510
511 describe "Undo objects" do
512 setup do
513 poster = insert(:user)
514 user = insert(:user)
515 {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
516 {:ok, like} = CommonAPI.favorite(user, post.id)
517 {:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
518 {:ok, announce} = CommonAPI.repeat(post.id, user)
519 {:ok, block} = CommonAPI.block(user, poster)
520
521 {:ok, undo_data, _meta} = Builder.undo(user, like)
522 {:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
523
524 {:ok, undo_data, _meta} = Builder.undo(user, reaction)
525 {:ok, reaction_undo, _meta} = ActivityPub.persist(undo_data, local: true)
526
527 {:ok, undo_data, _meta} = Builder.undo(user, announce)
528 {:ok, announce_undo, _meta} = ActivityPub.persist(undo_data, local: true)
529
530 {:ok, undo_data, _meta} = Builder.undo(user, block)
531 {:ok, block_undo, _meta} = ActivityPub.persist(undo_data, local: true)
532
533 %{
534 like_undo: like_undo,
535 post: post,
536 like: like,
537 reaction_undo: reaction_undo,
538 reaction: reaction,
539 announce_undo: announce_undo,
540 announce: announce,
541 block_undo: block_undo,
542 block: block,
543 poster: poster,
544 user: user
545 }
546 end
547
548 test "deletes the original block", %{
549 block_undo: block_undo,
550 block: block
551 } do
552 {:ok, _block_undo, _meta} = SideEffects.handle(block_undo)
553
554 refute Activity.get_by_id(block.id)
555 end
556
557 test "unblocks the blocked user", %{block_undo: block_undo, block: block} do
558 blocker = User.get_by_ap_id(block.data["actor"])
559 blocked = User.get_by_ap_id(block.data["object"])
560
561 {:ok, _block_undo, _} = SideEffects.handle(block_undo)
562 refute User.blocks?(blocker, blocked)
563 end
564
565 test "an announce undo removes the announce from the object", %{
566 announce_undo: announce_undo,
567 post: post
568 } do
569 {:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
570
571 object = Object.get_by_ap_id(post.data["object"])
572
573 assert object.data["announcement_count"] == 0
574 assert object.data["announcements"] == []
575 end
576
577 test "deletes the original announce", %{announce_undo: announce_undo, announce: announce} do
578 {:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
579 refute Activity.get_by_id(announce.id)
580 end
581
582 test "a reaction undo removes the reaction from the object", %{
583 reaction_undo: reaction_undo,
584 post: post
585 } do
586 {:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
587
588 object = Object.get_by_ap_id(post.data["object"])
589
590 assert object.data["reaction_count"] == 0
591 assert object.data["reactions"] == []
592 end
593
594 test "deletes the original reaction", %{reaction_undo: reaction_undo, reaction: reaction} do
595 {:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
596 refute Activity.get_by_id(reaction.id)
597 end
598
599 test "a like undo removes the like from the object", %{like_undo: like_undo, post: post} do
600 {:ok, _like_undo, _} = SideEffects.handle(like_undo)
601
602 object = Object.get_by_ap_id(post.data["object"])
603
604 assert object.data["like_count"] == 0
605 assert object.data["likes"] == []
606 end
607
608 test "deletes the original like", %{like_undo: like_undo, like: like} do
609 {:ok, _like_undo, _} = SideEffects.handle(like_undo)
610 refute Activity.get_by_id(like.id)
611 end
612 end
613
614 describe "like objects" do
615 setup do
616 poster = insert(:user)
617 user = insert(:user)
618 {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
619
620 {:ok, like_data, _meta} = Builder.like(user, post.object)
621 {:ok, like, _meta} = ActivityPub.persist(like_data, local: true)
622
623 %{like: like, user: user, poster: poster}
624 end
625
626 test "add the like to the original object", %{like: like, user: user} do
627 {:ok, like, _} = SideEffects.handle(like)
628 object = Object.get_by_ap_id(like.data["object"])
629 assert object.data["like_count"] == 1
630 assert user.ap_id in object.data["likes"]
631 end
632
633 test "creates a notification", %{like: like, poster: poster} do
634 {:ok, like, _} = SideEffects.handle(like)
635 assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id)
636 end
637 end
638
639 describe "announce objects" do
640 setup do
641 poster = insert(:user)
642 user = insert(:user)
643 {:ok, post} = CommonAPI.post(poster, %{status: "hey"})
644 {:ok, private_post} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
645
646 {:ok, announce_data, _meta} = Builder.announce(user, post.object, public: true)
647
648 {:ok, private_announce_data, _meta} =
649 Builder.announce(user, private_post.object, public: false)
650
651 {:ok, relay_announce_data, _meta} =
652 Builder.announce(Pleroma.Web.ActivityPub.Relay.get_actor(), post.object, public: true)
653
654 {:ok, announce, _meta} = ActivityPub.persist(announce_data, local: true)
655 {:ok, private_announce, _meta} = ActivityPub.persist(private_announce_data, local: true)
656 {:ok, relay_announce, _meta} = ActivityPub.persist(relay_announce_data, local: true)
657
658 %{
659 announce: announce,
660 user: user,
661 poster: poster,
662 private_announce: private_announce,
663 relay_announce: relay_announce
664 }
665 end
666
667 test "adds the announce to the original object", %{announce: announce, user: user} do
668 {:ok, announce, _} = SideEffects.handle(announce)
669 object = Object.get_by_ap_id(announce.data["object"])
670 assert object.data["announcement_count"] == 1
671 assert user.ap_id in object.data["announcements"]
672 end
673
674 test "does not add the announce to the original object if the actor is a service actor", %{
675 relay_announce: announce
676 } do
677 {:ok, announce, _} = SideEffects.handle(announce)
678 object = Object.get_by_ap_id(announce.data["object"])
679 assert object.data["announcement_count"] == nil
680 end
681
682 test "creates a notification", %{announce: announce, poster: poster} do
683 {:ok, announce, _} = SideEffects.handle(announce)
684 assert Repo.get_by(Notification, user_id: poster.id, activity_id: announce.id)
685 end
686
687 test "it streams out the announce", %{announce: announce} do
688 with_mocks([
689 {
690 Pleroma.Web.Streamer,
691 [],
692 [
693 stream: fn _, _ -> nil end
694 ]
695 },
696 {
697 Pleroma.Web.Push,
698 [],
699 [
700 send: fn _ -> nil end
701 ]
702 }
703 ]) do
704 {:ok, announce, _} = SideEffects.handle(announce)
705
706 assert called(
707 Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], announce)
708 )
709
710 assert called(Pleroma.Web.Push.send(:_))
711 end
712 end
713 end
714
715 describe "removing a follower" do
716 setup do
717 user = insert(:user)
718 followed = insert(:user)
719
720 {:ok, _, _, follow_activity} = CommonAPI.follow(user, followed)
721
722 {:ok, reject_data, []} = Builder.reject(followed, follow_activity)
723 {:ok, reject, _meta} = ActivityPub.persist(reject_data, local: true)
724
725 %{user: user, followed: followed, reject: reject}
726 end
727
728 test "", %{user: user, followed: followed, reject: reject} do
729 assert User.following?(user, followed)
730 assert Pleroma.FollowingRelationship.get(user, followed)
731
732 {:ok, _, _} = SideEffects.handle(reject)
733
734 refute User.following?(user, followed)
735 refute Pleroma.FollowingRelationship.get(user, followed)
736 assert User.get_follow_state(user, followed) == nil
737 assert User.get_follow_state(user, followed, nil) == nil
738 end
739 end
740
741 describe "removing a follower from remote" do
742 setup do
743 user = insert(:user)
744 followed = insert(:user, local: false)
745
746 # Mock a local-to-remote follow
747 {:ok, follow_data, []} = Builder.follow(user, followed)
748
749 follow_data =
750 follow_data
751 |> Map.put("state", "accept")
752
753 {:ok, follow, _meta} = ActivityPub.persist(follow_data, local: true)
754 {:ok, _, _} = SideEffects.handle(follow)
755
756 # Mock a remote-to-local accept
757 {:ok, accept_data, _} = Builder.accept(followed, follow)
758 {:ok, accept, _} = ActivityPub.persist(accept_data, local: false)
759 {:ok, _, _} = SideEffects.handle(accept)
760
761 # Mock a remote-to-local reject
762 {:ok, reject_data, []} = Builder.reject(followed, follow)
763 {:ok, reject, _meta} = ActivityPub.persist(reject_data, local: false)
764
765 %{user: user, followed: followed, reject: reject}
766 end
767
768 test "", %{user: user, followed: followed, reject: reject} do
769 assert User.following?(user, followed)
770 assert Pleroma.FollowingRelationship.get(user, followed)
771
772 {:ok, _, _} = SideEffects.handle(reject)
773
774 refute User.following?(user, followed)
775 refute Pleroma.FollowingRelationship.get(user, followed)
776
777 assert Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, followed).data["state"] ==
778 "reject"
779
780 assert User.get_follow_state(user, followed) == nil
781 assert User.get_follow_state(user, followed, nil) == nil
782 end
783 end
784 end