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