Merge branch 'develop' into 'post-languages'

# Conflicts:
#   lib/pleroma/web/activity_pub/transmogrifier.ex
#   test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs
This commit is contained in:
marcin mikołajczak 2024-01-19 16:36:37 +00:00
commit 250a4873a6
140 changed files with 797 additions and 378 deletions

View file

@ -39,7 +39,7 @@ defmodule Mix.PleromaTest do
describe "get_option/3" do
test "get from options" do
assert get_option([domain: "some-domain.com"], :domain, "Promt") == "some-domain.com"
assert get_option([domain: "some-domain.com"], :domain, "Prompt") == "some-domain.com"
end
test "get from prompt" do

View file

@ -140,7 +140,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
federating: true,
federation_incoming_replies_max_depth: 100,
federation_reachability_timeout_days: 7,
federation_publisher_modules: [Pleroma.Web.ActivityPub.Publisher],
allow_relay: true,
public: true,
quarantined_instances: [],
@ -183,8 +182,8 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
assert File.exists?(temp_file)
{:ok, file} = File.read(temp_file)
assert file ==
"import Config\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 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"
assert file =~ "import Config\n"
assert file =~ "A Pleroma instance, an alternative fediverse server"
end
end

View file

@ -13,7 +13,7 @@ defmodule Mix.Tasks.Pleroma.Ecto.RollbackTest do
assert capture_log(fn ->
Mix.Tasks.Pleroma.Ecto.Rollback.run(["--env", "test"])
end) =~ "[info] Rollback succesfully"
end) =~ "[info] Rollback successfully"
Logger.configure(level: level)
end

View file

@ -26,7 +26,7 @@ defmodule Mix.Tasks.Pleroma.RobotsTxtTest do
assert file == "User-Agent: *\nDisallow: /\n"
end
test "to existance folder" do
test "to existing folder" do
path = "test/fixtures/"
file_path = path <> "robots.txt"
clear_config([:instance, :static_dir], path)

View file

@ -145,6 +145,7 @@ defmodule Pleroma.ActivityTest do
setup do: clear_config([:instance, :limit_to_local_content])
@tag :skip_darwin
test "finds utf8 text in statuses", %{
japanese_activity: japanese_activity,
user: user

View file

@ -125,13 +125,12 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
media_removal: ["some.removal", {"some.other.instance", "Some reason"}]
)
expected_config = [
expected_config =
{:media_removal, [{"some.removal", ""}, {"some.other.instance", "Some reason"}]}
]
capture_log(fn -> DeprecationWarnings.warn() end)
assert Config.get([:mrf_simple]) == expected_config
assert expected_config in Config.get([:mrf_simple])
end
test "doesn't give a warning with correct config" do
@ -215,7 +214,7 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
```
config :pleroma, :mrf,
transparency_exclusions: [{"instance.tld", "Reason to exlude transparency"}]
transparency_exclusions: [{"instance.tld", "Reason to exclude transparency"}]
```
"""
end
@ -327,11 +326,11 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
end) =~ "Your config is using old namespace for activity expiration configuration."
end
test "check_uploders_s3_public_endpoint/0" do
test "check_uploaders_s3_public_endpoint/0" do
clear_config([Pleroma.Uploaders.S3], public_endpoint: "https://fake.amazonaws.com/bucket/")
assert capture_log(fn ->
DeprecationWarnings.check_uploders_s3_public_endpoint()
DeprecationWarnings.check_uploaders_s3_public_endpoint()
end) =~
"Your config is using the old setting for controlling the URL of media uploaded to your S3 bucket."
end

View file

@ -321,7 +321,7 @@ defmodule Pleroma.ConfigDBTest do
}) == {:proxy_url, {:socks5, {127, 0, 0, 1}, 1234}}
end
test "tuple with n childs" do
test "tuple with n children" do
assert ConfigDB.to_elixir_types(%{
"tuple" => [
"v1",
@ -399,7 +399,7 @@ defmodule Pleroma.ConfigDBTest do
assert ConfigDB.to_elixir_types(a: 1, b: 2, c: "string") == [a: 1, b: 2, c: "string"]
end
test "complex keyword with nested mixed childs" do
test "complex keyword with nested mixed children" do
assert ConfigDB.to_elixir_types([
%{"tuple" => [":uploader", "Pleroma.Uploaders.Local"]},
%{"tuple" => [":filters", ["Pleroma.Upload.Filter.Dedupe"]]},

View file

@ -57,7 +57,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
assert Participation.unread_count(other_user) == 0
end
test "for a new conversation, it sets the recipents of the participation" do
test "for a new conversation, it sets the recipients of the participation" do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)

View file

@ -72,7 +72,7 @@ defmodule Pleroma.Emoji.LoaderTest do
assert group == "special file"
end
test "no mathing returns nil", %{groups: groups} do
test "no matching returns nil", %{groups: groups} do
group =
groups
|> Loader.match_extra("/emoji/some_undefined.png")

View file

@ -324,7 +324,7 @@ defmodule Pleroma.FormatterTest do
assert {_text, [], ^expected_tags} = Formatter.linkify(text)
end
test "parses mulitple tags in html" do
test "parses multiple tags in html" do
text = "<p>#tag1 #tag2 #tag3 #tag4</p>"
expected_tags = [
@ -347,7 +347,7 @@ defmodule Pleroma.FormatterTest do
assert {_text, [], ^expected_tags} = Formatter.linkify(text)
end
test "parses mulitple tags on mulitple lines in html" do
test "parses multiple tags on multiple lines in html" do
text =
"<p>testing...</p><p>#tag1 #tag2 #tag3 #tag4</p><p>paragraph</p><p>#tag5 #tag6 #tag7 #tag8</p>"

View file

@ -9,14 +9,16 @@ defmodule Pleroma.HealthcheckTest do
test "system_info/0" do
result = Healthcheck.system_info() |> Map.from_struct()
assert Map.keys(result) == [
keys = Map.keys(result)
assert Keyword.equal?(keys, [
:active,
:healthy,
:idle,
:job_queue_stats,
:memory_used,
:pool_size
]
])
end
describe "check_health/1" do
@ -25,7 +27,7 @@ defmodule Pleroma.HealthcheckTest do
refute result.healthy
end
test "chech_health/1" do
test "check_health/1" do
result = Healthcheck.check_health(%Healthcheck{pool_size: 10, active: 9})
assert result.healthy
end

View file

@ -36,7 +36,7 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
assert opts[:certificates_verification]
end
test "https url with non standart port" do
test "https url with non-standard port" do
uri = URI.parse("https://example.com:115")
opts = Gun.options([receive_conn: false], uri)
@ -44,7 +44,7 @@ defmodule Pleroma.HTTP.AdapterHelper.GunTest do
assert opts[:certificates_verification]
end
test "merges with defaul http adapter config" do
test "merges with default http adapter config" do
defaults = Gun.options([receive_conn: false], URI.parse("https://example.com"))
assert Keyword.has_key?(defaults, :a)
assert Keyword.has_key?(defaults, :b)

View file

@ -7,6 +7,8 @@ defmodule Pleroma.MFA.TOTPTest do
alias Pleroma.MFA.TOTP
import Pleroma.Tests.Helpers, only: [uri_equal?: 2]
test "create provisioning_uri to generate qrcode" do
uri =
TOTP.provisioning_uri("test-secrcet", "test@example.com",
@ -15,7 +17,9 @@ defmodule Pleroma.MFA.TOTPTest do
period: 60
)
assert uri ==
assert uri_equal?(
uri,
"otpauth://totp/test@example.com?digits=8&issuer=Plerome-42&period=60&secret=test-secrcet"
)
end
end

View file

@ -28,7 +28,7 @@ defmodule Pleroma.OTPVersionTest do
"23.0"
end
test "with non existance file" do
test "with nonexistent file" do
assert OTPVersion.get_version_from_files([
"test/fixtures/warnings/otp_version/non-exising",
"test/fixtures/warnings/otp_version/22.4"

View file

@ -29,13 +29,13 @@ defmodule Pleroma.Repo.Migrations.AutolinkerToLinkifyTest do
%{value: new_opts} = ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Formatter})
assert new_opts == [
assert Keyword.equal?(new_opts,
class: false,
extra: true,
new_window: false,
rel: "testing",
strip_prefix: false
]
)
clear_config(Pleroma.Formatter, new_opts)
assert new_opts == Pleroma.Config.get(Pleroma.Formatter)
@ -67,6 +67,6 @@ defmodule Pleroma.Repo.Migrations.AutolinkerToLinkifyTest do
strip_prefix: false
]
assert migration.transform_opts(old_opts) == expected_opts
assert Keyword.equal?(migration.transform_opts(old_opts), expected_opts)
end
end

View file

@ -26,13 +26,13 @@ defmodule Pleroma.Repo.Migrations.FixMalformedFormatterConfigTest do
%{value: new_opts} = ConfigDB.get_by_params(%{group: :pleroma, key: Pleroma.Formatter})
assert new_opts == [
assert Keyword.equal?(new_opts,
class: false,
extra: true,
new_window: false,
rel: "F",
strip_prefix: false
]
)
clear_config(Pleroma.Formatter, new_opts)
assert new_opts == Pleroma.Config.get(Pleroma.Formatter)

View file

@ -306,7 +306,7 @@ defmodule Pleroma.ReverseProxyTest do
end
describe "response content disposition header" do
test "not atachment", %{conn: conn} do
test "not attachment", %{conn: conn} do
disposition_headers_mock([
{"content-type", "image/gif"},
{"content-length", "0"}

View file

@ -226,7 +226,7 @@ defmodule Pleroma.UserTest do
assert [] = User.get_follow_requests(followed)
end
test "follow_all follows mutliple users" do
test "follow_all follows multiple users" do
user = insert(:user)
followed_zero = insert(:user)
followed_one = insert(:user)
@ -250,7 +250,7 @@ defmodule Pleroma.UserTest do
refute User.following?(user, reverse_blocked)
end
test "follow_all follows mutliple users without duplicating" do
test "follow_all follows multiple users without duplicating" do
user = insert(:user)
followed_zero = insert(:user)
followed_one = insert(:user)
@ -873,7 +873,7 @@ defmodule Pleroma.UserTest do
end
end
describe "get_or_fetch/1 remote users with tld, while BE is runned on subdomain" do
describe "get_or_fetch/1 remote users with tld, while BE is running on a subdomain" do
setup do: clear_config([Pleroma.Web.WebFinger, :update_nickname_on_user_fetch], true)
test "for mastodon" do
@ -1018,13 +1018,13 @@ defmodule Pleroma.UserTest do
@tag capture_log: true
test "returns nil if no user could be fetched" do
{:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant@social.heldscal.la")
assert fetched_user == "not found nonexistant@social.heldscal.la"
{:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistent@social.heldscal.la")
assert fetched_user == "not found nonexistent@social.heldscal.la"
end
test "returns nil for nonexistant local user" do
{:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistant")
assert fetched_user == "not found nonexistant"
test "returns nil for nonexistent local user" do
{:error, fetched_user} = User.get_or_fetch_by_nickname("nonexistent")
assert fetched_user == "not found nonexistent"
end
test "updates an existing user, if stale" do
@ -1132,7 +1132,7 @@ defmodule Pleroma.UserTest do
assert cs.valid?
end
test "it sets the follower_adress" do
test "it sets the follower_address" do
cs = User.remote_user_changeset(@valid_remote)
# remote users get a fake local follower address
assert cs.changes.follower_address ==
@ -2683,13 +2683,23 @@ defmodule Pleroma.UserTest do
end
describe "full_nickname/1" do
test "returns fully qualified nickname for local and remote users" do
local_user =
insert(:user, nickname: "local_user", ap_id: "https://somehost.com/users/local_user")
test "returns fully qualified nickname for local users" do
local_user = insert(:user, nickname: "local_user")
assert User.full_nickname(local_user) == "local_user@localhost"
end
test "returns fully qualified nickname for local users when using different domain for webfinger" do
clear_config([Pleroma.Web.WebFinger, :domain], "plemora.dev")
local_user = insert(:user, nickname: "local_user")
assert User.full_nickname(local_user) == "local_user@plemora.dev"
end
test "returns fully qualified nickname for remote users" do
remote_user = insert(:user, nickname: "remote@host.com", local: false)
assert User.full_nickname(local_user) == "local_user@somehost.com"
assert User.full_nickname(remote_user) == "remote@host.com"
end

View file

@ -1028,7 +1028,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute repeat_activity in activities
end
test "see your own posts even when they adress actors from blocked domains" do
test "see your own posts even when they address actors from blocked domains" do
user = insert(:user)
domain = "dogwhistle.zone"

View file

@ -24,7 +24,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
assert res["object"]["summary"] == "re: object-summary"
end
test "it adds `re:` to summary object when child summary containts re-subject of parent summary " do
test "it adds `re:` to summary object when child summary contains re-subject of parent summary " do
message = %{
"type" => "Create",
"object" => %{

View file

@ -60,6 +60,33 @@ defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
|> File.exists?()
end
test "works with unknown extension", %{path: path} do
message = %{
"type" => "Create",
"object" => %{
"emoji" => [{"firedfox", "https://example.org/emoji/firedfox"}],
"actor" => "https://example.org/users/admin"
}
}
fullpath = Path.join(path, "firedfox.png")
Tesla.Mock.mock(fn %{method: :get, url: "https://example.org/emoji/firedfox"} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/image.jpg")}
end)
clear_config(:mrf_steal_emoji, hosts: ["example.org"], size_limit: 284_468)
refute "firedfox" in installed()
refute File.exists?(path)
assert {:ok, _message} = StealEmojiPolicy.filter(message)
assert "firedfox" in installed()
assert File.exists?(path)
assert File.exists?(fullpath)
end
test "reject regex shortcode", %{message: message} do
refute "firedfox" in installed()

View file

@ -1,10 +1,13 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRFTest do
use ExUnit.Case
use Pleroma.Tests.Helpers
import ExUnit.CaptureLog
alias Pleroma.Web.ActivityPub.MRF
test "subdomains_regex/1" do
@ -61,6 +64,14 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
refute MRF.subdomain_match?(regexes, "EXAMPLE.COM")
refute MRF.subdomain_match?(regexes, "example.com")
end
@tag capture_log: true
test "logs sensible error on accidental wildcard" do
assert_raise Regex.CompileError, fn ->
assert capture_log(MRF.subdomains_regex(["*unsafe.tld"])) =~
"MRF: Invalid subdomain Regex: *unsafe.tld"
end
end
end
describe "instance_list_from_tuples/1" do

View file

@ -164,7 +164,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
assert attachment.mediaType == "image/jpeg"
end
test "it transforms image dimentions to our internal format" do
test "it transforms image dimensions to our internal format" do
attachment = %{
"type" => "Document",
"name" => "Hello world",

View file

@ -147,6 +147,21 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
assert object["attachment"]
end
test "validates for a basic object with content but attachment set to empty array", %{
user: user,
recipient: recipient
} do
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "Hello!")
valid_chat_message =
valid_chat_message
|> Map.put("attachment", [])
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object == Map.drop(valid_chat_message, ["attachment"])
end
test "does not validate if the message has no content", %{
valid_chat_message: valid_chat_message
} do

View file

@ -212,7 +212,8 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
actor = insert(:user)
inbox = "http://404.site/users/nick1/inbox"
assert {:error, _} = Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
assert {:discard, _} =
Publisher.publish_one(%{inbox: inbox, json: "{}", actor: actor, id: 1})
assert called(Instances.set_unreachable(inbox))
end
@ -268,7 +269,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
describe "publish/2" do
test_with_mock "doesn't publish a non-public activity to quarantined instances.",
Pleroma.Web.Federator.Publisher,
Pleroma.Web.ActivityPub.Publisher,
[:passthrough],
[] do
Config.put([:instance, :quarantined_instances], [{"domain.com", "some reason"}])
@ -295,7 +296,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert not called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
Publisher.enqueue_one(%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: note_activity.data["id"]
@ -304,7 +305,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end
test_with_mock "Publishes a non-public activity to non-quarantined instances.",
Pleroma.Web.Federator.Publisher,
Pleroma.Web.ActivityPub.Publisher,
[:passthrough],
[] do
Config.put([:instance, :quarantined_instances], [{"somedomain.com", "some reason"}])
@ -331,8 +332,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(
Publisher,
Publisher.enqueue_one(
%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
@ -344,7 +344,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end
test_with_mock "Publishes to directly addressed actors with higher priority.",
Pleroma.Web.Federator.Publisher,
Pleroma.Web.ActivityPub.Publisher,
[:passthrough],
[] do
note_activity = insert(:direct_note_activity)
@ -356,8 +356,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(
Publisher,
Publisher.enqueue_one(
%{
inbox: :_,
actor_id: actor.id,
@ -369,7 +368,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end
test_with_mock "publishes an activity with BCC to all relevant peers.",
Pleroma.Web.Federator.Publisher,
Pleroma.Web.ActivityPub.Publisher,
[:passthrough],
[] do
follower =
@ -393,7 +392,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
Publisher.enqueue_one(%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
id: note_activity.data["id"]
@ -402,7 +401,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
end
test_with_mock "publishes a delete activity to peers who signed fetch requests to the create acitvity/object.",
Pleroma.Web.Federator.Publisher,
Pleroma.Web.ActivityPub.Publisher,
[:passthrough],
[] do
fetcher =
@ -443,8 +442,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
assert res == :ok
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(
Publisher,
Publisher.enqueue_one(
%{
inbox: "https://domain.com/users/nick1/inbox",
actor_id: actor.id,
@ -455,8 +453,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
)
assert called(
Pleroma.Web.Federator.Publisher.enqueue_one(
Publisher,
Publisher.enqueue_one(
%{
inbox: "https://domain2.com/users/nick1/inbox",
actor_id: actor.id,

View file

@ -17,11 +17,19 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.ActivityPub.SideEffects
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.ActivityDraft
import Mock
import Pleroma.Factory
defp get_announces_of_object(%{data: %{"id" => id}} = _object) do
Pleroma.Activity.Queries.by_type("Announce")
|> Pleroma.Activity.Queries.by_object_id(id)
|> Pleroma.Repo.all()
end
describe "handle_after_transaction" do
test "it streams out notifications and streams" do
author = insert(:user, local: true)
@ -915,4 +923,85 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
assert User.get_follow_state(user, followed, nil) == nil
end
end
describe "Group actors" do
setup do
poster =
insert(:user,
local: false,
nickname: "poster@example.com",
ap_id: "https://example.com/users/poster"
)
group = insert(:user, actor_type: "Group")
make_create = fn mentioned_users ->
mentions = mentioned_users |> Enum.map(fn u -> "@#{u.nickname}" end) |> Enum.join(" ")
{:ok, draft} = ActivityDraft.create(poster, %{status: "#{mentions} hey"})
create_activity_data =
Utils.make_create_data(draft.changes |> Map.put(:published, nil), %{})
|> put_in(["object", "id"], "https://example.com/object")
|> put_in(["id"], "https://example.com/activity")
assert Enum.all?(mentioned_users, fn u -> u.ap_id in create_activity_data["to"] end)
create_activity_data
end
%{poster: poster, group: group, make_create: make_create}
end
test "group should boost it", %{make_create: make_create, group: group} do
create_activity_data = make_create.([group])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity,
local: false,
object_data: create_activity_data["object"]
)
object = Object.normalize(create_activity, fetch: false)
assert [announce] = get_announces_of_object(object)
assert announce.actor == group.ap_id
end
test "remote group should not boost it", %{make_create: make_create, group: group} do
remote_group =
insert(:user, actor_type: "Group", local: false, nickname: "remotegroup@example.com")
create_activity_data = make_create.([group, remote_group])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity,
local: false,
object_data: create_activity_data["object"]
)
object = Object.normalize(create_activity, fetch: false)
assert [announce] = get_announces_of_object(object)
assert announce.actor == group.ap_id
end
test "group should not boost it if group is blocking poster", %{
make_create: make_create,
group: group,
poster: poster
} do
{:ok, _} = CommonAPI.block(group, poster)
create_activity_data = make_create.([group])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity,
local: false,
object_data: create_activity_data["object"]
)
object = Object.normalize(create_activity, fetch: false)
assert [] = get_announces_of_object(object)
end
end
end

View file

@ -251,6 +251,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
assert object.data["content"] == "Hi"
end
test "it works for incoming notices with a nil contentMap (firefish)" do
data =
File.read!("test/fixtures/mastodon-post-activity-contentmap.json")
|> Jason.decode!()
|> Map.put("contentMap", nil)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"], fetch: false)
assert object.data["content"] ==
"<p><span class=\"h-card\"><a href=\"http://localtesting.pleroma.lol/users/lain\" class=\"u-url mention\">@<span>lain</span></a></span></p>"
end
test "it works for incoming notices with to/cc not being an array (kroeg)" do
data = File.read!("test/fixtures/kroeg-post-activity.json") |> Jason.decode!()
@ -538,7 +551,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
[data: data]
end
test "returns not modified object when hasn't containts inReplyTo field", %{data: data} do
test "returns not modified object when has no inReplyTo field", %{data: data} do
assert Transmogrifier.fix_in_reply_to(data) == data
end

View file

@ -32,7 +32,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.UndoHandlingTest do
assert activity.data["type"] == "Undo"
end
test "it returns an error for incoming unlikes wihout a like activity" do
test "it returns an error for incoming unlikes without a like activity" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "leave a like pls"})

View file

@ -17,7 +17,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
require Pleroma.Constants
describe "strip_report_status_data/1" do
test "does not break on issues with the reported activites" do
test "does not break on issues with the reported activities" do
reporter = insert(:user)
target_account = insert(:user)
{:ok, activity} = CommonAPI.post(target_account, %{status: "foobar"})
@ -153,7 +153,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
assert Enum.sort(cc) == expected_cc
end
test "does not adress actor's follower address if the activity is not public", %{
test "does not address actor's follower address if the activity is not public", %{
user: user,
other_user: other_user,
third_user: third_user
@ -636,7 +636,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
end
describe "get_cached_emoji_reactions/1" do
test "returns the normalized data or an emtpy list" do
test "returns the normalized data or an empty list" do
object = insert(:note)
assert Utils.get_cached_emoji_reactions(object) == []

View file

@ -163,7 +163,7 @@ defmodule Pleroma.Web.AdminAPI.OAuthAppControllerTest do
assert response == ""
end
test "with non existance id", %{conn: conn} do
test "with nonexistent id", %{conn: conn} do
response =
conn
|> delete("/api/pleroma/admin/oauth_app/0")

View file

@ -26,8 +26,15 @@ defmodule Pleroma.Web.CommonAPITest do
import Mox
import Pleroma.Factory
require Pleroma.Activity.Queries
require Pleroma.Constants
defp get_announces_of_object(%{data: %{"id" => id}} = _object) do
Pleroma.Activity.Queries.by_type("Announce")
|> Pleroma.Activity.Queries.by_object_id(id)
|> Pleroma.Repo.all()
end
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
@ -1835,4 +1842,54 @@ defmodule Pleroma.Web.CommonAPITest do
assert Map.has_key?(updated_object.data, "updated")
end
end
describe "Group actors" do
setup do
poster = insert(:user)
group = insert(:user, actor_type: "Group")
other_group = insert(:user, actor_type: "Group")
%{poster: poster, group: group, other_group: other_group}
end
test "it boosts public posts", %{poster: poster, group: group} do
{:ok, post} = CommonAPI.post(poster, %{status: "hey @#{group.nickname}"})
announces = get_announces_of_object(post.object)
assert [_] = announces
end
test "it does not boost private posts", %{poster: poster, group: group} do
{:ok, private_post} =
CommonAPI.post(poster, %{status: "hey @#{group.nickname}", visibility: "private"})
assert [] = get_announces_of_object(private_post.object)
end
test "remote groups do not boost any posts", %{poster: poster} do
remote_group =
insert(:user, actor_type: "Group", local: false, nickname: "remote@example.com")
{:ok, post} = CommonAPI.post(poster, %{status: "hey @#{User.full_nickname(remote_group)}"})
assert remote_group.ap_id in post.data["to"]
announces = get_announces_of_object(post.object)
assert [] = announces
end
test "multiple groups mentioned", %{poster: poster, group: group, other_group: other_group} do
{:ok, post} =
CommonAPI.post(poster, %{status: "hey @#{group.nickname} @#{other_group.nickname}"})
announces = get_announces_of_object(post.object)
assert [_, _] = announces
end
test "it does not boost if group is blocking poster", %{poster: poster, group: group} do
{:ok, _} = CommonAPI.block(group, poster)
{:ok, post} = CommonAPI.post(poster, %{status: "hey @#{group.nickname}"})
announces = get_announces_of_object(post.object)
assert [] = announces
end
end
end

View file

@ -40,6 +40,44 @@ defmodule Pleroma.Web.FederatorTest do
%{activity: activity, relay_mock: relay_mock}
end
test "to shared inbox when multiple actors from same instance are recipients" do
user = insert(:user)
shared_inbox = "https://domain.com/inbox"
follower_one =
insert(:user, %{
local: false,
nickname: "nick1@domain.com",
ap_id: "https://domain.com/users/nick1",
inbox: "https://domain.com/users/nick1/inbox",
shared_inbox: shared_inbox
})
follower_two =
insert(:user, %{
local: false,
nickname: "nick2@domain.com",
ap_id: "https://domain.com/users/nick2",
inbox: "https://domain.com/users/nick2/inbox",
shared_inbox: shared_inbox
})
{:ok, _, _} = Pleroma.User.follow(follower_one, user)
{:ok, _, _} = Pleroma.User.follow(follower_two, user)
{:ok, _activity} = CommonAPI.post(user, %{status: "Happy Friday everyone!"})
ObanHelpers.perform(all_enqueued(worker: PublisherWorker))
inboxes =
all_enqueued(worker: PublisherWorker)
|> Enum.filter(&(get_in(&1, [Access.key(:args), Access.key("op")]) == "publish_one"))
|> Enum.map(&get_in(&1, [Access.key(:args), Access.key("params"), Access.key("inbox")]))
assert [shared_inbox] == inboxes
end
test "with relays active, it publishes to the relay", %{
activity: activity,
relay_mock: relay_mock

View file

@ -1360,7 +1360,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert user.registration_reason == "I'm a cool dude, bro"
end
test "returns error when user already registred", %{conn: conn, valid_params: valid_params} do
test "returns error when user already registered", %{conn: conn, valid_params: valid_params} do
_user = insert(:user, email: "lain@example.org")
app_token = insert(:oauth_token, user: nil)
@ -1495,7 +1495,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> Plug.Conn.put_req_header("authorization", "Bearer " <> token)
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/v1/accounts", %{
nickname: "nickanme",
nickname: "nickname",
agreement: true,
email: "email@example.com",
fullname: "Lain",
@ -1781,7 +1781,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert %{language: "ru_RU"} = Pleroma.User.get_by_nickname("foo")
end
test "createing an account without language parameter should fallback to cookie/header language",
test "creating an account without language parameter should fallback to cookie/header language",
%{conn: conn} do
params = %{
username: "foo2",

View file

@ -42,6 +42,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
end
end
@tag :skip_darwin
test "search", %{conn: conn} do
user = insert(:user)
user_two = insert(:user, %{nickname: "shp@shitposter.club"})

View file

@ -12,6 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.ScheduledActivity
alias Pleroma.Tests.Helpers
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@ -2191,7 +2192,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
# Using the header for pagination works correctly
[next, _] = get_resp_header(result, "link") |> hd() |> String.split(", ")
[_, max_id] = Regex.run(~r/max_id=([^&]+)/, next)
[next_url, _next_rel] = String.split(next, ";")
next_url = String.trim_trailing(next_url, ">") |> String.trim_leading("<")
max_id = Helpers.get_query_parameter(next_url, "max_id")
assert max_id == third_favorite.id

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
use Pleroma.Web.ConnCase, async: true
use Pleroma.Web.ConnCase, async: false
import Pleroma.Factory
@ -35,17 +35,20 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
defmacro assert_error_when_disable_push(do: yield) do
quote do
vapid_details = Application.get_env(:web_push_encryption, :vapid_details, [])
Application.put_env(:web_push_encryption, :vapid_details, [])
assert %{"error" => "Web push subscription is disabled on this Pleroma instance"} ==
unquote(yield)
Application.put_env(:web_push_encryption, :vapid_details, vapid_details)
end
end
describe "when disabled" do
setup do
vapid_config = Application.get_env(:web_push_encryption, :vapid_details)
Application.put_env(:web_push_encryption, :vapid_details, [])
on_exit(fn -> Application.put_env(:web_push_encryption, :vapid_details, vapid_config) end)
end
test "POST returns error", %{conn: conn} do
assert_error_when_disable_push do
conn

View file

@ -732,4 +732,20 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
end
describe "Mark account as group" do
setup do: oauth_access(["write:accounts"])
setup :request_content_type
test "changing actor_type to Group makes account a Group and enables bot indicator for backward compatibility",
%{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Group"})
|> json_response_and_validate_schema(200)
assert account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Group"
end
end
end

View file

@ -214,7 +214,7 @@ defmodule Pleroma.Web.OAuth.MFAControllerTest do
assert response == %{"error" => "Invalid code"}
end
test "returns error when client credentails is wrong ", %{conn: conn, user: user} do
test "returns error when client credentials is wrong ", %{conn: conn, user: user} do
otp_token = TOTP.generate_token(user.multi_factor_authentication_settings.totp.secret)
mfa_token = insert(:mfa_token, user: user)

View file

@ -13,7 +13,7 @@ defmodule Pleroma.Web.OAuth.Token.UtilsTest do
Utils.fetch_app(%Plug.Conn{params: %{"client_id" => 1, "client_secret" => "x"}})
end
test "returns App by params credentails" do
test "returns App by params credentials" do
app = insert(:oauth_app)
assert {:ok, load_app} =
@ -24,7 +24,7 @@ defmodule Pleroma.Web.OAuth.Token.UtilsTest do
assert load_app == app
end
test "returns App by header credentails" do
test "returns App by header credentials" do
app = insert(:oauth_app)
header = "Basic " <> Base.encode64("#{app.client_id}:#{app.client_secret}")

View file

@ -7,6 +7,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.Tests.Helpers
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@ -212,36 +213,63 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
result = json_response_and_validate_schema(response, 200)
[next, prev] = get_resp_header(response, "link") |> hd() |> String.split(", ")
api_endpoint = "/api/v1/pleroma/chats/"
api_endpoint = Pleroma.Web.Endpoint.url() <> "/api/v1/pleroma/chats/"
[next_url, next_rel] = String.split(next, ";")
next_url = String.trim_trailing(next_url, ">") |> String.trim_leading("<")
next_url_sorted = Helpers.uri_query_sort(next_url)
assert String.match?(
next,
~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*; rel=\"next\"$)
next_url_sorted,
~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*&offset=\d+$)
)
assert next_rel =~ "next"
[prev_url, prev_rel] = String.split(prev, ";")
prev_url = String.trim_trailing(prev_url, ">") |> String.trim_leading("<")
prev_url_sorted = Helpers.uri_query_sort(prev_url)
assert String.match?(
prev,
~r(#{api_endpoint}.*/messages\?limit=\d+&min_id=.*; rel=\"prev\"$)
prev_url_sorted,
~r(#{api_endpoint}.*/messages\?limit=\d+&min_id=.*&offset=\d+$)
)
assert prev_rel =~ "prev"
assert length(result) == 20
response =
get(conn, "/api/v1/pleroma/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}")
response = get(conn, "#{api_endpoint}#{chat.id}/messages?max_id=#{List.last(result)["id"]}")
result = json_response_and_validate_schema(response, 200)
[next, prev] = get_resp_header(response, "link") |> hd() |> String.split(", ")
assert String.match?(
next,
~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*; rel=\"next\"$)
)
[next_url, next_rel] = String.split(next, ";")
next_url = String.trim_trailing(next_url, ">") |> String.trim_leading("<")
next_url_sorted = Helpers.uri_query_sort(next_url)
assert String.match?(
prev,
~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*&min_id=.*; rel=\"prev\"$)
next_url_sorted,
~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*&offset=\d+$)
)
assert next_rel =~ "next"
[prev_url, prev_rel] = String.split(prev, ";")
prev_url = String.trim_trailing(prev_url, ">") |> String.trim_leading("<")
prev_url_sorted = Helpers.uri_query_sort(prev_url)
assert String.match?(
prev_url_sorted,
~r(#{api_endpoint}.*/messages\?limit=\d+&max_id=.*&min_id=.*&offset=\d+$)
)
assert prev_rel =~ "prev"
assert length(result) == 10
end

View file

@ -116,7 +116,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
%{method: :get, url: "https://example.com/nodeinfo/2.1.json"} ->
json(%{metadata: %{features: ["shareable_emoji_packs"]}})
%{method: :get, url: "https://example.com/api/pleroma/emoji/packs?page=2&page_size=1"} ->
%{method: :get, url: "https://example.com/api/v1/pleroma/emoji/packs?page=2&page_size=1"} ->
json(resp)
end)
@ -199,7 +199,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/pack?name=test_pack"
url: "https://example.com/api/v1/pleroma/emoji/pack?name=test_pack&page_size=" <> _n
} ->
conn
|> get("/api/pleroma/emoji/pack?name=test_pack")
@ -208,7 +208,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/archive?name=test_pack"
url: "https://example.com/api/v1/pleroma/emoji/packs/archive?name=test_pack"
} ->
conn
|> get("/api/pleroma/emoji/packs/archive?name=test_pack")
@ -217,7 +217,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/pack?name=test_pack_nonshared"
url:
"https://example.com/api/v1/pleroma/emoji/pack?name=test_pack_nonshared&page_size=" <>
_n
} ->
conn
|> get("/api/pleroma/emoji/pack?name=test_pack_nonshared")
@ -305,14 +307,14 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/pack?name=pack_bad_sha"
url: "https://example.com/api/v1/pleroma/emoji/pack?name=pack_bad_sha&page_size=" <> _n
} ->
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/archive?name=pack_bad_sha"
url: "https://example.com/api/v1/pleroma/emoji/packs/archive?name=pack_bad_sha"
} ->
%Tesla.Env{
status: 200,
@ -342,7 +344,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
%{
method: :get,
url: "https://example.com/api/pleroma/emoji/pack?name=test_pack"
url: "https://example.com/api/v1/pleroma/emoji/pack?name=test_pack&page_size=" <> _n
} ->
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
%Tesla.Env{status: 200, body: Jason.encode!(pack)}

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.PleromaApi.InstancesControllerTest do
{:ok, %Pleroma.Instances.Instance{unreachable_since: constant_unreachable}} =
Instances.set_consistently_unreachable(constant)
_eventual_unrechable = Instances.set_unreachable(eventual)
_eventual_unreachable = Instances.set_unreachable(eventual)
%{constant_unreachable: constant_unreachable, constant: constant}
end

View file

@ -23,8 +23,15 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
assert response.status == 200
assert response.resp_body ==
~s(<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="#{Pleroma.Web.Endpoint.url()}/.well-known/webfinger?resource={uri}" type="application/xrd+xml" /></XRD>)
response_xml =
response.resp_body
|> Floki.parse_document!(html_parser: Floki.HTMLParser.Mochiweb, attributes_as_maps: true)
expected_xml =
~s(<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="#{Pleroma.Web.Endpoint.url()}/.well-known/webfinger?resource={uri}" type="application/xrd+xml" /></XRD>)
|> Floki.parse_document!(html_parser: Floki.HTMLParser.Mochiweb, attributes_as_maps: true)
assert match?(^response_xml, expected_xml)
end
test "Webfinger JRD" do
@ -48,12 +55,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
]
end
test "reach user on tld, while pleroma is runned on subdomain" do
Pleroma.Web.Endpoint.config_change(
[{Pleroma.Web.Endpoint, url: [host: "sub.example.com"]}],
[]
)
test "reach user on tld, while pleroma is running on subdomain" do
clear_config([Pleroma.Web.Endpoint, :url, :host], "sub.example.com")
clear_config([Pleroma.Web.WebFinger, :domain], "example.com")
@ -68,13 +70,6 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
assert response["subject"] == "acct:#{user.nickname}@example.com"
assert response["aliases"] == ["https://sub.example.com/users/#{user.nickname}"]
on_exit(fn ->
Pleroma.Web.Endpoint.config_change(
[{Pleroma.Web.Endpoint, url: [host: "localhost"]}],
[]
)
end)
end
test "it returns 404 when user isn't found (JSON)" do

View file

@ -10,6 +10,39 @@ defmodule Pleroma.Tests.Helpers do
require Logger
@doc "Accepts two URLs/URIs and sorts the query parameters before comparing"
def uri_equal?(a, b) do
a_sorted = uri_query_sort(a)
b_sorted = uri_query_sort(b)
match?(^a_sorted, b_sorted)
end
@doc "Accepts a URL/URI and sorts the query parameters"
def uri_query_sort(uri) do
parsed = URI.parse(uri)
sorted_query =
String.split(parsed.query, "&")
|> Enum.sort()
|> Enum.join("&")
parsed
|> Map.put(:query, sorted_query)
|> URI.to_string()
end
@doc "Returns the value of the specified query parameter for the provided URL"
def get_query_parameter(url, param) do
url
|> URI.parse()
|> Map.get(:query)
|> URI.query_decoder()
|> Enum.to_list()
|> Enum.into(%{}, fn {x, y} -> {x, y} end)
|> Map.get(param)
end
defmacro clear_config(config_path) do
quote do
clear_config(unquote(config_path)) do

View file

@ -178,7 +178,7 @@ defmodule HttpRequestMock do
end
def get(
"https://social.heldscal.la/.well-known/webfinger?resource=nonexistant@social.heldscal.la",
"https://social.heldscal.la/.well-known/webfinger?resource=nonexistent@social.heldscal.la",
_,
_,
[{"accept", "application/xrd+xml,application/jrd+json"}]
@ -186,7 +186,7 @@ defmodule HttpRequestMock do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/nonexistant@social.heldscal.la.xml")
body: File.read!("test/fixtures/tesla_mock/nonexistent@social.heldscal.la.xml")
}}
end

View file

@ -6,6 +6,12 @@ Code.put_compiler_option(:warnings_as_errors, true)
ExUnit.start(exclude: [:federated, :erratic])
if match?({:unix, :darwin}, :os.type()) do
excluded = ExUnit.configuration() |> Keyword.get(:exclude, [])
excluded = excluded ++ [:skip_darwin]
ExUnit.configure(exclude: excluded)
end
Ecto.Adapters.SQL.Sandbox.mode(Pleroma.Repo, :manual)
Mox.defmock(Pleroma.ReverseProxy.ClientMock, for: Pleroma.ReverseProxy.Client)