Merge develop

This commit is contained in:
Roman Chvanikov 2020-06-23 20:56:55 +03:00
commit 1471b70ef1
219 changed files with 8058 additions and 1997 deletions

View file

@ -0,0 +1,96 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ApplicationRequirementsTest do
use Pleroma.DataCase
import ExUnit.CaptureLog
import Mock
alias Pleroma.Repo
describe "check_rum!" do
setup_with_mocks([
{Pleroma.ApplicationRequirements, [:passthrough],
[check_migrations_applied!: fn _ -> :ok end]}
]) do
:ok
end
setup do: clear_config([:database, :rum_enabled])
test "raises if rum is enabled and detects unapplied rum migrations" do
Pleroma.Config.put([:database, :rum_enabled], true)
with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> false end]}]) do
assert_raise Pleroma.ApplicationRequirements.VerifyError,
"Unapplied RUM Migrations detected",
fn ->
capture_log(&Pleroma.ApplicationRequirements.verify!/0)
end
end
end
test "raises if rum is disabled and detects rum migrations" do
Pleroma.Config.put([:database, :rum_enabled], false)
with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> true end]}]) do
assert_raise Pleroma.ApplicationRequirements.VerifyError,
"RUM Migrations detected",
fn ->
capture_log(&Pleroma.ApplicationRequirements.verify!/0)
end
end
end
test "doesn't do anything if rum enabled and applied migrations" do
Pleroma.Config.put([:database, :rum_enabled], true)
with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> true end]}]) do
assert Pleroma.ApplicationRequirements.verify!() == :ok
end
end
test "doesn't do anything if rum disabled" do
Pleroma.Config.put([:database, :rum_enabled], false)
with_mocks([{Repo, [:passthrough], [exists?: fn _, _ -> false end]}]) do
assert Pleroma.ApplicationRequirements.verify!() == :ok
end
end
end
describe "check_migrations_applied!" do
setup_with_mocks([
{Ecto.Migrator, [],
[
with_repo: fn repo, fun -> passthrough([repo, fun]) end,
migrations: fn Repo ->
[
{:up, 20_191_128_153_944, "fix_missing_following_count"},
{:up, 20_191_203_043_610, "create_report_notes"},
{:down, 20_191_220_174_645, "add_scopes_to_pleroma_feo_auth_records"}
]
end
]}
]) do
:ok
end
setup do: clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
test "raises if it detects unapplied migrations" do
assert_raise Pleroma.ApplicationRequirements.VerifyError,
"Unapplied Migrations detected",
fn ->
capture_log(&Pleroma.ApplicationRequirements.verify!/0)
end
end
test "doesn't do anything if disabled" do
Pleroma.Config.put([:i_am_aware_this_may_cause_data_loss, :disable_migration_check], true)
assert :ok == Pleroma.ApplicationRequirements.verify!()
end
end
end

View file

@ -0,0 +1,29 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Chat.MessageReferenceTest do
use Pleroma.DataCase, async: true
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "messages" do
test "it returns the last message in a chat" do
user = insert(:user)
recipient = insert(:user)
{:ok, _message_1} = CommonAPI.post_chat_message(user, recipient, "hey")
{:ok, _message_2} = CommonAPI.post_chat_message(recipient, user, "ho")
{:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
message = MessageReference.last_message_for_chat(chat)
assert message.object.data["content"] == "ho"
end
end
end

61
test/chat_test.exs Normal file
View file

@ -0,0 +1,61 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ChatTest do
use Pleroma.DataCase, async: true
alias Pleroma.Chat
import Pleroma.Factory
describe "creation and getting" do
test "it only works if the recipient is a valid user (for now)" do
user = insert(:user)
assert {:error, _chat} = Chat.bump_or_create(user.id, "http://some/nonexisting/account")
assert {:error, _chat} = Chat.get_or_create(user.id, "http://some/nonexisting/account")
end
test "it creates a chat for a user and recipient" do
user = insert(:user)
other_user = insert(:user)
{:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
assert chat.id
end
test "it returns and bumps a chat for a user and recipient if it already exists" do
user = insert(:user)
other_user = insert(:user)
{:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
{:ok, chat_two} = Chat.bump_or_create(user.id, other_user.ap_id)
assert chat.id == chat_two.id
end
test "it returns a chat for a user and recipient if it already exists" do
user = insert(:user)
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
{:ok, chat_two} = Chat.get_or_create(user.id, other_user.ap_id)
assert chat.id == chat_two.id
end
test "a returning chat will have an updated `update_at` field" do
user = insert(:user)
other_user = insert(:user)
{:ok, chat} = Chat.bump_or_create(user.id, other_user.ap_id)
:timer.sleep(1500)
{:ok, chat_two} = Chat.bump_or_create(user.id, other_user.ap_id)
assert chat.id == chat_two.id
assert chat.updated_at != chat_two.updated_at
end
end
end

View file

@ -7,40 +7,28 @@ defmodule Pleroma.ConfigDBTest do
import Pleroma.Factory
alias Pleroma.ConfigDB
test "get_by_key/1" do
test "get_by_params/1" do
config = insert(:config)
insert(:config)
assert config == ConfigDB.get_by_params(%{group: config.group, key: config.key})
end
test "create/1" do
{:ok, config} = ConfigDB.create(%{group: ":pleroma", key: ":some_key", value: "some_value"})
assert config == ConfigDB.get_by_params(%{group: ":pleroma", key: ":some_key"})
end
test "update/1" do
config = insert(:config)
{:ok, updated} = ConfigDB.update(config, %{value: "some_value"})
loaded = ConfigDB.get_by_params(%{group: config.group, key: config.key})
assert loaded == updated
end
test "get_all_as_keyword/0" do
saved = insert(:config)
insert(:config, group: ":quack", key: ":level", value: ConfigDB.to_binary(:info))
insert(:config, group: ":quack", key: ":meta", value: ConfigDB.to_binary([:none]))
insert(:config, group: ":quack", key: ":level", value: :info)
insert(:config, group: ":quack", key: ":meta", value: [:none])
insert(:config,
group: ":quack",
key: ":webhook_url",
value: ConfigDB.to_binary("https://hooks.slack.com/services/KEY/some_val")
value: "https://hooks.slack.com/services/KEY/some_val"
)
config = ConfigDB.get_all_as_keyword()
assert config[:pleroma] == [
{ConfigDB.from_string(saved.key), ConfigDB.from_binary(saved.value)}
{saved.key, saved.value}
]
assert config[:quack][:level] == :info
@ -51,11 +39,11 @@ defmodule Pleroma.ConfigDBTest do
describe "update_or_create/1" do
test "common" do
config = insert(:config)
key2 = "another_key"
key2 = :another_key
params = [
%{group: "pleroma", key: key2, value: "another_value"},
%{group: config.group, key: config.key, value: "new_value"}
%{group: :pleroma, key: key2, value: "another_value"},
%{group: :pleroma, key: config.key, value: [a: 1, b: 2, c: "new_value"]}
]
assert Repo.all(ConfigDB) |> length() == 1
@ -65,16 +53,16 @@ defmodule Pleroma.ConfigDBTest do
assert Repo.all(ConfigDB) |> length() == 2
config1 = ConfigDB.get_by_params(%{group: config.group, key: config.key})
config2 = ConfigDB.get_by_params(%{group: "pleroma", key: key2})
config2 = ConfigDB.get_by_params(%{group: :pleroma, key: key2})
assert config1.value == ConfigDB.transform("new_value")
assert config2.value == ConfigDB.transform("another_value")
assert config1.value == [a: 1, b: 2, c: "new_value"]
assert config2.value == "another_value"
end
test "partial update" do
config = insert(:config, value: ConfigDB.to_binary(key1: "val1", key2: :val2))
config = insert(:config, value: [key1: "val1", key2: :val2])
{:ok, _config} =
{:ok, config} =
ConfigDB.update_or_create(%{
group: config.group,
key: config.key,
@ -83,15 +71,14 @@ defmodule Pleroma.ConfigDBTest do
updated = ConfigDB.get_by_params(%{group: config.group, key: config.key})
value = ConfigDB.from_binary(updated.value)
assert length(value) == 3
assert value[:key1] == :val1
assert value[:key2] == :val2
assert value[:key3] == :val3
assert config.value == updated.value
assert updated.value[:key1] == :val1
assert updated.value[:key2] == :val2
assert updated.value[:key3] == :val3
end
test "deep merge" do
config = insert(:config, value: ConfigDB.to_binary(key1: "val1", key2: [k1: :v1, k2: "v2"]))
config = insert(:config, value: [key1: "val1", key2: [k1: :v1, k2: "v2"]])
{:ok, config} =
ConfigDB.update_or_create(%{
@ -103,18 +90,15 @@ defmodule Pleroma.ConfigDBTest do
updated = ConfigDB.get_by_params(%{group: config.group, key: config.key})
assert config.value == updated.value
value = ConfigDB.from_binary(updated.value)
assert value[:key1] == :val1
assert value[:key2] == [k1: :v1, k2: :v2, k3: :v3]
assert value[:key3] == :val3
assert updated.value[:key1] == :val1
assert updated.value[:key2] == [k1: :v1, k2: :v2, k3: :v3]
assert updated.value[:key3] == :val3
end
test "only full update for some keys" do
config1 = insert(:config, key: ":ecto_repos", value: ConfigDB.to_binary(repo: Pleroma.Repo))
config1 = insert(:config, key: :ecto_repos, value: [repo: Pleroma.Repo])
config2 =
insert(:config, group: ":cors_plug", key: ":max_age", value: ConfigDB.to_binary(18))
config2 = insert(:config, group: :cors_plug, key: :max_age, value: 18)
{:ok, _config} =
ConfigDB.update_or_create(%{
@ -133,8 +117,8 @@ defmodule Pleroma.ConfigDBTest do
updated1 = ConfigDB.get_by_params(%{group: config1.group, key: config1.key})
updated2 = ConfigDB.get_by_params(%{group: config2.group, key: config2.key})
assert ConfigDB.from_binary(updated1.value) == [another_repo: [Pleroma.Repo]]
assert ConfigDB.from_binary(updated2.value) == 777
assert updated1.value == [another_repo: [Pleroma.Repo]]
assert updated2.value == 777
end
test "full update if value is not keyword" do
@ -142,7 +126,7 @@ defmodule Pleroma.ConfigDBTest do
insert(:config,
group: ":tesla",
key: ":adapter",
value: ConfigDB.to_binary(Tesla.Adapter.Hackney)
value: Tesla.Adapter.Hackney
)
{:ok, _config} =
@ -154,20 +138,20 @@ defmodule Pleroma.ConfigDBTest do
updated = ConfigDB.get_by_params(%{group: config.group, key: config.key})
assert ConfigDB.from_binary(updated.value) == Tesla.Adapter.Httpc
assert updated.value == Tesla.Adapter.Httpc
end
test "only full update for some subkeys" do
config1 =
insert(:config,
key: ":emoji",
value: ConfigDB.to_binary(groups: [a: 1, b: 2], key: [a: 1])
value: [groups: [a: 1, b: 2], key: [a: 1]]
)
config2 =
insert(:config,
key: ":assets",
value: ConfigDB.to_binary(mascots: [a: 1, b: 2], key: [a: 1])
value: [mascots: [a: 1, b: 2], key: [a: 1]]
)
{:ok, _config} =
@ -187,8 +171,8 @@ defmodule Pleroma.ConfigDBTest do
updated1 = ConfigDB.get_by_params(%{group: config1.group, key: config1.key})
updated2 = ConfigDB.get_by_params(%{group: config2.group, key: config2.key})
assert ConfigDB.from_binary(updated1.value) == [groups: [c: 3, d: 4], key: [a: 1, b: 2]]
assert ConfigDB.from_binary(updated2.value) == [mascots: [c: 3, d: 4], key: [a: 1, b: 2]]
assert updated1.value == [groups: [c: 3, d: 4], key: [a: 1, b: 2]]
assert updated2.value == [mascots: [c: 3, d: 4], key: [a: 1, b: 2]]
end
end
@ -206,14 +190,14 @@ defmodule Pleroma.ConfigDBTest do
end
test "partial subkeys delete" do
config = insert(:config, value: ConfigDB.to_binary(groups: [a: 1, b: 2], key: [a: 1]))
config = insert(:config, value: [groups: [a: 1, b: 2], key: [a: 1]])
{:ok, deleted} =
ConfigDB.delete(%{group: config.group, key: config.key, subkeys: [":groups"]})
assert Ecto.get_meta(deleted, :state) == :loaded
assert deleted.value == ConfigDB.to_binary(key: [a: 1])
assert deleted.value == [key: [a: 1]]
updated = ConfigDB.get_by_params(%{group: config.group, key: config.key})
@ -221,7 +205,7 @@ defmodule Pleroma.ConfigDBTest do
end
test "full delete if remaining value after subkeys deletion is empty list" do
config = insert(:config, value: ConfigDB.to_binary(groups: [a: 1, b: 2]))
config = insert(:config, value: [groups: [a: 1, b: 2]])
{:ok, deleted} =
ConfigDB.delete(%{group: config.group, key: config.key, subkeys: [":groups"]})
@ -232,234 +216,159 @@ defmodule Pleroma.ConfigDBTest do
end
end
describe "transform/1" do
describe "to_elixir_types/1" do
test "string" do
binary = ConfigDB.transform("value as string")
assert binary == :erlang.term_to_binary("value as string")
assert ConfigDB.from_binary(binary) == "value as string"
assert ConfigDB.to_elixir_types("value as string") == "value as string"
end
test "boolean" do
binary = ConfigDB.transform(false)
assert binary == :erlang.term_to_binary(false)
assert ConfigDB.from_binary(binary) == false
assert ConfigDB.to_elixir_types(false) == false
end
test "nil" do
binary = ConfigDB.transform(nil)
assert binary == :erlang.term_to_binary(nil)
assert ConfigDB.from_binary(binary) == nil
assert ConfigDB.to_elixir_types(nil) == nil
end
test "integer" do
binary = ConfigDB.transform(150)
assert binary == :erlang.term_to_binary(150)
assert ConfigDB.from_binary(binary) == 150
assert ConfigDB.to_elixir_types(150) == 150
end
test "atom" do
binary = ConfigDB.transform(":atom")
assert binary == :erlang.term_to_binary(:atom)
assert ConfigDB.from_binary(binary) == :atom
assert ConfigDB.to_elixir_types(":atom") == :atom
end
test "ssl options" do
binary = ConfigDB.transform([":tlsv1", ":tlsv1.1", ":tlsv1.2"])
assert binary == :erlang.term_to_binary([:tlsv1, :"tlsv1.1", :"tlsv1.2"])
assert ConfigDB.from_binary(binary) == [:tlsv1, :"tlsv1.1", :"tlsv1.2"]
assert ConfigDB.to_elixir_types([":tlsv1", ":tlsv1.1", ":tlsv1.2"]) == [
:tlsv1,
:"tlsv1.1",
:"tlsv1.2"
]
end
test "pleroma module" do
binary = ConfigDB.transform("Pleroma.Bookmark")
assert binary == :erlang.term_to_binary(Pleroma.Bookmark)
assert ConfigDB.from_binary(binary) == Pleroma.Bookmark
assert ConfigDB.to_elixir_types("Pleroma.Bookmark") == Pleroma.Bookmark
end
test "pleroma string" do
binary = ConfigDB.transform("Pleroma")
assert binary == :erlang.term_to_binary("Pleroma")
assert ConfigDB.from_binary(binary) == "Pleroma"
assert ConfigDB.to_elixir_types("Pleroma") == "Pleroma"
end
test "phoenix module" do
binary = ConfigDB.transform("Phoenix.Socket.V1.JSONSerializer")
assert binary == :erlang.term_to_binary(Phoenix.Socket.V1.JSONSerializer)
assert ConfigDB.from_binary(binary) == Phoenix.Socket.V1.JSONSerializer
assert ConfigDB.to_elixir_types("Phoenix.Socket.V1.JSONSerializer") ==
Phoenix.Socket.V1.JSONSerializer
end
test "tesla module" do
binary = ConfigDB.transform("Tesla.Adapter.Hackney")
assert binary == :erlang.term_to_binary(Tesla.Adapter.Hackney)
assert ConfigDB.from_binary(binary) == Tesla.Adapter.Hackney
assert ConfigDB.to_elixir_types("Tesla.Adapter.Hackney") == Tesla.Adapter.Hackney
end
test "ExSyslogger module" do
binary = ConfigDB.transform("ExSyslogger")
assert binary == :erlang.term_to_binary(ExSyslogger)
assert ConfigDB.from_binary(binary) == ExSyslogger
assert ConfigDB.to_elixir_types("ExSyslogger") == ExSyslogger
end
test "Quack.Logger module" do
binary = ConfigDB.transform("Quack.Logger")
assert binary == :erlang.term_to_binary(Quack.Logger)
assert ConfigDB.from_binary(binary) == Quack.Logger
assert ConfigDB.to_elixir_types("Quack.Logger") == Quack.Logger
end
test "Swoosh.Adapters modules" do
binary = ConfigDB.transform("Swoosh.Adapters.SMTP")
assert binary == :erlang.term_to_binary(Swoosh.Adapters.SMTP)
assert ConfigDB.from_binary(binary) == Swoosh.Adapters.SMTP
binary = ConfigDB.transform("Swoosh.Adapters.AmazonSES")
assert binary == :erlang.term_to_binary(Swoosh.Adapters.AmazonSES)
assert ConfigDB.from_binary(binary) == Swoosh.Adapters.AmazonSES
assert ConfigDB.to_elixir_types("Swoosh.Adapters.SMTP") == Swoosh.Adapters.SMTP
assert ConfigDB.to_elixir_types("Swoosh.Adapters.AmazonSES") == Swoosh.Adapters.AmazonSES
end
test "sigil" do
binary = ConfigDB.transform("~r[comp[lL][aA][iI][nN]er]")
assert binary == :erlang.term_to_binary(~r/comp[lL][aA][iI][nN]er/)
assert ConfigDB.from_binary(binary) == ~r/comp[lL][aA][iI][nN]er/
assert ConfigDB.to_elixir_types("~r[comp[lL][aA][iI][nN]er]") == ~r/comp[lL][aA][iI][nN]er/
end
test "link sigil" do
binary = ConfigDB.transform("~r/https:\/\/example.com/")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/)
assert ConfigDB.from_binary(binary) == ~r/https:\/\/example.com/
assert ConfigDB.to_elixir_types("~r/https:\/\/example.com/") == ~r/https:\/\/example.com/
end
test "link sigil with um modifiers" do
binary = ConfigDB.transform("~r/https:\/\/example.com/um")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/um)
assert ConfigDB.from_binary(binary) == ~r/https:\/\/example.com/um
assert ConfigDB.to_elixir_types("~r/https:\/\/example.com/um") ==
~r/https:\/\/example.com/um
end
test "link sigil with i modifier" do
binary = ConfigDB.transform("~r/https:\/\/example.com/i")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/i)
assert ConfigDB.from_binary(binary) == ~r/https:\/\/example.com/i
assert ConfigDB.to_elixir_types("~r/https:\/\/example.com/i") == ~r/https:\/\/example.com/i
end
test "link sigil with s modifier" do
binary = ConfigDB.transform("~r/https:\/\/example.com/s")
assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/s)
assert ConfigDB.from_binary(binary) == ~r/https:\/\/example.com/s
assert ConfigDB.to_elixir_types("~r/https:\/\/example.com/s") == ~r/https:\/\/example.com/s
end
test "raise if valid delimiter not found" do
assert_raise ArgumentError, "valid delimiter for Regex expression not found", fn ->
ConfigDB.transform("~r/https://[]{}<>\"'()|example.com/s")
ConfigDB.to_elixir_types("~r/https://[]{}<>\"'()|example.com/s")
end
end
test "2 child tuple" do
binary = ConfigDB.transform(%{"tuple" => ["v1", ":v2"]})
assert binary == :erlang.term_to_binary({"v1", :v2})
assert ConfigDB.from_binary(binary) == {"v1", :v2}
assert ConfigDB.to_elixir_types(%{"tuple" => ["v1", ":v2"]}) == {"v1", :v2}
end
test "proxy tuple with localhost" do
binary =
ConfigDB.transform(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]
})
assert binary == :erlang.term_to_binary({:proxy_url, {:socks5, :localhost, 1234}})
assert ConfigDB.from_binary(binary) == {:proxy_url, {:socks5, :localhost, 1234}}
assert ConfigDB.to_elixir_types(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]
}) == {:proxy_url, {:socks5, :localhost, 1234}}
end
test "proxy tuple with domain" do
binary =
ConfigDB.transform(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]
})
assert binary == :erlang.term_to_binary({:proxy_url, {:socks5, 'domain.com', 1234}})
assert ConfigDB.from_binary(binary) == {:proxy_url, {:socks5, 'domain.com', 1234}}
assert ConfigDB.to_elixir_types(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]
}) == {:proxy_url, {:socks5, 'domain.com', 1234}}
end
test "proxy tuple with ip" do
binary =
ConfigDB.transform(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]
})
assert binary == :erlang.term_to_binary({:proxy_url, {:socks5, {127, 0, 0, 1}, 1234}})
assert ConfigDB.from_binary(binary) == {:proxy_url, {:socks5, {127, 0, 0, 1}, 1234}}
assert ConfigDB.to_elixir_types(%{
"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]
}) == {:proxy_url, {:socks5, {127, 0, 0, 1}, 1234}}
end
test "tuple with n childs" do
binary =
ConfigDB.transform(%{
"tuple" => [
"v1",
":v2",
"Pleroma.Bookmark",
150,
false,
"Phoenix.Socket.V1.JSONSerializer"
]
})
assert binary ==
:erlang.term_to_binary(
{"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer}
)
assert ConfigDB.from_binary(binary) ==
{"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer}
assert ConfigDB.to_elixir_types(%{
"tuple" => [
"v1",
":v2",
"Pleroma.Bookmark",
150,
false,
"Phoenix.Socket.V1.JSONSerializer"
]
}) == {"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer}
end
test "map with string key" do
binary = ConfigDB.transform(%{"key" => "value"})
assert binary == :erlang.term_to_binary(%{"key" => "value"})
assert ConfigDB.from_binary(binary) == %{"key" => "value"}
assert ConfigDB.to_elixir_types(%{"key" => "value"}) == %{"key" => "value"}
end
test "map with atom key" do
binary = ConfigDB.transform(%{":key" => "value"})
assert binary == :erlang.term_to_binary(%{key: "value"})
assert ConfigDB.from_binary(binary) == %{key: "value"}
assert ConfigDB.to_elixir_types(%{":key" => "value"}) == %{key: "value"}
end
test "list of strings" do
binary = ConfigDB.transform(["v1", "v2", "v3"])
assert binary == :erlang.term_to_binary(["v1", "v2", "v3"])
assert ConfigDB.from_binary(binary) == ["v1", "v2", "v3"]
assert ConfigDB.to_elixir_types(["v1", "v2", "v3"]) == ["v1", "v2", "v3"]
end
test "list of modules" do
binary = ConfigDB.transform(["Pleroma.Repo", "Pleroma.Activity"])
assert binary == :erlang.term_to_binary([Pleroma.Repo, Pleroma.Activity])
assert ConfigDB.from_binary(binary) == [Pleroma.Repo, Pleroma.Activity]
assert ConfigDB.to_elixir_types(["Pleroma.Repo", "Pleroma.Activity"]) == [
Pleroma.Repo,
Pleroma.Activity
]
end
test "list of atoms" do
binary = ConfigDB.transform([":v1", ":v2", ":v3"])
assert binary == :erlang.term_to_binary([:v1, :v2, :v3])
assert ConfigDB.from_binary(binary) == [:v1, :v2, :v3]
assert ConfigDB.to_elixir_types([":v1", ":v2", ":v3"]) == [:v1, :v2, :v3]
end
test "list of mixed values" do
binary =
ConfigDB.transform([
"v1",
":v2",
"Pleroma.Repo",
"Phoenix.Socket.V1.JSONSerializer",
15,
false
])
assert binary ==
:erlang.term_to_binary([
"v1",
:v2,
Pleroma.Repo,
Phoenix.Socket.V1.JSONSerializer,
15,
false
])
assert ConfigDB.from_binary(binary) == [
assert ConfigDB.to_elixir_types([
"v1",
":v2",
"Pleroma.Repo",
"Phoenix.Socket.V1.JSONSerializer",
15,
false
]) == [
"v1",
:v2,
Pleroma.Repo,
@ -470,40 +379,17 @@ defmodule Pleroma.ConfigDBTest do
end
test "simple keyword" do
binary = ConfigDB.transform([%{"tuple" => [":key", "value"]}])
assert binary == :erlang.term_to_binary([{:key, "value"}])
assert ConfigDB.from_binary(binary) == [{:key, "value"}]
assert ConfigDB.from_binary(binary) == [key: "value"]
end
test "keyword with partial_chain key" do
binary =
ConfigDB.transform([%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}])
assert binary == :erlang.term_to_binary(partial_chain: &:hackney_connect.partial_chain/1)
assert ConfigDB.from_binary(binary) == [partial_chain: &:hackney_connect.partial_chain/1]
assert ConfigDB.to_elixir_types([%{"tuple" => [":key", "value"]}]) == [key: "value"]
end
test "keyword" do
binary =
ConfigDB.transform([
%{"tuple" => [":types", "Pleroma.PostgresTypes"]},
%{"tuple" => [":telemetry_event", ["Pleroma.Repo.Instrumenter"]]},
%{"tuple" => [":migration_lock", nil]},
%{"tuple" => [":key1", 150]},
%{"tuple" => [":key2", "string"]}
])
assert binary ==
:erlang.term_to_binary(
types: Pleroma.PostgresTypes,
telemetry_event: [Pleroma.Repo.Instrumenter],
migration_lock: nil,
key1: 150,
key2: "string"
)
assert ConfigDB.from_binary(binary) == [
assert ConfigDB.to_elixir_types([
%{"tuple" => [":types", "Pleroma.PostgresTypes"]},
%{"tuple" => [":telemetry_event", ["Pleroma.Repo.Instrumenter"]]},
%{"tuple" => [":migration_lock", nil]},
%{"tuple" => [":key1", 150]},
%{"tuple" => [":key2", "string"]}
]) == [
types: Pleroma.PostgresTypes,
telemetry_event: [Pleroma.Repo.Instrumenter],
migration_lock: nil,
@ -512,86 +398,60 @@ defmodule Pleroma.ConfigDBTest do
]
end
test "complex keyword with nested mixed childs" do
binary =
ConfigDB.transform([
%{"tuple" => [":uploader", "Pleroma.Uploaders.Local"]},
%{"tuple" => [":filters", ["Pleroma.Upload.Filter.Dedupe"]]},
%{"tuple" => [":link_name", true]},
%{"tuple" => [":proxy_remote", false]},
%{"tuple" => [":common_map", %{":key" => "value"}]},
%{
"tuple" => [
":proxy_opts",
[
%{"tuple" => [":redirect_on_failure", false]},
%{"tuple" => [":max_body_length", 1_048_576]},
%{
"tuple" => [
":http",
[%{"tuple" => [":follow_redirect", true]}, %{"tuple" => [":pool", ":upload"]}]
]
}
]
]
}
])
test "trandformed keyword" do
assert ConfigDB.to_elixir_types(a: 1, b: 2, c: "string") == [a: 1, b: 2, c: "string"]
end
assert binary ==
:erlang.term_to_binary(
uploader: Pleroma.Uploaders.Local,
filters: [Pleroma.Upload.Filter.Dedupe],
link_name: true,
proxy_remote: false,
common_map: %{key: "value"},
proxy_opts: [
redirect_on_failure: false,
max_body_length: 1_048_576,
http: [
follow_redirect: true,
pool: :upload
test "complex keyword with nested mixed childs" do
assert ConfigDB.to_elixir_types([
%{"tuple" => [":uploader", "Pleroma.Uploaders.Local"]},
%{"tuple" => [":filters", ["Pleroma.Upload.Filter.Dedupe"]]},
%{"tuple" => [":link_name", true]},
%{"tuple" => [":proxy_remote", false]},
%{"tuple" => [":common_map", %{":key" => "value"}]},
%{
"tuple" => [
":proxy_opts",
[
%{"tuple" => [":redirect_on_failure", false]},
%{"tuple" => [":max_body_length", 1_048_576]},
%{
"tuple" => [
":http",
[
%{"tuple" => [":follow_redirect", true]},
%{"tuple" => [":pool", ":upload"]}
]
]
}
]
]
)
assert ConfigDB.from_binary(binary) ==
[
uploader: Pleroma.Uploaders.Local,
filters: [Pleroma.Upload.Filter.Dedupe],
link_name: true,
proxy_remote: false,
common_map: %{key: "value"},
proxy_opts: [
redirect_on_failure: false,
max_body_length: 1_048_576,
http: [
follow_redirect: true,
pool: :upload
]
}
]) == [
uploader: Pleroma.Uploaders.Local,
filters: [Pleroma.Upload.Filter.Dedupe],
link_name: true,
proxy_remote: false,
common_map: %{key: "value"},
proxy_opts: [
redirect_on_failure: false,
max_body_length: 1_048_576,
http: [
follow_redirect: true,
pool: :upload
]
]
]
end
test "common keyword" do
binary =
ConfigDB.transform([
%{"tuple" => [":level", ":warn"]},
%{"tuple" => [":meta", [":all"]]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":val", nil]},
%{"tuple" => [":webhook_url", "https://hooks.slack.com/services/YOUR-KEY-HERE"]}
])
assert binary ==
:erlang.term_to_binary(
level: :warn,
meta: [:all],
path: "",
val: nil,
webhook_url: "https://hooks.slack.com/services/YOUR-KEY-HERE"
)
assert ConfigDB.from_binary(binary) == [
assert ConfigDB.to_elixir_types([
%{"tuple" => [":level", ":warn"]},
%{"tuple" => [":meta", [":all"]]},
%{"tuple" => [":path", ""]},
%{"tuple" => [":val", nil]},
%{"tuple" => [":webhook_url", "https://hooks.slack.com/services/YOUR-KEY-HERE"]}
]) == [
level: :warn,
meta: [:all],
path: "",
@ -601,98 +461,73 @@ defmodule Pleroma.ConfigDBTest do
end
test "complex keyword with sigil" do
binary =
ConfigDB.transform([
%{"tuple" => [":federated_timeline_removal", []]},
%{"tuple" => [":reject", ["~r/comp[lL][aA][iI][nN]er/"]]},
%{"tuple" => [":replace", []]}
])
assert binary ==
:erlang.term_to_binary(
federated_timeline_removal: [],
reject: [~r/comp[lL][aA][iI][nN]er/],
replace: []
)
assert ConfigDB.from_binary(binary) ==
[federated_timeline_removal: [], reject: [~r/comp[lL][aA][iI][nN]er/], replace: []]
assert ConfigDB.to_elixir_types([
%{"tuple" => [":federated_timeline_removal", []]},
%{"tuple" => [":reject", ["~r/comp[lL][aA][iI][nN]er/"]]},
%{"tuple" => [":replace", []]}
]) == [
federated_timeline_removal: [],
reject: [~r/comp[lL][aA][iI][nN]er/],
replace: []
]
end
test "complex keyword with tuples with more than 2 values" do
binary =
ConfigDB.transform([
%{
"tuple" => [
":http",
[
%{
"tuple" => [
":key1",
[
%{
"tuple" => [
":_",
[
%{
"tuple" => [
"/api/v1/streaming",
"Pleroma.Web.MastodonAPI.WebsocketHandler",
[]
]
},
%{
"tuple" => [
"/websocket",
"Phoenix.Endpoint.CowboyWebSocket",
%{
"tuple" => [
"Phoenix.Transports.WebSocket",
%{
"tuple" => [
"Pleroma.Web.Endpoint",
"Pleroma.Web.UserSocket",
[]
]
}
]
}
]
},
%{
"tuple" => [
":_",
"Phoenix.Endpoint.Cowboy2Handler",
%{"tuple" => ["Pleroma.Web.Endpoint", []]}
]
}
]
]
}
]
]
}
]
]
}
])
assert binary ==
:erlang.term_to_binary(
http: [
key1: [
_: [
{"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
{"/websocket", Phoenix.Endpoint.CowboyWebSocket,
{Phoenix.Transports.WebSocket,
{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}},
{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
]
assert ConfigDB.to_elixir_types([
%{
"tuple" => [
":http",
[
%{
"tuple" => [
":key1",
[
%{
"tuple" => [
":_",
[
%{
"tuple" => [
"/api/v1/streaming",
"Pleroma.Web.MastodonAPI.WebsocketHandler",
[]
]
},
%{
"tuple" => [
"/websocket",
"Phoenix.Endpoint.CowboyWebSocket",
%{
"tuple" => [
"Phoenix.Transports.WebSocket",
%{
"tuple" => [
"Pleroma.Web.Endpoint",
"Pleroma.Web.UserSocket",
[]
]
}
]
}
]
},
%{
"tuple" => [
":_",
"Phoenix.Endpoint.Cowboy2Handler",
%{"tuple" => ["Pleroma.Web.Endpoint", []]}
]
}
]
]
}
]
]
}
]
]
)
assert ConfigDB.from_binary(binary) == [
}
]) == [
http: [
key1: [
{:_,

View file

@ -0,0 +1,57 @@
defmodule Pleroma.Config.DeprecationWarningsTest do
use ExUnit.Case, async: true
use Pleroma.Tests.Helpers
import ExUnit.CaptureLog
test "check_old_mrf_config/0" do
clear_config([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.NoOpPolicy)
clear_config([:instance, :mrf_transparency], true)
clear_config([:instance, :mrf_transparency_exclusions], [])
assert capture_log(fn -> Pleroma.Config.DeprecationWarnings.check_old_mrf_config() end) =~
"""
!!!DEPRECATION WARNING!!!
Your config is using old namespaces for MRF configuration. They should work for now, but you are advised to change to new namespaces to prevent possible issues later:
* `config :pleroma, :instance, rewrite_policy` is now `config :pleroma, :mrf, policies`
* `config :pleroma, :instance, mrf_transparency` is now `config :pleroma, :mrf, transparency`
* `config :pleroma, :instance, mrf_transparency_exclusions` is now `config :pleroma, :mrf, transparency_exclusions`
"""
end
test "move_namespace_and_warn/2" do
old_group1 = [:group, :key]
old_group2 = [:group, :key2]
old_group3 = [:group, :key3]
new_group1 = [:another_group, :key4]
new_group2 = [:another_group, :key5]
new_group3 = [:another_group, :key6]
clear_config(old_group1, 1)
clear_config(old_group2, 2)
clear_config(old_group3, 3)
clear_config(new_group1)
clear_config(new_group2)
clear_config(new_group3)
config_map = [
{old_group1, new_group1, "\n error :key"},
{old_group2, new_group2, "\n error :key2"},
{old_group3, new_group3, "\n error :key3"}
]
assert capture_log(fn ->
Pleroma.Config.DeprecationWarnings.move_namespace_and_warn(
config_map,
"Warning preface"
)
end) =~ "Warning preface\n error :key\n error :key2\n error :key3"
assert Pleroma.Config.get(new_group1) == 1
assert Pleroma.Config.get(new_group2) == 2
assert Pleroma.Config.get(new_group3) == 3
end
end

View file

@ -6,9 +6,9 @@ defmodule Pleroma.Config.TransferTaskTest do
use Pleroma.DataCase
import ExUnit.CaptureLog
import Pleroma.Factory
alias Pleroma.Config.TransferTask
alias Pleroma.ConfigDB
setup do: clear_config(:configurable_from_database, true)
@ -19,31 +19,11 @@ defmodule Pleroma.Config.TransferTaskTest do
refute Application.get_env(:postgrex, :test_key)
initial = Application.get_env(:logger, :level)
ConfigDB.create(%{
group: ":pleroma",
key: ":test_key",
value: [live: 2, com: 3]
})
ConfigDB.create(%{
group: ":idna",
key: ":test_key",
value: [live: 15, com: 35]
})
ConfigDB.create(%{
group: ":quack",
key: ":test_key",
value: [:test_value1, :test_value2]
})
ConfigDB.create(%{
group: ":postgrex",
key: ":test_key",
value: :value
})
ConfigDB.create(%{group: ":logger", key: ":level", value: :debug})
insert(:config, key: :test_key, value: [live: 2, com: 3])
insert(:config, group: :idna, key: :test_key, value: [live: 15, com: 35])
insert(:config, group: :quack, key: :test_key, value: [:test_value1, :test_value2])
insert(:config, group: :postgrex, key: :test_key, value: :value)
insert(:config, group: :logger, key: :level, value: :debug)
TransferTask.start_link([])
@ -66,17 +46,8 @@ defmodule Pleroma.Config.TransferTaskTest do
level = Application.get_env(:quack, :level)
meta = Application.get_env(:quack, :meta)
ConfigDB.create(%{
group: ":quack",
key: ":level",
value: :info
})
ConfigDB.create(%{
group: ":quack",
key: ":meta",
value: [:none]
})
insert(:config, group: :quack, key: :level, value: :info)
insert(:config, group: :quack, key: :meta, value: [:none])
TransferTask.start_link([])
@ -95,17 +66,8 @@ defmodule Pleroma.Config.TransferTaskTest do
clear_config(:emoji)
clear_config(:assets)
ConfigDB.create(%{
group: ":pleroma",
key: ":emoji",
value: [groups: [a: 1, b: 2]]
})
ConfigDB.create(%{
group: ":pleroma",
key: ":assets",
value: [mascots: [a: 1, b: 2]]
})
insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]])
insert(:config, key: :assets, value: [mascots: [a: 1, b: 2]])
TransferTask.start_link([])
@ -122,12 +84,7 @@ defmodule Pleroma.Config.TransferTaskTest do
test "don't restart if no reboot time settings were changed" do
clear_config(:emoji)
ConfigDB.create(%{
group: ":pleroma",
key: ":emoji",
value: [groups: [a: 1, b: 2]]
})
insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]])
refute String.contains?(
capture_log(fn -> TransferTask.start_link([]) end),
@ -137,25 +94,13 @@ defmodule Pleroma.Config.TransferTaskTest do
test "on reboot time key" do
clear_config(:chat)
ConfigDB.create(%{
group: ":pleroma",
key: ":chat",
value: [enabled: false]
})
insert(:config, key: :chat, value: [enabled: false])
assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted"
end
test "on reboot time subkey" do
clear_config(Pleroma.Captcha)
ConfigDB.create(%{
group: ":pleroma",
key: "Pleroma.Captcha",
value: [seconds_valid: 60]
})
insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60])
assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted"
end
@ -163,17 +108,8 @@ defmodule Pleroma.Config.TransferTaskTest do
clear_config(:chat)
clear_config(Pleroma.Captcha)
ConfigDB.create(%{
group: ":pleroma",
key: ":chat",
value: [enabled: false]
})
ConfigDB.create(%{
group: ":pleroma",
key: "Pleroma.Captcha",
value: [seconds_valid: 60]
})
insert(:config, key: :chat, value: [enabled: false])
insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60])
refute String.contains?(
capture_log(fn -> TransferTask.load_and_update_env([], false) end),

View file

@ -9,3 +9,5 @@ config :quack, level: :info
config :pleroma, Pleroma.Repo, pool: Ecto.Adapters.SQL.Sandbox
config :postgrex, :json_library, Poison
config :pleroma, :database, rum_enabled: true

31
test/fixtures/create-chat-message.json vendored Normal file
View file

@ -0,0 +1,31 @@
{
"actor": "http://2hu.gensokyo/users/raymoo",
"id": "http://2hu.gensokyo/objects/1",
"object": {
"attributedTo": "http://2hu.gensokyo/users/raymoo",
"content": "You expected a cute girl? Too bad. <script>alert('XSS')</script>",
"id": "http://2hu.gensokyo/objects/2",
"published": "2020-02-12T14:08:20Z",
"to": [
"http://2hu.gensokyo/users/marisa"
],
"tag": [
{
"icon": {
"type": "Image",
"url": "http://2hu.gensokyo/emoji/Firefox.gif"
},
"id": "http://2hu.gensokyo/emoji/Firefox.gif",
"name": ":firefox:",
"type": "Emoji",
"updated": "1970-01-01T00:00:00Z"
}
],
"type": "ChatMessage"
},
"published": "2018-02-12T14:08:20Z",
"to": [
"http://2hu.gensokyo/users/marisa"
],
"type": "Create"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

View file

@ -1,6 +1,7 @@
{
"files": {
"blank": "blank.png"
"blank": "blank.png",
"blank2": "blank2.png"
},
"pack": {
"description": "Test description",

View file

@ -4,7 +4,7 @@
"homepage": "https://pleroma.social",
"description": "Test description",
"fallback-src": "https://nonshared-pack",
"fallback-src-sha256": "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF",
"fallback-src-sha256": "1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D",
"share-files": false
},
"files": {

View file

@ -0,0 +1,56 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.MigrationHelper.NotificationBackfillTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.MigrationHelper.NotificationBackfill
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "fill_in_notification_types" do
test "it fills in missing notification types" do
user = insert(:user)
other_user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "yeah, @#{other_user.nickname}"})
{:ok, chat} = CommonAPI.post_chat_message(user, other_user, "yo")
{:ok, react} = CommonAPI.react_with_emoji(post.id, other_user, "")
{:ok, like} = CommonAPI.favorite(other_user, post.id)
{:ok, react_2} = CommonAPI.react_with_emoji(post.id, other_user, "")
data =
react_2.data
|> Map.put("type", "EmojiReaction")
{:ok, react_2} =
react_2
|> Activity.change(%{data: data})
|> Repo.update()
assert {5, nil} = Repo.update_all(Notification, set: [type: nil])
NotificationBackfill.fill_in_notification_types()
assert %{type: "mention"} =
Repo.get_by(Notification, user_id: other_user.id, activity_id: post.id)
assert %{type: "favourite"} =
Repo.get_by(Notification, user_id: user.id, activity_id: like.id)
assert %{type: "pleroma:emoji_reaction"} =
Repo.get_by(Notification, user_id: user.id, activity_id: react.id)
assert %{type: "pleroma:emoji_reaction"} =
Repo.get_by(Notification, user_id: user.id, activity_id: react_2.id)
assert %{type: "pleroma:chat_mention"} =
Repo.get_by(Notification, user_id: other_user.id, activity_id: chat.id)
end
end
end

View file

@ -10,6 +10,7 @@ defmodule Pleroma.NotificationTest do
alias Pleroma.FollowingRelationship
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@ -31,6 +32,7 @@ defmodule Pleroma.NotificationTest do
{:ok, [notification]} = Notification.create_notifications(activity)
assert notification.user_id == user.id
assert notification.type == "pleroma:emoji_reaction"
end
test "notifies someone when they are directly addressed" do
@ -48,6 +50,7 @@ defmodule Pleroma.NotificationTest do
notified_ids = Enum.sort([notification.user_id, other_notification.user_id])
assert notified_ids == [other_user.id, third_user.id]
assert notification.activity_id == activity.id
assert notification.type == "mention"
assert other_notification.activity_id == activity.id
assert [%Pleroma.Marker{unread_count: 2}] =
@ -303,6 +306,14 @@ defmodule Pleroma.NotificationTest do
assert {:ok, []} == Notification.create_notifications(status)
end
test "it disables notifications from people who are invisible" do
author = insert(:user, invisible: true)
user = insert(:user)
{:ok, status} = CommonAPI.post(author, %{status: "hey @#{user.nickname}"})
refute Notification.create_notification(status, user)
end
end
describe "follow / follow_request notifications" do
@ -335,9 +346,12 @@ defmodule Pleroma.NotificationTest do
# 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)
notification =
Repo.get(Notification, notification.id)
|> Repo.preload(:activity)
assert %{type: "follow"} =
NotificationView.render("show.json", notification: notification, for: followed_user)
end
test "it doesn't create a notification for follow-unfollow-follow chains" do

View file

@ -4,9 +4,7 @@
defmodule Pleroma.RepoTest do
use Pleroma.DataCase
import ExUnit.CaptureLog
import Pleroma.Factory
import Mock
alias Pleroma.User
@ -49,36 +47,4 @@ defmodule Pleroma.RepoTest do
assert Repo.get_assoc(token, :user) == {:error, :not_found}
end
end
describe "check_migrations_applied!" do
setup_with_mocks([
{Ecto.Migrator, [],
[
with_repo: fn repo, fun -> passthrough([repo, fun]) end,
migrations: fn Pleroma.Repo ->
[
{:up, 20_191_128_153_944, "fix_missing_following_count"},
{:up, 20_191_203_043_610, "create_report_notes"},
{:down, 20_191_220_174_645, "add_scopes_to_pleroma_feo_auth_records"}
]
end
]}
]) do
:ok
end
setup do: clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
test "raises if it detects unapplied migrations" do
assert_raise Pleroma.Repo.UnappliedMigrationsError, fn ->
capture_log(&Repo.check_migrations_applied!/0)
end
end
test "doesn't do anything if disabled" do
Pleroma.Config.put([:i_am_aware_this_may_cause_data_loss, :disable_migration_check], true)
assert :ok == Repo.check_migrations_applied!()
end
end
end

View file

@ -42,7 +42,8 @@ defmodule Pleroma.Factory do
user
| ap_id: User.ap_id(user),
follower_address: User.ap_followers(user),
following_address: User.ap_following(user)
following_address: User.ap_following(user),
raw_bio: user.bio
}
end
@ -396,24 +397,17 @@ defmodule Pleroma.Factory do
}
end
def config_factory do
def config_factory(attrs \\ %{}) do
%Pleroma.ConfigDB{
key:
sequence(:key, fn key ->
# Atom dynamic registration hack in tests
"some_key_#{key}"
|> String.to_atom()
|> inspect()
end),
group: ":pleroma",
key: sequence(:key, &String.to_atom("some_key_#{&1}")),
group: :pleroma,
value:
sequence(
:value,
fn key ->
:erlang.term_to_binary(%{another_key: "#{key}somevalue", another: "#{key}somevalue"})
end
&%{another_key: "#{&1}somevalue", another: "#{&1}somevalue"}
)
}
|> merge_attributes(attrs)
end
def marker_factory do

View file

@ -5,6 +5,8 @@
defmodule Mix.Tasks.Pleroma.ConfigTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.ConfigDB
alias Pleroma.Repo
@ -48,25 +50,21 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
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"})
refute ConfigDB.get_by_params(%{group: ":pleroma", key: ":database"})
assert ConfigDB.from_binary(config1.value) == [key: "value", key2: [Repo]]
assert ConfigDB.from_binary(config2.value) == [key: "value2", key2: ["Activity"]]
assert ConfigDB.from_binary(config3.value) == :info
assert config1.value == [key: "value", key2: [Repo]]
assert config2.value == [key: "value2", key2: ["Activity"]]
assert config3.value == :info
end
test "config table is truncated before migration" do
ConfigDB.create(%{
group: ":pleroma",
key: ":first_setting",
value: [key: "value", key2: ["Activity"]]
})
insert(:config, key: :first_setting, value: [key: "value", key2: ["Activity"]])
assert Repo.aggregate(ConfigDB, :count, :id) == 1
Mix.Tasks.Pleroma.Config.migrate_to_db("test/fixtures/config/temp.secret.exs")
config = ConfigDB.get_by_params(%{group: ":pleroma", key: ":first_setting"})
assert ConfigDB.from_binary(config.value) == [key: "value", key2: [Repo]]
assert config.value == [key: "value", key2: [Repo]]
end
end
@ -82,19 +80,9 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
end
test "settings are migrated to file and deleted from db", %{temp_file: temp_file} do
ConfigDB.create(%{
group: ":pleroma",
key: ":setting_first",
value: [key: "value", key2: ["Activity"]]
})
ConfigDB.create(%{
group: ":pleroma",
key: ":setting_second",
value: [key: "value2", key2: [Repo]]
})
ConfigDB.create(%{group: ":quack", key: ":level", value: :info})
insert(:config, key: :setting_first, value: [key: "value", key2: ["Activity"]])
insert(:config, key: :setting_second, value: [key: "value2", key2: [Repo]])
insert(:config, group: :quack, key: :level, value: :info)
Mix.Tasks.Pleroma.Config.run(["migrate_from_db", "--env", "temp", "-d"])
@ -107,9 +95,8 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
end
test "load a settings with large values and pass to file", %{temp_file: temp_file} do
ConfigDB.create(%{
group: ":pleroma",
key: ":instance",
insert(:config,
key: :instance,
value: [
name: "Pleroma",
email: "example@example.com",
@ -134,14 +121,11 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
federation_reachability_timeout_days: 7,
federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],
allow_relay: true,
rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
public: true,
quarantined_instances: [],
managed_config: true,
static_dir: "instance/static/",
allowed_post_formats: ["text/plain", "text/html", "text/markdown", "text/bbcode"],
mrf_transparency: true,
mrf_transparency_exclusions: [],
autofollowed_nicknames: [],
max_pinned_statuses: 1,
attachment_links: false,
@ -163,7 +147,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
extended_nickname_format: true,
multi_factor_authentication: [
totp: [
# digits 6 or 8
digits: 6,
period: 30
],
@ -173,7 +156,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
]
]
]
})
)
Mix.Tasks.Pleroma.Config.run(["migrate_from_db", "--env", "temp", "-d"])
@ -189,7 +172,7 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
end
assert file ==
"#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n mrf_transparency: true,\n mrf_transparency_exclusions: [],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n welcome_user_nickname: nil,\n welcome_message: nil,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
"#{header}\n\nconfig :pleroma, :instance,\n name: \"Pleroma\",\n email: \"example@example.com\",\n notify_email: \"noreply@example.com\",\n description: \"A Pleroma instance, an alternative fediverse server\",\n limit: 5000,\n chat_limit: 5000,\n remote_limit: 100_000,\n upload_limit: 16_000_000,\n avatar_upload_limit: 2_000_000,\n background_upload_limit: 4_000_000,\n banner_upload_limit: 4_000_000,\n poll_limits: %{\n max_expiration: 31_536_000,\n max_option_chars: 200,\n max_options: 20,\n min_expiration: 0\n },\n registrations_open: true,\n federating: true,\n federation_incoming_replies_max_depth: 100,\n federation_reachability_timeout_days: 7,\n federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],\n allow_relay: true,\n public: true,\n quarantined_instances: [],\n managed_config: true,\n static_dir: \"instance/static/\",\n allowed_post_formats: [\"text/plain\", \"text/html\", \"text/markdown\", \"text/bbcode\"],\n autofollowed_nicknames: [],\n max_pinned_statuses: 1,\n attachment_links: false,\n welcome_user_nickname: nil,\n welcome_message: nil,\n max_report_comment_size: 1000,\n safe_dm_mentions: false,\n healthcheck: false,\n remote_post_retention_days: 90,\n skip_thread_containment: true,\n limit_to_local_content: :unauthenticated,\n user_bio_length: 5000,\n user_name_length: 100,\n max_account_fields: 10,\n max_remote_account_fields: 20,\n account_field_name_length: 512,\n account_field_value_length: 2048,\n external_user_synchronization: true,\n extended_nickname_format: true,\n multi_factor_authentication: [\n totp: [digits: 6, period: 30],\n backup_codes: [number: 2, length: 6]\n ]\n"
end
end
end

View file

@ -4,6 +4,7 @@
defmodule Mix.Tasks.Pleroma.UserTest do
alias Pleroma.Activity
alias Pleroma.MFA
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
@ -278,6 +279,35 @@ defmodule Mix.Tasks.Pleroma.UserTest do
end
end
describe "running reset_mfa" do
test "disables MFA" do
user =
insert(:user,
multi_factor_authentication_settings: %MFA.Settings{
enabled: true,
totp: %MFA.Settings.TOTP{secret: "xx", confirmed: true}
}
)
Mix.Tasks.Pleroma.User.run(["reset_mfa", user.nickname])
assert_received {:mix_shell, :info, [message]}
assert message == "Multi-Factor Authentication disabled for #{user.nickname}"
assert %{enabled: false, totp: false} ==
user.nickname
|> User.get_cached_by_nickname()
|> MFA.mfa_settings()
end
test "no user to reset MFA" do
Mix.Tasks.Pleroma.User.run(["reset_password", "nonexistent"])
assert_received {:mix_shell, :error, [message]}
assert message =~ "No local user"
end
end
describe "running invite" do
test "invite token is generated" do
assert capture_io(fn ->

View file

@ -6,21 +6,17 @@ defmodule Pleroma.Upload.Filter.MogrifyTest do
use Pleroma.DataCase
import Mock
alias Pleroma.Config
alias Pleroma.Upload
alias Pleroma.Upload.Filter
setup do: clear_config([Filter.Mogrify, :args])
test "apply mogrify filter" do
Config.put([Filter.Mogrify, :args], [{"tint", "40"}])
clear_config(Filter.Mogrify, args: [{"tint", "40"}])
File.cp!(
"test/fixtures/image.jpg",
"test/fixtures/image_tmp.jpg"
)
upload = %Upload{
upload = %Pleroma.Upload{
name: "an… image.jpg",
content_type: "image/jpg",
path: Path.absname("test/fixtures/image_tmp.jpg"),

View file

@ -54,6 +54,7 @@ defmodule Pleroma.UploadTest do
%{
"name" => "image.jpg",
"type" => "Document",
"mediaType" => "image/jpeg",
"url" => [
%{
"href" => "http://localhost:4001/media/post-process-file.jpg",

View file

@ -1342,11 +1342,11 @@ defmodule Pleroma.UserTest do
end
end
describe "visible_for?/2" do
describe "visible_for/2" do
test "returns true when the account is itself" do
user = insert(:user, local: true)
assert User.visible_for?(user, user)
assert User.visible_for(user, user) == :visible
end
test "returns false when the account is unauthenticated and auth is required" do
@ -1355,14 +1355,14 @@ defmodule Pleroma.UserTest do
user = insert(:user, local: true, confirmation_pending: true)
other_user = insert(:user, local: true)
refute User.visible_for?(user, other_user)
refute User.visible_for(user, other_user) == :visible
end
test "returns true when the account is unauthenticated and auth is not required" do
user = insert(:user, local: true, confirmation_pending: true)
other_user = insert(:user, local: true)
assert User.visible_for?(user, other_user)
assert User.visible_for(user, other_user) == :visible
end
test "returns true when the account is unauthenticated and being viewed by a privileged account (auth required)" do
@ -1371,7 +1371,7 @@ defmodule Pleroma.UserTest do
user = insert(:user, local: true, confirmation_pending: true)
other_user = insert(:user, local: true, is_admin: true)
assert User.visible_for?(user, other_user)
assert User.visible_for(user, other_user) == :visible
end
end

View file

@ -574,7 +574,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute Enum.member?(activities, activity_four)
end
test "doesn't return announce activities concerning blocked users" do
test "doesn't return announce activities with blocked users in 'to'" do
blocker = insert(:user)
blockee = insert(:user)
friend = insert(:user)
@ -596,6 +596,39 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute Enum.member?(activities, activity_three.id)
end
test "doesn't return announce activities with blocked users in 'cc'" do
blocker = insert(:user)
blockee = insert(:user)
friend = insert(:user)
{:ok, _user_relationship} = User.block(blocker, blockee)
{:ok, activity_one} = CommonAPI.post(friend, %{status: "hey!"})
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
assert object = Pleroma.Object.normalize(activity_two)
data = %{
"actor" => friend.ap_id,
"object" => object.data["id"],
"context" => object.data["context"],
"type" => "Announce",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [blockee.ap_id]
}
assert {:ok, activity_three} = ActivityPub.insert(data)
activities =
ActivityPub.fetch_activities([], %{blocking_user: blocker})
|> Enum.map(fn act -> act.id end)
assert Enum.member?(activities, activity_one.id)
refute Enum.member?(activities, activity_two.id)
refute Enum.member?(activities, activity_three.id)
end
test "doesn't return activities from blocked domains" do
domain = "dogwhistle.zone"
domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
@ -1643,6 +1676,40 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert Enum.all?(visible_ids, &(&1 in activities_ids))
end
test "filtering out announces where the user is the actor of the announced message" do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
User.follow(user, other_user)
{:ok, post} = CommonAPI.post(user, %{status: "yo"})
{:ok, other_post} = CommonAPI.post(third_user, %{status: "yo"})
{:ok, _announce} = CommonAPI.repeat(post.id, other_user)
{:ok, _announce} = CommonAPI.repeat(post.id, third_user)
{:ok, announce} = CommonAPI.repeat(other_post.id, other_user)
params = %{
type: ["Announce"]
}
results =
[user.ap_id | User.following(user)]
|> ActivityPub.fetch_activities(params)
assert length(results) == 3
params = %{
type: ["Announce"],
announce_filtering_user: user
}
[result] =
[user.ap_id | User.following(user)]
|> ActivityPub.fetch_activities(params)
assert result.id == announce.id
end
end
describe "replies filtering with private messages" do
@ -1986,4 +2053,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end) =~ "Follower/Following counter update for #{user.ap_id} failed"
end
end
describe "global activity expiration" do
setup do: clear_config([:mrf, :policies])
test "creates an activity expiration for local Create activities" do
Pleroma.Config.put(
[:mrf, :policies],
Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
)
{:ok, %{id: id_create}} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
{:ok, _follow} = ActivityBuilder.insert(%{"type" => "Follow", "context" => "3hu"})
assert [%{activity_id: ^id_create}] = Pleroma.ActivityExpiration |> Repo.all()
end
end
end

View file

@ -0,0 +1,77 @@
# 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.MRF.ActivityExpirationPolicyTest do
use ExUnit.Case, async: true
alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
@id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
test "adds `expires_at` property" do
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
"type" => "Create",
"object" => %{"type" => "Note"}
})
assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
end
test "keeps existing `expires_at` if it less than the config setting" do
expires_at = NaiveDateTime.utc_now() |> Timex.shift(days: 1)
assert {:ok, %{"type" => "Create", "expires_at" => ^expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
"type" => "Create",
"expires_at" => expires_at,
"object" => %{"type" => "Note"}
})
end
test "overwrites existing `expires_at` if it greater than the config setting" do
too_distant_future = NaiveDateTime.utc_now() |> Timex.shift(years: 2)
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
"type" => "Create",
"expires_at" => too_distant_future,
"object" => %{"type" => "Note"}
})
assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
end
test "ignores remote activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
"type" => "Create",
"object" => %{"type" => "Note"}
})
refute Map.has_key?(activity, "expires_at")
end
test "ignores non-Create/Note activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
"type" => "Follow"
})
refute Map.has_key?(activity, "expires_at")
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
"type" => "Create",
"object" => %{"type" => "Cofe"}
})
refute Map.has_key?(activity, "expires_at")
end
end

View file

@ -8,6 +8,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
import Pleroma.Web.ActivityPub.MRF.HellthreadPolicy
alias Pleroma.Web.CommonAPI
setup do
user = insert(:user)
@ -20,7 +22,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
"https://instance.tld/users/user1",
"https://instance.tld/users/user2",
"https://instance.tld/users/user3"
]
],
"object" => %{
"type" => "Note"
}
}
[user: user, message: message]
@ -28,6 +33,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
setup do: clear_config(:mrf_hellthread)
test "doesn't die on chat messages" do
Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0})
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post_chat_message(user, other_user, "moin")
assert {:ok, _} = filter(activity.data)
end
describe "reject" do
test "rejects the message if the recipient count is above reject_threshold", %{
message: message

View file

@ -60,8 +60,6 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
end
describe "describe/0" do
setup do: clear_config([:instance, :rewrite_policy])
test "it works as expected with noop policy" do
expected = %{
mrf_policies: ["NoOpPolicy"],
@ -72,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
end
test "it works as expected with mock policy" do
Pleroma.Config.put([:instance, :rewrite_policy], [MRFModuleMock])
clear_config([:mrf, :policies], [MRFModuleMock])
expected = %{
mrf_policies: ["MRFModuleMock"],

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy
setup do: clear_config([:mrf_user_allowlist, :localhost])
setup do: clear_config(:mrf_user_allowlist)
test "pass filter if allow list is empty" do
actor = insert(:user)
@ -17,14 +17,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
test "pass filter if allow list isn't empty and user in allow list" do
actor = insert(:user)
Pleroma.Config.put([:mrf_user_allowlist, :localhost], [actor.ap_id, "test-ap-id"])
Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => [actor.ap_id, "test-ap-id"]})
message = %{"actor" => actor.ap_id}
assert UserAllowListPolicy.filter(message) == {:ok, message}
end
test "rejected if allow list isn't empty and user not in allow list" do
actor = insert(:user)
Pleroma.Config.put([:mrf_user_allowlist, :localhost], ["test-ap-id"])
Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => ["test-ap-id"]})
message = %{"actor" => actor.ap_id}
assert UserAllowListPolicy.filter(message) == {:reject, nil}
end

View file

@ -2,14 +2,264 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
use Pleroma.DataCase
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.ActivityPub.ObjectValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "attachments" do
test "works with honkerific attachments" do
attachment = %{
"mediaType" => "",
"name" => "",
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
"type" => "Document",
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
}
assert {:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "application/octet-stream"
end
test "it turns mastodon attachments into our attachments" do
attachment = %{
"url" =>
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
"type" => "Document",
"name" => nil,
"mediaType" => "image/jpeg"
}
{:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert [
%{
href:
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
type: "Link",
mediaType: "image/jpeg"
}
] = attachment.url
assert attachment.mediaType == "image/jpeg"
end
test "it handles our own uploads" do
user = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, attachment} =
attachment.data
|> AttachmentValidator.cast_and_validate()
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "image/jpeg"
end
end
describe "chat message create activities" do
test "it is invalid if the object already exists" do
user = insert(:user)
recipient = insert(:user)
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
object = Object.normalize(activity, false)
{:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
{:error, cng} = ObjectValidator.validate(create_data, [])
assert {:object, {"The object to create already exists", []}} in cng.errors
end
test "it is invalid if the object data has a different `to` or `actor` field" do
user = insert(:user)
recipient = insert(:user)
{:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey")
{:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id])
{:error, cng} = ObjectValidator.validate(create_data, [])
assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors
assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors
end
end
describe "chat messages" do
setup do
clear_config([:instance, :remote_limit])
user = insert(:user)
recipient = insert(:user, local: false)
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:")
%{user: user, recipient: recipient, valid_chat_message: valid_chat_message}
end
test "let's through some basic html", %{user: user, recipient: recipient} do
{:ok, valid_chat_message, _} =
Builder.chat_message(
user,
recipient.ap_id,
"hey <a href='https://example.org'>example</a> <script>alert('uguu')</script>"
)
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["content"] ==
"hey <a href=\"https://example.org\">example</a> alert(&#39;uguu&#39;)"
end
test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert Map.put(valid_chat_message, "attachment", nil) == object
end
test "validates for a basic object with an attachment", %{
valid_chat_message: valid_chat_message,
user: user
} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
valid_chat_message =
valid_chat_message
|> Map.put("attachment", attachment.data)
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["attachment"]
end
test "validates for a basic object with an attachment in an array", %{
valid_chat_message: valid_chat_message,
user: user
} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
valid_chat_message =
valid_chat_message
|> Map.put("attachment", [attachment.data])
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["attachment"]
end
test "validates for a basic object with an attachment but without content", %{
valid_chat_message: valid_chat_message,
user: user
} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
valid_chat_message =
valid_chat_message
|> Map.put("attachment", attachment.data)
|> Map.delete("content")
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["attachment"]
end
test "does not validate if the message has no content", %{
valid_chat_message: valid_chat_message
} do
contentless =
valid_chat_message
|> Map.delete("content")
refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, []))
end
test "does not validate if the message is longer than the remote_limit", %{
valid_chat_message: valid_chat_message
} do
Pleroma.Config.put([:instance, :remote_limit], 2)
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
end
test "does not validate if the recipient is blocking the actor", %{
valid_chat_message: valid_chat_message,
user: user,
recipient: recipient
} do
Pleroma.User.block(recipient, user)
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
end
test "does not validate if the actor or the recipient is not in our system", %{
valid_chat_message: valid_chat_message
} do
chat_message =
valid_chat_message
|> Map.put("actor", "https://raymoo.com/raymoo")
{:error, _} = ObjectValidator.validate(chat_message, [])
chat_message =
valid_chat_message
|> Map.put("to", ["https://raymoo.com/raymoo"])
{:error, _} = ObjectValidator.validate(chat_message, [])
end
test "does not validate for a message with multiple recipients", %{
valid_chat_message: valid_chat_message,
user: user,
recipient: recipient
} do
chat_message =
valid_chat_message
|> Map.put("to", [user.ap_id, recipient.ap_id])
assert {:error, _} = ObjectValidator.validate(chat_message, [])
end
test "does not validate if it doesn't concern local users" do
user = insert(:user, local: false)
recipient = insert(:user, local: false)
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey")
assert {:error, _} = ObjectValidator.validate(valid_chat_message, [])
end
end
describe "EmojiReacts" do
setup do
user = insert(:user)

View file

@ -1,5 +1,5 @@
defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTimeTest do
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTime
alias Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime
use Pleroma.DataCase
test "it validates an xsd:Datetime" do

View file

@ -1,5 +1,9 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ObjectValidators.Types.ObjectIDTest do
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.ObjectID
alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
use Pleroma.DataCase
@uris [

View file

@ -1,5 +1,5 @@
defmodule Pleroma.Web.ObjectValidators.Types.RecipientsTest do
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.Recipients
alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients
use Pleroma.DataCase
test "it asserts that all elements of the list are object ids" do

View file

@ -0,0 +1,30 @@
# 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.Types.SafeTextTest do
use Pleroma.DataCase
alias Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText
test "it lets normal text go through" do
text = "hey how are you"
assert {:ok, text} == SafeText.cast(text)
end
test "it removes html tags from text" do
text = "hey look xss <script>alert('foo')</script>"
assert {:ok, "hey look xss alert(&#39;foo&#39;)"} == SafeText.cast(text)
end
test "it keeps basic html tags" do
text = "hey <a href='http://gensokyo.2hu'>look</a> xss <script>alert('foo')</script>"
assert {:ok, "hey <a href=\"http://gensokyo.2hu\">look</a> xss alert(&#39;foo&#39;)"} ==
SafeText.cast(text)
end
test "errors for non-text" do
assert :error == SafeText.cast(1)
end
end

View file

@ -33,7 +33,10 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.SideEffects,
[],
[handle: fn o, m -> {:ok, o, m} end]
[
handle: fn o, m -> {:ok, o, m} end,
handle_after_transaction: fn m -> m end
]
},
{
Pleroma.Web.Federator,
@ -71,7 +74,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.SideEffects,
[],
[handle: fn o, m -> {:ok, o, m} end]
[handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
},
{
Pleroma.Web.Federator,
@ -110,7 +113,7 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.SideEffects,
[],
[handle: fn o, m -> {:ok, o, m} end]
[handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
},
{
Pleroma.Web.Federator,

View file

@ -7,6 +7,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
@ -20,6 +22,48 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
import Pleroma.Factory
import Mock
describe "handle_after_transaction" do
test "it streams out notifications and streams" do
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
assert [notification] = meta[:notifications]
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ -> nil end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
SideEffects.handle_after_transaction(meta)
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
assert called(Pleroma.Web.Push.send(notification))
end
end
end
describe "delete objects" do
setup do
user = insert(:user)
@ -290,6 +334,147 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
end
end
describe "creation of ChatMessages" do
test "notifies the recipient" do
author = insert(:user, local: false)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
assert Repo.get_by(Notification, user_id: recipient.id, activity_id: create_activity.id)
end
test "it streams the created ChatMessage" do
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
assert [_, _] = meta[:streamables]
end
test "it creates a Chat and MessageReferences for the local users and bumps the unread count, except for the author" do
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ -> nil end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
{:ok, _create_activity, meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
# The notification gets created
assert [notification] = meta[:notifications]
assert notification.activity_id == create_activity.id
# But it is not sent out
refute called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
refute called(Pleroma.Web.Push.send(notification))
# Same for the user chat stream
assert [{topics, _}, _] = meta[:streamables]
assert topics == ["user", "user:pleroma_chat"]
refute called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
chat = Chat.get(author.id, recipient.ap_id)
[cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all()
assert cm_ref.object.data["content"] == "hey"
assert cm_ref.unread == false
chat = Chat.get(recipient.id, author.ap_id)
[cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all()
assert cm_ref.object.data["content"] == "hey"
assert cm_ref.unread == true
end
end
test "it creates a Chat for the local users and bumps the unread count" do
author = insert(:user, local: false)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
# An object is created
assert Object.get_by_ap_id(chat_message_data["id"])
# The remote user won't get a chat
chat = Chat.get(author.id, recipient.ap_id)
refute chat
# The local user will get a chat
chat = Chat.get(recipient.id, author.ap_id)
assert chat
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
# Both users are local and get the chat
chat = Chat.get(author.id, recipient.ap_id)
assert chat
chat = Chat.get(recipient.id, author.ap_id)
assert chat
end
end
describe "announce objects" do
setup do
poster = insert(:user)

View file

@ -0,0 +1,153 @@
# 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.ChatMessageTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Transmogrifier
describe "handle_incoming" do
test "handles chonks with attachment" do
data = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"actor" => "https://honk.tedunangst.com/u/tedu",
"id" => "https://honk.tedunangst.com/u/tedu/honk/x6gt8X8PcyGkQcXxzg1T",
"object" => %{
"attachment" => [
%{
"mediaType" => "image/jpeg",
"name" => "298p3RG7j27tfsZ9RQ.jpg",
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
"type" => "Document",
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
}
],
"attributedTo" => "https://honk.tedunangst.com/u/tedu",
"content" => "",
"id" => "https://honk.tedunangst.com/u/tedu/chonk/26L4wl5yCbn4dr4y1b",
"published" => "2020-05-18T01:13:03Z",
"to" => [
"https://dontbulling.me/users/lain"
],
"type" => "ChatMessage"
},
"published" => "2020-05-18T01:13:03Z",
"to" => [
"https://dontbulling.me/users/lain"
],
"type" => "Create"
}
_user = insert(:user, ap_id: data["actor"])
_user = insert(:user, ap_id: hd(data["to"]))
assert {:ok, _activity} = Transmogrifier.handle_incoming(data)
end
test "it rejects messages that don't contain content" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
object =
data["object"]
|> Map.delete("content")
data =
data
|> Map.put("object", object)
_author =
insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
_recipient =
insert(:user,
ap_id: List.first(data["to"]),
local: true,
last_refreshed_at: DateTime.utc_now()
)
{:error, _} = Transmogrifier.handle_incoming(data)
end
test "it rejects messages that don't concern local users" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
_author =
insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
_recipient =
insert(:user,
ap_id: List.first(data["to"]),
local: false,
last_refreshed_at: DateTime.utc_now()
)
{:error, _} = Transmogrifier.handle_incoming(data)
end
test "it rejects messages where the `to` field of activity and object don't match" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
author = insert(:user, ap_id: data["actor"])
_recipient = insert(:user, ap_id: List.first(data["to"]))
data =
data
|> Map.put("to", author.ap_id)
assert match?({:error, _}, Transmogrifier.handle_incoming(data))
refute Object.get_by_ap_id(data["object"]["id"])
end
test "it fetches the actor if they aren't in our system" do
Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
|> Map.put("actor", "http://mastodon.example.org/users/admin")
|> put_in(["object", "actor"], "http://mastodon.example.org/users/admin")
_recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
{:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data)
end
test "it inserts it and creates a chat" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
author =
insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
{:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data)
assert activity.local == false
assert activity.actor == author.ap_id
assert activity.recipients == [recipient.ap_id, author.ap_id]
%Object{} = object = Object.get_by_ap_id(activity.data["object"])
assert object
assert object.data["content"] == "You expected a cute girl? Too bad. alert(&#39;XSS&#39;)"
assert match?(%{"firefox" => _}, object.data["emoji"])
refute Chat.get(author.id, recipient.ap_id)
assert Chat.get(recipient.id, author.ap_id)
end
end
end

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
@ -12,6 +13,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
import Pleroma.Factory
import Ecto.Query
import Mock
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -57,9 +59,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
activity = Repo.get(Activity, activity.id)
assert activity.data["state"] == "accept"
assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
[notification] = Notification.for_user(user)
assert notification.type == "follow"
end
test "with locked accounts, it does not create a follow or an accept" do
test "with locked accounts, it does create a Follow, but not an Accept" do
user = insert(:user, locked: true)
data =
@ -81,6 +86,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
|> Repo.all()
assert Enum.empty?(accepts)
[notification] = Notification.for_user(user)
assert notification.type == "follow_request"
end
test "it works for follow requests when you are already followed, creating a new accept activity" do
@ -144,6 +152,23 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
assert activity.data["state"] == "reject"
end
test "it rejects incoming follow requests if the following errors for some reason" do
user = insert(:user)
data =
File.read!("test/fixtures/mastodon-follow-activity.json")
|> Poison.decode!()
|> Map.put("object", user.ap_id)
with_mock Pleroma.User, [:passthrough], follow: fn _, _ -> {:error, :testing} end do
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
%Activity{} = activity = Activity.get_by_ap_id(id)
assert activity.data["state"] == "reject"
end
end
test "it works for incoming follow requests from hubzilla" do
user = insert(:user)

View file

@ -1571,9 +1571,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
assert modified_object["conversation"] ==
"tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
assert modified_object["context"] ==
"tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
end

View file

@ -337,7 +337,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
assert expected == json_response(conn, 200)
@ -614,7 +615,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => admin.ap_id
},
%{
"deactivated" => user.deactivated,
@ -625,7 +627,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => ["foo", "bar"],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
|> Enum.sort_by(& &1["nickname"])
@ -697,7 +700,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -722,7 +726,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -747,7 +752,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -772,7 +778,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -797,7 +804,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -822,7 +830,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -842,7 +851,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user2) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user2.name || user2.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user2.ap_id
}
]
}
@ -874,7 +884,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -899,7 +910,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
},
%{
"deactivated" => admin.deactivated,
@ -910,7 +922,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => admin.ap_id
},
%{
"deactivated" => false,
@ -921,7 +934,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => old_admin.ap_id
}
]
|> Enum.sort_by(& &1["nickname"])
@ -951,7 +965,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => admin.ap_id
},
%{
"deactivated" => false,
@ -962,7 +977,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => second_admin.ap_id
}
]
|> Enum.sort_by(& &1["nickname"])
@ -994,7 +1010,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(moderator.name || moderator.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => moderator.ap_id
}
]
}
@ -1019,7 +1036,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => ["first"],
"avatar" => User.avatar_url(user1) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user1.name || user1.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user1.ap_id
},
%{
"deactivated" => false,
@ -1030,7 +1048,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => ["second"],
"avatar" => User.avatar_url(user2) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user2.name || user2.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user2.ap_id
}
]
|> Enum.sort_by(& &1["nickname"])
@ -1069,7 +1088,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
]
}
@ -1093,7 +1113,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(admin) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(admin.name || admin.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => admin.ap_id
}
]
}
@ -1155,7 +1176,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
"tags" => [],
"avatar" => User.avatar_url(user) |> MediaProxy.url(),
"display_name" => HTML.strip_tags(user.name || user.nickname),
"confirmation_pending" => false
"confirmation_pending" => false,
"url" => user.ap_id
}
log_entry = Repo.one(ModerationLog)
@ -1577,14 +1599,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert patch(conn, "/api/pleroma/admin/users/#{user.nickname}/credentials", %{
"actor_type" => "Application"
})
|> json_response(200) == %{"errors" => %{"actor_type" => "is invalid"}}
|> json_response(400) == %{"errors" => %{"actor_type" => "is invalid"}}
end
test "update non existing user", %{conn: conn} do
assert patch(conn, "/api/pleroma/admin/users/non-existing/credentials", %{
"password" => "new_password"
})
|> json_response(200) == %{"error" => "Unable to update user."}
|> json_response(404) == %{"error" => "Not found"}
end
end

View file

@ -57,12 +57,12 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
]
} = json_response_and_validate_schema(conn, 200)
assert key1 == config1.key
assert key2 == config2.key
assert key1 == inspect(config1.key)
assert key2 == inspect(config2.key)
end
test "db is added to settings that are in db", %{conn: conn} do
_config = insert(:config, key: ":instance", value: ConfigDB.to_binary(name: "Some name"))
_config = insert(:config, key: ":instance", value: [name: "Some name"])
%{"configs" => configs} =
conn
@ -83,7 +83,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
config3 =
insert(:config,
value: ConfigDB.to_binary(k1: :v1, k2: :v2)
value: [k1: :v1, k2: :v2]
)
%{"configs" => configs} =
@ -93,42 +93,45 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
assert length(configs) > 3
saved_configs = [config1, config2, config3]
keys = Enum.map(saved_configs, &inspect(&1.key))
received_configs =
Enum.filter(configs, fn %{"group" => group, "key" => key} ->
group == ":pleroma" and key in [config1.key, config2.key, config3.key]
group == ":pleroma" and key in keys
end)
assert length(received_configs) == 3
db_keys =
config3.value
|> ConfigDB.from_binary()
|> Keyword.keys()
|> ConfigDB.convert()
|> ConfigDB.to_json_types()
keys = Enum.map(saved_configs -- [config3], &inspect(&1.key))
values = Enum.map(saved_configs, &ConfigDB.to_json_types(&1.value))
mapset_keys = MapSet.new(keys ++ db_keys)
Enum.each(received_configs, fn %{"value" => value, "db" => db} ->
assert db in [[config1.key], [config2.key], db_keys]
db = MapSet.new(db)
assert MapSet.subset?(db, mapset_keys)
assert value in [
ConfigDB.from_binary_with_convert(config1.value),
ConfigDB.from_binary_with_convert(config2.value),
ConfigDB.from_binary_with_convert(config3.value)
]
assert value in values
end)
end
test "subkeys with full update right merge", %{conn: conn} do
config1 =
insert(:config,
key: ":emoji",
value: ConfigDB.to_binary(groups: [a: 1, b: 2], key: [a: 1])
)
insert(:config,
key: ":emoji",
value: [groups: [a: 1, b: 2], key: [a: 1]]
)
config2 =
insert(:config,
key: ":assets",
value: ConfigDB.to_binary(mascots: [a: 1, b: 2], key: [a: 1])
)
insert(:config,
key: ":assets",
value: [mascots: [a: 1, b: 2], key: [a: 1]]
)
%{"configs" => configs} =
conn
@ -137,14 +140,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
vals =
Enum.filter(configs, fn %{"group" => group, "key" => key} ->
group == ":pleroma" and key in [config1.key, config2.key]
group == ":pleroma" and key in [":emoji", ":assets"]
end)
emoji = Enum.find(vals, fn %{"key" => key} -> key == ":emoji" end)
assets = Enum.find(vals, fn %{"key" => key} -> key == ":assets" end)
emoji_val = ConfigDB.transform_with_out_binary(emoji["value"])
assets_val = ConfigDB.transform_with_out_binary(assets["value"])
emoji_val = ConfigDB.to_elixir_types(emoji["value"])
assets_val = ConfigDB.to_elixir_types(assets["value"])
assert emoji_val[:groups] == [a: 1, b: 2]
assert assets_val[:mascots] == [a: 1, b: 2]
@ -277,7 +280,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
"value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]},
"db" => [":key5"]
}
]
],
"need_reboot" => false
}
assert Application.get_env(:pleroma, :key1) == "value1"
@ -357,7 +361,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
"value" => "https://hooks.slack.com/services/KEY",
"db" => [":webhook_url"]
}
]
],
"need_reboot" => false
}
assert Application.get_env(:quack, :level) == :info
@ -366,14 +371,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
end
test "saving config with partial update", %{conn: conn} do
config = insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: 2))
insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: 2))
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/config", %{
configs: [
%{group: config.group, key: config.key, value: [%{"tuple" => [":key3", 3]}]}
%{group: ":pleroma", key: ":key1", value: [%{"tuple" => [":key3", 3]}]}
]
})
@ -389,7 +394,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
],
"db" => [":key1", ":key2", ":key3"]
}
]
],
"need_reboot" => false
}
end
@ -500,8 +506,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
end
test "saving config with nested merge", %{conn: conn} do
config =
insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: [k1: 1, k2: 2]))
insert(:config, key: :key1, value: [key1: 1, key2: [k1: 1, k2: 2]])
conn =
conn
@ -509,8 +514,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|> post("/api/pleroma/admin/config", %{
configs: [
%{
group: config.group,
key: config.key,
group: ":pleroma",
key: ":key1",
value: [
%{"tuple" => [":key3", 3]},
%{
@ -548,7 +553,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
],
"db" => [":key1", ":key3", ":key2"]
}
]
],
"need_reboot" => false
}
end
@ -588,7 +594,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
],
"db" => [":ssl_options"]
}
]
],
"need_reboot" => false
}
assert Application.get_env(:pleroma, :key1) == [
@ -600,12 +607,11 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
backends = Application.get_env(:logger, :backends)
on_exit(fn -> Application.put_env(:logger, :backends, backends) end)
config =
insert(:config,
group: ":logger",
key: ":backends",
value: :erlang.term_to_binary([])
)
insert(:config,
group: :logger,
key: :backends,
value: []
)
Pleroma.Config.TransferTask.load_and_update_env([], false)
@ -617,8 +623,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|> post("/api/pleroma/admin/config", %{
configs: [
%{
group: config.group,
key: config.key,
group: ":logger",
key: ":backends",
value: [":console"]
}
]
@ -634,7 +640,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
],
"db" => [":backends"]
}
]
],
"need_reboot" => false
}
assert Application.get_env(:logger, :backends) == [
@ -643,19 +650,18 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
end
test "saving full setting if value is not keyword", %{conn: conn} do
config =
insert(:config,
group: ":tesla",
key: ":adapter",
value: :erlang.term_to_binary(Tesla.Adapter.Hackey)
)
insert(:config,
group: :tesla,
key: :adapter,
value: Tesla.Adapter.Hackey
)
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/config", %{
configs: [
%{group: config.group, key: config.key, value: "Tesla.Adapter.Httpc"}
%{group: ":tesla", key: ":adapter", value: "Tesla.Adapter.Httpc"}
]
})
@ -667,7 +673,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
"value" => "Tesla.Adapter.Httpc",
"db" => [":adapter"]
}
]
],
"need_reboot" => false
}
end
@ -677,13 +684,13 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
token: token
} do
ueberauth = Application.get_env(:ueberauth, Ueberauth)
config1 = insert(:config, key: ":keyaa1")
config2 = insert(:config, key: ":keyaa2")
insert(:config, key: :keyaa1)
insert(:config, key: :keyaa2)
config3 =
insert(:config,
group: ":ueberauth",
key: "Ueberauth"
group: :ueberauth,
key: Ueberauth
)
conn =
@ -691,8 +698,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/config", %{
configs: [
%{group: config1.group, key: config1.key, value: "another_value"},
%{group: config2.group, key: config2.key, value: "another_value"}
%{group: ":pleroma", key: ":keyaa1", value: "another_value"},
%{group: ":pleroma", key: ":keyaa2", value: "another_value"}
]
})
@ -700,22 +707,23 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
"configs" => [
%{
"group" => ":pleroma",
"key" => config1.key,
"key" => ":keyaa1",
"value" => "another_value",
"db" => [":keyaa1"]
},
%{
"group" => ":pleroma",
"key" => config2.key,
"key" => ":keyaa2",
"value" => "another_value",
"db" => [":keyaa2"]
}
]
],
"need_reboot" => false
}
assert Application.get_env(:pleroma, :keyaa1) == "another_value"
assert Application.get_env(:pleroma, :keyaa2) == "another_value"
assert Application.get_env(:ueberauth, Ueberauth) == ConfigDB.from_binary(config3.value)
assert Application.get_env(:ueberauth, Ueberauth) == config3.value
conn =
build_conn()
@ -724,7 +732,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/config", %{
configs: [
%{group: config2.group, key: config2.key, delete: true},
%{group: ":pleroma", key: ":keyaa2", delete: true},
%{
group: ":ueberauth",
key: "Ueberauth",
@ -734,7 +742,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
})
assert json_response_and_validate_schema(conn, 200) == %{
"configs" => []
"configs" => [],
"need_reboot" => false
}
assert Application.get_env(:ueberauth, Ueberauth) == ueberauth
@ -801,7 +810,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
":name"
]
}
]
],
"need_reboot" => false
}
end
@ -935,7 +945,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
],
"db" => [":http"]
}
]
],
"need_reboot" => false
}
end
@ -1000,7 +1011,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
],
"db" => [":key2", ":key3"]
}
]
],
"need_reboot" => false
}
end
@ -1027,7 +1039,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
"value" => %{"key" => "some_val"},
"db" => [":key1"]
}
]
],
"need_reboot" => false
}
end
@ -1077,16 +1090,16 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
":background"
]
}
]
],
"need_reboot" => false
}
end
test "delete part of settings by atom subkeys", %{conn: conn} do
config =
insert(:config,
key: ":keyaa1",
value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3")
)
insert(:config,
key: :keyaa1,
value: [subkey1: "val1", subkey2: "val2", subkey3: "val3"]
)
conn =
conn
@ -1094,8 +1107,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|> post("/api/pleroma/admin/config", %{
configs: [
%{
group: config.group,
key: config.key,
group: ":pleroma",
key: ":keyaa1",
subkeys: [":subkey1", ":subkey3"],
delete: true
}
@ -1110,7 +1123,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
"value" => [%{"tuple" => [":subkey2", "val2"]}],
"db" => [":subkey2"]
}
]
],
"need_reboot" => false
}
end
@ -1236,6 +1250,90 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == "value5"
assert Application.get_env(:not_real, :anything) == "value6"
end
test "args for Pleroma.Upload.Filter.Mogrify with custom tuples", %{conn: conn} do
clear_config(Pleroma.Upload.Filter.Mogrify)
assert conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/config", %{
configs: [
%{
group: ":pleroma",
key: "Pleroma.Upload.Filter.Mogrify",
value: [
%{"tuple" => [":args", ["auto-orient", "strip"]]}
]
}
]
})
|> json_response_and_validate_schema(200) == %{
"configs" => [
%{
"group" => ":pleroma",
"key" => "Pleroma.Upload.Filter.Mogrify",
"value" => [
%{"tuple" => [":args", ["auto-orient", "strip"]]}
],
"db" => [":args"]
}
],
"need_reboot" => false
}
assert Config.get(Pleroma.Upload.Filter.Mogrify) == [args: ["auto-orient", "strip"]]
assert conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/config", %{
configs: [
%{
group: ":pleroma",
key: "Pleroma.Upload.Filter.Mogrify",
value: [
%{
"tuple" => [
":args",
[
"auto-orient",
"strip",
"{\"implode\", \"1\"}",
"{\"resize\", \"3840x1080>\"}"
]
]
}
]
}
]
})
|> json_response(200) == %{
"configs" => [
%{
"group" => ":pleroma",
"key" => "Pleroma.Upload.Filter.Mogrify",
"value" => [
%{
"tuple" => [
":args",
[
"auto-orient",
"strip",
"{\"implode\", \"1\"}",
"{\"resize\", \"3840x1080>\"}"
]
]
}
],
"db" => [":args"]
}
],
"need_reboot" => false
}
assert Config.get(Pleroma.Upload.Filter.Mogrify) == [
args: ["auto-orient", "strip", {"implode", "1"}, {"resize", "3840x1080>"}]
]
end
end
describe "GET /api/pleroma/admin/config/descriptions" do

View file

@ -0,0 +1,145 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
import Mock
alias Pleroma.Web.MediaProxy
setup do: clear_config([:media_proxy])
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
Config.put([:media_proxy, :enabled], true)
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], MediaProxy.Invalidation.Script)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "GET /api/pleroma/admin/media_proxy_caches" do
test "shows banned MediaProxy URLs", %{conn: conn} do
MediaProxy.put_in_banned_urls([
"http://localhost:4001/media/a688346.jpg",
"http://localhost:4001/media/fb1f4d.jpg"
])
MediaProxy.put_in_banned_urls("http://localhost:4001/media/gb1f44.jpg")
MediaProxy.put_in_banned_urls("http://localhost:4001/media/tb13f47.jpg")
MediaProxy.put_in_banned_urls("http://localhost:4001/media/wb1f46.jpg")
response =
conn
|> get("/api/pleroma/admin/media_proxy_caches?page_size=2")
|> json_response_and_validate_schema(200)
assert response["urls"] == [
"http://localhost:4001/media/fb1f4d.jpg",
"http://localhost:4001/media/a688346.jpg"
]
response =
conn
|> get("/api/pleroma/admin/media_proxy_caches?page_size=2&page=2")
|> json_response_and_validate_schema(200)
assert response["urls"] == [
"http://localhost:4001/media/gb1f44.jpg",
"http://localhost:4001/media/tb13f47.jpg"
]
response =
conn
|> get("/api/pleroma/admin/media_proxy_caches?page_size=2&page=3")
|> json_response_and_validate_schema(200)
assert response["urls"] == ["http://localhost:4001/media/wb1f46.jpg"]
end
end
describe "POST /api/pleroma/admin/media_proxy_caches/delete" do
test "deleted MediaProxy URLs from banned", %{conn: conn} do
MediaProxy.put_in_banned_urls([
"http://localhost:4001/media/a688346.jpg",
"http://localhost:4001/media/fb1f4d.jpg"
])
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/media_proxy_caches/delete", %{
urls: ["http://localhost:4001/media/a688346.jpg"]
})
|> json_response_and_validate_schema(200)
assert response["urls"] == ["http://localhost:4001/media/a688346.jpg"]
refute MediaProxy.in_banned_urls("http://localhost:4001/media/a688346.jpg")
assert MediaProxy.in_banned_urls("http://localhost:4001/media/fb1f4d.jpg")
end
end
describe "POST /api/pleroma/admin/media_proxy_caches/purge" do
test "perform invalidates cache of MediaProxy", %{conn: conn} do
urls = [
"http://example.com/media/a688346.jpg",
"http://example.com/media/fb1f4d.jpg"
]
with_mocks [
{MediaProxy.Invalidation.Script, [],
[
purge: fn _, _ -> {"ok", 0} end
]}
] do
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/media_proxy_caches/purge", %{urls: urls, ban: false})
|> json_response_and_validate_schema(200)
assert response["urls"] == urls
refute MediaProxy.in_banned_urls("http://example.com/media/a688346.jpg")
refute MediaProxy.in_banned_urls("http://example.com/media/fb1f4d.jpg")
end
end
test "perform invalidates cache of MediaProxy and adds url to banned", %{conn: conn} do
urls = [
"http://example.com/media/a688346.jpg",
"http://example.com/media/fb1f4d.jpg"
]
with_mocks [{MediaProxy.Invalidation.Script, [], [purge: fn _, _ -> {"ok", 0} end]}] do
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/media_proxy_caches/purge", %{
urls: urls,
ban: true
})
|> json_response_and_validate_schema(200)
assert response["urls"] == urls
assert MediaProxy.in_banned_urls("http://example.com/media/a688346.jpg")
assert MediaProxy.in_banned_urls("http://example.com/media/fb1f4d.jpg")
end
end
end
end

View file

@ -5,7 +5,9 @@
defmodule Pleroma.Web.CommonAPITest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Conversation.Participation
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@ -23,6 +25,150 @@ defmodule Pleroma.Web.CommonAPITest do
setup do: clear_config([:instance, :limit])
setup do: clear_config([:instance, :max_pinned_statuses])
describe "posting chat messages" do
setup do: clear_config([:instance, :chat_limit])
test "it posts a chat message without content but with an attachment" do
author = insert(:user)
recipient = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: author.ap_id)
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ ->
nil
end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
nil,
media_id: upload.id
)
notification =
Notification.for_user_and_activity(recipient, activity)
|> Repo.preload(:activity)
assert called(Pleroma.Web.Push.send(notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
assert activity
end
end
test "it adds html newlines" do
author = insert(:user)
recipient = insert(:user)
other_user = insert(:user)
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
"uguu\nuguuu"
)
assert other_user.ap_id not in activity.recipients
object = Object.normalize(activity, false)
assert object.data["content"] == "uguu<br/>uguuu"
end
test "it linkifies" do
author = insert(:user)
recipient = insert(:user)
other_user = insert(:user)
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
"https://example.org is the site of @#{other_user.nickname} #2hu"
)
assert other_user.ap_id not in activity.recipients
object = Object.normalize(activity, false)
assert object.data["content"] ==
"<a href=\"https://example.org\" rel=\"ugc\">https://example.org</a> is the site of <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{
other_user.id
}\" href=\"#{other_user.ap_id}\" rel=\"ugc\">@<span>#{other_user.nickname}</span></a></span> <a class=\"hashtag\" data-tag=\"2hu\" href=\"http://localhost:4001/tag/2hu\">#2hu</a>"
end
test "it posts a chat message" do
author = insert(:user)
recipient = insert(:user)
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
"a test message <script>alert('uuu')</script> :firefox:"
)
assert activity.data["type"] == "Create"
assert activity.local
object = Object.normalize(activity)
assert object.data["type"] == "ChatMessage"
assert object.data["to"] == [recipient.ap_id]
assert object.data["content"] ==
"a test message &lt;script&gt;alert(&#39;uuu&#39;)&lt;/script&gt; :firefox:"
assert object.data["emoji"] == %{
"firefox" => "http://localhost:4001/emoji/Firefox.gif"
}
assert Chat.get(author.id, recipient.ap_id)
assert Chat.get(recipient.id, author.ap_id)
assert :ok == Pleroma.Web.Federator.perform(:publish, activity)
end
test "it reject messages over the local limit" do
Pleroma.Config.put([:instance, :chat_limit], 2)
author = insert(:user)
recipient = insert(:user)
{:error, message} =
CommonAPI.post_chat_message(
author,
recipient,
"123"
)
assert message == :content_too_long
end
end
describe "unblocking" do
test "it works even without an existing block activity" do
blocked = insert(:user)

View file

@ -23,7 +23,7 @@ defmodule Pleroma.Web.FederatorTest do
setup_all do: clear_config([:instance, :federating], true)
setup do: clear_config([:instance, :allow_relay])
setup do: clear_config([:instance, :rewrite_policy])
setup do: clear_config([:mrf, :policies])
setup do: clear_config([:mrf_keyword])
describe "Publish an activity" do
@ -158,7 +158,7 @@ defmodule Pleroma.Web.FederatorTest do
Pleroma.Config.put([:mrf_keyword, :reject], ["lain"])
Pleroma.Config.put(
[:instance, :rewrite_policy],
[:mrf, :policies],
Pleroma.Web.ActivityPub.MRF.KeywordPolicy
)

View file

@ -83,10 +83,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
test "updates the user's bio", %{conn: conn} do
user2 = insert(:user)
conn =
patch(conn, "/api/v1/accounts/update_credentials", %{
"note" => "I drink #cofe with @#{user2.nickname}\n\nsuya.."
})
raw_bio = "I drink #cofe with @#{user2.nickname}\n\nsuya.."
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
assert user_data = json_response_and_validate_schema(conn, 200)
@ -94,6 +93,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{
user2.id
}" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
assert user_data["source"]["note"] == raw_bio
user = Repo.get(User, user_data["id"])
assert user.raw_bio == raw_bio
end
test "updates the user's locking status", %{conn: conn} do
@ -395,4 +400,71 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|> json_response_and_validate_schema(403)
end
end
describe "Mark account as bot" do
setup do: oauth_access(["write:accounts"])
setup :request_content_type
test "changing actor_type to Service makes account a bot", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Service"})
|> json_response_and_validate_schema(200)
assert account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Service"
end
test "changing actor_type to Person makes account a human", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Person"})
|> json_response_and_validate_schema(200)
refute account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
test "changing actor_type to Application causes error", %{conn: conn} do
response =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Application"})
|> json_response_and_validate_schema(403)
assert %{"error" => "Invalid request"} == response
end
test "changing bot field to true changes actor_type to Service", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{bot: "true"})
|> json_response_and_validate_schema(200)
assert account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Service"
end
test "changing bot field to false changes actor_type to Person", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{bot: "false"})
|> json_response_and_validate_schema(200)
refute account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
test "actor_type field has a higher priority than bot", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{
actor_type: "Person",
bot: "true"
})
|> json_response_and_validate_schema(200)
refute account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
end
end

View file

@ -127,6 +127,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/accounts/internal.fetch")
|> json_response_and_validate_schema(404)
end
test "returns 404 for deactivated user", %{conn: conn} do
user = insert(:user, deactivated: true)
assert %{"error" => "Can't find user"} =
conn
|> get("/api/v1/accounts/#{user.id}")
|> json_response_and_validate_schema(:not_found)
end
end
defp local_and_remote_users do
@ -143,15 +152,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@ -173,8 +182,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Can't find user"
assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
"error" => "This API requires an authenticated user"
}
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
@ -203,8 +212,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Can't find user"
assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
"error" => "This API requires an authenticated user"
}
end
@ -249,6 +258,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert id == announce.id
end
test "deactivated user", %{conn: conn} do
user = insert(:user, deactivated: true)
assert %{"error" => "Can't find user"} ==
conn
|> get("/api/v1/accounts/#{user.id}/statuses")
|> json_response_and_validate_schema(:not_found)
end
test "returns 404 when user is invisible", %{conn: conn} do
user = insert(:user, %{invisible: true})
assert %{"error" => "Can't find user"} =
conn
|> get("/api/v1/accounts/#{user.id}")
|> json_response_and_validate_schema(404)
end
test "respects blocks", %{user: user_one, conn: conn} do
user_two = insert(:user)
user_three = insert(:user)
@ -350,9 +377,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert json_response_and_validate_schema(conn, 200) == []
end
test "gets an users media", %{conn: conn} do
test "gets an users media, excludes reblogs", %{conn: conn} do
note = insert(:note_activity)
user = User.get_cached_by_ap_id(note.data["actor"])
other_user = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
@ -364,6 +392,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
{:ok, %{id: image_post_id}} = CommonAPI.post(user, %{status: "cofe", media_ids: [media_id]})
{:ok, %{id: media_id}} = ActivityPub.upload(file, actor: other_user.ap_id)
{:ok, %{id: other_image_post_id}} =
CommonAPI.post(other_user, %{status: "cofe2", media_ids: [media_id]})
{:ok, _announce} = CommonAPI.repeat(other_image_post_id, user)
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?only_media=true")
assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200)
@ -422,15 +457,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@ -451,10 +486,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
@ -481,10 +516,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do

View file

@ -54,6 +54,27 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert response == expected_response
end
test "by default, does not contain pleroma:chat_mention" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
{:ok, _activity} = CommonAPI.post_chat_message(other_user, user, "hey")
result =
conn
|> get("/api/v1/notifications")
|> json_response_and_validate_schema(200)
assert [] == result
result =
conn
|> get("/api/v1/notifications?include_types[]=pleroma:chat_mention")
|> json_response_and_validate_schema(200)
assert [_] = result
end
test "getting a single notification" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
@ -292,6 +313,33 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert public_activity.id in activity_ids
refute unlisted_activity.id in activity_ids
end
test "doesn't return less than the requested amount of records when the user's reply is liked" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["read:notifications"])
{:ok, mention} =
CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "public"})
{:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:ok, reply} =
CommonAPI.post(other_user, %{
status: ".",
visibility: "public",
in_reply_to_status_id: activity.id
})
{:ok, _favorite} = CommonAPI.favorite(user, reply.id)
activity_ids =
conn
|> get("/api/v1/notifications?exclude_visibilities[]=direct&limit=2")
|> json_response_and_validate_schema(200)
|> Enum.map(& &1["status"]["id"])
assert [reply.id, mention.id] == activity_ids
end
end
test "filters notifications using exclude_types" do

View file

@ -111,6 +111,60 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
%{"name" => "prone", "url" => "#{Web.base_url()}/tag/prone"},
%{"name" => "AccidentProne", "url" => "#{Web.base_url()}/tag/AccidentProne"}
]
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "https://shpposter.club/users/shpuld"})}")
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "shpuld", "url" => "#{Web.base_url()}/tag/shpuld"}
]
results =
conn
|> get(
"/api/v2/search?#{
URI.encode_query(%{
q:
"https://www.washingtonpost.com/sports/2020/06/10/" <>
"nascar-ban-display-confederate-flag-all-events-properties/"
})
}"
)
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "nascar", "url" => "#{Web.base_url()}/tag/nascar"},
%{"name" => "ban", "url" => "#{Web.base_url()}/tag/ban"},
%{"name" => "display", "url" => "#{Web.base_url()}/tag/display"},
%{"name" => "confederate", "url" => "#{Web.base_url()}/tag/confederate"},
%{"name" => "flag", "url" => "#{Web.base_url()}/tag/flag"},
%{"name" => "all", "url" => "#{Web.base_url()}/tag/all"},
%{"name" => "events", "url" => "#{Web.base_url()}/tag/events"},
%{"name" => "properties", "url" => "#{Web.base_url()}/tag/properties"},
%{
"name" => "NascarBanDisplayConfederateFlagAllEventsProperties",
"url" =>
"#{Web.base_url()}/tag/NascarBanDisplayConfederateFlagAllEventsProperties"
}
]
end
test "supports pagination of hashtags search results", %{conn: conn} do
results =
conn
|> get(
"/api/v2/search?#{
URI.encode_query(%{q: "#some #text #with #hashtags", limit: 2, offset: 1})
}"
)
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "text", "url" => "#{Web.base_url()}/tag/text"},
%{"name" => "with", "url" => "#{Web.base_url()}/tag/with"}
]
end
test "excludes a blocked users from search results", %{conn: conn} do

View file

@ -1541,14 +1541,49 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
} = response
end
test "favorites paginate correctly" do
%{user: user, conn: conn} = oauth_access(["read:favourites"])
other_user = insert(:user)
{:ok, first_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, second_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, third_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, _first_favorite} = CommonAPI.favorite(user, third_post.id)
{:ok, _second_favorite} = CommonAPI.favorite(user, first_post.id)
{:ok, third_favorite} = CommonAPI.favorite(user, second_post.id)
result =
conn
|> get("/api/v1/favourites?limit=1")
assert [%{"id" => post_id}] = json_response_and_validate_schema(result, 200)
assert post_id == second_post.id
# Using the header for pagination works correctly
[next, _] = get_resp_header(result, "link") |> hd() |> String.split(", ")
[_, max_id] = Regex.run(~r/max_id=([^&]+)/, next)
assert max_id == third_favorite.id
result =
conn
|> get("/api/v1/favourites?max_id=#{max_id}")
assert [%{"id" => first_post_id}, %{"id" => third_post_id}] =
json_response_and_validate_schema(result, 200)
assert first_post_id == first_post.id
assert third_post_id == third_post.id
end
test "returns the favorites of a user" do
%{user: user, conn: conn} = oauth_access(["read:favourites"])
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, activity} = CommonAPI.post(other_user, %{status: "traps are happy"})
{:ok, activity} = CommonAPI.post(other_user, %{status: "trees are happy"})
{:ok, _} = CommonAPI.favorite(user, activity.id)
{:ok, last_like} = CommonAPI.favorite(user, activity.id)
first_conn = get(conn, "/api/v1/favourites")
@ -1566,9 +1601,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, _} = CommonAPI.favorite(user, second_activity.id)
last_like = status["id"]
second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like}")
second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like.id}")
assert [second_status] = json_response_and_validate_schema(second_conn, 200)
assert second_status["id"] == to_string(second_activity.id)

View file

@ -58,7 +58,9 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
result =
conn
|> post("/api/v1/push/subscription", %{
"data" => %{"alerts" => %{"mention" => true, "test" => true}},
"data" => %{
"alerts" => %{"mention" => true, "test" => true, "pleroma:chat_mention" => true}
},
"subscription" => @sub
})
|> json_response_and_validate_schema(200)
@ -66,7 +68,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
[subscription] = Pleroma.Repo.all(Subscription)
assert %{
"alerts" => %{"mention" => true},
"alerts" => %{"mention" => true, "pleroma:chat_mention" => true},
"endpoint" => subscription.endpoint,
"id" => to_string(subscription.id),
"server_key" => @server_key

View file

@ -33,7 +33,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
bio:
"<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"",
inserted_at: ~N[2017-08-15 15:47:06.597036],
emoji: %{"karjalanpiirakka" => "/file.png"}
emoji: %{"karjalanpiirakka" => "/file.png"},
raw_bio: "valid html. a\nb\nc\nd\nf '&<>\""
})
expected = %{
@ -72,6 +73,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
fields: []
},
pleroma: %{
ap_id: user.ap_id,
background_image: "https://example.com/images/asuka_hospital.png",
confirmation_pending: false,
tags: [],
@ -148,6 +150,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
fields: []
},
pleroma: %{
ap_id: user.ap_id,
background_image: nil,
confirmation_pending: false,
tags: [],

View file

@ -15,8 +15,17 @@ defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do
user = insert(:user)
other_user = insert(:user)
{:ok, parent} = CommonAPI.post(user, %{status: "parent"})
{:ok, activity} =
CommonAPI.post(user, %{status: "hey @#{other_user.nickname}", visibility: "direct"})
CommonAPI.post(user, %{
status: "hey @#{other_user.nickname}",
visibility: "direct",
in_reply_to_id: parent.id
})
{:ok, _reply_activity} =
CommonAPI.post(user, %{status: "hu", visibility: "public", in_reply_to_id: parent.id})
[participation] = Participation.for_user_with_last_activity_id(user)

View file

@ -6,7 +6,10 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
@ -14,6 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.NotificationView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
import Pleroma.Factory
defp test_notifications_rendering(notifications, user, expected_result) do
@ -31,6 +35,30 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
assert expected_result == result
end
test "ChatMessage notification" do
user = insert(:user)
recipient = insert(:user)
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "what's up my dude")
{:ok, [notification]} = Notification.create_notifications(activity)
object = Object.normalize(activity)
chat = Chat.get(recipient.id, user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false, is_muted: false},
type: "pleroma:chat_mention",
account: AccountView.render("show.json", %{user: user, for: recipient}),
chat_message: MessageReferenceView.render("show.json", %{chat_message_reference: cm_ref}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
test_notifications_rendering([notification], recipient, [expected])
end
test "Mention notification" do
user = insert(:user)
mentioned_user = insert(:user)
@ -40,7 +68,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "mention",
account:
AccountView.render("show.json", %{
@ -64,7 +92,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "favourite",
account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: create_activity, for: user}),
@ -84,7 +112,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "reblog",
account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: reblog_activity, for: user}),
@ -102,7 +130,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "follow",
account: AccountView.render("show.json", %{user: follower, for: followed}),
created_at: Utils.to_masto_date(notification.inserted_at)
@ -111,9 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], followed, [expected])
User.perform(:delete, follower)
notification = Notification |> Repo.one() |> Repo.preload(:activity)
test_notifications_rendering([notification], followed, [])
refute Repo.one(Notification)
end
@tag capture_log: true
@ -145,7 +171,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "move",
account: AccountView.render("show.json", %{user: old_user, for: follower}),
target: AccountView.render("show.json", %{user: new_user, for: follower}),
@ -170,7 +196,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "pleroma:emoji_reaction",
emoji: "",
account: AccountView.render("show.json", %{user: other_user, for: user}),
@ -180,4 +206,26 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], user, [expected])
end
test "muted notification" do
user = insert(:user)
another_user = insert(:user)
{:ok, _} = Pleroma.UserRelationship.create_mute(user, another_user)
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id)
{:ok, [notification]} = Notification.create_notifications(favorite_activity)
create_activity = Activity.get_by_id(create_activity.id)
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false, is_muted: true},
type: "favourite",
account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: create_activity, for: user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
test_notifications_rendering([notification], user, [expected])
end
end

View file

@ -0,0 +1,64 @@
defmodule Pleroma.Web.MediaProxy.InvalidationTest do
use ExUnit.Case
use Pleroma.Tests.Helpers
alias Pleroma.Config
alias Pleroma.Web.MediaProxy.Invalidation
import ExUnit.CaptureLog
import Mock
import Tesla.Mock
setup do: clear_config([:media_proxy])
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
describe "Invalidation.Http" do
test "perform request to clear cache" do
Config.put([:media_proxy, :enabled], false)
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], Invalidation.Http)
Config.put([Invalidation.Http], method: :purge, headers: [{"x-refresh", 1}])
image_url = "http://example.com/media/example.jpg"
Pleroma.Web.MediaProxy.put_in_banned_urls(image_url)
mock(fn
%{
method: :purge,
url: "http://example.com/media/example.jpg",
headers: [{"x-refresh", 1}]
} ->
%Tesla.Env{status: 200}
end)
assert capture_log(fn ->
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
assert Invalidation.purge([image_url]) == {:ok, [image_url]}
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
end) =~ "Running cache purge: [\"#{image_url}\"]"
end
end
describe "Invalidation.Script" do
test "run script to clear cache" do
Config.put([:media_proxy, :enabled], false)
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], Invalidation.Script)
Config.put([Invalidation.Script], script_path: "purge-nginx")
image_url = "http://example.com/media/example.jpg"
Pleroma.Web.MediaProxy.put_in_banned_urls(image_url)
with_mocks [{System, [], [cmd: fn _, _ -> {"ok", 0} end]}] do
assert capture_log(fn ->
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
assert Invalidation.purge([image_url]) == {:ok, [image_url]}
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
end) =~ "Running cache purge: [\"#{image_url}\"]"
end
end
end
end

View file

@ -5,6 +5,10 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
import ExUnit.CaptureLog
import Tesla.Mock
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "logs hasn't error message when request is valid" do
mock(fn
%{method: :purge, url: "http://example.com/media/example.jpg"} ->
@ -14,8 +18,8 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
refute capture_log(fn ->
assert Invalidation.Http.purge(
["http://example.com/media/example.jpg"],
%{}
) == {:ok, "success"}
[]
) == {:ok, ["http://example.com/media/example.jpg"]}
end) =~ "Error while cache purge"
end
@ -28,8 +32,8 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
assert capture_log(fn ->
assert Invalidation.Http.purge(
["http://example.com/media/example1.jpg"],
%{}
) == {:ok, "success"}
[]
) == {:ok, ["http://example.com/media/example1.jpg"]}
end) =~ "Error while cache purge: url - http://example.com/media/example1.jpg"
end
end

View file

@ -4,17 +4,23 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
import ExUnit.CaptureLog
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "it logger error when script not found" do
assert capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
%{script_path: "./example"}
) == {:error, "\"%ErlangError{original: :enoent}\""}
end) =~ "Error while cache purge: \"%ErlangError{original: :enoent}\""
script_path: "./example"
) == {:error, "%ErlangError{original: :enoent}"}
end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
%{}
) == {:error, "not found script path"}
capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
[]
) == {:error, "\"not found script path\""}
end)
end
end

View file

@ -10,6 +10,10 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
setup do: clear_config(:media_proxy)
setup do: clear_config([Pleroma.Web.Endpoint, :secret_key_base])
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "it returns 404 when MediaProxy disabled", %{conn: conn} do
Config.put([:media_proxy, :enabled], false)
@ -66,4 +70,16 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert %Plug.Conn{status: :success} = get(conn, url)
end
end
test "it returns 404 when url contains in banned_urls cache", %{conn: conn} do
Config.put([:media_proxy, :enabled], true)
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png")
Pleroma.Web.MediaProxy.put_in_banned_urls("https://google.fn/test.png")
with_mock Pleroma.ReverseProxy,
call: fn _conn, _url, _opts -> %Plug.Conn{status: :success} end do
assert %Plug.Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
end
end
end

View file

@ -67,10 +67,10 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "returns fieldsLimits field", %{conn: conn} do
Config.put([:instance, :max_account_fields], 10)
Config.put([:instance, :max_remote_account_fields], 15)
Config.put([:instance, :account_field_name_length], 255)
Config.put([:instance, :account_field_value_length], 2048)
clear_config([:instance, :max_account_fields], 10)
clear_config([:instance, :max_remote_account_fields], 15)
clear_config([:instance, :account_field_name_length], 255)
clear_config([:instance, :account_field_value_length], 2048)
response =
conn
@ -84,8 +84,7 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
option = Config.get([:instance, :safe_dm_mentions])
Config.put([:instance, :safe_dm_mentions], true)
clear_config([:instance, :safe_dm_mentions], true)
response =
conn
@ -102,8 +101,6 @@ defmodule Pleroma.Web.NodeInfoTest do
|> json_response(:ok)
refute "safe_dm_mentions" in response["metadata"]["features"]
Config.put([:instance, :safe_dm_mentions], option)
end
describe "`metadata/federation/enabled`" do
@ -145,7 +142,8 @@ defmodule Pleroma.Web.NodeInfoTest do
"shareable_emoji_packs",
"multifetch",
"pleroma_emoji_reactions",
"pleroma:api/v1/notifications:include_types_filter"
"pleroma:api/v1/notifications:include_types_filter",
"pleroma_chat_messages"
]
assert MapSet.subset?(
@ -155,14 +153,11 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "it shows MRF transparency data if enabled", %{conn: conn} do
config = Config.get([:instance, :rewrite_policy])
Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
option = Config.get([:instance, :mrf_transparency])
Config.put([:instance, :mrf_transparency], true)
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
clear_config([:mrf, :transparency], true)
simple_config = %{"reject" => ["example.com"]}
Config.put(:mrf_simple, simple_config)
clear_config(:mrf_simple, simple_config)
response =
conn
@ -170,26 +165,17 @@ defmodule Pleroma.Web.NodeInfoTest do
|> json_response(:ok)
assert response["metadata"]["federation"]["mrf_simple"] == simple_config
Config.put([:instance, :rewrite_policy], config)
Config.put([:instance, :mrf_transparency], option)
Config.put(:mrf_simple, %{})
end
test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do
config = Config.get([:instance, :rewrite_policy])
Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
option = Config.get([:instance, :mrf_transparency])
Config.put([:instance, :mrf_transparency], true)
exclusions = Config.get([:instance, :mrf_transparency_exclusions])
Config.put([:instance, :mrf_transparency_exclusions], ["other.site"])
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
clear_config([:mrf, :transparency], true)
clear_config([:mrf, :transparency_exclusions], ["other.site"])
simple_config = %{"reject" => ["example.com", "other.site"]}
expected_config = %{"reject" => ["example.com"]}
clear_config(:mrf_simple, simple_config)
Config.put(:mrf_simple, simple_config)
expected_config = %{"reject" => ["example.com"]}
response =
conn
@ -198,10 +184,5 @@ defmodule Pleroma.Web.NodeInfoTest do
assert response["metadata"]["federation"]["mrf_simple"] == expected_config
assert response["metadata"]["federation"]["exclusions"] == true
Config.put([:instance, :rewrite_policy], config)
Config.put([:instance, :mrf_transparency], option)
Config.put([:instance, :mrf_transparency_exclusions], exclusions)
Config.put(:mrf_simple, %{})
end
end

View file

@ -0,0 +1,336 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "POST /api/v1/pleroma/chats/:id/messages/:message_id/read" do
setup do: oauth_access(["write:chats"])
test "it marks one message as read", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
{:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
object = Object.normalize(create, false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == true
result =
conn
|> post("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}/read")
|> json_response_and_validate_schema(200)
assert result["unread"] == false
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == false
end
end
describe "POST /api/v1/pleroma/chats/:id/read" do
setup do: oauth_access(["write:chats"])
test "given a `last_read_id`, it marks everything until then as read", %{
conn: conn,
user: user
} do
other_user = insert(:user)
{:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
{:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
object = Object.normalize(create, false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == true
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/read", %{"last_read_id" => cm_ref.id})
|> json_response_and_validate_schema(200)
assert result["unread"] == 1
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == false
end
end
describe "POST /api/v1/pleroma/chats/:id/messages" do
setup do: oauth_access(["write:chats"])
test "it posts a message to the chat", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "Hallo!!"})
|> json_response_and_validate_schema(200)
assert result["content"] == "Hallo!!"
assert result["chat_id"] == chat.id |> to_string()
end
test "it fails if there is no content", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(400)
assert result
end
test "it works with an attachment", %{conn: conn, user: user} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{
"media_id" => to_string(upload.id)
})
|> json_response_and_validate_schema(200)
assert result["attachment"]
end
end
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
setup do: oauth_access(["write:chats"])
test "it deletes a message from the chat", %{conn: conn, user: user} do
recipient = insert(:user)
{:ok, message} =
CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend")
{:ok, other_message} = CommonAPI.post_chat_message(recipient, user, "nico nico ni")
object = Object.normalize(message, false)
chat = Chat.get(user.id, recipient.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
# Deleting your own message removes the message and the reference
result =
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == cm_ref.id
refute MessageReference.get_by_id(cm_ref.id)
assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id)
# Deleting other people's messages just removes the reference
object = Object.normalize(other_message, false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
result =
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == cm_ref.id
refute MessageReference.get_by_id(cm_ref.id)
assert Object.get_by_id(object.id)
end
end
describe "GET /api/v1/pleroma/chats/:id/messages" do
setup do: oauth_access(["read:chats"])
test "it paginates", %{conn: conn, user: user} do
recipient = insert(:user)
Enum.each(1..30, fn _ ->
{:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey")
end)
chat = Chat.get(user.id, recipient.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(200)
assert length(result) == 20
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}")
|> json_response_and_validate_schema(200)
assert length(result) == 10
end
test "it returns the messages for a given chat", %{conn: conn, user: user} do
other_user = insert(:user)
third_user = insert(:user)
{:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey")
{:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey")
{:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?")
{:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?")
chat = Chat.get(user.id, other_user.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(200)
result
|> Enum.each(fn message ->
assert message["chat_id"] == chat.id |> to_string()
end)
assert length(result) == 3
# Trying to get the chat of a different user
result =
conn
|> assign(:user, other_user)
|> get("/api/v1/pleroma/chats/#{chat.id}/messages")
assert result |> json_response(404)
end
end
describe "POST /api/v1/pleroma/chats/by-account-id/:id" do
setup do: oauth_access(["write:chats"])
test "it creates or returns a chat", %{conn: conn} do
other_user = insert(:user)
result =
conn
|> post("/api/v1/pleroma/chats/by-account-id/#{other_user.id}")
|> json_response_and_validate_schema(200)
assert result["id"]
end
end
describe "GET /api/v1/pleroma/chats/:id" do
setup do: oauth_access(["read:chats"])
test "it returns a chat", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == to_string(chat.id)
end
end
describe "GET /api/v1/pleroma/chats" do
setup do: oauth_access(["read:chats"])
test "it does not return chats with users you blocked", %{conn: conn, user: user} do
recipient = insert(:user)
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
assert length(result) == 1
User.block(user, recipient)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
assert length(result) == 0
end
test "it returns all chats", %{conn: conn, user: user} do
Enum.each(1..30, fn _ ->
recipient = insert(:user)
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
end)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
assert length(result) == 30
end
test "it return a list of chats the current user is participating in, in descending order of updates",
%{conn: conn, user: user} do
har = insert(:user)
jafnhar = insert(:user)
tridi = insert(:user)
{:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id)
:timer.sleep(1000)
{:ok, _chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
:timer.sleep(1000)
{:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id)
:timer.sleep(1000)
# bump the second one
{:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
ids = Enum.map(result, & &1["id"])
assert ids == [
chat_2.id |> to_string(),
chat_3.id |> to_string(),
chat_1.id |> to_string()
]
end
end
end

View file

@ -30,15 +30,55 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
test "GET /api/pleroma/emoji/packs", %{conn: conn} do
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
shared = resp["test_pack"]
assert shared["files"] == %{"blank" => "blank.png"}
assert resp["count"] == 3
assert resp["packs"]
|> Map.keys()
|> length() == 3
shared = resp["packs"]["test_pack"]
assert shared["files"] == %{"blank" => "blank.png", "blank2" => "blank2.png"}
assert Map.has_key?(shared["pack"], "download-sha256")
assert shared["pack"]["can-download"]
assert shared["pack"]["share-files"]
non_shared = resp["test_pack_nonshared"]
non_shared = resp["packs"]["test_pack_nonshared"]
assert non_shared["pack"]["share-files"] == false
assert non_shared["pack"]["can-download"] == false
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack1] = packs
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1&page=2")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack2] = packs
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1&page=3")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack3] = packs
assert [pack1, pack2, pack3] |> Enum.uniq() |> length() == 3
end
describe "GET /api/pleroma/emoji/packs/remote" do
@ -332,7 +372,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
Map.put(
new_data,
"fallback-src-sha256",
"74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF"
"1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D"
)
assert ctx[:admin_conn]
@ -398,7 +438,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
shortcode: "blank3",
filename: "dir/blank.png",
file: %Plug.Upload{
filename: "blank.png",
@ -407,7 +447,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
})
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank2" => "dir/blank.png"
"blank2" => "blank2.png",
"blank3" => "dir/blank.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
@ -431,7 +472,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
shortcode: "blank3",
filename: "dir/blank.png",
file: %Plug.Upload{
filename: "blank.png",
@ -440,7 +481,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
})
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank2" => "dir/blank.png"
"blank2" => "blank2.png",
"blank3" => "dir/blank.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
@ -448,14 +490,15 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
new_shortcode: "blank3",
shortcode: "blank3",
new_shortcode: "blank4",
new_filename: "dir_2/blank_3.png",
force: true
})
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank3" => "dir_2/blank_3.png"
"blank2" => "blank2.png",
"blank4" => "dir_2/blank_3.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
@ -481,7 +524,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/not_loaded/files", %{
shortcode: "blank2",
shortcode: "blank3",
filename: "dir/blank.png",
file: %Plug.Upload{
filename: "blank.png",
@ -535,7 +578,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
})
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank4" => "dir/blank.png"
"blank4" => "dir/blank.png",
"blank2" => "blank2.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
@ -549,7 +593,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
})
|> json_response_and_validate_schema(200) == %{
"blank3" => "dir_2/blank_3.png",
"blank" => "blank.png"
"blank" => "blank.png",
"blank2" => "blank2.png"
}
refute File.exists?("#{@emoji_path}/test_pack/dir/")
@ -557,7 +602,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3")
|> json_response_and_validate_schema(200) == %{"blank" => "blank.png"}
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank2" => "blank2.png"
}
refute File.exists?("#{@emoji_path}/test_pack/dir_2/")
@ -581,7 +629,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
})
|> json_response_and_validate_schema(200) == %{
"blank_url" => "blank_url.png",
"blank" => "blank.png"
"blank" => "blank.png",
"blank2" => "blank2.png"
}
assert File.exists?("#{@emoji_path}/test_pack/blank_url.png")
@ -602,15 +651,16 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
})
|> json_response_and_validate_schema(200) == %{
"shortcode" => "shortcode.png",
"blank" => "blank.png"
"blank" => "blank.png",
"blank2" => "blank2.png"
}
end
test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank2")
|> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "Emoji \"blank2\" does not exist"
"error" => "Emoji \"blank3\" does not exist"
}
end
@ -618,12 +668,12 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
new_shortcode: "blank3",
shortcode: "blank3",
new_shortcode: "blank4",
new_filename: "dir_2/blank_3.png"
})
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "Emoji \"blank2\" does not exist"
"error" => "Emoji \"blank3\" does not exist"
}
end
@ -651,7 +701,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{
"pack" => %{},
"files" => %{}
"files" => %{},
"files_count" => 0
}
assert admin_conn
@ -709,14 +760,14 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
refute Map.has_key?(resp, "test_pack_for_import")
refute Map.has_key?(resp["packs"], "test_pack_for_import")
assert admin_conn
|> get("/api/pleroma/emoji/packs/import")
|> json_response_and_validate_schema(200) == ["test_pack_for_import"]
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
assert resp["packs"]["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json")
@ -736,7 +787,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
assert resp["test_pack_for_import"]["files"] == %{
assert resp["packs"]["test_pack_for_import"]["files"] == %{
"blank" => "blank.png",
"blank2" => "blank.png",
"foo" => "blank.png"
@ -746,7 +797,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
describe "GET /api/pleroma/emoji/packs/:name" do
test "shows pack.json", %{conn: conn} do
assert %{
"files" => %{"blank" => "blank.png"},
"files" => files,
"files_count" => 2,
"pack" => %{
"can-download" => true,
"description" => "Test description",
@ -759,6 +811,28 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
conn
|> get("/api/pleroma/emoji/packs/test_pack")
|> json_response_and_validate_schema(200)
assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"}
assert %{
"files" => files,
"files_count" => 2
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack?page_size=1")
|> json_response_and_validate_schema(200)
assert files |> Map.keys() |> length() == 1
assert %{
"files" => files,
"files_count" => 2
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack?page_size=1&page=2")
|> json_response_and_validate_schema(200)
assert files |> Map.keys() |> length() == 1
end
test "non existing pack", %{conn: conn} do

View file

@ -0,0 +1,61 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceViewTest do
use Pleroma.DataCase
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
import Pleroma.Factory
test "it displays a chat message" do
user = insert(:user)
recipient = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "kippis :firefox:")
chat = Chat.get(user.id, recipient.ap_id)
object = Object.normalize(activity)
cm_ref = MessageReference.for_chat_and_object(chat, object)
chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
assert chat_message[:id] == cm_ref.id
assert chat_message[:content] == "kippis :firefox:"
assert chat_message[:account_id] == user.id
assert chat_message[:chat_id]
assert chat_message[:created_at]
assert chat_message[:unread] == false
assert match?([%{shortcode: "firefox"}], chat_message[:emojis])
{:ok, activity} = CommonAPI.post_chat_message(recipient, user, "gkgkgk", media_id: upload.id)
object = Object.normalize(activity)
cm_ref = MessageReference.for_chat_and_object(chat, object)
chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
assert chat_message_two[:id] == cm_ref.id
assert chat_message_two[:content] == "gkgkgk"
assert chat_message_two[:account_id] == recipient.id
assert chat_message_two[:chat_id] == chat_message[:chat_id]
assert chat_message_two[:attachment]
assert chat_message_two[:unread] == true
end
end

View file

@ -0,0 +1,48 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
use Pleroma.DataCase
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
alias Pleroma.Web.PleromaAPI.ChatView
import Pleroma.Factory
test "it represents a chat" do
user = insert(:user)
recipient = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
represented_chat = ChatView.render("show.json", chat: chat)
assert represented_chat == %{
id: "#{chat.id}",
account: AccountView.render("show.json", user: recipient),
unread: 0,
last_message: nil,
updated_at: Utils.to_masto_date(chat.updated_at)
}
{:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello")
chat_message = Object.normalize(chat_message_creation, false)
{:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
represented_chat = ChatView.render("show.json", chat: chat)
cm_ref = MessageReference.for_chat_and_object(chat, chat_message)
assert represented_chat[:last_message] ==
MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
end
end

View file

@ -5,8 +5,10 @@
defmodule Pleroma.Web.Push.ImplTest do
use Pleroma.DataCase
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Push.Impl
alias Pleroma.Web.Push.Subscription
@ -60,7 +62,8 @@ defmodule Pleroma.Web.Push.ImplTest do
notif =
insert(:notification,
user: user,
activity: activity
activity: activity,
type: "mention"
)
assert Impl.perform(notif) == {:ok, [:ok, :ok]}
@ -126,7 +129,7 @@ defmodule Pleroma.Web.Push.ImplTest do
) ==
"@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
assert Impl.format_title(%{activity: activity}) ==
assert Impl.format_title(%{activity: activity, type: "mention"}) ==
"New Mention"
end
@ -136,9 +139,10 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, _, _, activity} = CommonAPI.follow(user, other_user)
object = Object.normalize(activity, false)
assert Impl.format_body(%{activity: activity}, user, object) == "@Bob has followed you"
assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
"@Bob has followed you"
assert Impl.format_title(%{activity: activity}) ==
assert Impl.format_title(%{activity: activity, type: "follow"}) ==
"New Follower"
end
@ -157,7 +161,7 @@ defmodule Pleroma.Web.Push.ImplTest do
assert Impl.format_body(%{activity: announce_activity}, user, object) ==
"@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
assert Impl.format_title(%{activity: announce_activity}) ==
assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) ==
"New Repeat"
end
@ -173,9 +177,10 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.favorite(user, activity.id)
object = Object.normalize(activity)
assert Impl.format_body(%{activity: activity}, user, object) == "@Bob has favorited your post"
assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
"@Bob has favorited your post"
assert Impl.format_title(%{activity: activity}) ==
assert Impl.format_title(%{activity: activity, type: "favourite"}) ==
"New Favorite"
end
@ -193,6 +198,46 @@ defmodule Pleroma.Web.Push.ImplTest do
end
describe "build_content/3" do
test "builds content for chat messages" do
user = insert(:user)
recipient = insert(:user)
{:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey")
object = Object.normalize(chat, false)
[notification] = Notification.for_user(recipient)
res = Impl.build_content(notification, user, object)
assert res == %{
body: "@#{user.nickname}: hey",
title: "New Chat Message"
}
end
test "builds content for chat messages with no content" do
user = insert(:user)
recipient = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id)
object = Object.normalize(chat, false)
[notification] = Notification.for_user(recipient)
res = Impl.build_content(notification, user, object)
assert res == %{
body: "@#{user.nickname}: (Attachment)",
title: "New Chat Message"
}
end
test "hides details for notifications when privacy option enabled" do
user = insert(:user, nickname: "Bob")
user2 = insert(:user, nickname: "Rob", notification_settings: %{privacy_option: true})
@ -218,7 +263,7 @@ defmodule Pleroma.Web.Push.ImplTest do
status: "<Lorem ipsum dolor sit amet."
})
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "mention")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)
@ -229,7 +274,7 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.favorite(user, activity.id)
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "favourite")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)
@ -268,7 +313,7 @@ defmodule Pleroma.Web.Push.ImplTest do
"<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
})
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "mention")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)
@ -281,7 +326,7 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.favorite(user, activity.id)
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "favourite")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)

View file

@ -60,19 +60,19 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
test "doesn't just add a title" do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/non-ogp") ==
{:error,
"Found metadata was invalid or incomplete: %{url: \"http://example.com/non-ogp\"}"}
"Found metadata was invalid or incomplete: %{\"url\" => \"http://example.com/non-ogp\"}"}
end
test "parses ogp" do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/ogp") ==
{:ok,
%{
image: "http://ia.media-imdb.com/images/rock.jpg",
title: "The Rock",
description:
"image" => "http://ia.media-imdb.com/images/rock.jpg",
"title" => "The Rock",
"description" =>
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
type: "video.movie",
url: "http://example.com/ogp"
"type" => "video.movie",
"url" => "http://example.com/ogp"
}}
end
@ -80,12 +80,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/ogp-missing-title") ==
{:ok,
%{
image: "http://ia.media-imdb.com/images/rock.jpg",
title: "The Rock (1996)",
description:
"image" => "http://ia.media-imdb.com/images/rock.jpg",
"title" => "The Rock (1996)",
"description" =>
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
type: "video.movie",
url: "http://example.com/ogp-missing-title"
"type" => "video.movie",
"url" => "http://example.com/ogp-missing-title"
}}
end
@ -93,12 +93,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/twitter-card") ==
{:ok,
%{
card: "summary",
site: "@flickr",
image: "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
title: "Small Island Developing States Photo Submission",
description: "View the album on Flickr.",
url: "http://example.com/twitter-card"
"card" => "summary",
"site" => "@flickr",
"image" => "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
"title" => "Small Island Developing States Photo Submission",
"description" => "View the album on Flickr.",
"url" => "http://example.com/twitter-card"
}}
end
@ -106,27 +106,28 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/oembed") ==
{:ok,
%{
author_name: "bees",
author_url: "https://www.flickr.com/photos/bees/",
cache_age: 3600,
flickr_type: "photo",
height: "768",
html:
"author_name" => "bees",
"author_url" => "https://www.flickr.com/photos/bees/",
"cache_age" => 3600,
"flickr_type" => "photo",
"height" => "768",
"html" =>
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by bees, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>",
license: "All Rights Reserved",
license_id: 0,
provider_name: "Flickr",
provider_url: "https://www.flickr.com/",
thumbnail_height: 150,
thumbnail_url: "https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_q.jpg",
thumbnail_width: 150,
title: "Bacon Lollys",
type: "photo",
url: "http://example.com/oembed",
version: "1.0",
web_page: "https://www.flickr.com/photos/bees/2362225867/",
web_page_short_url: "https://flic.kr/p/4AK2sc",
width: "1024"
"license" => "All Rights Reserved",
"license_id" => 0,
"provider_name" => "Flickr",
"provider_url" => "https://www.flickr.com/",
"thumbnail_height" => 150,
"thumbnail_url" =>
"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_q.jpg",
"thumbnail_width" => 150,
"title" => "Bacon Lollys",
"type" => "photo",
"url" => "http://example.com/oembed",
"version" => "1.0",
"web_page" => "https://www.flickr.com/photos/bees/2362225867/",
"web_page_short_url" => "https://flic.kr/p/4AK2sc",
"width" => "1024"
}}
end

View file

@ -7,8 +7,7 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
alias Pleroma.Web.RichMedia.Parsers.TwitterCard
test "returns error when html not contains twitter card" do
assert TwitterCard.parse([{"html", [], [{"head", [], []}, {"body", [], []}]}], %{}) ==
{:error, "No twitter card metadata found"}
assert TwitterCard.parse([{"html", [], [{"head", [], []}, {"body", [], []}]}], %{}) == %{}
end
test "parses twitter card with only name attributes" do
@ -17,15 +16,21 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
"app:id:googleplay": "com.nytimes.android",
"app:name:googleplay": "NYTimes",
"app:url:googleplay": "nytimes://reader/id/100000006583622",
site: nil,
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database. - The New York Times"
}}
%{
"app:id:googleplay" => "com.nytimes.android",
"app:name:googleplay" => "NYTimes",
"app:url:googleplay" => "nytimes://reader/id/100000006583622",
"site" => nil,
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-facebookJumbo.jpg",
"type" => "article",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database."
}
end
test "parses twitter card with only property attributes" do
@ -34,19 +39,19 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
card: "summary_large_image",
description:
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
image:
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt": "",
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
url:
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
}}
%{
"card" => "summary_large_image",
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt" => "",
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
"type" => "article"
}
end
test "parses twitter card with name & property attributes" do
@ -55,23 +60,23 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
"app:id:googleplay": "com.nytimes.android",
"app:name:googleplay": "NYTimes",
"app:url:googleplay": "nytimes://reader/id/100000006583622",
card: "summary_large_image",
description:
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
image:
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt": "",
site: nil,
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
url:
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
}}
%{
"app:id:googleplay" => "com.nytimes.android",
"app:name:googleplay" => "NYTimes",
"app:url:googleplay" => "nytimes://reader/id/100000006583622",
"card" => "summary_large_image",
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt" => "",
"site" => nil,
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
"type" => "article"
}
end
test "respect only first title tag on the page" do
@ -84,14 +89,17 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
File.read!("test/fixtures/margaret-corbin-grave-west-point.html") |> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
site: "@atlasobscura",
title:
"The Missing Grave of Margaret Corbin, Revolutionary War Veteran - Atlas Obscura",
card: "summary_large_image",
image: image_path
}}
%{
"site" => "@atlasobscura",
"title" => "The Missing Grave of Margaret Corbin, Revolutionary War Veteran",
"card" => "summary_large_image",
"image" => image_path,
"description" =>
"She's the only woman veteran honored with a monument at West Point. But where was she buried?",
"site_name" => "Atlas Obscura",
"type" => "article",
"url" => "http://www.atlasobscura.com/articles/margaret-corbin-grave-west-point"
}
end
test "takes first founded title in html head if there is html markup error" do
@ -100,14 +108,20 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
site: nil,
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database. - The New York Times",
"app:id:googleplay": "com.nytimes.android",
"app:name:googleplay": "NYTimes",
"app:url:googleplay": "nytimes://reader/id/100000006583622"
}}
%{
"site" => nil,
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
"app:id:googleplay" => "com.nytimes.android",
"app:name:googleplay" => "NYTimes",
"app:url:googleplay" => "nytimes://reader/id/100000006583622",
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-facebookJumbo.jpg",
"type" => "article",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
}
end
end

View file

@ -7,11 +7,15 @@ defmodule Pleroma.Web.StreamerTest do
import Pleroma.Factory
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Conversation.Participation
alias Pleroma.List
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Streamer
alias Pleroma.Web.StreamerView
@moduletag needs_streamer: true, capture_log: true
@ -145,6 +149,57 @@ defmodule Pleroma.Web.StreamerTest do
refute Streamer.filtered_by_user?(user, notify)
end
test "it sends chat messages to the 'user:pleroma_chat' stream", %{user: user} do
other_user = insert(:user)
{:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
object = Object.normalize(create_activity, false)
chat = Chat.get(user.id, other_user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
cm_ref = %{cm_ref | chat: chat, object: object}
Streamer.get_topic_and_add_socket("user:pleroma_chat", user)
Streamer.stream("user:pleroma_chat", {user, cm_ref})
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
assert text =~ "hey cirno"
assert_receive {:text, ^text}
end
test "it sends chat messages to the 'user' stream", %{user: user} do
other_user = insert(:user)
{:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
object = Object.normalize(create_activity, false)
chat = Chat.get(user.id, other_user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
cm_ref = %{cm_ref | chat: chat, object: object}
Streamer.get_topic_and_add_socket("user", user)
Streamer.stream("user", {user, cm_ref})
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
assert text =~ "hey cirno"
assert_receive {:text, ^text}
end
test "it sends chat message notifications to the 'user:notification' stream", %{user: user} do
other_user = insert(:user)
{:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey")
notify =
Repo.get_by(Pleroma.Notification, user_id: user.id, activity_id: create_activity.id)
|> Repo.preload(:activity)
Streamer.get_topic_and_add_socket("user:notification", user)
Streamer.stream("user:notification", notify)
assert_receive {:render_with_user, _, _, ^notify}
refute Streamer.filtered_by_user?(user, notify)
end
test "it doesn't send notify to the 'user:notification' stream when a user is blocked", %{
user: user
} do

View file

@ -11,7 +11,9 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorkerTest do
import Pleroma.Factory
import ExUnit.CaptureLog
setup do: clear_config([ActivityExpiration, :enabled])
setup do
clear_config([ActivityExpiration, :enabled])
end
test "deletes an expiration activity" do
Pleroma.Config.put([ActivityExpiration, :enabled], true)
@ -36,6 +38,32 @@ defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorkerTest do
refute Pleroma.Repo.get(Pleroma.ActivityExpiration, expiration.id)
end
test "works with ActivityExpirationPolicy" do
Pleroma.Config.put([ActivityExpiration, :enabled], true)
clear_config([:mrf, :policies], Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy)
user = insert(:user)
days = Pleroma.Config.get([:mrf_activity_expiration, :days], 365)
{:ok, %{id: id} = activity} = Pleroma.Web.CommonAPI.post(user, %{status: "cofe"})
past_date =
NaiveDateTime.utc_now() |> Timex.shift(days: -days) |> NaiveDateTime.truncate(:second)
activity
|> Repo.preload(:expiration)
|> Map.get(:expiration)
|> Ecto.Changeset.change(%{scheduled_at: past_date})
|> Repo.update!()
Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker.perform(:ops, :pid)
assert [%{data: %{"type" => "Delete", "deleted_activity_id" => ^id}}] =
Pleroma.Repo.all(Pleroma.Activity)
end
describe "delete_activity/1" do
test "adds log message if activity isn't find" do
assert capture_log([level: :error], fn ->