Merge remote-tracking branch 'origin/develop' into instance-contact-account

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-03-08 12:12:55 +01:00
commit c0c4a9ed0d
335 changed files with 3031 additions and 1802 deletions

View file

@ -0,0 +1 @@
{"@context":"https://www.w3.org/ns/activitystreams","type":"Note","id":"https://cc.mkdir.uk/ap/note/e5d1d0a1-1ab3-4498-9949-588e3fdea286","attributedTo":"https://cc.mkdir.uk/ap/acct/hiira","inReplyTo":"","quoteUrl":"","content":"おはコンー","published":"2024-01-19T22:08:05Z","to":["https://www.w3.org/ns/activitystreams#Public"],"tag":null,"attachment":[],"object":null}

12
test/fixtures/rich_media/google.html vendored Normal file
View file

@ -0,0 +1,12 @@
<meta property="og:url" content="https://google.com">
<meta property="og:type" content="website">
<meta property="og:title" content="Google">
<meta property="og:description" content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.">
<meta property="og:image" content="">
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="google.com">
<meta property="twitter:url" content="https://google.com">
<meta name="twitter:title" content="Google">
<meta name="twitter:description" content="Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.">
<meta name="twitter:image" content="">

View file

@ -1,3 +1,3 @@
<link rel="alternate" type="application/json+oembed"
href="http://example.com/oembed.json"
href="https://example.com/oembed.json"
title="Bacon Lollys oEmbed Profile" />

12
test/fixtures/rich_media/yahoo.html vendored Normal file
View file

@ -0,0 +1,12 @@
<meta property="og:url" content="https://yahoo.com">
<meta property="og:type" content="website">
<meta property="og:title" content="Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos">
<meta property="og:description" content="Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!">
<meta property="og:image" content="https://s.yimg.com/cv/apiv2/social/images/yahoo_default_logo.png">
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="yahoo.com">
<meta property="twitter:url" content="https://yahoo.com">
<meta name="twitter:title" content="Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos">
<meta name="twitter:description" content="Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!">
<meta name="twitter:image" content="https://s.yimg.com/cv/apiv2/social/images/yahoo_default_logo.png">

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

@ -6,26 +6,26 @@ defmodule Pleroma.EmojiTest do
use ExUnit.Case, async: true
alias Pleroma.Emoji
describe "is_unicode_emoji?/1" do
describe "unicode?/1" do
test "tells if a string is an unicode emoji" do
refute Emoji.is_unicode_emoji?("X")
refute Emoji.is_unicode_emoji?("")
refute Emoji.unicode?("X")
refute Emoji.unicode?("")
# Only accept fully-qualified (RGI) emoji
# See http://www.unicode.org/reports/tr51/
refute Emoji.is_unicode_emoji?("")
refute Emoji.is_unicode_emoji?("")
refute Emoji.unicode?("")
refute Emoji.unicode?("")
assert Emoji.is_unicode_emoji?("🥺")
assert Emoji.is_unicode_emoji?("🤰")
assert Emoji.is_unicode_emoji?("❤️")
assert Emoji.is_unicode_emoji?("🏳️‍⚧️")
assert Emoji.is_unicode_emoji?("🫵")
assert Emoji.unicode?("🥺")
assert Emoji.unicode?("🤰")
assert Emoji.unicode?("❤️")
assert Emoji.unicode?("🏳️‍⚧️")
assert Emoji.unicode?("🫵")
# Additionally, we accept regional indicators.
assert Emoji.is_unicode_emoji?("🇵")
assert Emoji.is_unicode_emoji?("🇴")
assert Emoji.is_unicode_emoji?("🇬")
assert Emoji.unicode?("🇵")
assert Emoji.unicode?("🇴")
assert Emoji.unicode?("🇬")
end
end

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

@ -268,17 +268,6 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end)
end
test "accepts valid token on Sec-WebSocket-Protocol header", %{token: token} do
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
capture_log(fn ->
assert {:error, %WebSockex.RequestError{code: 401}} =
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
Process.sleep(30)
end)
end
test "accepts valid token on client-sent event", %{token: token} do
assert {:ok, pid} = start_socket()

View file

@ -0,0 +1,22 @@
# Pleroma: A lightweight social networking server
# Copyright © 2024 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.MapsTest do
use Pleroma.DataCase, async: true
alias Pleroma.Maps
describe "filter_empty_values/1" do
assert %{"bar" => "b", "ray" => ["foo"], "objs" => %{"a" => "b"}} ==
Maps.filter_empty_values(%{
"foo" => nil,
"fooz" => "",
"bar" => "b",
"rei" => [],
"ray" => ["foo"],
"obj" => %{},
"objs" => %{"a" => "b"}
})
end
end

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

@ -101,8 +101,7 @@ defmodule Pleroma.Object.FetcherTest do
test "it returns thread depth exceeded error if thread depth is exceeded" do
clear_config([:instance, :federation_incoming_replies_max_depth], 0)
assert {:error, "Max thread distance exceeded."} =
Fetcher.fetch_object_from_id(@ap_id, depth: 1)
assert {:error, :allowed_depth} = Fetcher.fetch_object_from_id(@ap_id, depth: 1)
end
test "it fetches object if max thread depth is restricted to 0 and depth is not specified" do
@ -220,14 +219,14 @@ defmodule Pleroma.Object.FetcherTest do
end
test "handle HTTP 410 Gone response" do
assert {:error, "Object has been deleted"} ==
assert {:error, :not_found} ==
Fetcher.fetch_and_contain_remote_object_from_id(
"https://mastodon.example.org/users/userisgone"
)
end
test "handle HTTP 404 response" do
assert {:error, "Object has been deleted"} ==
assert {:error, :not_found} ==
Fetcher.fetch_and_contain_remote_object_from_id(
"https://mastodon.example.org/users/userisgone404"
)

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

@ -113,7 +113,7 @@ defmodule Pleroma.SignatureTest do
test "it calls webfinger for 'acct:' accounts" do
with_mock(Pleroma.Web.WebFinger,
finger: fn _ -> %{"ap_id" => "https://gensokyo.2hu/users/raymoo"} end
finger: fn _ -> {:ok, %{"ap_id" => "https://gensokyo.2hu/users/raymoo"}} end
) do
assert Signature.key_id_to_actor_id("acct:raymoo@gensokyo.2hu") ==
{:ok, "https://gensokyo.2hu/users/raymoo"}

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 ==
@ -2424,20 +2424,20 @@ defmodule Pleroma.UserTest do
end
end
describe "is_internal_user?/1" do
describe "internal?/1" do
test "non-internal user returns false" do
user = insert(:user)
refute User.is_internal_user?(user)
refute User.internal?(user)
end
test "user with no nickname returns true" do
user = insert(:user, %{nickname: nil})
assert User.is_internal_user?(user)
assert User.internal?(user)
end
test "user with internal-prefixed nickname returns true" do
user = insert(:user, %{nickname: "internal.test"})
assert User.is_internal_user?(user)
assert User.internal?(user)
end
end
@ -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
@ -2918,4 +2928,51 @@ defmodule Pleroma.UserTest do
refute User.endorses?(user, pinned_user)
end
end
test "it checks fields links for a backlink" do
user = insert(:user, ap_id: "https://social.example.org/users/lain")
fields = [
%{"name" => "Link", "value" => "http://example.com/rel_me/null"},
%{"name" => "Verified link", "value" => "http://example.com/rel_me/link"},
%{"name" => "Not a link", "value" => "i'm not a link"}
]
user
|> User.update_and_set_cache(%{raw_fields: fields})
ObanHelpers.perform_all()
user = User.get_cached_by_id(user.id)
assert [
%{"verified_at" => nil},
%{"verified_at" => verified_at},
%{"verified_at" => nil}
] = user.fields
assert is_binary(verified_at)
end
test "updating fields does not invalidate previously validated links" do
user = insert(:user, ap_id: "https://social.example.org/users/lain")
user
|> User.update_and_set_cache(%{
raw_fields: [%{"name" => "verified link", "value" => "http://example.com/rel_me/link"}]
})
ObanHelpers.perform_all()
%User{fields: [%{"verified_at" => verified_at}]} = user = User.get_cached_by_id(user.id)
user
|> User.update_and_set_cache(%{
raw_fields: [%{"name" => "Verified link", "value" => "http://example.com/rel_me/link"}]
})
user = User.get_cached_by_id(user.id)
assert [%{"verified_at" => ^verified_at}] = user.fields
end
end

View file

@ -221,7 +221,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "test", visibility: "local"})
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
assert Pleroma.Web.ActivityPub.Visibility.local_public?(post)
object = Object.normalize(post, fetch: false)
uuid = String.split(object.data["id"], "/") |> List.last()
@ -238,7 +238,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "test", visibility: "local"})
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
assert Pleroma.Web.ActivityPub.Visibility.local_public?(post)
object = Object.normalize(post, fetch: false)
uuid = String.split(object.data["id"], "/") |> List.last()
@ -259,7 +259,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
{:ok, post} =
CommonAPI.post(user, %{status: "test @#{reader.nickname}", visibility: "local"})
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
assert Pleroma.Web.ActivityPub.Visibility.local_public?(post)
object = Object.normalize(post, fetch: false)
uuid = String.split(object.data["id"], "/") |> List.last()
@ -436,7 +436,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "test", visibility: "local"})
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
assert Pleroma.Web.ActivityPub.Visibility.local_public?(post)
uuid = String.split(post.data["id"], "/") |> List.last()
@ -452,7 +452,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "test", visibility: "local"})
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
assert Pleroma.Web.ActivityPub.Visibility.local_public?(post)
uuid = String.split(post.data["id"], "/") |> List.last()

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,59 @@ 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 "rejects invalid shortcodes", %{path: path} do
message = %{
"type" => "Create",
"object" => %{
"emoji" => [{"fired/fox", "https://example.org/emoji/firedfox"}],
"actor" => "https://example.org/users/admin"
}
}
fullpath = Path.join(path, "fired/fox.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)
refute "fired/fox" in installed()
refute 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

@ -93,6 +93,17 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
test "a Note from Convergence AP Bridge validates" do
insert(:user, ap_id: "https://cc.mkdir.uk/ap/acct/hiira")
note =
"test/fixtures/ccworld-ap-bridge_note.json"
|> File.read!()
|> Jason.decode!()
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
test "a note with an attachment should work", _ do
insert(:user, %{ap_id: "https://owncast.localhost.localdomain/federation/user/streamer"})

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

@ -221,6 +221,19 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
"<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 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!()
@ -508,7 +521,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

@ -132,7 +132,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
object = Object.normalize(activity)
assert [%{"type" => "Mention"}, %{"type" => "Link"}] = object.data["tag"]
end) =~ "Error while fetching"
end) =~ "Object rejected while fetching"
end
test "it accepts quote posts" do
@ -410,7 +410,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert capture_log(fn ->
{:error, _} = Transmogrifier.handle_incoming(data)
end) =~ "Object containment failed"
end) =~ "Object rejected while fetching"
end
test "it rejects activities which reference objects that have an incorrect attribution (variant 1)" do
@ -425,7 +425,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert capture_log(fn ->
{:error, _} = Transmogrifier.handle_incoming(data)
end) =~ "Object containment failed"
end) =~ "Object rejected while fetching"
end
test "it rejects activities which reference objects that have an incorrect attribution (variant 2)" do
@ -440,7 +440,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert capture_log(fn ->
{:error, _} = Transmogrifier.handle_incoming(data)
end) =~ "Object containment failed"
end) =~ "Object rejected while fetching"
end
end

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
@ -622,7 +622,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

@ -52,60 +52,60 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do
}
end
test "is_direct?", %{
test "direct?", %{
public: public,
private: private,
direct: direct,
unlisted: unlisted,
list: list
} do
assert Visibility.is_direct?(direct)
refute Visibility.is_direct?(public)
refute Visibility.is_direct?(private)
refute Visibility.is_direct?(unlisted)
assert Visibility.is_direct?(list)
assert Visibility.direct?(direct)
refute Visibility.direct?(public)
refute Visibility.direct?(private)
refute Visibility.direct?(unlisted)
assert Visibility.direct?(list)
end
test "is_public?", %{
test "public?", %{
public: public,
private: private,
direct: direct,
unlisted: unlisted,
list: list
} do
refute Visibility.is_public?(direct)
assert Visibility.is_public?(public)
refute Visibility.is_public?(private)
assert Visibility.is_public?(unlisted)
refute Visibility.is_public?(list)
refute Visibility.public?(direct)
assert Visibility.public?(public)
refute Visibility.public?(private)
assert Visibility.public?(unlisted)
refute Visibility.public?(list)
end
test "is_private?", %{
test "private?", %{
public: public,
private: private,
direct: direct,
unlisted: unlisted,
list: list
} do
refute Visibility.is_private?(direct)
refute Visibility.is_private?(public)
assert Visibility.is_private?(private)
refute Visibility.is_private?(unlisted)
refute Visibility.is_private?(list)
refute Visibility.private?(direct)
refute Visibility.private?(public)
assert Visibility.private?(private)
refute Visibility.private?(unlisted)
refute Visibility.private?(list)
end
test "is_list?", %{
test "list?", %{
public: public,
private: private,
direct: direct,
unlisted: unlisted,
list: list
} do
refute Visibility.is_list?(direct)
refute Visibility.is_list?(public)
refute Visibility.is_list?(private)
refute Visibility.is_list?(unlisted)
assert Visibility.is_list?(list)
refute Visibility.list?(direct)
refute Visibility.list?(public)
refute Visibility.list?(private)
refute Visibility.list?(unlisted)
assert Visibility.list?(list)
end
test "visible_for_user? Activity", %{
@ -227,7 +227,7 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do
} do
Repo.delete(user)
Pleroma.User.invalidate_cache(user)
refute Visibility.is_private?(direct)
refute Visibility.private?(direct)
end
test "get_visibility", %{

View file

@ -873,7 +873,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
%{
"tuple" => [
":_",
"Phoenix.Endpoint.Cowboy2Handler",
"Plug.Cowboy.Handler",
%{"tuple" => ["Pleroma.Web.Endpoint", []]}
]
}
@ -937,7 +937,7 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
%{
"tuple" => [
":_",
"Phoenix.Endpoint.Cowboy2Handler",
"Plug.Cowboy.Handler",
%{"tuple" => ["Pleroma.Web.Endpoint", []]}
]
}

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
@ -499,7 +506,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, convo_reply} =
CommonAPI.post(user, %{status: ".", in_reply_to_conversation_id: participation.id})
assert Visibility.is_direct?(convo_reply)
assert Visibility.direct?(convo_reply)
assert activity.data["context"] == convo_reply.data["context"]
end
@ -917,7 +924,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
{:ok, %Activity{} = announce_activity} = CommonAPI.repeat(activity.id, user)
assert Visibility.is_public?(announce_activity)
assert Visibility.public?(announce_activity)
end
test "can't repeat a repeat" do
@ -939,7 +946,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, %Activity{} = announce_activity} =
CommonAPI.repeat(activity.id, user, %{visibility: "private"})
assert Visibility.is_private?(announce_activity)
assert Visibility.private?(announce_activity)
refute Visibility.visible_for_user?(announce_activity, nil)
end
@ -952,7 +959,7 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, %Activity{} = announce_activity} = CommonAPI.repeat(activity.id, author)
assert Visibility.is_private?(announce_activity)
assert Visibility.private?(announce_activity)
refute Visibility.visible_for_user?(announce_activity, nil)
assert Visibility.visible_for_user?(activity, follower)
@ -1597,7 +1604,7 @@ defmodule Pleroma.Web.CommonAPITest do
with_mock Pleroma.Web.Federator, publish: fn _ -> :ok end do
{:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
assert_not_called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1612,7 +1619,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, %Activity{data: %{"deleted_activity_id" => ^activity_id}} = activity} =
CommonAPI.delete(activity_id, user)
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
assert_not_called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1628,7 +1635,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, %Activity{data: %{"type" => "Announce"}} = activity} =
CommonAPI.repeat(activity_id, user)
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1646,7 +1653,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, %Activity{data: %{"type" => "Undo"}} = activity} =
CommonAPI.unrepeat(activity_id, user)
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1661,7 +1668,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, %Activity{data: %{"type" => "Like"}} = activity} =
CommonAPI.favorite(user, activity.id)
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1676,7 +1683,7 @@ defmodule Pleroma.Web.CommonAPITest do
with_mock Pleroma.Web.Federator, publish: fn _ -> :ok end do
assert {:ok, activity} = CommonAPI.unfavorite(activity.id, user)
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1690,7 +1697,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, %Activity{data: %{"type" => "EmojiReact"}} = activity} =
CommonAPI.react_with_emoji(activity.id, user, "👍")
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
end
end
@ -1706,7 +1713,7 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, %Activity{data: %{"type" => "Undo"}} = activity} =
CommonAPI.unreact_with_emoji(activity.id, user, "👍")
assert Visibility.is_local_public?(activity)
assert Visibility.local_public?(activity)
refute called(Pleroma.Web.Federator.publish(activity))
end
end
@ -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
@ -335,13 +336,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
path -> Pleroma.Test.StaticConfig.get(path)
end)
Tesla.Mock.mock(fn
%{
method: :get,
url: "https://example.com/twitter-card"
} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}
Tesla.Mock.mock_global(fn
env ->
apply(HttpRequestMock, :request, [env])
end)
@ -2191,7 +2186,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

@ -511,10 +511,15 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account_data["fields"] == [
%{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"},
%{
"name" => "<a href=\"http://google.com\">foo</a>",
"value" => "bar",
"verified_at" => nil
},
%{
"name" => "link.io",
"value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)
"value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>),
"verified_at" => nil
}
]
@ -573,8 +578,8 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account_data["fields"] == [
%{"name" => ":firefox:", "value" => "is best 2hu"},
%{"name" => "they wins", "value" => ":blank:"}
%{"name" => ":firefox:", "value" => "is best 2hu", "verified_at" => nil},
%{"name" => "they wins", "value" => ":blank:", "verified_at" => nil}
]
assert account_data["source"]["fields"] == [
@ -602,10 +607,11 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account["fields"] == [
%{"name" => "foo", "value" => "bar"},
%{"name" => "foo", "value" => "bar", "verified_at" => nil},
%{
"name" => "link",
"value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>)
"value" => ~S(<a href="http://cofe.io" rel="ugc">http://cofe.io</a>),
"verified_at" => nil
}
]
@ -627,7 +633,7 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|> json_response_and_validate_schema(200)
assert account["fields"] == [
%{"name" => "foo", "value" => ""}
%{"name" => "foo", "value" => "", "verified_at" => nil}
]
end
@ -732,4 +738,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

@ -182,7 +182,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 500, body: ""}
end)
@ -197,7 +197,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
end)
@ -217,7 +217,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{
status: 200,
body: "",
@ -242,7 +242,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
end)
@ -260,7 +260,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
end)
@ -280,7 +280,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
clear_config([:media_preview_proxy, :min_content_length], 100_000)
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{
status: 200,
body: "",
@ -302,7 +302,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert_dependencies_installed()
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
%{method: :get, url: ^media_proxy_url} ->
@ -324,7 +324,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert_dependencies_installed()
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} ->
@ -344,7 +344,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
media_proxy_url: media_proxy_url
} do
Tesla.Mock.mock(fn
%{method: "HEAD", url: ^media_proxy_url} ->
%{method: :head, url: ^media_proxy_url} ->
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
%{method: :get, url: ^media_proxy_url} ->

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

@ -49,6 +49,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
:chat_message_id_idempotency_key_cache, ^id -> {:ok, "123"}
cache, key -> NullCache.get(cache, key)
end)
|> stub(:fetch, fn :rich_media_cache, _, _ -> {:ok, {:ok, %{}}} end)
chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)

View file

@ -3,7 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RichMedia.HelpersTest do
use Pleroma.DataCase, async: true
use Pleroma.DataCase, async: false
alias Pleroma.StaticStubbedConfigMock, as: ConfigMock
alias Pleroma.Web.CommonAPI
@ -14,7 +14,7 @@ defmodule Pleroma.Web.RichMedia.HelpersTest do
import Tesla.Mock
setup do
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
ConfigMock
|> stub(:get, fn
@ -83,8 +83,34 @@ defmodule Pleroma.Web.RichMedia.HelpersTest do
Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
end
# This does not seem to work. The urls are being fetched.
@tag skip: true
test "recrawls URLs on updates" do
original_url = "https://google.com/"
updated_url = "https://yahoo.com/"
Pleroma.StaticStubbedConfigMock
|> stub(:get, fn
[:rich_media, :enabled] -> true
path -> Pleroma.Test.StaticConfig.get(path)
end)
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "I like this site #{original_url}"})
assert match?(
%{page_url: ^original_url, rich_media: _},
Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
)
{:ok, _} = CommonAPI.update(user, activity, %{status: "I like this site #{updated_url}"})
activity = Pleroma.Activity.get_by_id(activity.id)
assert match?(
%{page_url: ^updated_url, rich_media: _},
Pleroma.Web.RichMedia.Helpers.fetch_data_for_activity(activity)
)
end
test "refuses to crawl URLs of private network from posts" do
user = insert(:user)
@ -102,10 +128,10 @@ defmodule Pleroma.Web.RichMedia.HelpersTest do
path -> Pleroma.Test.StaticConfig.get(path)
end)
assert %{} = Helpers.fetch_data_for_activity(activity)
assert %{} = Helpers.fetch_data_for_activity(activity2)
assert %{} = Helpers.fetch_data_for_activity(activity3)
assert %{} = Helpers.fetch_data_for_activity(activity4)
assert %{} = Helpers.fetch_data_for_activity(activity5)
assert %{} == Helpers.fetch_data_for_activity(activity)
assert %{} == Helpers.fetch_data_for_activity(activity2)
assert %{} == Helpers.fetch_data_for_activity(activity3)
assert %{} == Helpers.fetch_data_for_activity(activity4)
assert %{} == Helpers.fetch_data_for_activity(activity5)
end
end

View file

@ -22,7 +22,7 @@ defmodule Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrlTest do
expire_time =
Timex.parse!(timestamp, "{ISO:Basic:Z}") |> Timex.to_unix() |> Kernel.+(valid_till)
assert {:ok, expire_time} == Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl.ttl(metadata, url)
assert expire_time == Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl.ttl(metadata, url)
end
test "s3 signed url is parsed and correct ttl is set for rich media" do

View file

@ -3,95 +3,26 @@
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RichMedia.ParserTest do
use ExUnit.Case, async: true
use Pleroma.DataCase, async: false
alias Pleroma.Web.RichMedia.Parser
import Tesla.Mock
setup do
Tesla.Mock.mock(fn
%{
method: :get,
url: "http://example.com/ogp"
} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}
%{
method: :get,
url: "http://example.com/non-ogp"
} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/non_ogp_embed.html")}
%{
method: :get,
url: "http://example.com/ogp-missing-title"
} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/rich_media/ogp-missing-title.html")
}
%{
method: :get,
url: "http://example.com/twitter-card"
} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}
%{
method: :get,
url: "http://example.com/oembed"
} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.html")}
%{
method: :get,
url: "http://example.com/oembed.json"
} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.json")}
%{method: :get, url: "http://example.com/empty"} ->
%Tesla.Env{status: 200, body: "hello"}
%{method: :get, url: "http://example.com/malformed"} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/malformed-data.html")}
%{method: :get, url: "http://example.com/error"} ->
{:error, :overload}
%{
method: :head,
url: "http://example.com/huge-page"
} ->
%Tesla.Env{
status: 200,
headers: [{"content-length", "2000001"}, {"content-type", "text/html"}]
}
%{
method: :head,
url: "http://example.com/pdf-file"
} ->
%Tesla.Env{
status: 200,
headers: [{"content-length", "1000000"}, {"content-type", "application/pdf"}]
}
%{method: :head} ->
%Tesla.Env{status: 404, body: "", headers: []}
end)
:ok
mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
end
test "returns error when no metadata present" do
assert {:error, _} = Parser.parse("http://example.com/empty")
assert {:error, _} = Parser.parse("https://example.com/empty")
end
test "doesn't just add a title" do
assert {:error, {:invalid_metadata, _}} = Parser.parse("http://example.com/non-ogp")
assert {:error, {:invalid_metadata, _}} = Parser.parse("https://example.com/non-ogp")
end
test "parses ogp" do
assert Parser.parse("http://example.com/ogp") ==
assert Parser.parse("https://example.com/ogp") ==
{:ok,
%{
"image" => "http://ia.media-imdb.com/images/rock.jpg",
@ -99,12 +30,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
"description" =>
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
"type" => "video.movie",
"url" => "http://example.com/ogp"
"url" => "https://example.com/ogp"
}}
end
test "falls back to <title> when ogp:title is missing" do
assert Parser.parse("http://example.com/ogp-missing-title") ==
assert Parser.parse("https://example.com/ogp-missing-title") ==
{:ok,
%{
"image" => "http://ia.media-imdb.com/images/rock.jpg",
@ -112,12 +43,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
"description" =>
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
"type" => "video.movie",
"url" => "http://example.com/ogp-missing-title"
"url" => "https://example.com/ogp-missing-title"
}}
end
test "parses twitter card" do
assert Parser.parse("http://example.com/twitter-card") ==
assert Parser.parse("https://example.com/twitter-card") ==
{:ok,
%{
"card" => "summary",
@ -125,12 +56,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
"image" => "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
"title" => "Small Island Developing States Photo Submission",
"description" => "View the album on Flickr.",
"url" => "http://example.com/twitter-card"
"url" => "https://example.com/twitter-card"
}}
end
test "parses OEmbed and filters HTML tags" do
assert Parser.parse("http://example.com/oembed") ==
assert Parser.parse("https://example.com/oembed") ==
{:ok,
%{
"author_name" => "\u202E\u202D\u202Cbees\u202C",
@ -150,7 +81,7 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
"thumbnail_width" => 150,
"title" => "Bacon Lollys",
"type" => "photo",
"url" => "http://example.com/oembed",
"url" => "https://example.com/oembed",
"version" => "1.0",
"web_page" => "https://www.flickr.com/photos/bees/2362225867/",
"web_page_short_url" => "https://flic.kr/p/4AK2sc",
@ -159,18 +90,18 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
end
test "rejects invalid OGP data" do
assert {:error, _} = Parser.parse("http://example.com/malformed")
assert {:error, _} = Parser.parse("https://example.com/malformed")
end
test "returns error if getting page was not successful" do
assert {:error, :overload} = Parser.parse("http://example.com/error")
assert {:error, :overload} = Parser.parse("https://example.com/error")
end
test "does a HEAD request to check if the body is too large" do
assert {:error, :body_too_large} = Parser.parse("http://example.com/huge-page")
assert {:error, :body_too_large} = Parser.parse("https://example.com/huge-page")
end
test "does a HEAD request to check if the body is html" do
assert {:error, {:content_type, _}} = Parser.parse("http://example.com/pdf-file")
assert {:error, {:content_type, _}} = Parser.parse("https://example.com/pdf-file")
end
end

View file

@ -137,7 +137,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
|> html_response(200)
assert response =~ "Error fetching user"
end) =~ "Object has been deleted"
end) =~ ":not_found"
end
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

@ -0,0 +1,69 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.RemoteFetcherWorkerTest do
use Pleroma.DataCase
use Oban.Testing, repo: Pleroma.Repo
alias Pleroma.Workers.RemoteFetcherWorker
@deleted_object_one "https://deleted-404.example.com/"
@deleted_object_two "https://deleted-410.example.com/"
@unauthorized_object "https://unauthorized.example.com/"
@depth_object "https://depth.example.com/"
describe "RemoteFetcherWorker" do
setup do
Tesla.Mock.mock(fn
%{method: :get, url: @deleted_object_one} ->
%Tesla.Env{
status: 404
}
%{method: :get, url: @deleted_object_two} ->
%Tesla.Env{
status: 410
}
%{method: :get, url: @unauthorized_object} ->
%Tesla.Env{
status: 403
}
%{method: :get, url: @depth_object} ->
%Tesla.Env{
status: 200
}
end)
end
test "does not requeue a deleted object" do
assert {:discard, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @deleted_object_one}
})
assert {:discard, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @deleted_object_two}
})
end
test "does not requeue an unauthorized object" do
assert {:discard, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @unauthorized_object}
})
end
test "does not requeue an object that exceeded depth" do
clear_config([:instance, :federation_incoming_replies_max_depth], 0)
assert {:discard, _} =
RemoteFetcherWorker.perform(%Oban.Job{
args: %{"op" => "fetch_remote", "id" => @depth_object, "depth" => 1}
})
end
end
end

View file

@ -26,9 +26,15 @@ defmodule Pleroma.CachexProxy do
@impl true
defdelegate fetch!(cache, key, func), to: Cachex
@impl true
defdelegate fetch(cache, key, func), to: Cachex
@impl true
defdelegate expire_at(cache, str, num), to: Cachex
@impl true
defdelegate expire(cache, str, num), to: Cachex
@impl true
defdelegate exists?(cache, key), to: Cachex

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
@ -1059,7 +1059,7 @@ defmodule HttpRequestMock do
}}
end
def get("http://example.com/malformed", _, _, _) do
def get("https://example.com/malformed", _, _, _) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/malformed-data.html")}}
end
@ -1464,6 +1464,45 @@ defmodule HttpRequestMock do
}}
end
def get("https://google.com/", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/google.html")}}
end
def get("https://yahoo.com/", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/yahoo.html")}}
end
def get("https://example.com/error", _, _, _), do: {:error, :overload}
def get("https://example.com/ogp-missing-title", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/rich_media/ogp-missing-title.html")
}}
end
def get("https://example.com/oembed", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.html")}}
end
def get("https://example.com/oembed.json", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/oembed.json")}}
end
def get("https://example.com/twitter-card", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/twitter_card.html")}}
end
def get("https://example.com/non-ogp", _, _, _) do
{:ok,
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/non_ogp_embed.html")}}
end
def get("https://example.com/empty", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: "hello"}}
end
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
@ -1537,14 +1576,41 @@ defmodule HttpRequestMock do
# Most of the rich media mocks are missing HEAD requests, so we just return 404.
@rich_media_mocks [
"https://example.com/empty",
"https://example.com/error",
"https://example.com/malformed",
"https://example.com/non-ogp",
"https://example.com/oembed",
"https://example.com/oembed.json",
"https://example.com/ogp",
"https://example.com/ogp-missing-data",
"https://example.com/twitter-card"
"https://example.com/ogp-missing-title",
"https://example.com/twitter-card",
"https://google.com/",
"https://pleroma.local/notice/9kCP7V",
"https://yahoo.com/"
]
def head(url, _query, _body, _headers) when url in @rich_media_mocks do
{:ok, %Tesla.Env{status: 404, body: ""}}
end
def head("https://example.com/pdf-file", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
headers: [{"content-length", "1000000"}, {"content-type", "application/pdf"}]
}}
end
def head("https://example.com/huge-page", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
headers: [{"content-length", "2000001"}, {"content-type", "text/html"}]
}}
end
def head(url, query, body, headers) do
{:error,
"Mock response not implemented for HEAD #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}

View file

@ -28,6 +28,9 @@ defmodule Pleroma.NullCache do
end
end
@impl true
def fetch(_, key, func), do: func.(key)
@impl true
def get_and_update(_, _, func) do
func.(nil)
@ -36,6 +39,9 @@ defmodule Pleroma.NullCache do
@impl true
def expire_at(_, _, _), do: {:ok, true}
@impl true
def expire(_, _, _), do: {:ok, true}
@impl true
def exists?(_, _), do: {:ok, false}

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)