Merge branch 'develop' into 'remove-twitter-api'
# Conflicts: # lib/pleroma/web/nodeinfo/nodeinfo_controller.ex
This commit is contained in:
commit
d15aa9d950
598 changed files with 28836 additions and 10625 deletions
|
|
@ -83,7 +83,7 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
|
|||
assert Enum.member?(topics, "hashtag:bar")
|
||||
end
|
||||
|
||||
test "only converts strinngs to hash tags", %{
|
||||
test "only converts strings to hash tags", %{
|
||||
activity: %{object: %{data: data} = object} = activity
|
||||
} do
|
||||
tagged_data = Map.put(data, "tag", [2])
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ defmodule Pleroma.ActivityTest do
|
|||
alias Pleroma.ThreadMute
|
||||
import Pleroma.Factory
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
end
|
||||
|
||||
test "returns an activity by it's AP id" do
|
||||
activity = insert(:note_activity)
|
||||
found_activity = Activity.get_by_ap_id(activity.data["id"])
|
||||
|
|
@ -107,8 +112,6 @@ defmodule Pleroma.ActivityTest do
|
|||
|
||||
describe "search" do
|
||||
setup do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
params = %{
|
||||
|
|
@ -125,8 +128,8 @@ defmodule Pleroma.ActivityTest do
|
|||
"to" => ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
}
|
||||
|
||||
{:ok, local_activity} = Pleroma.Web.CommonAPI.post(user, %{"status" => "find me!"})
|
||||
{:ok, japanese_activity} = Pleroma.Web.CommonAPI.post(user, %{"status" => "更新情報"})
|
||||
{:ok, local_activity} = Pleroma.Web.CommonAPI.post(user, %{status: "find me!"})
|
||||
{:ok, japanese_activity} = Pleroma.Web.CommonAPI.post(user, %{status: "更新情報"})
|
||||
{:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
|
||||
{:ok, remote_activity} = ObanHelpers.perform(job)
|
||||
|
||||
|
|
@ -225,8 +228,8 @@ defmodule Pleroma.ActivityTest do
|
|||
test "all_by_actor_and_id/2" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, %{id: id1}} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofe"})
|
||||
{:ok, %{id: id2}} = Pleroma.Web.CommonAPI.post(user, %{"status" => "cofefe"})
|
||||
{:ok, %{id: id1}} = Pleroma.Web.CommonAPI.post(user, %{status: "cofe"})
|
||||
{:ok, %{id: id2}} = Pleroma.Web.CommonAPI.post(user, %{status: "cofefe"})
|
||||
|
||||
assert [] == Activity.all_by_actor_and_id(user, [])
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ defmodule Pleroma.BBS.HandlerTest do
|
|||
|
||||
{:ok, user} = User.follow(user, followed)
|
||||
|
||||
{:ok, _first} = CommonAPI.post(user, %{"status" => "hey"})
|
||||
{:ok, _second} = CommonAPI.post(followed, %{"status" => "hello"})
|
||||
{:ok, _first} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, _second} = CommonAPI.post(followed, %{status: "hello"})
|
||||
|
||||
output =
|
||||
capture_io(fn ->
|
||||
|
|
@ -62,7 +62,7 @@ defmodule Pleroma.BBS.HandlerTest do
|
|||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "this is a test post"})
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{status: "this is a test post"})
|
||||
activity_object = Object.normalize(activity)
|
||||
|
||||
output =
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.BookmarkTest do
|
|||
describe "create/2" do
|
||||
test "with valid params" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "Some cool information"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "Some cool information"})
|
||||
{:ok, bookmark} = Bookmark.create(user.id, activity.id)
|
||||
assert bookmark.user_id == user.id
|
||||
assert bookmark.activity_id == activity.id
|
||||
|
|
@ -32,7 +32,7 @@ defmodule Pleroma.BookmarkTest do
|
|||
test "with valid params" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "Some cool information"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "Some cool information"})
|
||||
{:ok, _bookmark} = Bookmark.create(user.id, activity.id)
|
||||
|
||||
{:ok, _deleted_bookmark} = Bookmark.destroy(user.id, activity.id)
|
||||
|
|
@ -45,7 +45,7 @@ defmodule Pleroma.BookmarkTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" =>
|
||||
status:
|
||||
"Scientists Discover The Secret Behind Tenshi Eating A Corndog Being So Cute – Science Daily"
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ defmodule Pleroma.CaptchaTest do
|
|||
|
||||
assert is_binary(answer)
|
||||
assert :ok = Native.validate(token, answer, answer)
|
||||
assert {:error, "Invalid CAPTCHA"} == Native.validate(token, answer, answer <> "foobar")
|
||||
assert {:error, :invalid} == Native.validate(token, answer, answer <> "foobar")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -78,6 +78,7 @@ defmodule Pleroma.CaptchaTest do
|
|||
|
||||
assert is_binary(answer)
|
||||
assert :ok = Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer)
|
||||
Cachex.del(:used_captcha_cache, token)
|
||||
end
|
||||
|
||||
test "doesn't validate invalid answer" do
|
||||
|
|
@ -92,7 +93,7 @@ defmodule Pleroma.CaptchaTest do
|
|||
|
||||
assert is_binary(answer)
|
||||
|
||||
assert {:error, "Invalid answer data"} =
|
||||
assert {:error, :invalid_answer_data} =
|
||||
Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", answer <> "foobar")
|
||||
end
|
||||
|
||||
|
|
@ -108,7 +109,7 @@ defmodule Pleroma.CaptchaTest do
|
|||
|
||||
assert is_binary(answer)
|
||||
|
||||
assert {:error, "Invalid answer data"} =
|
||||
assert {:error, :invalid_answer_data} =
|
||||
Captcha.validate(token, "63615261b77f5354fb8c4e4986477555", nil)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -43,11 +43,9 @@ defmodule Pleroma.ConfigDBTest do
|
|||
{ConfigDB.from_string(saved.key), ConfigDB.from_binary(saved.value)}
|
||||
]
|
||||
|
||||
assert config[:quack] == [
|
||||
level: :info,
|
||||
meta: [:none],
|
||||
webhook_url: "https://hooks.slack.com/services/KEY/some_val"
|
||||
]
|
||||
assert config[:quack][:level] == :info
|
||||
assert config[:quack][:meta] == [:none]
|
||||
assert config[:quack][:webhook_url] == "https://hooks.slack.com/services/KEY/some_val"
|
||||
end
|
||||
|
||||
describe "update_or_create/1" do
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
refute Application.get_env(:pleroma, :test_key)
|
||||
refute Application.get_env(:idna, :test_key)
|
||||
refute Application.get_env(:quack, :test_key)
|
||||
refute Application.get_env(:postgrex, :test_key)
|
||||
initial = Application.get_env(:logger, :level)
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":pleroma",
|
||||
|
|
@ -35,16 +37,28 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
value: [:test_value1, :test_value2]
|
||||
})
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":postgrex",
|
||||
key: ":test_key",
|
||||
value: :value
|
||||
})
|
||||
|
||||
ConfigDB.create(%{group: ":logger", key: ":level", value: :debug})
|
||||
|
||||
TransferTask.start_link([])
|
||||
|
||||
assert Application.get_env(:pleroma, :test_key) == [live: 2, com: 3]
|
||||
assert Application.get_env(:idna, :test_key) == [live: 15, com: 35]
|
||||
assert Application.get_env(:quack, :test_key) == [:test_value1, :test_value2]
|
||||
assert Application.get_env(:logger, :level) == :debug
|
||||
assert Application.get_env(:postgrex, :test_key) == :value
|
||||
|
||||
on_exit(fn ->
|
||||
Application.delete_env(:pleroma, :test_key)
|
||||
Application.delete_env(:idna, :test_key)
|
||||
Application.delete_env(:quack, :test_key)
|
||||
Application.delete_env(:postgrex, :test_key)
|
||||
Application.put_env(:logger, :level, initial)
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
@ -78,8 +92,8 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
end
|
||||
|
||||
test "transfer config values with full subkey update" do
|
||||
emoji = Application.get_env(:pleroma, :emoji)
|
||||
assets = Application.get_env(:pleroma, :assets)
|
||||
clear_config(:emoji)
|
||||
clear_config(:assets)
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":pleroma",
|
||||
|
|
@ -99,11 +113,6 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
assert emoji_env[:groups] == [a: 1, b: 2]
|
||||
assets_env = Application.get_env(:pleroma, :assets)
|
||||
assert assets_env[:mascots] == [a: 1, b: 2]
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:pleroma, :emoji, emoji)
|
||||
Application.put_env(:pleroma, :assets, assets)
|
||||
end)
|
||||
end
|
||||
|
||||
describe "pleroma restart" do
|
||||
|
|
@ -112,8 +121,7 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
end
|
||||
|
||||
test "don't restart if no reboot time settings were changed" do
|
||||
emoji = Application.get_env(:pleroma, :emoji)
|
||||
on_exit(fn -> Application.put_env(:pleroma, :emoji, emoji) end)
|
||||
clear_config(:emoji)
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":pleroma",
|
||||
|
|
@ -128,8 +136,7 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
end
|
||||
|
||||
test "on reboot time key" do
|
||||
chat = Application.get_env(:pleroma, :chat)
|
||||
on_exit(fn -> Application.put_env(:pleroma, :chat, chat) end)
|
||||
clear_config(:chat)
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":pleroma",
|
||||
|
|
@ -141,8 +148,7 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
end
|
||||
|
||||
test "on reboot time subkey" do
|
||||
captcha = Application.get_env(:pleroma, Pleroma.Captcha)
|
||||
on_exit(fn -> Application.put_env(:pleroma, Pleroma.Captcha, captcha) end)
|
||||
clear_config(Pleroma.Captcha)
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":pleroma",
|
||||
|
|
@ -154,13 +160,8 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
end
|
||||
|
||||
test "don't restart pleroma on reboot time key and subkey if there is false flag" do
|
||||
chat = Application.get_env(:pleroma, :chat)
|
||||
captcha = Application.get_env(:pleroma, Pleroma.Captcha)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:pleroma, :chat, chat)
|
||||
Application.put_env(:pleroma, Pleroma.Captcha, captcha)
|
||||
end)
|
||||
clear_config(:chat)
|
||||
clear_config(Pleroma.Captcha)
|
||||
|
||||
ConfigDB.create(%{
|
||||
group: ":pleroma",
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{"status" => "Hey @#{other_user.nickname}.", "visibility" => "direct"})
|
||||
CommonAPI.post(user, %{status: "Hey @#{other_user.nickname}.", visibility: "direct"})
|
||||
|
||||
[participation] = Participation.for_user(user)
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
other_user = insert(:user)
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user, %{"status" => "Hey @#{other_user.nickname}.", "visibility" => "direct"})
|
||||
CommonAPI.post(user, %{status: "Hey @#{other_user.nickname}.", visibility: "direct"})
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
other_user = User.get_cached_by_id(other_user.id)
|
||||
|
|
@ -43,9 +43,9 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(other_user, %{
|
||||
"status" => "Hey @#{user.nickname}.",
|
||||
"visibility" => "direct",
|
||||
"in_reply_to_conversation_id" => participation.id
|
||||
status: "Hey @#{user.nickname}.",
|
||||
visibility: "direct",
|
||||
in_reply_to_conversation_id: participation.id
|
||||
})
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
|
|
@ -64,7 +64,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
third_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{"status" => "Hey @#{other_user.nickname}.", "visibility" => "direct"})
|
||||
CommonAPI.post(user, %{status: "Hey @#{other_user.nickname}.", visibility: "direct"})
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
other_user = User.get_cached_by_id(other_user.id)
|
||||
|
|
@ -79,9 +79,9 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"in_reply_to_status_id" => activity.id,
|
||||
"status" => "Hey @#{third_user.nickname}.",
|
||||
"visibility" => "direct"
|
||||
in_reply_to_status_id: activity.id,
|
||||
status: "Hey @#{third_user.nickname}.",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
[participation] = Participation.for_user(user)
|
||||
|
|
@ -154,14 +154,14 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
|
||||
test "gets all the participations for a user, ordered by updated at descending" do
|
||||
user = insert(:user)
|
||||
{:ok, activity_one} = CommonAPI.post(user, %{"status" => "x", "visibility" => "direct"})
|
||||
{:ok, activity_two} = CommonAPI.post(user, %{"status" => "x", "visibility" => "direct"})
|
||||
{:ok, activity_one} = CommonAPI.post(user, %{status: "x", visibility: "direct"})
|
||||
{:ok, activity_two} = CommonAPI.post(user, %{status: "x", visibility: "direct"})
|
||||
|
||||
{:ok, activity_three} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "x",
|
||||
"visibility" => "direct",
|
||||
"in_reply_to_status_id" => activity_one.id
|
||||
status: "x",
|
||||
visibility: "direct",
|
||||
in_reply_to_status_id: activity_one.id
|
||||
})
|
||||
|
||||
# Offset participations because the accuracy of updated_at is down to a second
|
||||
|
|
@ -201,7 +201,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
test "Doesn't die when the conversation gets empty" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
|
||||
[participation] = Participation.for_user_with_last_activity_id(user)
|
||||
|
||||
assert participation.last_activity_id == activity.id
|
||||
|
|
@ -215,7 +215,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"})
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
|
||||
[participation] = Participation.for_user_with_last_activity_id(user)
|
||||
|
||||
participation = Repo.preload(participation, :recipients)
|
||||
|
|
@ -239,26 +239,26 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
|
||||
{:ok, _direct1} =
|
||||
CommonAPI.post(third_user, %{
|
||||
"status" => "Hi @#{blocker.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{blocker.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
{:ok, _direct2} =
|
||||
CommonAPI.post(third_user, %{
|
||||
"status" => "Hi @#{blocker.nickname}, @#{blocked.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{blocker.nickname}, @#{blocked.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
{:ok, _direct3} =
|
||||
CommonAPI.post(blocked, %{
|
||||
"status" => "Hi @#{blocker.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{blocker.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
{:ok, _direct4} =
|
||||
CommonAPI.post(blocked, %{
|
||||
"status" => "Hi @#{blocker.nickname}, @#{third_user.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{blocker.nickname}, @#{third_user.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
assert [%{read: false}, %{read: false}, %{read: false}, %{read: false}] =
|
||||
|
|
@ -293,8 +293,8 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
# When the blocked user is the author
|
||||
{:ok, _direct1} =
|
||||
CommonAPI.post(blocked, %{
|
||||
"status" => "Hi @#{blocker.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{blocker.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
assert [%{read: true}] = Participation.for_user(blocker)
|
||||
|
|
@ -303,8 +303,8 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
# When the blocked user is a recipient
|
||||
{:ok, _direct2} =
|
||||
CommonAPI.post(third_user, %{
|
||||
"status" => "Hi @#{blocker.nickname}, @#{blocked.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{blocker.nickname}, @#{blocked.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
assert [%{read: true}, %{read: true}] = Participation.for_user(blocker)
|
||||
|
|
@ -321,8 +321,8 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
|
||||
{:ok, _direct1} =
|
||||
CommonAPI.post(blocker, %{
|
||||
"status" => "Hi @#{third_user.nickname}, @#{blocked.nickname}",
|
||||
"visibility" => "direct"
|
||||
status: "Hi @#{third_user.nickname}, @#{blocked.nickname}",
|
||||
visibility: "direct"
|
||||
})
|
||||
|
||||
{:ok, _user_relationship} = User.block(blocker, blocked)
|
||||
|
|
@ -334,9 +334,9 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
# When it's a reply from the blocked user
|
||||
{:ok, _direct2} =
|
||||
CommonAPI.post(blocked, %{
|
||||
"status" => "reply",
|
||||
"visibility" => "direct",
|
||||
"in_reply_to_conversation_id" => blocked_participation.id
|
||||
status: "reply",
|
||||
visibility: "direct",
|
||||
in_reply_to_conversation_id: blocked_participation.id
|
||||
})
|
||||
|
||||
assert [%{read: true}] = Participation.for_user(blocker)
|
||||
|
|
@ -347,9 +347,9 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
# When it's a reply from the third user
|
||||
{:ok, _direct3} =
|
||||
CommonAPI.post(third_user, %{
|
||||
"status" => "reply",
|
||||
"visibility" => "direct",
|
||||
"in_reply_to_conversation_id" => third_user_participation.id
|
||||
status: "reply",
|
||||
visibility: "direct",
|
||||
in_reply_to_conversation_id: third_user_participation.id
|
||||
})
|
||||
|
||||
assert [%{read: true}] = Participation.for_user(blocker)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ defmodule Pleroma.ConversationTest do
|
|||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{"visibility" => "direct", "status" => "hey @#{other_user.nickname}"})
|
||||
CommonAPI.post(user, %{visibility: "direct", status: "hey @#{other_user.nickname}"})
|
||||
|
||||
Pleroma.Tests.ObanHelpers.perform_all()
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ defmodule Pleroma.ConversationTest do
|
|||
|
||||
test "public posts don't create conversations" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "Hey"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "Hey"})
|
||||
|
||||
object = Pleroma.Object.normalize(activity)
|
||||
context = object.data["context"]
|
||||
|
|
@ -62,7 +62,7 @@ defmodule Pleroma.ConversationTest do
|
|||
tridi = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(har, %{"status" => "Hey @#{jafnhar.nickname}", "visibility" => "direct"})
|
||||
CommonAPI.post(har, %{status: "Hey @#{jafnhar.nickname}", visibility: "direct"})
|
||||
|
||||
object = Pleroma.Object.normalize(activity)
|
||||
context = object.data["context"]
|
||||
|
|
@ -81,9 +81,9 @@ defmodule Pleroma.ConversationTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(jafnhar, %{
|
||||
"status" => "Hey @#{har.nickname}",
|
||||
"visibility" => "direct",
|
||||
"in_reply_to_status_id" => activity.id
|
||||
status: "Hey @#{har.nickname}",
|
||||
visibility: "direct",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
object = Pleroma.Object.normalize(activity)
|
||||
|
|
@ -105,9 +105,9 @@ defmodule Pleroma.ConversationTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(tridi, %{
|
||||
"status" => "Hey @#{har.nickname}",
|
||||
"visibility" => "direct",
|
||||
"in_reply_to_status_id" => activity.id
|
||||
status: "Hey @#{har.nickname}",
|
||||
visibility: "direct",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
object = Pleroma.Object.normalize(activity)
|
||||
|
|
@ -149,14 +149,14 @@ defmodule Pleroma.ConversationTest do
|
|||
jafnhar = insert(:user, local: false)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(har, %{"status" => "Hey @#{jafnhar.nickname}", "visibility" => "direct"})
|
||||
CommonAPI.post(har, %{status: "Hey @#{jafnhar.nickname}", visibility: "direct"})
|
||||
|
||||
{:ok, conversation} = Conversation.create_or_bump_for(activity)
|
||||
|
||||
assert length(conversation.participations) == 2
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(har, %{"status" => "Hey @#{jafnhar.nickname}", "visibility" => "public"})
|
||||
CommonAPI.post(har, %{status: "Hey @#{jafnhar.nickname}", visibility: "public"})
|
||||
|
||||
assert {:error, _} = Conversation.create_or_bump_for(activity)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Emoji.FormatterTest do
|
||||
alias Pleroma.Emoji
|
||||
alias Pleroma.Emoji.Formatter
|
||||
use Pleroma.DataCase
|
||||
|
||||
|
|
@ -32,30 +31,19 @@ defmodule Pleroma.Emoji.FormatterTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "get_emoji" do
|
||||
describe "get_emoji_map" do
|
||||
test "it returns the emoji used in the text" do
|
||||
text = "I love :firefox:"
|
||||
|
||||
assert Formatter.get_emoji(text) == [
|
||||
{"firefox",
|
||||
%Emoji{
|
||||
code: "firefox",
|
||||
file: "/emoji/Firefox.gif",
|
||||
tags: ["Gif", "Fun"],
|
||||
safe_code: "firefox",
|
||||
safe_file: "/emoji/Firefox.gif"
|
||||
}}
|
||||
]
|
||||
assert Formatter.get_emoji_map("I love :firefox:") == %{
|
||||
"firefox" => "http://localhost:4001/emoji/Firefox.gif"
|
||||
}
|
||||
end
|
||||
|
||||
test "it returns a nice empty result when no emojis are present" do
|
||||
text = "I love moominamma"
|
||||
assert Formatter.get_emoji(text) == []
|
||||
assert Formatter.get_emoji_map("I love moominamma") == %{}
|
||||
end
|
||||
|
||||
test "it doesn't die when text is absent" do
|
||||
text = nil
|
||||
assert Formatter.get_emoji(text) == []
|
||||
assert Formatter.get_emoji_map(nil) == %{}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -141,17 +141,15 @@ defmodule Pleroma.FilterTest do
|
|||
context: ["home"]
|
||||
}
|
||||
|
||||
query_two = %Pleroma.Filter{
|
||||
user_id: user.id,
|
||||
filter_id: 1,
|
||||
changes = %{
|
||||
phrase: "who",
|
||||
context: ["home", "timeline"]
|
||||
}
|
||||
|
||||
{:ok, filter_one} = Pleroma.Filter.create(query_one)
|
||||
{:ok, filter_two} = Pleroma.Filter.update(query_two)
|
||||
{:ok, filter_two} = Pleroma.Filter.update(filter_one, changes)
|
||||
assert filter_one != filter_two
|
||||
assert filter_two.phrase == query_two.phrase
|
||||
assert filter_two.context == query_two.context
|
||||
assert filter_two.phrase == changes.phrase
|
||||
assert filter_two.context == changes.context
|
||||
end
|
||||
end
|
||||
|
|
|
|||
2
test/fixtures/config/temp.secret.exs
vendored
2
test/fixtures/config/temp.secret.exs
vendored
|
|
@ -7,3 +7,5 @@ config :pleroma, :second_setting, key: "value2", key2: ["Activity"]
|
|||
config :quack, level: :info
|
||||
|
||||
config :pleroma, Pleroma.Repo, pool: Ecto.Adapters.SQL.Sandbox
|
||||
|
||||
config :postgrex, :json_library, Poison
|
||||
|
|
|
|||
BIN
test/fixtures/emoji/packs/blank.png.zip
vendored
Normal file
BIN
test/fixtures/emoji/packs/blank.png.zip
vendored
Normal file
Binary file not shown.
10
test/fixtures/emoji/packs/default-manifest.json
vendored
Normal file
10
test/fixtures/emoji/packs/default-manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"finmoji": {
|
||||
"license": "CC BY-NC-ND 4.0",
|
||||
"homepage": "https://finland.fi/emoji/",
|
||||
"description": "Finland is the first country in the world to publish its own set of country themed emojis. The Finland emoji collection contains 56 tongue-in-cheek emotions, which were created to explain some hard-to-describe Finnish emotions, Finnish words and customs.",
|
||||
"src": "https://finland.fi/wp-content/uploads/2017/06/finland-emojis.zip",
|
||||
"src_sha256": "384025A1AC6314473863A11AC7AB38A12C01B851A3F82359B89B4D4211D3291D",
|
||||
"files": "finmoji.json"
|
||||
}
|
||||
}
|
||||
3
test/fixtures/emoji/packs/finmoji.json
vendored
Normal file
3
test/fixtures/emoji/packs/finmoji.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"blank": "blank.png"
|
||||
}
|
||||
10
test/fixtures/emoji/packs/manifest.json
vendored
Normal file
10
test/fixtures/emoji/packs/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"blobs.gg": {
|
||||
"src_sha256": "3a12f3a181678d5b3584a62095411b0d60a335118135910d879920f8ade5a57f",
|
||||
"src": "https://git.pleroma.social/pleroma/emoji-index/raw/master/packs/blobs_gg.zip",
|
||||
"license": "Apache 2.0",
|
||||
"homepage": "https://blobs.gg",
|
||||
"files": "blobs_gg.json",
|
||||
"description": "Blob Emoji from blobs.gg repacked as apng"
|
||||
}
|
||||
}
|
||||
112
test/fixtures/tesla_mock/craigmaloney.json
vendored
Normal file
112
test/fixtures/tesla_mock/craigmaloney.json
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"CacheFile": "pt:CacheFile",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"Infohash": "pt:Infohash",
|
||||
"RsaSignature2017": "https://w3id.org/security#RsaSignature2017",
|
||||
"category": "sc:category",
|
||||
"commentsEnabled": {
|
||||
"@id": "pt:commentsEnabled",
|
||||
"@type": "sc:Boolean"
|
||||
},
|
||||
"downloadEnabled": {
|
||||
"@id": "pt:downloadEnabled",
|
||||
"@type": "sc:Boolean"
|
||||
},
|
||||
"expires": "sc:expires",
|
||||
"fps": {
|
||||
"@id": "pt:fps",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"language": "sc:inLanguage",
|
||||
"licence": "sc:license",
|
||||
"originallyPublishedAt": "sc:datePublished",
|
||||
"position": {
|
||||
"@id": "pt:position",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"pt": "https://joinpeertube.org/ns#",
|
||||
"sc": "http://schema.org#",
|
||||
"sensitive": "as:sensitive",
|
||||
"size": {
|
||||
"@id": "pt:size",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"startTimestamp": {
|
||||
"@id": "pt:startTimestamp",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"state": {
|
||||
"@id": "pt:state",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"stopTimestamp": {
|
||||
"@id": "pt:stopTimestamp",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"subtitleLanguage": "sc:subtitleLanguage",
|
||||
"support": {
|
||||
"@id": "pt:support",
|
||||
"@type": "sc:Text"
|
||||
},
|
||||
"uuid": "sc:identifier",
|
||||
"views": {
|
||||
"@id": "pt:views",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"waitTranscoding": {
|
||||
"@id": "pt:waitTranscoding",
|
||||
"@type": "sc:Boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comments": {
|
||||
"@id": "as:comments",
|
||||
"@type": "@id"
|
||||
},
|
||||
"dislikes": {
|
||||
"@id": "as:dislikes",
|
||||
"@type": "@id"
|
||||
},
|
||||
"likes": {
|
||||
"@id": "as:likes",
|
||||
"@type": "@id"
|
||||
},
|
||||
"playlists": {
|
||||
"@id": "pt:playlists",
|
||||
"@type": "@id"
|
||||
},
|
||||
"shares": {
|
||||
"@id": "as:shares",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://peertube.social/inbox"
|
||||
},
|
||||
"followers": "https://peertube.social/accounts/craigmaloney/followers",
|
||||
"following": "https://peertube.social/accounts/craigmaloney/following",
|
||||
"icon": {
|
||||
"mediaType": "image/png",
|
||||
"type": "Image",
|
||||
"url": "https://peertube.social/lazy-static/avatars/87bd694b-95bc-4066-83f4-bddfcd2b9caa.png"
|
||||
},
|
||||
"id": "https://peertube.social/accounts/craigmaloney",
|
||||
"inbox": "https://peertube.social/accounts/craigmaloney/inbox",
|
||||
"name": "Craig Maloney",
|
||||
"outbox": "https://peertube.social/accounts/craigmaloney/outbox",
|
||||
"playlists": "https://peertube.social/accounts/craigmaloney/playlists",
|
||||
"preferredUsername": "craigmaloney",
|
||||
"publicKey": {
|
||||
"id": "https://peertube.social/accounts/craigmaloney#main-key",
|
||||
"owner": "https://peertube.social/accounts/craigmaloney",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9qvGIYUW01yc8CCsrwxK\n5OXlV5s7EbNWY8tJr/p1oGuELZwAnG2XKxtdbvgcCT+YxL5uRXIdCFIIIKrzRFr/\nHfS0mOgNT9u3gu+SstCNgtatciT0RVP77yiC3b2NHq1NRRvvVhzQb4cpIWObIxqh\nb2ypDClTc7XaKtgmQCbwZlGyZMT+EKz/vustD6BlpGsglRkm7iES6s1PPGb1BU+n\nS94KhbS2DOFiLcXCVWt0QarokIIuKznp4+xP1axKyP+SkT5AHx08Nd5TYFb2C1Jl\nz0WD/1q0mAN62m7QrA3SQPUgB+wWD+S3Nzf7FwNPiP4srbBgxVEUnji/r9mQ6BXC\nrQIDAQAB\n-----END PUBLIC KEY-----"
|
||||
},
|
||||
"summary": null,
|
||||
"type": "Person",
|
||||
"url": "https://peertube.social/accounts/craigmaloney"
|
||||
}
|
||||
44
test/fixtures/tesla_mock/funkwhale_audio.json
vendored
Normal file
44
test/fixtures/tesla_mock/funkwhale_audio.json
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"id": "https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871",
|
||||
"type": "Audio",
|
||||
"name": "Compositions - Test Audio for Pleroma",
|
||||
"attributedTo": "https://channels.tests.funkwhale.audio/federation/actors/compositions",
|
||||
"published": "2020-03-11T10:01:52.714918+00:00",
|
||||
"to": "https://www.w3.org/ns/activitystreams#Public",
|
||||
"url": [
|
||||
{
|
||||
"type": "Link",
|
||||
"mimeType": "audio/ogg",
|
||||
"href": "https://channels.tests.funkwhale.audio/api/v1/listen/3901e5d8-0445-49d5-9711-e096cf32e515/?upload=42342395-0208-4fee-a38d-259a6dae0871&download=false"
|
||||
},
|
||||
{
|
||||
"type": "Link",
|
||||
"mimeType": "text/html",
|
||||
"href": "https://channels.tests.funkwhale.audio/library/tracks/74"
|
||||
}
|
||||
],
|
||||
"content": "<p>This is a test Audio for Pleroma.</p>",
|
||||
"mediaType": "text/html",
|
||||
"tag": [
|
||||
{
|
||||
"type": "Hashtag",
|
||||
"name": "#funkwhale"
|
||||
},
|
||||
{
|
||||
"type": "Hashtag",
|
||||
"name": "#test"
|
||||
},
|
||||
{
|
||||
"type": "Hashtag",
|
||||
"name": "#tests"
|
||||
}
|
||||
],
|
||||
"summary": "#funkwhale #test #tests",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers"
|
||||
}
|
||||
]
|
||||
}
|
||||
44
test/fixtures/tesla_mock/funkwhale_channel.json
vendored
Normal file
44
test/fixtures/tesla_mock/funkwhale_channel.json
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"id": "https://channels.tests.funkwhale.audio/federation/actors/compositions",
|
||||
"outbox": "https://channels.tests.funkwhale.audio/federation/actors/compositions/outbox",
|
||||
"inbox": "https://channels.tests.funkwhale.audio/federation/actors/compositions/inbox",
|
||||
"preferredUsername": "compositions",
|
||||
"type": "Person",
|
||||
"name": "Compositions",
|
||||
"followers": "https://channels.tests.funkwhale.audio/federation/actors/compositions/followers",
|
||||
"following": "https://channels.tests.funkwhale.audio/federation/actors/compositions/following",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"url": [
|
||||
{
|
||||
"type": "Link",
|
||||
"href": "https://channels.tests.funkwhale.audio/channels/compositions",
|
||||
"mediaType": "text/html"
|
||||
},
|
||||
{
|
||||
"type": "Link",
|
||||
"href": "https://channels.tests.funkwhale.audio/api/v1/channels/compositions/rss",
|
||||
"mediaType": "application/rss+xml"
|
||||
}
|
||||
],
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "https://channels.tests.funkwhale.audio/media/attachments/75/b4/f1/nosmile.jpeg",
|
||||
"mediaType": "image/jpeg"
|
||||
},
|
||||
"summary": "<p>I'm testing federation with the fediverse :)</p>",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers"
|
||||
}
|
||||
],
|
||||
"publicKey": {
|
||||
"owner": "https://channels.tests.funkwhale.audio/federation/actors/compositions",
|
||||
"publicKeyPem": "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAv25u57oZfVLV3KltS+HcsdSx9Op4MmzIes1J8Wu8s0KbdXf2zEwS\nsVqyHgs/XCbnzsR3FqyJTo46D2BVnvZcuU5srNcR2I2HMaqQ0oVdnATE4K6KdcgV\nN+98pMWo56B8LTgE1VpvqbsrXLi9jCTzjrkebVMOP+ZVu+64v1qdgddseblYMnBZ\nct0s7ONbHnqrWlTGf5wES1uIZTVdn5r4MduZG+Uenfi1opBS0lUUxfWdW9r0oF2b\nyneZUyaUCbEroeKbqsweXCWVgnMarUOsgqC42KM4cf95lySSwTSaUtZYIbTw7s9W\n2jveU/rVg8BYZu5JK5obgBoxtlUeUoSswwIDAQAB\n-----END RSA PUBLIC KEY-----\n",
|
||||
"id": "https://channels.tests.funkwhale.audio/federation/actors/compositions#main-key"
|
||||
},
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://channels.tests.funkwhale.audio/federation/shared/inbox"
|
||||
}
|
||||
}
|
||||
234
test/fixtures/tesla_mock/peertube-social.json
vendored
Normal file
234
test/fixtures/tesla_mock/peertube-social.json
vendored
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"CacheFile": "pt:CacheFile",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"Infohash": "pt:Infohash",
|
||||
"RsaSignature2017": "https://w3id.org/security#RsaSignature2017",
|
||||
"category": "sc:category",
|
||||
"commentsEnabled": {
|
||||
"@id": "pt:commentsEnabled",
|
||||
"@type": "sc:Boolean"
|
||||
},
|
||||
"downloadEnabled": {
|
||||
"@id": "pt:downloadEnabled",
|
||||
"@type": "sc:Boolean"
|
||||
},
|
||||
"expires": "sc:expires",
|
||||
"fps": {
|
||||
"@id": "pt:fps",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"language": "sc:inLanguage",
|
||||
"licence": "sc:license",
|
||||
"originallyPublishedAt": "sc:datePublished",
|
||||
"position": {
|
||||
"@id": "pt:position",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"pt": "https://joinpeertube.org/ns#",
|
||||
"sc": "http://schema.org#",
|
||||
"sensitive": "as:sensitive",
|
||||
"size": {
|
||||
"@id": "pt:size",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"startTimestamp": {
|
||||
"@id": "pt:startTimestamp",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"state": {
|
||||
"@id": "pt:state",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"stopTimestamp": {
|
||||
"@id": "pt:stopTimestamp",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"subtitleLanguage": "sc:subtitleLanguage",
|
||||
"support": {
|
||||
"@id": "pt:support",
|
||||
"@type": "sc:Text"
|
||||
},
|
||||
"uuid": "sc:identifier",
|
||||
"views": {
|
||||
"@id": "pt:views",
|
||||
"@type": "sc:Number"
|
||||
},
|
||||
"waitTranscoding": {
|
||||
"@id": "pt:waitTranscoding",
|
||||
"@type": "sc:Boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"comments": {
|
||||
"@id": "as:comments",
|
||||
"@type": "@id"
|
||||
},
|
||||
"dislikes": {
|
||||
"@id": "as:dislikes",
|
||||
"@type": "@id"
|
||||
},
|
||||
"likes": {
|
||||
"@id": "as:likes",
|
||||
"@type": "@id"
|
||||
},
|
||||
"playlists": {
|
||||
"@id": "pt:playlists",
|
||||
"@type": "@id"
|
||||
},
|
||||
"shares": {
|
||||
"@id": "as:shares",
|
||||
"@type": "@id"
|
||||
}
|
||||
}
|
||||
],
|
||||
"attributedTo": [
|
||||
{
|
||||
"id": "https://peertube.social/accounts/craigmaloney",
|
||||
"type": "Person"
|
||||
},
|
||||
{
|
||||
"id": "https://peertube.social/video-channels/9909c7d9-6b5b-4aae-9164-c1af7229c91c",
|
||||
"type": "Group"
|
||||
}
|
||||
],
|
||||
"category": {
|
||||
"identifier": "15",
|
||||
"name": "Science & Technology"
|
||||
},
|
||||
"cc": [
|
||||
"https://peertube.social/accounts/craigmaloney/followers"
|
||||
],
|
||||
"comments": "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe/comments",
|
||||
"commentsEnabled": true,
|
||||
"content": "Support this and our other Michigan!/usr/group videos and meetings. Learn more at http://mug.org/membership\n\nTwenty Years in Jail: FreeBSD's Jails, Then and Now\n\nJails started as a limited virtualization system, but over the last two years they've...",
|
||||
"dislikes": "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe/dislikes",
|
||||
"downloadEnabled": true,
|
||||
"duration": "PT5151S",
|
||||
"icon": {
|
||||
"height": 122,
|
||||
"mediaType": "image/jpeg",
|
||||
"type": "Image",
|
||||
"url": "https://peertube.social/static/thumbnails/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe.jpg",
|
||||
"width": 223
|
||||
},
|
||||
"id": "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe",
|
||||
"language": {
|
||||
"identifier": "en",
|
||||
"name": "English"
|
||||
},
|
||||
"licence": {
|
||||
"identifier": "1",
|
||||
"name": "Attribution"
|
||||
},
|
||||
"likes": "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe/likes",
|
||||
"mediaType": "text/markdown",
|
||||
"name": "Twenty Years in Jail: FreeBSD's Jails, Then and Now",
|
||||
"originallyPublishedAt": "2019-08-13T00:00:00.000Z",
|
||||
"published": "2020-02-12T01:06:08.054Z",
|
||||
"sensitive": false,
|
||||
"shares": "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe/announces",
|
||||
"state": 1,
|
||||
"subtitleLanguage": [],
|
||||
"support": "Learn more at http://mug.org",
|
||||
"tag": [
|
||||
{
|
||||
"name": "linux",
|
||||
"type": "Hashtag"
|
||||
},
|
||||
{
|
||||
"name": "mug.org",
|
||||
"type": "Hashtag"
|
||||
},
|
||||
{
|
||||
"name": "open",
|
||||
"type": "Hashtag"
|
||||
},
|
||||
{
|
||||
"name": "oss",
|
||||
"type": "Hashtag"
|
||||
},
|
||||
{
|
||||
"name": "source",
|
||||
"type": "Hashtag"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type": "Video",
|
||||
"updated": "2020-02-15T15:01:09.474Z",
|
||||
"url": [
|
||||
{
|
||||
"href": "https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe",
|
||||
"mediaType": "text/html",
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"fps": 30,
|
||||
"height": 240,
|
||||
"href": "https://peertube.social/static/webseed/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-240.mp4",
|
||||
"mediaType": "video/mp4",
|
||||
"size": 119465800,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"height": 240,
|
||||
"href": "https://peertube.social/static/torrents/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-240.torrent",
|
||||
"mediaType": "application/x-bittorrent",
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"height": 240,
|
||||
"href": "magnet:?xs=https%3A%2F%2Fpeertube.social%2Fstatic%2Ftorrents%2F278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-240.torrent&xt=urn:btih:b3365331a8543bf48d09add56d7fe4b1cbbb5659&dn=Twenty+Years+in+Jail%3A+FreeBSD's+Jails%2C+Then+and+Now&tr=wss%3A%2F%2Fpeertube.social%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.social%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.social%2Fstatic%2Fwebseed%2F278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-240.mp4",
|
||||
"mediaType": "application/x-bittorrent;x-scheme-handler/magnet",
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"fps": 30,
|
||||
"height": 360,
|
||||
"href": "https://peertube.social/static/webseed/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-360.mp4",
|
||||
"mediaType": "video/mp4",
|
||||
"size": 143930318,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"height": 360,
|
||||
"href": "https://peertube.social/static/torrents/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-360.torrent",
|
||||
"mediaType": "application/x-bittorrent",
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"height": 360,
|
||||
"href": "magnet:?xs=https%3A%2F%2Fpeertube.social%2Fstatic%2Ftorrents%2F278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-360.torrent&xt=urn:btih:0d37b23c98cb0d89e28b5dc8f49b3c97a041e569&dn=Twenty+Years+in+Jail%3A+FreeBSD's+Jails%2C+Then+and+Now&tr=wss%3A%2F%2Fpeertube.social%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.social%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.social%2Fstatic%2Fwebseed%2F278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-360.mp4",
|
||||
"mediaType": "application/x-bittorrent;x-scheme-handler/magnet",
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"fps": 30,
|
||||
"height": 480,
|
||||
"href": "https://peertube.social/static/webseed/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-480.mp4",
|
||||
"mediaType": "video/mp4",
|
||||
"size": 130530754,
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"height": 480,
|
||||
"href": "https://peertube.social/static/torrents/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-480.torrent",
|
||||
"mediaType": "application/x-bittorrent",
|
||||
"type": "Link"
|
||||
},
|
||||
{
|
||||
"height": 480,
|
||||
"href": "magnet:?xs=https%3A%2F%2Fpeertube.social%2Fstatic%2Ftorrents%2F278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-480.torrent&xt=urn:btih:3a13ff822ad9494165eff6167183ddaaabc1372a&dn=Twenty+Years+in+Jail%3A+FreeBSD's+Jails%2C+Then+and+Now&tr=wss%3A%2F%2Fpeertube.social%3A443%2Ftracker%2Fsocket&tr=https%3A%2F%2Fpeertube.social%2Ftracker%2Fannounce&ws=https%3A%2F%2Fpeertube.social%2Fstatic%2Fwebseed%2F278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe-480.mp4",
|
||||
"mediaType": "application/x-bittorrent;x-scheme-handler/magnet",
|
||||
"type": "Link"
|
||||
}
|
||||
],
|
||||
"uuid": "278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe",
|
||||
"views": 2,
|
||||
"waitTranscoding": false
|
||||
}
|
||||
41
test/fixtures/users_mock/localhost.json
vendored
Normal file
41
test/fixtures/users_mock/localhost.json
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"http://localhost:4001/schemas/litepub-0.1.jsonld",
|
||||
{
|
||||
"@language": "und"
|
||||
}
|
||||
],
|
||||
"attachment": [],
|
||||
"endpoints": {
|
||||
"oauthAuthorizationEndpoint": "http://localhost:4001/oauth/authorize",
|
||||
"oauthRegistrationEndpoint": "http://localhost:4001/api/v1/apps",
|
||||
"oauthTokenEndpoint": "http://localhost:4001/oauth/token",
|
||||
"sharedInbox": "http://localhost:4001/inbox"
|
||||
},
|
||||
"followers": "http://localhost:4001/users/{{nickname}}/followers",
|
||||
"following": "http://localhost:4001/users/{{nickname}}/following",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "http://localhost:4001/media/4e914f5b84e4a259a3f6c2d2edc9ab642f2ab05f3e3d9c52c81fc2d984b3d51e.jpg"
|
||||
},
|
||||
"id": "http://localhost:4001/users/{{nickname}}",
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"url": "http://localhost:4001/media/f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg?name=f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg"
|
||||
},
|
||||
"inbox": "http://localhost:4001/users/{{nickname}}/inbox",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"name": "{{nickname}}",
|
||||
"outbox": "http://localhost:4001/users/{{nickname}}/outbox",
|
||||
"preferredUsername": "{{nickname}}",
|
||||
"publicKey": {
|
||||
"id": "http://localhost:4001/users/{{nickname}}#main-key",
|
||||
"owner": "http://localhost:4001/users/{{nickname}}",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5DLtwGXNZElJyxFGfcVc\nXANhaMadj/iYYQwZjOJTV9QsbtiNBeIK54PJrYuU0/0YIdrvS1iqheX5IwXRhcwa\nhm3ZyLz7XeN9st7FBni4BmZMBtMpxAuYuu5p/jbWy13qAiYOhPreCx0wrWgm/lBD\n9mkgaxIxPooBE0S4ZWEJIDIV1Vft3AWcRUyWW1vIBK0uZzs6GYshbQZB952S0yo4\nFzI1hABGHncH8UvuFauh4EZ8tY7/X5I0pGRnDOcRN1dAht5w5yTA+6r5kebiFQjP\nIzN/eCO/a9Flrj9YGW7HDNtjSOH0A31PLRGlJtJO3yK57dnf5ppyCZGfL4emShQo\ncQIDAQAB\n-----END PUBLIC KEY-----\n\n"
|
||||
},
|
||||
"summary": "your friendly neighborhood pleroma developer<br>I like cute things and distributed systems, and really hate delete and redrafts",
|
||||
"tag": [],
|
||||
"type": "Person",
|
||||
"url": "http://localhost:4001/users/{{nickname}}"
|
||||
}
|
||||
1
test/fixtures/warnings/otp_version/21.1
vendored
Normal file
1
test/fixtures/warnings/otp_version/21.1
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
21.1
|
||||
1
test/fixtures/warnings/otp_version/22.1
vendored
Normal file
1
test/fixtures/warnings/otp_version/22.1
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
22.1
|
||||
1
test/fixtures/warnings/otp_version/22.4
vendored
Normal file
1
test/fixtures/warnings/otp_version/22.4
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
22.4
|
||||
1
test/fixtures/warnings/otp_version/23.0
vendored
Normal file
1
test/fixtures/warnings/otp_version/23.0
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
23.0
|
||||
|
|
@ -15,28 +15,28 @@ defmodule Pleroma.FollowingRelationshipTest do
|
|||
test "returns following addresses without internal.fetch" do
|
||||
user = insert(:user)
|
||||
fetch_actor = InternalFetchActor.get_actor()
|
||||
FollowingRelationship.follow(fetch_actor, user, "accept")
|
||||
FollowingRelationship.follow(fetch_actor, user, :follow_accept)
|
||||
assert FollowingRelationship.following(fetch_actor) == [user.follower_address]
|
||||
end
|
||||
|
||||
test "returns following addresses without relay" do
|
||||
user = insert(:user)
|
||||
relay_actor = Relay.get_actor()
|
||||
FollowingRelationship.follow(relay_actor, user, "accept")
|
||||
FollowingRelationship.follow(relay_actor, user, :follow_accept)
|
||||
assert FollowingRelationship.following(relay_actor) == [user.follower_address]
|
||||
end
|
||||
|
||||
test "returns following addresses without remote user" do
|
||||
user = insert(:user)
|
||||
actor = insert(:user, local: false)
|
||||
FollowingRelationship.follow(actor, user, "accept")
|
||||
FollowingRelationship.follow(actor, user, :follow_accept)
|
||||
assert FollowingRelationship.following(actor) == [user.follower_address]
|
||||
end
|
||||
|
||||
test "returns following addresses with local user" do
|
||||
user = insert(:user)
|
||||
actor = insert(:user, local: true)
|
||||
FollowingRelationship.follow(actor, user, "accept")
|
||||
FollowingRelationship.follow(actor, user, :follow_accept)
|
||||
|
||||
assert FollowingRelationship.following(actor) == [
|
||||
actor.follower_address,
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ defmodule Pleroma.FormatterTest do
|
|||
archaeme =
|
||||
insert(:user,
|
||||
nickname: "archa_eme_",
|
||||
source_data: %{"url" => "https://archeme/@archa_eme_"}
|
||||
uri: "https://archeme/@archa_eme_"
|
||||
)
|
||||
|
||||
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
|
||||
|
|
@ -150,13 +150,13 @@ defmodule Pleroma.FormatterTest do
|
|||
assert length(mentions) == 3
|
||||
|
||||
expected_text =
|
||||
~s(<span class="h-card"><a data-user="#{gsimg.id}" class="u-url mention" href="#{
|
||||
~s(<span class="h-card"><a class="u-url mention" data-user="#{gsimg.id}" href="#{
|
||||
gsimg.ap_id
|
||||
}" rel="ugc">@<span>gsimg</span></a></span> According to <span class="h-card"><a data-user="#{
|
||||
}" rel="ugc">@<span>gsimg</span></a></span> According to <span class="h-card"><a class="u-url mention" data-user="#{
|
||||
archaeme.id
|
||||
}" class="u-url mention" href="#{"https://archeme/@archa_eme_"}" rel="ugc">@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class="h-card"><a data-user="#{
|
||||
}" href="#{"https://archeme/@archa_eme_"}" rel="ugc">@<span>archa_eme_</span></a></span>, that is @daggsy. Also hello <span class="h-card"><a class="u-url mention" data-user="#{
|
||||
archaeme_remote.id
|
||||
}" class="u-url mention" href="#{archaeme_remote.ap_id}" rel="ugc">@<span>archaeme</span></a></span>)
|
||||
}" href="#{archaeme_remote.ap_id}" rel="ugc">@<span>archaeme</span></a></span>)
|
||||
|
||||
assert expected_text == text
|
||||
end
|
||||
|
|
@ -171,7 +171,7 @@ defmodule Pleroma.FormatterTest do
|
|||
assert length(mentions) == 1
|
||||
|
||||
expected_text =
|
||||
~s(<span class="h-card"><a data-user="#{mike.id}" class="u-url mention" href="#{
|
||||
~s(<span class="h-card"><a class="u-url mention" data-user="#{mike.id}" href="#{
|
||||
mike.ap_id
|
||||
}" rel="ugc">@<span>mike</span></a></span> test)
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ defmodule Pleroma.FormatterTest do
|
|||
assert length(mentions) == 1
|
||||
|
||||
expected_text =
|
||||
~s(<span class="h-card"><a data-user="#{o.id}" class="u-url mention" href="#{o.ap_id}" rel="ugc">@<span>o</span></a></span> hi)
|
||||
~s(<span class="h-card"><a class="u-url mention" data-user="#{o.id}" href="#{o.ap_id}" rel="ugc">@<span>o</span></a></span> hi)
|
||||
|
||||
assert expected_text == text
|
||||
end
|
||||
|
|
@ -209,17 +209,13 @@ defmodule Pleroma.FormatterTest do
|
|||
assert mentions == [{"@#{user.nickname}", user}, {"@#{other_user.nickname}", other_user}]
|
||||
|
||||
assert expected_text ==
|
||||
~s(<span class="h-card"><a data-user="#{user.id}" class="u-url mention" href="#{
|
||||
~s(<span class="h-card"><a class="u-url mention" data-user="#{user.id}" href="#{
|
||||
user.ap_id
|
||||
}" rel="ugc">@<span>#{user.nickname}</span></a></span> <span class="h-card"><a data-user="#{
|
||||
}" rel="ugc">@<span>#{user.nickname}</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{
|
||||
other_user.id
|
||||
}" class="u-url mention" href="#{other_user.ap_id}" rel="ugc">@<span>#{
|
||||
other_user.nickname
|
||||
}</span></a></span> hey dudes i hate <span class="h-card"><a data-user="#{
|
||||
}" href="#{other_user.ap_id}" rel="ugc">@<span>#{other_user.nickname}</span></a></span> hey dudes i hate <span class="h-card"><a class="u-url mention" data-user="#{
|
||||
third_user.id
|
||||
}" class="u-url mention" href="#{third_user.ap_id}" rel="ugc">@<span>#{
|
||||
third_user.nickname
|
||||
}</span></a></span>)
|
||||
}" href="#{third_user.ap_id}" rel="ugc">@<span>#{third_user.nickname}</span></a></span>)
|
||||
end
|
||||
|
||||
test "given the 'safe_mention' option, it will still work without any mention" do
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ defmodule Pleroma.HTMLTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" =>
|
||||
status:
|
||||
"I think I just found the best github repo https://github.com/komeiji-satori/Dress"
|
||||
})
|
||||
|
||||
|
|
@ -186,7 +186,7 @@ defmodule Pleroma.HTMLTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" =>
|
||||
status:
|
||||
"@#{other_user.nickname} install misskey! https://github.com/syuilo/misskey/blob/develop/docs/setup.en.md"
|
||||
})
|
||||
|
||||
|
|
@ -203,8 +203,7 @@ defmodule Pleroma.HTMLTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" =>
|
||||
"#cofe https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
|
||||
status: "#cofe https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140"
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
|
@ -218,9 +217,9 @@ defmodule Pleroma.HTMLTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" =>
|
||||
status:
|
||||
"<a href=\"https://pleroma.gov/tags/cofe\" rel=\"tag\">#cofe</a> https://www.pixiv.net/member_illust.php?mode=medium&illust_id=72255140",
|
||||
"content_type" => "text/html"
|
||||
content_type: "text/html"
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
|
@ -232,8 +231,7 @@ defmodule Pleroma.HTMLTest do
|
|||
test "does not crash when there is an HTML entity in a link" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{"status" => "\"http://cofe.com/?boomer=ok&foo=bar\""})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "\"http://cofe.com/?boomer=ok&foo=bar\""})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
|
|
|
|||
258
test/http/adapter_helper/gun_test.exs
Normal file
258
test/http/adapter_helper/gun_test.exs
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper.GunTest do
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import Mox
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Gun.Conn
|
||||
alias Pleroma.HTTP.AdapterHelper.Gun
|
||||
alias Pleroma.Pool.Connections
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
defp gun_mock(_) do
|
||||
gun_mock()
|
||||
:ok
|
||||
end
|
||||
|
||||
defp gun_mock do
|
||||
Pleroma.GunMock
|
||||
|> stub(:open, fn _, _, _ -> Task.start_link(fn -> Process.sleep(1000) end) end)
|
||||
|> stub(:await_up, fn _, _ -> {:ok, :http} end)
|
||||
|> stub(:set_owner, fn _, _ -> :ok end)
|
||||
end
|
||||
|
||||
describe "options/1" do
|
||||
setup do: clear_config([:http, :adapter], a: 1, b: 2)
|
||||
|
||||
test "https url with default port" do
|
||||
uri = URI.parse("https://example.com")
|
||||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:certificates_verification]
|
||||
assert opts[:tls_opts][:log_level] == :warning
|
||||
end
|
||||
|
||||
test "https ipv4 with default port" do
|
||||
uri = URI.parse("https://127.0.0.1")
|
||||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:certificates_verification]
|
||||
assert opts[:tls_opts][:log_level] == :warning
|
||||
end
|
||||
|
||||
test "https ipv6 with default port" do
|
||||
uri = URI.parse("https://[2a03:2880:f10c:83:face:b00c:0:25de]")
|
||||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:certificates_verification]
|
||||
assert opts[:tls_opts][:log_level] == :warning
|
||||
end
|
||||
|
||||
test "https url with non standart port" do
|
||||
uri = URI.parse("https://example.com:115")
|
||||
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
|
||||
assert opts[:certificates_verification]
|
||||
end
|
||||
|
||||
test "get conn on next request" do
|
||||
gun_mock()
|
||||
level = Application.get_env(:logger, :level)
|
||||
Logger.configure(level: :debug)
|
||||
on_exit(fn -> Logger.configure(level: level) end)
|
||||
uri = URI.parse("http://some-domain2.com")
|
||||
|
||||
opts = Gun.options(uri)
|
||||
|
||||
assert opts[:conn] == nil
|
||||
assert opts[:close_conn] == nil
|
||||
|
||||
Process.sleep(50)
|
||||
opts = Gun.options(uri)
|
||||
|
||||
assert is_pid(opts[:conn])
|
||||
assert opts[:close_conn] == false
|
||||
end
|
||||
|
||||
test "merges with defaul http adapter config" do
|
||||
defaults = Gun.options([receive_conn: false], URI.parse("https://example.com"))
|
||||
assert Keyword.has_key?(defaults, :a)
|
||||
assert Keyword.has_key?(defaults, :b)
|
||||
end
|
||||
|
||||
test "default ssl adapter opts with connection" do
|
||||
gun_mock()
|
||||
uri = URI.parse("https://some-domain.com")
|
||||
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
opts = Gun.options(uri)
|
||||
|
||||
assert opts[:certificates_verification]
|
||||
refute opts[:tls_opts] == []
|
||||
|
||||
assert opts[:close_conn] == false
|
||||
assert is_pid(opts[:conn])
|
||||
end
|
||||
|
||||
test "parses string proxy host & port" do
|
||||
proxy = Config.get([:http, :proxy_url])
|
||||
Config.put([:http, :proxy_url], "localhost:8123")
|
||||
on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
|
||||
|
||||
uri = URI.parse("https://some-domain.com")
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:proxy] == {'localhost', 8123}
|
||||
end
|
||||
|
||||
test "parses tuple proxy scheme host and port" do
|
||||
proxy = Config.get([:http, :proxy_url])
|
||||
Config.put([:http, :proxy_url], {:socks, 'localhost', 1234})
|
||||
on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
|
||||
|
||||
uri = URI.parse("https://some-domain.com")
|
||||
opts = Gun.options([receive_conn: false], uri)
|
||||
assert opts[:proxy] == {:socks, 'localhost', 1234}
|
||||
end
|
||||
|
||||
test "passed opts have more weight than defaults" do
|
||||
proxy = Config.get([:http, :proxy_url])
|
||||
Config.put([:http, :proxy_url], {:socks5, 'localhost', 1234})
|
||||
on_exit(fn -> Config.put([:http, :proxy_url], proxy) end)
|
||||
uri = URI.parse("https://some-domain.com")
|
||||
opts = Gun.options([receive_conn: false, proxy: {'example.com', 4321}], uri)
|
||||
|
||||
assert opts[:proxy] == {'example.com', 4321}
|
||||
end
|
||||
end
|
||||
|
||||
describe "options/1 with receive_conn parameter" do
|
||||
setup :gun_mock
|
||||
|
||||
test "receive conn by default" do
|
||||
uri = URI.parse("http://another-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
received_opts = Gun.options(uri)
|
||||
assert received_opts[:close_conn] == false
|
||||
assert is_pid(received_opts[:conn])
|
||||
end
|
||||
|
||||
test "don't receive conn if receive_conn is false" do
|
||||
uri = URI.parse("http://another-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
opts = [receive_conn: false]
|
||||
received_opts = Gun.options(opts, uri)
|
||||
assert received_opts[:close_conn] == nil
|
||||
assert received_opts[:conn] == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "after_request/1" do
|
||||
setup :gun_mock
|
||||
|
||||
test "body_as not chunks" do
|
||||
uri = URI.parse("http://some-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options(uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:some-domain.com:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :idle,
|
||||
used_by: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "body_as chunks" do
|
||||
uri = URI.parse("http://some-domain.com")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options([body_as: :chunks], uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
self = self()
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:some-domain.com:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "with no connection" do
|
||||
uri = URI.parse("http://uniq-domain.com")
|
||||
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
|
||||
opts = Gun.options([body_as: :chunks], uri)
|
||||
conn = opts[:conn]
|
||||
opts = Keyword.delete(opts, :conn)
|
||||
self = self()
|
||||
|
||||
:ok = Gun.after_request(opts)
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:uniq-domain.com:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "with ipv4" do
|
||||
uri = URI.parse("http://127.0.0.1")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options(uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :idle,
|
||||
used_by: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
|
||||
test "with ipv6" do
|
||||
uri = URI.parse("http://[2a03:2880:f10c:83:face:b00c:0:25de]")
|
||||
:ok = Conn.open(uri, :gun_connections)
|
||||
opts = Gun.options(uri)
|
||||
:ok = Gun.after_request(opts)
|
||||
conn = opts[:conn]
|
||||
|
||||
assert %Connections{
|
||||
conns: %{
|
||||
"http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Pleroma.Gun.Conn{
|
||||
conn: ^conn,
|
||||
conn_state: :idle,
|
||||
used_by: []
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(:gun_connections)
|
||||
end
|
||||
end
|
||||
end
|
||||
47
test/http/adapter_helper/hackney_test.exs
Normal file
47
test/http/adapter_helper/hackney_test.exs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper.HackneyTest do
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
alias Pleroma.HTTP.AdapterHelper.Hackney
|
||||
|
||||
setup_all do
|
||||
uri = URI.parse("http://domain.com")
|
||||
{:ok, uri: uri}
|
||||
end
|
||||
|
||||
describe "options/2" do
|
||||
setup do: clear_config([:http, :adapter], a: 1, b: 2)
|
||||
|
||||
test "add proxy and opts from config", %{uri: uri} do
|
||||
opts = Hackney.options([proxy: "localhost:8123"], uri)
|
||||
|
||||
assert opts[:a] == 1
|
||||
assert opts[:b] == 2
|
||||
assert opts[:proxy] == "localhost:8123"
|
||||
end
|
||||
|
||||
test "respect connection opts and no proxy", %{uri: uri} do
|
||||
opts = Hackney.options([a: 2, b: 1], uri)
|
||||
|
||||
assert opts[:a] == 2
|
||||
assert opts[:b] == 1
|
||||
refute Keyword.has_key?(opts, :proxy)
|
||||
end
|
||||
|
||||
test "add opts for https" do
|
||||
uri = URI.parse("https://domain.com")
|
||||
|
||||
opts = Hackney.options(uri)
|
||||
|
||||
assert opts[:ssl_options] == [
|
||||
partial_chain: &:hackney_connect.partial_chain/1,
|
||||
versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"],
|
||||
server_name_indication: 'domain.com'
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
28
test/http/adapter_helper_test.exs
Normal file
28
test/http/adapter_helper_test.exs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelperTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pleroma.HTTP.AdapterHelper
|
||||
|
||||
describe "format_proxy/1" do
|
||||
test "with nil" do
|
||||
assert AdapterHelper.format_proxy(nil) == nil
|
||||
end
|
||||
|
||||
test "with string" do
|
||||
assert AdapterHelper.format_proxy("127.0.0.1:8123") == {{127, 0, 0, 1}, 8123}
|
||||
end
|
||||
|
||||
test "localhost with port" do
|
||||
assert AdapterHelper.format_proxy("localhost:8123") == {'localhost', 8123}
|
||||
end
|
||||
|
||||
test "tuple" do
|
||||
assert AdapterHelper.format_proxy({:socks4, :localhost, 9050}) ==
|
||||
{:socks4, 'localhost', 9050}
|
||||
end
|
||||
end
|
||||
end
|
||||
135
test/http/connection_test.exs
Normal file
135
test/http/connection_test.exs
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.ConnectionTest do
|
||||
use ExUnit.Case
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.HTTP.Connection
|
||||
|
||||
describe "parse_host/1" do
|
||||
test "as atom to charlist" do
|
||||
assert Connection.parse_host(:localhost) == 'localhost'
|
||||
end
|
||||
|
||||
test "as string to charlist" do
|
||||
assert Connection.parse_host("localhost.com") == 'localhost.com'
|
||||
end
|
||||
|
||||
test "as string ip to tuple" do
|
||||
assert Connection.parse_host("127.0.0.1") == {127, 0, 0, 1}
|
||||
end
|
||||
end
|
||||
|
||||
describe "parse_proxy/1" do
|
||||
test "ip with port" do
|
||||
assert Connection.parse_proxy("127.0.0.1:8123") == {:ok, {127, 0, 0, 1}, 8123}
|
||||
end
|
||||
|
||||
test "host with port" do
|
||||
assert Connection.parse_proxy("localhost:8123") == {:ok, 'localhost', 8123}
|
||||
end
|
||||
|
||||
test "as tuple" do
|
||||
assert Connection.parse_proxy({:socks4, :localhost, 9050}) ==
|
||||
{:ok, :socks4, 'localhost', 9050}
|
||||
end
|
||||
|
||||
test "as tuple with string host" do
|
||||
assert Connection.parse_proxy({:socks5, "localhost", 9050}) ==
|
||||
{:ok, :socks5, 'localhost', 9050}
|
||||
end
|
||||
end
|
||||
|
||||
describe "parse_proxy/1 errors" do
|
||||
test "ip without port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("127.0.0.1") == {:error, :invalid_proxy}
|
||||
end) =~ "parsing proxy fail \"127.0.0.1\""
|
||||
end
|
||||
|
||||
test "host without port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("localhost") == {:error, :invalid_proxy}
|
||||
end) =~ "parsing proxy fail \"localhost\""
|
||||
end
|
||||
|
||||
test "host with bad port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("localhost:port") == {:error, :invalid_proxy_port}
|
||||
end) =~ "parsing port in proxy fail \"localhost:port\""
|
||||
end
|
||||
|
||||
test "ip with bad port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy("127.0.0.1:15.9") == {:error, :invalid_proxy_port}
|
||||
end) =~ "parsing port in proxy fail \"127.0.0.1:15.9\""
|
||||
end
|
||||
|
||||
test "as tuple without port" do
|
||||
capture_log(fn ->
|
||||
assert Connection.parse_proxy({:socks5, :localhost}) == {:error, :invalid_proxy}
|
||||
end) =~ "parsing proxy fail {:socks5, :localhost}"
|
||||
end
|
||||
|
||||
test "with nil" do
|
||||
assert Connection.parse_proxy(nil) == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "options/3" do
|
||||
setup do: clear_config([:http, :proxy_url])
|
||||
|
||||
test "without proxy_url in config" do
|
||||
Config.delete([:http, :proxy_url])
|
||||
|
||||
opts = Connection.options(%URI{})
|
||||
refute Keyword.has_key?(opts, :proxy)
|
||||
end
|
||||
|
||||
test "parses string proxy host & port" do
|
||||
Config.put([:http, :proxy_url], "localhost:8123")
|
||||
|
||||
opts = Connection.options(%URI{})
|
||||
assert opts[:proxy] == {'localhost', 8123}
|
||||
end
|
||||
|
||||
test "parses tuple proxy scheme host and port" do
|
||||
Config.put([:http, :proxy_url], {:socks, 'localhost', 1234})
|
||||
|
||||
opts = Connection.options(%URI{})
|
||||
assert opts[:proxy] == {:socks, 'localhost', 1234}
|
||||
end
|
||||
|
||||
test "passed opts have more weight than defaults" do
|
||||
Config.put([:http, :proxy_url], {:socks5, 'localhost', 1234})
|
||||
|
||||
opts = Connection.options(%URI{}, proxy: {'example.com', 4321})
|
||||
|
||||
assert opts[:proxy] == {'example.com', 4321}
|
||||
end
|
||||
end
|
||||
|
||||
describe "format_host/1" do
|
||||
test "with domain" do
|
||||
assert Connection.format_host("example.com") == 'example.com'
|
||||
end
|
||||
|
||||
test "with idna domain" do
|
||||
assert Connection.format_host("ですexample.com") == 'xn--example-183fne.com'
|
||||
end
|
||||
|
||||
test "with ipv4" do
|
||||
assert Connection.format_host("127.0.0.1") == '127.0.0.1'
|
||||
end
|
||||
|
||||
test "with ipv6" do
|
||||
assert Connection.format_host("2a03:2880:f10c:83:face:b00c:0:25de") ==
|
||||
'2a03:2880:f10c:83:face:b00c:0:25de'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,57 +3,38 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.RequestBuilderTest do
|
||||
use ExUnit.Case, async: true
|
||||
use ExUnit.Case
|
||||
use Pleroma.Tests.Helpers
|
||||
alias Pleroma.HTTP.Request
|
||||
alias Pleroma.HTTP.RequestBuilder
|
||||
|
||||
describe "headers/2" do
|
||||
setup do: clear_config([:http, :send_user_agent])
|
||||
setup do: clear_config([:http, :user_agent])
|
||||
|
||||
test "don't send pleroma user agent" do
|
||||
assert RequestBuilder.headers(%{}, []) == %{headers: []}
|
||||
assert RequestBuilder.headers(%Request{}, []) == %Request{headers: []}
|
||||
end
|
||||
|
||||
test "send pleroma user agent" do
|
||||
Pleroma.Config.put([:http, :send_user_agent], true)
|
||||
Pleroma.Config.put([:http, :user_agent], :default)
|
||||
clear_config([:http, :send_user_agent], true)
|
||||
clear_config([:http, :user_agent], :default)
|
||||
|
||||
assert RequestBuilder.headers(%{}, []) == %{
|
||||
headers: [{"User-Agent", Pleroma.Application.user_agent()}]
|
||||
assert RequestBuilder.headers(%Request{}, []) == %Request{
|
||||
headers: [{"user-agent", Pleroma.Application.user_agent()}]
|
||||
}
|
||||
end
|
||||
|
||||
test "send custom user agent" do
|
||||
Pleroma.Config.put([:http, :send_user_agent], true)
|
||||
Pleroma.Config.put([:http, :user_agent], "totally-not-pleroma")
|
||||
clear_config([:http, :send_user_agent], true)
|
||||
clear_config([:http, :user_agent], "totally-not-pleroma")
|
||||
|
||||
assert RequestBuilder.headers(%{}, []) == %{
|
||||
headers: [{"User-Agent", "totally-not-pleroma"}]
|
||||
assert RequestBuilder.headers(%Request{}, []) == %Request{
|
||||
headers: [{"user-agent", "totally-not-pleroma"}]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "add_optional_params/3" do
|
||||
test "don't add if keyword is empty" do
|
||||
assert RequestBuilder.add_optional_params(%{}, %{}, []) == %{}
|
||||
end
|
||||
|
||||
test "add query parameter" do
|
||||
assert RequestBuilder.add_optional_params(
|
||||
%{},
|
||||
%{query: :query, body: :body, another: :val},
|
||||
[
|
||||
{:query, "param1=val1¶m2=val2"},
|
||||
{:body, "some body"}
|
||||
]
|
||||
) == %{query: "param1=val1¶m2=val2", body: "some body"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "add_param/4" do
|
||||
test "add file parameter" do
|
||||
%{
|
||||
%Request{
|
||||
body: %Tesla.Multipart{
|
||||
boundary: _,
|
||||
content_type_params: [],
|
||||
|
|
@ -70,7 +51,7 @@ defmodule Pleroma.HTTP.RequestBuilderTest do
|
|||
}
|
||||
]
|
||||
}
|
||||
} = RequestBuilder.add_param(%{}, :file, "filename.png", "some-path/filename.png")
|
||||
} = RequestBuilder.add_param(%Request{}, :file, "filename.png", "some-path/filename.png")
|
||||
end
|
||||
|
||||
test "add key to body" do
|
||||
|
|
@ -82,7 +63,7 @@ defmodule Pleroma.HTTP.RequestBuilderTest do
|
|||
%Tesla.Multipart.Part{
|
||||
body: "\"someval\"",
|
||||
dispositions: [name: "somekey"],
|
||||
headers: ["Content-Type": "application/json"]
|
||||
headers: [{"content-type", "application/json"}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTPTest do
|
||||
use Pleroma.DataCase
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.Tests.Helpers
|
||||
import Tesla.Mock
|
||||
alias Pleroma.HTTP
|
||||
|
||||
setup do
|
||||
mock(fn
|
||||
|
|
@ -27,7 +29,7 @@ defmodule Pleroma.HTTPTest do
|
|||
|
||||
describe "get/1" do
|
||||
test "returns successfully result" do
|
||||
assert Pleroma.HTTP.get("http://example.com/hello") == {
|
||||
assert HTTP.get("http://example.com/hello") == {
|
||||
:ok,
|
||||
%Tesla.Env{status: 200, body: "hello"}
|
||||
}
|
||||
|
|
@ -36,7 +38,7 @@ defmodule Pleroma.HTTPTest do
|
|||
|
||||
describe "get/2 (with headers)" do
|
||||
test "returns successfully result for json content-type" do
|
||||
assert Pleroma.HTTP.get("http://example.com/hello", [{"content-type", "application/json"}]) ==
|
||||
assert HTTP.get("http://example.com/hello", [{"content-type", "application/json"}]) ==
|
||||
{
|
||||
:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -50,7 +52,7 @@ defmodule Pleroma.HTTPTest do
|
|||
|
||||
describe "post/2" do
|
||||
test "returns successfully result" do
|
||||
assert Pleroma.HTTP.post("http://example.com/world", "") == {
|
||||
assert HTTP.post("http://example.com/world", "") == {
|
||||
:ok,
|
||||
%Tesla.Env{status: 200, body: "world"}
|
||||
}
|
||||
|
|
|
|||
BIN
test/instance_static/add/shortcode.png
Normal file
BIN
test/instance_static/add/shortcode.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 95 B |
BIN
test/instance_static/emoji/pack_bad_sha/blank.png
Normal file
BIN
test/instance_static/emoji/pack_bad_sha/blank.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 95 B |
13
test/instance_static/emoji/pack_bad_sha/pack.json
Normal file
13
test/instance_static/emoji/pack_bad_sha/pack.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"pack": {
|
||||
"license": "Test license",
|
||||
"homepage": "https://pleroma.social",
|
||||
"description": "Test description",
|
||||
"can-download": true,
|
||||
"share-files": true,
|
||||
"download-sha256": "57482F30674FD3DE821FF48C81C00DA4D4AF1F300209253684ABA7075E5FC238"
|
||||
},
|
||||
"files": {
|
||||
"blank": "blank.png"
|
||||
}
|
||||
}
|
||||
BIN
test/instance_static/emoji/pack_bad_sha/pack_bad_sha.zip
Normal file
BIN
test/instance_static/emoji/pack_bad_sha/pack_bad_sha.zip
Normal file
Binary file not shown.
|
|
@ -1,13 +1,11 @@
|
|||
{
|
||||
"pack": {
|
||||
"license": "Test license",
|
||||
"homepage": "https://pleroma.social",
|
||||
"description": "Test description",
|
||||
|
||||
"share-files": true
|
||||
},
|
||||
|
||||
"files": {
|
||||
"blank": "blank.png"
|
||||
},
|
||||
"pack": {
|
||||
"description": "Test description",
|
||||
"homepage": "https://pleroma.social",
|
||||
"license": "Test license",
|
||||
"share-files": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,14 +3,11 @@
|
|||
"license": "Test license",
|
||||
"homepage": "https://pleroma.social",
|
||||
"description": "Test description",
|
||||
|
||||
"fallback-src": "https://nonshared-pack",
|
||||
"fallback-src-sha256": "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF",
|
||||
|
||||
"share-files": false
|
||||
},
|
||||
|
||||
"files": {
|
||||
"blank": "blank.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,17 +12,14 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.OAuth
|
||||
|
||||
@moduletag needs_streamer: true, capture_log: true
|
||||
|
||||
@path Pleroma.Web.Endpoint.url()
|
||||
|> URI.parse()
|
||||
|> Map.put(:scheme, "ws")
|
||||
|> Map.put(:path, "/api/v1/streaming")
|
||||
|> URI.to_string()
|
||||
|
||||
setup_all do
|
||||
start_supervised(Pleroma.Web.Streamer.supervisor())
|
||||
:ok
|
||||
end
|
||||
|
||||
def start_socket(qs \\ nil, headers \\ []) do
|
||||
path =
|
||||
case qs do
|
||||
|
|
@ -35,7 +32,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
|
||||
test "refuses invalid requests" do
|
||||
capture_log(fn ->
|
||||
assert {:error, {400, _}} = start_socket()
|
||||
assert {:error, {404, _}} = start_socket()
|
||||
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
|
|
@ -43,8 +40,8 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
|
||||
test "requires authentication and a valid token for protected streams" do
|
||||
capture_log(fn ->
|
||||
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||
assert {:error, {403, _}} = start_socket("?stream=user")
|
||||
assert {:error, {401, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||
assert {:error, {401, _}} = start_socket("?stream=user")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
end
|
||||
|
|
@ -58,7 +55,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
test "receives well formatted events" do
|
||||
user = insert(:user)
|
||||
{:ok, _} = start_socket("?stream=public")
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "nice echo chamber"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, json} = Jason.decode(raw_json)
|
||||
|
|
@ -103,7 +100,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||
|
||||
assert capture_log(fn ->
|
||||
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user")
|
||||
assert {:error, {401, _}} = start_socket("?stream=user")
|
||||
Process.sleep(30)
|
||||
end) =~ ":badarg"
|
||||
end
|
||||
|
|
@ -112,7 +109,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
||||
|
||||
assert capture_log(fn ->
|
||||
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user:notification")
|
||||
assert {:error, {401, _}} = start_socket("?stream=user:notification")
|
||||
Process.sleep(30)
|
||||
end) =~ ":badarg"
|
||||
end
|
||||
|
|
@ -121,7 +118,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
|
||||
|
||||
assert capture_log(fn ->
|
||||
assert {:error, {403, "Forbidden"}} =
|
||||
assert {:error, {401, _}} =
|
||||
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
|
||||
|
||||
Process.sleep(30)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,39 @@ defmodule Pleroma.MarkerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "multi_set_unread_count/3" do
|
||||
test "returns multi" do
|
||||
user = insert(:user)
|
||||
|
||||
assert %Ecto.Multi{
|
||||
operations: [marker: {:run, _}, counters: {:run, _}]
|
||||
} =
|
||||
Marker.multi_set_last_read_id(
|
||||
Ecto.Multi.new(),
|
||||
user,
|
||||
"notifications"
|
||||
)
|
||||
end
|
||||
|
||||
test "return empty multi" do
|
||||
user = insert(:user)
|
||||
multi = Ecto.Multi.new()
|
||||
assert Marker.multi_set_last_read_id(multi, user, "home") == multi
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_markers/2" do
|
||||
test "returns user markers" do
|
||||
user = insert(:user)
|
||||
marker = insert(:marker, user: user)
|
||||
insert(:notification, user: user)
|
||||
insert(:notification, user: user)
|
||||
insert(:marker, timeline: "home", user: user)
|
||||
assert Marker.get_markers(user, ["notifications"]) == [refresh_record(marker)]
|
||||
|
||||
assert Marker.get_markers(
|
||||
user,
|
||||
["notifications"]
|
||||
) == [%Marker{refresh_record(marker) | unread_count: 2}]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
11
test/mfa/backup_codes_test.exs
Normal file
11
test/mfa/backup_codes_test.exs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
defmodule Pleroma.MFA.BackupCodesTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.MFA.BackupCodes
|
||||
|
||||
test "generate backup codes" do
|
||||
codes = BackupCodes.generate(number_of_codes: 2, length: 4)
|
||||
|
||||
assert [<<_::bytes-size(4)>>, <<_::bytes-size(4)>>] = codes
|
||||
end
|
||||
end
|
||||
17
test/mfa/totp_test.exs
Normal file
17
test/mfa/totp_test.exs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
defmodule Pleroma.MFA.TOTPTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.MFA.TOTP
|
||||
|
||||
test "create provisioning_uri to generate qrcode" do
|
||||
uri =
|
||||
TOTP.provisioning_uri("test-secrcet", "test@example.com",
|
||||
issuer: "Plerome-42",
|
||||
digits: 8,
|
||||
period: 60
|
||||
)
|
||||
|
||||
assert uri ==
|
||||
"otpauth://totp/test@example.com?digits=8&issuer=Plerome-42&period=60&secret=test-secrcet"
|
||||
end
|
||||
end
|
||||
52
test/mfa_test.exs
Normal file
52
test/mfa_test.exs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.MFATest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
alias Pleroma.MFA
|
||||
|
||||
describe "mfa_settings" do
|
||||
test "returns settings user's" do
|
||||
user =
|
||||
insert(:user,
|
||||
multi_factor_authentication_settings: %MFA.Settings{
|
||||
enabled: true,
|
||||
totp: %MFA.Settings.TOTP{secret: "xx", confirmed: true}
|
||||
}
|
||||
)
|
||||
|
||||
settings = MFA.mfa_settings(user)
|
||||
assert match?(^settings, %{enabled: true, totp: true})
|
||||
end
|
||||
end
|
||||
|
||||
describe "generate backup codes" do
|
||||
test "returns backup codes" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, [code1, code2]} = MFA.generate_backup_codes(user)
|
||||
updated_user = refresh_record(user)
|
||||
[hash1, hash2] = updated_user.multi_factor_authentication_settings.backup_codes
|
||||
assert Pbkdf2.verify_pass(code1, hash1)
|
||||
assert Pbkdf2.verify_pass(code2, hash2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "invalidate_backup_code" do
|
||||
test "invalid used code" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, _} = MFA.generate_backup_codes(user)
|
||||
user = refresh_record(user)
|
||||
assert length(user.multi_factor_authentication_settings.backup_codes) == 2
|
||||
[hash_code | _] = user.multi_factor_authentication_settings.backup_codes
|
||||
|
||||
{:ok, user} = MFA.invalidate_backup_code(user, hash_code)
|
||||
|
||||
assert length(user.multi_factor_authentication_settings.backup_codes) == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6,12 +6,18 @@ defmodule Pleroma.NotificationTest do
|
|||
use Pleroma.DataCase
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
|
||||
alias Pleroma.FollowingRelationship
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.NotificationView
|
||||
alias Pleroma.Web.Push
|
||||
alias Pleroma.Web.Streamer
|
||||
|
||||
describe "create_notifications" do
|
||||
|
|
@ -19,8 +25,8 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "yeah"})
|
||||
{:ok, activity, _object} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "yeah"})
|
||||
{:ok, activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
|
||||
|
|
@ -34,7 +40,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{other_user.nickname} and @#{third_user.nickname}"
|
||||
status: "hey @#{other_user.nickname} and @#{third_user.nickname}"
|
||||
})
|
||||
|
||||
{:ok, [notification, other_notification]} = Notification.create_notifications(activity)
|
||||
|
|
@ -43,6 +49,9 @@ defmodule Pleroma.NotificationTest do
|
|||
assert notified_ids == [other_user.id, third_user.id]
|
||||
assert notification.activity_id == activity.id
|
||||
assert other_notification.activity_id == activity.id
|
||||
|
||||
assert [%Pleroma.Marker{unread_count: 2}] =
|
||||
Pleroma.Marker.get_markers(other_user, ["notifications"])
|
||||
end
|
||||
|
||||
test "it creates a notification for subscribed users" do
|
||||
|
|
@ -51,7 +60,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
User.subscribe(subscriber, user)
|
||||
|
||||
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
|
||||
{:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
|
||||
{:ok, [notification]} = Notification.create_notifications(status)
|
||||
|
||||
assert notification.user_id == subscriber.id
|
||||
|
|
@ -64,12 +73,12 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
User.subscribe(subscriber, other_user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
{:ok, _reply_activity} =
|
||||
CommonAPI.post(other_user, %{
|
||||
"status" => "test reply",
|
||||
"in_reply_to_status_id" => activity.id
|
||||
status: "test reply",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
user_notifications = Notification.for_user(user)
|
||||
|
|
@ -80,18 +89,96 @@ defmodule Pleroma.NotificationTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "CommonApi.post/2 notification-related functionality" do
|
||||
test_with_mock "creates but does NOT send notification to blocker user",
|
||||
Push,
|
||||
[:passthrough],
|
||||
[] do
|
||||
user = insert(:user)
|
||||
blocker = insert(:user)
|
||||
{:ok, _user_relationship} = User.block(blocker, user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "hey @#{blocker.nickname}!"})
|
||||
|
||||
blocker_id = blocker.id
|
||||
assert [%Notification{user_id: ^blocker_id}] = Repo.all(Notification)
|
||||
refute called(Push.send(:_))
|
||||
end
|
||||
|
||||
test_with_mock "creates but does NOT send notification to notification-muter user",
|
||||
Push,
|
||||
[:passthrough],
|
||||
[] do
|
||||
user = insert(:user)
|
||||
muter = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(muter, user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "hey @#{muter.nickname}!"})
|
||||
|
||||
muter_id = muter.id
|
||||
assert [%Notification{user_id: ^muter_id}] = Repo.all(Notification)
|
||||
refute called(Push.send(:_))
|
||||
end
|
||||
|
||||
test_with_mock "creates but does NOT send notification to thread-muter user",
|
||||
Push,
|
||||
[:passthrough],
|
||||
[] do
|
||||
user = insert(:user)
|
||||
thread_muter = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{thread_muter.nickname}!"})
|
||||
|
||||
{:ok, _} = CommonAPI.add_mute(thread_muter, activity)
|
||||
|
||||
{:ok, _same_context_activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "hey-hey-hey @#{thread_muter.nickname}!",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
[pre_mute_notification, post_mute_notification] =
|
||||
Repo.all(from(n in Notification, where: n.user_id == ^thread_muter.id, order_by: n.id))
|
||||
|
||||
pre_mute_notification_id = pre_mute_notification.id
|
||||
post_mute_notification_id = post_mute_notification.id
|
||||
|
||||
assert called(
|
||||
Push.send(
|
||||
:meck.is(fn
|
||||
%Notification{id: ^pre_mute_notification_id} -> true
|
||||
_ -> false
|
||||
end)
|
||||
)
|
||||
)
|
||||
|
||||
refute called(
|
||||
Push.send(
|
||||
:meck.is(fn
|
||||
%Notification{id: ^post_mute_notification_id} -> true
|
||||
_ -> false
|
||||
end)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "create_notification" do
|
||||
@tag needs_streamer: true
|
||||
test "it creates a notification for user and send to the 'user' and the 'user:notification' stream" do
|
||||
user = insert(:user)
|
||||
task = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
|
||||
task_user_notification = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
|
||||
Streamer.add_socket("user", %{transport_pid: task.pid, assigns: %{user: user}})
|
||||
|
||||
Streamer.add_socket(
|
||||
"user:notification",
|
||||
%{transport_pid: task_user_notification.pid, assigns: %{user: user}}
|
||||
)
|
||||
task =
|
||||
Task.async(fn ->
|
||||
Streamer.get_topic_and_add_socket("user", user)
|
||||
assert_receive {:render_with_user, _, _, _}, 4_000
|
||||
end)
|
||||
|
||||
task_user_notification =
|
||||
Task.async(fn ->
|
||||
Streamer.get_topic_and_add_socket("user:notification", user)
|
||||
assert_receive {:render_with_user, _, _, _}, 4_000
|
||||
end)
|
||||
|
||||
activity = insert(:note_activity)
|
||||
|
||||
|
|
@ -115,7 +202,7 @@ defmodule Pleroma.NotificationTest do
|
|||
muted = insert(:user)
|
||||
{:ok, _} = User.mute(muter, muted)
|
||||
muter = Repo.get(User, muter.id)
|
||||
{:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
|
||||
|
||||
assert Notification.create_notification(activity, muter)
|
||||
end
|
||||
|
|
@ -126,7 +213,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, _user_relationships} = User.mute(muter, muted, false)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(muted, %{"status" => "Hi @#{muter.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(muted, %{status: "Hi @#{muter.nickname}"})
|
||||
|
||||
assert Notification.create_notification(activity, muter)
|
||||
end
|
||||
|
|
@ -134,13 +221,13 @@ defmodule Pleroma.NotificationTest do
|
|||
test "it creates a notification for an activity from a muted thread" do
|
||||
muter = insert(:user)
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(muter, %{"status" => "hey"})
|
||||
{:ok, activity} = CommonAPI.post(muter, %{status: "hey"})
|
||||
CommonAPI.add_mute(muter, activity)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(other_user, %{
|
||||
"status" => "Hi @#{muter.nickname}",
|
||||
"in_reply_to_status_id" => activity.id
|
||||
status: "Hi @#{muter.nickname}",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
assert Notification.create_notification(activity, muter)
|
||||
|
|
@ -153,7 +240,7 @@ defmodule Pleroma.NotificationTest do
|
|||
insert(:user, notification_settings: %Pleroma.User.NotificationSetting{followers: false})
|
||||
|
||||
User.follow(follower, followed)
|
||||
{:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
|
||||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
|
|
@ -165,7 +252,7 @@ defmodule Pleroma.NotificationTest do
|
|||
notification_settings: %Pleroma.User.NotificationSetting{non_followers: false}
|
||||
)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
|
||||
refute Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
|
|
@ -176,7 +263,7 @@ defmodule Pleroma.NotificationTest do
|
|||
followed = insert(:user)
|
||||
User.follow(follower, followed)
|
||||
follower = Repo.get(User, follower.id)
|
||||
{:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
|
||||
refute Notification.create_notification(activity, follower)
|
||||
end
|
||||
|
||||
|
|
@ -185,7 +272,7 @@ defmodule Pleroma.NotificationTest do
|
|||
insert(:user, notification_settings: %Pleroma.User.NotificationSetting{non_follows: false})
|
||||
|
||||
followed = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(followed, %{status: "hey @#{follower.nickname}"})
|
||||
refute Notification.create_notification(activity, follower)
|
||||
end
|
||||
|
||||
|
|
@ -196,23 +283,13 @@ defmodule Pleroma.NotificationTest do
|
|||
refute Notification.create_notification(activity, author)
|
||||
end
|
||||
|
||||
test "it doesn't create a notification for follow-unfollow-follow chains" do
|
||||
user = insert(:user)
|
||||
followed_user = insert(:user)
|
||||
{:ok, _, _, activity} = CommonAPI.follow(user, followed_user)
|
||||
Notification.create_notification(activity, followed_user)
|
||||
CommonAPI.unfollow(user, followed_user)
|
||||
{:ok, _, _, activity_dupe} = CommonAPI.follow(user, followed_user)
|
||||
refute Notification.create_notification(activity_dupe, followed_user)
|
||||
end
|
||||
|
||||
test "it doesn't create duplicate notifications for follow+subscribed users" do
|
||||
user = insert(:user)
|
||||
subscriber = insert(:user)
|
||||
|
||||
{:ok, _, _, _} = CommonAPI.follow(subscriber, user)
|
||||
User.subscribe(subscriber, user)
|
||||
{:ok, status} = CommonAPI.post(user, %{"status" => "Akariiiin"})
|
||||
{:ok, status} = CommonAPI.post(user, %{status: "Akariiiin"})
|
||||
{:ok, [_notif]} = Notification.create_notifications(status)
|
||||
end
|
||||
|
||||
|
|
@ -222,18 +299,78 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
User.subscribe(subscriber, user)
|
||||
|
||||
{:ok, status} = CommonAPI.post(user, %{"status" => "inwisible", "visibility" => "direct"})
|
||||
{:ok, status} = CommonAPI.post(user, %{status: "inwisible", visibility: "direct"})
|
||||
|
||||
assert {:ok, []} == Notification.create_notifications(status)
|
||||
end
|
||||
end
|
||||
|
||||
describe "follow / follow_request notifications" do
|
||||
test "it creates `follow` notification for approved Follow activity" do
|
||||
user = insert(:user)
|
||||
followed_user = insert(:user, locked: false)
|
||||
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
|
||||
assert FollowingRelationship.following?(user, followed_user)
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
assert %{type: "follow"} =
|
||||
NotificationView.render("show.json", %{
|
||||
notification: notification,
|
||||
for: followed_user
|
||||
})
|
||||
end
|
||||
|
||||
test "it creates `follow_request` notification for pending Follow activity" do
|
||||
user = insert(:user)
|
||||
followed_user = insert(:user, locked: true)
|
||||
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
|
||||
refute FollowingRelationship.following?(user, followed_user)
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
render_opts = %{notification: notification, for: followed_user}
|
||||
assert %{type: "follow_request"} = NotificationView.render("show.json", render_opts)
|
||||
|
||||
# After request is accepted, the same notification is rendered with type "follow":
|
||||
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
|
||||
|
||||
notification_id = notification.id
|
||||
assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
|
||||
assert %{type: "follow"} = NotificationView.render("show.json", render_opts)
|
||||
end
|
||||
|
||||
test "it doesn't create a notification for follow-unfollow-follow chains" do
|
||||
user = insert(:user)
|
||||
followed_user = insert(:user, locked: false)
|
||||
|
||||
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
|
||||
assert FollowingRelationship.following?(user, followed_user)
|
||||
assert [notification] = Notification.for_user(followed_user)
|
||||
|
||||
CommonAPI.unfollow(user, followed_user)
|
||||
{:ok, _, _, _activity_dupe} = CommonAPI.follow(user, followed_user)
|
||||
|
||||
notification_id = notification.id
|
||||
assert [%{id: ^notification_id}] = Notification.for_user(followed_user)
|
||||
end
|
||||
|
||||
test "dismisses the notification on follow request rejection" do
|
||||
user = insert(:user, locked: true)
|
||||
follower = insert(:user)
|
||||
{:ok, _, _, _follow_activity} = CommonAPI.follow(follower, user)
|
||||
assert [notification] = Notification.for_user(user)
|
||||
{:ok, _follower} = CommonAPI.reject_follow_request(follower, user)
|
||||
assert [] = Notification.for_user(user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get notification" do
|
||||
test "it gets a notification that belongs to the user" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
{:ok, notification} = Notification.get(other_user, notification.id)
|
||||
|
|
@ -245,7 +382,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
{:error, _notification} = Notification.get(user, notification.id)
|
||||
|
|
@ -257,7 +394,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
{:ok, notification} = Notification.dismiss(other_user, notification.id)
|
||||
|
|
@ -269,7 +406,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}"})
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(activity)
|
||||
{:error, _notification} = Notification.dismiss(user, notification.id)
|
||||
|
|
@ -284,14 +421,14 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"
|
||||
status: "hey @#{other_user.nickname} and @#{third_user.nickname} !"
|
||||
})
|
||||
|
||||
{:ok, _notifs} = Notification.create_notifications(activity)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
|
||||
status: "hey again @#{other_user.nickname} and @#{third_user.nickname} !"
|
||||
})
|
||||
|
||||
{:ok, _notifs} = Notification.create_notifications(activity)
|
||||
|
|
@ -309,12 +446,12 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{other_user.nickname}!"
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey again @#{other_user.nickname}!"
|
||||
status: "hey again @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
[n2, n1] = notifs = Notification.for_user(other_user)
|
||||
|
|
@ -324,7 +461,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey yet again @#{other_user.nickname}!"
|
||||
status: "hey yet again @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
Notification.set_read_up_to(other_user, n2.id)
|
||||
|
|
@ -334,6 +471,16 @@ defmodule Pleroma.NotificationTest do
|
|||
assert n1.seen == true
|
||||
assert n2.seen == true
|
||||
assert n3.seen == false
|
||||
|
||||
assert %Pleroma.Marker{} =
|
||||
m =
|
||||
Pleroma.Repo.get_by(
|
||||
Pleroma.Marker,
|
||||
user_id: other_user.id,
|
||||
timeline: "notifications"
|
||||
)
|
||||
|
||||
assert m.last_read_id == to_string(n2.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -353,7 +500,7 @@ defmodule Pleroma.NotificationTest do
|
|||
Enum.each(0..10, fn i ->
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user1, %{
|
||||
"status" => "hey ##{i} @#{user2.nickname}!"
|
||||
status: "hey ##{i} @#{user2.nickname}!"
|
||||
})
|
||||
end)
|
||||
|
||||
|
|
@ -382,17 +529,19 @@ defmodule Pleroma.NotificationTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "notification target determination" do
|
||||
describe "notification target determination / get_notified_from_activity/2" do
|
||||
test "it sends notifications to addressed users in new messages" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{other_user.nickname}!"
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
assert other_user in Notification.get_notified_from_activity(activity)
|
||||
{enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert other_user in enabled_receivers
|
||||
end
|
||||
|
||||
test "it sends notifications to mentioned users in new messages" do
|
||||
|
|
@ -420,7 +569,9 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, activity} = Transmogrifier.handle_incoming(create_activity)
|
||||
|
||||
assert other_user in Notification.get_notified_from_activity(activity)
|
||||
{enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert other_user in enabled_receivers
|
||||
end
|
||||
|
||||
test "it does not send notifications to users who are only cc in new messages" do
|
||||
|
|
@ -442,7 +593,9 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, activity} = Transmogrifier.handle_incoming(create_activity)
|
||||
|
||||
assert other_user not in Notification.get_notified_from_activity(activity)
|
||||
{enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert other_user not in enabled_receivers
|
||||
end
|
||||
|
||||
test "it does not send notification to mentioned users in likes" do
|
||||
|
|
@ -452,12 +605,37 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, activity_one} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{other_user.nickname}!"
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
{:ok, activity_two, _} = CommonAPI.favorite(activity_one.id, third_user)
|
||||
{:ok, activity_two} = CommonAPI.favorite(third_user, activity_one.id)
|
||||
|
||||
assert other_user not in Notification.get_notified_from_activity(activity_two)
|
||||
{enabled_receivers, _disabled_receivers} =
|
||||
Notification.get_notified_from_activity(activity_two)
|
||||
|
||||
assert other_user not in enabled_receivers
|
||||
end
|
||||
|
||||
test "it only notifies the post's author in likes" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
third_user = insert(:user)
|
||||
|
||||
{:ok, activity_one} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
{:ok, like_data, _} = Builder.like(third_user, activity_one.object)
|
||||
|
||||
{:ok, like, _} =
|
||||
like_data
|
||||
|> Map.put("to", [other_user.ap_id | like_data["to"]])
|
||||
|> ActivityPub.persist(local: true)
|
||||
|
||||
{enabled_receivers, _disabled_receivers} = Notification.get_notified_from_activity(like)
|
||||
|
||||
assert other_user not in enabled_receivers
|
||||
end
|
||||
|
||||
test "it does not send notification to mentioned users in announces" do
|
||||
|
|
@ -467,12 +645,93 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
{:ok, activity_one} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{other_user.nickname}!"
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
{:ok, activity_two, _} = CommonAPI.repeat(activity_one.id, third_user)
|
||||
|
||||
assert other_user not in Notification.get_notified_from_activity(activity_two)
|
||||
{enabled_receivers, _disabled_receivers} =
|
||||
Notification.get_notified_from_activity(activity_two)
|
||||
|
||||
assert other_user not in enabled_receivers
|
||||
end
|
||||
|
||||
test "it returns blocking recipient in disabled recipients list" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
{:ok, _user_relationship} = User.block(other_user, user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
|
||||
|
||||
{enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert [] == enabled_receivers
|
||||
assert [other_user] == disabled_receivers
|
||||
end
|
||||
|
||||
test "it returns notification-muting recipient in disabled recipients list" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(other_user, user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
|
||||
|
||||
{enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert [] == enabled_receivers
|
||||
assert [other_user] == disabled_receivers
|
||||
end
|
||||
|
||||
test "it returns thread-muting recipient in disabled recipients list" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
|
||||
|
||||
{:ok, _} = CommonAPI.add_mute(other_user, activity)
|
||||
|
||||
{:ok, same_context_activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "hey-hey-hey @#{other_user.nickname}!",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
{enabled_receivers, disabled_receivers} =
|
||||
Notification.get_notified_from_activity(same_context_activity)
|
||||
|
||||
assert [other_user] == disabled_receivers
|
||||
refute other_user in enabled_receivers
|
||||
end
|
||||
|
||||
test "it returns non-following domain-blocking recipient in disabled recipients list" do
|
||||
blocked_domain = "blocked.domain"
|
||||
user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, other_user} = User.block_domain(other_user, blocked_domain)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
|
||||
|
||||
{enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert [] == enabled_receivers
|
||||
assert [other_user] == disabled_receivers
|
||||
end
|
||||
|
||||
test "it returns following domain-blocking recipient in enabled recipients list" do
|
||||
blocked_domain = "blocked.domain"
|
||||
user = insert(:user, %{ap_id: "https://#{blocked_domain}/@actor"})
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, other_user} = User.block_domain(other_user, blocked_domain)
|
||||
{:ok, other_user} = User.follow(other_user, user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{other_user.nickname}!"})
|
||||
|
||||
{enabled_receivers, disabled_receivers} = Notification.get_notified_from_activity(activity)
|
||||
|
||||
assert [other_user] == enabled_receivers
|
||||
assert [] == disabled_receivers
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -481,11 +740,11 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
{:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
|
||||
{:ok, _} = CommonAPI.favorite(other_user, activity.id)
|
||||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
|
||||
|
|
@ -498,15 +757,15 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
{:ok, _, _} = CommonAPI.favorite(activity.id, other_user)
|
||||
{:ok, _} = CommonAPI.favorite(other_user, activity.id)
|
||||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
|
||||
{:ok, _, _, _} = CommonAPI.unfavorite(activity.id, other_user)
|
||||
{:ok, _} = CommonAPI.unfavorite(activity.id, other_user)
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
end
|
||||
|
|
@ -515,7 +774,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
|
|
@ -532,7 +791,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
|
|
@ -540,7 +799,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
|
||||
{:ok, _, _} = CommonAPI.unrepeat(activity.id, other_user)
|
||||
{:ok, _} = CommonAPI.unrepeat(activity.id, other_user)
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
end
|
||||
|
|
@ -549,7 +808,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
|
|
@ -557,7 +816,7 @@ defmodule Pleroma.NotificationTest do
|
|||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
{:error, _} = CommonAPI.favorite(activity.id, other_user)
|
||||
{:error, :not_found} = CommonAPI.favorite(other_user, activity.id)
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
end
|
||||
|
|
@ -566,7 +825,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
||||
|
|
@ -583,13 +842,13 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test post"})
|
||||
{:ok, _deletion_activity} = CommonAPI.delete(activity.id, user)
|
||||
|
||||
{:ok, _reply_activity} =
|
||||
CommonAPI.post(other_user, %{
|
||||
"status" => "test reply",
|
||||
"in_reply_to_status_id" => activity.id
|
||||
status: "test reply",
|
||||
in_reply_to_status_id: activity.id
|
||||
})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user))
|
||||
|
|
@ -600,7 +859,7 @@ defmodule Pleroma.NotificationTest do
|
|||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{"status" => "hi @#{other_user.nickname}", "visibility" => "direct"})
|
||||
CommonAPI.post(user, %{status: "hi @#{other_user.nickname}", visibility: "direct"})
|
||||
|
||||
refute Enum.empty?(Notification.for_user(other_user))
|
||||
|
||||
|
|
@ -649,12 +908,20 @@ defmodule Pleroma.NotificationTest do
|
|||
"object" => remote_user.ap_id
|
||||
}
|
||||
|
||||
remote_user_url = remote_user.ap_id
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: :get, url: ^remote_user_url} ->
|
||||
%Tesla.Env{status: 404, body: ""}
|
||||
end)
|
||||
|
||||
{:ok, _delete_activity} = Transmogrifier.handle_incoming(delete_user_message)
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert Enum.empty?(Notification.for_user(local_user))
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "move activity generates a notification" do
|
||||
%{ap_id: old_ap_id} = old_user = insert(:user)
|
||||
%{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
|
||||
|
|
@ -664,6 +931,18 @@ defmodule Pleroma.NotificationTest do
|
|||
User.follow(follower, old_user)
|
||||
User.follow(other_follower, old_user)
|
||||
|
||||
old_user_url = old_user.ap_id
|
||||
|
||||
body =
|
||||
File.read!("test/fixtures/users_mock/localhost.json")
|
||||
|> String.replace("{{nickname}}", old_user.nickname)
|
||||
|> Jason.encode!()
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: :get, url: ^old_user_url} ->
|
||||
%Tesla.Env{status: 200, body: body}
|
||||
end)
|
||||
|
||||
Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user)
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
|
|
@ -691,7 +970,7 @@ defmodule Pleroma.NotificationTest do
|
|||
muted = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(user, muted, false)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
|
|
@ -701,7 +980,7 @@ defmodule Pleroma.NotificationTest do
|
|||
muted = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(user, muted)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert Notification.for_user(user) == []
|
||||
end
|
||||
|
|
@ -711,26 +990,38 @@ defmodule Pleroma.NotificationTest do
|
|||
blocked = insert(:user)
|
||||
{:ok, _user_relationship} = User.block(user, blocked)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert Notification.for_user(user) == []
|
||||
end
|
||||
|
||||
test "it doesn't return notificatitons for blocked domain" do
|
||||
test "it doesn't return notifications for domain-blocked non-followed user" do
|
||||
user = insert(:user)
|
||||
blocked = insert(:user, ap_id: "http://some-domain.com")
|
||||
{:ok, user} = User.block_domain(user, "some-domain.com")
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert Notification.for_user(user) == []
|
||||
end
|
||||
|
||||
test "it returns notifications for domain-blocked but followed user" do
|
||||
user = insert(:user)
|
||||
blocked = insert(:user, ap_id: "http://some-domain.com")
|
||||
|
||||
{:ok, user} = User.block_domain(user, "some-domain.com")
|
||||
{:ok, _} = User.follow(user, blocked)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert length(Notification.for_user(user)) == 1
|
||||
end
|
||||
|
||||
test "it doesn't return notifications for muted thread" do
|
||||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
|
||||
assert Notification.for_user(user) == []
|
||||
|
|
@ -741,7 +1032,7 @@ defmodule Pleroma.NotificationTest do
|
|||
muted = insert(:user)
|
||||
{:ok, _user_relationships} = User.mute(user, muted)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(muted, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(muted, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert length(Notification.for_user(user, %{with_muted: true})) == 1
|
||||
end
|
||||
|
|
@ -751,17 +1042,18 @@ defmodule Pleroma.NotificationTest do
|
|||
blocked = insert(:user)
|
||||
{:ok, _user_relationship} = User.block(user, blocked)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
|
||||
end
|
||||
|
||||
test "it doesn't return notifications from a domain-blocked user when with_muted is set" do
|
||||
test "when with_muted is set, " <>
|
||||
"it doesn't return notifications from a domain-blocked non-followed user" do
|
||||
user = insert(:user)
|
||||
blocked = insert(:user, ap_id: "http://some-domain.com")
|
||||
{:ok, user} = User.block_domain(user, "some-domain.com")
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, _activity} = CommonAPI.post(blocked, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
assert Enum.empty?(Notification.for_user(user, %{with_muted: true}))
|
||||
end
|
||||
|
|
@ -770,7 +1062,7 @@ defmodule Pleroma.NotificationTest do
|
|||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{"status" => "hey @#{user.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{status: "hey @#{user.nickname}"})
|
||||
|
||||
{:ok, _} = Pleroma.ThreadMute.add_mute(user.id, activity.data["context"])
|
||||
assert length(Notification.for_user(user, %{with_muted: true})) == 1
|
||||
|
|
|
|||
|
|
@ -380,7 +380,8 @@ defmodule Pleroma.ObjectTest do
|
|||
|
||||
user = insert(:user)
|
||||
activity = Activity.get_create_by_object_ap_id(object.data["id"])
|
||||
{:ok, _activity, object} = CommonAPI.favorite(activity.id, user)
|
||||
{:ok, activity} = CommonAPI.favorite(user, activity.id)
|
||||
object = Object.get_by_ap_id(activity.data["object"])
|
||||
|
||||
assert object.data["like_count"] == 1
|
||||
|
||||
|
|
|
|||
42
test/otp_version_test.exs
Normal file
42
test/otp_version_test.exs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.OTPVersionTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pleroma.OTPVersion
|
||||
|
||||
describe "check/1" do
|
||||
test "22.4" do
|
||||
assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/22.4"]) ==
|
||||
"22.4"
|
||||
end
|
||||
|
||||
test "22.1" do
|
||||
assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/22.1"]) ==
|
||||
"22.1"
|
||||
end
|
||||
|
||||
test "21.1" do
|
||||
assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/21.1"]) ==
|
||||
"21.1"
|
||||
end
|
||||
|
||||
test "23.0" do
|
||||
assert OTPVersion.get_version_from_files(["test/fixtures/warnings/otp_version/23.0"]) ==
|
||||
"23.0"
|
||||
end
|
||||
|
||||
test "with non existance file" do
|
||||
assert OTPVersion.get_version_from_files([
|
||||
"test/fixtures/warnings/otp_version/non-exising",
|
||||
"test/fixtures/warnings/otp_version/22.4"
|
||||
]) == "22.4"
|
||||
end
|
||||
|
||||
test "empty paths" do
|
||||
assert OTPVersion.get_version_from_files([]) == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6,6 +6,8 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do
|
|||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Plugs.AuthenticationPlug
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Plugs.PlugHelper
|
||||
alias Pleroma.User
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
|
@ -14,7 +16,7 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do
|
|||
user = %User{
|
||||
id: 1,
|
||||
name: "dude",
|
||||
password_hash: Comeonin.Pbkdf2.hashpwsalt("guy")
|
||||
password_hash: Pbkdf2.hash_pwd_salt("guy")
|
||||
}
|
||||
|
||||
conn =
|
||||
|
|
@ -36,13 +38,16 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do
|
|||
assert ret_conn == conn
|
||||
end
|
||||
|
||||
test "with a correct password in the credentials, it assigns the auth_user", %{conn: conn} do
|
||||
test "with a correct password in the credentials, " <>
|
||||
"it assigns the auth_user and marks OAuthScopesPlug as skipped",
|
||||
%{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:auth_credentials, %{password: "guy"})
|
||||
|> AuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns.user == conn.assigns.auth_user
|
||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
|
||||
end
|
||||
|
||||
test "with a wrong password in the credentials, it does nothing", %{conn: conn} do
|
||||
|
|
@ -74,6 +79,13 @@ defmodule Pleroma.Plugs.AuthenticationPlugTest do
|
|||
assert AuthenticationPlug.checkpw("password", hash)
|
||||
end
|
||||
|
||||
test "check bcrypt hash" do
|
||||
hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS"
|
||||
|
||||
assert AuthenticationPlug.checkpw("password", hash)
|
||||
refute AuthenticationPlug.checkpw("password1", hash)
|
||||
end
|
||||
|
||||
test "it returns false when hash invalid" do
|
||||
hash =
|
||||
"psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1"
|
||||
|
|
|
|||
|
|
@ -20,34 +20,61 @@ defmodule Pleroma.Plugs.EnsureAuthenticatedPlugTest do
|
|||
conn = assign(conn, :user, %User{})
|
||||
ret_conn = EnsureAuthenticatedPlug.call(conn, %{})
|
||||
|
||||
assert ret_conn == conn
|
||||
refute ret_conn.halted
|
||||
end
|
||||
end
|
||||
|
||||
test "it halts if user is assigned and MFA enabled", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, %User{multi_factor_authentication_settings: %{enabled: true}})
|
||||
|> assign(:auth_credentials, %{password: "xd-42"})
|
||||
|> EnsureAuthenticatedPlug.call(%{})
|
||||
|
||||
assert conn.status == 403
|
||||
assert conn.halted == true
|
||||
|
||||
assert conn.resp_body ==
|
||||
"{\"error\":\"Two-factor authentication enabled, you must use a access token.\"}"
|
||||
end
|
||||
|
||||
test "it continues if user is assigned and MFA disabled", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, %User{multi_factor_authentication_settings: %{enabled: false}})
|
||||
|> assign(:auth_credentials, %{password: "xd-42"})
|
||||
|> EnsureAuthenticatedPlug.call(%{})
|
||||
|
||||
refute conn.status == 403
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
describe "with :if_func / :unless_func options" do
|
||||
setup do
|
||||
%{
|
||||
true_fn: fn -> true end,
|
||||
false_fn: fn -> false end
|
||||
true_fn: fn _conn -> true end,
|
||||
false_fn: fn _conn -> false end
|
||||
}
|
||||
end
|
||||
|
||||
test "it continues if a user is assigned", %{conn: conn, true_fn: true_fn, false_fn: false_fn} do
|
||||
conn = assign(conn, :user, %User{})
|
||||
assert EnsureAuthenticatedPlug.call(conn, if_func: true_fn) == conn
|
||||
assert EnsureAuthenticatedPlug.call(conn, if_func: false_fn) == conn
|
||||
assert EnsureAuthenticatedPlug.call(conn, unless_func: true_fn) == conn
|
||||
assert EnsureAuthenticatedPlug.call(conn, unless_func: false_fn) == conn
|
||||
refute EnsureAuthenticatedPlug.call(conn, if_func: true_fn).halted
|
||||
refute EnsureAuthenticatedPlug.call(conn, if_func: false_fn).halted
|
||||
refute EnsureAuthenticatedPlug.call(conn, unless_func: true_fn).halted
|
||||
refute EnsureAuthenticatedPlug.call(conn, unless_func: false_fn).halted
|
||||
end
|
||||
|
||||
test "it continues if a user is NOT assigned but :if_func evaluates to `false`",
|
||||
%{conn: conn, false_fn: false_fn} do
|
||||
assert EnsureAuthenticatedPlug.call(conn, if_func: false_fn) == conn
|
||||
ret_conn = EnsureAuthenticatedPlug.call(conn, if_func: false_fn)
|
||||
refute ret_conn.halted
|
||||
end
|
||||
|
||||
test "it continues if a user is NOT assigned but :unless_func evaluates to `true`",
|
||||
%{conn: conn, true_fn: true_fn} do
|
||||
assert EnsureAuthenticatedPlug.call(conn, unless_func: true_fn) == conn
|
||||
ret_conn = EnsureAuthenticatedPlug.call(conn, unless_func: true_fn)
|
||||
refute ret_conn.halted
|
||||
end
|
||||
|
||||
test "it halts if a user is NOT assigned and :if_func evaluates to `true`",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do
|
|||
conn
|
||||
|> EnsurePublicOrAuthenticatedPlug.call(%{})
|
||||
|
||||
assert ret_conn == conn
|
||||
refute ret_conn.halted
|
||||
end
|
||||
|
||||
test "it continues if a user is assigned, even if not public", %{conn: conn} do
|
||||
|
|
@ -43,6 +43,6 @@ defmodule Pleroma.Plugs.EnsurePublicOrAuthenticatedPlugTest do
|
|||
conn
|
||||
|> EnsurePublicOrAuthenticatedPlug.call(%{})
|
||||
|
||||
assert ret_conn == conn
|
||||
refute ret_conn.halted
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do
|
|||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Plugs.LegacyAuthenticationPlug
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Plugs.PlugHelper
|
||||
alias Pleroma.User
|
||||
|
||||
setup do
|
||||
|
|
@ -36,7 +38,8 @@ defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do
|
|||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
test "it authenticates the auth_user if present and password is correct and resets the password",
|
||||
test "if `auth_user` is present and password is correct, " <>
|
||||
"it authenticates the user, resets the password, marks OAuthScopesPlug as skipped",
|
||||
%{
|
||||
conn: conn,
|
||||
user: user
|
||||
|
|
@ -49,6 +52,7 @@ defmodule Pleroma.Plugs.LegacyAuthenticationPlugTest do
|
|||
conn = LegacyAuthenticationPlug.call(conn, %{})
|
||||
|
||||
assert conn.assigns.user.id == user.id
|
||||
assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug)
|
||||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
|
|
|
|||
|
|
@ -5,15 +5,22 @@
|
|||
defmodule Pleroma.Plugs.OAuthScopesPlugTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
|
||||
alias Pleroma.Plugs.OAuthScopesPlug
|
||||
alias Pleroma.Repo
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
setup_with_mocks([{EnsurePublicOrAuthenticatedPlug, [], [call: fn conn, _ -> conn end]}]) do
|
||||
:ok
|
||||
test "is not performed if marked as skipped", %{conn: conn} do
|
||||
with_mock OAuthScopesPlug, [:passthrough], perform: &passthrough([&1, &2]) do
|
||||
conn =
|
||||
conn
|
||||
|> OAuthScopesPlug.skip_plug()
|
||||
|> OAuthScopesPlug.call(%{scopes: ["random_scope"]})
|
||||
|
||||
refute called(OAuthScopesPlug.perform(:_, :_))
|
||||
refute conn.halted
|
||||
end
|
||||
end
|
||||
|
||||
test "if `token.scopes` fulfills specified 'any of' conditions, " <>
|
||||
|
|
@ -48,7 +55,7 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do
|
|||
|
||||
describe "with `fallback: :proceed_unauthenticated` option, " do
|
||||
test "if `token.scopes` doesn't fulfill specified conditions, " <>
|
||||
"clears :user and :token assigns and calls EnsurePublicOrAuthenticatedPlug",
|
||||
"clears :user and :token assigns",
|
||||
%{conn: conn} do
|
||||
user = insert(:user)
|
||||
token1 = insert(:oauth_token, scopes: ["read", "write"], user: user)
|
||||
|
|
@ -67,35 +74,6 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do
|
|||
refute ret_conn.halted
|
||||
refute ret_conn.assigns[:user]
|
||||
refute ret_conn.assigns[:token]
|
||||
|
||||
assert called(EnsurePublicOrAuthenticatedPlug.call(ret_conn, :_))
|
||||
end
|
||||
end
|
||||
|
||||
test "with :skip_instance_privacy_check option, " <>
|
||||
"if `token.scopes` doesn't fulfill specified conditions, " <>
|
||||
"clears :user and :token assigns and does NOT call EnsurePublicOrAuthenticatedPlug",
|
||||
%{conn: conn} do
|
||||
user = insert(:user)
|
||||
token1 = insert(:oauth_token, scopes: ["read:statuses", "write"], user: user)
|
||||
|
||||
for token <- [token1, nil], op <- [:|, :&] do
|
||||
ret_conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, token)
|
||||
|> OAuthScopesPlug.call(%{
|
||||
scopes: ["read"],
|
||||
op: op,
|
||||
fallback: :proceed_unauthenticated,
|
||||
skip_instance_privacy_check: true
|
||||
})
|
||||
|
||||
refute ret_conn.halted
|
||||
refute ret_conn.assigns[:user]
|
||||
refute ret_conn.assigns[:token]
|
||||
|
||||
refute called(EnsurePublicOrAuthenticatedPlug.call(ret_conn, :_))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
defmodule Pleroma.Plugs.RateLimiterTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Phoenix.ConnTest
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Plugs.RateLimiter
|
||||
alias Plug.Conn
|
||||
|
||||
import Pleroma.Factory
|
||||
import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
|
||||
|
|
@ -36,8 +38,15 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
end
|
||||
|
||||
test "it is disabled if it remote ip plug is enabled but no remote ip is found" do
|
||||
Config.put([Pleroma.Web.Endpoint, :http, :ip], {127, 0, 0, 1})
|
||||
assert RateLimiter.disabled?(Plug.Conn.assign(build_conn(), :remote_ip_found, false))
|
||||
assert RateLimiter.disabled?(Conn.assign(build_conn(), :remote_ip_found, false))
|
||||
end
|
||||
|
||||
test "it is enabled if remote ip found" do
|
||||
refute RateLimiter.disabled?(Conn.assign(build_conn(), :remote_ip_found, true))
|
||||
end
|
||||
|
||||
test "it is enabled if remote_ip_found flag doesn't exist" do
|
||||
refute RateLimiter.disabled?(build_conn())
|
||||
end
|
||||
|
||||
test "it restricts based on config values" do
|
||||
|
|
@ -58,7 +67,7 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
end
|
||||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
Process.sleep(50)
|
||||
|
|
@ -68,7 +77,7 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
|
||||
|
||||
refute conn.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
end
|
||||
|
|
@ -98,7 +107,7 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
plug_opts = RateLimiter.init(name: limiter_name, params: ["id"])
|
||||
|
||||
conn = build_conn(:get, "/?id=1")
|
||||
conn = Plug.Conn.fetch_query_params(conn)
|
||||
conn = Conn.fetch_query_params(conn)
|
||||
conn_2 = build_conn(:get, "/?id=2")
|
||||
|
||||
RateLimiter.call(conn, plug_opts)
|
||||
|
|
@ -119,7 +128,7 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
id = "100"
|
||||
|
||||
conn = build_conn(:get, "/?id=#{id}")
|
||||
conn = Plug.Conn.fetch_query_params(conn)
|
||||
conn = Conn.fetch_query_params(conn)
|
||||
conn_2 = build_conn(:get, "/?id=#{101}")
|
||||
|
||||
RateLimiter.call(conn, plug_opts)
|
||||
|
|
@ -147,13 +156,13 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
conn_2 = RateLimiter.call(conn_2, plug_opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
|
||||
|
||||
refute conn_2.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn_2.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn_2.resp_body
|
||||
refute conn_2.halted
|
||||
end
|
||||
|
|
@ -187,7 +196,7 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
end
|
||||
|
||||
|
|
@ -210,12 +219,12 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
end
|
||||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
conn_2 = RateLimiter.call(conn_2, plug_opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, plug_opts)
|
||||
refute conn_2.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn_2.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn_2.resp_body
|
||||
refute conn_2.halted
|
||||
end
|
||||
|
|
|
|||
760
test/pool/connections_test.exs
Normal file
760
test/pool/connections_test.exs
Normal file
|
|
@ -0,0 +1,760 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Pool.ConnectionsTest do
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
|
||||
alias Pleroma.Gun.Conn
|
||||
alias Pleroma.GunMock
|
||||
alias Pleroma.Pool.Connections
|
||||
|
||||
setup :verify_on_exit!
|
||||
|
||||
setup_all do
|
||||
name = :test_connections
|
||||
{:ok, pid} = Connections.start_link({name, [checkin_timeout: 150]})
|
||||
{:ok, _} = Registry.start_link(keys: :unique, name: Pleroma.GunMock)
|
||||
|
||||
on_exit(fn ->
|
||||
if Process.alive?(pid), do: GenServer.stop(name)
|
||||
end)
|
||||
|
||||
{:ok, name: name}
|
||||
end
|
||||
|
||||
defp open_mock(num \\ 1) do
|
||||
GunMock
|
||||
|> expect(:open, num, &start_and_register(&1, &2, &3))
|
||||
|> expect(:await_up, num, fn _, _ -> {:ok, :http} end)
|
||||
|> expect(:set_owner, num, fn _, _ -> :ok end)
|
||||
end
|
||||
|
||||
defp connect_mock(mock) do
|
||||
mock
|
||||
|> expect(:connect, &connect(&1, &2))
|
||||
|> expect(:await, &await(&1, &2))
|
||||
end
|
||||
|
||||
defp info_mock(mock), do: expect(mock, :info, &info(&1))
|
||||
|
||||
defp start_and_register('gun-not-up.com', _, _), do: {:error, :timeout}
|
||||
|
||||
defp start_and_register(host, port, _) do
|
||||
{:ok, pid} = Task.start_link(fn -> Process.sleep(1000) end)
|
||||
|
||||
scheme =
|
||||
case port do
|
||||
443 -> "https"
|
||||
_ -> "http"
|
||||
end
|
||||
|
||||
Registry.register(GunMock, pid, %{
|
||||
origin_scheme: scheme,
|
||||
origin_host: host,
|
||||
origin_port: port
|
||||
})
|
||||
|
||||
{:ok, pid}
|
||||
end
|
||||
|
||||
defp info(pid) do
|
||||
[{_, info}] = Registry.lookup(GunMock, pid)
|
||||
info
|
||||
end
|
||||
|
||||
defp connect(pid, _) do
|
||||
ref = make_ref()
|
||||
Registry.register(GunMock, ref, pid)
|
||||
ref
|
||||
end
|
||||
|
||||
defp await(pid, ref) do
|
||||
[{_, ^pid}] = Registry.lookup(GunMock, ref)
|
||||
{:response, :fin, 200, []}
|
||||
end
|
||||
|
||||
defp now, do: :os.system_time(:second)
|
||||
|
||||
describe "alive?/2" do
|
||||
test "is alive", %{name: name} do
|
||||
assert Connections.alive?(name)
|
||||
end
|
||||
|
||||
test "returns false if not started" do
|
||||
refute Connections.alive?(:some_random_name)
|
||||
end
|
||||
end
|
||||
|
||||
test "opens connection and reuse it on next request", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://some-domain.com"
|
||||
key = "http:some-domain.com:80"
|
||||
refute Connections.checkin(url, name)
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}, {^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
:ok = Connections.checkout(conn, self, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
:ok = Connections.checkout(conn, self, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [],
|
||||
conn_state: :idle
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "reuse connection for idna domains", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://ですsome-domain.com"
|
||||
refute Connections.checkin(url, name)
|
||||
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:ですsome-domain.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
end
|
||||
|
||||
test "reuse for ipv4", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://127.0.0.1"
|
||||
|
||||
refute Connections.checkin(url, name)
|
||||
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
|
||||
:ok = Connections.checkout(conn, self, name)
|
||||
:ok = Connections.checkout(reused_conn, self, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [],
|
||||
conn_state: :idle
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "reuse for ipv6", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://[2a03:2880:f10c:83:face:b00c:0:25de]"
|
||||
|
||||
refute Connections.checkin(url, name)
|
||||
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
self = self()
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert conn == reused_conn
|
||||
end
|
||||
|
||||
test "up and down ipv4", %{name: name} do
|
||||
open_mock()
|
||||
|> info_mock()
|
||||
|> allow(self(), name)
|
||||
|
||||
self = self()
|
||||
url = "http://127.0.0.1"
|
||||
:ok = Conn.open(url, name)
|
||||
conn = Connections.checkin(url, name)
|
||||
send(name, {:gun_down, conn, nil, nil, nil})
|
||||
send(name, {:gun_up, conn, nil})
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:127.0.0.1:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "up and down ipv6", %{name: name} do
|
||||
self = self()
|
||||
|
||||
open_mock()
|
||||
|> info_mock()
|
||||
|> allow(self, name)
|
||||
|
||||
url = "http://[2a03:2880:f10c:83:face:b00c:0:25de]"
|
||||
:ok = Conn.open(url, name)
|
||||
conn = Connections.checkin(url, name)
|
||||
send(name, {:gun_down, conn, nil, nil, nil})
|
||||
send(name, {:gun_up, conn, nil})
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:2a03:2880:f10c:83:face:b00c:0:25de:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}],
|
||||
conn_state: :active
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "reuses connection based on protocol", %{name: name} do
|
||||
open_mock(2)
|
||||
http_url = "http://some-domain.com"
|
||||
http_key = "http:some-domain.com:80"
|
||||
https_url = "https://some-domain.com"
|
||||
https_key = "https:some-domain.com:443"
|
||||
|
||||
refute Connections.checkin(http_url, name)
|
||||
:ok = Conn.open(http_url, name)
|
||||
conn = Connections.checkin(http_url, name)
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
refute Connections.checkin(https_url, name)
|
||||
:ok = Conn.open(https_url, name)
|
||||
https_conn = Connections.checkin(https_url, name)
|
||||
|
||||
refute conn == https_conn
|
||||
|
||||
reused_https = Connections.checkin(https_url, name)
|
||||
|
||||
refute conn == reused_https
|
||||
|
||||
assert reused_https == https_conn
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^http_key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
},
|
||||
^https_key => %Conn{
|
||||
conn: ^https_conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "connection can't get up", %{name: name} do
|
||||
expect(GunMock, :open, &start_and_register(&1, &2, &3))
|
||||
url = "http://gun-not-up.com"
|
||||
|
||||
assert capture_log(fn ->
|
||||
refute Conn.open(url, name)
|
||||
refute Connections.checkin(url, name)
|
||||
end) =~
|
||||
"Opening connection to http://gun-not-up.com failed with error {:error, :timeout}"
|
||||
end
|
||||
|
||||
test "process gun_down message and then gun_up", %{name: name} do
|
||||
self = self()
|
||||
|
||||
open_mock()
|
||||
|> info_mock()
|
||||
|> allow(self, name)
|
||||
|
||||
url = "http://gun-down-and-up.com"
|
||||
key = "http:gun-down-and-up.com:80"
|
||||
:ok = Conn.open(url, name)
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
assert is_pid(conn)
|
||||
assert Process.alive?(conn)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
send(name, {:gun_down, conn, :http, nil, nil})
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :down,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
send(name, {:gun_up, conn, :http})
|
||||
|
||||
conn2 = Connections.checkin(url, name)
|
||||
assert conn == conn2
|
||||
|
||||
assert is_pid(conn2)
|
||||
assert Process.alive?(conn2)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: _,
|
||||
gun_state: :up,
|
||||
used_by: [{^self, _}, {^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
test "async processes get same conn for same domain", %{name: name} do
|
||||
open_mock()
|
||||
url = "http://some-domain.com"
|
||||
:ok = Conn.open(url, name)
|
||||
|
||||
tasks =
|
||||
for _ <- 1..5 do
|
||||
Task.async(fn ->
|
||||
Connections.checkin(url, name)
|
||||
end)
|
||||
end
|
||||
|
||||
tasks_with_results = Task.yield_many(tasks)
|
||||
|
||||
results =
|
||||
Enum.map(tasks_with_results, fn {task, res} ->
|
||||
res || Task.shutdown(task, :brutal_kill)
|
||||
end)
|
||||
|
||||
conns = for {:ok, value} <- results, do: value
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:some-domain.com:80" => %Conn{
|
||||
conn: conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
assert Enum.all?(conns, fn res -> res == conn end)
|
||||
end
|
||||
|
||||
test "remove frequently used and idle", %{name: name} do
|
||||
open_mock(3)
|
||||
self = self()
|
||||
http_url = "http://some-domain.com"
|
||||
https_url = "https://some-domain.com"
|
||||
:ok = Conn.open(https_url, name)
|
||||
:ok = Conn.open(http_url, name)
|
||||
|
||||
conn1 = Connections.checkin(https_url, name)
|
||||
|
||||
[conn2 | _conns] =
|
||||
for _ <- 1..4 do
|
||||
Connections.checkin(http_url, name)
|
||||
end
|
||||
|
||||
http_key = "http:some-domain.com:80"
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^http_key => %Conn{
|
||||
conn: ^conn2,
|
||||
gun_state: :up,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}, {^self, _}, {^self, _}, {^self, _}]
|
||||
},
|
||||
"https:some-domain.com:443" => %Conn{
|
||||
conn: ^conn1,
|
||||
gun_state: :up,
|
||||
conn_state: :active,
|
||||
used_by: [{^self, _}]
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
:ok = Connections.checkout(conn1, self, name)
|
||||
|
||||
another_url = "http://another-domain.com"
|
||||
:ok = Conn.open(another_url, name)
|
||||
conn = Connections.checkin(another_url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:another-domain.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
},
|
||||
^http_key => %Conn{
|
||||
conn: _,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
end
|
||||
|
||||
describe "with proxy" do
|
||||
test "as ip", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "http://proxy-string.com"
|
||||
key = "http:proxy-string.com:80"
|
||||
:ok = Conn.open(url, name, proxy: {{127, 0, 0, 1}, 8123})
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
^key => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "as host", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "http://proxy-tuple-atom.com"
|
||||
:ok = Conn.open(url, name, proxy: {'localhost', 9050})
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:proxy-tuple-atom.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "as ip and ssl", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "https://proxy-string.com"
|
||||
|
||||
:ok = Conn.open(url, name, proxy: {{127, 0, 0, 1}, 8123})
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"https:proxy-string.com:443" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "as host and ssl", %{name: name} do
|
||||
open_mock()
|
||||
|> connect_mock()
|
||||
|
||||
url = "https://proxy-tuple-atom.com"
|
||||
:ok = Conn.open(url, name, proxy: {'localhost', 9050})
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"https:proxy-tuple-atom.com:443" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "with socks type", %{name: name} do
|
||||
open_mock()
|
||||
|
||||
url = "http://proxy-socks.com"
|
||||
|
||||
:ok = Conn.open(url, name, proxy: {:socks5, 'localhost', 1234})
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"http:proxy-socks.com:80" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
|
||||
test "with socks4 type and ssl", %{name: name} do
|
||||
open_mock()
|
||||
url = "https://proxy-socks.com"
|
||||
|
||||
:ok = Conn.open(url, name, proxy: {:socks4, 'localhost', 1234})
|
||||
|
||||
conn = Connections.checkin(url, name)
|
||||
|
||||
%Connections{
|
||||
conns: %{
|
||||
"https:proxy-socks.com:443" => %Conn{
|
||||
conn: ^conn,
|
||||
gun_state: :up
|
||||
}
|
||||
}
|
||||
} = Connections.get_state(name)
|
||||
|
||||
reused_conn = Connections.checkin(url, name)
|
||||
|
||||
assert reused_conn == conn
|
||||
end
|
||||
end
|
||||
|
||||
describe "crf/3" do
|
||||
setup do
|
||||
crf = Connections.crf(1, 10, 1)
|
||||
{:ok, crf: crf}
|
||||
end
|
||||
|
||||
test "more used will have crf higher", %{crf: crf} do
|
||||
# used 3 times
|
||||
crf1 = Connections.crf(1, 10, crf)
|
||||
crf1 = Connections.crf(1, 10, crf1)
|
||||
|
||||
# used 2 times
|
||||
crf2 = Connections.crf(1, 10, crf)
|
||||
|
||||
assert crf1 > crf2
|
||||
end
|
||||
|
||||
test "recently used will have crf higher on equal references", %{crf: crf} do
|
||||
# used 3 sec ago
|
||||
crf1 = Connections.crf(3, 10, crf)
|
||||
|
||||
# used 4 sec ago
|
||||
crf2 = Connections.crf(4, 10, crf)
|
||||
|
||||
assert crf1 > crf2
|
||||
end
|
||||
|
||||
test "equal crf on equal reference and time", %{crf: crf} do
|
||||
# used 2 times
|
||||
crf1 = Connections.crf(1, 10, crf)
|
||||
|
||||
# used 2 times
|
||||
crf2 = Connections.crf(1, 10, crf)
|
||||
|
||||
assert crf1 == crf2
|
||||
end
|
||||
|
||||
test "recently used will have higher crf", %{crf: crf} do
|
||||
crf1 = Connections.crf(2, 10, crf)
|
||||
crf1 = Connections.crf(1, 10, crf1)
|
||||
|
||||
crf2 = Connections.crf(3, 10, crf)
|
||||
crf2 = Connections.crf(4, 10, crf2)
|
||||
assert crf1 > crf2
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_unused_conns/1" do
|
||||
test "crf is equalent, sorting by reference", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
last_reference: now() - 1
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
last_reference: now()
|
||||
})
|
||||
|
||||
assert [{"1", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
|
||||
test "reference is equalent, sorting by crf", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 1.999
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 2
|
||||
})
|
||||
|
||||
assert [{"1", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
|
||||
test "higher crf and lower reference", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 3,
|
||||
last_reference: now() - 1
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 2,
|
||||
last_reference: now()
|
||||
})
|
||||
|
||||
assert [{"2", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
|
||||
test "lower crf and lower reference", %{name: name} do
|
||||
Connections.add_conn(name, "1", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 1.99,
|
||||
last_reference: now() - 1
|
||||
})
|
||||
|
||||
Connections.add_conn(name, "2", %Conn{
|
||||
conn_state: :idle,
|
||||
crf: 2,
|
||||
last_reference: now()
|
||||
})
|
||||
|
||||
assert [{"1", _unused_conn} | _others] = Connections.get_unused_conns(name)
|
||||
end
|
||||
end
|
||||
|
||||
test "count/1" do
|
||||
name = :test_count
|
||||
{:ok, _} = Connections.start_link({name, [checkin_timeout: 150]})
|
||||
assert Connections.count(name) == 0
|
||||
Connections.add_conn(name, "1", %Conn{conn: self()})
|
||||
assert Connections.count(name) == 1
|
||||
Connections.remove_conn(name, "1")
|
||||
assert Connections.count(name) == 0
|
||||
end
|
||||
end
|
||||
|
|
@ -4,13 +4,16 @@
|
|||
|
||||
defmodule Pleroma.ReverseProxyTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
|
||||
alias Pleroma.ReverseProxy
|
||||
alias Pleroma.ReverseProxy.ClientMock
|
||||
alias Plug.Conn
|
||||
|
||||
setup_all do
|
||||
{:ok, _} = Registry.start_link(keys: :unique, name: Pleroma.ReverseProxy.ClientMock)
|
||||
{:ok, _} = Registry.start_link(keys: :unique, name: ClientMock)
|
||||
:ok
|
||||
end
|
||||
|
||||
|
|
@ -21,7 +24,7 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, url, _, _, _ ->
|
||||
Registry.register(Pleroma.ReverseProxy.ClientMock, url, 0)
|
||||
Registry.register(ClientMock, url, 0)
|
||||
|
||||
{:ok, 200,
|
||||
[
|
||||
|
|
@ -29,14 +32,14 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
{"content-length", byte_size(json) |> to_string()}
|
||||
], %{url: url}}
|
||||
end)
|
||||
|> expect(:stream_body, invokes, fn %{url: url} ->
|
||||
case Registry.lookup(Pleroma.ReverseProxy.ClientMock, url) do
|
||||
|> expect(:stream_body, invokes, fn %{url: url} = client ->
|
||||
case Registry.lookup(ClientMock, url) do
|
||||
[{_, 0}] ->
|
||||
Registry.update_value(Pleroma.ReverseProxy.ClientMock, url, &(&1 + 1))
|
||||
{:ok, json}
|
||||
Registry.update_value(ClientMock, url, &(&1 + 1))
|
||||
{:ok, json, client}
|
||||
|
||||
[{_, 1}] ->
|
||||
Registry.unregister(Pleroma.ReverseProxy.ClientMock, url)
|
||||
Registry.unregister(ClientMock, url)
|
||||
:done
|
||||
end
|
||||
end)
|
||||
|
|
@ -78,7 +81,39 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
assert conn.halted
|
||||
end
|
||||
|
||||
describe "max_body " do
|
||||
defp stream_mock(invokes, with_close? \\ false) do
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, "/stream-bytes/" <> length, _, _, _ ->
|
||||
Registry.register(ClientMock, "/stream-bytes/" <> length, 0)
|
||||
|
||||
{:ok, 200, [{"content-type", "application/octet-stream"}],
|
||||
%{url: "/stream-bytes/" <> length}}
|
||||
end)
|
||||
|> expect(:stream_body, invokes, fn %{url: "/stream-bytes/" <> length} = client ->
|
||||
max = String.to_integer(length)
|
||||
|
||||
case Registry.lookup(ClientMock, "/stream-bytes/" <> length) do
|
||||
[{_, current}] when current < max ->
|
||||
Registry.update_value(
|
||||
ClientMock,
|
||||
"/stream-bytes/" <> length,
|
||||
&(&1 + 10)
|
||||
)
|
||||
|
||||
{:ok, "0123456789", client}
|
||||
|
||||
[{_, ^max}] ->
|
||||
Registry.unregister(ClientMock, "/stream-bytes/" <> length)
|
||||
:done
|
||||
end
|
||||
end)
|
||||
|
||||
if with_close? do
|
||||
expect(ClientMock, :close, fn _ -> :ok end)
|
||||
end
|
||||
end
|
||||
|
||||
describe "max_body" do
|
||||
test "length returns error if content-length more than option", %{conn: conn} do
|
||||
user_agent_mock("hackney/1.15.1", 0)
|
||||
|
||||
|
|
@ -94,38 +129,6 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
end) == ""
|
||||
end
|
||||
|
||||
defp stream_mock(invokes, with_close? \\ false) do
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, "/stream-bytes/" <> length, _, _, _ ->
|
||||
Registry.register(Pleroma.ReverseProxy.ClientMock, "/stream-bytes/" <> length, 0)
|
||||
|
||||
{:ok, 200, [{"content-type", "application/octet-stream"}],
|
||||
%{url: "/stream-bytes/" <> length}}
|
||||
end)
|
||||
|> expect(:stream_body, invokes, fn %{url: "/stream-bytes/" <> length} ->
|
||||
max = String.to_integer(length)
|
||||
|
||||
case Registry.lookup(Pleroma.ReverseProxy.ClientMock, "/stream-bytes/" <> length) do
|
||||
[{_, current}] when current < max ->
|
||||
Registry.update_value(
|
||||
Pleroma.ReverseProxy.ClientMock,
|
||||
"/stream-bytes/" <> length,
|
||||
&(&1 + 10)
|
||||
)
|
||||
|
||||
{:ok, "0123456789"}
|
||||
|
||||
[{_, ^max}] ->
|
||||
Registry.unregister(Pleroma.ReverseProxy.ClientMock, "/stream-bytes/" <> length)
|
||||
:done
|
||||
end
|
||||
end)
|
||||
|
||||
if with_close? do
|
||||
expect(ClientMock, :close, fn _ -> :ok end)
|
||||
end
|
||||
end
|
||||
|
||||
test "max_body_length returns error if streaming body more than that option", %{conn: conn} do
|
||||
stream_mock(3, true)
|
||||
|
||||
|
|
@ -214,24 +217,24 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
conn = ReverseProxy.call(conn, "/stream-bytes/200")
|
||||
assert conn.state == :chunked
|
||||
assert byte_size(conn.resp_body) == 200
|
||||
assert Plug.Conn.get_resp_header(conn, "content-type") == ["application/octet-stream"]
|
||||
assert Conn.get_resp_header(conn, "content-type") == ["application/octet-stream"]
|
||||
end
|
||||
|
||||
defp headers_mock(_) do
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, "/headers", headers, _, _ ->
|
||||
Registry.register(Pleroma.ReverseProxy.ClientMock, "/headers", 0)
|
||||
Registry.register(ClientMock, "/headers", 0)
|
||||
{:ok, 200, [{"content-type", "application/json"}], %{url: "/headers", headers: headers}}
|
||||
end)
|
||||
|> expect(:stream_body, 2, fn %{url: url, headers: headers} ->
|
||||
case Registry.lookup(Pleroma.ReverseProxy.ClientMock, url) do
|
||||
|> expect(:stream_body, 2, fn %{url: url, headers: headers} = client ->
|
||||
case Registry.lookup(ClientMock, url) do
|
||||
[{_, 0}] ->
|
||||
Registry.update_value(Pleroma.ReverseProxy.ClientMock, url, &(&1 + 1))
|
||||
Registry.update_value(ClientMock, url, &(&1 + 1))
|
||||
headers = for {k, v} <- headers, into: %{}, do: {String.capitalize(k), v}
|
||||
{:ok, Jason.encode!(%{headers: headers})}
|
||||
{:ok, Jason.encode!(%{headers: headers}), client}
|
||||
|
||||
[{_, 1}] ->
|
||||
Registry.unregister(Pleroma.ReverseProxy.ClientMock, url)
|
||||
Registry.unregister(ClientMock, url)
|
||||
:done
|
||||
end
|
||||
end)
|
||||
|
|
@ -244,7 +247,7 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
|
||||
test "header passes", %{conn: conn} do
|
||||
conn =
|
||||
Plug.Conn.put_req_header(
|
||||
Conn.put_req_header(
|
||||
conn,
|
||||
"accept",
|
||||
"text/html"
|
||||
|
|
@ -257,7 +260,7 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
|
||||
test "header is filtered", %{conn: conn} do
|
||||
conn =
|
||||
Plug.Conn.put_req_header(
|
||||
Conn.put_req_header(
|
||||
conn,
|
||||
"accept-language",
|
||||
"en-US"
|
||||
|
|
@ -290,18 +293,18 @@ defmodule Pleroma.ReverseProxyTest do
|
|||
defp disposition_headers_mock(headers) do
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, "/disposition", _, _, _ ->
|
||||
Registry.register(Pleroma.ReverseProxy.ClientMock, "/disposition", 0)
|
||||
Registry.register(ClientMock, "/disposition", 0)
|
||||
|
||||
{:ok, 200, headers, %{url: "/disposition"}}
|
||||
end)
|
||||
|> expect(:stream_body, 2, fn %{url: "/disposition"} ->
|
||||
case Registry.lookup(Pleroma.ReverseProxy.ClientMock, "/disposition") do
|
||||
|> expect(:stream_body, 2, fn %{url: "/disposition"} = client ->
|
||||
case Registry.lookup(ClientMock, "/disposition") do
|
||||
[{_, 0}] ->
|
||||
Registry.update_value(Pleroma.ReverseProxy.ClientMock, "/disposition", &(&1 + 1))
|
||||
{:ok, ""}
|
||||
Registry.update_value(ClientMock, "/disposition", &(&1 + 1))
|
||||
{:ok, "", client}
|
||||
|
||||
[{_, 1}] ->
|
||||
Registry.unregister(Pleroma.ReverseProxy.ClientMock, "/disposition")
|
||||
Registry.unregister(ClientMock, "/disposition")
|
||||
:done
|
||||
end
|
||||
end)
|
||||
|
|
@ -19,12 +19,7 @@ defmodule Pleroma.SignatureTest do
|
|||
|
||||
@private_key "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA48qb4v6kqigZutO9Ot0wkp27GIF2LiVaADgxQORZozZR63jH\nTaoOrS3Xhngbgc8SSOhfXET3omzeCLqaLNfXnZ8OXmuhJfJSU6mPUvmZ9QdT332j\nfN/g3iWGhYMf/M9ftCKh96nvFVO/tMruzS9xx7tkrfJjehdxh/3LlJMMImPtwcD7\nkFXwyt1qZTAU6Si4oQAJxRDQXHp1ttLl3Ob829VM7IKkrVmY8TD+JSlV0jtVJPj6\n1J19ytKTx/7UaucYvb9HIiBpkuiy5n/irDqKLVf5QEdZoNCdojOZlKJmTLqHhzKP\n3E9TxsUjhrf4/EqegNc/j982RvOxeu4i40zMQwIDAQABAoIBAQDH5DXjfh21i7b4\ncXJuw0cqget617CDUhemdakTDs9yH+rHPZd3mbGDWuT0hVVuFe4vuGpmJ8c+61X0\nRvugOlBlavxK8xvYlsqTzAmPgKUPljyNtEzQ+gz0I+3mH2jkin2rL3D+SksZZgKm\nfiYMPIQWB2WUF04gB46DDb2mRVuymGHyBOQjIx3WC0KW2mzfoFUFRlZEF+Nt8Ilw\nT+g/u0aZ1IWoszbsVFOEdghgZET0HEarum0B2Je/ozcPYtwmU10iBANGMKdLqaP/\nj954BPunrUf6gmlnLZKIKklJj0advx0NA+cL79+zeVB3zexRYSA5o9q0WPhiuTwR\n/aedWHnBAoGBAP0sDWBAM1Y4TRAf8ZI9PcztwLyHPzfEIqzbObJJnx1icUMt7BWi\n+/RMOnhrlPGE1kMhOqSxvXYN3u+eSmWTqai2sSH5Hdw2EqnrISSTnwNUPINX7fHH\njEkgmXQ6ixE48SuBZnb4w1EjdB/BA6/sjL+FNhggOc87tizLTkMXmMtTAoGBAOZV\n+wPuAMBDBXmbmxCuDIjoVmgSlgeRunB1SA8RCPAFAiUo3+/zEgzW2Oz8kgI+xVwM\n33XkLKrWG1Orhpp6Hm57MjIc5MG+zF4/YRDpE/KNG9qU1tiz0UD5hOpIU9pP4bR/\ngxgPxZzvbk4h5BfHWLpjlk8UUpgk6uxqfti48c1RAoGBALBOKDZ6HwYRCSGMjUcg\n3NPEUi84JD8qmFc2B7Tv7h2he2ykIz9iFAGpwCIyETQsJKX1Ewi0OlNnD3RhEEAy\nl7jFGQ+mkzPSeCbadmcpYlgIJmf1KN/x7fDTAepeBpCEzfZVE80QKbxsaybd3Dp8\nCfwpwWUFtBxr4c7J+gNhAGe/AoGAPn8ZyqkrPv9wXtyfqFjxQbx4pWhVmNwrkBPi\nZ2Qh3q4dNOPwTvTO8vjghvzIyR8rAZzkjOJKVFgftgYWUZfM5gE7T2mTkBYq8W+U\n8LetF+S9qAM2gDnaDx0kuUTCq7t87DKk6URuQ/SbI0wCzYjjRD99KxvChVGPBHKo\n1DjqMuECgYEAgJGNm7/lJCS2wk81whfy/ttKGsEIkyhPFYQmdGzSYC5aDc2gp1R3\nxtOkYEvdjfaLfDGEa4UX8CHHF+w3t9u8hBtcdhMH6GYb9iv6z0VBTt4A/11HUR49\n3Z7TQ18Iyh3jAUCzFV9IJlLIExq5Y7P4B3ojWFBN607sDCt8BMPbDYs=\n-----END RSA PRIVATE KEY-----"
|
||||
|
||||
@public_key %{
|
||||
"id" => "https://mastodon.social/users/lambadalambda#main-key",
|
||||
"owner" => "https://mastodon.social/users/lambadalambda",
|
||||
"publicKeyPem" =>
|
||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw0P/Tq4gb4G/QVuMGbJo\nC/AfMNcv+m7NfrlOwkVzcU47jgESuYI4UtJayissCdBycHUnfVUd9qol+eznSODz\nCJhfJloqEIC+aSnuEPGA0POtWad6DU0E6/Ho5zQn5WAWUwbRQqowbrsm/GHo2+3v\neR5jGenwA6sYhINg/c3QQbksyV0uJ20Umyx88w8+TJuv53twOfmyDWuYNoQ3y5cc\nHKOZcLHxYOhvwg3PFaGfFHMFiNmF40dTXt9K96r7sbzc44iLD+VphbMPJEjkMuf8\nPGEFOBzy8pm3wJZw2v32RNW2VESwMYyqDzwHXGSq1a73cS7hEnc79gXlELsK04L9\nQQIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
}
|
||||
@public_key "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw0P/Tq4gb4G/QVuMGbJo\nC/AfMNcv+m7NfrlOwkVzcU47jgESuYI4UtJayissCdBycHUnfVUd9qol+eznSODz\nCJhfJloqEIC+aSnuEPGA0POtWad6DU0E6/Ho5zQn5WAWUwbRQqowbrsm/GHo2+3v\neR5jGenwA6sYhINg/c3QQbksyV0uJ20Umyx88w8+TJuv53twOfmyDWuYNoQ3y5cc\nHKOZcLHxYOhvwg3PFaGfFHMFiNmF40dTXt9K96r7sbzc44iLD+VphbMPJEjkMuf8\nPGEFOBzy8pm3wJZw2v32RNW2VESwMYyqDzwHXGSq1a73cS7hEnc79gXlELsK04L9\nQQIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
|
||||
@rsa_public_key {
|
||||
:RSAPublicKey,
|
||||
|
|
@ -42,19 +37,20 @@ defmodule Pleroma.SignatureTest do
|
|||
test "it returns key" do
|
||||
expected_result = {:ok, @rsa_public_key}
|
||||
|
||||
user = insert(:user, source_data: %{"publicKey" => @public_key})
|
||||
user = insert(:user, public_key: @public_key)
|
||||
|
||||
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
|
||||
end
|
||||
|
||||
test "it returns error when not found user" do
|
||||
assert capture_log(fn ->
|
||||
assert Signature.fetch_public_key(make_fake_conn("test-ap_id")) == {:error, :error}
|
||||
assert Signature.fetch_public_key(make_fake_conn("https://test-ap-id")) ==
|
||||
{:error, :error}
|
||||
end) =~ "[error] Could not decode user"
|
||||
end
|
||||
|
||||
test "it returns error if public key is empty" do
|
||||
user = insert(:user, source_data: %{"publicKey" => %{}})
|
||||
test "it returns error if public key is nil" do
|
||||
user = insert(:user, public_key: nil)
|
||||
|
||||
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == {:error, :error}
|
||||
end
|
||||
|
|
@ -69,7 +65,7 @@ defmodule Pleroma.SignatureTest do
|
|||
|
||||
test "it returns error when not found user" do
|
||||
assert capture_log(fn ->
|
||||
{:error, _} = Signature.refetch_public_key(make_fake_conn("test-ap_id"))
|
||||
{:error, _} = Signature.refetch_public_key(make_fake_conn("https://test-ap_id"))
|
||||
end) =~ "[error] Could not decode user"
|
||||
end
|
||||
end
|
||||
|
|
@ -105,12 +101,21 @@ defmodule Pleroma.SignatureTest do
|
|||
describe "key_id_to_actor_id/1" do
|
||||
test "it properly deduces the actor id for misskey" do
|
||||
assert Signature.key_id_to_actor_id("https://example.com/users/1234/publickey") ==
|
||||
"https://example.com/users/1234"
|
||||
{:ok, "https://example.com/users/1234"}
|
||||
end
|
||||
|
||||
test "it properly deduces the actor id for mastodon and pleroma" do
|
||||
assert Signature.key_id_to_actor_id("https://example.com/users/1234#main-key") ==
|
||||
"https://example.com/users/1234"
|
||||
{:ok, "https://example.com/users/1234"}
|
||||
end
|
||||
|
||||
test "it calls webfinger for 'acct:' accounts" do
|
||||
with_mock(Pleroma.Web.WebFinger,
|
||||
finger: fn _ -> %{"ap_id" => "https://gensokyo.2hu/users/raymoo"} end
|
||||
) do
|
||||
assert Signature.key_id_to_actor_id("acct:raymoo@gensokyo.2hu") ==
|
||||
{:ok, "https://gensokyo.2hu/users/raymoo"}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,36 +2,46 @@
|
|||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.StateTest do
|
||||
defmodule Pleroma.StatsTest do
|
||||
use Pleroma.DataCase
|
||||
import Pleroma.Factory
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
describe "user count" do
|
||||
test "it ignores internal users" do
|
||||
_user = insert(:user, local: true)
|
||||
_internal = insert(:user, local: true, nickname: nil)
|
||||
_internal = Pleroma.Web.ActivityPub.Relay.get_actor()
|
||||
|
||||
assert match?(%{stats: %{user_count: 1}}, Pleroma.Stats.calculate_stat_data())
|
||||
end
|
||||
end
|
||||
|
||||
describe "status visibility count" do
|
||||
test "on new status" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||
CommonAPI.post(user, %{visibility: "public", status: "hey"})
|
||||
|
||||
Enum.each(0..1, fn _ ->
|
||||
CommonAPI.post(user, %{
|
||||
"visibility" => "unlisted",
|
||||
"status" => "hey"
|
||||
visibility: "unlisted",
|
||||
status: "hey"
|
||||
})
|
||||
end)
|
||||
|
||||
Enum.each(0..2, fn _ ->
|
||||
CommonAPI.post(user, %{
|
||||
"visibility" => "direct",
|
||||
"status" => "hey @#{other_user.nickname}"
|
||||
visibility: "direct",
|
||||
status: "hey @#{other_user.nickname}"
|
||||
})
|
||||
end)
|
||||
|
||||
Enum.each(0..3, fn _ ->
|
||||
CommonAPI.post(user, %{
|
||||
"visibility" => "private",
|
||||
"status" => "hey"
|
||||
visibility: "private",
|
||||
status: "hey"
|
||||
})
|
||||
end)
|
||||
|
||||
|
|
@ -41,7 +51,7 @@ defmodule Pleroma.StateTest do
|
|||
|
||||
test "on status delete" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{visibility: "public", status: "hey"})
|
||||
assert %{public: 1} = Pleroma.Stats.get_status_visibility_count()
|
||||
CommonAPI.delete(activity.id, user)
|
||||
assert %{public: 0} = Pleroma.Stats.get_status_visibility_count()
|
||||
|
|
@ -49,18 +59,18 @@ defmodule Pleroma.StateTest do
|
|||
|
||||
test "on status visibility update" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{visibility: "public", status: "hey"})
|
||||
assert %{public: 1, private: 0} = Pleroma.Stats.get_status_visibility_count()
|
||||
{:ok, _} = CommonAPI.update_activity_scope(activity.id, %{"visibility" => "private"})
|
||||
{:ok, _} = CommonAPI.update_activity_scope(activity.id, %{visibility: "private"})
|
||||
assert %{public: 0, private: 1} = Pleroma.Stats.get_status_visibility_count()
|
||||
end
|
||||
|
||||
test "doesn't count unrelated activities" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{visibility: "public", status: "hey"})
|
||||
_ = CommonAPI.follow(user, other_user)
|
||||
CommonAPI.favorite(activity.id, other_user)
|
||||
CommonAPI.favorite(other_user, activity.id)
|
||||
CommonAPI.repeat(activity.id, other_user)
|
||||
|
||||
assert %{direct: 0, private: 0, public: 1, unlisted: 0} =
|
||||
57
test/support/api_spec_helpers.ex
Normal file
57
test/support/api_spec_helpers.ex
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Tests.ApiSpecHelpers do
|
||||
@moduledoc """
|
||||
OpenAPI spec test helpers
|
||||
"""
|
||||
|
||||
import ExUnit.Assertions
|
||||
|
||||
alias OpenApiSpex.Cast.Error
|
||||
alias OpenApiSpex.Reference
|
||||
alias OpenApiSpex.Schema
|
||||
|
||||
def assert_schema(value, schema) do
|
||||
api_spec = Pleroma.Web.ApiSpec.spec()
|
||||
|
||||
case OpenApiSpex.cast_value(value, schema, api_spec) do
|
||||
{:ok, data} ->
|
||||
data
|
||||
|
||||
{:error, errors} ->
|
||||
errors =
|
||||
Enum.map(errors, fn error ->
|
||||
message = Error.message(error)
|
||||
path = Error.path_to_string(error)
|
||||
"#{message} at #{path}"
|
||||
end)
|
||||
|
||||
flunk(
|
||||
"Value does not conform to schema #{schema.title}: #{Enum.join(errors, "\n")}\n#{
|
||||
inspect(value)
|
||||
}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def resolve_schema(%Schema{} = schema), do: schema
|
||||
|
||||
def resolve_schema(%Reference{} = ref) do
|
||||
schemas = Pleroma.Web.ApiSpec.spec().components.schemas
|
||||
Reference.resolve_schema(ref, schemas)
|
||||
end
|
||||
|
||||
def api_operations do
|
||||
paths = Pleroma.Web.ApiSpec.spec().paths
|
||||
|
||||
Enum.flat_map(paths, fn {_, path_item} ->
|
||||
path_item
|
||||
|> Map.take([:delete, :get, :head, :options, :patch, :post, :put, :trace])
|
||||
|> Map.values()
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.uniq()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
@ -21,7 +21,15 @@ defmodule Pleroma.Builders.ActivityBuilder do
|
|||
|
||||
def insert(data \\ %{}, opts \\ %{}) do
|
||||
activity = build(data, opts)
|
||||
ActivityPub.insert(activity)
|
||||
|
||||
case ActivityPub.insert(activity) do
|
||||
ok = {:ok, activity} ->
|
||||
ActivityPub.notify_and_stream(activity)
|
||||
ok
|
||||
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
def insert_list(times, data \\ %{}, opts \\ %{}) do
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ defmodule Pleroma.Builders.UserBuilder do
|
|||
email: "test@example.org",
|
||||
name: "Test Name",
|
||||
nickname: "testname",
|
||||
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
|
||||
password_hash: Pbkdf2.hash_pwd_salt("test"),
|
||||
bio: "A tester.",
|
||||
ap_id: "some id",
|
||||
last_digest_emailed_at: NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second),
|
||||
multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
|
||||
notification_settings: %Pleroma.User.NotificationSetting{}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,16 @@ defmodule Pleroma.Captcha.Mock do
|
|||
alias Pleroma.Captcha.Service
|
||||
@behaviour Service
|
||||
|
||||
@solution "63615261b77f5354fb8c4e4986477555"
|
||||
|
||||
def solution, do: @solution
|
||||
|
||||
@impl Service
|
||||
def new,
|
||||
do: %{
|
||||
type: :mock,
|
||||
token: "afa1815e14e29355e6c8f6b143a39fa2",
|
||||
answer_data: "63615261b77f5354fb8c4e4986477555",
|
||||
answer_data: @solution,
|
||||
url: "https://example.org/captcha.png"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,60 @@ defmodule Pleroma.Web.ConnCase do
|
|||
%{user: user, token: token, conn: conn}
|
||||
end
|
||||
|
||||
defp request_content_type(%{conn: conn}) do
|
||||
conn = put_req_header(conn, "content-type", "multipart/form-data")
|
||||
[conn: conn]
|
||||
end
|
||||
|
||||
defp json_response_and_validate_schema(
|
||||
%{
|
||||
private: %{
|
||||
open_api_spex: %{operation_id: op_id, operation_lookup: lookup, spec: spec}
|
||||
}
|
||||
} = conn,
|
||||
status
|
||||
) do
|
||||
content_type =
|
||||
conn
|
||||
|> Plug.Conn.get_resp_header("content-type")
|
||||
|> List.first()
|
||||
|> String.split(";")
|
||||
|> List.first()
|
||||
|
||||
status = Plug.Conn.Status.code(status)
|
||||
|
||||
unless lookup[op_id].responses[status] do
|
||||
err = "Response schema not found for #{status} #{conn.method} #{conn.request_path}"
|
||||
flunk(err)
|
||||
end
|
||||
|
||||
schema = lookup[op_id].responses[status].content[content_type].schema
|
||||
json = json_response(conn, status)
|
||||
|
||||
case OpenApiSpex.cast_value(json, schema, spec) do
|
||||
{:ok, _data} ->
|
||||
json
|
||||
|
||||
{:error, errors} ->
|
||||
errors =
|
||||
Enum.map(errors, fn error ->
|
||||
message = OpenApiSpex.Cast.Error.message(error)
|
||||
path = OpenApiSpex.Cast.Error.path_to_string(error)
|
||||
"#{message} at #{path}"
|
||||
end)
|
||||
|
||||
flunk(
|
||||
"Response does not conform to schema of #{op_id} operation: #{
|
||||
Enum.join(errors, "\n")
|
||||
}\n#{inspect(json)}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
defp json_response_and_validate_schema(conn, _status) do
|
||||
flunk("Response schema not found for #{conn.method} #{conn.request_path} #{conn.status}")
|
||||
end
|
||||
|
||||
defp ensure_federating_or_authenticated(conn, url, user) do
|
||||
initial_setting = Config.get([:instance, :federating])
|
||||
on_exit(fn -> Config.put([:instance, :federating], initial_setting) end)
|
||||
|
|
@ -85,7 +139,11 @@ defmodule Pleroma.Web.ConnCase do
|
|||
end
|
||||
|
||||
if tags[:needs_streamer] do
|
||||
start_supervised(Pleroma.Web.Streamer.supervisor())
|
||||
start_supervised(%{
|
||||
id: Pleroma.Web.Streamer.registry(),
|
||||
start:
|
||||
{Registry, :start_link, [[keys: :duplicate, name: Pleroma.Web.Streamer.registry()]]}
|
||||
})
|
||||
end
|
||||
|
||||
{:ok, conn: Phoenix.ConnTest.build_conn()}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,11 @@ defmodule Pleroma.DataCase do
|
|||
end
|
||||
|
||||
if tags[:needs_streamer] do
|
||||
start_supervised(Pleroma.Web.Streamer.supervisor())
|
||||
start_supervised(%{
|
||||
id: Pleroma.Web.Streamer.registry(),
|
||||
start:
|
||||
{Registry, :start_link, [[keys: :duplicate, name: Pleroma.Web.Streamer.registry()]]}
|
||||
})
|
||||
end
|
||||
|
||||
:ok
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@ defmodule Pleroma.Factory do
|
|||
name: sequence(:name, &"Test テスト User #{&1}"),
|
||||
email: sequence(:email, &"user#{&1}@example.com"),
|
||||
nickname: sequence(:nickname, &"nick#{&1}"),
|
||||
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
|
||||
password_hash: Pbkdf2.hash_pwd_salt("test"),
|
||||
bio: sequence(:bio, &"Tester Number #{&1}"),
|
||||
last_digest_emailed_at: NaiveDateTime.utc_now(),
|
||||
notification_settings: %Pleroma.User.NotificationSetting{}
|
||||
last_refreshed_at: NaiveDateTime.utc_now(),
|
||||
notification_settings: %Pleroma.User.NotificationSetting{},
|
||||
multi_factor_authentication_settings: %Pleroma.MFA.Settings{}
|
||||
}
|
||||
|
||||
%{
|
||||
|
|
@ -294,7 +296,7 @@ defmodule Pleroma.Factory do
|
|||
|
||||
def oauth_app_factory do
|
||||
%Pleroma.Web.OAuth.App{
|
||||
client_name: "Some client",
|
||||
client_name: sequence(:client_name, &"Some client #{&1}"),
|
||||
redirect_uris: "https://example.com/callback",
|
||||
scopes: ["read", "write", "follow", "push", "admin"],
|
||||
website: "https://example.com",
|
||||
|
|
@ -421,4 +423,13 @@ defmodule Pleroma.Factory do
|
|||
last_read_id: "1"
|
||||
}
|
||||
end
|
||||
|
||||
def mfa_token_factory do
|
||||
%Pleroma.MFA.Token{
|
||||
token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false),
|
||||
authorization: build(:oauth_authorization),
|
||||
valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10),
|
||||
user: build(:user)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -40,12 +40,18 @@ defmodule Pleroma.Tests.Helpers do
|
|||
clear_config: 2
|
||||
]
|
||||
|
||||
def to_datetime(naive_datetime) do
|
||||
def to_datetime(%NaiveDateTime{} = naive_datetime) do
|
||||
naive_datetime
|
||||
|> DateTime.from_naive!("Etc/UTC")
|
||||
|> DateTime.truncate(:second)
|
||||
end
|
||||
|
||||
def to_datetime(datetime) when is_binary(datetime) do
|
||||
datetime
|
||||
|> NaiveDateTime.from_iso8601!()
|
||||
|> to_datetime()
|
||||
end
|
||||
|
||||
def collect_ids(collection) do
|
||||
collection
|
||||
|> Enum.map(& &1.id)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ defmodule HttpRequestMock do
|
|||
"https://osada.macgirvin.com/.well-known/webfinger?resource=acct:mike@osada.macgirvin.com",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -120,7 +120,7 @@ defmodule HttpRequestMock do
|
|||
"https://social.heldscal.la/.well-known/webfinger?resource=https://social.heldscal.la/user/29191",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -141,7 +141,7 @@ defmodule HttpRequestMock do
|
|||
"https://pawoo.net/.well-known/webfinger?resource=acct:https://pawoo.net/users/pekorino",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -167,7 +167,7 @@ defmodule HttpRequestMock do
|
|||
"https://social.stopwatchingus-heidelberg.de/.well-known/webfinger?resource=acct:https://social.stopwatchingus-heidelberg.de/user/18330",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -188,7 +188,7 @@ defmodule HttpRequestMock do
|
|||
"https://mamot.fr/.well-known/webfinger?resource=acct:https://mamot.fr/users/Skruyb",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -201,7 +201,7 @@ defmodule HttpRequestMock do
|
|||
"https://social.heldscal.la/.well-known/webfinger?resource=nonexistant@social.heldscal.la",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -211,10 +211,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"https://squeet.me/xrd/?uri=lain@squeet.me",
|
||||
"https://squeet.me/xrd/?uri=acct:lain@squeet.me",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -227,7 +227,7 @@ defmodule HttpRequestMock do
|
|||
"https://mst3k.interlinked.me/users/luciferMysticus",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/activity+json"
|
||||
[{"accept", "application/activity+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -248,7 +248,7 @@ defmodule HttpRequestMock do
|
|||
"https://hubzilla.example.org/channel/kaniini",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/activity+json"
|
||||
[{"accept", "application/activity+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -257,7 +257,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://niu.moe/users/rye", _, _, Accept: "application/activity+json") do
|
||||
def get("https://niu.moe/users/rye", _, _, [{"accept", "application/activity+json"}]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -265,7 +265,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://n1u.moe/users/rye", _, _, Accept: "application/activity+json") do
|
||||
def get("https://n1u.moe/users/rye", _, _, [{"accept", "application/activity+json"}]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -284,7 +284,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://puckipedia.com/", _, _, Accept: "application/activity+json") do
|
||||
def get("https://puckipedia.com/", _, _, [{"accept", "application/activity+json"}]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -308,9 +308,25 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39", _, _,
|
||||
Accept: "application/activity+json"
|
||||
) do
|
||||
def get("https://peertube.social/accounts/craigmaloney", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/craigmaloney.json")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://peertube.social/videos/watch/278d2b7c-0f38-4aaa-afe6-9ecc0c4a34fe", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/tesla_mock/peertube-social.json")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39", _, _, [
|
||||
{"accept", "application/activity+json"}
|
||||
]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -318,7 +334,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://mobilizon.org/@tcit", _, _, Accept: "application/activity+json") do
|
||||
def get("https://mobilizon.org/@tcit", _, _, [{"accept", "application/activity+json"}]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -358,7 +374,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("http://mastodon.example.org/users/admin", _, _, Accept: "application/activity+json") do
|
||||
def get("http://mastodon.example.org/users/admin", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -366,7 +382,9 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("http://mastodon.example.org/users/relay", _, _, Accept: "application/activity+json") do
|
||||
def get("http://mastodon.example.org/users/relay", _, _, [
|
||||
{"accept", "application/activity+json"}
|
||||
]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -374,7 +392,9 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("http://mastodon.example.org/users/gargron", _, _, Accept: "application/activity+json") do
|
||||
def get("http://mastodon.example.org/users/gargron", _, _, [
|
||||
{"accept", "application/activity+json"}
|
||||
]) do
|
||||
{:error, :nxdomain}
|
||||
end
|
||||
|
||||
|
|
@ -557,7 +577,7 @@ defmodule HttpRequestMock do
|
|||
"http://mastodon.example.org/@admin/99541947525187367",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/activity+json"
|
||||
_
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -582,7 +602,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://mstdn.io/users/mayuutann", _, _, Accept: "application/activity+json") do
|
||||
def get("https://mstdn.io/users/mayuutann", _, _, [{"accept", "application/activity+json"}]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -594,7 +614,7 @@ defmodule HttpRequestMock do
|
|||
"https://mstdn.io/users/mayuutann/statuses/99568293732299394",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/activity+json"
|
||||
[{"accept", "application/activity+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -614,7 +634,7 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get(url, _, _, Accept: "application/xrd+xml,application/jrd+json")
|
||||
def get(url, _, _, [{"accept", "application/xrd+xml,application/jrd+json"}])
|
||||
when url in [
|
||||
"https://pleroma.soykaf.com/.well-known/webfinger?resource=acct:https://pleroma.soykaf.com/users/lain",
|
||||
"https://pleroma.soykaf.com/.well-known/webfinger?resource=https://pleroma.soykaf.com/users/lain"
|
||||
|
|
@ -641,7 +661,7 @@ defmodule HttpRequestMock do
|
|||
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/1",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -685,7 +705,7 @@ defmodule HttpRequestMock do
|
|||
"https://shitposter.club/.well-known/webfinger?resource=https://shitposter.club/user/5381",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -738,7 +758,7 @@ defmodule HttpRequestMock do
|
|||
"https://social.sakamoto.gq/.well-known/webfinger?resource=https://social.sakamoto.gq/users/eal",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -751,7 +771,7 @@ defmodule HttpRequestMock do
|
|||
"https://social.sakamoto.gq/objects/0ccc1a2c-66b0-4305-b23a-7f7f2b040056",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/atom+xml"
|
||||
[{"accept", "application/atom+xml"}]
|
||||
) do
|
||||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sakamoto.atom")}}
|
||||
end
|
||||
|
|
@ -768,7 +788,7 @@ defmodule HttpRequestMock do
|
|||
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/lambadalambda",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -790,7 +810,7 @@ defmodule HttpRequestMock do
|
|||
"http://gs.example.org/.well-known/webfinger?resource=http://gs.example.org:4040/index.php/user/1",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -804,7 +824,7 @@ defmodule HttpRequestMock do
|
|||
"http://gs.example.org:4040/index.php/user/1",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/activity+json"
|
||||
[{"accept", "application/activity+json"}]
|
||||
) do
|
||||
{:ok, %Tesla.Env{status: 406, body: ""}}
|
||||
end
|
||||
|
|
@ -840,7 +860,7 @@ defmodule HttpRequestMock do
|
|||
"https://squeet.me/xrd?uri=lain@squeet.me",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -850,10 +870,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"https://social.heldscal.la/.well-known/webfinger?resource=shp@social.heldscal.la",
|
||||
"https://social.heldscal.la/.well-known/webfinger?resource=acct:shp@social.heldscal.la",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -863,10 +883,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"https://social.heldscal.la/.well-known/webfinger?resource=invalid_content@social.heldscal.la",
|
||||
"https://social.heldscal.la/.well-known/webfinger?resource=acct:invalid_content@social.heldscal.la",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end
|
||||
|
|
@ -880,10 +900,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"http://framatube.org/main/xrd?uri=framasoft@framatube.org",
|
||||
"http://framatube.org/main/xrd?uri=acct:framasoft@framatube.org",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -905,7 +925,7 @@ defmodule HttpRequestMock do
|
|||
"http://gnusocial.de/main/xrd?uri=winterdienst@gnusocial.de",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -939,10 +959,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"https://gerzilla.de/xrd/?uri=kaniini@gerzilla.de",
|
||||
"https://gerzilla.de/xrd/?uri=acct:kaniini@gerzilla.de",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -1005,7 +1025,7 @@ defmodule HttpRequestMock do
|
|||
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json")}}
|
||||
end
|
||||
|
||||
def get("https://social.heldscal.la/user/23211", _, _, Accept: "application/activity+json") do
|
||||
def get("https://social.heldscal.la/user/23211", _, _, [{"accept", "application/activity+json"}]) do
|
||||
{:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)}
|
||||
end
|
||||
|
||||
|
|
@ -1135,10 +1155,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=lain@zetsubou.xn--q9jyb4c",
|
||||
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:lain@zetsubou.xn--q9jyb4c",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -1148,10 +1168,10 @@ defmodule HttpRequestMock do
|
|||
end
|
||||
|
||||
def get(
|
||||
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=https://zetsubou.xn--q9jyb4c/users/lain",
|
||||
"https://zetsubou.xn--q9jyb4c/.well-known/webfinger?resource=acct:https://zetsubou.xn--q9jyb4c/users/lain",
|
||||
_,
|
||||
_,
|
||||
Accept: "application/xrd+xml,application/jrd+json"
|
||||
[{"accept", "application/xrd+xml,application/jrd+json"}]
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
|
|
@ -1173,7 +1193,9 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://info.pleroma.site/activity.json", _, _, Accept: "application/activity+json") do
|
||||
def get("https://info.pleroma.site/activity.json", _, _, [
|
||||
{"accept", "application/activity+json"}
|
||||
]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -1185,7 +1207,9 @@ defmodule HttpRequestMock do
|
|||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
end
|
||||
|
||||
def get("https://info.pleroma.site/activity2.json", _, _, Accept: "application/activity+json") do
|
||||
def get("https://info.pleroma.site/activity2.json", _, _, [
|
||||
{"accept", "application/activity+json"}
|
||||
]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -1197,7 +1221,9 @@ defmodule HttpRequestMock do
|
|||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
end
|
||||
|
||||
def get("https://info.pleroma.site/activity3.json", _, _, Accept: "application/activity+json") do
|
||||
def get("https://info.pleroma.site/activity3.json", _, _, [
|
||||
{"accept", "application/activity+json"}
|
||||
]) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
|
|
@ -1273,6 +1299,21 @@ defmodule HttpRequestMock do
|
|||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/rin.json")}}
|
||||
end
|
||||
|
||||
def get(
|
||||
"https://channels.tests.funkwhale.audio/federation/music/uploads/42342395-0208-4fee-a38d-259a6dae0871",
|
||||
_,
|
||||
_,
|
||||
_
|
||||
) do
|
||||
{:ok,
|
||||
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/funkwhale_audio.json")}}
|
||||
end
|
||||
|
||||
def get("https://channels.tests.funkwhale.audio/federation/actors/compositions", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/funkwhale_channel.json")}}
|
||||
end
|
||||
|
||||
def get("http://example.com/rel_me/error", _, _, _) do
|
||||
{:ok, %Tesla.Env{status: 404, body: ""}}
|
||||
end
|
||||
|
|
|
|||
65
test/tasks/app_test.exs
Normal file
65
test/tasks/app_test.exs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.AppTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
setup_all do
|
||||
Mix.shell(Mix.Shell.Process)
|
||||
|
||||
on_exit(fn ->
|
||||
Mix.shell(Mix.Shell.IO)
|
||||
end)
|
||||
end
|
||||
|
||||
describe "creates new app" do
|
||||
test "with default scopes" do
|
||||
name = "Some name"
|
||||
redirect = "https://example.com"
|
||||
Mix.Tasks.Pleroma.App.run(["create", "-n", name, "-r", redirect])
|
||||
|
||||
assert_app(name, redirect, ["read", "write", "follow", "push"])
|
||||
end
|
||||
|
||||
test "with custom scopes" do
|
||||
name = "Another name"
|
||||
redirect = "https://example.com"
|
||||
|
||||
Mix.Tasks.Pleroma.App.run([
|
||||
"create",
|
||||
"-n",
|
||||
name,
|
||||
"-r",
|
||||
redirect,
|
||||
"-s",
|
||||
"read,write,follow,push,admin"
|
||||
])
|
||||
|
||||
assert_app(name, redirect, ["read", "write", "follow", "push", "admin"])
|
||||
end
|
||||
end
|
||||
|
||||
test "with errors" do
|
||||
Mix.Tasks.Pleroma.App.run(["create"])
|
||||
{:mix_shell, :error, ["Creating failed:"]}
|
||||
{:mix_shell, :error, ["name: can't be blank"]}
|
||||
{:mix_shell, :error, ["redirect_uris: can't be blank"]}
|
||||
end
|
||||
|
||||
defp assert_app(name, redirect, scopes) do
|
||||
app = Repo.get_by(Pleroma.Web.OAuth.App, client_name: name)
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message == "#{name} successfully created:"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message == "App client_id: #{app.client_id}"
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message == "App client_secret: #{app.client_secret}"
|
||||
|
||||
assert app.scopes == scopes
|
||||
assert app.redirect_uris == redirect
|
||||
end
|
||||
end
|
||||
|
|
@ -38,7 +38,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
on_exit(fn -> Application.put_env(:quack, :level, initial) end)
|
||||
end
|
||||
|
||||
test "settings are migrated to db" do
|
||||
test "filtered settings are migrated to db" do
|
||||
assert Repo.all(ConfigDB) == []
|
||||
|
||||
Mix.Tasks.Pleroma.Config.migrate_to_db("test/fixtures/config/temp.secret.exs")
|
||||
|
|
@ -47,6 +47,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
config2 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":second_setting"})
|
||||
config3 = ConfigDB.get_by_params(%{group: ":quack", key: ":level"})
|
||||
refute ConfigDB.get_by_params(%{group: ":pleroma", key: "Pleroma.Repo"})
|
||||
refute ConfigDB.get_by_params(%{group: ":postgrex", key: ":json_library"})
|
||||
|
||||
assert ConfigDB.from_binary(config1.value) == [key: "value", key2: [Repo]]
|
||||
assert ConfigDB.from_binary(config2.value) == [key: "value2", key2: ["Activity"]]
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ defmodule Mix.Tasks.Pleroma.CountStatusesTest do
|
|||
|
||||
test "counts statuses" do
|
||||
user = insert(:user)
|
||||
{:ok, _} = CommonAPI.post(user, %{"status" => "test"})
|
||||
{:ok, _} = CommonAPI.post(user, %{"status" => "test2"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "test"})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "test2"})
|
||||
|
||||
user2 = insert(:user)
|
||||
{:ok, _} = CommonAPI.post(user2, %{"status" => "test3"})
|
||||
{:ok, _} = CommonAPI.post(user2, %{status: "test3"})
|
||||
|
||||
user = refresh_record(user)
|
||||
user2 = refresh_record(user2)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
|
|||
describe "running remove_embedded_objects" do
|
||||
test "it replaces objects with references" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test"})
|
||||
new_data = Map.put(activity.data, "object", activity.object.data)
|
||||
|
||||
{:ok, activity} =
|
||||
|
|
@ -99,10 +99,10 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
|
|||
test "it turns OrderedCollection likes into empty arrays" do
|
||||
[user, user2] = insert_pair(:user)
|
||||
|
||||
{:ok, %{id: id, object: object}} = CommonAPI.post(user, %{"status" => "test"})
|
||||
{:ok, %{object: object2}} = CommonAPI.post(user, %{"status" => "test test"})
|
||||
{:ok, %{id: id, object: object}} = CommonAPI.post(user, %{status: "test"})
|
||||
{:ok, %{object: object2}} = CommonAPI.post(user, %{status: "test test"})
|
||||
|
||||
CommonAPI.favorite(id, user2)
|
||||
CommonAPI.favorite(user2, id)
|
||||
|
||||
likes = %{
|
||||
"first" =>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ defmodule Mix.Tasks.Pleroma.DigestTest do
|
|||
Enum.each(0..10, fn i ->
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user1, %{
|
||||
"status" => "hey ##{i} @#{user2.nickname}!"
|
||||
status: "hey ##{i} @#{user2.nickname}!"
|
||||
})
|
||||
end)
|
||||
|
||||
|
|
|
|||
226
test/tasks/emoji_test.exs
Normal file
226
test/tasks/emoji_test.exs
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
defmodule Mix.Tasks.Pleroma.EmojiTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
import ExUnit.CaptureIO
|
||||
import Tesla.Mock
|
||||
|
||||
alias Mix.Tasks.Pleroma.Emoji
|
||||
|
||||
describe "ls-packs" do
|
||||
test "with default manifest as url" do
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://git.pleroma.social/pleroma/emoji-index/raw/master/index.json"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/emoji/packs/default-manifest.json")
|
||||
}
|
||||
end)
|
||||
|
||||
capture_io(fn -> Emoji.run(["ls-packs"]) end) =~
|
||||
"https://finland.fi/wp-content/uploads/2017/06/finland-emojis.zip"
|
||||
end
|
||||
|
||||
test "with passed manifest as file" do
|
||||
capture_io(fn ->
|
||||
Emoji.run(["ls-packs", "-m", "test/fixtures/emoji/packs/manifest.json"])
|
||||
end) =~ "https://git.pleroma.social/pleroma/emoji-index/raw/master/packs/blobs_gg.zip"
|
||||
end
|
||||
end
|
||||
|
||||
describe "get-packs" do
|
||||
test "download pack from default manifest" do
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://git.pleroma.social/pleroma/emoji-index/raw/master/index.json"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/emoji/packs/default-manifest.json")
|
||||
}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://finland.fi/wp-content/uploads/2017/06/finland-emojis.zip"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/emoji/packs/blank.png.zip")
|
||||
}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://git.pleroma.social/pleroma/emoji-index/raw/master/finmoji.json"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/emoji/packs/finmoji.json")
|
||||
}
|
||||
end)
|
||||
|
||||
assert capture_io(fn -> Emoji.run(["get-packs", "finmoji"]) end) =~ "Writing pack.json for"
|
||||
|
||||
emoji_path =
|
||||
Path.join(
|
||||
Pleroma.Config.get!([:instance, :static_dir]),
|
||||
"emoji"
|
||||
)
|
||||
|
||||
assert File.exists?(Path.join([emoji_path, "finmoji", "pack.json"]))
|
||||
on_exit(fn -> File.rm_rf!("test/instance_static/emoji/finmoji") end)
|
||||
end
|
||||
|
||||
test "pack not found" do
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://git.pleroma.social/pleroma/emoji-index/raw/master/index.json"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/emoji/packs/default-manifest.json")
|
||||
}
|
||||
end)
|
||||
|
||||
assert capture_io(fn -> Emoji.run(["get-packs", "not_found"]) end) =~
|
||||
"No pack named \"not_found\" found"
|
||||
end
|
||||
|
||||
test "raise on bad sha256" do
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://git.pleroma.social/pleroma/emoji-index/raw/master/packs/blobs_gg.zip"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/emoji/packs/blank.png.zip")
|
||||
}
|
||||
end)
|
||||
|
||||
assert_raise RuntimeError, ~r/^Bad SHA256 for blobs.gg/, fn ->
|
||||
capture_io(fn ->
|
||||
Emoji.run(["get-packs", "blobs.gg", "-m", "test/fixtures/emoji/packs/manifest.json"])
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "gen-pack" do
|
||||
setup do
|
||||
url = "https://finland.fi/wp-content/uploads/2017/06/finland-emojis.zip"
|
||||
|
||||
mock(fn %{
|
||||
method: :get,
|
||||
url: ^url
|
||||
} ->
|
||||
%Tesla.Env{status: 200, body: File.read!("test/fixtures/emoji/packs/blank.png.zip")}
|
||||
end)
|
||||
|
||||
{:ok, url: url}
|
||||
end
|
||||
|
||||
test "with default extensions", %{url: url} do
|
||||
name = "pack1"
|
||||
pack_json = "#{name}.json"
|
||||
files_json = "#{name}_file.json"
|
||||
refute File.exists?(pack_json)
|
||||
refute File.exists?(files_json)
|
||||
|
||||
captured =
|
||||
capture_io(fn ->
|
||||
Emoji.run([
|
||||
"gen-pack",
|
||||
url,
|
||||
"--name",
|
||||
name,
|
||||
"--license",
|
||||
"license",
|
||||
"--homepage",
|
||||
"homepage",
|
||||
"--description",
|
||||
"description",
|
||||
"--files",
|
||||
files_json,
|
||||
"--extensions",
|
||||
".png .gif"
|
||||
])
|
||||
end)
|
||||
|
||||
assert captured =~ "#{pack_json} has been created with the pack1 pack"
|
||||
assert captured =~ "Using .png .gif extensions"
|
||||
|
||||
assert File.exists?(pack_json)
|
||||
assert File.exists?(files_json)
|
||||
|
||||
on_exit(fn ->
|
||||
File.rm!(pack_json)
|
||||
File.rm!(files_json)
|
||||
end)
|
||||
end
|
||||
|
||||
test "with custom extensions and update existing files", %{url: url} do
|
||||
name = "pack2"
|
||||
pack_json = "#{name}.json"
|
||||
files_json = "#{name}_file.json"
|
||||
refute File.exists?(pack_json)
|
||||
refute File.exists?(files_json)
|
||||
|
||||
captured =
|
||||
capture_io(fn ->
|
||||
Emoji.run([
|
||||
"gen-pack",
|
||||
url,
|
||||
"--name",
|
||||
name,
|
||||
"--license",
|
||||
"license",
|
||||
"--homepage",
|
||||
"homepage",
|
||||
"--description",
|
||||
"description",
|
||||
"--files",
|
||||
files_json,
|
||||
"--extensions",
|
||||
" .png .gif .jpeg "
|
||||
])
|
||||
end)
|
||||
|
||||
assert captured =~ "#{pack_json} has been created with the pack2 pack"
|
||||
assert captured =~ "Using .png .gif .jpeg extensions"
|
||||
|
||||
assert File.exists?(pack_json)
|
||||
assert File.exists?(files_json)
|
||||
|
||||
captured =
|
||||
capture_io(fn ->
|
||||
Emoji.run([
|
||||
"gen-pack",
|
||||
url,
|
||||
"--name",
|
||||
name,
|
||||
"--license",
|
||||
"license",
|
||||
"--homepage",
|
||||
"homepage",
|
||||
"--description",
|
||||
"description",
|
||||
"--files",
|
||||
files_json,
|
||||
"--extensions",
|
||||
" .png .gif .jpeg "
|
||||
])
|
||||
end)
|
||||
|
||||
assert captured =~ "#{pack_json} has been updated with the pack2 pack"
|
||||
|
||||
on_exit(fn ->
|
||||
File.rm!(pack_json)
|
||||
File.rm!(files_json)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -12,26 +12,26 @@ defmodule Mix.Tasks.Pleroma.RefreshCounterCacheTest do
|
|||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"})
|
||||
CommonAPI.post(user, %{visibility: "public", status: "hey"})
|
||||
|
||||
Enum.each(0..1, fn _ ->
|
||||
CommonAPI.post(user, %{
|
||||
"visibility" => "unlisted",
|
||||
"status" => "hey"
|
||||
visibility: "unlisted",
|
||||
status: "hey"
|
||||
})
|
||||
end)
|
||||
|
||||
Enum.each(0..2, fn _ ->
|
||||
CommonAPI.post(user, %{
|
||||
"visibility" => "direct",
|
||||
"status" => "hey @#{other_user.nickname}"
|
||||
visibility: "direct",
|
||||
status: "hey @#{other_user.nickname}"
|
||||
})
|
||||
end)
|
||||
|
||||
Enum.each(0..3, fn _ ->
|
||||
CommonAPI.post(user, %{
|
||||
"visibility" => "private",
|
||||
"status" => "hey"
|
||||
visibility: "private",
|
||||
status: "hey"
|
||||
})
|
||||
end)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,21 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Mix.Tasks.Pleroma.UserTest do
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.OAuth.Authorization
|
||||
alias Pleroma.Web.OAuth.Token
|
||||
|
||||
use Pleroma.DataCase
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Pleroma.Factory
|
||||
import ExUnit.CaptureIO
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
setup_all do
|
||||
Mix.shell(Mix.Shell.Process)
|
||||
|
|
@ -87,12 +93,39 @@ defmodule Mix.Tasks.Pleroma.UserTest do
|
|||
test "user is deleted" do
|
||||
user = insert(:user)
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["rm", user.nickname])
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _ -> nil end do
|
||||
Mix.Tasks.Pleroma.User.run(["rm", user.nickname])
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ " deleted"
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ " deleted"
|
||||
assert %{deactivated: true} = User.get_by_nickname(user.nickname)
|
||||
|
||||
refute User.get_by_nickname(user.nickname)
|
||||
assert called(Pleroma.Web.Federator.publish(:_))
|
||||
end
|
||||
end
|
||||
|
||||
test "a remote user's create activity is deleted when the object has been pruned" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "uguu"})
|
||||
object = Object.normalize(post)
|
||||
Object.prune(object)
|
||||
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _ -> nil end do
|
||||
Mix.Tasks.Pleroma.User.run(["rm", user.nickname])
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert_received {:mix_shell, :info, [message]}
|
||||
assert message =~ " deleted"
|
||||
assert %{deactivated: true} = User.get_by_nickname(user.nickname)
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(:_))
|
||||
end
|
||||
|
||||
refute Activity.get_by_id(post.id)
|
||||
end
|
||||
|
||||
test "no user to delete" do
|
||||
|
|
@ -140,7 +173,7 @@ defmodule Mix.Tasks.Pleroma.UserTest do
|
|||
test "user is unsubscribed" do
|
||||
followed = insert(:user)
|
||||
user = insert(:user)
|
||||
User.follow(user, followed, "accept")
|
||||
User.follow(user, followed, :follow_accept)
|
||||
|
||||
Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname])
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: [
|
|||
ExUnit.start(exclude: [:federated | os_exclude])
|
||||
|
||||
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual)
|
||||
|
||||
Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client)
|
||||
Mox.defmock(Pleroma.GunMock, for: Pleroma.Gun)
|
||||
|
||||
{:ok, _} = Application.ensure_all_started(:ex_machina)
|
||||
|
||||
ExUnit.after_suite(fn _results ->
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ defmodule Pleroma.Uploaders.S3Test do
|
|||
name: "image-tet.jpg",
|
||||
content_type: "image/jpg",
|
||||
path: "test_folder/image-tet.jpg",
|
||||
tempfile: Path.absname("test/fixtures/image_tmp.jpg")
|
||||
tempfile: Path.absname("test/instance_static/add/shortcode.png")
|
||||
}
|
||||
|
||||
[file_upload: file_upload]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
defmodule Pleroma.UserInviteTokenTest do
|
||||
use ExUnit.Case, async: true
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.UserInviteToken
|
||||
|
||||
describe "valid_invite?/1 one time invites" do
|
||||
|
|
@ -64,7 +63,6 @@ defmodule Pleroma.UserInviteTokenTest do
|
|||
|
||||
test "expires yesterday returns false", %{invite: invite} do
|
||||
invite = %{invite | expires_at: Date.add(Date.utc_today(), -1)}
|
||||
invite = Repo.insert!(invite)
|
||||
refute UserInviteToken.valid_invite?(invite)
|
||||
end
|
||||
end
|
||||
|
|
@ -82,7 +80,6 @@ defmodule Pleroma.UserInviteTokenTest do
|
|||
|
||||
test "overdue date and less uses returns false", %{invite: invite} do
|
||||
invite = %{invite | expires_at: Date.add(Date.utc_today(), -1)}
|
||||
invite = Repo.insert!(invite)
|
||||
refute UserInviteToken.valid_invite?(invite)
|
||||
end
|
||||
|
||||
|
|
@ -93,7 +90,6 @@ defmodule Pleroma.UserInviteTokenTest do
|
|||
|
||||
test "overdue date with more uses returns false", %{invite: invite} do
|
||||
invite = %{invite | expires_at: Date.add(Date.utc_today(), -1), uses: 5}
|
||||
invite = Repo.insert!(invite)
|
||||
refute UserInviteToken.valid_invite?(invite)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ defmodule Pleroma.UserSearchTest do
|
|||
|> Map.put(:search_rank, nil)
|
||||
|> Map.put(:search_type, nil)
|
||||
|> Map.put(:last_digest_emailed_at, nil)
|
||||
|> Map.put(:multi_factor_authentication_settings, nil)
|
||||
|> Map.put(:notification_settings, nil)
|
||||
|
||||
assert user == expected
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ defmodule Pleroma.UserTest do
|
|||
use Pleroma.DataCase
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
|
|
@ -86,7 +85,7 @@ defmodule Pleroma.UserTest do
|
|||
{:ok, user: insert(:user)}
|
||||
end
|
||||
|
||||
test "outgoing_relations_ap_ids/1", %{user: user} do
|
||||
test "outgoing_relationships_ap_ids/1", %{user: user} do
|
||||
rel_types = [:block, :mute, :notification_mute, :reblog_mute, :inverse_subscription]
|
||||
|
||||
ap_ids_by_rel =
|
||||
|
|
@ -124,10 +123,10 @@ defmodule Pleroma.UserTest do
|
|||
assert ap_ids_by_rel[:inverse_subscription] ==
|
||||
Enum.sort(Enum.map(User.subscriber_users(user), & &1.ap_id))
|
||||
|
||||
outgoing_relations_ap_ids = User.outgoing_relations_ap_ids(user, rel_types)
|
||||
outgoing_relationships_ap_ids = User.outgoing_relationships_ap_ids(user, rel_types)
|
||||
|
||||
assert ap_ids_by_rel ==
|
||||
Enum.into(outgoing_relations_ap_ids, %{}, fn {k, v} -> {k, Enum.sort(v)} end)
|
||||
Enum.into(outgoing_relationships_ap_ids, %{}, fn {k, v} -> {k, Enum.sort(v)} end)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -194,7 +193,8 @@ defmodule Pleroma.UserTest do
|
|||
CommonAPI.follow(pending_follower, locked)
|
||||
CommonAPI.follow(pending_follower, locked)
|
||||
CommonAPI.follow(accepted_follower, locked)
|
||||
Pleroma.FollowingRelationship.update(accepted_follower, locked, "accept")
|
||||
|
||||
Pleroma.FollowingRelationship.update(accepted_follower, locked, :follow_accept)
|
||||
|
||||
assert [^pending_follower] = User.get_follow_requests(locked)
|
||||
end
|
||||
|
|
@ -319,7 +319,7 @@ defmodule Pleroma.UserTest do
|
|||
following_address: "http://localhost:4001/users/fuser2/following"
|
||||
})
|
||||
|
||||
{:ok, user} = User.follow(user, followed, "accept")
|
||||
{:ok, user} = User.follow(user, followed, :follow_accept)
|
||||
|
||||
{:ok, user, _activity} = User.unfollow(user, followed)
|
||||
|
||||
|
|
@ -332,7 +332,7 @@ defmodule Pleroma.UserTest do
|
|||
followed = insert(:user)
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, user} = User.follow(user, followed, "accept")
|
||||
{:ok, user} = User.follow(user, followed, :follow_accept)
|
||||
|
||||
assert User.following(user) == [user.follower_address, followed.follower_address]
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ defmodule Pleroma.UserTest do
|
|||
test "test if a user is following another user" do
|
||||
followed = insert(:user)
|
||||
user = insert(:user)
|
||||
User.follow(user, followed, "accept")
|
||||
User.follow(user, followed, :follow_accept)
|
||||
|
||||
assert User.following?(user, followed)
|
||||
refute User.following?(followed, user)
|
||||
|
|
@ -581,7 +581,7 @@ defmodule Pleroma.UserTest do
|
|||
|
||||
{:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
|
||||
|
||||
assert user.source_data["endpoints"]
|
||||
assert user.inbox
|
||||
|
||||
refute user.last_refreshed_at == orig_user.last_refreshed_at
|
||||
end
|
||||
|
|
@ -609,7 +609,7 @@ defmodule Pleroma.UserTest do
|
|||
) <> "/followers"
|
||||
end
|
||||
|
||||
describe "remote user creation changeset" do
|
||||
describe "remote user changeset" do
|
||||
@valid_remote %{
|
||||
bio: "hello",
|
||||
name: "Someone",
|
||||
|
|
@ -621,28 +621,28 @@ defmodule Pleroma.UserTest do
|
|||
setup do: clear_config([:instance, :user_name_length])
|
||||
|
||||
test "it confirms validity" do
|
||||
cs = User.remote_user_creation(@valid_remote)
|
||||
cs = User.remote_user_changeset(@valid_remote)
|
||||
assert cs.valid?
|
||||
end
|
||||
|
||||
test "it sets the follower_adress" do
|
||||
cs = User.remote_user_creation(@valid_remote)
|
||||
cs = User.remote_user_changeset(@valid_remote)
|
||||
# remote users get a fake local follower address
|
||||
assert cs.changes.follower_address ==
|
||||
User.ap_followers(%User{nickname: @valid_remote[:nickname]})
|
||||
end
|
||||
|
||||
test "it enforces the fqn format for nicknames" do
|
||||
cs = User.remote_user_creation(%{@valid_remote | nickname: "bla"})
|
||||
cs = User.remote_user_changeset(%{@valid_remote | nickname: "bla"})
|
||||
assert Ecto.Changeset.get_field(cs, :local) == false
|
||||
assert cs.changes.avatar
|
||||
refute cs.valid?
|
||||
end
|
||||
|
||||
test "it has required fields" do
|
||||
[:name, :ap_id]
|
||||
[:ap_id]
|
||||
|> Enum.each(fn field ->
|
||||
cs = User.remote_user_creation(Map.delete(@valid_remote, field))
|
||||
cs = User.remote_user_changeset(Map.delete(@valid_remote, field))
|
||||
refute cs.valid?
|
||||
end)
|
||||
end
|
||||
|
|
@ -755,8 +755,8 @@ defmodule Pleroma.UserTest do
|
|||
]
|
||||
|
||||
{:ok, job} = User.follow_import(user1, identifiers)
|
||||
result = ObanHelpers.perform(job)
|
||||
|
||||
assert {:ok, result} = ObanHelpers.perform(job)
|
||||
assert is_list(result)
|
||||
assert result == [user2, user3]
|
||||
end
|
||||
|
|
@ -978,14 +978,26 @@ defmodule Pleroma.UserTest do
|
|||
]
|
||||
|
||||
{:ok, job} = User.blocks_import(user1, identifiers)
|
||||
result = ObanHelpers.perform(job)
|
||||
|
||||
assert {:ok, result} = ObanHelpers.perform(job)
|
||||
assert is_list(result)
|
||||
assert result == [user2, user3]
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_recipients_from_activity" do
|
||||
test "works for announces" do
|
||||
actor = insert(:user)
|
||||
user = insert(:user, local: true)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(actor, %{status: "hello"})
|
||||
{:ok, announce, _} = CommonAPI.repeat(activity.id, user)
|
||||
|
||||
recipients = User.get_recipients_from_activity(announce)
|
||||
|
||||
assert user in recipients
|
||||
end
|
||||
|
||||
test "get recipients" do
|
||||
actor = insert(:user)
|
||||
user = insert(:user, local: true)
|
||||
|
|
@ -995,7 +1007,7 @@ defmodule Pleroma.UserTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(actor, %{
|
||||
"status" => "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
|
||||
status: "hey @#{addressed.nickname} @#{addressed_remote.nickname}"
|
||||
})
|
||||
|
||||
assert Enum.map([actor, addressed], & &1.ap_id) --
|
||||
|
|
@ -1017,7 +1029,7 @@ defmodule Pleroma.UserTest do
|
|||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(actor, %{
|
||||
"status" => "hey @#{addressed.nickname}"
|
||||
status: "hey @#{addressed.nickname}"
|
||||
})
|
||||
|
||||
assert Enum.map([actor, addressed], & &1.ap_id) --
|
||||
|
|
@ -1078,7 +1090,7 @@ defmodule Pleroma.UserTest do
|
|||
|
||||
{:ok, user2} = User.follow(user2, user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{user2.nickname}"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey @#{user2.nickname}"})
|
||||
|
||||
activity = Repo.preload(activity, :bookmark)
|
||||
|
||||
|
|
@ -1114,24 +1126,15 @@ defmodule Pleroma.UserTest do
|
|||
setup do: clear_config([:instance, :federating])
|
||||
|
||||
test ".delete_user_activities deletes all create activities", %{user: user} do
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "2hu"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "2hu"})
|
||||
|
||||
User.delete_user_activities(user)
|
||||
|
||||
# TODO: Remove favorites, repeats, delete activities.
|
||||
# TODO: Test removal favorites, repeats, delete activities.
|
||||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
|
||||
test "it deletes deactivated user" do
|
||||
{:ok, user} = insert(:user, deactivated: true) |> User.set_cache()
|
||||
|
||||
{:ok, job} = User.delete(user)
|
||||
{:ok, _user} = ObanHelpers.perform(job)
|
||||
|
||||
refute User.get_by_id(user.id)
|
||||
end
|
||||
|
||||
test "it deletes a user, all follow relationships and all activities", %{user: user} do
|
||||
test "it deactivates a user, all follow relationships and all activities", %{user: user} do
|
||||
follower = insert(:user)
|
||||
{:ok, follower} = User.follow(follower, user)
|
||||
|
||||
|
|
@ -1141,8 +1144,8 @@ defmodule Pleroma.UserTest do
|
|||
object_two = insert(:note, user: follower)
|
||||
activity_two = insert(:note_activity, user: follower, note: object_two)
|
||||
|
||||
{:ok, like, _} = CommonAPI.favorite(activity_two.id, user)
|
||||
{:ok, like_two, _} = CommonAPI.favorite(activity.id, follower)
|
||||
{:ok, like} = CommonAPI.favorite(user, activity_two.id)
|
||||
{:ok, like_two} = CommonAPI.favorite(follower, activity.id)
|
||||
{:ok, repeat, _} = CommonAPI.repeat(activity_two.id, user)
|
||||
|
||||
{:ok, job} = User.delete(user)
|
||||
|
|
@ -1151,8 +1154,7 @@ defmodule Pleroma.UserTest do
|
|||
follower = User.get_cached_by_id(follower.id)
|
||||
|
||||
refute User.following?(follower, user)
|
||||
refute User.get_by_id(user.id)
|
||||
assert {:ok, nil} == Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
|
||||
assert %{deactivated: true} = User.get_by_id(user.id)
|
||||
|
||||
user_activities =
|
||||
user.ap_id
|
||||
|
|
@ -1167,89 +1169,12 @@ defmodule Pleroma.UserTest do
|
|||
refute Activity.get_by_id(like_two.id)
|
||||
refute Activity.get_by_id(repeat.id)
|
||||
end
|
||||
|
||||
test_with_mock "it sends out User Delete activity",
|
||||
%{user: user},
|
||||
Pleroma.Web.ActivityPub.Publisher,
|
||||
[:passthrough],
|
||||
[] do
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
|
||||
{:ok, follower} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
|
||||
{:ok, _} = User.follow(follower, user)
|
||||
|
||||
{:ok, job} = User.delete(user)
|
||||
{:ok, _user} = ObanHelpers.perform(job)
|
||||
|
||||
assert ObanHelpers.member?(
|
||||
%{
|
||||
"op" => "publish_one",
|
||||
"params" => %{
|
||||
"inbox" => "http://mastodon.example.org/inbox",
|
||||
"id" => "pleroma:fakeid"
|
||||
}
|
||||
},
|
||||
all_enqueued(worker: Pleroma.Workers.PublisherWorker)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
test "get_public_key_for_ap_id fetches a user that's not in the db" do
|
||||
assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
||||
end
|
||||
|
||||
describe "insert or update a user from given data" do
|
||||
test "with normal data" do
|
||||
user = insert(:user, %{nickname: "nick@name.de"})
|
||||
data = %{ap_id: user.ap_id <> "xxx", name: user.name, nickname: user.nickname}
|
||||
|
||||
assert {:ok, %User{}} = User.insert_or_update_user(data)
|
||||
end
|
||||
|
||||
test "with overly long fields" do
|
||||
current_max_length = Pleroma.Config.get([:instance, :account_field_value_length], 255)
|
||||
user = insert(:user, nickname: "nickname@supergood.domain")
|
||||
|
||||
data = %{
|
||||
ap_id: user.ap_id,
|
||||
name: user.name,
|
||||
nickname: user.nickname,
|
||||
fields: [
|
||||
%{"name" => "myfield", "value" => String.duplicate("h", current_max_length + 1)}
|
||||
]
|
||||
}
|
||||
|
||||
assert {:ok, %User{}} = User.insert_or_update_user(data)
|
||||
end
|
||||
|
||||
test "with an overly long bio" do
|
||||
current_max_length = Pleroma.Config.get([:instance, :user_bio_length], 5000)
|
||||
user = insert(:user, nickname: "nickname@supergood.domain")
|
||||
|
||||
data = %{
|
||||
ap_id: user.ap_id,
|
||||
name: user.name,
|
||||
nickname: user.nickname,
|
||||
bio: String.duplicate("h", current_max_length + 1)
|
||||
}
|
||||
|
||||
assert {:ok, %User{}} = User.insert_or_update_user(data)
|
||||
end
|
||||
|
||||
test "with an overly long display name" do
|
||||
current_max_length = Pleroma.Config.get([:instance, :user_name_length], 100)
|
||||
user = insert(:user, nickname: "nickname@supergood.domain")
|
||||
|
||||
data = %{
|
||||
ap_id: user.ap_id,
|
||||
name: String.duplicate("h", current_max_length + 1),
|
||||
nickname: user.nickname
|
||||
}
|
||||
|
||||
assert {:ok, %User{}} = User.insert_or_update_user(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "per-user rich-text filtering" do
|
||||
test "html_filter_policy returns default policies, when rich-text is enabled" do
|
||||
user = insert(:user)
|
||||
|
|
@ -1404,7 +1329,7 @@ defmodule Pleroma.UserTest do
|
|||
bio = "A.k.a. @nick@domain.com"
|
||||
|
||||
expected_text =
|
||||
~s(A.k.a. <span class="h-card"><a data-user="#{remote_user.id}" class="u-url mention" href="#{
|
||||
~s(A.k.a. <span class="h-card"><a class="u-url mention" data-user="#{remote_user.id}" href="#{
|
||||
remote_user.ap_id
|
||||
}" rel="ugc">@<span>nick@domain.com</span></a></span>)
|
||||
|
||||
|
|
@ -1486,7 +1411,7 @@ defmodule Pleroma.UserTest do
|
|||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "hey @#{to.nickname}"
|
||||
status: "hey @#{to.nickname}"
|
||||
})
|
||||
end)
|
||||
|
||||
|
|
@ -1518,12 +1443,12 @@ defmodule Pleroma.UserTest do
|
|||
Enum.each(recipients, fn to ->
|
||||
{:ok, _} =
|
||||
CommonAPI.post(sender, %{
|
||||
"status" => "hey @#{to.nickname}"
|
||||
status: "hey @#{to.nickname}"
|
||||
})
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(sender, %{
|
||||
"status" => "hey again @#{to.nickname}"
|
||||
status: "hey again @#{to.nickname}"
|
||||
})
|
||||
end)
|
||||
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
|
||||
test "cached purged after activity deletion", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "cofe"})
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "cofe"})
|
||||
|
||||
uuid = String.split(activity.data["id"], "/") |> List.last()
|
||||
|
||||
|
|
@ -765,51 +765,110 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "POST /users/:nickname/outbox" do
|
||||
test "it rejects posts from other users / unauuthenticated users", %{conn: conn} do
|
||||
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
|
||||
describe "POST /users/:nickname/outbox (C2S)" do
|
||||
setup do
|
||||
[
|
||||
activity: %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Create",
|
||||
"object" => %{"type" => "Note", "content" => "AP C2S test"},
|
||||
"to" => "https://www.w3.org/ns/activitystreams#Public",
|
||||
"cc" => []
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "it rejects posts from other users / unauthenticated users", %{
|
||||
conn: conn,
|
||||
activity: activity
|
||||
} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
conn = put_req_header(conn, "content-type", "application/activity+json")
|
||||
|
||||
conn
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
|> post("/users/#{user.nickname}/outbox", activity)
|
||||
|> json_response(403)
|
||||
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
|> post("/users/#{user.nickname}/outbox", activity)
|
||||
|> json_response(403)
|
||||
end
|
||||
|
||||
test "it inserts an incoming create activity into the database", %{conn: conn} do
|
||||
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
|
||||
test "it inserts an incoming create activity into the database", %{
|
||||
conn: conn,
|
||||
activity: activity
|
||||
} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
|
||||
result = json_response(conn, 201)
|
||||
|> post("/users/#{user.nickname}/outbox", activity)
|
||||
|> json_response(201)
|
||||
|
||||
assert Activity.get_by_ap_id(result["id"])
|
||||
assert result["object"]
|
||||
assert %Object{data: object} = Object.normalize(result["object"])
|
||||
assert object["content"] == activity["object"]["content"]
|
||||
end
|
||||
|
||||
test "it rejects an incoming activity with bogus type", %{conn: conn} do
|
||||
data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!()
|
||||
test "it rejects anything beyond 'Note' creations", %{conn: conn, activity: activity} do
|
||||
user = insert(:user)
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("type", "BadType")
|
||||
activity =
|
||||
activity
|
||||
|> put_in(["object", "type"], "Benis")
|
||||
|
||||
_result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{user.nickname}/outbox", activity)
|
||||
|> json_response(400)
|
||||
end
|
||||
|
||||
test "it inserts an incoming sensitive activity into the database", %{
|
||||
conn: conn,
|
||||
activity: activity
|
||||
} do
|
||||
user = insert(:user)
|
||||
conn = assign(conn, :user, user)
|
||||
object = Map.put(activity["object"], "sensitive", true)
|
||||
activity = Map.put(activity, "object", object)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{user.nickname}/outbox", activity)
|
||||
|> json_response(201)
|
||||
|
||||
assert Activity.get_by_ap_id(response["id"])
|
||||
assert response["object"]
|
||||
assert %Object{data: response_object} = Object.normalize(response["object"])
|
||||
assert response_object["sensitive"] == true
|
||||
assert response_object["content"] == activity["object"]["content"]
|
||||
|
||||
representation =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get(response["id"])
|
||||
|> json_response(200)
|
||||
|
||||
assert representation["object"]["sensitive"] == true
|
||||
end
|
||||
|
||||
test "it rejects an incoming activity with bogus type", %{conn: conn, activity: activity} do
|
||||
user = insert(:user)
|
||||
activity = Map.put(activity, "type", "BadType")
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{user.nickname}/outbox", data)
|
||||
|> post("/users/#{user.nickname}/outbox", activity)
|
||||
|
||||
assert json_response(conn, 400)
|
||||
end
|
||||
|
|
@ -1019,12 +1078,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert result["totalItems"] == 15
|
||||
end
|
||||
|
||||
test "returns 403 if requester is not logged in", %{conn: conn} do
|
||||
test "does not require authentication", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/followers")
|
||||
|> json_response(403)
|
||||
|> json_response(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1116,12 +1175,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert result["totalItems"] == 15
|
||||
end
|
||||
|
||||
test "returns 403 if requester is not logged in", %{conn: conn} do
|
||||
test "does not require authentication", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/following")
|
||||
|> json_response(403)
|
||||
|> json_response(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1239,16 +1298,56 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
conn =
|
||||
object =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
|
||||
|> json_response(:created)
|
||||
|
||||
assert object = json_response(conn, :created)
|
||||
assert object["name"] == desc
|
||||
assert object["type"] == "Document"
|
||||
assert object["actor"] == user.ap_id
|
||||
assert [%{"href" => object_href, "mediaType" => object_mediatype}] = object["url"]
|
||||
assert is_binary(object_href)
|
||||
assert object_mediatype == "image/jpeg"
|
||||
|
||||
activity_request = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "AP C2S test, attachment",
|
||||
"attachment" => [object]
|
||||
},
|
||||
"to" => "https://www.w3.org/ns/activitystreams#Public",
|
||||
"cc" => []
|
||||
}
|
||||
|
||||
activity_response =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/users/#{user.nickname}/outbox", activity_request)
|
||||
|> json_response(:created)
|
||||
|
||||
assert activity_response["id"]
|
||||
assert activity_response["object"]
|
||||
assert activity_response["actor"] == user.ap_id
|
||||
|
||||
assert %Object{data: %{"attachment" => [attachment]}} =
|
||||
Object.normalize(activity_response["object"])
|
||||
|
||||
assert attachment["type"] == "Document"
|
||||
assert attachment["name"] == desc
|
||||
|
||||
assert [
|
||||
%{
|
||||
"href" => ^object_href,
|
||||
"type" => "Link",
|
||||
"mediaType" => ^object_mediatype
|
||||
}
|
||||
] = attachment["url"]
|
||||
|
||||
# Fails if unauthenticated
|
||||
conn
|
||||
|> post("/api/ap/upload_media", %{"file" => image, "description" => desc})
|
||||
|> json_response(403)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicyTest do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
||||
|
|
@ -110,6 +110,15 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
end
|
||||
|
||||
describe "with unknown actors" do
|
||||
setup do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: :get, url: "http://invalid.actor"} ->
|
||||
%Tesla.Env{status: 500, body: ""}
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "it rejects posts without links" do
|
||||
message =
|
||||
@linkless_message
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
||||
|
|
@ -20,26 +20,38 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
|||
:ok
|
||||
end
|
||||
|
||||
defp get_old_message do
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
end
|
||||
|
||||
defp get_new_message do
|
||||
old_message = get_old_message()
|
||||
|
||||
new_object =
|
||||
old_message
|
||||
|> Map.get("object")
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
old_message
|
||||
|> Map.put("object", new_object)
|
||||
end
|
||||
|
||||
describe "with reject action" do
|
||||
test "it rejects an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:reject])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
data = get_old_message()
|
||||
|
||||
{:reject, _} = ObjectAgePolicy.filter(data)
|
||||
assert match?({:reject, _}, ObjectAgePolicy.filter(data))
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:reject])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
data = get_new_message()
|
||||
|
||||
{:ok, _} = ObjectAgePolicy.filter(data)
|
||||
assert match?({:ok, _}, ObjectAgePolicy.filter(data))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -47,9 +59,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
|||
test "it delists an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:delist])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
data = get_old_message()
|
||||
|
||||
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
|
|
@ -61,14 +71,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
|||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:delist])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
data = get_new_message()
|
||||
|
||||
{:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, ^data} = ObjectAgePolicy.filter(data)
|
||||
assert match?({:ok, ^data}, ObjectAgePolicy.filter(data))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -76,9 +83,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
|||
test "it strips followers collections from an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:strip_followers])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
data = get_old_message()
|
||||
|
||||
{:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
|
|
@ -91,14 +96,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
|||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:strip_followers])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
data = get_new_message()
|
||||
|
||||
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, ^data} = ObjectAgePolicy.filter(data)
|
||||
assert match?({:ok, ^data}, ObjectAgePolicy.filter(data))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.RejectNonPublicTest do
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
||||
|
|
@ -17,7 +17,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
reject: [],
|
||||
accept: [],
|
||||
avatar_removal: [],
|
||||
banner_removal: []
|
||||
banner_removal: [],
|
||||
reject_deletes: []
|
||||
)
|
||||
|
||||
describe "when :media_removal" do
|
||||
|
|
@ -382,6 +383,66 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "when :reject_deletes is empty" do
|
||||
setup do: Config.put([:mrf_simple, :reject_deletes], [])
|
||||
|
||||
test "it accepts deletions even from rejected servers" do
|
||||
Config.put([:mrf_simple, :reject], ["remote.instance"])
|
||||
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
|
||||
end
|
||||
|
||||
test "it accepts deletions even from non-whitelisted servers" do
|
||||
Config.put([:mrf_simple, :accept], ["non.matching.remote"])
|
||||
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
|
||||
end
|
||||
end
|
||||
|
||||
describe "when :reject_deletes is not empty but it doesn't have a matching host" do
|
||||
setup do: Config.put([:mrf_simple, :reject_deletes], ["non.matching.remote"])
|
||||
|
||||
test "it accepts deletions even from rejected servers" do
|
||||
Config.put([:mrf_simple, :reject], ["remote.instance"])
|
||||
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
|
||||
end
|
||||
|
||||
test "it accepts deletions even from non-whitelisted servers" do
|
||||
Config.put([:mrf_simple, :accept], ["non.matching.remote"])
|
||||
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message}
|
||||
end
|
||||
end
|
||||
|
||||
describe "when :reject_deletes has a matching host" do
|
||||
setup do: Config.put([:mrf_simple, :reject_deletes], ["remote.instance"])
|
||||
|
||||
test "it rejects the deletion" do
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
|
||||
end
|
||||
end
|
||||
|
||||
describe "when :reject_deletes match with wildcard domain" do
|
||||
setup do: Config.put([:mrf_simple, :reject_deletes], ["*.remote.instance"])
|
||||
|
||||
test "it rejects the deletion" do
|
||||
deletion_message = build_remote_deletion_message()
|
||||
|
||||
assert SimplePolicy.filter(deletion_message) == {:reject, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp build_local_message do
|
||||
%{
|
||||
"actor" => "#{Pleroma.Web.base_url()}/users/alice",
|
||||
|
|
@ -408,4 +469,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
|
|||
"type" => "Person"
|
||||
}
|
||||
end
|
||||
|
||||
defp build_remote_deletion_message do
|
||||
%{
|
||||
"type" => "Delete",
|
||||
"actor" => "https://remote.instance/users/bob"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
283
test/web/activity_pub/object_validator_test.exs
Normal file
283
test/web/activity_pub/object_validator_test.exs
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "EmojiReacts" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
object = Pleroma.Object.get_by_ap_id(post_activity.data["object"])
|
||||
|
||||
{:ok, valid_emoji_react, []} = Builder.emoji_react(user, object, "👌")
|
||||
|
||||
%{user: user, post_activity: post_activity, valid_emoji_react: valid_emoji_react}
|
||||
end
|
||||
|
||||
test "it validates a valid EmojiReact", %{valid_emoji_react: valid_emoji_react} do
|
||||
assert {:ok, _, _} = ObjectValidator.validate(valid_emoji_react, [])
|
||||
end
|
||||
|
||||
test "it is not valid without a 'content' field", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_content =
|
||||
valid_emoji_react
|
||||
|> Map.delete("content")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", "x")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
|
||||
assert {:content, {"must be a single character emoji", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
|
||||
describe "Undos" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
{:ok, like} = CommonAPI.favorite(user, post_activity.id)
|
||||
{:ok, valid_like_undo, []} = Builder.undo(user, like)
|
||||
|
||||
%{user: user, like: like, valid_like_undo: valid_like_undo}
|
||||
end
|
||||
|
||||
test "it validates a basic like undo", %{valid_like_undo: valid_like_undo} do
|
||||
assert {:ok, _, _} = ObjectValidator.validate(valid_like_undo, [])
|
||||
end
|
||||
|
||||
test "it does not validate if the actor of the undo is not the actor of the object", %{
|
||||
valid_like_undo: valid_like_undo
|
||||
} do
|
||||
other_user = insert(:user, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
bad_actor =
|
||||
valid_like_undo
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(bad_actor, [])
|
||||
|
||||
assert {:actor, {"not the same as object actor", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it does not validate if the object is missing", %{valid_like_undo: valid_like_undo} do
|
||||
missing_object =
|
||||
valid_like_undo
|
||||
|> Map.put("object", "https://gensokyo.2hu/objects/1")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(missing_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
assert length(cng.errors) == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "deletes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "cancel me daddy"})
|
||||
|
||||
{:ok, valid_post_delete, _} = Builder.delete(user, post_activity.data["object"])
|
||||
{:ok, valid_user_delete, _} = Builder.delete(user, user.ap_id)
|
||||
|
||||
%{user: user, valid_post_delete: valid_post_delete, valid_user_delete: valid_user_delete}
|
||||
end
|
||||
|
||||
test "it is valid for a post deletion", %{valid_post_delete: valid_post_delete} do
|
||||
{:ok, valid_post_delete, _} = ObjectValidator.validate(valid_post_delete, [])
|
||||
|
||||
assert valid_post_delete["deleted_activity_id"]
|
||||
end
|
||||
|
||||
test "it is invalid if the object isn't in a list of certain types", %{
|
||||
valid_post_delete: valid_post_delete
|
||||
} do
|
||||
object = Object.get_by_ap_id(valid_post_delete["object"])
|
||||
|
||||
data =
|
||||
object.data
|
||||
|> Map.put("type", "Like")
|
||||
|
||||
{:ok, _object} =
|
||||
object
|
||||
|> Ecto.Changeset.change(%{data: data})
|
||||
|> Object.update_and_set_cache()
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(valid_post_delete, [])
|
||||
assert {:object, {"object not in allowed types", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is valid for a user deletion", %{valid_user_delete: valid_user_delete} do
|
||||
assert match?({:ok, _, _}, ObjectValidator.validate(valid_user_delete, []))
|
||||
end
|
||||
|
||||
test "it's invalid if the id is missing", %{valid_post_delete: valid_post_delete} do
|
||||
no_id =
|
||||
valid_post_delete
|
||||
|> Map.delete("id")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(no_id, [])
|
||||
|
||||
assert {:id, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's invalid if the object doesn't exist", %{valid_post_delete: valid_post_delete} do
|
||||
missing_object =
|
||||
valid_post_delete
|
||||
|> Map.put("object", "http://does.not/exist")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(missing_object, [])
|
||||
|
||||
assert {:object, {"can't find object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's invalid if the actor of the object and the actor of delete are from different domains",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
valid_user = insert(:user)
|
||||
|
||||
valid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", valid_user.ap_id)
|
||||
|
||||
assert match?({:ok, _, _}, ObjectValidator.validate(valid_other_actor, []))
|
||||
|
||||
invalid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(invalid_other_actor, [])
|
||||
|
||||
assert {:actor, {"is not allowed to delete object", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it's valid if the actor of the object is a local superuser",
|
||||
%{valid_post_delete: valid_post_delete} do
|
||||
user =
|
||||
insert(:user, local: true, is_moderator: true, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
valid_other_actor =
|
||||
valid_post_delete
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:ok, _, meta} = ObjectValidator.validate(valid_other_actor, [])
|
||||
assert meta[:do_not_federate]
|
||||
end
|
||||
end
|
||||
|
||||
describe "likes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
|
||||
|
||||
valid_like = %{
|
||||
"to" => [user.ap_id],
|
||||
"cc" => [],
|
||||
"type" => "Like",
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"object" => post_activity.data["object"],
|
||||
"actor" => user.ap_id,
|
||||
"context" => "a context"
|
||||
}
|
||||
|
||||
%{valid_like: valid_like, user: user, post_activity: post_activity}
|
||||
end
|
||||
|
||||
test "returns ok when called in the ObjectValidator", %{valid_like: valid_like} do
|
||||
{:ok, object, _meta} = ObjectValidator.validate(valid_like, [])
|
||||
|
||||
assert "id" in Map.keys(object)
|
||||
end
|
||||
|
||||
test "is valid for a valid object", %{valid_like: valid_like} do
|
||||
assert LikeValidator.cast_and_validate(valid_like).valid?
|
||||
end
|
||||
|
||||
test "sets the 'to' field to the object actor if no recipients are given", %{
|
||||
valid_like: valid_like,
|
||||
user: user
|
||||
} do
|
||||
without_recipients =
|
||||
valid_like
|
||||
|> Map.delete("to")
|
||||
|
||||
{:ok, object, _meta} = ObjectValidator.validate(without_recipients, [])
|
||||
|
||||
assert object["to"] == [user.ap_id]
|
||||
end
|
||||
|
||||
test "sets the context field to the context of the object if no context is given", %{
|
||||
valid_like: valid_like,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
without_context =
|
||||
valid_like
|
||||
|> Map.delete("context")
|
||||
|
||||
{:ok, object, _meta} = ObjectValidator.validate(without_context, [])
|
||||
|
||||
assert object["context"] == post_activity.data["context"]
|
||||
end
|
||||
|
||||
test "it errors when the actor is missing or not known", %{valid_like: valid_like} do
|
||||
without_actor = Map.delete(valid_like, "actor")
|
||||
|
||||
refute LikeValidator.cast_and_validate(without_actor).valid?
|
||||
|
||||
with_invalid_actor = Map.put(valid_like, "actor", "invalidactor")
|
||||
|
||||
refute LikeValidator.cast_and_validate(with_invalid_actor).valid?
|
||||
end
|
||||
|
||||
test "it errors when the object is missing or not known", %{valid_like: valid_like} do
|
||||
without_object = Map.delete(valid_like, "object")
|
||||
|
||||
refute LikeValidator.cast_and_validate(without_object).valid?
|
||||
|
||||
with_invalid_object = Map.put(valid_like, "object", "invalidobject")
|
||||
|
||||
refute LikeValidator.cast_and_validate(with_invalid_object).valid?
|
||||
end
|
||||
|
||||
test "it errors when the actor has already like the object", %{
|
||||
valid_like: valid_like,
|
||||
user: user,
|
||||
post_activity: post_activity
|
||||
} do
|
||||
_like = CommonAPI.favorite(user, post_activity.id)
|
||||
|
||||
refute LikeValidator.cast_and_validate(valid_like).valid?
|
||||
end
|
||||
|
||||
test "it works when actor or object are wrapped in maps", %{valid_like: valid_like} do
|
||||
wrapped_like =
|
||||
valid_like
|
||||
|> Map.put("actor", %{"id" => valid_like["actor"]})
|
||||
|> Map.put("object", %{"id" => valid_like["object"]})
|
||||
|
||||
validated = LikeValidator.cast_and_validate(wrapped_like)
|
||||
|
||||
assert validated.valid?
|
||||
|
||||
assert {:actor, valid_like["actor"]} in validated.changes
|
||||
assert {:object, valid_like["object"]} in validated.changes
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidatorTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "Notes" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
note = %{
|
||||
"id" => Utils.generate_activity_id(),
|
||||
"type" => "Note",
|
||||
"actor" => user.ap_id,
|
||||
"to" => [user.follower_address],
|
||||
"cc" => [],
|
||||
"content" => "Hellow this is content.",
|
||||
"context" => "xxx",
|
||||
"summary" => "a post"
|
||||
}
|
||||
|
||||
%{user: user, note: note}
|
||||
end
|
||||
|
||||
test "a basic note validates", %{note: note} do
|
||||
%{valid?: true} = NoteValidator.cast_and_validate(note)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTimeTest do
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTime
|
||||
use Pleroma.DataCase
|
||||
|
||||
test "it validates an xsd:Datetime" do
|
||||
valid_strings = [
|
||||
"2004-04-12T13:20:00",
|
||||
"2004-04-12T13:20:15.5",
|
||||
"2004-04-12T13:20:00-05:00",
|
||||
"2004-04-12T13:20:00Z"
|
||||
]
|
||||
|
||||
invalid_strings = [
|
||||
"2004-04-12T13:00",
|
||||
"2004-04-1213:20:00",
|
||||
"99-04-12T13:00",
|
||||
"2004-04-12"
|
||||
]
|
||||
|
||||
assert {:ok, "2004-04-01T12:00:00Z"} == DateTime.cast("2004-04-01T12:00:00Z")
|
||||
|
||||
Enum.each(valid_strings, fn date_time ->
|
||||
result = DateTime.cast(date_time)
|
||||
assert {:ok, _} = result
|
||||
end)
|
||||
|
||||
Enum.each(invalid_strings, fn date_time ->
|
||||
result = DateTime.cast(date_time)
|
||||
assert :error == result
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
defmodule Pleroma.Web.ObjectValidators.Types.ObjectIDTest do
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.ObjectID
|
||||
use Pleroma.DataCase
|
||||
|
||||
@uris [
|
||||
"http://lain.com/users/lain",
|
||||
"http://lain.com",
|
||||
"https://lain.com/object/1"
|
||||
]
|
||||
|
||||
@non_uris [
|
||||
"https://",
|
||||
"rin",
|
||||
1,
|
||||
:x,
|
||||
%{"1" => 2}
|
||||
]
|
||||
|
||||
test "it accepts http uris" do
|
||||
Enum.each(@uris, fn uri ->
|
||||
assert {:ok, uri} == ObjectID.cast(uri)
|
||||
end)
|
||||
end
|
||||
|
||||
test "it accepts an object with a nested uri id" do
|
||||
Enum.each(@uris, fn uri ->
|
||||
assert {:ok, uri} == ObjectID.cast(%{"id" => uri})
|
||||
end)
|
||||
end
|
||||
|
||||
test "it rejects non-uri strings" do
|
||||
Enum.each(@non_uris, fn non_uri ->
|
||||
assert :error == ObjectID.cast(non_uri)
|
||||
assert :error == ObjectID.cast(%{"id" => non_uri})
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
defmodule Pleroma.Web.ObjectValidators.Types.RecipientsTest do
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.Recipients
|
||||
use Pleroma.DataCase
|
||||
|
||||
test "it asserts that all elements of the list are object ids" do
|
||||
list = ["https://lain.com/users/lain", "invalid"]
|
||||
|
||||
assert :error == Recipients.cast(list)
|
||||
end
|
||||
|
||||
test "it works with a list" do
|
||||
list = ["https://lain.com/users/lain"]
|
||||
assert {:ok, list} == Recipients.cast(list)
|
||||
end
|
||||
|
||||
test "it works with a list with whole objects" do
|
||||
list = ["https://lain.com/users/lain", %{"id" => "https://gensokyo.2hu/users/raymoo"}]
|
||||
resulting_list = ["https://gensokyo.2hu/users/raymoo", "https://lain.com/users/lain"]
|
||||
assert {:ok, resulting_list} == Recipients.cast(list)
|
||||
end
|
||||
|
||||
test "it turns a single string into a list" do
|
||||
recipient = "https://lain.com/users/lain"
|
||||
|
||||
assert {:ok, [recipient]} == Recipients.cast(recipient)
|
||||
end
|
||||
end
|
||||
87
test/web/activity_pub/pipeline_test.exs
Normal file
87
test/web/activity_pub/pipeline_test.exs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.PipelineTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "common_pipeline/2" do
|
||||
test "it goes through validation, filtering, persisting, side effects and federation for local activities" do
|
||||
activity = insert(:note_activity)
|
||||
meta = [local: true]
|
||||
|
||||
with_mocks([
|
||||
{Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
|
||||
{
|
||||
Pleroma.Web.ActivityPub.MRF,
|
||||
[],
|
||||
[filter: fn o -> {:ok, o} end]
|
||||
},
|
||||
{
|
||||
Pleroma.Web.ActivityPub.ActivityPub,
|
||||
[],
|
||||
[persist: fn o, m -> {:ok, o, m} end]
|
||||
},
|
||||
{
|
||||
Pleroma.Web.ActivityPub.SideEffects,
|
||||
[],
|
||||
[handle: fn o, m -> {:ok, o, m} end]
|
||||
},
|
||||
{
|
||||
Pleroma.Web.Federator,
|
||||
[],
|
||||
[publish: fn _o -> :ok end]
|
||||
}
|
||||
]) do
|
||||
assert {:ok, ^activity, ^meta} =
|
||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||
|
||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||
assert_called(Pleroma.Web.Federator.publish(activity))
|
||||
end
|
||||
end
|
||||
|
||||
test "it goes through validation, filtering, persisting, side effects without federation for remote activities" do
|
||||
activity = insert(:note_activity)
|
||||
meta = [local: false]
|
||||
|
||||
with_mocks([
|
||||
{Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
|
||||
{
|
||||
Pleroma.Web.ActivityPub.MRF,
|
||||
[],
|
||||
[filter: fn o -> {:ok, o} end]
|
||||
},
|
||||
{
|
||||
Pleroma.Web.ActivityPub.ActivityPub,
|
||||
[],
|
||||
[persist: fn o, m -> {:ok, o, m} end]
|
||||
},
|
||||
{
|
||||
Pleroma.Web.ActivityPub.SideEffects,
|
||||
[],
|
||||
[handle: fn o, m -> {:ok, o, m} end]
|
||||
},
|
||||
{
|
||||
Pleroma.Web.Federator,
|
||||
[],
|
||||
[]
|
||||
}
|
||||
]) do
|
||||
assert {:ok, ^activity, ^meta} =
|
||||
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
|
||||
|
||||
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
|
||||
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
|
||||
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
|
||||
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -48,10 +48,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
|
||||
describe "determine_inbox/2" do
|
||||
test "it returns sharedInbox for messages involving as:Public in to" do
|
||||
user =
|
||||
insert(:user, %{
|
||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
||||
})
|
||||
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||
|
||||
activity = %Activity{
|
||||
data: %{"to" => [@as_public], "cc" => [user.follower_address]}
|
||||
|
|
@ -61,10 +58,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
end
|
||||
|
||||
test "it returns sharedInbox for messages involving as:Public in cc" do
|
||||
user =
|
||||
insert(:user, %{
|
||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
||||
})
|
||||
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||
|
||||
activity = %Activity{
|
||||
data: %{"cc" => [@as_public], "to" => [user.follower_address]}
|
||||
|
|
@ -74,11 +68,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
end
|
||||
|
||||
test "it returns sharedInbox for messages involving multiple recipients in to" do
|
||||
user =
|
||||
insert(:user, %{
|
||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
||||
})
|
||||
|
||||
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||
user_two = insert(:user)
|
||||
user_three = insert(:user)
|
||||
|
||||
|
|
@ -90,11 +80,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
end
|
||||
|
||||
test "it returns sharedInbox for messages involving multiple recipients in cc" do
|
||||
user =
|
||||
insert(:user, %{
|
||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
||||
})
|
||||
|
||||
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||
user_two = insert(:user)
|
||||
user_three = insert(:user)
|
||||
|
||||
|
|
@ -107,12 +93,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
|
||||
test "it returns sharedInbox for messages involving multiple recipients in total" do
|
||||
user =
|
||||
insert(:user,
|
||||
source_data: %{
|
||||
"inbox" => "http://example.com/personal-inbox",
|
||||
"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}
|
||||
}
|
||||
)
|
||||
insert(:user, %{
|
||||
shared_inbox: "http://example.com/inbox",
|
||||
inbox: "http://example.com/personal-inbox"
|
||||
})
|
||||
|
||||
user_two = insert(:user)
|
||||
|
||||
|
|
@ -125,12 +109,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
|
||||
test "it returns inbox for messages involving single recipients in total" do
|
||||
user =
|
||||
insert(:user,
|
||||
source_data: %{
|
||||
"inbox" => "http://example.com/personal-inbox",
|
||||
"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}
|
||||
}
|
||||
)
|
||||
insert(:user, %{
|
||||
shared_inbox: "http://example.com/inbox",
|
||||
inbox: "http://example.com/personal-inbox"
|
||||
})
|
||||
|
||||
activity = %Activity{
|
||||
data: %{"to" => [user.ap_id], "cc" => []}
|
||||
|
|
@ -258,11 +240,11 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
[:passthrough],
|
||||
[] do
|
||||
follower =
|
||||
insert(:user,
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"},
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
)
|
||||
})
|
||||
|
||||
actor = insert(:user, follower_address: follower.ap_id)
|
||||
user = insert(:user)
|
||||
|
|
@ -295,14 +277,14 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
fetcher =
|
||||
insert(:user,
|
||||
local: false,
|
||||
source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"},
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
)
|
||||
|
||||
another_fetcher =
|
||||
insert(:user,
|
||||
local: false,
|
||||
source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"},
|
||||
inbox: "https://domain2.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,11 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
|
|||
}
|
||||
)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: :get, url: "http://mastodon.example.org/eee/99541947525187367"} ->
|
||||
%Tesla.Env{status: 500, body: ""}
|
||||
end)
|
||||
|
||||
assert capture_log(fn ->
|
||||
assert Relay.publish(activity) == {:error, nil}
|
||||
end) =~ "[error] error: nil"
|
||||
|
|
|
|||
267
test/web/activity_pub/side_effects_test.exs
Normal file
267
test/web/activity_pub/side_effects_test.exs
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.SideEffects
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
|
||||
describe "delete objects" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
|
||||
{:ok, favorite} = CommonAPI.favorite(user, post.id)
|
||||
object = Object.normalize(post)
|
||||
{:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
|
||||
{:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
|
||||
{:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
|
||||
{:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
|
||||
|
||||
%{
|
||||
user: user,
|
||||
delete: delete,
|
||||
post: post,
|
||||
object: object,
|
||||
delete_user: delete_user,
|
||||
op: op,
|
||||
favorite: favorite
|
||||
}
|
||||
end
|
||||
|
||||
test "it handles object deletions", %{
|
||||
delete: delete,
|
||||
post: post,
|
||||
object: object,
|
||||
user: user,
|
||||
op: op,
|
||||
favorite: favorite
|
||||
} do
|
||||
with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
|
||||
stream_out: fn _ -> nil end,
|
||||
stream_out_participations: fn _, _ -> nil end do
|
||||
{:ok, delete, _} = SideEffects.handle(delete)
|
||||
user = User.get_cached_by_ap_id(object.data["actor"])
|
||||
|
||||
assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
|
||||
assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
|
||||
end
|
||||
|
||||
object = Object.get_by_id(object.id)
|
||||
assert object.data["type"] == "Tombstone"
|
||||
refute Activity.get_by_id(post.id)
|
||||
refute Activity.get_by_id(favorite.id)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.note_count == 0
|
||||
|
||||
object = Object.normalize(op.data["object"], false)
|
||||
|
||||
assert object.data["repliesCount"] == 0
|
||||
end
|
||||
|
||||
test "it handles object deletions when the object itself has been pruned", %{
|
||||
delete: delete,
|
||||
post: post,
|
||||
object: object,
|
||||
user: user,
|
||||
op: op
|
||||
} do
|
||||
with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
|
||||
stream_out: fn _ -> nil end,
|
||||
stream_out_participations: fn _, _ -> nil end do
|
||||
{:ok, delete, _} = SideEffects.handle(delete)
|
||||
user = User.get_cached_by_ap_id(object.data["actor"])
|
||||
|
||||
assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
|
||||
assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
|
||||
end
|
||||
|
||||
object = Object.get_by_id(object.id)
|
||||
assert object.data["type"] == "Tombstone"
|
||||
refute Activity.get_by_id(post.id)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.note_count == 0
|
||||
|
||||
object = Object.normalize(op.data["object"], false)
|
||||
|
||||
assert object.data["repliesCount"] == 0
|
||||
end
|
||||
|
||||
test "it handles user deletions", %{delete_user: delete, user: user} do
|
||||
{:ok, _delete, _} = SideEffects.handle(delete)
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert User.get_cached_by_ap_id(user.ap_id).deactivated
|
||||
end
|
||||
end
|
||||
|
||||
describe "EmojiReact objects" do
|
||||
setup do
|
||||
poster = insert(:user)
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
||||
|
||||
{:ok, emoji_react_data, []} = Builder.emoji_react(user, post.object, "👌")
|
||||
{:ok, emoji_react, _meta} = ActivityPub.persist(emoji_react_data, local: true)
|
||||
|
||||
%{emoji_react: emoji_react, user: user, poster: poster}
|
||||
end
|
||||
|
||||
test "adds the reaction to the object", %{emoji_react: emoji_react, user: user} do
|
||||
{:ok, emoji_react, _} = SideEffects.handle(emoji_react)
|
||||
object = Object.get_by_ap_id(emoji_react.data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert ["👌", [user.ap_id]] in object.data["reactions"]
|
||||
end
|
||||
|
||||
test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
|
||||
{:ok, emoji_react, _} = SideEffects.handle(emoji_react)
|
||||
assert Repo.get_by(Notification, user_id: poster.id, activity_id: emoji_react.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Undo objects" do
|
||||
setup do
|
||||
poster = insert(:user)
|
||||
user = insert(:user)
|
||||
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
||||
{:ok, like} = CommonAPI.favorite(user, post.id)
|
||||
{:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
|
||||
{:ok, announce, _} = CommonAPI.repeat(post.id, user)
|
||||
{:ok, block} = ActivityPub.block(user, poster)
|
||||
User.block(user, poster)
|
||||
|
||||
{:ok, undo_data, _meta} = Builder.undo(user, like)
|
||||
{:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
||||
|
||||
{:ok, undo_data, _meta} = Builder.undo(user, reaction)
|
||||
{:ok, reaction_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
||||
|
||||
{:ok, undo_data, _meta} = Builder.undo(user, announce)
|
||||
{:ok, announce_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
||||
|
||||
{:ok, undo_data, _meta} = Builder.undo(user, block)
|
||||
{:ok, block_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
||||
|
||||
%{
|
||||
like_undo: like_undo,
|
||||
post: post,
|
||||
like: like,
|
||||
reaction_undo: reaction_undo,
|
||||
reaction: reaction,
|
||||
announce_undo: announce_undo,
|
||||
announce: announce,
|
||||
block_undo: block_undo,
|
||||
block: block,
|
||||
poster: poster,
|
||||
user: user
|
||||
}
|
||||
end
|
||||
|
||||
test "deletes the original block", %{block_undo: block_undo, block: block} do
|
||||
{:ok, _block_undo, _} = SideEffects.handle(block_undo)
|
||||
refute Activity.get_by_id(block.id)
|
||||
end
|
||||
|
||||
test "unblocks the blocked user", %{block_undo: block_undo, block: block} do
|
||||
blocker = User.get_by_ap_id(block.data["actor"])
|
||||
blocked = User.get_by_ap_id(block.data["object"])
|
||||
|
||||
{:ok, _block_undo, _} = SideEffects.handle(block_undo)
|
||||
refute User.blocks?(blocker, blocked)
|
||||
end
|
||||
|
||||
test "an announce undo removes the announce from the object", %{
|
||||
announce_undo: announce_undo,
|
||||
post: post
|
||||
} do
|
||||
{:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
|
||||
|
||||
object = Object.get_by_ap_id(post.data["object"])
|
||||
|
||||
assert object.data["announcement_count"] == 0
|
||||
assert object.data["announcements"] == []
|
||||
end
|
||||
|
||||
test "deletes the original announce", %{announce_undo: announce_undo, announce: announce} do
|
||||
{:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
|
||||
refute Activity.get_by_id(announce.id)
|
||||
end
|
||||
|
||||
test "a reaction undo removes the reaction from the object", %{
|
||||
reaction_undo: reaction_undo,
|
||||
post: post
|
||||
} do
|
||||
{:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
|
||||
|
||||
object = Object.get_by_ap_id(post.data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 0
|
||||
assert object.data["reactions"] == []
|
||||
end
|
||||
|
||||
test "deletes the original reaction", %{reaction_undo: reaction_undo, reaction: reaction} do
|
||||
{:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
|
||||
refute Activity.get_by_id(reaction.id)
|
||||
end
|
||||
|
||||
test "a like undo removes the like from the object", %{like_undo: like_undo, post: post} do
|
||||
{:ok, _like_undo, _} = SideEffects.handle(like_undo)
|
||||
|
||||
object = Object.get_by_ap_id(post.data["object"])
|
||||
|
||||
assert object.data["like_count"] == 0
|
||||
assert object.data["likes"] == []
|
||||
end
|
||||
|
||||
test "deletes the original like", %{like_undo: like_undo, like: like} do
|
||||
{:ok, _like_undo, _} = SideEffects.handle(like_undo)
|
||||
refute Activity.get_by_id(like.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "like objects" do
|
||||
setup do
|
||||
poster = insert(:user)
|
||||
user = insert(:user)
|
||||
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
||||
|
||||
{:ok, like_data, _meta} = Builder.like(user, post.object)
|
||||
{:ok, like, _meta} = ActivityPub.persist(like_data, local: true)
|
||||
|
||||
%{like: like, user: user, poster: poster}
|
||||
end
|
||||
|
||||
test "add the like to the original object", %{like: like, user: user} do
|
||||
{:ok, like, _} = SideEffects.handle(like)
|
||||
object = Object.get_by_ap_id(like.data["object"])
|
||||
assert object.data["like_count"] == 1
|
||||
assert user.ap_id in object.data["likes"]
|
||||
end
|
||||
|
||||
test "creates a notification", %{like: like, poster: poster} do
|
||||
{:ok, like, _} = SideEffects.handle(like)
|
||||
assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
114
test/web/activity_pub/transmogrifier/delete_handling_test.exs
Normal file
114
test/web/activity_pub/transmogrifier/delete_handling_test.exs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.Transmogrifier.DeleteHandlingTest do
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
end
|
||||
|
||||
test "it works for incoming deletes" do
|
||||
activity = insert(:note_activity)
|
||||
deleting_user = insert(:user)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-delete.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("actor", deleting_user.ap_id)
|
||||
|> put_in(["object", "id"], activity.data["object"])
|
||||
|
||||
{:ok, %Activity{actor: actor, local: false, data: %{"id" => id}}} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert id == data["id"]
|
||||
|
||||
# We delete the Create activity because we base our timelines on it.
|
||||
# This should be changed after we unify objects and activities
|
||||
refute Activity.get_by_id(activity.id)
|
||||
assert actor == deleting_user.ap_id
|
||||
|
||||
# Objects are replaced by a tombstone object.
|
||||
object = Object.normalize(activity.data["object"])
|
||||
assert object.data["type"] == "Tombstone"
|
||||
end
|
||||
|
||||
test "it works for incoming when the object has been pruned" do
|
||||
activity = insert(:note_activity)
|
||||
|
||||
{:ok, object} =
|
||||
Object.normalize(activity.data["object"])
|
||||
|> Repo.delete()
|
||||
|
||||
Cachex.del(:object_cache, "object:#{object.data["id"]}")
|
||||
|
||||
deleting_user = insert(:user)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-delete.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("actor", deleting_user.ap_id)
|
||||
|> put_in(["object", "id"], activity.data["object"])
|
||||
|
||||
{:ok, %Activity{actor: actor, local: false, data: %{"id" => id}}} =
|
||||
Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert id == data["id"]
|
||||
|
||||
# We delete the Create activity because we base our timelines on it.
|
||||
# This should be changed after we unify objects and activities
|
||||
refute Activity.get_by_id(activity.id)
|
||||
assert actor == deleting_user.ap_id
|
||||
end
|
||||
|
||||
test "it fails for incoming deletes with spoofed origin" do
|
||||
activity = insert(:note_activity)
|
||||
%{ap_id: ap_id} = insert(:user, ap_id: "https://gensokyo.2hu/users/raymoo")
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-delete.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("actor", ap_id)
|
||||
|> put_in(["object", "id"], activity.data["object"])
|
||||
|
||||
assert match?({:error, _}, Transmogrifier.handle_incoming(data))
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "it works for incoming user deletes" do
|
||||
%{ap_id: ap_id} = insert(:user, ap_id: "http://mastodon.example.org/users/admin")
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-delete-user.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:ok, _} = Transmogrifier.handle_incoming(data)
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert User.get_cached_by_ap_id(ap_id).deactivated
|
||||
end
|
||||
|
||||
test "it fails for incoming user deletes with spoofed origin" do
|
||||
%{ap_id: ap_id} = insert(:user)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-delete-user.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("actor", ap_id)
|
||||
|
||||
assert match?({:error, _}, Transmogrifier.handle_incoming(data))
|
||||
|
||||
assert User.get_cached_by_ap_id(ap_id)
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue