total rebase
[anni] / test / pleroma / web / activity_pub / object_validators / chat_validation_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.ObjectValidators.ChatValidationTest do
6   use Pleroma.DataCase
7   alias Pleroma.Object
8   alias Pleroma.UnstubbedConfigMock, as: ConfigMock
9   alias Pleroma.Web.ActivityPub.ActivityPub
10   alias Pleroma.Web.ActivityPub.Builder
11   alias Pleroma.Web.ActivityPub.ObjectValidator
12   alias Pleroma.Web.CommonAPI
13
14   import Mox
15   import Pleroma.Factory
16
17   describe "chat message create activities" do
18     test "it is invalid if the object already exists" do
19       user = insert(:user)
20       recipient = insert(:user)
21       {:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
22       object = Object.normalize(activity, fetch: false)
23
24       {:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
25
26       {:error, cng} = ObjectValidator.validate(create_data, [])
27
28       assert {:object, {"The object to create already exists", []}} in cng.errors
29     end
30
31     test "it is invalid if the object data has a different `to` or `actor` field" do
32       user = insert(:user)
33       recipient = insert(:user)
34       {:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey")
35
36       {:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id])
37
38       {:error, cng} = ObjectValidator.validate(create_data, [])
39
40       assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors
41       assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors
42     end
43   end
44
45   describe "chat messages" do
46     setup do
47       clear_config([:instance, :remote_limit])
48       user = insert(:user)
49       recipient = insert(:user, local: false)
50
51       {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:")
52
53       %{user: user, recipient: recipient, valid_chat_message: valid_chat_message}
54     end
55
56     test "let's through some basic html", %{user: user, recipient: recipient} do
57       {:ok, valid_chat_message, _} =
58         Builder.chat_message(
59           user,
60           recipient.ap_id,
61           "hey <a href='https://example.org'>example</a> <script>alert('uguu')</script>"
62         )
63
64       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
65
66       assert object["content"] ==
67                "hey <a href=\"https://example.org\">example</a> alert(&#39;uguu&#39;)"
68     end
69
70     test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do
71       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
72
73       assert valid_chat_message == object
74       assert match?(%{"firefox" => _}, object["emoji"])
75     end
76
77     test "validates for a basic object with an attachment", %{
78       valid_chat_message: valid_chat_message,
79       user: user
80     } do
81       file = %Plug.Upload{
82         content_type: "image/jpeg",
83         path: Path.absname("test/fixtures/image.jpg"),
84         filename: "an_image.jpg"
85       }
86
87       ConfigMock
88       |> stub_with(Pleroma.Test.StaticConfig)
89
90       {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
91
92       valid_chat_message =
93         valid_chat_message
94         |> Map.put("attachment", attachment.data)
95
96       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
97
98       assert object["attachment"]
99     end
100
101     test "validates for a basic object with an attachment in an array", %{
102       valid_chat_message: valid_chat_message,
103       user: user
104     } do
105       file = %Plug.Upload{
106         content_type: "image/jpeg",
107         path: Path.absname("test/fixtures/image.jpg"),
108         filename: "an_image.jpg"
109       }
110
111       ConfigMock
112       |> stub_with(Pleroma.Test.StaticConfig)
113
114       {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
115
116       valid_chat_message =
117         valid_chat_message
118         |> Map.put("attachment", [attachment.data])
119
120       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
121
122       assert object["attachment"]
123     end
124
125     test "validates for a basic object with an attachment but without content", %{
126       valid_chat_message: valid_chat_message,
127       user: user
128     } do
129       file = %Plug.Upload{
130         content_type: "image/jpeg",
131         path: Path.absname("test/fixtures/image.jpg"),
132         filename: "an_image.jpg"
133       }
134
135       ConfigMock
136       |> stub_with(Pleroma.Test.StaticConfig)
137
138       {:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
139
140       valid_chat_message =
141         valid_chat_message
142         |> Map.put("attachment", attachment.data)
143         |> Map.delete("content")
144
145       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
146
147       assert object["attachment"]
148     end
149
150     test "validates for a basic object with content but attachment set to empty array", %{
151       user: user,
152       recipient: recipient
153     } do
154       {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "Hello!")
155
156       valid_chat_message =
157         valid_chat_message
158         |> Map.put("attachment", [])
159
160       assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
161
162       assert object == Map.drop(valid_chat_message, ["attachment"])
163     end
164
165     test "does not validate if the message has no content", %{
166       valid_chat_message: valid_chat_message
167     } do
168       contentless =
169         valid_chat_message
170         |> Map.delete("content")
171
172       refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, []))
173     end
174
175     test "does not validate if the message is longer than the remote_limit", %{
176       valid_chat_message: valid_chat_message
177     } do
178       clear_config([:instance, :remote_limit], 2)
179       refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
180     end
181
182     test "does not validate if the recipient is blocking the actor", %{
183       valid_chat_message: valid_chat_message,
184       user: user,
185       recipient: recipient
186     } do
187       Pleroma.User.block(recipient, user)
188       refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
189     end
190
191     test "does not validate if the recipient is not accepting chat messages", %{
192       valid_chat_message: valid_chat_message,
193       recipient: recipient
194     } do
195       recipient
196       |> Ecto.Changeset.change(%{accepts_chat_messages: false})
197       |> Pleroma.Repo.update!()
198
199       refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
200     end
201
202     test "does not validate if the actor or the recipient is not in our system", %{
203       valid_chat_message: valid_chat_message
204     } do
205       chat_message =
206         valid_chat_message
207         |> Map.put("actor", "https://raymoo.com/raymoo")
208
209       {:error, _} = ObjectValidator.validate(chat_message, [])
210
211       chat_message =
212         valid_chat_message
213         |> Map.put("to", ["https://raymoo.com/raymoo"])
214
215       {:error, _} = ObjectValidator.validate(chat_message, [])
216     end
217
218     test "does not validate for a message with multiple recipients", %{
219       valid_chat_message: valid_chat_message,
220       user: user,
221       recipient: recipient
222     } do
223       chat_message =
224         valid_chat_message
225         |> Map.put("to", [user.ap_id, recipient.ap_id])
226
227       assert {:error, _} = ObjectValidator.validate(chat_message, [])
228     end
229
230     test "does not validate if it doesn't concern local users" do
231       user = insert(:user, local: false)
232       recipient = insert(:user, local: false)
233
234       {:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey")
235       assert {:error, _} = ObjectValidator.validate(valid_chat_message, [])
236     end
237   end
238 end