Merge remote-tracking branch 'origin/develop' into review-pr-7933
This commit is contained in:
commit
465a81ecf2
115 changed files with 1733 additions and 546 deletions
|
|
@ -369,5 +369,39 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
MixTask.run(["filter_whitelisted", "--force"])
|
||||
assert config_records() == existing
|
||||
end
|
||||
|
||||
test "filters blacklisted settings" do
|
||||
clear_config(:database_config_whitelist, [{:pleroma}])
|
||||
clear_config(:database_config_blacklist, [{:pleroma, :logger}, {:blacklisted_group}])
|
||||
|
||||
insert_config_record(:pleroma, :logger, backends: :console)
|
||||
insert_config_record(:web_push_encryption, :vapid_details, a: 1)
|
||||
insert_config_record(:blacklisted_group, :anything, a: 1)
|
||||
|
||||
MixTask.run(["filter_blacklisted", "--force"])
|
||||
|
||||
assert [
|
||||
%ConfigDB{group: :pleroma, key: :instance},
|
||||
%ConfigDB{group: :pleroma, key: Pleroma.Captcha},
|
||||
%ConfigDB{group: :pleroma2, key: :key2},
|
||||
%ConfigDB{group: :web_push_encryption, key: :vapid_details}
|
||||
] = config_records()
|
||||
end
|
||||
|
||||
test "filter_blacklisted doesn't crash when blacklist is unset" do
|
||||
clear_config(:database_config_blacklist, nil)
|
||||
|
||||
existing = config_records()
|
||||
MixTask.run(["filter_blacklisted", "--force"])
|
||||
assert config_records() == existing
|
||||
end
|
||||
|
||||
test "filter_blacklisted doesn't crash when blacklist is disabled" do
|
||||
clear_config(:database_config_blacklist, false)
|
||||
|
||||
existing = config_records()
|
||||
MixTask.run(["filter_blacklisted", "--force"])
|
||||
assert config_records() == existing
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
39
test/pleroma/application_test.exs
Normal file
39
test/pleroma/application_test.exs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ApplicationTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
# TODO HACK: Temporarily disabled.
|
||||
# Currently causes a bunch of warnings about :warn being deprecated in logs.
|
||||
# ex_syslogger needs to either be updated upstream or forked.
|
||||
describe "config :pleroma, :logger, backends: [{:ex_syslogger, :ex_syslogger}]" do
|
||||
setup do
|
||||
clear_config([:logger], backends: [{:ex_syslogger, :ex_syslogger}])
|
||||
end
|
||||
|
||||
@tag :skip
|
||||
test "is handled" do
|
||||
log = capture_log(fn -> Pleroma.Application.configure_logger() end)
|
||||
|
||||
assert log =~
|
||||
"Configuration {:ex_syslogger, :ex_syslogger} is incorrect. Use {ExSyslogger, :ex_syslogger} instead!"
|
||||
|
||||
assert log =~ "Successfully added logger backend: {ExSyslogger, :ex_syslogger}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "config :pleroma, :logger, :backends: [:console]" do
|
||||
setup do
|
||||
clear_config([:logger], backends: [:console])
|
||||
end
|
||||
|
||||
test "emits a warning" do
|
||||
assert capture_log(fn -> Pleroma.Application.configure_logger() end) =~
|
||||
":console is no longer considered a backend and is enabled by default"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Config.DeprecationWarningsTest do
|
||||
use ExUnit.Case
|
||||
use ExUnit.Case, async: false
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
|
|
@ -388,4 +388,62 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
|
|||
end) =~
|
||||
"Your config is using the old namespace for the Shoutbox configuration."
|
||||
end
|
||||
|
||||
describe "check_deprecated_logger_config" do
|
||||
setup do
|
||||
initial_console = Application.get_env(:logger, :console, nil)
|
||||
initial_backends = Application.get_env(:logger, :backends, nil)
|
||||
|
||||
# NOTE: The Logger does not get reconfigured when running in the test env,
|
||||
# the added and on_exit removed settings below should have no effect besides
|
||||
# triggering the deprecation warnings
|
||||
Application.put_env(:logger, :console, level: :all)
|
||||
Application.put_env(:logger, :backends, [:console])
|
||||
|
||||
on_exit(fn ->
|
||||
if initial_console do
|
||||
Application.put_env(:logger, :console, initial_console)
|
||||
else
|
||||
Application.delete_env(:logger, :console)
|
||||
end
|
||||
|
||||
if initial_backends do
|
||||
Application.put_env(:logger, :backends, initial_backends)
|
||||
else
|
||||
Application.delete_env(:logger, :backends)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
test "warns on deprecated syntax" do
|
||||
log =
|
||||
capture_log(fn ->
|
||||
Pleroma.Config.DeprecationWarnings.check_deprecated_logger_config()
|
||||
end)
|
||||
|
||||
assert log =~
|
||||
"""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your configuration is using deprecated syntax for configuring backends of Elixir's logger.
|
||||
`config :logger, backends: [...]` is deprecated syntax due to changes in Elixir.
|
||||
Please update your configuration at your earliest convenience to use:
|
||||
`config :pleroma, :logger, backends: [...]`
|
||||
|
||||
Note: `:console` is no longer considered a backend and is used by default, you can disable it using:
|
||||
`config :logger, :default_handler: false`
|
||||
"""
|
||||
|
||||
assert log =~
|
||||
"""
|
||||
!!!DEPRECATION WARNING!!!
|
||||
Your configuration is using deprecated syntax for configuring logging to console.
|
||||
`config :logger, :console` is deprecated syntax due to changes in Elixir.
|
||||
Please update your configuration at your earliest convenience to use
|
||||
`config :logger, default_handler` and `config :logger, :default_formatter`.
|
||||
|
||||
Note: `:default_handler` is used only for the `level` setting. All other configurations go under
|
||||
`:default_formatter`. For more info visit: https://hexdocs.pm/logger/Logger.html#module-backends-and-backwards-compatibility
|
||||
"""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1988,14 +1988,26 @@ defmodule Pleroma.UserTest do
|
|||
end
|
||||
|
||||
describe "caching" do
|
||||
test "set_cache stores friends under the AP ID cache key" do
|
||||
user = insert(:user)
|
||||
|
||||
User.set_cache(user)
|
||||
|
||||
assert {:ok, []} = Cachex.get(:user_cache, "friends_ap_ids:#{user.ap_id}")
|
||||
assert {:ok, nil} = Cachex.get(:user_cache, "friends_ap_ids:#{user.nickname}")
|
||||
end
|
||||
|
||||
test "invalidate_cache works" do
|
||||
user = insert(:user)
|
||||
|
||||
User.set_cache(user)
|
||||
User.get_cached_by_id(user.id)
|
||||
User.invalidate_cache(user)
|
||||
|
||||
{:ok, nil} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
|
||||
{:ok, nil} = Cachex.get(:user_cache, "nickname:#{user.nickname}")
|
||||
{:ok, nil} = Cachex.get(:user_cache, "friends_ap_ids:#{user.ap_id}")
|
||||
{:ok, nil} = Cachex.get(:user_cache, "id:#{user.id}")
|
||||
end
|
||||
|
||||
test "User.delete() plugs any possible zombie objects" do
|
||||
|
|
|
|||
|
|
@ -220,5 +220,13 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
"acceptsChatMessages"
|
||||
)
|
||||
end
|
||||
|
||||
test "it returns false if chat is disabled" do
|
||||
clear_config([Pleroma.Chat, :enabled], false)
|
||||
user = insert(:user, accepts_chat_messages: true)
|
||||
|
||||
assert %{"capabilities" => %{"acceptsChatMessages" => false}} =
|
||||
UserView.render("user.json", user: user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -194,19 +194,9 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|
||||
setup do: clear_config(:configurable_from_database, true)
|
||||
|
||||
setup do:
|
||||
clear_config(:database_config_whitelist, [
|
||||
{:pleroma},
|
||||
{:http},
|
||||
{:idna},
|
||||
{:oban},
|
||||
{:tesla},
|
||||
{:ueberauth}
|
||||
])
|
||||
|
||||
test "create new config setting in db", %{conn: conn} do
|
||||
ueberauth = Application.get_env(:ueberauth, Ueberauth)
|
||||
on_exit(fn -> Application.put_env(:ueberauth, Ueberauth, ueberauth) end)
|
||||
aws = Application.get_env(:ex_aws, :s3)
|
||||
on_exit(fn -> Application.put_env(:ex_aws, :s3, aws) end)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -215,9 +205,9 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
configs: [
|
||||
%{group: ":pleroma", key: ":key1", value: "value1"},
|
||||
%{
|
||||
group: ":ueberauth",
|
||||
key: "Ueberauth",
|
||||
value: [%{"tuple" => [":consumer_secret", "aaaa"]}]
|
||||
group: ":cors_plug",
|
||||
key: ":key1",
|
||||
value: [%{"tuple" => [":key", "value"]}]
|
||||
},
|
||||
%{
|
||||
group: ":pleroma",
|
||||
|
|
@ -244,9 +234,9 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"}
|
||||
},
|
||||
%{
|
||||
group: ":idna",
|
||||
key: ":key5",
|
||||
value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}
|
||||
group: ":ex_aws",
|
||||
key: ":s3",
|
||||
value: %{"tuple" => ["access_key_id", "aaaa", []]}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -260,10 +250,10 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
"db" => [":key1"]
|
||||
},
|
||||
%{
|
||||
"group" => ":ueberauth",
|
||||
"key" => "Ueberauth",
|
||||
"value" => [%{"tuple" => [":consumer_secret", "aaaa"]}],
|
||||
"db" => [":consumer_secret"]
|
||||
"group" => ":cors_plug",
|
||||
"key" => ":key1",
|
||||
"value" => [%{"tuple" => [":key", "value"]}],
|
||||
"db" => [":key"]
|
||||
},
|
||||
%{
|
||||
"group" => ":pleroma",
|
||||
|
|
@ -293,10 +283,10 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
"db" => [":key4"]
|
||||
},
|
||||
%{
|
||||
"group" => ":idna",
|
||||
"key" => ":key5",
|
||||
"value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]},
|
||||
"db" => [":key5"]
|
||||
"group" => ":ex_aws",
|
||||
"key" => ":s3",
|
||||
"value" => %{"tuple" => ["access_key_id", "aaaa", []]},
|
||||
"db" => [":s3"]
|
||||
}
|
||||
],
|
||||
"need_reboot" => false
|
||||
|
|
@ -322,18 +312,19 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
nested_5: :upload
|
||||
}
|
||||
|
||||
assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
|
||||
assert Application.get_env(:cors_plug, :key1) == [key: "value"]
|
||||
assert Application.get_env(:ex_aws, :s3) == {"access_key_id", "aaaa", []}
|
||||
end
|
||||
|
||||
test "save configs setting without explicit key", %{conn: conn} do
|
||||
adapter = Application.get_env(:http, :adapter)
|
||||
send_user_agent = Application.get_env(:http, :send_user_agent)
|
||||
user_agent = Application.get_env(:http, :user_agent)
|
||||
mime = Application.get_env(:mime, :library)
|
||||
prometheus = Application.get_env(:prometheus, Pleroma.Web.Endpoint.MetricsExporter)
|
||||
web_push = Application.get_env(:web_push_encryption, :vapid_details)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:http, :adapter, adapter)
|
||||
Application.put_env(:http, :send_user_agent, send_user_agent)
|
||||
Application.put_env(:http, :user_agent, user_agent)
|
||||
Application.put_env(:mime, :library, mime)
|
||||
Application.put_env(:prometheus, Pleroma.Web.Endpoint.MetricsExporter, prometheus)
|
||||
Application.put_env(:web_push_encryption, :vapid_details, web_push)
|
||||
end)
|
||||
|
||||
conn =
|
||||
|
|
@ -342,19 +333,19 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{
|
||||
group: ":http",
|
||||
key: ":adapter",
|
||||
group: ":mime",
|
||||
key: ":library",
|
||||
value: [":someval"]
|
||||
},
|
||||
%{
|
||||
group: ":http",
|
||||
key: ":send_user_agent",
|
||||
group: ":prometheus",
|
||||
key: "Pleroma.Web.Endpoint.MetricsExporter",
|
||||
value: true
|
||||
},
|
||||
%{
|
||||
group: ":http",
|
||||
key: ":user_agent",
|
||||
value: [":default"]
|
||||
group: ":web_push_encryption",
|
||||
key: ":vapid_details",
|
||||
value: [":nope"]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -362,30 +353,30 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"configs" => [
|
||||
%{
|
||||
"group" => ":http",
|
||||
"key" => ":adapter",
|
||||
"group" => ":mime",
|
||||
"key" => ":library",
|
||||
"value" => [":someval"],
|
||||
"db" => [":adapter"]
|
||||
"db" => [":library"]
|
||||
},
|
||||
%{
|
||||
"group" => ":http",
|
||||
"key" => ":send_user_agent",
|
||||
"group" => ":prometheus",
|
||||
"key" => "Pleroma.Web.Endpoint.MetricsExporter",
|
||||
"value" => true,
|
||||
"db" => [":send_user_agent"]
|
||||
"db" => ["Pleroma.Web.Endpoint.MetricsExporter"]
|
||||
},
|
||||
%{
|
||||
"group" => ":http",
|
||||
"key" => ":user_agent",
|
||||
"value" => [":default"],
|
||||
"db" => [":user_agent"]
|
||||
"group" => ":web_push_encryption",
|
||||
"key" => ":vapid_details",
|
||||
"value" => [":nope"],
|
||||
"db" => [":vapid_details"]
|
||||
}
|
||||
],
|
||||
"need_reboot" => false
|
||||
}
|
||||
|
||||
assert Application.get_env(:http, :adapter) == [:someval]
|
||||
assert Application.get_env(:http, :send_user_agent) == true
|
||||
assert Application.get_env(:http, :user_agent) == [:default]
|
||||
assert Application.get_env(:mime, :library) == [:someval]
|
||||
assert Application.get_env(:prometheus, Pleroma.Web.Endpoint.MetricsExporter) == true
|
||||
assert Application.get_env(:web_push_encryption, :vapid_details) == [:nope]
|
||||
end
|
||||
|
||||
test "saving config with partial update", %{conn: conn} do
|
||||
|
|
@ -631,17 +622,17 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{group: ":tesla", key: ":adapter", value: "Tesla.Adapter.Httpc"}
|
||||
%{group: ":pleroma", key: ":key1", value: "Pleroma.Web.Endpoint"}
|
||||
]
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"configs" => [
|
||||
%{
|
||||
"group" => ":tesla",
|
||||
"key" => ":adapter",
|
||||
"value" => "Tesla.Adapter.Httpc",
|
||||
"db" => [":adapter"]
|
||||
"group" => ":pleroma",
|
||||
"key" => ":key1",
|
||||
"value" => "Pleroma.Web.Endpoint",
|
||||
"db" => [":key1"]
|
||||
}
|
||||
],
|
||||
"need_reboot" => false
|
||||
|
|
@ -653,14 +644,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
admin: admin,
|
||||
token: token
|
||||
} do
|
||||
ueberauth = Application.get_env(:ueberauth, Ueberauth)
|
||||
prometheus = Application.get_env(:prometheus, Pleroma.Web.Endpoint.MetricsExporter)
|
||||
insert(:config, key: :keyaa1)
|
||||
insert(:config, key: :keyaa2)
|
||||
|
||||
config3 =
|
||||
insert(:config,
|
||||
group: :ueberauth,
|
||||
key: Ueberauth
|
||||
group: :prometheus,
|
||||
key: Pleroma.Web.Endpoint.MetricsExporter
|
||||
)
|
||||
|
||||
conn =
|
||||
|
|
@ -693,7 +684,9 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|
||||
assert Application.get_env(:pleroma, :keyaa1) == "another_value"
|
||||
assert Application.get_env(:pleroma, :keyaa2) == "another_value"
|
||||
assert Application.get_env(:ueberauth, Ueberauth) == config3.value
|
||||
|
||||
assert Application.get_env(:prometheus, Pleroma.Web.Endpoint.MetricsExporter) ==
|
||||
config3.value
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|
|
@ -704,8 +697,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
configs: [
|
||||
%{group: ":pleroma", key: ":keyaa2", delete: true},
|
||||
%{
|
||||
group: ":ueberauth",
|
||||
key: "Ueberauth",
|
||||
group: ":prometheus",
|
||||
key: "Pleroma.Web.Endpoint.MetricsExporter",
|
||||
delete: true
|
||||
}
|
||||
]
|
||||
|
|
@ -716,7 +709,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
"need_reboot" => false
|
||||
}
|
||||
|
||||
assert Application.get_env(:ueberauth, Ueberauth) == ueberauth
|
||||
assert Application.get_env(:prometheus, Pleroma.Web.Endpoint.MetricsExporter) == prometheus
|
||||
refute Keyword.has_key?(Application.get_all_env(:pleroma), :keyaa2)
|
||||
end
|
||||
|
||||
|
|
@ -1021,8 +1014,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{
|
||||
"group" => ":oban",
|
||||
"key" => ":queues",
|
||||
"group" => ":pleroma",
|
||||
"key" => ":nonexist_oban_queues",
|
||||
"value" => [
|
||||
%{"tuple" => [":federator_incoming", 50]},
|
||||
%{"tuple" => [":federator_outgoing", 50]},
|
||||
|
|
@ -1039,8 +1032,8 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"configs" => [
|
||||
%{
|
||||
"group" => ":oban",
|
||||
"key" => ":queues",
|
||||
"group" => ":pleroma",
|
||||
"key" => ":nonexist_oban_queues",
|
||||
"value" => [
|
||||
%{"tuple" => [":federator_incoming", 50]},
|
||||
%{"tuple" => [":federator_outgoing", 50]},
|
||||
|
|
@ -1245,6 +1238,57 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
refute ConfigDB.get_by_group_and_key(:pleroma, :database_config_whitelist)
|
||||
end
|
||||
|
||||
test "doesn't set keys in the blacklist", %{conn: conn} do
|
||||
clear_config(:database_config_blacklist, [
|
||||
{:pleroma, :logger},
|
||||
{:pleroma, :key2},
|
||||
{:pleroma, Pleroma.Captcha.NotReal},
|
||||
{:blacklisted_group}
|
||||
])
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{group: ":pleroma", key: ":logger", value: "logconf"},
|
||||
%{group: ":pleroma", key: ":key1", value: "value1"},
|
||||
%{group: ":pleroma", key: ":key2", value: "value2"},
|
||||
%{group: ":not_real", key: ":anything", value: "value3"},
|
||||
%{group: ":blacklisted_group", key: ":anything", value: "value4"}
|
||||
]
|
||||
})
|
||||
|
||||
assert Application.get_env(:pleroma, :logger) == nil
|
||||
assert Application.get_env(:pleroma, :key1) == "value1"
|
||||
assert Application.get_env(:pleroma, :key2) == nil
|
||||
assert Application.get_env(:pleroma, Pleroma.Captcha.NotReal) == nil
|
||||
assert Application.get_env(:blacklisted_group, :anything) == nil
|
||||
end
|
||||
|
||||
test "doesn't allow updating the database_config_blacklist itself", %{conn: conn} do
|
||||
original_blacklist = Pleroma.Config.get(:database_config_blacklist)
|
||||
|
||||
refute ConfigDB.get_by_group_and_key(:pleroma, :database_config_blacklist)
|
||||
|
||||
%{"configs" => configs} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{
|
||||
group: ":pleroma",
|
||||
key: ":database_config_blacklist",
|
||||
value: [%{"tuple" => [":pleroma", ":key1"]}]
|
||||
}
|
||||
]
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert configs == []
|
||||
assert Pleroma.Config.get(:database_config_blacklist) == original_blacklist
|
||||
refute ConfigDB.get_by_group_and_key(:pleroma, :database_config_blacklist)
|
||||
end
|
||||
|
||||
test "args for Pleroma.Upload.Filter.Mogrify with custom tuples", %{conn: conn} do
|
||||
assert conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|
|
@ -1515,5 +1559,35 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|
||||
assert length(response) == length(Pleroma.Docs.JSON.compiled_descriptions())
|
||||
end
|
||||
|
||||
test "filters by database configuration blacklist and whitelist", %{conn: conn} do
|
||||
clear_config(:database_config_whitelist, [
|
||||
{:pleroma, :instance},
|
||||
{:pleroma, :activitypub},
|
||||
{:pleroma, Pleroma.Upload}
|
||||
])
|
||||
|
||||
clear_config(:database_config_blacklist, [
|
||||
{:pleroma, Pleroma.Upload}
|
||||
])
|
||||
|
||||
children =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/config/descriptions")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert length(children) == 2
|
||||
|
||||
assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 2
|
||||
|
||||
instance = Enum.find(children, fn c -> c["key"] == ":instance" end)
|
||||
assert instance["children"]
|
||||
|
||||
activitypub = Enum.find(children, fn c -> c["key"] == ":activitypub" end)
|
||||
assert activitypub["children"]
|
||||
|
||||
web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end)
|
||||
refute web_endpoint["children"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
59
test/pleroma/web/feed/feed_view_test.exs
Normal file
59
test/pleroma/web/feed/feed_view_test.exs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Feed.FeedViewTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.Web.Feed.FeedView
|
||||
|
||||
test "escapes fallback content" do
|
||||
data = %{
|
||||
"attachment" => [],
|
||||
"content" => "",
|
||||
"summary" => "<script>alert('feed')</script>"
|
||||
}
|
||||
|
||||
expected = "<script>alert('feed')</script>"
|
||||
|
||||
assert FeedView.atom_content_encoded(data) == expected
|
||||
assert FeedView.rss_content_encoded(data) == expected
|
||||
end
|
||||
|
||||
test "does not preview or classify sensitive attachments" do
|
||||
attachment = %{
|
||||
"name" => "spoiler",
|
||||
"url" => [%{"href" => "https://example.com/spoiler.png", "mediaType" => "image/png"}]
|
||||
}
|
||||
|
||||
data = %{
|
||||
"attachment" => [attachment],
|
||||
"content" => "content warning",
|
||||
"sensitive" => true
|
||||
}
|
||||
|
||||
assert FeedView.atom_content_encoded(data) == "content warning"
|
||||
assert FeedView.rss_content_encoded(data) == "content warning"
|
||||
assert FeedView.media_content_xml(attachment, true) == ""
|
||||
assert FeedView.media_content_xml(attachment, "true") == ""
|
||||
|
||||
media_content = FeedView.media_content_xml(attachment, false)
|
||||
assert media_content =~ "<media:description type=\"plain\">spoiler</media:description>"
|
||||
refute media_content =~ "media:rating"
|
||||
|
||||
assert FeedView.media_content_xml(Map.delete(attachment, "name"), false) ==
|
||||
~s(<media:content url="https://example.com/spoiler.png" type="image/png" medium="image"/>\n)
|
||||
end
|
||||
|
||||
test "does not treat a legacy false string as sensitive" do
|
||||
data = %{
|
||||
"attachment" => [
|
||||
%{"url" => [%{"href" => "https://example.com/image.png", "mediaType" => "image/png"}]}
|
||||
],
|
||||
"content" => "visible",
|
||||
"sensitive" => "false"
|
||||
}
|
||||
|
||||
assert FeedView.atom_content_encoded(data) =~ "<img"
|
||||
end
|
||||
end
|
||||
|
|
@ -30,9 +30,18 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
|||
%{
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
|
||||
"href" => "https://peertube.moe/video.mp4?first=one&second=two",
|
||||
"mediaType" => "video/mp4",
|
||||
"size" => "123",
|
||||
"type" => "Link"
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
"url" => [
|
||||
%{
|
||||
"href" => "https://peertube.moe/notes.pdf",
|
||||
"mediaType" => "application/pdf",
|
||||
"type" => "Link"
|
||||
}
|
||||
]
|
||||
|
|
@ -63,6 +72,15 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
|||
]
|
||||
|
||||
assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname]
|
||||
assert xpath(xml, ~x"//feed/entry/link[@rel='self']/@href"sl) == []
|
||||
assert length(xpath(xml, ~x"//feed/entry/link[@rel='alternate']/@href"sl)) == 2
|
||||
|
||||
assert xpath(xml, ~x"//feed/entry/link[@rel='enclosure']/@href"sl) == [
|
||||
"https://peertube.moe/video.mp4?first=one&second=two",
|
||||
"https://peertube.moe/notes.pdf"
|
||||
]
|
||||
|
||||
assert xpath(xml, ~x"//feed/entry/link[@rel='enclosure']/@length"sl) == ["123"]
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -96,17 +114,28 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
|||
%{
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4",
|
||||
"href" => "https://peertube.moe/video.mp4?first=one&second=two",
|
||||
"mediaType" => "video/mp4",
|
||||
"size" => "123",
|
||||
"type" => "Link"
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
"url" => [
|
||||
%{
|
||||
"href" => "https://peertube.moe/notes.pdf",
|
||||
"mediaType" => "application/pdf",
|
||||
"type" => "Link"
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
|
||||
edited_at = NaiveDateTime.add(object.updated_at, 60)
|
||||
|
||||
object
|
||||
|> Ecto.Changeset.change(data: object_data)
|
||||
|> Ecto.Changeset.change(data: object_data, updated_at: edited_at)
|
||||
|> Pleroma.Repo.update()
|
||||
|
||||
{:ok, activity2} = CommonAPI.post(user, %{status: "42 This is :moominmamma #PleromaArt"})
|
||||
|
|
@ -136,15 +165,27 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
|||
~c"yeah #PleromaArt"
|
||||
]
|
||||
|
||||
assert xpath(xml, ~x"//channel/item/guid/@isPermaLink"sl) == ["true", "true"]
|
||||
|
||||
assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [
|
||||
FeedView.to_rfc2822(activity2.data["published"]),
|
||||
FeedView.to_rfc2822(activity1.data["published"])
|
||||
]
|
||||
|
||||
assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [
|
||||
"https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4"
|
||||
assert xpath(xml, ~x"//channel/lastBuildDate/text()"s) ==
|
||||
FeedView.to_rfc2822(edited_at)
|
||||
|
||||
assert xpath(xml, ~x"//channel/item/media:content/@url"sl) == [
|
||||
"https://peertube.moe/video.mp4?first=one&second=two",
|
||||
"https://peertube.moe/notes.pdf"
|
||||
]
|
||||
|
||||
assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [
|
||||
"https://peertube.moe/video.mp4?first=one&second=two"
|
||||
]
|
||||
|
||||
assert xpath(xml, ~x"//channel/item/enclosure/@length"sl) == ["123"]
|
||||
|
||||
obj1 = Object.normalize(activity1, fetch: false)
|
||||
obj2 = Object.normalize(activity2, fetch: false)
|
||||
|
||||
|
|
@ -181,6 +222,90 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
|||
]
|
||||
end
|
||||
|
||||
test "does not fabricate lastBuildDate for an empty RSS feed", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/rss+xml")
|
||||
|> get(tag_feed_path(conn, :feed, "empty.rss"))
|
||||
|> response(200)
|
||||
|
||||
refute response =~ "<lastBuildDate>"
|
||||
end
|
||||
|
||||
test "provides a valid updated timestamp for an empty Atom feed", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/atom+xml")
|
||||
|> get(tag_feed_path(conn, :feed, "empty.atom"))
|
||||
|> response(200)
|
||||
|
||||
updated = response |> parse() |> xpath(~x"//feed/updated/text()"s)
|
||||
assert {:ok, _datetime, 0} = DateTime.from_iso8601(updated)
|
||||
end
|
||||
|
||||
test "escapes Atom IDs and tag feed self links", %{conn: conn} do
|
||||
user = insert(:user, local: false)
|
||||
object_id = "https://remote.example/object?first=one&second=two"
|
||||
|
||||
note =
|
||||
insert(:note,
|
||||
user: user,
|
||||
object_local: false,
|
||||
data: %{
|
||||
"content" => "remote #atomlink",
|
||||
"external_url" => object_id,
|
||||
"id" => object_id,
|
||||
"summary" => "",
|
||||
"tag" => ["atomlink"]
|
||||
}
|
||||
)
|
||||
|
||||
insert(:note_activity, user: user, note: note, local: false, object_local: false)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/atom+xml")
|
||||
|> get("/tags/atomlink.atom?third=three&fourth=four")
|
||||
|> response(200)
|
||||
|
||||
assert response =~ "https://remote.example/object?first=one&second=two"
|
||||
assert response =~ "third=three&fourth=four"
|
||||
|
||||
xml = parse(response)
|
||||
assert xpath(xml, ~x"//feed/entry/id/text()"s) == object_id
|
||||
end
|
||||
|
||||
test "escapes and round-trips RSS item permalinks", %{conn: conn} do
|
||||
user = insert(:user, local: false)
|
||||
permalink = "https://remote.example/post?first=one&second=two"
|
||||
|
||||
note =
|
||||
insert(:note,
|
||||
user: user,
|
||||
object_local: false,
|
||||
data: %{
|
||||
"content" => "remote #rsslink",
|
||||
"external_url" => permalink,
|
||||
"summary" => "",
|
||||
"tag" => ["rsslink"]
|
||||
}
|
||||
)
|
||||
|
||||
insert(:note_activity, user: user, note: note, local: false, object_local: false)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("accept", "application/rss+xml")
|
||||
|> get(tag_feed_path(conn, :feed, "rsslink.rss"))
|
||||
|> response(200)
|
||||
|
||||
assert response =~ "https://remote.example/post?first=one&second=two"
|
||||
|
||||
xml = parse(response)
|
||||
assert xpath(xml, ~x"//channel/item/guid/text()"s) == permalink
|
||||
assert xpath(xml, ~x"//channel/item/link/text()"s) == permalink
|
||||
end
|
||||
|
||||
describe "private instance" do
|
||||
setup do: clear_config([:instance, :public], false)
|
||||
|
||||
|
|
|
|||
|
|
@ -83,12 +83,12 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> get(user_feed_path(conn, :feed, user.nickname))
|
||||
|> response(200)
|
||||
|
||||
activity_titles =
|
||||
resp
|
||||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||
xml = SweetXml.parse(resp)
|
||||
activity_titles = SweetXml.xpath(xml, ~x"//entry/title/text()"l)
|
||||
|
||||
assert activity_titles == [~c"Won't, didn'...", ~c"2hu", ~c"2hu & as"]
|
||||
assert SweetXml.xpath(xml, ~x"//entry/link[@rel='self']/@href"sl) == []
|
||||
assert length(SweetXml.xpath(xml, ~x"//entry/link[@rel='alternate']/@href"sl)) == 3
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
|
|
@ -138,6 +138,107 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
assert activity_titles == [~c"2hu & as"]
|
||||
end
|
||||
|
||||
test "escapes query parameters in feed self links", %{conn: conn, user: user} do
|
||||
for format <- ~w[atom rss] do
|
||||
response =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/feed.#{format}?first=one&second=two")
|
||||
|> response(200)
|
||||
|
||||
assert response =~ "first=one&second=two"
|
||||
refute response =~ "first=one&second=two"
|
||||
end
|
||||
end
|
||||
|
||||
test "keeps fallback summary markup inert in rendered Atom content", %{
|
||||
conn: conn,
|
||||
object: object,
|
||||
user: user
|
||||
} do
|
||||
data =
|
||||
object.data
|
||||
|> Map.put("content", "")
|
||||
|> Map.put("summary", "<script>alert('feed')</script>")
|
||||
|
||||
object
|
||||
|> Ecto.Changeset.change(data: data)
|
||||
|> Pleroma.Repo.update!()
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/feed.atom")
|
||||
|> response(200)
|
||||
|
||||
assert response =~
|
||||
"&lt;script&gt;alert(&#39;feed&#39;)&lt;/script&gt;"
|
||||
|
||||
content_values = response |> parse() |> xpath(~x"//entry/content/text()"sl)
|
||||
|
||||
assert Enum.any?(content_values, fn content ->
|
||||
String.starts_with?(content, "<script>alert('feed')</script>")
|
||||
end)
|
||||
end
|
||||
|
||||
test "does not expose sensitive attachments as enclosures", %{
|
||||
conn: conn,
|
||||
object: object,
|
||||
user: user
|
||||
} do
|
||||
object
|
||||
|> Ecto.Changeset.change(data: Map.put(object.data, "sensitive", true))
|
||||
|> Pleroma.Repo.update!()
|
||||
|
||||
atom_response =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/feed.atom")
|
||||
|> response(200)
|
||||
|
||||
rss_response =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/feed.rss")
|
||||
|> response(200)
|
||||
|
||||
refute atom_response =~ "rel=\"enclosure\""
|
||||
refute rss_response =~ "<enclosure "
|
||||
end
|
||||
|
||||
test "uses enclosure fallbacks for user feeds", %{conn: conn, object: object, user: user} do
|
||||
attachment = %{"url" => [%{"href" => "https://example.com/file.bin"}]}
|
||||
|
||||
object
|
||||
|> Ecto.Changeset.change(data: Map.put(object.data, "attachment", [attachment]))
|
||||
|> Pleroma.Repo.update!()
|
||||
|
||||
atom_xml =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/feed.atom")
|
||||
|> response(200)
|
||||
|> parse()
|
||||
|
||||
assert xpath(atom_xml, ~x"//entry/link[@rel='enclosure']/@href"sl) == [
|
||||
"https://example.com/file.bin"
|
||||
]
|
||||
|
||||
assert xpath(atom_xml, ~x"//entry/link[@rel='enclosure']/@type"sl) == [
|
||||
"application/octet-stream"
|
||||
]
|
||||
|
||||
assert xpath(atom_xml, ~x"//entry/link[@rel='enclosure']/@length"sl) == []
|
||||
|
||||
rss_xml =
|
||||
conn
|
||||
|> get("/users/#{user.nickname}/feed.rss")
|
||||
|> response(200)
|
||||
|> parse()
|
||||
|
||||
assert xpath(rss_xml, ~x"//item/enclosure/@url"sl) == []
|
||||
assert xpath(rss_xml, ~x"//item/media:content/@url"sl) == ["https://example.com/file.bin"]
|
||||
|
||||
assert xpath(rss_xml, ~x"//item/media:content/@type"sl) == [
|
||||
"application/octet-stream"
|
||||
]
|
||||
end
|
||||
|
||||
test "returns 404 for a missing feed", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|
|
|
|||
|
|
@ -907,21 +907,53 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
{:ok, activity_test1} = CommonAPI.post(user, %{status: "#test #test1"})
|
||||
{:ok, activity_none} = CommonAPI.post(user, %{status: "#test #none"})
|
||||
|
||||
any_test = get(conn, "/api/v1/timelines/tag/test?any[]=test1")
|
||||
for hashtag_timeline_mode <- [:enabled, :disabled] do
|
||||
clear_config([:features, :improved_hashtag_timeline], hashtag_timeline_mode)
|
||||
|
||||
[status_none, status_test1, status_test] = json_response_and_validate_schema(any_test, :ok)
|
||||
any_test = get(conn, "/api/v1/timelines/tag/test?any[]=test1")
|
||||
|
||||
assert to_string(activity_test.id) == status_test["id"]
|
||||
assert to_string(activity_test1.id) == status_test1["id"]
|
||||
assert to_string(activity_none.id) == status_none["id"]
|
||||
[status_none, status_test1, status_test] =
|
||||
json_response_and_validate_schema(any_test, :ok)
|
||||
|
||||
restricted_test = get(conn, "/api/v1/timelines/tag/test?all[]=test1&none[]=none")
|
||||
assert to_string(activity_test.id) == status_test["id"]
|
||||
assert to_string(activity_test1.id) == status_test1["id"]
|
||||
assert to_string(activity_none.id) == status_none["id"]
|
||||
|
||||
assert [status_test1] == json_response_and_validate_schema(restricted_test, :ok)
|
||||
restricted_test = get(conn, "/api/v1/timelines/tag/test?all[]=test1&none[]=none")
|
||||
|
||||
all_test = get(conn, "/api/v1/timelines/tag/test?all[]=none")
|
||||
assert [status_test1] == json_response_and_validate_schema(restricted_test, :ok)
|
||||
|
||||
assert [status_none] == json_response_and_validate_schema(all_test, :ok)
|
||||
all_test = get(conn, "/api/v1/timelines/tag/test?all[]=none")
|
||||
|
||||
assert [status_none] == json_response_and_validate_schema(all_test, :ok)
|
||||
end
|
||||
end
|
||||
|
||||
test "multi-hashtag timeline pagination returns unique statuses", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity_one} = CommonAPI.post(user, %{status: "#test #test1"})
|
||||
{:ok, activity_two} = CommonAPI.post(user, %{status: "#test #test1"})
|
||||
{:ok, activity_three} = CommonAPI.post(user, %{status: "#test #test1"})
|
||||
|
||||
for hashtag_timeline_mode <- [:enabled, :disabled] do
|
||||
clear_config([:features, :improved_hashtag_timeline], hashtag_timeline_mode)
|
||||
|
||||
first_page =
|
||||
conn
|
||||
|> get("/api/v1/timelines/tag/test?any[]=test1&limit=2")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert Enum.map(first_page, & &1["id"]) ==
|
||||
Enum.map([activity_three, activity_two], &to_string(&1.id))
|
||||
|
||||
second_page =
|
||||
conn
|
||||
|> get("/api/v1/timelines/tag/test?any[]=test1&limit=2&max_id=#{activity_two.id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert Enum.map(second_page, & &1["id"]) == [to_string(activity_one.id)]
|
||||
end
|
||||
end
|
||||
|
||||
test "muted emotions", %{conn: conn} do
|
||||
|
|
|
|||
|
|
@ -114,8 +114,6 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do
|
|||
"quote_posting",
|
||||
"pleroma_emoji_reactions",
|
||||
"pleroma_custom_emoji_reactions",
|
||||
"pleroma_chat_messages",
|
||||
"pleroma:pin_chats",
|
||||
"pleroma:get:main/ostatus",
|
||||
"pleroma:group_actors",
|
||||
"pleroma:bookmark_folders",
|
||||
|
|
@ -128,6 +126,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do
|
|||
"gopher",
|
||||
"chat",
|
||||
"shout",
|
||||
"pleroma_chat_messages",
|
||||
"pleroma:pin_chats",
|
||||
"relay",
|
||||
"safe_dm_mentions",
|
||||
"exposable_reactions",
|
||||
|
|
@ -139,6 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do
|
|||
[:media_proxy, :enabled],
|
||||
[:gopher, :enabled],
|
||||
[:shout, :enabled],
|
||||
[Pleroma.Chat, :enabled],
|
||||
[:instance, :allow_relay],
|
||||
[:instance, :safe_dm_mentions],
|
||||
[:instance, :show_reactions],
|
||||
|
|
@ -443,6 +444,32 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "chat features" do
|
||||
test "advertises Shout without Chats" do
|
||||
clear_config([:shout, :enabled], true)
|
||||
clear_config([Pleroma.Chat, :enabled], false)
|
||||
|
||||
features = InstanceView.features()
|
||||
|
||||
assert "chat" in features
|
||||
assert "shout" in features
|
||||
refute "pleroma_chat_messages" in features
|
||||
refute "pleroma:pin_chats" in features
|
||||
end
|
||||
|
||||
test "advertises Chats without Shout" do
|
||||
clear_config([:shout, :enabled], false)
|
||||
clear_config([Pleroma.Chat, :enabled], true)
|
||||
|
||||
features = InstanceView.features()
|
||||
|
||||
refute "chat" in features
|
||||
refute "shout" in features
|
||||
assert "pleroma_chat_messages" in features
|
||||
assert "pleroma:pin_chats" in features
|
||||
end
|
||||
end
|
||||
|
||||
describe "federation/0" do
|
||||
setup do: clear_config([:mrf, :transparency], true)
|
||||
|
||||
|
|
|
|||
|
|
@ -546,6 +546,14 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
|
|||
account_ids = Enum.map(result, &get_in(&1, ["account", "id"]))
|
||||
assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id])
|
||||
end
|
||||
|
||||
test "it returns 404 when chats are disabled", %{conn: conn} do
|
||||
clear_config([Pleroma.Chat, :enabled], false)
|
||||
|
||||
conn
|
||||
|> get(unquote(tested_endpoint))
|
||||
|> json_response_and_validate_schema(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -122,16 +122,27 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||
|
||||
clear_config([:frontends, :pickable], ["#{name}/#{ref}"])
|
||||
path = "#{@dir}/frontends/#{name}/#{ref}"
|
||||
path2 = "#{@dir}/frontends/#{name}/#{ref}/packs/html"
|
||||
|
||||
Pleroma.Backports.mkdir_p!(path)
|
||||
File.write!("#{path}/index.html", "from frontend plug")
|
||||
|
||||
Pleroma.Backports.mkdir_p!(path2)
|
||||
File.write!("#{path2}/custom.html", "from frontend plug")
|
||||
|
||||
index =
|
||||
conn
|
||||
|> put_req_cookie("preferred_frontend", "#{name}/#{ref}")
|
||||
|> get("/")
|
||||
|
||||
assert html_response(index, 200) == "from frontend plug"
|
||||
|
||||
custom =
|
||||
conn
|
||||
|> put_req_cookie("preferred_frontend", "#{name}/#{ref}")
|
||||
|> get("/packs/html/custom.html")
|
||||
|
||||
assert html_response(custom, 200) == "from frontend plug"
|
||||
end
|
||||
|
||||
test "only returns content from pickable frontends", %{conn: conn} do
|
||||
|
|
|
|||
|
|
@ -61,6 +61,28 @@ defmodule Pleroma.Web.Plugs.InstanceStaticTest do
|
|||
File.write!(@dir <> "/static/kaniini.html", "<h1>rabbit hugs as a service</h1>")
|
||||
index = get(build_conn(), "/static/kaniini.html")
|
||||
assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
|
||||
|
||||
File.write!(@dir <> "/static/kaniini the bnuuy.html", "<h1>rabbit hugs as a service</h1>")
|
||||
index = get(build_conn(), "/static/kaniini%20the%20bnuuy.html")
|
||||
assert html_response(index, 200) == "<h1>rabbit hugs as a service</h1>"
|
||||
end
|
||||
|
||||
test "overrides /static/styles files with spaces in URL" do
|
||||
Pleroma.Backports.mkdir_p!(@dir <> "/static/styles")
|
||||
File.write(@dir <> "/static/styles/Redmond DX.iss", "overridden")
|
||||
|
||||
index = get(build_conn(), "/static/styles/Redmond%20DX.iss")
|
||||
assert index.status == 200
|
||||
assert index.resp_body == File.read!(@dir <> "/static/styles/Redmond DX.iss")
|
||||
assert index.halted == true
|
||||
end
|
||||
|
||||
test "serves fallback /static/styles files with spaces in URL" do
|
||||
index = get(build_conn(), "/static/styles/Redmond%20DX.iss")
|
||||
|
||||
assert index.status == 200
|
||||
assert index.resp_body == File.read!("priv/static/static/styles/Redmond DX.iss")
|
||||
assert index.halted == true
|
||||
end
|
||||
|
||||
test "does not sanitize dangerous files in general, as there can be html and javascript files legitimately in this folder" do
|
||||
|
|
@ -137,47 +159,4 @@ defmodule Pleroma.Web.Plugs.InstanceStaticTest do
|
|||
# It should be preserved because "image" is in the allowed_mime_types list
|
||||
assert content_type == "image/jpeg"
|
||||
end
|
||||
|
||||
describe "404s for missing files in static-only paths" do
|
||||
test "returns 404 for non-existent static-only JSON files" do
|
||||
conn = get(build_conn(), "/static/non-existent.json")
|
||||
|
||||
assert conn.status == 404
|
||||
assert ["application/json"] = get_resp_header(conn, "content-type")
|
||||
assert Jason.decode!(conn.resp_body) == %{"error" => "not found"}
|
||||
end
|
||||
|
||||
test "returns 404 for non-existent static-only non-JSON files" do
|
||||
conn = get(build_conn(), "/static/non-existent.txt")
|
||||
|
||||
assert conn.status == 404
|
||||
assert conn.resp_body == "Not found"
|
||||
assert ["text/plain"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
|
||||
test "returns 404 for non-existent .css files" do
|
||||
conn = get(build_conn(), "/static/non-existent.css")
|
||||
|
||||
assert conn.status == 404
|
||||
assert conn.resp_body == "Not found"
|
||||
# Verifies that we forced text/plain for the error body, even though the path was .css
|
||||
assert ["text/plain"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
|
||||
test "returns 404 for non-existent files without an extension" do
|
||||
conn = get(build_conn(), "/static/non-existent")
|
||||
|
||||
assert conn.status == 404
|
||||
assert conn.resp_body == "Not found"
|
||||
assert ["text/plain"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
|
||||
test "returns 200 (falls through to SPA) for non-static-only paths" do
|
||||
# /some-route is NOT in static_only_files, so it should still fall through to the SPA.
|
||||
conn = get(build_conn(), "/some-route")
|
||||
|
||||
assert conn.status == 200
|
||||
assert ["text/html; charset=utf-8"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44,6 +44,18 @@ defmodule Pleroma.Web.Plugs.OAuthPlugTest do
|
|||
assert conn.assigns[:user] == opts[:user]
|
||||
end
|
||||
|
||||
test "with a valid token, it does not preload the duplicate user association", %{
|
||||
conn: conn,
|
||||
token: token
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("authorization", "bearer #{token.token}")
|
||||
|> OAuthPlug.call(%{})
|
||||
|
||||
assert %Ecto.Association.NotLoaded{} = conn.assigns.token.user
|
||||
end
|
||||
|
||||
test "with valid token (downcase) in url parameters, it assigns the user", opts do
|
||||
conn =
|
||||
:get
|
||||
|
|
|
|||
49
test/pleroma/web/plugs/static_not_found_plug_test.exs
Normal file
49
test/pleroma/web/plugs/static_not_found_plug_test.exs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
defmodule Pleroma.Web.Plugs.StaticNotFoundPlugTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
describe "404s for missing files in static-only paths" do
|
||||
test "returns 404 for non-existent static-only JSON files" do
|
||||
conn = get(build_conn(), "/static/non-existent.json")
|
||||
|
||||
assert conn.status == 404
|
||||
assert ["application/json"] = get_resp_header(conn, "content-type")
|
||||
assert Jason.decode!(conn.resp_body) == %{"error" => "not found"}
|
||||
end
|
||||
|
||||
test "returns 404 for non-existent static-only non-JSON files" do
|
||||
conn = get(build_conn(), "/static/non-existent.txt")
|
||||
|
||||
assert conn.status == 404
|
||||
assert conn.resp_body == "Not found"
|
||||
assert ["text/plain"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
|
||||
test "returns 404 for non-existent .css files" do
|
||||
conn = get(build_conn(), "/static/non-existent.css")
|
||||
|
||||
assert conn.status == 404
|
||||
assert conn.resp_body == "Not found"
|
||||
# Verifies that we forced text/plain for the error body, even though the path was .css
|
||||
assert ["text/plain"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
|
||||
test "returns 404 for non-existent files without an extension" do
|
||||
conn = get(build_conn(), "/static/non-existent")
|
||||
|
||||
assert conn.status == 404
|
||||
assert conn.resp_body == "Not found"
|
||||
assert ["text/plain"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
|
||||
test "returns 200 (falls through to SPA) for non-static-only paths" do
|
||||
# /some-route is NOT in static_only_files, so it should still fall through to the SPA.
|
||||
conn = get(build_conn(), "/some-route")
|
||||
|
||||
assert conn.status == 200
|
||||
assert ["text/html; charset=utf-8"] = get_resp_header(conn, "content-type")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -475,6 +475,20 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert Streamer.filtered_by_user?(user, favorite_activity)
|
||||
end
|
||||
|
||||
test "it does not filter followed users on blocked domains", %{user: user} do
|
||||
followed =
|
||||
insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/friend"})
|
||||
|
||||
{:ok, user} = User.block_domain(user, "hecking-lewd-place.com")
|
||||
{:ok, activity} = CommonAPI.post(followed, %{status: "still a friend"})
|
||||
|
||||
assert Streamer.filtered_by_user?(user, activity)
|
||||
|
||||
{:ok, user, _followed} = User.follow(user, followed)
|
||||
|
||||
refute Streamer.filtered_by_user?(user, activity)
|
||||
end
|
||||
|
||||
test "it sends follow activities to the 'user:notification' stream", %{
|
||||
user: user,
|
||||
token: oauth_token
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ defmodule Pleroma.Workers.PublisherWorkerTest do
|
|||
use Pleroma.DataCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
|
||||
alias Pleroma.Instances
|
||||
alias Pleroma.Object
|
||||
|
|
@ -15,6 +15,8 @@ defmodule Pleroma.Workers.PublisherWorkerTest do
|
|||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.Federator
|
||||
alias Pleroma.Web.FederatorMock
|
||||
alias Pleroma.Workers.PublisherWorker
|
||||
|
||||
describe "Oban job priority:" do
|
||||
setup do
|
||||
|
|
@ -55,49 +57,80 @@ defmodule Pleroma.Workers.PublisherWorkerTest do
|
|||
end
|
||||
|
||||
test "marks server as unreachable only on final failure", %{activity: activity} do
|
||||
with_mock Pleroma.Web.Federator,
|
||||
perform: fn :publish_one, _params -> {:error, :connection_error} end do
|
||||
# First attempt
|
||||
job = %Oban.Job{
|
||||
args: %{
|
||||
"op" => "publish_one",
|
||||
"params" => %{
|
||||
"inbox" => "https://example.com/inbox",
|
||||
"activity_id" => activity.id
|
||||
}
|
||||
},
|
||||
attempt: 1,
|
||||
max_attempts: 5
|
||||
}
|
||||
expect(FederatorMock, :perform, 2, fn :publish_one, _params ->
|
||||
{:error, :connection_error}
|
||||
end)
|
||||
|
||||
assert {:error, :connection_error} = Pleroma.Workers.PublisherWorker.perform(job)
|
||||
assert Instances.reachable?("https://example.com/inbox")
|
||||
# First attempt
|
||||
job = %Oban.Job{
|
||||
args: %{
|
||||
"op" => "publish_one",
|
||||
"params" => %{
|
||||
"inbox" => "https://example.com/inbox",
|
||||
"activity_id" => activity.id
|
||||
}
|
||||
},
|
||||
attempt: 1,
|
||||
max_attempts: 5
|
||||
}
|
||||
|
||||
# Final attempt
|
||||
job = %{job | attempt: 5}
|
||||
assert {:error, :connection_error} = Pleroma.Workers.PublisherWorker.perform(job)
|
||||
refute Instances.reachable?("https://example.com/inbox")
|
||||
end
|
||||
assert {:error, :connection_error} = PublisherWorker.perform(job)
|
||||
assert Instances.reachable?("https://example.com/inbox")
|
||||
|
||||
# Final attempt
|
||||
job = %{job | attempt: 5}
|
||||
assert {:error, :connection_error} = PublisherWorker.perform(job)
|
||||
refute Instances.reachable?("https://example.com/inbox")
|
||||
end
|
||||
|
||||
test "does not mark server as unreachable on successful publish", %{activity: activity} do
|
||||
with_mock Pleroma.Web.Federator,
|
||||
perform: fn :publish_one, _params -> {:ok, %{status: 200}} end do
|
||||
job = %Oban.Job{
|
||||
args: %{
|
||||
"op" => "publish_one",
|
||||
"params" => %{
|
||||
"inbox" => "https://example.com/inbox",
|
||||
"activity_id" => activity.id
|
||||
}
|
||||
},
|
||||
attempt: 1,
|
||||
max_attempts: 5
|
||||
}
|
||||
expect(FederatorMock, :perform, fn :publish_one, _params -> {:ok, %{status: 200}} end)
|
||||
|
||||
assert :ok = Pleroma.Workers.PublisherWorker.perform(job)
|
||||
assert Instances.reachable?("https://example.com/inbox")
|
||||
end
|
||||
job = %Oban.Job{
|
||||
args: %{
|
||||
"op" => "publish_one",
|
||||
"params" => %{
|
||||
"inbox" => "https://example.com/inbox",
|
||||
"activity_id" => activity.id
|
||||
}
|
||||
},
|
||||
attempt: 1,
|
||||
max_attempts: 5
|
||||
}
|
||||
|
||||
assert :ok = PublisherWorker.perform(job)
|
||||
assert Instances.reachable?("https://example.com/inbox")
|
||||
end
|
||||
|
||||
test "does not create atoms from unexpected job params", %{activity: activity} do
|
||||
unknown_key = "unknown_#{System.unique_integer([:positive])}"
|
||||
|
||||
assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key) end
|
||||
|
||||
expect(FederatorMock, :perform, fn :publish_one, params ->
|
||||
assert params == %{
|
||||
inbox: "https://example.com/inbox",
|
||||
activity_id: activity.id
|
||||
}
|
||||
|
||||
{:ok, %{status: 200}}
|
||||
end)
|
||||
|
||||
job = %Oban.Job{
|
||||
args: %{
|
||||
"op" => "publish_one",
|
||||
"params" => %{
|
||||
"inbox" => "https://example.com/inbox",
|
||||
"activity_id" => activity.id,
|
||||
unknown_key => "ignored"
|
||||
}
|
||||
},
|
||||
attempt: 1,
|
||||
max_attempts: 5
|
||||
}
|
||||
|
||||
assert :ok = PublisherWorker.perform(job)
|
||||
assert_raise ArgumentError, fn -> String.to_existing_atom(unknown_key) end
|
||||
end
|
||||
|
||||
test "cancels job if server is unreachable", %{activity: activity} do
|
||||
|
|
@ -117,7 +150,7 @@ defmodule Pleroma.Workers.PublisherWorkerTest do
|
|||
max_attempts: 5
|
||||
}
|
||||
|
||||
assert {:cancel, :unreachable} = Pleroma.Workers.PublisherWorker.perform(job)
|
||||
assert {:cancel, :unreachable} = PublisherWorker.perform(job)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue