First
[anni] / test / pleroma / web / activity_pub / side_effects / delete_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.SideEffects.DeleteTest do
6   use Oban.Testing, repo: Pleroma.Repo
7   use Pleroma.DataCase, async: true
8
9   alias Pleroma.Activity
10   alias Pleroma.Object
11   alias Pleroma.Repo
12   alias Pleroma.Tests.ObanHelpers
13   alias Pleroma.User
14   alias Pleroma.Web.ActivityPub.ActivityPub
15   alias Pleroma.Web.ActivityPub.Builder
16   alias Pleroma.Web.ActivityPub.SideEffects
17   alias Pleroma.Web.CommonAPI
18
19   alias Pleroma.LoggerMock
20   alias Pleroma.Web.ActivityPub.ActivityPubMock
21
22   import Mox
23   import Pleroma.Factory
24
25   describe "user deletion" do
26     setup do
27       user = insert(:user)
28
29       {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
30       {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
31
32       %{
33         user: user,
34         delete_user: delete_user
35       }
36     end
37
38     test "it handles user deletions", %{delete_user: delete, user: user} do
39       {:ok, _delete, _} = SideEffects.handle(delete)
40       ObanHelpers.perform_all()
41
42       refute User.get_cached_by_ap_id(user.ap_id).is_active
43     end
44   end
45
46   describe "object deletion" do
47     setup do
48       user = insert(:user)
49       other_user = insert(:user)
50
51       {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
52       {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
53       {:ok, favorite} = CommonAPI.favorite(user, post.id)
54       object = Object.normalize(post, fetch: false)
55       {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
56       {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
57
58       %{
59         user: user,
60         delete: delete,
61         post: post,
62         object: object,
63         op: op,
64         favorite: favorite
65       }
66     end
67
68     test "it handles object deletions", %{
69       delete: delete,
70       post: post,
71       object: object,
72       user: user,
73       op: op,
74       favorite: favorite
75     } do
76       object_id = object.id
77       user_id = user.id
78
79       ActivityPubMock
80       |> expect(:stream_out, fn ^delete -> nil end)
81       |> expect(:stream_out_participations, fn %Object{id: ^object_id}, %User{id: ^user_id} ->
82         nil
83       end)
84
85       {:ok, _delete, _} = SideEffects.handle(delete)
86       user = User.get_cached_by_ap_id(object.data["actor"])
87
88       object = Object.get_by_id(object.id)
89       assert object.data["type"] == "Tombstone"
90       refute Activity.get_by_id(post.id)
91       refute Activity.get_by_id(favorite.id)
92
93       user = User.get_by_id(user.id)
94       assert user.note_count == 0
95
96       object = Object.normalize(op.data["object"], fetch: false)
97
98       assert object.data["repliesCount"] == 0
99     end
100
101     test "it handles object deletions when the object itself has been pruned", %{
102       delete: delete,
103       post: post,
104       object: object,
105       user: user,
106       op: op
107     } do
108       object_id = object.id
109       user_id = user.id
110
111       ActivityPubMock
112       |> expect(:stream_out, fn ^delete -> nil end)
113       |> expect(:stream_out_participations, fn %Object{id: ^object_id}, %User{id: ^user_id} ->
114         nil
115       end)
116
117       {:ok, _delete, _} = SideEffects.handle(delete)
118       user = User.get_cached_by_ap_id(object.data["actor"])
119
120       object = Object.get_by_id(object.id)
121       assert object.data["type"] == "Tombstone"
122       refute Activity.get_by_id(post.id)
123
124       user = User.get_by_id(user.id)
125       assert user.note_count == 0
126
127       object = Object.normalize(op.data["object"], fetch: false)
128
129       assert object.data["repliesCount"] == 0
130     end
131
132     test "it logs issues with objects deletion", %{
133       delete: delete,
134       object: object
135     } do
136       {:ok, _object} =
137         object
138         |> Object.change(%{data: Map.delete(object.data, "actor")})
139         |> Repo.update()
140
141       LoggerMock
142       |> expect(:error, fn str -> assert str =~ "The object doesn't have an actor" end)
143
144       {:error, :no_object_actor} = SideEffects.handle(delete)
145     end
146   end
147 end