1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do
8 require Pleroma.Constants
10 alias Pleroma.Web.ActivityPub.MRF
11 alias Pleroma.Web.ActivityPub.MRF.EmojiPolicy
13 setup do: clear_config(:mrf_emoji)
16 clear_config([:mrf_emoji], %{
19 federated_timeline_removal_url: [],
20 federated_timeline_removal_shortcode: []
28 "url" => "https://example.org/emoji/biribiri/mikoto_smile2.png"
30 "id" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
31 "name" => ":mikoto_smile2:",
33 "updated" => "1970-01-01T00:00:00Z"
38 "url" => "https://example.org/emoji/biribiri/mikoto_smile3.png"
40 "id" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
41 "name" => ":mikoto_smile3:",
43 "updated" => "1970-01-01T00:00:00Z"
48 "url" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
50 "id" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
51 "name" => ":nekomimi_girl_emoji_007:",
53 "updated" => "1970-01-01T00:00:00Z"
58 "url" => "https://example.org/test.png"
60 "id" => "https://example.org/test.png",
63 "updated" => "1970-01-01T00:00:00Z"
67 @misc_tags [%{"type" => "Placeholder"}]
71 "id" => "https://example.org/placeholder",
73 "tag" => @emoji_tags ++ @misc_tags
80 "id" => "https://example.org/placeholder",
82 "tag" => @emoji_tags ++ @misc_tags,
84 "mikoto_smile2" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
85 "mikoto_smile3" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
86 "nekomimi_girl_emoji_007" =>
87 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
88 "test" => "https://example.org/test.png"
90 "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
91 "cc" => ["https://example.org/someone"]
93 "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
94 "cc" => ["https://example.org/someone"]
97 @status_data_with_history %{
100 @status_data["object"]
102 "formerRepresentations" => %{
103 "type" => "OrderedCollection",
104 "orderedItems" => [@status_data["object"] |> Map.put("content", "older")],
108 "to" => ["https://example.org/self", Pleroma.Constants.as_public()],
109 "cc" => ["https://example.org/someone"]
113 "type" => "EmojiReact",
114 "tag" => [@emoji_tags |> Enum.at(3)],
115 "object" => "https://example.org/someobject",
116 "to" => ["https://example.org/self"],
117 "cc" => ["https://example.org/someone"]
120 @emoji_react_data_matching_regex %{
121 "type" => "EmojiReact",
122 "tag" => [@emoji_tags |> Enum.at(1)],
123 "object" => "https://example.org/someobject",
124 "to" => ["https://example.org/self"],
125 "cc" => ["https://example.org/someone"]
128 @emoji_react_data_matching_nothing %{
129 "type" => "EmojiReact",
130 "tag" => [@emoji_tags |> Enum.at(2)],
131 "object" => "https://example.org/someobject",
132 "to" => ["https://example.org/self"],
133 "cc" => ["https://example.org/someone"]
136 @emoji_react_data_unicode %{
137 "type" => "EmojiReact",
139 "object" => "https://example.org/someobject",
140 "to" => ["https://example.org/self"],
141 "cc" => ["https://example.org/someone"]
144 describe "remove_url" do
146 clear_config([:mrf_emoji, :remove_url], [
147 "https://example.org/test.png",
148 ~r{/biribiri/mikoto_smile[23]\.png},
149 "nekomimi_girl_emoji"
155 test "processes user" do
156 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
158 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
160 assert %{"tag" => ^expected_tags} = filtered
163 test "processes status" do
164 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
166 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
169 "nekomimi_girl_emoji_007" =>
170 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
173 assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
176 test "processes status with history" do
177 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
179 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
182 "nekomimi_girl_emoji_007" =>
183 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
188 "tag" => ^expected_tags,
189 "emoji" => ^expected_emoji,
190 "formerRepresentations" => %{"orderedItems" => [item]}
194 assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
197 test "processes updates" do
199 MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
201 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
204 "nekomimi_girl_emoji_007" =>
205 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
210 "tag" => ^expected_tags,
211 "emoji" => ^expected_emoji,
212 "formerRepresentations" => %{"orderedItems" => [item]}
216 assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
219 test "processes EmojiReact" do
220 assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
221 MRF.filter_one(EmojiPolicy, @emoji_react_data)
223 assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
224 MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
226 assert {:ok, @emoji_react_data_matching_nothing} ==
227 MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
229 assert {:ok, @emoji_react_data_unicode} ==
230 MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
234 describe "remove_shortcode" do
236 clear_config([:mrf_emoji, :remove_shortcode], [
239 "nekomimi_girl_emoji"
245 test "processes user" do
246 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
248 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
250 assert %{"tag" => ^expected_tags} = filtered
253 test "processes status" do
254 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
256 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
259 "nekomimi_girl_emoji_007" =>
260 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
263 assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
266 test "processes status with history" do
267 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
269 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
272 "nekomimi_girl_emoji_007" =>
273 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
278 "tag" => ^expected_tags,
279 "emoji" => ^expected_emoji,
280 "formerRepresentations" => %{"orderedItems" => [item]}
284 assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
287 test "processes updates" do
289 MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
291 expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
294 "nekomimi_girl_emoji_007" =>
295 "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
300 "tag" => ^expected_tags,
301 "emoji" => ^expected_emoji,
302 "formerRepresentations" => %{"orderedItems" => [item]}
306 assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
309 test "processes EmojiReact" do
310 assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
311 MRF.filter_one(EmojiPolicy, @emoji_react_data)
313 assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
314 MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
316 assert {:ok, @emoji_react_data_matching_nothing} ==
317 MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
319 assert {:ok, @emoji_react_data_unicode} ==
320 MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
324 describe "federated_timeline_removal_url" do
326 clear_config([:mrf_emoji, :federated_timeline_removal_url], [
327 "https://example.org/test.png",
328 ~r{/biribiri/mikoto_smile[23]\.png},
329 "nekomimi_girl_emoji"
335 test "processes status" do
336 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
338 expected_tags = @status_data["object"]["tag"]
339 expected_emoji = @status_data["object"]["emoji"]
341 expected_to = ["https://example.org/self"]
342 expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
345 "to" => ^expected_to,
346 "cc" => ^expected_cc,
347 "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
351 test "ignore updates" do
352 {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data |> Map.put("type", "Update"))
354 expected_tags = @status_data["object"]["tag"]
355 expected_emoji = @status_data["object"]["emoji"]
357 expected_to = ["https://example.org/self", Pleroma.Constants.as_public()]
358 expected_cc = ["https://example.org/someone"]
361 "to" => ^expected_to,
362 "cc" => ^expected_cc,
363 "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
367 test "processes status with history" do
369 @status_data_with_history
370 |> put_in(["object", "tag"], @misc_tags)
371 |> put_in(["object", "emoji"], %{})
373 {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
375 expected_tags = @status_data["object"]["tag"]
376 expected_emoji = @status_data["object"]["emoji"]
378 expected_to = ["https://example.org/self"]
379 expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
382 "to" => ^expected_to,
383 "cc" => ^expected_cc,
385 "formerRepresentations" => %{
386 "orderedItems" => [%{"tag" => ^expected_tags, "emoji" => ^expected_emoji}]
393 describe "edge cases" do
395 clear_config([:mrf_emoji, :remove_url], [
396 "https://example.org/test.png",
397 ~r{/biribiri/mikoto_smile[23]\.png},
398 "nekomimi_girl_emoji"
404 test "non-statuses" do
405 answer = @status_data |> put_in(["object", "type"], "Answer")
406 {:ok, filtered} = MRF.filter_one(EmojiPolicy, answer)
408 assert filtered == answer
411 test "without tag" do
412 status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["tag"]))
413 {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
415 refute Map.has_key?(filtered["object"], "tag")
418 test "without emoji" do
419 status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["emoji"]))
420 {:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
422 refute Map.has_key?(filtered["object"], "emoji")