Merge remote-tracking branch 'origin/develop' into status-notification-type
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
commit
226e53fdd7
667 changed files with 14147 additions and 4553 deletions
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.Ir.TopicsTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Activity.Ir.Topics
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ defmodule Pleroma.ActivityTest do
|
|||
|
||||
setup do: clear_config([:instance, :limit_to_local_content])
|
||||
|
||||
@tag :skip_on_mac
|
||||
@tag :skip_darwin
|
||||
test "finds utf8 text in statuses", %{
|
||||
japanese_activity: japanese_activity,
|
||||
user: user
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.BBS.HandlerTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.BBS.Handler
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import ExUnit.CaptureIO
|
||||
import Pleroma.Factory
|
||||
import Ecto.Query
|
||||
|
||||
test "getting the home timeline" do
|
||||
user = insert(:user)
|
||||
followed = insert(:user)
|
||||
|
||||
{:ok, user, followed} = User.follow(user, followed)
|
||||
|
||||
{:ok, _first} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, _second} = CommonAPI.post(followed, %{status: "hello"})
|
||||
|
||||
output =
|
||||
capture_io(fn ->
|
||||
Handler.handle_command(%{user: user}, "home")
|
||||
end)
|
||||
|
||||
assert output =~ user.nickname
|
||||
assert output =~ followed.nickname
|
||||
|
||||
assert output =~ "hey"
|
||||
assert output =~ "hello"
|
||||
end
|
||||
|
||||
test "posting" do
|
||||
user = insert(:user)
|
||||
|
||||
output =
|
||||
capture_io(fn ->
|
||||
Handler.handle_command(%{user: user}, "p this is a test post")
|
||||
end)
|
||||
|
||||
assert output =~ "Posted"
|
||||
|
||||
activity =
|
||||
Repo.one(
|
||||
from(a in Activity,
|
||||
where: fragment("?->>'type' = ?", a.data, "Create")
|
||||
)
|
||||
)
|
||||
|
||||
assert activity.actor == user.ap_id
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
assert object.data["content"] == "this is a test post"
|
||||
end
|
||||
|
||||
test "replying" do
|
||||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(another_user, %{status: "this is a test post"})
|
||||
activity_object = Object.normalize(activity, fetch: false)
|
||||
|
||||
output =
|
||||
capture_io(fn ->
|
||||
Handler.handle_command(%{user: user}, "r #{activity.id} this is a reply")
|
||||
end)
|
||||
|
||||
assert output =~ "Replied"
|
||||
|
||||
reply =
|
||||
Repo.one(
|
||||
from(a in Activity,
|
||||
where: fragment("?->>'type' = ?", a.data, "Create"),
|
||||
where: a.actor == ^user.ap_id
|
||||
)
|
||||
)
|
||||
|
||||
assert reply.actor == user.ap_id
|
||||
|
||||
reply_object_data = Object.normalize(reply, fetch: false).data
|
||||
assert reply_object_data["content"] == "this is a reply"
|
||||
assert reply_object_data["inReplyTo"] == activity_object.data["id"]
|
||||
end
|
||||
end
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
|
|||
describe "load/2" do
|
||||
test "loads release defaults config and warns about non-existent runtime config" do
|
||||
ExUnit.CaptureIO.capture_io(fn ->
|
||||
merged = ReleaseRuntimeProvider.load([], [])
|
||||
merged = ReleaseRuntimeProvider.load([], config_path: "/var/empty/config.exs")
|
||||
assert merged == Pleroma.Config.Holder.release_defaults()
|
||||
end) =~
|
||||
"!!! Config path is not declared! Please ensure it exists and that PLEROMA_CONFIG_PATH is unset or points to an existing file"
|
||||
end
|
||||
|
||||
test "merged runtime config" do
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640)
|
||||
|
||||
merged =
|
||||
ReleaseRuntimeProvider.load([], config_path: "test/fixtures/config/temp.secret.exs")
|
||||
|
||||
|
|
@ -25,6 +27,8 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
|
|||
end
|
||||
|
||||
test "merged exported config" do
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640)
|
||||
|
||||
ExUnit.CaptureIO.capture_io(fn ->
|
||||
merged =
|
||||
ReleaseRuntimeProvider.load([],
|
||||
|
|
@ -37,6 +41,9 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
|
|||
end
|
||||
|
||||
test "runtime config is merged with exported config" do
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640)
|
||||
assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640)
|
||||
|
||||
merged =
|
||||
ReleaseRuntimeProvider.load([],
|
||||
config_path: "test/fixtures/config/temp.secret.exs",
|
||||
|
|
|
|||
|
|
@ -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"]]},
|
||||
|
|
@ -443,13 +443,13 @@ defmodule Pleroma.ConfigDBTest do
|
|||
|
||||
test "common keyword" do
|
||||
assert ConfigDB.to_elixir_types([
|
||||
%{"tuple" => [":level", ":warn"]},
|
||||
%{"tuple" => [":level", ":warning"]},
|
||||
%{"tuple" => [":meta", [":all"]]},
|
||||
%{"tuple" => [":path", ""]},
|
||||
%{"tuple" => [":val", nil]},
|
||||
%{"tuple" => [":webhook_url", "https://hooks.slack.com/services/YOUR-KEY-HERE"]}
|
||||
]) == [
|
||||
level: :warn,
|
||||
level: :warning,
|
||||
meta: [:all],
|
||||
path: "",
|
||||
val: nil,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ defmodule Pleroma.ConversationTest do
|
|||
|
||||
setup_all do: clear_config([:instance, :federating], true)
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
test "it goes through old direct conversations" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.BareUriTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators.BareUri
|
||||
|
||||
test "diaspora://" do
|
||||
text = "diaspora://alice@fediverse.example/post/deadbeefdeadbeefdeadbeefdeadbeef"
|
||||
assert {:ok, ^text} = BareUri.cast(text)
|
||||
end
|
||||
|
||||
test "nostr:" do
|
||||
text = "nostr:note1gwdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||
assert {:ok, ^text} = BareUri.cast(text)
|
||||
end
|
||||
|
||||
test "errors for non-URIs" do
|
||||
assert :error == BareUri.cast(1)
|
||||
assert :error == BareUri.cast("foo")
|
||||
assert :error == BareUri.cast("foo bar")
|
||||
end
|
||||
end
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -90,4 +90,8 @@ defmodule Pleroma.Emoji.PackTest do
|
|||
|
||||
assert updated_pack.files_count == 1
|
||||
end
|
||||
|
||||
test "load_pack/1 ignores path traversal in a forged pack name", %{pack: pack} do
|
||||
assert {:ok, ^pack} = Pack.load_pack("../../../../../dump_pack")
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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>"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.AdapterHelper.HackneyTest do
|
||||
use ExUnit.Case, async: true
|
||||
use ExUnit.Case
|
||||
use Pleroma.Tests.Helpers
|
||||
|
||||
alias Pleroma.HTTP.AdapterHelper.Hackney
|
||||
|
|
|
|||
45
test/pleroma/http/web_push_test.exs
Normal file
45
test/pleroma/http/web_push_test.exs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.HTTP.WebPushTest do
|
||||
use ExUnit.Case
|
||||
|
||||
import Tesla.Mock
|
||||
alias Pleroma.HTTP
|
||||
|
||||
@push_url "https://some-push-server/"
|
||||
|
||||
setup do
|
||||
mock(fn
|
||||
%{
|
||||
method: :post,
|
||||
url: @push_url,
|
||||
headers: headers
|
||||
} ->
|
||||
if {"content-type", "octet-stream"} in headers do
|
||||
%Tesla.Env{
|
||||
status: 200
|
||||
}
|
||||
else
|
||||
%Tesla.Env{
|
||||
status: 403
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "post" do
|
||||
response =
|
||||
HTTP.WebPush.post(
|
||||
@push_url,
|
||||
"encrypted payload",
|
||||
%{"authorization" => "WebPush"},
|
||||
[]
|
||||
)
|
||||
|
||||
assert {:ok, %{status: 200}} = response
|
||||
end
|
||||
end
|
||||
|
|
@ -31,14 +31,6 @@ defmodule Pleroma.Instances.InstanceTest do
|
|||
assert {:ok, instance} = Instance.set_reachable(instance.host)
|
||||
refute instance.unreachable_since
|
||||
end
|
||||
|
||||
test "does NOT create an Instance record in case of no existing matching record" do
|
||||
host = "domain.org"
|
||||
assert nil == Instance.set_reachable(host)
|
||||
|
||||
assert [] = Repo.all(Ecto.Query.from(i in Instance))
|
||||
assert Instance.reachable?(host)
|
||||
end
|
||||
end
|
||||
|
||||
describe "set_unreachable/1" do
|
||||
|
|
@ -161,6 +153,66 @@ defmodule Pleroma.Instances.InstanceTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "get_or_update_metadata/1" do
|
||||
test "Scrapes Wildebeest NodeInfo" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "https://wildebeest.example.org/.well-known/nodeinfo"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/wildebeest-well-known-nodeinfo.json")
|
||||
}
|
||||
|
||||
%{url: "https://wildebeest.example.org/nodeinfo/2.1"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/wildebeest-nodeinfo21.json")
|
||||
}
|
||||
end)
|
||||
|
||||
expected = %{
|
||||
software_name: "wildebeest",
|
||||
software_repository: "https://github.com/cloudflare/wildebeest",
|
||||
software_version: "0.0.1"
|
||||
}
|
||||
|
||||
assert expected ==
|
||||
Instance.get_or_update_metadata(URI.parse("https://wildebeest.example.org/"))
|
||||
|
||||
expected = %Pleroma.Instances.Instance.Pleroma.Instances.Metadata{
|
||||
software_name: "wildebeest",
|
||||
software_repository: "https://github.com/cloudflare/wildebeest",
|
||||
software_version: "0.0.1"
|
||||
}
|
||||
|
||||
assert expected ==
|
||||
Repo.get_by(Pleroma.Instances.Instance, %{host: "wildebeest.example.org"}).metadata
|
||||
end
|
||||
|
||||
test "Scrapes Mastodon NodeInfo" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "https://mastodon.example.org/.well-known/nodeinfo"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/mastodon-well-known-nodeinfo.json")
|
||||
}
|
||||
|
||||
%{url: "https://mastodon.example.org/nodeinfo/2.0"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/mastodon-nodeinfo20.json")
|
||||
}
|
||||
end)
|
||||
|
||||
expected = %{
|
||||
software_name: "mastodon",
|
||||
software_version: "4.1.0"
|
||||
}
|
||||
|
||||
assert expected ==
|
||||
Instance.get_or_update_metadata(URI.parse("https://mastodon.example.org/"))
|
||||
end
|
||||
end
|
||||
|
||||
test "delete_users_and_activities/1 deletes remote instance users and activities" do
|
||||
[mario, luigi, _peach, wario] =
|
||||
users = [
|
||||
|
|
|
|||
|
|
@ -31,9 +31,22 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
WebsocketClient.start_link(self(), path, headers)
|
||||
end
|
||||
|
||||
defp decode_json(json) do
|
||||
with {:ok, %{"event" => event, "payload" => payload_text}} <- Jason.decode(json),
|
||||
{:ok, payload} <- Jason.decode(payload_text) do
|
||||
{:ok, %{"event" => event, "payload" => payload}}
|
||||
end
|
||||
end
|
||||
|
||||
# Turns atom keys to strings
|
||||
defp atom_key_to_string(json) do
|
||||
json
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
end
|
||||
|
||||
test "refuses invalid requests" do
|
||||
capture_log(fn ->
|
||||
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket()
|
||||
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket("?stream=ncjdk")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
|
|
@ -49,6 +62,10 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
end)
|
||||
end
|
||||
|
||||
test "allows unified stream" do
|
||||
assert {:ok, _} = start_socket()
|
||||
end
|
||||
|
||||
test "allows public streams without authentication" do
|
||||
assert {:ok, _} = start_socket("?stream=public")
|
||||
assert {:ok, _} = start_socket("?stream=public:local")
|
||||
|
|
@ -70,12 +87,143 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
|
||||
view_json =
|
||||
Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
|> atom_key_to_string()
|
||||
|
||||
assert json == view_json
|
||||
end
|
||||
|
||||
describe "subscribing via WebSocket" do
|
||||
test "can subscribe" do
|
||||
user = insert(:user)
|
||||
{:ok, pid} = start_socket()
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, json} = Jason.decode(raw_json)
|
||||
|
||||
assert "update" == json["event"]
|
||||
assert json["payload"]
|
||||
assert {:ok, json} = Jason.decode(json["payload"])
|
||||
|
||||
view_json =
|
||||
Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
|
||||
assert json == view_json
|
||||
end
|
||||
|
||||
test "can subscribe to multiple streams" do
|
||||
user = insert(:user)
|
||||
{:ok, pid} = start_socket()
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "subscribe", stream: "hashtag", tag: "mew"} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber #mew"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, %{"stream" => stream1}} = Jason.decode(raw_json)
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, %{"stream" => stream2}} = Jason.decode(raw_json)
|
||||
|
||||
streams = [stream1, stream2]
|
||||
assert ["hashtag", "mew"] in streams
|
||||
assert ["public"] in streams
|
||||
end
|
||||
|
||||
test "won't double subscribe" do
|
||||
user = insert(:user)
|
||||
{:ok, pid} = start_socket()
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "ignored"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
|
||||
|
||||
assert_receive {:text, _}, 1_000
|
||||
refute_receive {:text, _}, 1_000
|
||||
end
|
||||
|
||||
test "rejects invalid streams" do
|
||||
{:ok, pid} = start_socket()
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "nonsense"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "error", "error" => "bad_topic"}
|
||||
}} = decode_json(raw_json)
|
||||
end
|
||||
|
||||
test "can unsubscribe" do
|
||||
user = insert(:user)
|
||||
{:ok, pid} = start_socket()
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
WebsocketClient.send_text(pid, %{type: "unsubscribe", stream: "public"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "unsubscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
|
||||
refute_receive {:text, _}, 1_000
|
||||
end
|
||||
end
|
||||
|
||||
describe "with a valid user token" do
|
||||
setup do
|
||||
{:ok, app} =
|
||||
|
|
@ -131,6 +279,124 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
end)
|
||||
end
|
||||
|
||||
test "accepts valid token on client-sent event", %{token: token} do
|
||||
assert {:ok, pid} = start_socket()
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "pleroma:authenticate", token: token.token} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "pleroma:authenticate", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "user"} |> Jason.encode!())
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
end
|
||||
|
||||
test "rejects invalid token on client-sent event" do
|
||||
assert {:ok, pid} = start_socket()
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "pleroma:authenticate", token: "Something else"} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{
|
||||
"type" => "pleroma:authenticate",
|
||||
"result" => "error",
|
||||
"error" => "unauthorized"
|
||||
}
|
||||
}} = decode_json(raw_json)
|
||||
end
|
||||
|
||||
test "rejects new authenticate request if already logged-in", %{token: token} do
|
||||
assert {:ok, pid} = start_socket()
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "pleroma:authenticate", token: token.token} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "pleroma:authenticate", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "pleroma:authenticate", token: "Something else"} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{
|
||||
"type" => "pleroma:authenticate",
|
||||
"result" => "error",
|
||||
"error" => "already_authenticated"
|
||||
}
|
||||
}} = decode_json(raw_json)
|
||||
end
|
||||
|
||||
test "accepts the 'list' stream", %{token: token, user: user} do
|
||||
posting_user = insert(:user)
|
||||
|
||||
{:ok, list} = Pleroma.List.create("test", user)
|
||||
Pleroma.List.follow(list, posting_user)
|
||||
|
||||
assert {:ok, _} = start_socket("?stream=list&access_token=#{token.token}&list=#{list.id}")
|
||||
|
||||
assert {:ok, pid} = start_socket("?access_token=#{token.token}")
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "subscribe", stream: "list", list: list.id} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "success"}
|
||||
}} = decode_json(raw_json)
|
||||
|
||||
WebsocketClient.send_text(
|
||||
pid,
|
||||
%{type: "subscribe", stream: "list", list: to_string(list.id)} |> Jason.encode!()
|
||||
)
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "pleroma:respond",
|
||||
"payload" => %{"type" => "subscribe", "result" => "ignored"}
|
||||
}} = decode_json(raw_json)
|
||||
end
|
||||
|
||||
test "disconnect when token is revoked", %{app: app, user: user, token: token} do
|
||||
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
||||
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||
|
|
@ -146,5 +412,85 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert_receive {:close, _}
|
||||
refute_receive {:close, _}
|
||||
end
|
||||
|
||||
test "receives private statuses", %{user: reading_user, token: token} do
|
||||
user = insert(:user)
|
||||
CommonAPI.follow(reading_user, user)
|
||||
|
||||
{:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "nice echo chamber", visibility: "private"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
assert {:ok, json} = Jason.decode(raw_json)
|
||||
|
||||
assert "update" == json["event"]
|
||||
assert json["payload"]
|
||||
assert {:ok, json} = Jason.decode(json["payload"])
|
||||
|
||||
view_json =
|
||||
Pleroma.Web.MastodonAPI.StatusView.render("show.json",
|
||||
activity: activity,
|
||||
for: reading_user
|
||||
)
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
|
||||
assert json == view_json
|
||||
end
|
||||
|
||||
test "receives edits", %{user: reading_user, token: token} do
|
||||
user = insert(:user)
|
||||
CommonAPI.follow(reading_user, user)
|
||||
|
||||
{:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "nice echo chamber", visibility: "private"})
|
||||
|
||||
assert_receive {:text, _raw_json}, 1_000
|
||||
|
||||
{:ok, _} = CommonAPI.update(user, activity, %{status: "mew mew", visibility: "private"})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
activity = Pleroma.Activity.normalize(activity)
|
||||
|
||||
view_json =
|
||||
Pleroma.Web.MastodonAPI.StatusView.render("show.json",
|
||||
activity: activity,
|
||||
for: reading_user
|
||||
)
|
||||
|> Jason.encode!()
|
||||
|> Jason.decode!()
|
||||
|
||||
assert {:ok, %{"event" => "status.update", "payload" => ^view_json}} = decode_json(raw_json)
|
||||
end
|
||||
|
||||
test "receives notifications", %{user: reading_user, token: token} do
|
||||
user = insert(:user)
|
||||
CommonAPI.follow(reading_user, user)
|
||||
|
||||
{:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
||||
|
||||
{:ok, %Pleroma.Activity{id: activity_id} = _activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "nice echo chamber @#{reading_user.nickname}",
|
||||
visibility: "private"
|
||||
})
|
||||
|
||||
assert_receive {:text, raw_json}, 1_000
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"event" => "notification",
|
||||
"payload" => %{
|
||||
"status" => %{
|
||||
"id" => ^activity_id
|
||||
}
|
||||
}
|
||||
}} = decode_json(raw_json)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ defmodule Pleroma.NotificationTest do
|
|||
alias Pleroma.Web.Push
|
||||
alias Pleroma.Web.Streamer
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "create_notifications" do
|
||||
test "never returns nil" do
|
||||
user = insert(:user)
|
||||
|
|
@ -268,7 +273,7 @@ defmodule Pleroma.NotificationTest do
|
|||
task =
|
||||
Task.async(fn ->
|
||||
{:ok, _topic} = Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
assert_receive {:render_with_user, _, _, _}, 4_000
|
||||
assert_receive {:render_with_user, _, _, _, _}, 4_000
|
||||
end)
|
||||
|
||||
task_user_notification =
|
||||
|
|
@ -276,7 +281,7 @@ defmodule Pleroma.NotificationTest do
|
|||
{:ok, _topic} =
|
||||
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
|
||||
|
||||
assert_receive {:render_with_user, _, _, _}, 4_000
|
||||
assert_receive {:render_with_user, _, _, _, _}, 4_000
|
||||
end)
|
||||
|
||||
activity = insert(:note_activity)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
alias Pleroma.Instances
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
|
||||
setup do
|
||||
|
|
@ -97,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
|
||||
|
|
@ -216,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"
|
||||
)
|
||||
|
|
@ -284,6 +287,8 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
|
||||
describe "refetching" do
|
||||
setup do
|
||||
insert(:user, ap_id: "https://mastodon.social/users/emelie")
|
||||
|
||||
object1 = %{
|
||||
"id" => "https://mastodon.social/1",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
|
|
@ -293,10 +298,14 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z",
|
||||
"updated" => "2023-05-09 23:43:20Z"
|
||||
}
|
||||
|
||||
{:ok, local_object1, _} = ObjectValidator.validate(object1, [])
|
||||
|
||||
object2 = %{
|
||||
"id" => "https://mastodon.social/2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
|
|
@ -306,8 +315,10 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z",
|
||||
"updated" => "2023-05-09 23:43:25Z",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
|
|
@ -319,14 +330,18 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z",
|
||||
"updated" => "2023-05-09 23:43:21Z"
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, local_object2, _} = ObjectValidator.validate(object2, [])
|
||||
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
|
|
@ -335,7 +350,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object1)
|
||||
body: Jason.encode!(object1 |> Map.put("updated", "2023-05-09 23:44:20Z"))
|
||||
}
|
||||
|
||||
%{
|
||||
|
|
@ -345,7 +360,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object2)
|
||||
body: Jason.encode!(object2 |> Map.put("updated", "2023-05-09 23:44:20Z"))
|
||||
}
|
||||
|
||||
%{
|
||||
|
|
@ -370,7 +385,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
apply(HttpRequestMock, :request, [env])
|
||||
end)
|
||||
|
||||
%{object1: object1, object2: object2}
|
||||
%{object1: local_object1, object2: local_object2}
|
||||
end
|
||||
|
||||
test "it keeps formerRepresentations if remote does not have this attr", %{object1: object1} do
|
||||
|
|
@ -388,8 +403,9 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
"to" => [Pleroma.Constants.as_public()],
|
||||
"summary" => "",
|
||||
"published" => "2023-05-08 23:43:20Z"
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
|
|
@ -467,6 +483,53 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
}
|
||||
} = refetched.data
|
||||
end
|
||||
|
||||
test "it keeps the history intact if only updated time has changed",
|
||||
%{object1: object1} do
|
||||
full_object1 =
|
||||
object1
|
||||
|> Map.merge(%{
|
||||
"updated" => "2023-05-08 23:43:47Z",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"type" => "Note", "content" => "mew mew 1"}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
})
|
||||
|
||||
{:ok, o} = Object.create(full_object1)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{
|
||||
"content" => "test 1",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{"content" => "mew mew 1"}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
} = refetched.data
|
||||
end
|
||||
|
||||
test "it goes through ObjectValidator and MRF", %{object2: object2} do
|
||||
with_mock Pleroma.Web.ActivityPub.MRF, [:passthrough],
|
||||
filter: fn
|
||||
%{"type" => "Note"} = object ->
|
||||
{:ok, Map.put(object, "content", "MRFd content")}
|
||||
|
||||
arg ->
|
||||
passthrough([arg])
|
||||
end do
|
||||
{:ok, o} = Object.create(object2)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{"content" => "MRFd content"} = refetched.data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetch with history" do
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.ObjectTest do
|
|||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
|
||||
|
|
@ -15,10 +16,12 @@ defmodule Pleroma.ObjectTest do
|
|||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
setup do
|
||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
ConfigMock |> stub_with(Pleroma.Test.StaticConfig)
|
||||
:ok
|
||||
end
|
||||
|
||||
|
|
@ -444,4 +447,42 @@ defmodule Pleroma.ObjectTest do
|
|||
Enum.sort_by(object.hashtags, & &1.name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_emoji_reactions/1" do
|
||||
test "3-tuple current format" do
|
||||
object = %Object{
|
||||
data: %{
|
||||
"reactions" => [
|
||||
["x", ["https://some/user"], "https://some/emoji"]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
assert Object.get_emoji_reactions(object) == object.data["reactions"]
|
||||
end
|
||||
|
||||
test "2-tuple legacy format" do
|
||||
object = %Object{
|
||||
data: %{
|
||||
"reactions" => [
|
||||
["x", ["https://some/user"]]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
|
||||
end
|
||||
|
||||
test "Map format" do
|
||||
object = %Object{
|
||||
data: %{
|
||||
"reactions" => %{
|
||||
"x" => ["https://some/user"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"}
|
||||
|
|
|
|||
|
|
@ -3,19 +3,23 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.ScheduledActivityTest do
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.Test.StaticConfig
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do: clear_config([ScheduledActivity, :enabled])
|
||||
|
||||
setup [:ensure_local_uploader]
|
||||
|
||||
describe "creation" do
|
||||
test "scheduled activities with jobs when ScheduledActivity enabled" do
|
||||
clear_config([ScheduledActivity, :enabled], true)
|
||||
ConfigMock
|
||||
|> stub(:get, fn
|
||||
[ScheduledActivity, :enabled] -> true
|
||||
path -> StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
today =
|
||||
|
|
@ -34,7 +38,12 @@ defmodule Pleroma.ScheduledActivityTest do
|
|||
end
|
||||
|
||||
test "scheduled activities without jobs when ScheduledActivity disabled" do
|
||||
clear_config([ScheduledActivity, :enabled], false)
|
||||
ConfigMock
|
||||
|> stub(:get, fn
|
||||
[ScheduledActivity, :enabled] -> false
|
||||
path -> StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
today =
|
||||
|
|
@ -53,6 +62,9 @@ defmodule Pleroma.ScheduledActivityTest do
|
|||
end
|
||||
|
||||
test "when daily user limit is exceeded" do
|
||||
ConfigMock
|
||||
|> stub_with(StaticConfig)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
today =
|
||||
|
|
@ -69,6 +81,9 @@ defmodule Pleroma.ScheduledActivityTest do
|
|||
end
|
||||
|
||||
test "when total user limit is exceeded" do
|
||||
ConfigMock
|
||||
|> stub_with(StaticConfig)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
today =
|
||||
|
|
@ -89,6 +104,9 @@ defmodule Pleroma.ScheduledActivityTest do
|
|||
end
|
||||
|
||||
test "when scheduled_at is earlier than 5 minute from now" do
|
||||
ConfigMock
|
||||
|> stub_with(StaticConfig)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
scheduled_at =
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Activity.SearchTest do
|
||||
alias Pleroma.Activity.Search
|
||||
defmodule Pleroma.Search.DatabaseSearchTest do
|
||||
alias Pleroma.Search.DatabaseSearch, as: Search
|
||||
alias Pleroma.Web.CommonAPI
|
||||
import Pleroma.Factory
|
||||
|
||||
160
test/pleroma/search/meilisearch_test.exs
Normal file
160
test/pleroma/search/meilisearch_test.exs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Search.MeilisearchTest do
|
||||
require Pleroma.Constants
|
||||
|
||||
use Pleroma.DataCase, async: true
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
import Mox
|
||||
|
||||
alias Pleroma.Search.Meilisearch
|
||||
alias Pleroma.UnstubbedConfigMock, as: Config
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Workers.SearchIndexingWorker
|
||||
|
||||
describe "meilisearch" do
|
||||
test "indexes a local post on creation" do
|
||||
user = insert(:user)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
method: :put,
|
||||
url: "http://127.0.0.1:7700/indexes/objects/documents",
|
||||
body: body
|
||||
} ->
|
||||
assert match?(
|
||||
[%{"content" => "guys i just don't wanna leave the swamp"}],
|
||||
Jason.decode!(body)
|
||||
)
|
||||
|
||||
# To make sure that the worker is called
|
||||
send(self(), "posted_to_meilisearch")
|
||||
|
||||
%{
|
||||
"enqueuedAt" => "2023-11-12T12:36:46.927517Z",
|
||||
"indexUid" => "objects",
|
||||
"status" => "enqueued",
|
||||
"taskUid" => 6,
|
||||
"type" => "documentAdditionOrUpdate"
|
||||
}
|
||||
|> json()
|
||||
end)
|
||||
|
||||
Config
|
||||
|> expect(:get, 3, fn
|
||||
[Pleroma.Search, :module], nil ->
|
||||
Meilisearch
|
||||
|
||||
[Pleroma.Search.Meilisearch, :url], nil ->
|
||||
"http://127.0.0.1:7700"
|
||||
|
||||
[Pleroma.Search.Meilisearch, :private_key], nil ->
|
||||
"secret"
|
||||
end)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "guys i just don't wanna leave the swamp",
|
||||
visibility: "public"
|
||||
})
|
||||
|
||||
args = %{"op" => "add_to_index", "activity" => activity.id}
|
||||
|
||||
assert_enqueued(
|
||||
worker: SearchIndexingWorker,
|
||||
args: args
|
||||
)
|
||||
|
||||
assert :ok = perform_job(SearchIndexingWorker, args)
|
||||
assert_received("posted_to_meilisearch")
|
||||
end
|
||||
|
||||
test "doesn't index posts that are not public" do
|
||||
user = insert(:user)
|
||||
|
||||
Enum.each(["private", "direct"], fn visibility ->
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "guys i just don't wanna leave the swamp",
|
||||
visibility: visibility
|
||||
})
|
||||
|
||||
args = %{"op" => "add_to_index", "activity" => activity.id}
|
||||
|
||||
Config
|
||||
|> expect(:get, fn
|
||||
[Pleroma.Search, :module], nil ->
|
||||
Meilisearch
|
||||
end)
|
||||
|
||||
assert_enqueued(worker: SearchIndexingWorker, args: args)
|
||||
assert :ok = perform_job(SearchIndexingWorker, args)
|
||||
end)
|
||||
end
|
||||
|
||||
test "deletes posts from index when deleted locally" do
|
||||
user = insert(:user)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
method: :put,
|
||||
url: "http://127.0.0.1:7700/indexes/objects/documents",
|
||||
body: body
|
||||
} ->
|
||||
assert match?(
|
||||
[%{"content" => "guys i just don't wanna leave the swamp"}],
|
||||
Jason.decode!(body)
|
||||
)
|
||||
|
||||
%{
|
||||
"enqueuedAt" => "2023-11-12T12:36:46.927517Z",
|
||||
"indexUid" => "objects",
|
||||
"status" => "enqueued",
|
||||
"taskUid" => 6,
|
||||
"type" => "documentAdditionOrUpdate"
|
||||
}
|
||||
|> json()
|
||||
|
||||
%{method: :delete, url: "http://127.0.0.1:7700/indexes/objects/documents/" <> id} ->
|
||||
send(self(), "called_delete")
|
||||
assert String.length(id) > 1
|
||||
json(%{})
|
||||
end)
|
||||
|
||||
Config
|
||||
|> expect(:get, 6, fn
|
||||
[Pleroma.Search, :module], nil ->
|
||||
Meilisearch
|
||||
|
||||
[Pleroma.Search.Meilisearch, :url], nil ->
|
||||
"http://127.0.0.1:7700"
|
||||
|
||||
[Pleroma.Search.Meilisearch, :private_key], nil ->
|
||||
"secret"
|
||||
end)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "guys i just don't wanna leave the swamp",
|
||||
visibility: "public"
|
||||
})
|
||||
|
||||
args = %{"op" => "add_to_index", "activity" => activity.id}
|
||||
assert_enqueued(worker: SearchIndexingWorker, args: args)
|
||||
assert :ok = perform_job(SearchIndexingWorker, args)
|
||||
|
||||
{:ok, _} = CommonAPI.delete(activity.id, user)
|
||||
|
||||
delete_args = %{"op" => "remove_from_index", "object" => activity.object.id}
|
||||
assert_enqueued(worker: SearchIndexingWorker, args: delete_args)
|
||||
assert :ok = perform_job(SearchIndexingWorker, delete_args)
|
||||
|
||||
assert_received("called_delete")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -43,10 +43,7 @@ defmodule Pleroma.SignatureTest do
|
|||
end
|
||||
|
||||
test "it returns error when not found user" do
|
||||
assert capture_log(fn ->
|
||||
assert Signature.fetch_public_key(make_fake_conn("https://test-ap-id")) ==
|
||||
{:error, :error}
|
||||
end) =~ "[error] Could not decode user"
|
||||
assert Signature.fetch_public_key(make_fake_conn("https://test-ap-id")) == {:error, :error}
|
||||
end
|
||||
|
||||
test "it returns error if public key is nil" do
|
||||
|
|
@ -116,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"}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,20 @@ defmodule Pleroma.Upload.Filter.AnalyzeMetadataTest do
|
|||
assert meta.blurhash
|
||||
end
|
||||
|
||||
test "it blurhashes images with an alpha component" do
|
||||
upload = %Pleroma.Upload{
|
||||
name: "an… image.jpg",
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/png_with_transparency.png"),
|
||||
tempfile: Path.absname("test/fixtures/png_with_transparency.png")
|
||||
}
|
||||
|
||||
{:ok, :filtered, meta} = AnalyzeMetadata.filter(upload)
|
||||
|
||||
assert %{width: 320, height: 320} = meta
|
||||
assert meta.blurhash == "eXJi-E:SwCEm5rCmn$+YWYn+15K#5A$xxCi{SiV]s*W:Efa#s.jE-T"
|
||||
end
|
||||
|
||||
test "adds the dimensions for videos" do
|
||||
upload = %Pleroma.Upload{
|
||||
name: "coolvideo.mp4",
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Upload.Filter.Exiftool.ReadDescriptionTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Upload.Filter
|
||||
|
||||
@uploads %Pleroma.Upload{
|
||||
|
|
|
|||
32
test/pleroma/upload/filter/only_media_test.exs
Normal file
32
test/pleroma/upload/filter/only_media_test.exs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Upload.Filter.OnlyMediaTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.Upload
|
||||
alias Pleroma.Upload.Filter.OnlyMedia
|
||||
|
||||
test "Allows media Content-Type" do
|
||||
["audio/mpeg", "image/jpeg", "video/mp4"]
|
||||
|> Enum.each(fn type ->
|
||||
upload = %Upload{
|
||||
content_type: type
|
||||
}
|
||||
|
||||
assert {:ok, :noop} = OnlyMedia.filter(upload)
|
||||
end)
|
||||
end
|
||||
|
||||
test "Disallows non-media Content-Type" do
|
||||
["application/javascript", "application/pdf", "text/html"]
|
||||
|> Enum.each(fn type ->
|
||||
upload = %Upload{
|
||||
content_type: type
|
||||
}
|
||||
|
||||
assert {:error, _} = OnlyMedia.filter(upload)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
@ -6,10 +6,19 @@ defmodule Pleroma.UploadTest do
|
|||
use Pleroma.DataCase
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Upload
|
||||
alias Pleroma.Uploaders.Uploader
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
@upload_file %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
|
|
@ -236,6 +245,8 @@ defmodule Pleroma.UploadTest do
|
|||
describe "Setting a custom base_url for uploaded media" do
|
||||
setup do: clear_config([Pleroma.Upload, :base_url], "https://cache.pleroma.social")
|
||||
|
||||
# This seems to be backwards. Skipped for that reason
|
||||
@tag skip: true
|
||||
test "returns a media url with configured base_url" do
|
||||
base_url = Pleroma.Config.get([Pleroma.Upload, :base_url])
|
||||
|
||||
|
|
|
|||
|
|
@ -3,22 +3,27 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Uploaders.S3Test do
|
||||
use Pleroma.DataCase
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Uploaders.S3
|
||||
alias Pleroma.Uploaders.S3.ExAwsMock
|
||||
|
||||
import Mock
|
||||
import Mox
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
setup do
|
||||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.S3)
|
||||
clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
|
||||
clear_config([Pleroma.Uploaders.S3])
|
||||
clear_config([Pleroma.Uploaders.S3, :bucket], "test_bucket")
|
||||
end
|
||||
|
||||
describe "get_file/1" do
|
||||
test "it returns path to local folder for files" do
|
||||
test "it returns url for files" do
|
||||
ConfigMock
|
||||
|> expect(:get, 6, fn key ->
|
||||
[
|
||||
{Pleroma.Upload,
|
||||
[uploader: Pleroma.Uploaders.S3, base_url: "https://s3.amazonaws.com"]},
|
||||
{Pleroma.Uploaders.S3, [bucket: "test_bucket"]}
|
||||
]
|
||||
|> get_in(key)
|
||||
end)
|
||||
|
||||
assert S3.get_file("test_image.jpg") == {
|
||||
:ok,
|
||||
{:url, "https://s3.amazonaws.com/test_bucket/test_image.jpg"}
|
||||
|
|
@ -26,13 +31,16 @@ defmodule Pleroma.Uploaders.S3Test do
|
|||
end
|
||||
|
||||
test "it returns path without bucket when truncated_namespace set to ''" do
|
||||
clear_config([Pleroma.Uploaders.S3],
|
||||
bucket: "test_bucket",
|
||||
bucket_namespace: "myaccount",
|
||||
truncated_namespace: ""
|
||||
)
|
||||
|
||||
clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
|
||||
ConfigMock
|
||||
|> expect(:get, 6, fn key ->
|
||||
[
|
||||
{Pleroma.Upload,
|
||||
[uploader: Pleroma.Uploaders.S3, base_url: "https://s3.amazonaws.com"]},
|
||||
{Pleroma.Uploaders.S3,
|
||||
[bucket: "test_bucket", truncated_namespace: "", bucket_namespace: "myaccount"]}
|
||||
]
|
||||
|> get_in(key)
|
||||
end)
|
||||
|
||||
assert S3.get_file("test_image.jpg") == {
|
||||
:ok,
|
||||
|
|
@ -41,10 +49,15 @@ defmodule Pleroma.Uploaders.S3Test do
|
|||
end
|
||||
|
||||
test "it returns path with bucket namespace when namespace is set" do
|
||||
clear_config([Pleroma.Uploaders.S3],
|
||||
bucket: "test_bucket",
|
||||
bucket_namespace: "family"
|
||||
)
|
||||
ConfigMock
|
||||
|> expect(:get, 6, fn key ->
|
||||
[
|
||||
{Pleroma.Upload,
|
||||
[uploader: Pleroma.Uploaders.S3, base_url: "https://s3.amazonaws.com"]},
|
||||
{Pleroma.Uploaders.S3, [bucket: "test_bucket", bucket_namespace: "family"]}
|
||||
]
|
||||
|> get_in(key)
|
||||
end)
|
||||
|
||||
assert S3.get_file("test_image.jpg") == {
|
||||
:ok,
|
||||
|
|
@ -62,28 +75,42 @@ defmodule Pleroma.Uploaders.S3Test do
|
|||
tempfile: Path.absname("test/instance_static/add/shortcode.png")
|
||||
}
|
||||
|
||||
ConfigMock
|
||||
|> expect(:get, fn [Pleroma.Uploaders.S3] ->
|
||||
[
|
||||
bucket: "test_bucket"
|
||||
]
|
||||
end)
|
||||
|
||||
[file_upload: file_upload]
|
||||
end
|
||||
|
||||
test "save file", %{file_upload: file_upload} do
|
||||
with_mock ExAws, request: fn _ -> {:ok, :ok} end do
|
||||
assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}}
|
||||
end
|
||||
ExAwsMock
|
||||
|> expect(:request, fn _req -> {:ok, %{status_code: 200}} end)
|
||||
|
||||
assert S3.put_file(file_upload) == {:ok, {:file, "test_folder/image-tet.jpg"}}
|
||||
end
|
||||
|
||||
test "returns error", %{file_upload: file_upload} do
|
||||
with_mock ExAws, request: fn _ -> {:error, "S3 Upload failed"} end do
|
||||
assert capture_log(fn ->
|
||||
assert S3.put_file(file_upload) == {:error, "S3 Upload failed"}
|
||||
end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}"
|
||||
end
|
||||
ExAwsMock
|
||||
|> expect(:request, fn _req -> {:error, "S3 Upload failed"} end)
|
||||
|
||||
assert capture_log(fn ->
|
||||
assert S3.put_file(file_upload) == {:error, "S3 Upload failed"}
|
||||
end) =~ "Elixir.Pleroma.Uploaders.S3: {:error, \"S3 Upload failed\"}"
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_file/1" do
|
||||
test_with_mock "deletes file", ExAws, request: fn _req -> {:ok, %{status_code: 204}} end do
|
||||
test "deletes file" do
|
||||
ExAwsMock
|
||||
|> expect(:request, fn _req -> {:ok, %{status_code: 204}} end)
|
||||
|
||||
ConfigMock
|
||||
|> expect(:get, fn [Pleroma.Uploaders.S3, :bucket] -> "test_bucket" end)
|
||||
|
||||
assert :ok = S3.delete_file("image.jpg")
|
||||
assert_called(ExAws.request(:_))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
51
test/pleroma/user/backup_async_test.exs
Normal file
51
test/pleroma/user/backup_async_test.exs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.User.BackupAsyncTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mox
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User.Backup
|
||||
alias Pleroma.User.Backup.ProcessorMock
|
||||
|
||||
setup do
|
||||
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
|
||||
|
||||
{:ok, backup} = user |> Backup.new() |> Repo.insert()
|
||||
%{backup: backup}
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "it handles unrecoverable exceptions", %{backup: backup} do
|
||||
ProcessorMock
|
||||
|> expect(:do_process, fn _, _ ->
|
||||
raise "mock exception"
|
||||
end)
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Config)
|
||||
|
||||
{:error, %{backup: backup, reason: :exit}} = Backup.process(backup, ProcessorMock)
|
||||
|
||||
assert backup.state == :failed
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "it handles timeouts", %{backup: backup} do
|
||||
ProcessorMock
|
||||
|> expect(:do_process, fn _, _ ->
|
||||
Process.sleep(:timer.seconds(4))
|
||||
end)
|
||||
|
||||
ConfigMock
|
||||
|> expect(:get, fn [Pleroma.User.Backup, :process_wait_time] -> :timer.seconds(2) end)
|
||||
|
||||
{:error, %{backup: backup, reason: :timeout}} = Backup.process(backup, ProcessorMock)
|
||||
|
||||
assert backup.state == :failed
|
||||
end
|
||||
end
|
||||
|
|
@ -9,10 +9,14 @@ defmodule Pleroma.User.BackupTest do
|
|||
import Mock
|
||||
import Pleroma.Factory
|
||||
import Swoosh.TestAssertions
|
||||
import Mox
|
||||
|
||||
alias Pleroma.Bookmark
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Uploaders.S3.ExAwsMock
|
||||
alias Pleroma.User.Backup
|
||||
alias Pleroma.User.Backup.ProcessorMock
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Workers.BackupWorker
|
||||
|
||||
|
|
@ -20,6 +24,14 @@ defmodule Pleroma.User.BackupTest do
|
|||
clear_config([Pleroma.Upload, :uploader])
|
||||
clear_config([Backup, :limit_days])
|
||||
clear_config([Pleroma.Emails.Mailer, :enabled], true)
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Config)
|
||||
|
||||
ProcessorMock
|
||||
|> stub_with(Pleroma.User.Backup.Processor)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "it does not requrie enabled email" do
|
||||
|
|
@ -39,7 +51,7 @@ defmodule Pleroma.User.BackupTest do
|
|||
assert_enqueued(worker: BackupWorker, args: args)
|
||||
|
||||
backup = Backup.get(args["backup_id"])
|
||||
assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup
|
||||
assert %Backup{user_id: ^user_id, processed: false, file_size: 0, state: :pending} = backup
|
||||
end
|
||||
|
||||
test "it return an error if the export limit is over" do
|
||||
|
|
@ -59,7 +71,30 @@ defmodule Pleroma.User.BackupTest do
|
|||
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
|
||||
assert {:ok, backup} = perform_job(BackupWorker, args)
|
||||
assert backup.file_size > 0
|
||||
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
|
||||
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
|
||||
|
||||
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
|
||||
|
||||
assert_enqueued(worker: BackupWorker, args: delete_job_args)
|
||||
assert {:ok, backup} = perform_job(BackupWorker, delete_job_args)
|
||||
refute Backup.get(backup_id)
|
||||
|
||||
email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup)
|
||||
|
||||
assert_email_sent(
|
||||
to: {user.name, user.email},
|
||||
html_body: email.html_body
|
||||
)
|
||||
end
|
||||
|
||||
test "it updates states of the backup" do
|
||||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||
%{id: user_id} = user = insert(:user)
|
||||
|
||||
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
|
||||
assert {:ok, backup} = perform_job(BackupWorker, args)
|
||||
assert backup.file_size > 0
|
||||
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
|
||||
|
||||
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
|
||||
|
||||
|
|
@ -148,7 +183,7 @@ defmodule Pleroma.User.BackupTest do
|
|||
Bookmark.create(user.id, status3.id)
|
||||
|
||||
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
|
||||
assert {:ok, path} = Backup.export(backup)
|
||||
assert {:ok, path} = Backup.export(backup, self())
|
||||
assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(path), [:memory])
|
||||
assert {:ok, {'actor.json', json}} = :zip.zip_get('actor.json', zipfile)
|
||||
|
||||
|
|
@ -230,6 +265,55 @@ defmodule Pleroma.User.BackupTest do
|
|||
File.rm!(path)
|
||||
end
|
||||
|
||||
test "it counts the correct number processed" do
|
||||
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
|
||||
|
||||
Enum.map(1..120, fn i ->
|
||||
{:ok, status} = CommonAPI.post(user, %{status: "status #{i}"})
|
||||
CommonAPI.favorite(user, status.id)
|
||||
Bookmark.create(user.id, status.id)
|
||||
end)
|
||||
|
||||
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
|
||||
{:ok, backup} = Backup.process(backup)
|
||||
|
||||
assert backup.processed_number == 1 + 120 + 120 + 120
|
||||
|
||||
Backup.delete(backup)
|
||||
end
|
||||
|
||||
test "it handles errors" do
|
||||
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
|
||||
|
||||
Enum.map(1..120, fn i ->
|
||||
{:ok, _status} = CommonAPI.post(user, %{status: "status #{i}"})
|
||||
end)
|
||||
|
||||
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
|
||||
|
||||
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
|
||||
[:passthrough],
|
||||
prepare_outgoing: fn data ->
|
||||
object =
|
||||
data["object"]
|
||||
|> Pleroma.Object.normalize(fetch: false)
|
||||
|> Map.get(:data)
|
||||
|
||||
data = data |> Map.put("object", object)
|
||||
|
||||
if String.contains?(data["object"]["content"], "119"),
|
||||
do: raise(%Postgrex.Error{}),
|
||||
else: {:ok, data}
|
||||
end do
|
||||
{:ok, backup} = Backup.process(backup)
|
||||
assert backup.processed
|
||||
assert backup.state == :complete
|
||||
assert backup.processed_number == 1 + 119
|
||||
|
||||
Backup.delete(backup)
|
||||
end
|
||||
end
|
||||
|
||||
describe "it uploads and deletes a backup archive" do
|
||||
setup do
|
||||
clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
|
||||
|
|
@ -246,7 +330,7 @@ defmodule Pleroma.User.BackupTest do
|
|||
Bookmark.create(user.id, status3.id)
|
||||
|
||||
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
|
||||
assert {:ok, path} = Backup.export(backup)
|
||||
assert {:ok, path} = Backup.export(backup, self())
|
||||
|
||||
[path: path, backup: backup]
|
||||
end
|
||||
|
|
@ -255,14 +339,14 @@ defmodule Pleroma.User.BackupTest do
|
|||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.S3)
|
||||
clear_config([Pleroma.Uploaders.S3, :streaming_enabled], false)
|
||||
|
||||
with_mock ExAws,
|
||||
request: fn
|
||||
%{http_method: :put} -> {:ok, :ok}
|
||||
%{http_method: :delete} -> {:ok, %{status_code: 204}}
|
||||
end do
|
||||
assert {:ok, %Pleroma.Upload{}} = Backup.upload(backup, path)
|
||||
assert {:ok, _backup} = Backup.delete(backup)
|
||||
end
|
||||
ExAwsMock
|
||||
|> expect(:request, 2, fn
|
||||
%{http_method: :put} -> {:ok, :ok}
|
||||
%{http_method: :delete} -> {:ok, %{status_code: 204}}
|
||||
end)
|
||||
|
||||
assert {:ok, %Pleroma.Upload{}} = Backup.upload(backup, path)
|
||||
assert {:ok, _backup} = Backup.delete(backup)
|
||||
end
|
||||
|
||||
test "Local", %{path: path, backup: backup} do
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ defmodule Pleroma.UserTest do
|
|||
import ExUnit.CaptureLog
|
||||
import Swoosh.TestAssertions
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
|
|
@ -221,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)
|
||||
|
|
@ -245,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)
|
||||
|
|
@ -868,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
|
||||
|
|
@ -1013,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
|
||||
|
|
@ -1127,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 ==
|
||||
|
|
@ -1844,7 +1849,6 @@ defmodule Pleroma.UserTest do
|
|||
confirmation_token: "qqqq",
|
||||
domain_blocks: ["lain.com"],
|
||||
is_active: false,
|
||||
ap_enabled: true,
|
||||
is_moderator: true,
|
||||
is_admin: true,
|
||||
mascot: %{"a" => "b"},
|
||||
|
|
@ -1885,7 +1889,6 @@ defmodule Pleroma.UserTest do
|
|||
confirmation_token: nil,
|
||||
domain_blocks: [],
|
||||
is_active: false,
|
||||
ap_enabled: false,
|
||||
is_moderator: false,
|
||||
is_admin: false,
|
||||
mascot: nil,
|
||||
|
|
@ -1948,8 +1951,8 @@ defmodule Pleroma.UserTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "get_public_key_for_ap_id fetches a user that's not in the db" do
|
||||
assert {:ok, _key} = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
||||
test "get_public_key_for_ap_id returns correctly for user that's not in the db" do
|
||||
assert :error = User.get_public_key_for_ap_id("http://mastodon.example.org/users/admin")
|
||||
end
|
||||
|
||||
describe "per-user rich-text filtering" do
|
||||
|
|
@ -2421,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
|
||||
|
||||
|
|
@ -2473,8 +2476,7 @@ defmodule Pleroma.UserTest do
|
|||
insert(:user,
|
||||
local: false,
|
||||
follower_address: "http://localhost:4001/users/masto_closed/followers",
|
||||
following_address: "http://localhost:4001/users/masto_closed/following",
|
||||
ap_enabled: true
|
||||
following_address: "http://localhost:4001/users/masto_closed/following"
|
||||
)
|
||||
|
||||
assert other_user.following_count == 0
|
||||
|
|
@ -2495,8 +2497,7 @@ defmodule Pleroma.UserTest do
|
|||
insert(:user,
|
||||
local: false,
|
||||
follower_address: "http://localhost:4001/users/masto_closed/followers",
|
||||
following_address: "http://localhost:4001/users/masto_closed/following",
|
||||
ap_enabled: true
|
||||
following_address: "http://localhost:4001/users/masto_closed/following"
|
||||
)
|
||||
|
||||
assert other_user.following_count == 0
|
||||
|
|
@ -2517,8 +2518,7 @@ defmodule Pleroma.UserTest do
|
|||
insert(:user,
|
||||
local: false,
|
||||
follower_address: "http://localhost:4001/users/masto_closed/followers",
|
||||
following_address: "http://localhost:4001/users/masto_closed/following",
|
||||
ap_enabled: true
|
||||
following_address: "http://localhost:4001/users/masto_closed/following"
|
||||
)
|
||||
|
||||
assert other_user.following_count == 0
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
|
||||
require Pleroma.Constants
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
|
|
@ -216,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()
|
||||
|
|
@ -233,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()
|
||||
|
|
@ -254,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()
|
||||
|
|
@ -431,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()
|
||||
|
||||
|
|
@ -447,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()
|
||||
|
||||
|
|
@ -575,7 +580,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
user =
|
||||
insert(:user,
|
||||
ap_id: "https://mastodon.example.org/users/raymoo",
|
||||
ap_enabled: true,
|
||||
local: false,
|
||||
last_refreshed_at: nil
|
||||
)
|
||||
|
|
@ -891,6 +895,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert Activity.get_by_ap_id(data["id"])
|
||||
end
|
||||
|
||||
test "it rejects an invalid incoming activity", %{conn: conn, data: data} do
|
||||
user = insert(:user, is_active: false)
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("bcc", [user.ap_id])
|
||||
|> Kernel.put_in(["object", "bcc"], [user.ap_id])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:valid_signature, true)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{user.nickname}/inbox", data)
|
||||
|
||||
assert "Invalid request." == json_response(conn, 400)
|
||||
end
|
||||
|
||||
test "it accepts messages with to as string instead of array", %{conn: conn, data: data} do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
alias Pleroma.Config
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
|
@ -19,11 +20,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
|
||||
import ExUnit.CaptureLog
|
||||
import Mock
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
|
||||
setup do
|
||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
|
|
@ -174,7 +180,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
||||
assert user.ap_id == user_id
|
||||
assert user.nickname == "admin@mastodon.example.org"
|
||||
assert user.ap_enabled
|
||||
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
|
||||
end
|
||||
|
||||
|
|
@ -771,6 +776,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert %{data: _data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
||||
assert object.data["repliesCount"] == 2
|
||||
end
|
||||
|
||||
test "increates quotes count", %{user: user} do
|
||||
user2 = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "1", visibility: "public"})
|
||||
ap_id = activity.data["id"]
|
||||
quote_data = %{status: "1", quote_id: activity.id}
|
||||
|
||||
# public
|
||||
{:ok, _} = CommonAPI.post(user2, Map.put(quote_data, :visibility, "public"))
|
||||
assert %{data: _data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
||||
assert object.data["quotesCount"] == 1
|
||||
|
||||
# unlisted
|
||||
{:ok, _} = CommonAPI.post(user2, Map.put(quote_data, :visibility, "unlisted"))
|
||||
assert %{data: _data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
||||
assert object.data["quotesCount"] == 2
|
||||
|
||||
# private
|
||||
{:ok, _} = CommonAPI.post(user2, Map.put(quote_data, :visibility, "private"))
|
||||
assert %{data: _data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
||||
assert object.data["quotesCount"] == 2
|
||||
|
||||
# direct
|
||||
{:ok, _} = CommonAPI.post(user2, Map.put(quote_data, :visibility, "direct"))
|
||||
assert %{data: _data, object: object} = Activity.get_by_ap_id_with_object(ap_id)
|
||||
assert object.data["quotesCount"] == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetch activities for recipients" do
|
||||
|
|
@ -995,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"
|
||||
|
|
@ -1342,6 +1375,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
%{test_file: test_file}
|
||||
end
|
||||
|
||||
test "strips / from filename", %{test_file: file} do
|
||||
file = %Plug.Upload{file | filename: "../../../../../nested/bad.jpg"}
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file)
|
||||
[%{"href" => href}] = object.data["url"]
|
||||
assert Regex.match?(~r"/bad.jpg$", href)
|
||||
refute Regex.match?(~r"/nested/", href)
|
||||
end
|
||||
|
||||
test "sets a description if given", %{test_file: file} do
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file, description: "a cool file")
|
||||
assert object.data["name"] == "a cool file"
|
||||
|
|
@ -2645,4 +2686,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
{:ok, user} = ActivityPub.make_user_from_ap_id("https://princess.cat/users/mewmew")
|
||||
assert user.name == " "
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "pin_data_from_featured_collection will ignore unsupported values" do
|
||||
assert %{} ==
|
||||
ActivityPub.pin_data_from_featured_collection(%{
|
||||
"type" => "OrderedCollection",
|
||||
"first" => "https://social.example/users/alice/collections/featured?page=true"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44,5 +44,34 @@ defmodule Pleroma.Web.ActivityPub.BuilderTest do
|
|||
|
||||
assert {:ok, ^expected, []} = Builder.note(draft)
|
||||
end
|
||||
|
||||
test "quote post" do
|
||||
user = insert(:user)
|
||||
note = insert(:note)
|
||||
|
||||
draft = %ActivityDraft{
|
||||
user: user,
|
||||
context: "2hu",
|
||||
content_html: "<h1>This is :moominmamma: note</h1>",
|
||||
quote_post: note,
|
||||
extra: %{}
|
||||
}
|
||||
|
||||
expected = %{
|
||||
"actor" => user.ap_id,
|
||||
"attachment" => [],
|
||||
"content" => "<h1>This is :moominmamma: note</h1>",
|
||||
"context" => "2hu",
|
||||
"sensitive" => false,
|
||||
"type" => "Note",
|
||||
"quoteUrl" => note.data["id"],
|
||||
"cc" => [],
|
||||
"summary" => nil,
|
||||
"tag" => [],
|
||||
"to" => []
|
||||
}
|
||||
|
||||
assert {:ok, ^expected, []} = Builder.note(draft)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
425
test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs
Normal file
425
test/pleroma/web/activity_pub/mrf/emoji_policy_test.exs
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.EmojiPolicy
|
||||
|
||||
setup do: clear_config(:mrf_emoji)
|
||||
|
||||
setup do
|
||||
clear_config([:mrf_emoji], %{
|
||||
remove_url: [],
|
||||
remove_shortcode: [],
|
||||
federated_timeline_removal_url: [],
|
||||
federated_timeline_removal_shortcode: []
|
||||
})
|
||||
end
|
||||
|
||||
@emoji_tags [
|
||||
%{
|
||||
"icon" => %{
|
||||
"type" => "Image",
|
||||
"url" => "https://example.org/emoji/biribiri/mikoto_smile2.png"
|
||||
},
|
||||
"id" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
|
||||
"name" => ":mikoto_smile2:",
|
||||
"type" => "Emoji",
|
||||
"updated" => "1970-01-01T00:00:00Z"
|
||||
},
|
||||
%{
|
||||
"icon" => %{
|
||||
"type" => "Image",
|
||||
"url" => "https://example.org/emoji/biribiri/mikoto_smile3.png"
|
||||
},
|
||||
"id" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
|
||||
"name" => ":mikoto_smile3:",
|
||||
"type" => "Emoji",
|
||||
"updated" => "1970-01-01T00:00:00Z"
|
||||
},
|
||||
%{
|
||||
"icon" => %{
|
||||
"type" => "Image",
|
||||
"url" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
},
|
||||
"id" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
|
||||
"name" => ":nekomimi_girl_emoji_007:",
|
||||
"type" => "Emoji",
|
||||
"updated" => "1970-01-01T00:00:00Z"
|
||||
},
|
||||
%{
|
||||
"icon" => %{
|
||||
"type" => "Image",
|
||||
"url" => "https://example.org/test.png"
|
||||
},
|
||||
"id" => "https://example.org/test.png",
|
||||
"name" => ":test:",
|
||||
"type" => "Emoji",
|
||||
"updated" => "1970-01-01T00:00:00Z"
|
||||
}
|
||||
]
|
||||
|
||||
@misc_tags [%{"type" => "Placeholder"}]
|
||||
|
||||
@user_data %{
|
||||
"type" => "Person",
|
||||
"id" => "https://example.org/placeholder",
|
||||
"name" => "lol",
|
||||
"tag" => @emoji_tags ++ @misc_tags
|
||||
}
|
||||
|
||||
@status_data %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"id" => "https://example.org/placeholder",
|
||||
"content" => "lol",
|
||||
"tag" => @emoji_tags ++ @misc_tags,
|
||||
"emoji" => %{
|
||||
"mikoto_smile2" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
|
||||
"mikoto_smile3" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
|
||||
"test" => "https://example.org/test.png"
|
||||
},
|
||||
"to" => ["https://example.org/self", Pleroma.Constants.as_public()],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
},
|
||||
"to" => ["https://example.org/self", Pleroma.Constants.as_public()],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
}
|
||||
|
||||
@status_data_with_history %{
|
||||
"type" => "Create",
|
||||
"object" =>
|
||||
@status_data["object"]
|
||||
|> Map.merge(%{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [@status_data["object"] |> Map.put("content", "older")],
|
||||
"totalItems" => 1
|
||||
}
|
||||
}),
|
||||
"to" => ["https://example.org/self", Pleroma.Constants.as_public()],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
}
|
||||
|
||||
@emoji_react_data %{
|
||||
"type" => "EmojiReact",
|
||||
"tag" => [@emoji_tags |> Enum.at(3)],
|
||||
"object" => "https://example.org/someobject",
|
||||
"to" => ["https://example.org/self"],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
}
|
||||
|
||||
@emoji_react_data_matching_regex %{
|
||||
"type" => "EmojiReact",
|
||||
"tag" => [@emoji_tags |> Enum.at(1)],
|
||||
"object" => "https://example.org/someobject",
|
||||
"to" => ["https://example.org/self"],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
}
|
||||
|
||||
@emoji_react_data_matching_nothing %{
|
||||
"type" => "EmojiReact",
|
||||
"tag" => [@emoji_tags |> Enum.at(2)],
|
||||
"object" => "https://example.org/someobject",
|
||||
"to" => ["https://example.org/self"],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
}
|
||||
|
||||
@emoji_react_data_unicode %{
|
||||
"type" => "EmojiReact",
|
||||
"content" => "😍",
|
||||
"object" => "https://example.org/someobject",
|
||||
"to" => ["https://example.org/self"],
|
||||
"cc" => ["https://example.org/someone"]
|
||||
}
|
||||
|
||||
describe "remove_url" do
|
||||
setup do
|
||||
clear_config([:mrf_emoji, :remove_url], [
|
||||
"https://example.org/test.png",
|
||||
~r{/biribiri/mikoto_smile[23]\.png},
|
||||
"nekomimi_girl_emoji"
|
||||
])
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "processes user" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
assert %{"tag" => ^expected_tags} = filtered
|
||||
end
|
||||
|
||||
test "processes status" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
expected_emoji = %{
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
}
|
||||
|
||||
assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
|
||||
end
|
||||
|
||||
test "processes status with history" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
expected_emoji = %{
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
}
|
||||
|
||||
assert %{
|
||||
"object" => %{
|
||||
"tag" => ^expected_tags,
|
||||
"emoji" => ^expected_emoji,
|
||||
"formerRepresentations" => %{"orderedItems" => [item]}
|
||||
}
|
||||
} = filtered
|
||||
|
||||
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
|
||||
end
|
||||
|
||||
test "processes updates" do
|
||||
{:ok, filtered} =
|
||||
MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
expected_emoji = %{
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
}
|
||||
|
||||
assert %{
|
||||
"object" => %{
|
||||
"tag" => ^expected_tags,
|
||||
"emoji" => ^expected_emoji,
|
||||
"formerRepresentations" => %{"orderedItems" => [item]}
|
||||
}
|
||||
} = filtered
|
||||
|
||||
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
|
||||
end
|
||||
|
||||
test "processes EmojiReact" do
|
||||
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data)
|
||||
|
||||
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
|
||||
|
||||
assert {:ok, @emoji_react_data_matching_nothing} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
|
||||
|
||||
assert {:ok, @emoji_react_data_unicode} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
|
||||
end
|
||||
end
|
||||
|
||||
describe "remove_shortcode" do
|
||||
setup do
|
||||
clear_config([:mrf_emoji, :remove_shortcode], [
|
||||
"test",
|
||||
~r{mikoto_s},
|
||||
"nekomimi_girl_emoji"
|
||||
])
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "processes user" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
assert %{"tag" => ^expected_tags} = filtered
|
||||
end
|
||||
|
||||
test "processes status" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
expected_emoji = %{
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
}
|
||||
|
||||
assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
|
||||
end
|
||||
|
||||
test "processes status with history" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
expected_emoji = %{
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
}
|
||||
|
||||
assert %{
|
||||
"object" => %{
|
||||
"tag" => ^expected_tags,
|
||||
"emoji" => ^expected_emoji,
|
||||
"formerRepresentations" => %{"orderedItems" => [item]}
|
||||
}
|
||||
} = filtered
|
||||
|
||||
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
|
||||
end
|
||||
|
||||
test "processes updates" do
|
||||
{:ok, filtered} =
|
||||
MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
|
||||
|
||||
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
|
||||
|
||||
expected_emoji = %{
|
||||
"nekomimi_girl_emoji_007" =>
|
||||
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
|
||||
}
|
||||
|
||||
assert %{
|
||||
"object" => %{
|
||||
"tag" => ^expected_tags,
|
||||
"emoji" => ^expected_emoji,
|
||||
"formerRepresentations" => %{"orderedItems" => [item]}
|
||||
}
|
||||
} = filtered
|
||||
|
||||
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
|
||||
end
|
||||
|
||||
test "processes EmojiReact" do
|
||||
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data)
|
||||
|
||||
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
|
||||
|
||||
assert {:ok, @emoji_react_data_matching_nothing} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
|
||||
|
||||
assert {:ok, @emoji_react_data_unicode} ==
|
||||
MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
|
||||
end
|
||||
end
|
||||
|
||||
describe "federated_timeline_removal_url" do
|
||||
setup do
|
||||
clear_config([:mrf_emoji, :federated_timeline_removal_url], [
|
||||
"https://example.org/test.png",
|
||||
~r{/biribiri/mikoto_smile[23]\.png},
|
||||
"nekomimi_girl_emoji"
|
||||
])
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "processes status" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
|
||||
|
||||
expected_tags = @status_data["object"]["tag"]
|
||||
expected_emoji = @status_data["object"]["emoji"]
|
||||
|
||||
expected_to = ["https://example.org/self"]
|
||||
expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
|
||||
|
||||
assert %{
|
||||
"to" => ^expected_to,
|
||||
"cc" => ^expected_cc,
|
||||
"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
|
||||
} = filtered
|
||||
end
|
||||
|
||||
test "ignore updates" do
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data |> Map.put("type", "Update"))
|
||||
|
||||
expected_tags = @status_data["object"]["tag"]
|
||||
expected_emoji = @status_data["object"]["emoji"]
|
||||
|
||||
expected_to = ["https://example.org/self", Pleroma.Constants.as_public()]
|
||||
expected_cc = ["https://example.org/someone"]
|
||||
|
||||
assert %{
|
||||
"to" => ^expected_to,
|
||||
"cc" => ^expected_cc,
|
||||
"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
|
||||
} = filtered
|
||||
end
|
||||
|
||||
test "processes status with history" do
|
||||
status =
|
||||
@status_data_with_history
|
||||
|> put_in(["object", "tag"], @misc_tags)
|
||||
|> put_in(["object", "emoji"], %{})
|
||||
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
|
||||
|
||||
expected_tags = @status_data["object"]["tag"]
|
||||
expected_emoji = @status_data["object"]["emoji"]
|
||||
|
||||
expected_to = ["https://example.org/self"]
|
||||
expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
|
||||
|
||||
assert %{
|
||||
"to" => ^expected_to,
|
||||
"cc" => ^expected_cc,
|
||||
"object" => %{
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"tag" => ^expected_tags, "emoji" => ^expected_emoji}]
|
||||
}
|
||||
}
|
||||
} = filtered
|
||||
end
|
||||
end
|
||||
|
||||
describe "edge cases" do
|
||||
setup do
|
||||
clear_config([:mrf_emoji, :remove_url], [
|
||||
"https://example.org/test.png",
|
||||
~r{/biribiri/mikoto_smile[23]\.png},
|
||||
"nekomimi_girl_emoji"
|
||||
])
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "non-statuses" do
|
||||
answer = @status_data |> put_in(["object", "type"], "Answer")
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, answer)
|
||||
|
||||
assert filtered == answer
|
||||
end
|
||||
|
||||
test "without tag" do
|
||||
status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["tag"]))
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
|
||||
|
||||
refute Map.has_key?(filtered["object"], "tag")
|
||||
end
|
||||
|
||||
test "without emoji" do
|
||||
status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["emoji"]))
|
||||
{:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
|
||||
|
||||
refute Map.has_key?(filtered["object"], "emoji")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -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" => %{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.FollowBotPolicyTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.MRF.FollowBotPolicy
|
||||
|
|
|
|||
|
|
@ -256,4 +256,55 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
|
|||
}
|
||||
}} = MRF.filter_one(ForceMentionsInContent, activity)
|
||||
end
|
||||
|
||||
test "don't add duplicate mentions for mastodon or misskey posts" do
|
||||
[zero, rogerick, greg] = [
|
||||
insert(:user,
|
||||
ap_id: "https://pleroma.example.com/users/zero",
|
||||
uri: "https://pleroma.example.com/users/zero",
|
||||
nickname: "zero@pleroma.example.com",
|
||||
local: false
|
||||
),
|
||||
insert(:user,
|
||||
ap_id: "https://misskey.example.com/users/104ab42f11",
|
||||
uri: "https://misskey.example.com/@rogerick",
|
||||
nickname: "rogerick@misskey.example.com",
|
||||
local: false
|
||||
),
|
||||
insert(:user,
|
||||
ap_id: "https://mastodon.example.com/users/greg",
|
||||
uri: "https://mastodon.example.com/@greg",
|
||||
nickname: "greg@mastodon.example.com",
|
||||
local: false
|
||||
)
|
||||
]
|
||||
|
||||
{:ok, post} = CommonAPI.post(rogerick, %{status: "eugh"})
|
||||
|
||||
inline_mentions = [
|
||||
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{rogerick.id}\" href=\"#{rogerick.ap_id}\" rel=\"ugc\">@<span>rogerick</span></a></span>",
|
||||
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{greg.id}\" href=\"#{greg.uri}\" rel=\"ugc\">@<span>greg</span></a></span>"
|
||||
]
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => zero.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => zero.ap_id,
|
||||
"content" => "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm",
|
||||
"to" => [
|
||||
rogerick.ap_id,
|
||||
greg.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => Object.normalize(post).data["id"]
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
|
||||
|
||||
assert filtered ==
|
||||
"#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
112
test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
Normal file
112
test/pleroma/web/activity_pub/mrf/inline_quote_policy_test.exs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
|
||||
alias Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy
|
||||
use Pleroma.DataCase
|
||||
|
||||
test "adds quote URL to post content" do
|
||||
quote_url = "https://gleasonator.com/objects/1234"
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://gleasonator.com/users/alex",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "Nice post",
|
||||
"quoteUrl" => quote_url
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
|
||||
|
||||
assert filtered ==
|
||||
"Nice post<span class=\"quote-inline\"><br/><br/><bdi>RT:</bdi> <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span>"
|
||||
end
|
||||
|
||||
test "adds quote URL to post content, custom template" do
|
||||
clear_config([:mrf_inline_quote, :template], "{url}'s quoting")
|
||||
quote_url = "https://gleasonator.com/objects/1234"
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://gleasonator.com/users/alex",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "Nice post",
|
||||
"quoteUrl" => quote_url
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
|
||||
|
||||
assert filtered ==
|
||||
"Nice post<span class=\"quote-inline\"><br/><br/><a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a>'s quoting</span>"
|
||||
end
|
||||
|
||||
test "doesn't add line breaks to markdown posts" do
|
||||
quote_url = "https://gleasonator.com/objects/1234"
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://gleasonator.com/users/alex",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "<p>Nice post</p>",
|
||||
"quoteUrl" => quote_url
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
|
||||
|
||||
assert filtered ==
|
||||
"<p>Nice post<span class=\"quote-inline\"><br/><br/><bdi>RT:</bdi> <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span></p>"
|
||||
end
|
||||
|
||||
test "ignores Misskey quote posts" do
|
||||
object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://misskey.io/users/7rkrarq81i",
|
||||
"object" => object
|
||||
}
|
||||
|
||||
{:ok, filtered} = InlineQuotePolicy.filter(activity)
|
||||
assert filtered == activity
|
||||
end
|
||||
|
||||
test "ignores Fedibird quote posts" do
|
||||
object = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
|
||||
|
||||
# Normally the ObjectValidator will fix this before it reaches MRF
|
||||
object = Map.put(object, "quoteUrl", object["quoteURL"])
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://fedibird.com/users/noellabo",
|
||||
"object" => object
|
||||
}
|
||||
|
||||
{:ok, filtered} = InlineQuotePolicy.filter(activity)
|
||||
assert filtered == activity
|
||||
end
|
||||
|
||||
test "skips objects which already have an .inline-quote span" do
|
||||
object =
|
||||
File.read!("test/fixtures/quote_post/fedibird_quote_mismatched.json") |> Jason.decode!()
|
||||
|
||||
# Normally the ObjectValidator will fix this before it reaches MRF
|
||||
object = Map.put(object, "quoteUrl", object["quoteUri"])
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://fedibird.com/users/noellabo",
|
||||
"object" => object
|
||||
}
|
||||
|
||||
{:ok, filtered} = InlineQuotePolicy.filter(activity)
|
||||
assert filtered == activity
|
||||
end
|
||||
end
|
||||
|
|
@ -7,10 +7,12 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
use Pleroma.Tests.Helpers
|
||||
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
|
||||
|
||||
import Mock
|
||||
import Mox
|
||||
|
||||
@message %{
|
||||
"type" => "Create",
|
||||
|
|
@ -42,6 +44,13 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
setup do: clear_config([:media_proxy, :enabled], true)
|
||||
|
||||
test "it prefetches media proxy URIs" do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicyTest do
|
||||
alias Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy
|
||||
|
||||
use Pleroma.DataCase
|
||||
|
||||
require Pleroma.Constants
|
||||
|
||||
test "Add quote url to Link tag" do
|
||||
quote_url = "https://gleasonator.com/objects/1234"
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://gleasonator.com/users/alex",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "Nice post",
|
||||
"quoteUrl" => quote_url
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => object}} = QuoteToLinkTagPolicy.filter(activity)
|
||||
|
||||
assert object["tag"] == [
|
||||
%{
|
||||
"type" => "Link",
|
||||
"href" => quote_url,
|
||||
"mediaType" => Pleroma.Constants.activity_json_canonical_mime_type()
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "Add quote url to Link tag, append to the end" do
|
||||
quote_url = "https://gleasonator.com/objects/1234"
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://gleasonator.com/users/alex",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "Nice post",
|
||||
"quoteUrl" => quote_url,
|
||||
"tag" => [%{"type" => "Hashtag", "name" => "#foo"}]
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{"object" => object}} = QuoteToLinkTagPolicy.filter(activity)
|
||||
|
||||
assert [_, tag] = object["tag"]
|
||||
|
||||
assert tag == %{
|
||||
"type" => "Link",
|
||||
"href" => quote_url,
|
||||
"mediaType" => Pleroma.Constants.activity_json_canonical_mime_type()
|
||||
}
|
||||
end
|
||||
|
||||
test "Bypass posts without quoteUrl" do
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => "https://gleasonator.com/users/alex",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "Nice post"
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, ^activity} = QuoteToLinkTagPolicy.filter(activity)
|
||||
end
|
||||
end
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
19
test/pleroma/web/activity_pub/mrf/utils_test.exs
Normal file
19
test/pleroma/web/activity_pub/mrf/utils_test.exs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.UtilsTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.Web.ActivityPub.MRF.Utils
|
||||
|
||||
describe "describe_regex_or_string/1" do
|
||||
test "describes regex" do
|
||||
assert "~r/foo/i" == Utils.describe_regex_or_string(~r/foo/i)
|
||||
end
|
||||
|
||||
test "returns string as-is" do
|
||||
assert "foo" == Utils.describe_regex_or_string("foo")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -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, async: true
|
||||
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
|
||||
|
|
|
|||
|
|
@ -116,4 +116,53 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
|
|||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "Fedibird quote post" do
|
||||
insert(:user, ap_id: "https://fedibird.com/users/noellabo")
|
||||
|
||||
data = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
|
||||
cng = ArticleNotePageValidator.cast_and_validate(data)
|
||||
|
||||
assert cng.valid?
|
||||
assert cng.changes.quoteUrl == "https://misskey.io/notes/8vsn2izjwh"
|
||||
end
|
||||
|
||||
test "Fedibird quote post with quoteUri field" do
|
||||
insert(:user, ap_id: "https://fedibird.com/users/noellabo")
|
||||
|
||||
data = File.read!("test/fixtures/quote_post/fedibird_quote_uri.json") |> Jason.decode!()
|
||||
cng = ArticleNotePageValidator.cast_and_validate(data)
|
||||
|
||||
assert cng.valid?
|
||||
assert cng.changes.quoteUrl == "https://fedibird.com/users/yamako/statuses/107699333438289729"
|
||||
end
|
||||
|
||||
test "Misskey quote post" do
|
||||
insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
|
||||
|
||||
data = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
|
||||
cng = ArticleNotePageValidator.cast_and_validate(data)
|
||||
|
||||
assert cng.valid?
|
||||
assert cng.changes.quoteUrl == "https://misskey.io/notes/8vs6wxufd0"
|
||||
end
|
||||
|
||||
test "Parse tag as quote" do
|
||||
# https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
|
||||
|
||||
insert(:user, ap_id: "https://server.example/users/1")
|
||||
|
||||
data = File.read!("test/fixtures/quote_post/fep-e232-tag-example.json") |> Jason.decode!()
|
||||
cng = ArticleNotePageValidator.cast_and_validate(data)
|
||||
|
||||
assert cng.valid?
|
||||
assert cng.changes.quoteUrl == "https://server.example/objects/123"
|
||||
|
||||
assert Enum.at(cng.changes.tag, 0).changes == %{
|
||||
type: "Link",
|
||||
mediaType: "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
|
||||
href: "https://server.example/objects/123",
|
||||
name: "RE: https://server.example/objects/123"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "attachments" do
|
||||
|
|
@ -116,6 +118,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
{:ok, attachment} =
|
||||
|
|
@ -159,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",
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Builder
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "chat message create activities" do
|
||||
|
|
@ -82,6 +84,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
|
|
@ -103,6 +108,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
|
|
@ -124,6 +132,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ChatValidationTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
valid_chat_message =
|
||||
|
|
@ -136,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
|
||||
|
|
|
|||
|
|
@ -38,16 +38,70 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactHandlingTest do
|
|||
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
|
||||
test "it is valid when custom emoji is used", %{valid_emoji_react: valid_emoji_react} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", "x")
|
||||
|> Map.put("content", ":hello:")
|
||||
|> Map.put("tag", [
|
||||
%{
|
||||
"type" => "Emoji",
|
||||
"name" => ":hello:",
|
||||
"icon" => %{"url" => "http://somewhere", "type" => "Image"}
|
||||
}
|
||||
])
|
||||
|
||||
{:ok, _, _} = ObjectValidator.validate(without_emoji_content, [])
|
||||
end
|
||||
|
||||
test "it is not valid when custom emoji don't have a matching tag", %{
|
||||
valid_emoji_react: valid_emoji_react
|
||||
} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", ":hello:")
|
||||
|> Map.put("tag", [
|
||||
%{
|
||||
"type" => "Emoji",
|
||||
"name" => ":whoops:",
|
||||
"icon" => %{"url" => "http://somewhere", "type" => "Image"}
|
||||
}
|
||||
])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
|
||||
assert {:content, {"must be a single character emoji", []}} in cng.errors
|
||||
assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is not valid when custom emoji have no tags", %{
|
||||
valid_emoji_react: valid_emoji_react
|
||||
} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", ":hello:")
|
||||
|> Map.put("tag", [])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
|
||||
assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
|
||||
end
|
||||
|
||||
test "it is not valid when custom emoji doesn't match a shortcode format", %{
|
||||
valid_emoji_react: valid_emoji_react
|
||||
} do
|
||||
without_emoji_content =
|
||||
valid_emoji_react
|
||||
|> Map.put("content", "hello")
|
||||
|> Map.put("tag", [])
|
||||
|
||||
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
|
||||
|
||||
refute cng.valid?
|
||||
|
||||
assert {:tag, {"does not contain an Emoji tag", []}} in cng.errors
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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"}])
|
||||
|
|
@ -276,8 +277,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
follower =
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
inbox: "https://domain.com/users/nick1/inbox"
|
||||
})
|
||||
|
||||
actor = insert(:user, follower_address: follower.ap_id)
|
||||
|
|
@ -296,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"]
|
||||
|
|
@ -305,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"}])
|
||||
|
|
@ -313,8 +313,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
follower =
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
inbox: "https://domain.com/users/nick1/inbox"
|
||||
})
|
||||
|
||||
actor = insert(:user, follower_address: follower.ap_id)
|
||||
|
|
@ -333,23 +332,49 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
assert res == :ok
|
||||
|
||||
assert called(
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
actor_id: actor.id,
|
||||
id: note_activity.data["id"]
|
||||
})
|
||||
Publisher.enqueue_one(
|
||||
%{
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
actor_id: actor.id,
|
||||
id: note_activity.data["id"]
|
||||
},
|
||||
priority: 1
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
test_with_mock "Publishes to directly addressed actors with higher priority.",
|
||||
Pleroma.Web.ActivityPub.Publisher,
|
||||
[:passthrough],
|
||||
[] do
|
||||
note_activity = insert(:direct_note_activity)
|
||||
|
||||
actor = Pleroma.User.get_by_ap_id(note_activity.data["actor"])
|
||||
|
||||
res = Publisher.publish(actor, note_activity)
|
||||
|
||||
assert res == :ok
|
||||
|
||||
assert called(
|
||||
Publisher.enqueue_one(
|
||||
%{
|
||||
inbox: :_,
|
||||
actor_id: actor.id,
|
||||
id: note_activity.data["id"]
|
||||
},
|
||||
priority: 0
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
test_with_mock "publishes an activity with BCC to all relevant peers.",
|
||||
Pleroma.Web.Federator.Publisher,
|
||||
Pleroma.Web.ActivityPub.Publisher,
|
||||
[:passthrough],
|
||||
[] do
|
||||
follower =
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
inbox: "https://domain.com/users/nick1/inbox"
|
||||
})
|
||||
|
||||
actor = insert(:user, follower_address: follower.ap_id)
|
||||
|
|
@ -367,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"]
|
||||
|
|
@ -376,21 +401,19 @@ 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 =
|
||||
insert(:user,
|
||||
local: false,
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
inbox: "https://domain.com/users/nick1/inbox"
|
||||
)
|
||||
|
||||
another_fetcher =
|
||||
insert(:user,
|
||||
local: false,
|
||||
inbox: "https://domain2.com/users/nick1/inbox",
|
||||
ap_enabled: true
|
||||
inbox: "https://domain2.com/users/nick1/inbox"
|
||||
)
|
||||
|
||||
actor = insert(:user)
|
||||
|
|
@ -419,19 +442,25 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
|
|||
assert res == :ok
|
||||
|
||||
assert called(
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
actor_id: actor.id,
|
||||
id: delete.data["id"]
|
||||
})
|
||||
Publisher.enqueue_one(
|
||||
%{
|
||||
inbox: "https://domain.com/users/nick1/inbox",
|
||||
actor_id: actor.id,
|
||||
id: delete.data["id"]
|
||||
},
|
||||
priority: 1
|
||||
)
|
||||
)
|
||||
|
||||
assert called(
|
||||
Pleroma.Web.Federator.Publisher.enqueue_one(Publisher, %{
|
||||
inbox: "https://domain2.com/users/nick1/inbox",
|
||||
actor_id: actor.id,
|
||||
id: delete.data["id"]
|
||||
})
|
||||
Publisher.enqueue_one(
|
||||
%{
|
||||
inbox: "https://domain2.com/users/nick1/inbox",
|
||||
actor_id: actor.id,
|
||||
id: delete.data["id"]
|
||||
},
|
||||
priority: 1
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -453,7 +461,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
object = Object.get_by_ap_id(emoji_react.data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert ["👌", [user.ap_id]] in object.data["reactions"]
|
||||
assert ["👌", [user.ap_id], nil] in object.data["reactions"]
|
||||
end
|
||||
|
||||
test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -34,7 +34,56 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
|
|||
object = Object.get_by_ap_id(data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert match?([["👌", _]], object.data["reactions"])
|
||||
assert match?([["👌", _, nil]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it works for incoming custom emoji reactions" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hello"})
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/custom-emoji-reaction.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("object", activity.data["object"])
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == other_user.ap_id
|
||||
assert data["type"] == "EmojiReact"
|
||||
assert data["id"] == "https://misskey.local.live/likes/917ocsybgp"
|
||||
assert data["object"] == activity.data["object"]
|
||||
assert data["content"] == ":hanapog:"
|
||||
|
||||
assert data["tag"] == [
|
||||
%{
|
||||
"id" => "https://misskey.local.live/emojis/hanapog",
|
||||
"type" => "Emoji",
|
||||
"name" => "hanapog",
|
||||
"updated" => "2022-06-07T12:00:05.773Z",
|
||||
"icon" => %{
|
||||
"type" => "Image",
|
||||
"url" =>
|
||||
"https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
object = Object.get_by_ap_id(data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
|
||||
assert match?(
|
||||
[
|
||||
[
|
||||
"hanapog",
|
||||
_,
|
||||
"https://misskey.local.live/files/webpublic-8f8a9768-7264-4171-88d6-2356aabeadcd"
|
||||
]
|
||||
],
|
||||
object.data["reactions"]
|
||||
)
|
||||
end
|
||||
|
||||
test "it works for incoming unqualified emoji reactions" do
|
||||
|
|
@ -65,7 +114,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
|
|||
object = Object.get_by_ap_id(data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert match?([[^emoji, _]], object.data["reactions"])
|
||||
assert match?([[^emoji, _, _]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it reject invalid emoji reactions" do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.Transmogrifier.ImageHandlingTest do
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
||||
test "Hubzilla Image object" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "https://hub.somaton.com/channel/testc6"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/hubzilla-actor.json"),
|
||||
headers: HttpRequestMock.activitypub_object_headers()
|
||||
}
|
||||
end)
|
||||
|
||||
data = File.read!("test/fixtures/hubzilla-create-image.json") |> Poison.decode!()
|
||||
|
||||
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
|
||||
|
||||
assert object.data["cc"] == ["https://hub.somaton.com/followers/testc6"]
|
||||
|
||||
assert object.data["attachment"] == [
|
||||
%{
|
||||
"mediaType" => "image/jpeg",
|
||||
"type" => "Link",
|
||||
"url" => [
|
||||
%{
|
||||
"height" => 2200,
|
||||
"href" =>
|
||||
"https://hub.somaton.com/photo/452583b2-7e1f-4ac3-8334-ff666f134afe-0.jpg",
|
||||
"mediaType" => "image/jpeg",
|
||||
"type" => "Link",
|
||||
"width" => 2200
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"})
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
|
@ -123,6 +122,40 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
|
||||
assert activity.data["context"] == object.data["context"]
|
||||
end
|
||||
|
||||
test "it keeps link tags" do
|
||||
insert(:user, ap_id: "https://example.org/users/alice")
|
||||
|
||||
message = File.read!("test/fixtures/fep-e232.json") |> Jason.decode!()
|
||||
|
||||
assert capture_log(fn ->
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
|
||||
object = Object.normalize(activity)
|
||||
assert [%{"type" => "Mention"}, %{"type" => "Link"}] = object.data["tag"]
|
||||
end) =~ "Object rejected while fetching"
|
||||
end
|
||||
|
||||
test "it accepts quote posts" do
|
||||
insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
|
||||
|
||||
object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
|
||||
|
||||
message = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Create",
|
||||
"actor" => "https://misskey.io/users/7rkrarq81i",
|
||||
"object" => object
|
||||
}
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
|
||||
|
||||
# Object was created in the database
|
||||
object = Object.normalize(activity)
|
||||
assert object.data["quoteUrl"] == "https://misskey.io/notes/8vs6wxufd0"
|
||||
|
||||
# It fetched the quoted post
|
||||
assert Object.normalize("https://misskey.io/notes/8vs6wxufd0")
|
||||
end
|
||||
end
|
||||
|
||||
describe "prepare outgoing" do
|
||||
|
|
@ -337,68 +370,19 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
}
|
||||
} = prepared["object"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "user upgrade" do
|
||||
test "it upgrades a user to activitypub" do
|
||||
user =
|
||||
insert(:user, %{
|
||||
nickname: "rye@niu.moe",
|
||||
local: false,
|
||||
ap_id: "https://niu.moe/users/rye",
|
||||
follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
|
||||
})
|
||||
test "it prepares a quote post" do
|
||||
user = insert(:user)
|
||||
|
||||
user_two = insert(:user)
|
||||
Pleroma.FollowingRelationship.follow(user_two, user, :follow_accept)
|
||||
{:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quote_id: quoted_post.id})
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "test"})
|
||||
{:ok, unrelated_activity} = CommonAPI.post(user_two, %{status: "test"})
|
||||
assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
|
||||
{:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data)
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
assert user.note_count == 1
|
||||
%{data: %{"id" => quote_id}} = Object.normalize(quoted_post)
|
||||
|
||||
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
|
||||
ObanHelpers.perform_all()
|
||||
|
||||
assert user.ap_enabled
|
||||
assert user.note_count == 1
|
||||
assert user.follower_address == "https://niu.moe/users/rye/followers"
|
||||
assert user.following_address == "https://niu.moe/users/rye/following"
|
||||
|
||||
user = User.get_cached_by_id(user.id)
|
||||
assert user.note_count == 1
|
||||
|
||||
activity = Activity.get_by_id(activity.id)
|
||||
assert user.follower_address in activity.recipients
|
||||
|
||||
assert %{
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
|
||||
}
|
||||
]
|
||||
} = user.avatar
|
||||
|
||||
assert %{
|
||||
"url" => [
|
||||
%{
|
||||
"href" =>
|
||||
"https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
||||
}
|
||||
]
|
||||
} = user.banner
|
||||
|
||||
refute "..." in activity.recipients
|
||||
|
||||
unrelated_activity = Activity.get_by_id(unrelated_activity.id)
|
||||
refute user.follower_address in unrelated_activity.recipients
|
||||
|
||||
user_two = User.get_cached_by_id(user_two.id)
|
||||
assert User.following?(user_two, user)
|
||||
refute "..." in User.following(user_two)
|
||||
assert modified["object"]["quoteUrl"] == quote_id
|
||||
assert modified["object"]["quoteUri"] == quote_id
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -426,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
|
||||
|
|
@ -441,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
|
||||
|
|
@ -456,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
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,41 @@ 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 activities" do
|
||||
reporter = insert(:user)
|
||||
target_account = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(target_account, %{status: "foobar"})
|
||||
context = Utils.generate_context_id()
|
||||
content = "foobar"
|
||||
post_id = activity.data["id"]
|
||||
|
||||
res =
|
||||
Utils.make_flag_data(
|
||||
%{
|
||||
actor: reporter,
|
||||
context: context,
|
||||
account: target_account,
|
||||
statuses: [%{"id" => post_id}],
|
||||
content: content
|
||||
},
|
||||
%{}
|
||||
)
|
||||
|
||||
res =
|
||||
res
|
||||
|> Map.put("object", res["object"] ++ [nil, 1, 5, "123"])
|
||||
|
||||
{:ok, activity} = Pleroma.Web.ActivityPub.ActivityPub.insert(res)
|
||||
|
||||
[user_id, object | _] = activity.data["object"]
|
||||
|
||||
{:ok, stripped} = Utils.strip_report_status_data(activity)
|
||||
|
||||
assert stripped.data["object"] == [user_id, object["id"]]
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetch the latest Follow" do
|
||||
test "fetches the latest Follow activity" do
|
||||
%Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity)
|
||||
|
|
@ -118,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
|
||||
|
|
@ -587,15 +622,38 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
end
|
||||
|
||||
describe "get_cached_emoji_reactions/1" do
|
||||
test "returns the 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) == []
|
||||
|
||||
object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]})
|
||||
assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]]
|
||||
assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"], nil]]
|
||||
|
||||
object = insert(:note, data: %{"reactions" => %{}})
|
||||
assert Utils.get_cached_emoji_reactions(object) == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "add_emoji_reaction_to_object/1" do
|
||||
test "works with legacy 2-tuple format" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
third_user = insert(:user)
|
||||
|
||||
note =
|
||||
insert(:note,
|
||||
user: user,
|
||||
data: %{
|
||||
"reactions" => [["😿", [other_user.ap_id]]]
|
||||
}
|
||||
)
|
||||
|
||||
_activity = insert(:note_activity, user: user, note: note)
|
||||
|
||||
Utils.add_emoji_reaction_to_object(
|
||||
%Activity{data: %{"content" => "😿", "actor" => third_user.ap_id}},
|
||||
note
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -76,6 +76,15 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
|
|||
assert %{"invisible" => true} = UserView.render("service.json", %{user: user})
|
||||
end
|
||||
|
||||
test "service has a few essential fields" do
|
||||
user = insert(:user)
|
||||
result = UserView.render("service.json", %{user: user})
|
||||
assert result["id"]
|
||||
assert result["type"] == "Application"
|
||||
assert result["inbox"]
|
||||
assert result["outbox"]
|
||||
end
|
||||
|
||||
test "renders AKAs" do
|
||||
akas = ["https://i.tusooa.xyz/users/test-pleroma"]
|
||||
user = insert(:user, also_known_as: akas)
|
||||
|
|
|
|||
|
|
@ -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", %{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
alias Pleroma.ModerationLog
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
|
|
@ -1077,6 +1078,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
describe "/api/pleroma/backups" do
|
||||
test "it creates a backup", %{conn: conn} do
|
||||
ConfigMock
|
||||
|> Mox.stub_with(Pleroma.Config)
|
||||
|
||||
admin = %{id: admin_id, nickname: admin_nickname} = insert(:user, is_admin: true)
|
||||
token = insert(:oauth_admin_token, user: admin)
|
||||
user = %{id: user_id, nickname: user_nickname} = insert(:user)
|
||||
|
|
|
|||
|
|
@ -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", []]}
|
||||
]
|
||||
}
|
||||
|
|
@ -1502,15 +1502,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
clear_config(:database_config_whitelist, [
|
||||
{:pleroma, :instance},
|
||||
{:pleroma, :activitypub},
|
||||
{:pleroma, Pleroma.Upload},
|
||||
{:esshd}
|
||||
{:pleroma, Pleroma.Upload}
|
||||
])
|
||||
|
||||
conn = get(conn, "/api/pleroma/admin/config/descriptions")
|
||||
|
||||
children = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
assert length(children) == 4
|
||||
assert length(children) == 3
|
||||
|
||||
assert Enum.count(children, fn c -> c["group"] == ":pleroma" end) == 3
|
||||
|
||||
|
|
@ -1522,9 +1521,6 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|
||||
web_endpoint = Enum.find(children, fn c -> c["key"] == "Pleroma.Upload" end)
|
||||
assert web_endpoint["children"]
|
||||
|
||||
esshd = Enum.find(children, fn c -> c["group"] == ":esshd" end)
|
||||
assert esshd["children"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ defmodule Pleroma.Web.AdminAPI.FrontendControllerTest do
|
|||
"build_url" => "http://gensokyo.2hu/builds/${ref}",
|
||||
"git" => nil,
|
||||
"installed" => true,
|
||||
"installed_refs" => ["fantasy"],
|
||||
"name" => "pleroma",
|
||||
"ref" => "fantasy"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
setup do: clear_config([:media_proxy])
|
||||
|
|
@ -128,6 +130,9 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
|
|||
"http://example.com/media/fb1f4d.jpg"
|
||||
]
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
with_mocks [
|
||||
{MediaProxy.Invalidation.Script, [],
|
||||
[
|
||||
|
|
@ -150,6 +155,9 @@ defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
|
|||
"http://example.com/media/fb1f4d.jpg"
|
||||
]
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
with_mocks [{MediaProxy.Invalidation.Script, [], [purge: fn _, _ -> {"ok", 0} end]}] do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
})
|
||||
|
||||
%{
|
||||
reporter: reporter,
|
||||
id: report_id,
|
||||
second_report_id: second_report_id
|
||||
}
|
||||
|
|
@ -266,6 +267,26 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
assert ModerationLog.get_log_entry_message(second_log_entry) ==
|
||||
"@#{admin.nickname} updated report ##{second_report_id} (on user @#{second_activity.user_actor.nickname}) with 'closed' state"
|
||||
end
|
||||
|
||||
test "works if reporter is deactivated", %{
|
||||
conn: conn,
|
||||
id: id,
|
||||
reporter: reporter
|
||||
} do
|
||||
Pleroma.User.set_activation(reporter, false)
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [
|
||||
%{"state" => "resolved", "id" => id}
|
||||
]
|
||||
})
|
||||
|> json_response_and_validate_schema(:no_content)
|
||||
|
||||
activity = Activity.get_by_id_with_user_actor(id)
|
||||
assert activity.data["state"] == "resolved"
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/admin/reports" do
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ defmodule Pleroma.Web.AdminAPI.UserControllerTest do
|
|||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
||||
|
|
|
|||
56
test/pleroma/web/api_spec/scopes/compiler_test.exs
Normal file
56
test/pleroma/web/api_spec/scopes/compiler_test.exs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.Scopes.CompilerTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pleroma.Web.ApiSpec.Scopes.Compiler
|
||||
|
||||
@dummy_response %{}
|
||||
|
||||
@data %{
|
||||
paths: %{
|
||||
"/mew" => %OpenApiSpex.PathItem{
|
||||
post: %OpenApiSpex.Operation{
|
||||
security: [%{"oAuth" => ["a:b:c"]}],
|
||||
responses: @dummy_response
|
||||
},
|
||||
get: %OpenApiSpex.Operation{security: nil, responses: @dummy_response}
|
||||
},
|
||||
"/mew2" => %OpenApiSpex.PathItem{
|
||||
post: %OpenApiSpex.Operation{
|
||||
security: [%{"oAuth" => ["d:e", "f:g"]}],
|
||||
responses: @dummy_response
|
||||
},
|
||||
get: %OpenApiSpex.Operation{security: nil, responses: @dummy_response}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe "process_scope/1" do
|
||||
test "gives all higher-level scopes" do
|
||||
scopes = Compiler.process_scope("admin:read:accounts")
|
||||
|
||||
assert [_, _, _] = scopes
|
||||
assert "admin" in scopes
|
||||
assert "admin:read" in scopes
|
||||
assert "admin:read:accounts" in scopes
|
||||
end
|
||||
end
|
||||
|
||||
describe "extract_all_scopes_from/1" do
|
||||
test "extracts scopes" do
|
||||
scopes = Compiler.extract_all_scopes_from(@data)
|
||||
|
||||
assert [_, _, _, _, _, _, _] = scopes
|
||||
assert "a" in scopes
|
||||
assert "a:b" in scopes
|
||||
assert "a:b:c" in scopes
|
||||
assert "d" in scopes
|
||||
assert "d:e" in scopes
|
||||
assert "f" in scopes
|
||||
assert "f:g" in scopes
|
||||
end
|
||||
end
|
||||
end
|
||||
33
test/pleroma/web/common_api/activity_draft_test.exs
Normal file
33
test/pleroma/web/common_api/activity_draft_test.exs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.CommonAPI.ActivityDraftTest do
|
||||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "create/2 with a quote post" do
|
||||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, direct} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
|
||||
{:ok, private} = CommonAPI.post(user, %{status: ".", visibility: "private"})
|
||||
{:ok, unlisted} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
|
||||
{:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"})
|
||||
{:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"})
|
||||
|
||||
{:error, _} = ActivityDraft.create(user, %{status: "nice", quote_id: direct.id})
|
||||
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: private.id})
|
||||
{:error, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: private.id})
|
||||
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: unlisted.id})
|
||||
{:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: unlisted.id})
|
||||
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: local.id})
|
||||
{:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: local.id})
|
||||
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: public.id})
|
||||
{:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: public.id})
|
||||
end
|
||||
end
|
||||
|
|
@ -200,7 +200,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
{result, _, []} = Utils.format_input(code, "text/markdown")
|
||||
|
||||
assert result ==
|
||||
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what’s up?</p>]
|
||||
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what's up?</p>]
|
||||
end
|
||||
|
||||
test "remote mentions" do
|
||||
|
|
@ -211,7 +211,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
{result, _, []} = Utils.format_input(code, "text/markdown")
|
||||
|
||||
assert result ==
|
||||
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what’s up?</p>]
|
||||
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what's up?</p>]
|
||||
end
|
||||
|
||||
test "raw HTML" do
|
||||
|
|
@ -229,7 +229,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
test "blockquote" do
|
||||
code = ~s[> whoms't are you quoting?]
|
||||
{result, [], []} = Utils.format_input(code, "text/markdown")
|
||||
assert result == "<blockquote><p>whoms’t are you quoting?</p></blockquote>"
|
||||
assert result == "<blockquote><p>whoms't are you quoting?</p></blockquote>"
|
||||
end
|
||||
|
||||
test "code" do
|
||||
|
|
@ -586,41 +586,61 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "attachments_from_ids_descs/2" do
|
||||
describe "attachments_from_ids_descs/3" do
|
||||
test "returns [] when attachment ids is empty" do
|
||||
assert Utils.attachments_from_ids_descs([], "{}") == []
|
||||
assert Utils.attachments_from_ids_descs([], "{}", nil) == []
|
||||
end
|
||||
|
||||
test "returns list attachments with desc" do
|
||||
object = insert(:note)
|
||||
user = insert(:user)
|
||||
object = insert(:attachment, %{user: user})
|
||||
desc = Jason.encode!(%{object.id => "test-desc"})
|
||||
|
||||
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc) == [
|
||||
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc, user) == [
|
||||
Map.merge(object.data, %{"name" => "test-desc"})
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "attachments_from_ids/1" do
|
||||
describe "attachments_from_ids/2" do
|
||||
test "returns attachments with descs" do
|
||||
object = insert(:note)
|
||||
user = insert(:user)
|
||||
object = insert(:attachment, %{user: user})
|
||||
desc = Jason.encode!(%{object.id => "test-desc"})
|
||||
|
||||
assert Utils.attachments_from_ids(%{
|
||||
media_ids: ["#{object.id}"],
|
||||
descriptions: desc
|
||||
}) == [
|
||||
assert Utils.attachments_from_ids(
|
||||
%{
|
||||
media_ids: ["#{object.id}"],
|
||||
descriptions: desc
|
||||
},
|
||||
user
|
||||
) == [
|
||||
Map.merge(object.data, %{"name" => "test-desc"})
|
||||
]
|
||||
end
|
||||
|
||||
test "returns attachments without descs" do
|
||||
object = insert(:note)
|
||||
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}) == [object.data]
|
||||
user = insert(:user)
|
||||
object = insert(:attachment, %{user: user})
|
||||
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user) == [object.data]
|
||||
end
|
||||
|
||||
test "returns [] when not pass media_ids" do
|
||||
assert Utils.attachments_from_ids(%{}) == []
|
||||
assert Utils.attachments_from_ids(%{}, nil) == []
|
||||
end
|
||||
|
||||
test "returns [] when media_ids not belong to current user" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
object = insert(:attachment, %{user: user})
|
||||
|
||||
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user2) == []
|
||||
end
|
||||
|
||||
test "checks that the object is of upload type" do
|
||||
object = insert(:note)
|
||||
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, nil) == []
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
|
|
@ -20,17 +21,32 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Workers.PollWorker
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mock
|
||||
import Ecto.Query, only: [from: 2]
|
||||
import Mock
|
||||
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
|
||||
end
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
setup do: clear_config([:instance, :safe_dm_mentions])
|
||||
setup do: clear_config([:instance, :limit])
|
||||
setup do: clear_config([:instance, :max_pinned_statuses])
|
||||
|
|
@ -279,6 +295,24 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
|
||||
CommonAPI.post_chat_message(author, recipient, "GNO/Linux")
|
||||
end
|
||||
|
||||
test "it reject messages with attachments not belonging to user" do
|
||||
author = insert(:user)
|
||||
not_author = insert(:user)
|
||||
recipient = author
|
||||
|
||||
attachment = insert(:attachment, %{user: not_author})
|
||||
|
||||
{:error, message} =
|
||||
CommonAPI.post_chat_message(
|
||||
author,
|
||||
recipient,
|
||||
"123",
|
||||
media_id: attachment.id
|
||||
)
|
||||
|
||||
assert message == :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
describe "unblocking" do
|
||||
|
|
@ -393,6 +427,20 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
refute Activity.get_by_id(post.id)
|
||||
end
|
||||
|
||||
test "it allows privileged users to delete banned user's posts" do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
user = insert(:user)
|
||||
moderator = insert(:user, is_moderator: true)
|
||||
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
|
||||
User.set_activation(user, false)
|
||||
|
||||
assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
|
||||
assert delete.local
|
||||
|
||||
refute Activity.get_by_id(post.id)
|
||||
end
|
||||
end
|
||||
|
||||
test "favoriting race condition" do
|
||||
|
|
@ -458,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
|
||||
|
|
@ -527,6 +575,17 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
assert Object.tags(object) == ["ساٴينس"]
|
||||
end
|
||||
|
||||
test "allows lang attribute" do
|
||||
user = insert(:user)
|
||||
text = ~s{<span lang="en">something</span><p lang="diaetuitech_rpyhpgc">random</p>}
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: text, content_type: "text/html"})
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == text
|
||||
end
|
||||
|
||||
test "double dot in link is allowed" do
|
||||
user = insert(:user)
|
||||
text = "https://example.to/something..mp3"
|
||||
|
|
@ -753,6 +812,65 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
scheduled_at: expires_at
|
||||
)
|
||||
end
|
||||
|
||||
test "it allows quote posting" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"})
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id})
|
||||
|
||||
quoted = Object.normalize(quoted)
|
||||
quote_post = Object.normalize(quote_post)
|
||||
|
||||
assert quote_post.data["quoteUrl"] == quoted.data["id"]
|
||||
|
||||
# The OP is not mentioned
|
||||
refute quoted.data["actor"] in quote_post.data["to"]
|
||||
end
|
||||
|
||||
test "quote posting with explicit addressing doesn't mention the OP" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"})
|
||||
|
||||
{:ok, quote_post} =
|
||||
CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id, to: []})
|
||||
|
||||
assert Object.normalize(quote_post).data["to"] == [Pleroma.Constants.as_public()]
|
||||
end
|
||||
|
||||
test "quote posting visibility" do
|
||||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, direct} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
|
||||
{:ok, private} = CommonAPI.post(user, %{status: ".", visibility: "private"})
|
||||
{:ok, unlisted} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
|
||||
{:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"})
|
||||
{:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"})
|
||||
|
||||
{:error, _} = CommonAPI.post(user, %{status: "nice", quote_id: direct.id})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: private.id})
|
||||
{:error, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: private.id})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: unlisted.id})
|
||||
{:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: unlisted.id})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: local.id})
|
||||
{:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: local.id})
|
||||
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: public.id})
|
||||
{:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: public.id})
|
||||
end
|
||||
|
||||
test "it properly mentions punycode domain" do
|
||||
user = insert(:user)
|
||||
|
||||
_mentioned_user =
|
||||
insert(:user, ap_id: "https://xn--i2raa.com/users/yyy", nickname: "yyy@xn--i2raa.com")
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "hey @yyy@xn--i2raa.com", content_type: "text/markdown"})
|
||||
|
||||
assert "https://xn--i2raa.com/users/yyy" in Object.normalize(activity).data["to"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "reactions" do
|
||||
|
|
@ -806,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
|
||||
|
|
@ -828,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
|
||||
|
||||
|
|
@ -841,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)
|
||||
|
|
@ -1328,7 +1446,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
test "cancels a pending follow for a remote user" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user, is_locked: true, local: false, ap_enabled: true)
|
||||
followed = insert(:user, is_locked: true, local: false)
|
||||
|
||||
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
|
||||
CommonAPI.follow(follower, followed)
|
||||
|
|
@ -1486,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
|
||||
|
|
@ -1501,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
|
||||
|
|
@ -1517,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
|
||||
|
|
@ -1535,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
|
||||
|
|
@ -1550,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
|
||||
|
|
@ -1565,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
|
||||
|
|
@ -1579,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
|
||||
|
|
@ -1595,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
|
||||
|
|
@ -1724,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
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Endpoint.MetricsExporterTest do
|
||||
# Modifies AppEnv, has to stay synchronous
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
alias Pleroma.Web.Endpoint.MetricsExporter
|
||||
|
||||
defp config do
|
||||
Application.get_env(:prometheus, MetricsExporter)
|
||||
end
|
||||
|
||||
describe "with default config" do
|
||||
test "does NOT expose app metrics", %{conn: conn} do
|
||||
conn
|
||||
|> get(config()[:path])
|
||||
|> json_response(404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when enabled" do
|
||||
setup do
|
||||
initial_config = config()
|
||||
on_exit(fn -> Application.put_env(:prometheus, MetricsExporter, initial_config) end)
|
||||
|
||||
Application.put_env(
|
||||
:prometheus,
|
||||
MetricsExporter,
|
||||
Keyword.put(initial_config, :enabled, true)
|
||||
)
|
||||
end
|
||||
|
||||
test "serves app metrics", %{conn: conn} do
|
||||
conn = get(conn, config()[:path])
|
||||
assert response = response(conn, 200)
|
||||
|
||||
for metric <- [
|
||||
"http_requests_total",
|
||||
"http_request_duration_microseconds",
|
||||
"phoenix_controller_call_duration",
|
||||
"telemetry_scrape_duration",
|
||||
"erlang_vm_memory_atom_bytes_total"
|
||||
] do
|
||||
assert response =~ ~r/#{metric}/
|
||||
end
|
||||
end
|
||||
|
||||
test "when IP whitelist configured, " <>
|
||||
"serves app metrics only if client IP is whitelisted",
|
||||
%{conn: conn} do
|
||||
Application.put_env(
|
||||
:prometheus,
|
||||
MetricsExporter,
|
||||
Keyword.put(config(), :ip_whitelist, ["127.127.127.127", {1, 1, 1, 1}, '255.255.255.255'])
|
||||
)
|
||||
|
||||
conn
|
||||
|> get(config()[:path])
|
||||
|> json_response(404)
|
||||
|
||||
conn
|
||||
|> Map.put(:remote_ip, {127, 127, 127, 127})
|
||||
|> get(config()[:path])
|
||||
|> response(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -6,20 +6,6 @@ defmodule Pleroma.Web.FallbackTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "neither preloaded data nor metadata attached to" do
|
||||
test "GET /registration/:token", %{conn: conn} do
|
||||
response = get(conn, "/registration/foo")
|
||||
|
||||
assert html_response(response, 200) =~ "<!--server-generated-meta-->"
|
||||
end
|
||||
|
||||
test "GET /*path", %{conn: conn} do
|
||||
assert conn
|
||||
|> get("/foo")
|
||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /*path adds a title", %{conn: conn} do
|
||||
clear_config([:instance, :name], "a cool title")
|
||||
|
||||
|
|
@ -29,21 +15,28 @@ defmodule Pleroma.Web.FallbackTest do
|
|||
end
|
||||
|
||||
describe "preloaded data and metadata attached to" do
|
||||
test "GET /:maybe_nickname_or_id", %{conn: conn} do
|
||||
test "GET /:maybe_nickname_or_id with existing user", %{conn: conn} do
|
||||
clear_config([:instance, :name], "a cool title")
|
||||
user = insert(:user)
|
||||
|
||||
resp = get(conn, "/#{user.nickname}")
|
||||
|
||||
assert html_response(resp, 200) =~ "<title>a cool title</title>"
|
||||
refute html_response(resp, 200) =~ "<!--server-generated-meta-->"
|
||||
assert html_response(resp, 200) =~ "initial-results"
|
||||
end
|
||||
|
||||
test "GET /:maybe_nickname_or_id with missing user", %{conn: conn} do
|
||||
clear_config([:instance, :name], "a cool title")
|
||||
|
||||
user = insert(:user)
|
||||
user_missing = get(conn, "/foo")
|
||||
user_present = get(conn, "/#{user.nickname}")
|
||||
resp = get(conn, "/foo")
|
||||
|
||||
assert html_response(user_missing, 200) =~ "<!--server-generated-meta-->"
|
||||
refute html_response(user_present, 200) =~ "<!--server-generated-meta-->"
|
||||
assert html_response(user_present, 200) =~ "initial-results"
|
||||
assert html_response(user_present, 200) =~ "<title>a cool title</title>"
|
||||
assert html_response(resp, 200) =~ "<title>a cool title</title>"
|
||||
refute html_response(resp, 200) =~ "initial-results"
|
||||
end
|
||||
|
||||
test "GET /*path", %{conn: conn} do
|
||||
assert conn
|
||||
refute conn
|
||||
|> get("/foo")
|
||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
||||
|
||||
|
|
@ -65,10 +58,12 @@ defmodule Pleroma.Web.FallbackTest do
|
|||
end
|
||||
|
||||
test "GET /main/all", %{conn: conn} do
|
||||
clear_config([:instance, :name], "a cool title")
|
||||
public_page = get(conn, "/main/all")
|
||||
|
||||
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
|
||||
assert html_response(public_page, 200) =~ "initial-results"
|
||||
assert html_response(public_page, 200) =~ "<title>a cool title</title>"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -78,16 +116,14 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
local: false,
|
||||
nickname: "nick1@domain.com",
|
||||
ap_id: "https://domain.com/users/nick1",
|
||||
inbox: inbox1,
|
||||
ap_enabled: true
|
||||
inbox: inbox1
|
||||
})
|
||||
|
||||
insert(:user, %{
|
||||
local: false,
|
||||
nickname: "nick2@domain2.com",
|
||||
ap_id: "https://domain2.com/users/nick2",
|
||||
inbox: inbox2,
|
||||
ap_enabled: true
|
||||
inbox: inbox2
|
||||
})
|
||||
|
||||
dt = NaiveDateTime.utc_now()
|
||||
|
|
@ -133,7 +169,7 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
assert {:ok, _activity} = ObanHelpers.perform(job)
|
||||
|
||||
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
||||
assert {:error, :already_present} = ObanHelpers.perform(job)
|
||||
assert {:cancel, :already_present} = ObanHelpers.perform(job)
|
||||
end
|
||||
|
||||
test "rejects incoming AP docs with incorrect origin" do
|
||||
|
|
|
|||
|
|
@ -57,9 +57,23 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
)
|
||||
|
||||
note_activity2 = insert(:note_activity, note: note2)
|
||||
|
||||
note3 =
|
||||
insert(:note,
|
||||
user: user,
|
||||
data: %{
|
||||
"content" => "This note tests whether HTML entities are truncated properly",
|
||||
"summary" => "Won't, didn't fail",
|
||||
"inReplyTo" => note_activity2.id
|
||||
}
|
||||
)
|
||||
|
||||
_note_activity3 = insert(:note_activity, note: note3)
|
||||
object = Object.normalize(note_activity, fetch: false)
|
||||
|
||||
[user: user, object: object, max_id: note_activity2.id]
|
||||
encoded_title = FeedView.activity_title(note3.data)
|
||||
|
||||
[user: user, object: object, max_id: note_activity2.id, encoded_title: encoded_title]
|
||||
end
|
||||
|
||||
test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do
|
||||
|
|
@ -74,7 +88,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||
|
||||
assert activity_titles == ['2hu', '2hu & as']
|
||||
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
|
|
@ -105,7 +119,7 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//item/title/text()"l)
|
||||
|
||||
assert activity_titles == ['2hu', '2hu & as']
|
||||
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
|
|
@ -176,6 +190,30 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
|||
|> get("/users/#{user.nickname}/feed.rss")
|
||||
|> response(200)
|
||||
end
|
||||
|
||||
test "does not mangle HTML entities midway", %{
|
||||
conn: conn,
|
||||
user: user,
|
||||
object: object,
|
||||
encoded_title: encoded_title
|
||||
} do
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "application/atom+xml")
|
||||
|> get(user_feed_path(conn, :feed, user.nickname))
|
||||
|> response(200)
|
||||
|
||||
activity_titles =
|
||||
resp
|
||||
|> SweetXml.parse()
|
||||
|> SweetXml.xpath(~x"//entry/title/text()"l)
|
||||
|
||||
assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as']
|
||||
assert resp =~ FeedView.escape(object.data["content"])
|
||||
assert resp =~ FeedView.escape(object.data["summary"])
|
||||
assert resp =~ FeedView.escape(object.data["context"])
|
||||
assert resp =~ encoded_title
|
||||
end
|
||||
end
|
||||
|
||||
# Note: see ActivityPubControllerTest for JSON format tests
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "account fetching" do
|
||||
test "works by id" do
|
||||
%User{id: user_id} = insert(:user)
|
||||
|
|
@ -1355,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)
|
||||
|
||||
|
|
@ -1490,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",
|
||||
|
|
@ -1776,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",
|
||||
|
|
@ -2031,6 +2036,39 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert [%{"id" => ^id1}] = result
|
||||
end
|
||||
|
||||
test "list of blocks with with_relationships parameter" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:blocks"])
|
||||
%{id: id1} = other_user1 = insert(:user)
|
||||
%{id: id2} = other_user2 = insert(:user)
|
||||
%{id: id3} = other_user3 = insert(:user)
|
||||
|
||||
{:ok, _, _} = User.follow(other_user1, user)
|
||||
{:ok, _, _} = User.follow(other_user2, user)
|
||||
{:ok, _, _} = User.follow(other_user3, user)
|
||||
|
||||
{:ok, _} = User.block(user, other_user1)
|
||||
{:ok, _} = User.block(user, other_user2)
|
||||
{:ok, _} = User.block(user, other_user3)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"id" => ^id3,
|
||||
"pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
|
||||
},
|
||||
%{
|
||||
"id" => ^id2,
|
||||
"pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
|
||||
},
|
||||
%{
|
||||
"id" => ^id1,
|
||||
"pleroma" => %{"relationship" => %{"blocking" => true, "followed_by" => false}}
|
||||
}
|
||||
] =
|
||||
conn
|
||||
|> get("/api/v1/blocks?with_relationships=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "account lookup", %{conn: conn} do
|
||||
%{nickname: acct} = insert(:user, %{nickname: "nickname"})
|
||||
%{nickname: acct_two} = insert(:user, %{nickname: "nickname@notlocaldoma.in"})
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.DirectoryControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase
|
||||
alias Pleroma.Web.CommonAPI
|
||||
import Pleroma.Factory
|
||||
|
||||
|
|
|
|||
|
|
@ -106,4 +106,11 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
|
|||
|> get("/api/v1/instance")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "get instance information v2", %{conn: conn} do
|
||||
clear_config([:auth, :oauth_consumer_strategies], [])
|
||||
|
||||
assert get(conn, "/api/v2/instance")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
|
||||
import ExUnit.CaptureLog
|
||||
import Mox
|
||||
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
|
||||
|
|
@ -15,6 +17,9 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
setup do: oauth_access(["write:media"])
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
image = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
|
|
@ -122,12 +127,32 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "Do not allow nested filename", %{conn: conn, image: image} do
|
||||
image = %Plug.Upload{
|
||||
image
|
||||
| filename: "../../../../../nested/file.jpg"
|
||||
}
|
||||
|
||||
desc = "Description of the image"
|
||||
|
||||
media =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/media", %{"file" => image, "description" => desc})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
refute Regex.match?(~r"/nested/", media["url"])
|
||||
end
|
||||
end
|
||||
|
||||
describe "Update media description" do
|
||||
setup do: oauth_access(["write:media"])
|
||||
|
||||
setup %{user: actor} do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
|
|
@ -160,6 +185,9 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
setup do: oauth_access(["read:media"])
|
||||
|
||||
setup %{user: actor} do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
test "does NOT render account/pleroma/relationship by default" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -3,15 +3,25 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
|
||||
import Pleroma.Factory
|
||||
import Ecto.Query
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do: clear_config([ScheduledActivity, :enabled])
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub(:get, fn
|
||||
[ScheduledActivity, :enabled] -> true
|
||||
path -> Pleroma.Test.StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "shows scheduled activities" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:statuses"])
|
||||
|
|
@ -55,7 +65,6 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
|||
end
|
||||
|
||||
test "updates a scheduled activity" do
|
||||
clear_config([ScheduledActivity, :enabled], true)
|
||||
%{user: user, conn: conn} = oauth_access(["write:statuses"])
|
||||
|
||||
scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 60)
|
||||
|
|
@ -103,7 +112,6 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
|||
end
|
||||
|
||||
test "deletes a scheduled activity" do
|
||||
clear_config([ScheduledActivity, :enabled], true)
|
||||
%{user: user, conn: conn} = oauth_access(["write:statuses"])
|
||||
scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 60)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
import Tesla.Mock
|
||||
import Mock
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
setup_all do
|
||||
mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
|
|
@ -37,7 +42,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
@tag :skip_darwin
|
||||
test "search", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -19,25 +20,38 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Workers.ScheduledActivityWorker
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do: clear_config([:instance, :federating])
|
||||
setup do: clear_config([:instance, :allow_relay])
|
||||
setup do: clear_config([:rich_media, :enabled])
|
||||
setup do: clear_config([:mrf, :policies])
|
||||
setup do: clear_config([:mrf_keyword, :reject])
|
||||
|
||||
setup do
|
||||
Pleroma.UnstubbedConfigMock
|
||||
|> stub_with(Pleroma.Config)
|
||||
|
||||
Pleroma.StaticStubbedConfigMock
|
||||
|> stub(:get, fn
|
||||
[:rich_media, :enabled] -> false
|
||||
path -> Pleroma.Test.StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "posting statuses" do
|
||||
setup do: oauth_access(["write:statuses"])
|
||||
|
||||
test "posting a status does not increment reblog_count when relaying", %{conn: conn} do
|
||||
clear_config([:instance, :federating], true)
|
||||
Config.get([:instance, :allow_relay], true)
|
||||
clear_config([:instance, :allow_relay], true)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{
|
||||
|> post("/api/v1/statuses", %{
|
||||
"content_type" => "text/plain",
|
||||
"source" => "Pleroma FE",
|
||||
"status" => "Hello world",
|
||||
|
|
@ -50,7 +64,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
response =
|
||||
conn
|
||||
|> get("api/v1/statuses/#{response["id"]}", %{})
|
||||
|> get("/api/v1/statuses/#{response["id"]}", %{})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["reblogs_count"] == 0
|
||||
|
|
@ -109,7 +123,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
conn_four =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "oolong",
|
||||
"expires_in" => expires_in
|
||||
})
|
||||
|
|
@ -125,6 +139,28 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
)
|
||||
end
|
||||
|
||||
test "posting a quote post", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, %{id: activity_id} = activity} = CommonAPI.post(user, %{status: "yolo"})
|
||||
%{data: %{"id" => quote_url}} = Object.normalize(activity)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "indeed",
|
||||
"quote_id" => activity_id
|
||||
})
|
||||
|
||||
assert %{
|
||||
"id" => id,
|
||||
"pleroma" => %{"quote" => %{"id" => ^activity_id}, "quote_url" => ^quote_url}
|
||||
} = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
assert Activity.get_by_id(id)
|
||||
end
|
||||
|
||||
test "it fails to create a status if `expires_in` is less or equal than an hour", %{
|
||||
conn: conn
|
||||
} do
|
||||
|
|
@ -134,7 +170,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
assert %{"error" => "Expiry date is too soon"} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "oolong",
|
||||
"expires_in" => expires_in
|
||||
})
|
||||
|
|
@ -146,7 +182,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
assert %{"error" => "Expiry date is too soon"} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "oolong",
|
||||
"expires_in" => expires_in
|
||||
})
|
||||
|
|
@ -160,7 +196,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
assert %{"error" => "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{"status" => "GNO/Linux"})
|
||||
|> post("/api/v1/statuses", %{"status" => "GNO/Linux"})
|
||||
|> json_response_and_validate_schema(422)
|
||||
end
|
||||
|
||||
|
|
@ -294,7 +330,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
end
|
||||
|
||||
test "fake statuses' preview card is not cached", %{conn: conn} do
|
||||
clear_config([:rich_media, :enabled], true)
|
||||
Pleroma.StaticStubbedConfigMock
|
||||
|> stub(:get, fn
|
||||
[:rich_media, :enabled] -> true
|
||||
path -> Pleroma.Test.StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{
|
||||
|
|
@ -331,7 +371,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
test "posting a status with OGP link preview", %{conn: conn} do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
clear_config([:rich_media, :enabled], true)
|
||||
|
||||
Pleroma.StaticStubbedConfigMock
|
||||
|> stub(:get, fn
|
||||
[:rich_media, :enabled] -> true
|
||||
path -> Pleroma.Test.StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -353,7 +398,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
|
||||
|> post("/api/v1/statuses", %{"status" => content, "visibility" => "direct"})
|
||||
|
||||
assert %{"id" => id} = response = json_response_and_validate_schema(conn, 200)
|
||||
assert response["visibility"] == "direct"
|
||||
|
|
@ -390,7 +435,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> get("api/v1/statuses/#{activity}")
|
||||
|> get("/api/v1/statuses/#{activity}")
|
||||
|
||||
assert %{
|
||||
"content" => "cofe is my copilot",
|
||||
|
|
@ -419,7 +464,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
result =
|
||||
conn
|
||||
|> get("api/v1/statuses/#{activity}")
|
||||
|> get("/api/v1/statuses/#{activity}")
|
||||
|
||||
assert %{
|
||||
"content" => "club mate is my wingman",
|
||||
|
|
@ -626,7 +671,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "desu~",
|
||||
"poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1}
|
||||
"poll" => %{
|
||||
"options" => Enum.map(0..limit, fn num -> "desu #{num}" end),
|
||||
"expires_in" => 1
|
||||
}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response_and_validate_schema(conn, 422)
|
||||
|
|
@ -642,7 +690,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> post("/api/v1/statuses", %{
|
||||
"status" => "...",
|
||||
"poll" => %{
|
||||
"options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)],
|
||||
"options" => [String.duplicate(".", limit + 1), "lol"],
|
||||
"expires_in" => 1
|
||||
}
|
||||
})
|
||||
|
|
@ -724,6 +772,32 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
assert object.data["type"] == "Question"
|
||||
assert length(object.data["oneOf"]) == 3
|
||||
end
|
||||
|
||||
test "cannot have only one option", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "desu~",
|
||||
"poll" => %{"options" => ["mew"], "expires_in" => 1}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response_and_validate_schema(conn, 422)
|
||||
assert error == "Poll must contain at least 2 options"
|
||||
end
|
||||
|
||||
test "cannot have only duplicated options", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "desu~",
|
||||
"poll" => %{"options" => ["mew", "mew"], "expires_in" => 1}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response_and_validate_schema(conn, 422)
|
||||
assert error == "Poll must contain at least 2 options"
|
||||
end
|
||||
end
|
||||
|
||||
test "get a status" do
|
||||
|
|
@ -742,6 +816,49 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
{:ok, local: local, remote: remote}
|
||||
end
|
||||
|
||||
defp local_and_remote_context_activities do
|
||||
local_user_1 = insert(:user)
|
||||
local_user_2 = insert(:user)
|
||||
remote_user = insert(:user, local: false)
|
||||
|
||||
{:ok, %{id: id1, data: %{"context" => context}}} =
|
||||
CommonAPI.post(local_user_1, %{status: "post"})
|
||||
|
||||
{:ok, %{id: id2} = post} =
|
||||
CommonAPI.post(local_user_2, %{status: "local reply", in_reply_to_status_id: id1})
|
||||
|
||||
params = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"actor" => remote_user.ap_id,
|
||||
"type" => "Create",
|
||||
"context" => context,
|
||||
"id" => "#{remote_user.ap_id}/activities/1",
|
||||
"inReplyTo" => post.data["id"],
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "remote reply",
|
||||
"context" => context,
|
||||
"id" => "#{remote_user.ap_id}/objects/1",
|
||||
"attributedTo" => remote_user.ap_id,
|
||||
"to" => [
|
||||
local_user_1.ap_id,
|
||||
local_user_2.ap_id,
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"to" => [
|
||||
local_user_1.ap_id,
|
||||
local_user_2.ap_id,
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
}
|
||||
|
||||
{:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
|
||||
{:ok, remote_activity} = ObanHelpers.perform(job)
|
||||
|
||||
%{locals: [id1, id2], remote: remote_activity.id, context: context}
|
||||
end
|
||||
|
||||
describe "status with restrict unauthenticated activities for local and remote" do
|
||||
setup do: local_and_remote_activities()
|
||||
|
||||
|
|
@ -928,6 +1045,230 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "getting status contexts restricted unauthenticated for local and remote" do
|
||||
setup do: local_and_remote_context_activities()
|
||||
|
||||
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
|
||||
|
||||
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
|
||||
|
||||
test "if user is unauthenticated", %{conn: conn, locals: [post_id, _]} do
|
||||
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
|
||||
|
||||
assert json_response_and_validate_schema(res_conn, 200) == %{
|
||||
"ancestors" => [],
|
||||
"descendants" => []
|
||||
}
|
||||
end
|
||||
|
||||
test "if user is unauthenticated reply", %{conn: conn, locals: [_, reply_id]} do
|
||||
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
|
||||
|
||||
assert json_response_and_validate_schema(res_conn, 200) == %{
|
||||
"ancestors" => [],
|
||||
"descendants" => []
|
||||
}
|
||||
end
|
||||
|
||||
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
|
||||
|
||||
%{"ancestors" => [], "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert reply_id in descendant_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
|
||||
test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
|
||||
|
||||
%{"ancestors" => ancestors, "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
ancestor_ids =
|
||||
ancestors
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert post_id in ancestor_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
end
|
||||
|
||||
describe "getting status contexts restricted unauthenticated for local" do
|
||||
setup do: local_and_remote_context_activities()
|
||||
|
||||
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
|
||||
|
||||
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], false)
|
||||
|
||||
test "if user is unauthenticated", %{
|
||||
conn: conn,
|
||||
locals: [post_id, reply_id],
|
||||
remote: remote_reply_id
|
||||
} do
|
||||
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
|
||||
|
||||
%{"ancestors" => [], "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert reply_id not in descendant_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
|
||||
test "if user is unauthenticated reply", %{
|
||||
conn: conn,
|
||||
locals: [post_id, reply_id],
|
||||
remote: remote_reply_id
|
||||
} do
|
||||
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
|
||||
|
||||
%{"ancestors" => ancestors, "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
ancestor_ids =
|
||||
ancestors
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert post_id not in ancestor_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
|
||||
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
|
||||
|
||||
%{"ancestors" => [], "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert reply_id in descendant_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
|
||||
test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
|
||||
|
||||
%{"ancestors" => ancestors, "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
ancestor_ids =
|
||||
ancestors
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert post_id in ancestor_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
end
|
||||
|
||||
describe "getting status contexts restricted unauthenticated for remote" do
|
||||
setup do: local_and_remote_context_activities()
|
||||
|
||||
setup do: clear_config([:restrict_unauthenticated, :activities, :local], false)
|
||||
|
||||
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
|
||||
|
||||
test "if user is unauthenticated", %{
|
||||
conn: conn,
|
||||
locals: [post_id, reply_id],
|
||||
remote: remote_reply_id
|
||||
} do
|
||||
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
|
||||
|
||||
%{"ancestors" => [], "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert reply_id in descendant_ids
|
||||
assert remote_reply_id not in descendant_ids
|
||||
end
|
||||
|
||||
test "if user is unauthenticated reply", %{
|
||||
conn: conn,
|
||||
locals: [post_id, reply_id],
|
||||
remote: remote_reply_id
|
||||
} do
|
||||
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
|
||||
|
||||
%{"ancestors" => ancestors, "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
ancestor_ids =
|
||||
ancestors
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert post_id in ancestor_ids
|
||||
assert remote_reply_id not in descendant_ids
|
||||
end
|
||||
|
||||
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
|
||||
|
||||
%{"ancestors" => [], "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
reply_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert reply_id in reply_ids
|
||||
assert remote_reply_id in reply_ids
|
||||
end
|
||||
|
||||
test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
|
||||
%{conn: conn} = oauth_access(["read"])
|
||||
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
|
||||
|
||||
%{"ancestors" => ancestors, "descendants" => descendants} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
ancestor_ids =
|
||||
ancestors
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
descendant_ids =
|
||||
descendants
|
||||
|> Enum.map(& &1["id"])
|
||||
|
||||
assert post_id in ancestor_ids
|
||||
assert remote_reply_id in descendant_ids
|
||||
end
|
||||
end
|
||||
|
||||
describe "deleting a status" do
|
||||
test "when you created it" do
|
||||
%{user: author, conn: conn} = oauth_access(["write:statuses"])
|
||||
|
|
@ -989,6 +1330,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
|
||||
test "when you're privileged and the user is banned", %{conn: conn} do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
posting_user = insert(:user, is_active: false)
|
||||
refute posting_user.is_active
|
||||
activity = insert(:note_activity, user: posting_user)
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
res_conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
|
||||
|> delete("/api/v1/statuses/#{activity.id}")
|
||||
|
||||
assert %{} = json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() ==
|
||||
"@#{user.nickname} deleted status ##{activity.id}"
|
||||
|
||||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "reblogging" do
|
||||
|
|
@ -1305,7 +1667,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
assert %{"id" => id} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("api/v1/statuses", %{
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "oolong",
|
||||
"expires_in" => expires_in
|
||||
})
|
||||
|
|
@ -1345,7 +1707,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
describe "cards" do
|
||||
setup do
|
||||
clear_config([:rich_media, :enabled], true)
|
||||
Pleroma.StaticStubbedConfigMock
|
||||
|> stub(:get, fn
|
||||
[:rich_media, :enabled] -> true
|
||||
path -> Pleroma.Test.StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
oauth_access(["read:statuses"])
|
||||
end
|
||||
|
|
@ -1555,7 +1921,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
conn
|
||||
|> assign(:user, user3)
|
||||
|> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"]))
|
||||
|> get("api/v1/timelines/home")
|
||||
|> get("/api/v1/timelines/home")
|
||||
|
||||
[reblogged_activity] = json_response_and_validate_schema(conn3, 200)
|
||||
|
||||
|
|
@ -1826,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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -527,7 +527,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
|> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"]))
|
||||
|
||||
# Only direct should be visible here
|
||||
res_conn = get(conn_user_two, "api/v1/timelines/direct")
|
||||
res_conn = get(conn_user_two, "/api/v1/timelines/direct")
|
||||
|
||||
assert [status] = json_response_and_validate_schema(res_conn, :ok)
|
||||
|
||||
|
|
@ -539,14 +539,14 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
build_conn()
|
||||
|> assign(:user, user_one)
|
||||
|> assign(:token, insert(:oauth_token, user: user_one, scopes: ["read:statuses"]))
|
||||
|> get("api/v1/timelines/direct")
|
||||
|> get("/api/v1/timelines/direct")
|
||||
|
||||
[status] = json_response_and_validate_schema(res_conn, :ok)
|
||||
|
||||
assert %{"visibility" => "direct"} = status
|
||||
|
||||
# Both should be visible here
|
||||
res_conn = get(conn_user_two, "api/v1/timelines/home")
|
||||
res_conn = get(conn_user_two, "/api/v1/timelines/home")
|
||||
|
||||
[_s1, _s2] = json_response_and_validate_schema(res_conn, :ok)
|
||||
|
||||
|
|
@ -559,14 +559,14 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
})
|
||||
end)
|
||||
|
||||
res_conn = get(conn_user_two, "api/v1/timelines/direct")
|
||||
res_conn = get(conn_user_two, "/api/v1/timelines/direct")
|
||||
|
||||
statuses = json_response_and_validate_schema(res_conn, :ok)
|
||||
assert length(statuses) == 20
|
||||
|
||||
max_id = List.last(statuses)["id"]
|
||||
|
||||
res_conn = get(conn_user_two, "api/v1/timelines/direct?max_id=#{max_id}")
|
||||
res_conn = get(conn_user_two, "/api/v1/timelines/direct?max_id=#{max_id}")
|
||||
|
||||
assert [status] = json_response_and_validate_schema(res_conn, :ok)
|
||||
|
||||
|
|
@ -591,7 +591,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
visibility: "direct"
|
||||
})
|
||||
|
||||
res_conn = get(conn, "api/v1/timelines/direct")
|
||||
res_conn = get(conn, "/api/v1/timelines/direct")
|
||||
|
||||
[status] = json_response_and_validate_schema(res_conn, :ok)
|
||||
assert status["id"] == direct.id
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
|
|||
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.MastodonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
import Mox
|
||||
|
||||
describe "follow/3" do
|
||||
test "returns error when followed user is deactivated" do
|
||||
|
|
@ -88,6 +90,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPITest do
|
|||
|
||||
describe "get_scheduled_activities/2" do
|
||||
test "returns user scheduled activities" do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
today =
|
||||
|
|
|
|||
|
|
@ -4,13 +4,22 @@
|
|||
|
||||
defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
import Mock
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "updating credentials" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
setup :request_content_type
|
||||
|
|
@ -97,6 +106,42 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.raw_bio == raw_bio
|
||||
end
|
||||
|
||||
test "updating bio honours bio limit", %{conn: conn} do
|
||||
bio_limit = Config.get([:instance, :user_bio_length], 5000)
|
||||
|
||||
raw_bio = String.duplicate(".", bio_limit + 1)
|
||||
|
||||
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
|
||||
|
||||
assert %{"error" => "Bio is too long"} = json_response_and_validate_schema(conn, 413)
|
||||
end
|
||||
|
||||
test "updating name honours name limit", %{conn: conn} do
|
||||
name_limit = Config.get([:instance, :user_name_length], 100)
|
||||
|
||||
name = String.duplicate(".", name_limit + 1)
|
||||
|
||||
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => name})
|
||||
|
||||
assert %{"error" => "Name is too long"} = json_response_and_validate_schema(conn, 413)
|
||||
end
|
||||
|
||||
test "when both name and bio exceeds the limit, display name error", %{conn: conn} do
|
||||
name_limit = Config.get([:instance, :user_name_length], 100)
|
||||
bio_limit = Config.get([:instance, :user_bio_length], 5000)
|
||||
|
||||
name = String.duplicate(".", name_limit + 1)
|
||||
raw_bio = String.duplicate(".", bio_limit + 1)
|
||||
|
||||
conn =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"display_name" => name,
|
||||
"note" => raw_bio
|
||||
})
|
||||
|
||||
assert %{"error" => "Name is too long"} = json_response_and_validate_schema(conn, 413)
|
||||
end
|
||||
|
||||
test "updates the user's locking status", %{conn: conn} do
|
||||
conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
|
||||
|
||||
|
|
@ -385,6 +430,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "Strip / from upload files", %{user: user, conn: conn} do
|
||||
new_image = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image.jpg"),
|
||||
filename: "../../../../nested/an_image.jpg"
|
||||
}
|
||||
|
||||
assert user.avatar == %{}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"avatar" => new_image,
|
||||
"header" => new_image,
|
||||
"pleroma_background_image" => new_image
|
||||
})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 200)
|
||||
assert user_response["avatar"]
|
||||
assert user_response["header"]
|
||||
assert user_response["pleroma"]["background_image"]
|
||||
refute Regex.match?(~r"/nested/", user_response["avatar"])
|
||||
refute Regex.match?(~r"/nested/", user_response["header"])
|
||||
refute Regex.match?(~r"/nested/", user_response["pleroma"]["background_image"])
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
refute user.avatar == %{}
|
||||
end
|
||||
|
||||
test "requires 'write:accounts' permission" do
|
||||
token1 = insert(:oauth_token, scopes: ["read"])
|
||||
token2 = insert(:oauth_token, scopes: ["write", "follow"])
|
||||
|
|
@ -567,17 +640,17 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
|
||||
fields = [%{"name" => "foo", "value" => long_value}]
|
||||
|
||||
assert %{"error" => "Invalid request"} ==
|
||||
assert %{"error" => "One or more field entries are too long"} ==
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|
||||
|> json_response_and_validate_schema(403)
|
||||
|> json_response_and_validate_schema(413)
|
||||
|
||||
fields = [%{"name" => long_name, "value" => "bar"}]
|
||||
|
||||
assert %{"error" => "Invalid request"} ==
|
||||
assert %{"error" => "One or more field entries are too long"} ==
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|
||||
|> json_response_and_validate_schema(403)
|
||||
|> json_response_and_validate_schema(413)
|
||||
|
||||
clear_config([:instance, :max_account_fields], 1)
|
||||
|
||||
|
|
@ -586,10 +659,10 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
%{"name" => "link", "value" => "cofe.io"}
|
||||
]
|
||||
|
||||
assert %{"error" => "Invalid request"} ==
|
||||
assert %{"error" => "Too many field entries"} ==
|
||||
conn
|
||||
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|
||||
|> json_response_and_validate_schema(403)
|
||||
|> json_response_and_validate_schema(413)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -659,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
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
|
||||
|
|
@ -35,7 +37,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
inserted_at: ~N[2017-08-15 15:47:06.597036],
|
||||
emoji: %{"karjalanpiirakka" => "/file.png"},
|
||||
raw_bio: "valid html. a\nb\nc\nd\nf '&<>\"",
|
||||
also_known_as: ["https://shitposter.zone/users/shp"]
|
||||
also_known_as: ["https://shitposter.zone/users/shp"],
|
||||
last_status_at: NaiveDateTime.utc_now()
|
||||
})
|
||||
|
||||
expected = %{
|
||||
|
|
@ -74,7 +77,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
fields: []
|
||||
},
|
||||
fqn: "shp@shitposter.club",
|
||||
last_status_at: nil,
|
||||
last_status_at: user.last_status_at |> NaiveDateTime.to_date() |> Date.to_iso8601(),
|
||||
pleroma: %{
|
||||
ap_id: user.ap_id,
|
||||
also_known_as: ["https://shitposter.zone/users/shp"],
|
||||
|
|
@ -752,6 +755,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
clear_config([:media_proxy, :enabled], true)
|
||||
clear_config([:media_preview_proxy, :enabled])
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
user =
|
||||
insert(:user,
|
||||
avatar: %{"url" => [%{"href" => "https://evil.website/avatar.png"}]},
|
||||
|
|
@ -759,7 +765,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
emoji: %{"joker_smile" => "https://evil.website/society.png"}
|
||||
)
|
||||
|
||||
with media_preview_enabled <- [false, true] do
|
||||
Enum.each([true, false], fn media_preview_enabled ->
|
||||
clear_config([:media_preview_proxy, :enabled], media_preview_enabled)
|
||||
|
||||
AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|
||||
|
|
@ -777,7 +783,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
true
|
||||
end)
|
||||
|> assert()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
test "renders mute expiration date" do
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
|||
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
|
||||
import Pleroma.Factory
|
||||
|
||||
setup do
|
||||
Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
|
||||
:ok
|
||||
end
|
||||
|
||||
defp test_notifications_rendering(notifications, user, expected_result) do
|
||||
result = NotificationView.render("index.json", %{notifications: notifications, for: user})
|
||||
|
||||
|
|
@ -190,7 +195,47 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
|||
emoji: "☕",
|
||||
account: AccountView.render("show.json", %{user: other_user, for: user}),
|
||||
status: StatusView.render("show.json", %{activity: activity, for: user}),
|
||||
created_at: Utils.to_masto_date(notification.inserted_at)
|
||||
created_at: Utils.to_masto_date(notification.inserted_at),
|
||||
emoji_url: nil
|
||||
}
|
||||
|
||||
test_notifications_rendering([notification], user, [expected])
|
||||
end
|
||||
|
||||
test "EmojiReact custom emoji notification" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
note =
|
||||
insert(:note,
|
||||
user: user,
|
||||
data: %{
|
||||
"reactions" => [
|
||||
["👍", [user.ap_id], nil],
|
||||
["dinosaur", [user.ap_id], "http://localhost:4001/emoji/dino walking.gif"]
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note, user: user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.react_with_emoji(activity.id, other_user, "dinosaur")
|
||||
|
||||
activity = Repo.get(Activity, activity.id)
|
||||
|
||||
[notification] = Notification.for_user(user)
|
||||
|
||||
assert notification
|
||||
|
||||
expected = %{
|
||||
id: to_string(notification.id),
|
||||
pleroma: %{is_seen: false, is_muted: false},
|
||||
type: "pleroma:emoji_reaction",
|
||||
emoji: ":dinosaur:",
|
||||
account: AccountView.render("show.json", %{user: other_user, for: user}),
|
||||
status: StatusView.render("show.json", %{activity: activity, for: user}),
|
||||
created_at: Utils.to_masto_date(notification.inserted_at),
|
||||
emoji_url: "http://localhost:4001/emoji/dino walking.gif"
|
||||
}
|
||||
|
||||
test_notifications_rendering([notification], user, [expected])
|
||||
|
|
|
|||
|
|
@ -4,12 +4,16 @@
|
|||
|
||||
defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
test "A scheduled activity with a media attachment" do
|
||||
|
|
@ -27,6 +31,9 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
|
|||
filename: "an_image.jpg"
|
||||
}
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
|
||||
|
||||
attrs = %{
|
||||
|
|
@ -48,7 +55,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
|
|||
id: to_string(scheduled_activity.id),
|
||||
media_attachments:
|
||||
%{media_ids: [upload.id]}
|
||||
|> Utils.attachments_from_ids()
|
||||
|> Utils.attachments_from_ids(user)
|
||||
|> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})),
|
||||
params: %{
|
||||
in_reply_to_id: to_string(activity.id),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
alias Pleroma.HTML
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -19,9 +20,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
|
||||
require Bitwise
|
||||
|
||||
import Mox
|
||||
import OpenApiSpex.TestAssertions
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
import OpenApiSpex.TestAssertions
|
||||
|
||||
setup do
|
||||
mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
|
@ -35,16 +37,26 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
{:ok, activity} = CommonAPI.post(user, %{status: "dae cofe??"})
|
||||
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "☕")
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, user, ":dinosaur:")
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
|
||||
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, ":dinosaur:")
|
||||
|
||||
activity = Repo.get(Activity, activity.id)
|
||||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: false},
|
||||
%{name: "🍵", count: 1, me: false}
|
||||
%{name: "☕", count: 2, me: false, url: nil, account_ids: [other_user.id, user.id]},
|
||||
%{
|
||||
count: 2,
|
||||
me: false,
|
||||
name: "dinosaur",
|
||||
url: "http://localhost:4001/emoji/dino walking.gif",
|
||||
account_ids: [other_user.id, user.id]
|
||||
},
|
||||
%{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
|
@ -52,8 +64,36 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: true},
|
||||
%{name: "🍵", count: 1, me: false}
|
||||
%{name: "☕", count: 2, me: true, url: nil, account_ids: [other_user.id, user.id]},
|
||||
%{
|
||||
count: 2,
|
||||
me: true,
|
||||
name: "dinosaur",
|
||||
url: "http://localhost:4001/emoji/dino walking.gif",
|
||||
account_ids: [other_user.id, user.id]
|
||||
},
|
||||
%{name: "🍵", count: 1, me: false, url: nil, account_ids: [third_user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
test "works with legacy-formatted reactions" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
note =
|
||||
insert(:note,
|
||||
user: user,
|
||||
data: %{
|
||||
"reactions" => [["😿", [other_user.ap_id]]]
|
||||
}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, user: user, note: note)
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "😿", count: 1, me: false, url: nil, account_ids: [other_user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
@ -66,11 +106,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
|> Object.update_data(%{"reactions" => %{"☕" => [user.ap_id], "x" => 1}})
|
||||
|
||||
activity = Activity.get_by_id(activity.id)
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: true}
|
||||
%{name: "☕", count: 1, me: true, url: nil, account_ids: [user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
@ -90,7 +129,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: false}
|
||||
%{name: "☕", count: 1, me: false, url: nil, account_ids: [other_user.id]}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
|
@ -102,19 +141,25 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
status = StatusView.render("show.json", activity: activity)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 2, me: false}
|
||||
%{
|
||||
name: "☕",
|
||||
count: 2,
|
||||
me: false,
|
||||
url: nil,
|
||||
account_ids: [third_user.id, other_user.id]
|
||||
}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: false}
|
||||
%{name: "☕", count: 1, me: false, url: nil, account_ids: [third_user.id]}
|
||||
]
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, for: other_user)
|
||||
|
||||
assert status[:pleroma][:emoji_reactions] == [
|
||||
%{name: "☕", count: 1, me: true}
|
||||
%{name: "☕", count: 1, me: true, url: nil, account_ids: [other_user.id]}
|
||||
]
|
||||
end
|
||||
|
||||
|
|
@ -155,6 +200,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "returns a temporary ap_id based user for activities missing db users" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
@ -283,6 +329,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
conversation_id: convo_id,
|
||||
context: object_data["context"],
|
||||
in_reply_to_account_acct: nil,
|
||||
quote: nil,
|
||||
quote_id: nil,
|
||||
quote_url: nil,
|
||||
quote_visible: false,
|
||||
content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
|
||||
spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
|
||||
expires_at: nil,
|
||||
|
|
@ -290,7 +340,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
thread_muted: false,
|
||||
emoji_reactions: [],
|
||||
parent_visible: false,
|
||||
pinned_at: nil
|
||||
pinned_at: nil,
|
||||
quotes_count: 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -379,6 +430,88 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
assert status.in_reply_to_id == to_string(note.id)
|
||||
end
|
||||
|
||||
test "a quote post" do
|
||||
post = insert(:note_activity)
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
|
||||
{:ok, quoted_quote_post} = CommonAPI.post(user, %{status: "yo", quote_id: quote_post.id})
|
||||
|
||||
status = StatusView.render("show.json", %{activity: quoted_quote_post})
|
||||
|
||||
assert status.pleroma.quote.id == to_string(quote_post.id)
|
||||
assert status.pleroma.quote_id == to_string(quote_post.id)
|
||||
assert status.pleroma.quote_url == Object.normalize(quote_post).data["id"]
|
||||
assert status.pleroma.quote_visible
|
||||
|
||||
# Quotes don't go more than one level deep
|
||||
refute status.pleroma.quote.pleroma.quote
|
||||
assert status.pleroma.quote.pleroma.quote_id == to_string(post.id)
|
||||
assert status.pleroma.quote.pleroma.quote_url == Object.normalize(post).data["id"]
|
||||
assert status.pleroma.quote.pleroma.quote_visible
|
||||
|
||||
# In an index
|
||||
[status] = StatusView.render("index.json", %{activities: [quoted_quote_post], as: :activity})
|
||||
|
||||
assert status.pleroma.quote.id == to_string(quote_post.id)
|
||||
end
|
||||
|
||||
test "quoted private post" do
|
||||
user = insert(:user)
|
||||
|
||||
# Insert a private post
|
||||
private = insert(:followers_only_note_activity, user: user)
|
||||
private_object = Object.normalize(private)
|
||||
|
||||
# Create a public post quoting the private post
|
||||
quote_private =
|
||||
insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => private_object.data["id"]}))
|
||||
|
||||
status = StatusView.render("show.json", %{activity: quote_private})
|
||||
|
||||
# The quote isn't rendered
|
||||
refute status.pleroma.quote
|
||||
assert status.pleroma.quote_url == private_object.data["id"]
|
||||
refute status.pleroma.quote_visible
|
||||
|
||||
# After following the user, the quote is rendered
|
||||
follower = insert(:user)
|
||||
CommonAPI.follow(follower, user)
|
||||
|
||||
status = StatusView.render("show.json", %{activity: quote_private, for: follower})
|
||||
assert status.pleroma.quote.id == to_string(private.id)
|
||||
assert status.pleroma.quote_visible
|
||||
end
|
||||
|
||||
test "quoted direct message" do
|
||||
# Insert a direct message
|
||||
direct = insert(:direct_note_activity)
|
||||
direct_object = Object.normalize(direct)
|
||||
|
||||
# Create a public post quoting the direct message
|
||||
quote_direct =
|
||||
insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => direct_object.data["id"]}))
|
||||
|
||||
status = StatusView.render("show.json", %{activity: quote_direct})
|
||||
|
||||
# The quote isn't rendered
|
||||
refute status.pleroma.quote
|
||||
assert status.pleroma.quote_url == direct_object.data["id"]
|
||||
refute status.pleroma.quote_visible
|
||||
end
|
||||
|
||||
test "repost of quote post" do
|
||||
post = insert(:note_activity)
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
|
||||
{:ok, repost} = CommonAPI.repeat(quote_post.id, user)
|
||||
|
||||
[status] = StatusView.render("index.json", %{activities: [repost], as: :activity})
|
||||
|
||||
assert status.reblog.pleroma.quote.id == to_string(post.id)
|
||||
end
|
||||
|
||||
test "contains mentions" do
|
||||
user = insert(:user)
|
||||
mentioned = insert(:user)
|
||||
|
|
@ -649,6 +782,39 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
%{provider_name: "example.com"} =
|
||||
StatusView.render("card.json", %{page_url: page_url, rich_media: card})
|
||||
end
|
||||
|
||||
test "a rich media card has all media proxied" do
|
||||
clear_config([:media_proxy, :enabled], true)
|
||||
clear_config([:media_preview_proxy, :enabled])
|
||||
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
page_url = "http://example.com"
|
||||
|
||||
card = %{
|
||||
url: page_url,
|
||||
site_name: "Example site name",
|
||||
title: "Example website",
|
||||
image: page_url <> "/example.jpg",
|
||||
audio: page_url <> "/example.ogg",
|
||||
video: page_url <> "/example.mp4",
|
||||
description: "Example description"
|
||||
}
|
||||
|
||||
strcard = for {k, v} <- card, into: %{}, do: {to_string(k), v}
|
||||
|
||||
%{
|
||||
provider_name: "example.com",
|
||||
image: image,
|
||||
pleroma: %{opengraph: og}
|
||||
} = StatusView.render("card.json", %{page_url: page_url, rich_media: strcard})
|
||||
|
||||
assert String.match?(image, ~r/\/proxy\//)
|
||||
assert String.match?(og["image"], ~r/\/proxy\//)
|
||||
assert String.match?(og["audio"], ~r/\/proxy\//)
|
||||
assert String.match?(og["video"], ~r/\/proxy\//)
|
||||
end
|
||||
end
|
||||
|
||||
test "does not embed a relationship in the account" do
|
||||
|
|
|
|||
|
|
@ -6,10 +6,20 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
|
||||
import Mock
|
||||
import Mox
|
||||
|
||||
alias Pleroma.ReverseProxy.ClientMock
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.MediaProxy
|
||||
alias Plug.Conn
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "Media Proxy" do
|
||||
setup do
|
||||
clear_config([:media_proxy, :enabled], true)
|
||||
|
|
@ -74,6 +84,20 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
assert %Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
|
||||
end
|
||||
end
|
||||
|
||||
test "it applies sandbox CSP to MediaProxy requests", %{conn: conn} do
|
||||
media_url = "https://lain.com/image.png"
|
||||
media_proxy_url = MediaProxy.encode_url(media_url)
|
||||
|
||||
ClientMock
|
||||
|> expect(:request, fn :get, ^media_url, _, _, _ ->
|
||||
{:ok, 200, [{"content-type", "image/png"}]}
|
||||
end)
|
||||
|
||||
%Conn{resp_headers: headers} = get(conn, media_proxy_url)
|
||||
|
||||
assert {"content-security-policy", "sandbox;"} in headers
|
||||
end
|
||||
end
|
||||
|
||||
describe "Media Preview Proxy" do
|
||||
|
|
@ -158,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)
|
||||
|
||||
|
|
@ -173,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)
|
||||
|
||||
|
|
@ -193,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: "",
|
||||
|
|
@ -218,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)
|
||||
|
||||
|
|
@ -236,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)
|
||||
|
||||
|
|
@ -256,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: "",
|
||||
|
|
@ -278,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} ->
|
||||
|
|
@ -300,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} ->
|
||||
|
|
@ -320,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} ->
|
||||
|
|
|
|||
|
|
@ -7,9 +7,19 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
use Pleroma.Tests.Helpers
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.MediaProxy
|
||||
|
||||
import Mox
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
defp decode_result(encoded) do
|
||||
{:ok, decoded} = MediaProxy.decode_url(encoded)
|
||||
decoded
|
||||
|
|
@ -222,7 +232,12 @@ defmodule Pleroma.Web.MediaProxyTest do
|
|||
|
||||
test "ensure Pleroma.Upload base_url is always whitelisted" do
|
||||
media_url = "https://media.pleroma.social"
|
||||
clear_config([Pleroma.Upload, :base_url], media_url)
|
||||
|
||||
ConfigMock
|
||||
|> stub(:get, fn
|
||||
[Pleroma.Upload, :base_url] -> media_url
|
||||
path -> Pleroma.Test.StaticConfig.get(path)
|
||||
end)
|
||||
|
||||
url = "#{media_url}/static/logo.png"
|
||||
encoded = MediaProxy.url(url)
|
||||
|
|
|
|||
|
|
@ -4,9 +4,19 @@
|
|||
|
||||
defmodule Pleroma.Web.Metadata.Providers.OpenGraphTest do
|
||||
use Pleroma.DataCase
|
||||
import Mox
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.UnstubbedConfigMock, as: ConfigMock
|
||||
alias Pleroma.Web.Metadata.Providers.OpenGraph
|
||||
|
||||
setup do
|
||||
ConfigMock
|
||||
|> stub_with(Pleroma.Test.StaticConfig)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
setup do: clear_config([Pleroma.Web.Metadata, :unfurl_nsfw])
|
||||
|
||||
test "it renders all supported types of attachments and skips unknown types" do
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue