2023-02-28 15:40:24 +00:00
|
|
|
# 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
|
|
|
|
|
2023-02-28 16:47:53 +00:00
|
|
|
require Pleroma.Constants
|
|
|
|
|
2023-02-28 15:40:24 +00:00
|
|
|
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"
|
2023-02-28 16:47:53 +00:00
|
|
|
},
|
|
|
|
"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"]
|
2023-02-28 15:40:24 +00:00
|
|
|
}
|
|
|
|
|
2023-06-13 18:53:20 +00:00
|
|
|
@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"]
|
|
|
|
}
|
|
|
|
|
2023-06-13 18:55:27 +00:00
|
|
|
@emoji_react_data_unicode %{
|
|
|
|
"type" => "EmojiReact",
|
|
|
|
"content" => "😍",
|
|
|
|
"object" => "https://example.org/someobject",
|
|
|
|
"to" => ["https://example.org/self"],
|
|
|
|
"cc" => ["https://example.org/someone"]
|
|
|
|
}
|
|
|
|
|
2023-02-28 15:40:24 +00:00
|
|
|
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
|
2023-02-28 16:47:53 +00:00
|
|
|
|
|
|
|
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
|
2023-06-13 18:53:20 +00:00
|
|
|
|
|
|
|
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)
|
2023-06-13 18:55:27 +00:00
|
|
|
|
|
|
|
assert {:ok, @emoji_react_data_unicode} ==
|
|
|
|
MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
|
2023-06-13 18:53:20 +00:00
|
|
|
end
|
2023-02-28 15:40:24 +00:00
|
|
|
end
|
2023-02-28 15:51:56 +00:00
|
|
|
|
|
|
|
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
|
2023-02-28 16:47:53 +00:00
|
|
|
|
|
|
|
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
|
2023-06-13 18:53:20 +00:00
|
|
|
|
|
|
|
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)
|
2023-06-13 18:55:27 +00:00
|
|
|
|
|
|
|
assert {:ok, @emoji_react_data_unicode} ==
|
|
|
|
MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
|
2023-06-13 18:53:20 +00:00
|
|
|
end
|
2023-02-28 16:47:53 +00:00
|
|
|
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
|
2023-02-28 15:51:56 +00:00
|
|
|
end
|
2023-06-20 14:14:01 +00:00
|
|
|
|
|
|
|
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
|
2023-02-28 15:40:24 +00:00
|
|
|
end
|