Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into feature/emojireactv...
[akkoma] / test / web / activity_pub / side_effects_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 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.CommonAPI
19
20 import Pleroma.Factory
21 import Mock
22
23 describe "delete objects" do
24 setup do
25 user = insert(:user)
26 other_user = insert(:user)
27
28 {:ok, op} = CommonAPI.post(other_user, %{"status" => "big oof"})
29 {:ok, post} = CommonAPI.post(user, %{"status" => "hey", "in_reply_to_id" => op})
30 object = Object.normalize(post)
31 {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
32 {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
33 {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
34 {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
35 %{user: user, delete: delete, post: post, object: object, delete_user: delete_user, op: op}
36 end
37
38 test "it handles object deletions", %{
39 delete: delete,
40 post: post,
41 object: object,
42 user: user,
43 op: op
44 } do
45 with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
46 stream_out: fn _ -> nil end,
47 stream_out_participations: fn _, _ -> nil end do
48 {:ok, delete, _} = SideEffects.handle(delete)
49 user = User.get_cached_by_ap_id(object.data["actor"])
50
51 assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
52 assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
53 end
54
55 object = Object.get_by_id(object.id)
56 assert object.data["type"] == "Tombstone"
57 refute Activity.get_by_id(post.id)
58
59 user = User.get_by_id(user.id)
60 assert user.note_count == 0
61
62 object = Object.normalize(op.data["object"], false)
63
64 assert object.data["repliesCount"] == 0
65 end
66
67 test "it handles user deletions", %{delete_user: delete, user: user} do
68 {:ok, _delete, _} = SideEffects.handle(delete)
69 ObanHelpers.perform_all()
70
71 assert User.get_cached_by_ap_id(user.ap_id).deactivated
72 end
73 end
74
75 describe "EmojiReact objects" do
76 setup do
77 poster = insert(:user)
78 user = insert(:user)
79
80 {:ok, post} = CommonAPI.post(poster, %{"status" => "hey"})
81
82 {:ok, emoji_react_data, []} = Builder.emoji_react(user, post.object, "👌")
83 {:ok, emoji_react, _meta} = ActivityPub.persist(emoji_react_data, local: true)
84
85 %{emoji_react: emoji_react, user: user, poster: poster}
86 end
87
88 test "adds the reaction to the object", %{emoji_react: emoji_react, user: user} do
89 {:ok, emoji_react, _} = SideEffects.handle(emoji_react)
90 object = Object.get_by_ap_id(emoji_react.data["object"])
91
92 assert object.data["reaction_count"] == 1
93 assert ["👌", [user.ap_id]] in object.data["reactions"]
94 end
95
96 test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
97 {:ok, emoji_react, _} = SideEffects.handle(emoji_react)
98 assert Repo.get_by(Notification, user_id: poster.id, activity_id: emoji_react.id)
99 end
100 end
101
102 describe "Undo objects" do
103 setup do
104 poster = insert(:user)
105 user = insert(:user)
106 {:ok, post} = CommonAPI.post(poster, %{"status" => "hey"})
107 {:ok, like} = CommonAPI.favorite(user, post.id)
108 {:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
109 {:ok, announce, _} = CommonAPI.repeat(post.id, user)
110 {:ok, block} = ActivityPub.block(user, poster)
111 User.block(user, poster)
112
113 {:ok, undo_data, _meta} = Builder.undo(user, like)
114 {:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
115
116 {:ok, undo_data, _meta} = Builder.undo(user, reaction)
117 {:ok, reaction_undo, _meta} = ActivityPub.persist(undo_data, local: true)
118
119 {:ok, undo_data, _meta} = Builder.undo(user, announce)
120 {:ok, announce_undo, _meta} = ActivityPub.persist(undo_data, local: true)
121
122 {:ok, undo_data, _meta} = Builder.undo(user, block)
123 {:ok, block_undo, _meta} = ActivityPub.persist(undo_data, local: true)
124
125 %{
126 like_undo: like_undo,
127 post: post,
128 like: like,
129 reaction_undo: reaction_undo,
130 reaction: reaction,
131 announce_undo: announce_undo,
132 announce: announce,
133 block_undo: block_undo,
134 block: block,
135 poster: poster,
136 user: user
137 }
138 end
139
140 test "deletes the original block", %{block_undo: block_undo, block: block} do
141 {:ok, _block_undo, _} = SideEffects.handle(block_undo)
142 refute Activity.get_by_id(block.id)
143 end
144
145 test "unblocks the blocked user", %{block_undo: block_undo, block: block} do
146 blocker = User.get_by_ap_id(block.data["actor"])
147 blocked = User.get_by_ap_id(block.data["object"])
148
149 {:ok, _block_undo, _} = SideEffects.handle(block_undo)
150 refute User.blocks?(blocker, blocked)
151 end
152
153 test "an announce undo removes the announce from the object", %{
154 announce_undo: announce_undo,
155 post: post
156 } do
157 {:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
158
159 object = Object.get_by_ap_id(post.data["object"])
160
161 assert object.data["announcement_count"] == 0
162 assert object.data["announcements"] == []
163 end
164
165 test "deletes the original announce", %{announce_undo: announce_undo, announce: announce} do
166 {:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
167 refute Activity.get_by_id(announce.id)
168 end
169
170 test "a reaction undo removes the reaction from the object", %{
171 reaction_undo: reaction_undo,
172 post: post
173 } do
174 {:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
175
176 object = Object.get_by_ap_id(post.data["object"])
177
178 assert object.data["reaction_count"] == 0
179 assert object.data["reactions"] == []
180 end
181
182 test "deletes the original reaction", %{reaction_undo: reaction_undo, reaction: reaction} do
183 {:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
184 refute Activity.get_by_id(reaction.id)
185 end
186
187 test "a like undo removes the like from the object", %{like_undo: like_undo, post: post} do
188 {:ok, _like_undo, _} = SideEffects.handle(like_undo)
189
190 object = Object.get_by_ap_id(post.data["object"])
191
192 assert object.data["like_count"] == 0
193 assert object.data["likes"] == []
194 end
195
196 test "deletes the original like", %{like_undo: like_undo, like: like} do
197 {:ok, _like_undo, _} = SideEffects.handle(like_undo)
198 refute Activity.get_by_id(like.id)
199 end
200 end
201
202 describe "like objects" do
203 setup do
204 poster = insert(:user)
205 user = insert(:user)
206 {:ok, post} = CommonAPI.post(poster, %{"status" => "hey"})
207
208 {:ok, like_data, _meta} = Builder.like(user, post.object)
209 {:ok, like, _meta} = ActivityPub.persist(like_data, local: true)
210
211 %{like: like, user: user, poster: poster}
212 end
213
214 test "add the like to the original object", %{like: like, user: user} do
215 {:ok, like, _} = SideEffects.handle(like)
216 object = Object.get_by_ap_id(like.data["object"])
217 assert object.data["like_count"] == 1
218 assert user.ap_id in object.data["likes"]
219 end
220
221 test "creates a notification", %{like: like, poster: poster} do
222 {:ok, like, _} = SideEffects.handle(like)
223 assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id)
224 end
225 end
226 end