diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs | 425 | ||||
-rw-r--r-- | test/pleroma/web/activity_pub/mrf/utils_test.exs | 19 |
2 files changed, 444 insertions, 0 deletions
diff --git a/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs b/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs new file mode 100644 index 000000000..7350800f0 --- /dev/null +++ b/test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs @@ -0,0 +1,425 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do + use Pleroma.DataCase + + require Pleroma.Constants + + alias Pleroma.Web.ActivityPub.MRF + alias Pleroma.Web.ActivityPub.MRF.EmojiPolicy + + setup do: clear_config(:mrf_emoji) + + setup do + clear_config([:mrf_emoji], %{ + remove_url: [], + remove_shortcode: [], + federated_timeline_removal_url: [], + federated_timeline_removal_shortcode: [] + }) + end + + @emoji_tags [ + %{ + "icon" => %{ + "type" => "Image", + "url" => "https://example.org/emoji/biribiri/mikoto_smile2.png" + }, + "id" => "https://example.org/emoji/biribiri/mikoto_smile2.png", + "name" => ":mikoto_smile2:", + "type" => "Emoji", + "updated" => "1970-01-01T00:00:00Z" + }, + %{ + "icon" => %{ + "type" => "Image", + "url" => "https://example.org/emoji/biribiri/mikoto_smile3.png" + }, + "id" => "https://example.org/emoji/biribiri/mikoto_smile3.png", + "name" => ":mikoto_smile3:", + "type" => "Emoji", + "updated" => "1970-01-01T00:00:00Z" + }, + %{ + "icon" => %{ + "type" => "Image", + "url" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + }, + "id" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png", + "name" => ":nekomimi_girl_emoji_007:", + "type" => "Emoji", + "updated" => "1970-01-01T00:00:00Z" + }, + %{ + "icon" => %{ + "type" => "Image", + "url" => "https://example.org/test.png" + }, + "id" => "https://example.org/test.png", + "name" => ":test:", + "type" => "Emoji", + "updated" => "1970-01-01T00:00:00Z" + } + ] + + @misc_tags [%{"type" => "Placeholder"}] + + @user_data %{ + "type" => "Person", + "id" => "https://example.org/placeholder", + "name" => "lol", + "tag" => @emoji_tags ++ @misc_tags + } + + @status_data %{ + "type" => "Create", + "object" => %{ + "type" => "Note", + "id" => "https://example.org/placeholder", + "content" => "lol", + "tag" => @emoji_tags ++ @misc_tags, + "emoji" => %{ + "mikoto_smile2" => "https://example.org/emoji/biribiri/mikoto_smile2.png", + "mikoto_smile3" => "https://example.org/emoji/biribiri/mikoto_smile3.png", + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png", + "test" => "https://example.org/test.png" + }, + "to" => ["https://example.org/self", Pleroma.Constants.as_public()], + "cc" => ["https://example.org/someone"] + }, + "to" => ["https://example.org/self", Pleroma.Constants.as_public()], + "cc" => ["https://example.org/someone"] + } + + @status_data_with_history %{ + "type" => "Create", + "object" => + @status_data["object"] + |> Map.merge(%{ + "formerRepresentations" => %{ + "type" => "OrderedCollection", + "orderedItems" => [@status_data["object"] |> Map.put("content", "older")], + "totalItems" => 1 + } + }), + "to" => ["https://example.org/self", Pleroma.Constants.as_public()], + "cc" => ["https://example.org/someone"] + } + + @emoji_react_data %{ + "type" => "EmojiReact", + "tag" => [@emoji_tags |> Enum.at(3)], + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + + @emoji_react_data_matching_regex %{ + "type" => "EmojiReact", + "tag" => [@emoji_tags |> Enum.at(1)], + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + + @emoji_react_data_matching_nothing %{ + "type" => "EmojiReact", + "tag" => [@emoji_tags |> Enum.at(2)], + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + + @emoji_react_data_unicode %{ + "type" => "EmojiReact", + "content" => "😍", + "object" => "https://example.org/someobject", + "to" => ["https://example.org/self"], + "cc" => ["https://example.org/someone"] + } + + describe "remove_url" do + setup do + clear_config([:mrf_emoji, :remove_url], [ + "https://example.org/test.png", + ~r{/biribiri/mikoto_smile[23]\.png}, + "nekomimi_girl_emoji" + ]) + + :ok + end + + test "processes user" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + assert %{"tag" => ^expected_tags} = filtered + end + + test "processes status" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + expected_emoji = %{ + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + } + + assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered + end + + test "processes status with history" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + expected_emoji = %{ + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + } + + assert %{ + "object" => %{ + "tag" => ^expected_tags, + "emoji" => ^expected_emoji, + "formerRepresentations" => %{"orderedItems" => [item]} + } + } = filtered + + assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item + end + + test "processes updates" do + {:ok, filtered} = + MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update")) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + expected_emoji = %{ + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + } + + assert %{ + "object" => %{ + "tag" => ^expected_tags, + "emoji" => ^expected_emoji, + "formerRepresentations" => %{"orderedItems" => [item]} + } + } = filtered + + assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item + end + + test "processes EmojiReact" do + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data) + + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex) + + assert {:ok, @emoji_react_data_matching_nothing} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing) + + assert {:ok, @emoji_react_data_unicode} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode) + end + end + + describe "remove_shortcode" do + setup do + clear_config([:mrf_emoji, :remove_shortcode], [ + "test", + ~r{mikoto_s}, + "nekomimi_girl_emoji" + ]) + + :ok + end + + test "processes user" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + assert %{"tag" => ^expected_tags} = filtered + end + + test "processes status" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + expected_emoji = %{ + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + } + + assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered + end + + test "processes status with history" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + expected_emoji = %{ + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + } + + assert %{ + "object" => %{ + "tag" => ^expected_tags, + "emoji" => ^expected_emoji, + "formerRepresentations" => %{"orderedItems" => [item]} + } + } = filtered + + assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item + end + + test "processes updates" do + {:ok, filtered} = + MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update")) + + expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags + + expected_emoji = %{ + "nekomimi_girl_emoji_007" => + "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png" + } + + assert %{ + "object" => %{ + "tag" => ^expected_tags, + "emoji" => ^expected_emoji, + "formerRepresentations" => %{"orderedItems" => [item]} + } + } = filtered + + assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item + end + + test "processes EmojiReact" do + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data) + + assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex) + + assert {:ok, @emoji_react_data_matching_nothing} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing) + + assert {:ok, @emoji_react_data_unicode} == + MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode) + end + end + + describe "federated_timeline_removal_url" do + setup do + clear_config([:mrf_emoji, :federated_timeline_removal_url], [ + "https://example.org/test.png", + ~r{/biribiri/mikoto_smile[23]\.png}, + "nekomimi_girl_emoji" + ]) + + :ok + end + + test "processes status" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data) + + expected_tags = @status_data["object"]["tag"] + expected_emoji = @status_data["object"]["emoji"] + + expected_to = ["https://example.org/self"] + expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"] + + assert %{ + "to" => ^expected_to, + "cc" => ^expected_cc, + "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} + } = filtered + end + + test "ignore updates" do + {:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data |> Map.put("type", "Update")) + + expected_tags = @status_data["object"]["tag"] + expected_emoji = @status_data["object"]["emoji"] + + expected_to = ["https://example.org/self", Pleroma.Constants.as_public()] + expected_cc = ["https://example.org/someone"] + + assert %{ + "to" => ^expected_to, + "cc" => ^expected_cc, + "object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} + } = filtered + end + + test "processes status with history" do + status = + @status_data_with_history + |> put_in(["object", "tag"], @misc_tags) + |> put_in(["object", "emoji"], %{}) + + {:ok, filtered} = MRF.filter_one(EmojiPolicy, status) + + expected_tags = @status_data["object"]["tag"] + expected_emoji = @status_data["object"]["emoji"] + + expected_to = ["https://example.org/self"] + expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"] + + assert %{ + "to" => ^expected_to, + "cc" => ^expected_cc, + "object" => %{ + "formerRepresentations" => %{ + "orderedItems" => [%{"tag" => ^expected_tags, "emoji" => ^expected_emoji}] + } + } + } = filtered + end + end + + describe "edge cases" do + setup do + clear_config([:mrf_emoji, :remove_url], [ + "https://example.org/test.png", + ~r{/biribiri/mikoto_smile[23]\.png}, + "nekomimi_girl_emoji" + ]) + + :ok + end + + test "non-statuses" do + answer = @status_data |> put_in(["object", "type"], "Answer") + {:ok, filtered} = MRF.filter_one(EmojiPolicy, answer) + + assert filtered == answer + end + + test "without tag" do + status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["tag"])) + {:ok, filtered} = MRF.filter_one(EmojiPolicy, status) + + refute Map.has_key?(filtered["object"], "tag") + end + + test "without emoji" do + status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["emoji"])) + {:ok, filtered} = MRF.filter_one(EmojiPolicy, status) + + refute Map.has_key?(filtered["object"], "emoji") + end + end +end diff --git a/test/pleroma/web/activity_pub/mrf/utils_test.exs b/test/pleroma/web/activity_pub/mrf/utils_test.exs new file mode 100644 index 000000000..3bbc2cfd3 --- /dev/null +++ b/test/pleroma/web/activity_pub/mrf/utils_test.exs @@ -0,0 +1,19 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ActivityPub.MRF.UtilsTest do + use Pleroma.DataCase, async: true + + alias Pleroma.Web.ActivityPub.MRF.Utils + + describe "describe_regex_or_string/1" do + test "describes regex" do + assert "~r/foo/i" == Utils.describe_regex_or_string(~r/foo/i) + end + + test "returns string as-is" do + assert "foo" == Utils.describe_regex_or_string("foo") + end + end +end |