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