Merge remote-tracking branch 'remotes/upstream/develop' into 1335-user-api-id-fields-relations
This commit is contained in:
commit
01d9c093c3
73 changed files with 3612 additions and 445 deletions
|
|
@ -6,6 +6,14 @@ defmodule Pleroma.EmojiTest do
|
|||
use ExUnit.Case, async: true
|
||||
alias Pleroma.Emoji
|
||||
|
||||
describe "is_unicode_emoji?/1" do
|
||||
test "tells if a string is an unicode emoji" do
|
||||
refute Emoji.is_unicode_emoji?("X")
|
||||
assert Emoji.is_unicode_emoji?("☂")
|
||||
assert Emoji.is_unicode_emoji?("🥺")
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_all/0" do
|
||||
setup do
|
||||
emoji_list = Emoji.get_all()
|
||||
|
|
|
|||
30
test/fixtures/emoji-reaction.json
vendored
Normal file
30
test/fixtures/emoji-reaction.json
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"type": "EmojiReaction",
|
||||
"signature": {
|
||||
"type": "RsaSignature2017",
|
||||
"signatureValue": "fdxMfQSMwbC6wP6sh6neS/vM5879K67yQkHTbiT5Npr5wAac0y6+o3Ij+41tN3rL6wfuGTosSBTHOtta6R4GCOOhCaCSLMZKypnp1VltCzLDoyrZELnYQIC8gpUXVmIycZbREk22qWUe/w7DAFaKK4UscBlHDzeDVcA0K3Se5Sluqi9/Zh+ldAnEzj/rSEPDjrtvf5wGNf3fHxbKSRKFt90JvKK6hS+vxKUhlRFDf6/SMETw+EhwJSNW4d10yMUakqUWsFv4Acq5LW7l+HpYMvlYY1FZhNde1+uonnCyuQDyvzkff8zwtEJmAXC4RivO/VVLa17SmqheJZfI8oluVg==",
|
||||
"creator": "http://mastodon.example.org/users/admin#main-key",
|
||||
"created": "2018-02-17T18:57:49Z"
|
||||
},
|
||||
"object": "http://localtesting.pleroma.lol/objects/eb92579d-3417-42a8-8652-2492c2d4f454",
|
||||
"content": "👌",
|
||||
"nickname": "lain",
|
||||
"id": "http://mastodon.example.org/users/admin#reactions/2",
|
||||
"actor": "http://mastodon.example.org/users/admin",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"sensitive": "as:sensitive",
|
||||
"ostatus": "http://ostatus.org#",
|
||||
"movedTo": "as:movedTo",
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
|
||||
"conversation": "ostatus:conversation",
|
||||
"atomUri": "ostatus:atomUri",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"Emoji": "toot:Emoji"
|
||||
}
|
||||
]
|
||||
}
|
||||
14
test/fixtures/misskey-like.json
vendored
Normal file
14
test/fixtures/misskey-like.json
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"@context" : [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{"Hashtag" : "as:Hashtag"}
|
||||
],
|
||||
"_misskey_reaction" : "pudding",
|
||||
"actor": "http://mastodon.example.org/users/admin",
|
||||
"cc" : ["https://testing.pleroma.lol/users/lain"],
|
||||
"id" : "https://misskey.xyz/75149198-2f45-46e4-930a-8b0538297075",
|
||||
"nickname" : "lain",
|
||||
"object" : "https://testing.pleroma.lol/objects/c331bbf7-2eb9-4801-a709-2a6103492a5a",
|
||||
"type" : "Like"
|
||||
}
|
||||
|
|
@ -17,6 +17,16 @@ defmodule Pleroma.Object.ContainmentTest do
|
|||
end
|
||||
|
||||
describe "general origin containment" do
|
||||
test "works for completely actorless posts" do
|
||||
assert :error ==
|
||||
Containment.contain_origin("https://glaceon.social/users/monorail", %{
|
||||
"deleted" => "2019-10-30T05:48:50.249606Z",
|
||||
"formerType" => "Note",
|
||||
"id" => "https://glaceon.social/users/monorail/statuses/103049757364029187",
|
||||
"type" => "Tombstone"
|
||||
})
|
||||
end
|
||||
|
||||
test "contain_origin_from_id() catches obvious spoofing attempts" do
|
||||
data = %{
|
||||
"id" => "http://example.com/~alyssa/activities/1234.json"
|
||||
|
|
|
|||
|
|
@ -12,163 +12,196 @@ defmodule Pleroma.Plugs.RateLimiterTest do
|
|||
|
||||
# Note: each example must work with separate buckets in order to prevent concurrency issues
|
||||
|
||||
test "init/1" do
|
||||
limiter_name = :test_init
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {1, 1})
|
||||
describe "config" do
|
||||
test "config is required for plug to work" do
|
||||
limiter_name = :test_init
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {1, 1})
|
||||
|
||||
assert {limiter_name, {1, 1}, []} == RateLimiter.init(limiter_name)
|
||||
assert nil == RateLimiter.init(:foo)
|
||||
assert %{limits: {1, 1}, name: :test_init, opts: [name: :test_init]} ==
|
||||
RateLimiter.init(name: limiter_name)
|
||||
|
||||
assert nil == RateLimiter.init(name: :foo)
|
||||
end
|
||||
|
||||
test "it restricts based on config values" do
|
||||
limiter_name = :test_opts
|
||||
scale = 80
|
||||
limit = 5
|
||||
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit})
|
||||
|
||||
opts = RateLimiter.init(name: limiter_name)
|
||||
conn = conn(:get, "/")
|
||||
|
||||
for i <- 1..5 do
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
Process.sleep(10)
|
||||
end
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
Process.sleep(50)
|
||||
|
||||
conn = conn(:get, "/")
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
|
||||
refute conn.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
end
|
||||
end
|
||||
|
||||
test "ip/1" do
|
||||
assert "127.0.0.1" == RateLimiter.ip(%{remote_ip: {127, 0, 0, 1}})
|
||||
describe "options" do
|
||||
test "`bucket_name` option overrides default bucket name" do
|
||||
limiter_name = :test_bucket_name
|
||||
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
|
||||
|
||||
base_bucket_name = "#{limiter_name}:group1"
|
||||
opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name)
|
||||
|
||||
conn = conn(:get, "/")
|
||||
|
||||
RateLimiter.call(conn, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, base_bucket_name, opts)
|
||||
assert {:err, :not_found} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
end
|
||||
|
||||
test "`params` option allows different queries to be tracked independently" do
|
||||
limiter_name = :test_params
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
|
||||
|
||||
opts = RateLimiter.init(name: limiter_name, params: ["id"])
|
||||
|
||||
conn = conn(:get, "/?id=1")
|
||||
conn = Plug.Conn.fetch_query_params(conn)
|
||||
conn_2 = conn(:get, "/?id=2")
|
||||
|
||||
RateLimiter.call(conn, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
assert {0, 5} = RateLimiter.inspect_bucket(conn_2, limiter_name, opts)
|
||||
end
|
||||
|
||||
test "it supports combination of options modifying bucket name" do
|
||||
limiter_name = :test_options_combo
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {1000, 5})
|
||||
|
||||
base_bucket_name = "#{limiter_name}:group1"
|
||||
opts = RateLimiter.init(name: limiter_name, bucket_name: base_bucket_name, params: ["id"])
|
||||
id = "100"
|
||||
|
||||
conn = conn(:get, "/?id=#{id}")
|
||||
conn = Plug.Conn.fetch_query_params(conn)
|
||||
conn_2 = conn(:get, "/?id=#{101}")
|
||||
|
||||
RateLimiter.call(conn, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, base_bucket_name, opts)
|
||||
assert {0, 5} = RateLimiter.inspect_bucket(conn_2, base_bucket_name, opts)
|
||||
end
|
||||
end
|
||||
|
||||
test "it restricts by opts" do
|
||||
limiter_name = :test_opts
|
||||
scale = 1000
|
||||
limit = 5
|
||||
describe "unauthenticated users" do
|
||||
test "are restricted based on remote IP" do
|
||||
limiter_name = :test_unauthenticated
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], [{1000, 5}, {1, 10}])
|
||||
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit})
|
||||
opts = RateLimiter.init(name: limiter_name)
|
||||
|
||||
opts = RateLimiter.init(limiter_name)
|
||||
conn = conn(:get, "/")
|
||||
bucket_name = "#{limiter_name}:#{RateLimiter.ip(conn)}"
|
||||
conn = %{conn(:get, "/") | remote_ip: {127, 0, 0, 2}}
|
||||
conn_2 = %{conn(:get, "/") | remote_ip: {127, 0, 0, 3}}
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
for i <- 1..5 do
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {2, 3, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {3, 2, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {4, 1, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
conn_2 = RateLimiter.call(conn_2, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, opts)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {5, 0, to_reset, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
Process.sleep(to_reset)
|
||||
|
||||
conn = conn(:get, "/")
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
refute conn.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
refute conn_2.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn_2.resp_body
|
||||
refute conn_2.halted
|
||||
end
|
||||
end
|
||||
|
||||
test "`bucket_name` option overrides default bucket name" do
|
||||
limiter_name = :test_bucket_name
|
||||
scale = 1000
|
||||
limit = 5
|
||||
describe "authenticated users" do
|
||||
setup do
|
||||
Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
|
||||
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit})
|
||||
base_bucket_name = "#{limiter_name}:group1"
|
||||
opts = RateLimiter.init({limiter_name, bucket_name: base_bucket_name})
|
||||
:ok
|
||||
end
|
||||
|
||||
conn = conn(:get, "/")
|
||||
default_bucket_name = "#{limiter_name}:#{RateLimiter.ip(conn)}"
|
||||
customized_bucket_name = "#{base_bucket_name}:#{RateLimiter.ip(conn)}"
|
||||
test "can have limits seperate from unauthenticated connections" do
|
||||
limiter_name = :test_authenticated
|
||||
|
||||
RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(customized_bucket_name, scale, limit)
|
||||
assert {0, 5, _, _, _} = ExRated.inspect_bucket(default_bucket_name, scale, limit)
|
||||
end
|
||||
scale = 1000
|
||||
limit = 5
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {scale, limit}])
|
||||
|
||||
test "`params` option appends specified params' values to bucket name" do
|
||||
limiter_name = :test_params
|
||||
scale = 1000
|
||||
limit = 5
|
||||
opts = RateLimiter.init(name: limiter_name)
|
||||
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit})
|
||||
opts = RateLimiter.init({limiter_name, params: ["id"]})
|
||||
id = "1"
|
||||
user = insert(:user)
|
||||
conn = conn(:get, "/") |> assign(:user, user)
|
||||
|
||||
conn = conn(:get, "/?id=#{id}")
|
||||
conn = Plug.Conn.fetch_query_params(conn)
|
||||
for i <- 1..5 do
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
default_bucket_name = "#{limiter_name}:#{RateLimiter.ip(conn)}"
|
||||
parametrized_bucket_name = "#{limiter_name}:#{id}:#{RateLimiter.ip(conn)}"
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
|
||||
RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(parametrized_bucket_name, scale, limit)
|
||||
assert {0, 5, _, _, _} = ExRated.inspect_bucket(default_bucket_name, scale, limit)
|
||||
end
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
test "it supports combination of options modifying bucket name" do
|
||||
limiter_name = :test_options_combo
|
||||
scale = 1000
|
||||
limit = 5
|
||||
Process.sleep(1550)
|
||||
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], {scale, limit})
|
||||
base_bucket_name = "#{limiter_name}:group1"
|
||||
opts = RateLimiter.init({limiter_name, bucket_name: base_bucket_name, params: ["id"]})
|
||||
id = "100"
|
||||
conn = conn(:get, "/") |> assign(:user, user)
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
|
||||
conn = conn(:get, "/?id=#{id}")
|
||||
conn = Plug.Conn.fetch_query_params(conn)
|
||||
refute conn.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
end
|
||||
|
||||
default_bucket_name = "#{limiter_name}:#{RateLimiter.ip(conn)}"
|
||||
parametrized_bucket_name = "#{base_bucket_name}:#{id}:#{RateLimiter.ip(conn)}"
|
||||
test "diffrerent users are counted independently" do
|
||||
limiter_name = :test_authenticated
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {1000, 5}])
|
||||
|
||||
RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(parametrized_bucket_name, scale, limit)
|
||||
assert {0, 5, _, _, _} = ExRated.inspect_bucket(default_bucket_name, scale, limit)
|
||||
end
|
||||
opts = RateLimiter.init(name: limiter_name)
|
||||
|
||||
test "optional limits for authenticated users" do
|
||||
limiter_name = :test_authenticated
|
||||
Ecto.Adapters.SQL.Sandbox.checkout(Pleroma.Repo)
|
||||
user = insert(:user)
|
||||
conn = conn(:get, "/") |> assign(:user, user)
|
||||
|
||||
scale = 1000
|
||||
limit = 5
|
||||
Pleroma.Config.put([:rate_limit, limiter_name], [{1, 10}, {scale, limit}])
|
||||
user_2 = insert(:user)
|
||||
conn_2 = conn(:get, "/") |> assign(:user, user_2)
|
||||
|
||||
opts = RateLimiter.init(limiter_name)
|
||||
for i <- 1..5 do
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
end
|
||||
|
||||
user = insert(:user)
|
||||
conn = conn(:get, "/") |> assign(:user, user)
|
||||
bucket_name = "#{limiter_name}:#{user.id}"
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {2, 3, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {3, 2, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {4, 1, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {5, 0, to_reset, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
|
||||
assert %{"error" => "Throttled"} = Phoenix.ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
|
||||
Process.sleep(to_reset)
|
||||
|
||||
conn = conn(:get, "/") |> assign(:user, user)
|
||||
|
||||
conn = RateLimiter.call(conn, opts)
|
||||
assert {1, 4, _, _, _} = ExRated.inspect_bucket(bucket_name, scale, limit)
|
||||
|
||||
refute conn.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
conn_2 = RateLimiter.call(conn_2, opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn_2, limiter_name, opts)
|
||||
refute conn_2.status == Plug.Conn.Status.code(:too_many_requests)
|
||||
refute conn_2.resp_body
|
||||
refute conn_2.halted
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,6 +16,23 @@ defmodule Pleroma.Plugs.UserEnabledPlugTest do
|
|||
assert ret_conn == conn
|
||||
end
|
||||
|
||||
test "with a user that's not confirmed and a config requiring confirmation, it removes that user",
|
||||
%{conn: conn} do
|
||||
old = Pleroma.Config.get([:instance, :account_activation_required])
|
||||
Pleroma.Config.put([:instance, :account_activation_required], true)
|
||||
|
||||
user = insert(:user, confirmation_pending: true)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> UserEnabledPlug.call(%{})
|
||||
|
||||
assert conn.assigns.user == nil
|
||||
|
||||
Pleroma.Config.put([:instance, :account_activation_required], old)
|
||||
end
|
||||
|
||||
test "with a user that is deactivated, it removes that user", %{conn: conn} do
|
||||
user = insert(:user, deactivated: true)
|
||||
|
||||
|
|
|
|||
|
|
@ -1198,6 +1198,13 @@ defmodule Pleroma.UserTest do
|
|||
refute User.auth_active?(local_user)
|
||||
assert User.auth_active?(confirmed_user)
|
||||
assert User.auth_active?(remote_user)
|
||||
|
||||
# also shows unactive for deactivated users
|
||||
|
||||
deactivated_but_confirmed =
|
||||
insert(:user, local: true, confirmation_pending: false, deactivated: true)
|
||||
|
||||
refute User.auth_active?(deactivated_but_confirmed)
|
||||
end
|
||||
|
||||
describe "superuser?/1" do
|
||||
|
|
|
|||
|
|
@ -815,6 +815,78 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "react to an object" do
|
||||
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
user = insert(:user)
|
||||
reactor = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
|
||||
assert object = Object.normalize(activity)
|
||||
|
||||
{:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(reaction_activity))
|
||||
end
|
||||
|
||||
test "adds an emoji reaction activity to the db" do
|
||||
user = insert(:user)
|
||||
reactor = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
|
||||
assert object = Object.normalize(activity)
|
||||
|
||||
{:ok, reaction_activity, object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
|
||||
|
||||
assert reaction_activity
|
||||
|
||||
assert reaction_activity.data["actor"] == reactor.ap_id
|
||||
assert reaction_activity.data["type"] == "EmojiReaction"
|
||||
assert reaction_activity.data["content"] == "🔥"
|
||||
assert reaction_activity.data["object"] == object.data["id"]
|
||||
assert reaction_activity.data["to"] == [User.ap_followers(reactor), activity.data["actor"]]
|
||||
assert reaction_activity.data["context"] == object.data["context"]
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert object.data["reactions"]["🔥"] == [reactor.ap_id]
|
||||
end
|
||||
end
|
||||
|
||||
describe "unreacting to an object" do
|
||||
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
user = insert(:user)
|
||||
reactor = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
|
||||
assert object = Object.normalize(activity)
|
||||
|
||||
{:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(reaction_activity))
|
||||
|
||||
{:ok, unreaction_activity, _object} =
|
||||
ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"])
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(unreaction_activity))
|
||||
end
|
||||
|
||||
test "adds an undo activity to the db" do
|
||||
user = insert(:user)
|
||||
reactor = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
|
||||
assert object = Object.normalize(activity)
|
||||
|
||||
{:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
|
||||
|
||||
{:ok, unreaction_activity, _object} =
|
||||
ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"])
|
||||
|
||||
assert unreaction_activity.actor == reactor.ap_id
|
||||
assert unreaction_activity.data["object"] == reaction_activity.data["id"]
|
||||
|
||||
object = Object.get_by_ap_id(object.data["id"])
|
||||
assert object.data["reaction_count"] == 0
|
||||
assert object.data["reactions"] == %{}
|
||||
end
|
||||
end
|
||||
|
||||
describe "like an object" do
|
||||
test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
|
|
|
|||
105
test/web/activity_pub/mrf/object_age_policy_test.exs
Normal file
105
test/web/activity_pub/mrf/object_age_policy_test.exs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do
|
||||
use Pleroma.DataCase
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy
|
||||
alias Pleroma.Web.ActivityPub.Visibility
|
||||
|
||||
clear_config([:mrf_object_age]) do
|
||||
Config.put(:mrf_object_age,
|
||||
threshold: 172_800,
|
||||
actions: [:delist, :strip_followers]
|
||||
)
|
||||
end
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "with reject action" do
|
||||
test "it rejects an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:reject])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:reject, _} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:reject])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
{:ok, _} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with delist action" do
|
||||
test "it delists an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:delist])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, data} = ObjectAgePolicy.filter(data)
|
||||
|
||||
assert Visibility.get_visibility(%{data: data}) == "unlisted"
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:delist])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
{:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, ^data} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with strip_followers action" do
|
||||
test "it strips followers collections from an old post" do
|
||||
Config.put([:mrf_object_age, :actions], [:strip_followers])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
{:ok, user} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, data} = ObjectAgePolicy.filter(data)
|
||||
|
||||
refute user.follower_address in data["to"]
|
||||
refute user.follower_address in data["cc"]
|
||||
end
|
||||
|
||||
test "it allows a new post" do
|
||||
Config.put([:mrf_object_age, :actions], [:strip_followers])
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601())
|
||||
|
||||
{:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"])
|
||||
|
||||
{:ok, ^data} = ObjectAgePolicy.filter(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -339,6 +339,80 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert data["object"] == activity.data["object"]
|
||||
end
|
||||
|
||||
test "it works for incoming misskey likes, turning them into EmojiReactions" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/misskey-like.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("object", activity.data["object"])
|
||||
|
||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == data["actor"]
|
||||
assert data["type"] == "EmojiReaction"
|
||||
assert data["id"] == data["id"]
|
||||
assert data["object"] == activity.data["object"]
|
||||
assert data["content"] == "🍮"
|
||||
end
|
||||
|
||||
test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReactions" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/misskey-like.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("object", activity.data["object"])
|
||||
|> Map.put("_misskey_reaction", "⭐")
|
||||
|
||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == data["actor"]
|
||||
assert data["type"] == "EmojiReaction"
|
||||
assert data["id"] == data["id"]
|
||||
assert data["object"] == activity.data["object"]
|
||||
assert data["content"] == "⭐"
|
||||
end
|
||||
|
||||
test "it works for incoming emoji reactions" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/emoji-reaction.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("object", activity.data["object"])
|
||||
|
||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == "http://mastodon.example.org/users/admin"
|
||||
assert data["type"] == "EmojiReaction"
|
||||
assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2"
|
||||
assert data["object"] == activity.data["object"]
|
||||
assert data["content"] == "👌"
|
||||
end
|
||||
|
||||
test "it works for incoming emoji reaction undos" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
|
||||
{:ok, reaction_activity, _object} = CommonAPI.react_with_emoji(activity.id, user, "👌")
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-undo-like.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("object", reaction_activity.data["id"])
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:ok, activity} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert activity.actor == user.ap_id
|
||||
assert activity.data["id"] == data["id"]
|
||||
assert activity.data["type"] == "Undo"
|
||||
end
|
||||
|
||||
test "it returns an error for incoming unlikes wihout a like activity" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "leave a like pls"})
|
||||
|
|
@ -553,6 +627,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
refute Map.has_key?(object.data, "likes")
|
||||
end
|
||||
|
||||
test "it strips internal reactions" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
|
||||
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "📢")
|
||||
|
||||
%{object: object} = Activity.get_by_id_with_object(activity.id)
|
||||
assert Map.has_key?(object.data, "reactions")
|
||||
assert Map.has_key?(object.data, "reaction_count")
|
||||
|
||||
object_data = Transmogrifier.strip_internal_fields(object.data)
|
||||
refute Map.has_key?(object_data, "reactions")
|
||||
refute Map.has_key?(object_data, "reaction_count")
|
||||
end
|
||||
|
||||
test "it works for incoming update activities" do
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
||||
|
||||
|
|
|
|||
|
|
@ -636,4 +636,47 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
assert updated_object.data["announcement_count"] == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_reports_grouped_by_status/1" do
|
||||
setup do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
first_status = insert(:note_activity, user: target_user)
|
||||
second_status = insert(:note_activity, user: target_user)
|
||||
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"comment" => "I feel offended",
|
||||
"status_ids" => [first_status.id]
|
||||
})
|
||||
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"comment" => "I feel offended2",
|
||||
"status_ids" => [second_status.id]
|
||||
})
|
||||
|
||||
data = [%{activity: first_status.data["id"]}, %{activity: second_status.data["id"]}]
|
||||
|
||||
{:ok,
|
||||
%{
|
||||
first_status: first_status,
|
||||
second_status: second_status,
|
||||
data: data
|
||||
}}
|
||||
end
|
||||
|
||||
test "works for deprecated reports format", %{
|
||||
first_status: first_status,
|
||||
second_status: second_status,
|
||||
data: data
|
||||
} do
|
||||
groups = Utils.get_reports_grouped_by_status(data).groups
|
||||
|
||||
first_group = Enum.find(groups, &(&1.status.id == first_status.data["id"]))
|
||||
second_group = Enum.find(groups, &(&1.status.id == second_status.data["id"]))
|
||||
|
||||
assert first_group.status.id == first_status.data["id"]
|
||||
assert second_group.status.id == second_status.data["id"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1312,7 +1312,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "PUT /api/pleroma/admin/reports/:id" do
|
||||
describe "PATCH /api/pleroma/admin/reports" do
|
||||
setup %{conn: conn} do
|
||||
admin = insert(:user, is_admin: true)
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
|
|
@ -1325,16 +1325,32 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
"status_ids" => [activity.id]
|
||||
})
|
||||
|
||||
%{conn: assign(conn, :user, admin), id: report_id, admin: admin}
|
||||
{:ok, %{id: second_report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"comment" => "I feel very offended",
|
||||
"status_ids" => [activity.id]
|
||||
})
|
||||
|
||||
%{
|
||||
conn: assign(conn, :user, admin),
|
||||
id: report_id,
|
||||
admin: admin,
|
||||
second_report_id: second_report_id
|
||||
}
|
||||
end
|
||||
|
||||
test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
|
||||
response =
|
||||
conn
|
||||
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"})
|
||||
|> json_response(:ok)
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [
|
||||
%{"state" => "resolved", "id" => id}
|
||||
]
|
||||
})
|
||||
|> json_response(:no_content)
|
||||
|
||||
assert response["state"] == "resolved"
|
||||
activity = Activity.get_by_id(id)
|
||||
assert activity.data["state"] == "resolved"
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
|
|
@ -1343,12 +1359,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
|
||||
test "closes report", %{conn: conn, id: id, admin: admin} do
|
||||
response =
|
||||
conn
|
||||
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"})
|
||||
|> json_response(:ok)
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [
|
||||
%{"state" => "closed", "id" => id}
|
||||
]
|
||||
})
|
||||
|> json_response(:no_content)
|
||||
|
||||
assert response["state"] == "closed"
|
||||
activity = Activity.get_by_id(id)
|
||||
assert activity.data["state"] == "closed"
|
||||
|
||||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
|
|
@ -1359,17 +1379,54 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
test "returns 400 when state is unknown", %{conn: conn, id: id} do
|
||||
conn =
|
||||
conn
|
||||
|> put("/api/pleroma/admin/reports/#{id}", %{"state" => "test"})
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [
|
||||
%{"state" => "test", "id" => id}
|
||||
]
|
||||
})
|
||||
|
||||
assert json_response(conn, :bad_request) == "Unsupported state"
|
||||
assert hd(json_response(conn, :bad_request))["error"] == "Unsupported state"
|
||||
end
|
||||
|
||||
test "returns 404 when report is not exist", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put("/api/pleroma/admin/reports/test", %{"state" => "closed"})
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [
|
||||
%{"state" => "closed", "id" => "test"}
|
||||
]
|
||||
})
|
||||
|
||||
assert json_response(conn, :not_found) == "Not found"
|
||||
assert hd(json_response(conn, :bad_request))["error"] == "not_found"
|
||||
end
|
||||
|
||||
test "updates state of multiple reports", %{
|
||||
conn: conn,
|
||||
id: id,
|
||||
admin: admin,
|
||||
second_report_id: second_report_id
|
||||
} do
|
||||
conn
|
||||
|> patch("/api/pleroma/admin/reports", %{
|
||||
"reports" => [
|
||||
%{"state" => "resolved", "id" => id},
|
||||
%{"state" => "closed", "id" => second_report_id}
|
||||
]
|
||||
})
|
||||
|> json_response(:no_content)
|
||||
|
||||
activity = Activity.get_by_id(id)
|
||||
second_activity = Activity.get_by_id(second_report_id)
|
||||
assert activity.data["state"] == "resolved"
|
||||
assert second_activity.data["state"] == "closed"
|
||||
|
||||
[first_log_entry, second_log_entry] = Repo.all(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(first_log_entry) ==
|
||||
"@#{admin.nickname} updated report ##{id} with 'resolved' state"
|
||||
|
||||
assert ModerationLog.get_log_entry_message(second_log_entry) ==
|
||||
"@#{admin.nickname} updated report ##{second_report_id} with 'closed' state"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1492,7 +1549,145 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
describe "GET /api/pleroma/admin/grouped_reports" do
|
||||
setup %{conn: conn} do
|
||||
admin = insert(:user, is_admin: true)
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
|
||||
date1 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!()
|
||||
date2 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!()
|
||||
date3 = (DateTime.to_unix(DateTime.utc_now()) + 3000) |> DateTime.from_unix!()
|
||||
|
||||
first_status =
|
||||
insert(:note_activity, user: target_user, data_attrs: %{"published" => date1})
|
||||
|
||||
second_status =
|
||||
insert(:note_activity, user: target_user, data_attrs: %{"published" => date2})
|
||||
|
||||
third_status =
|
||||
insert(:note_activity, user: target_user, data_attrs: %{"published" => date3})
|
||||
|
||||
{:ok, first_report} =
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"status_ids" => [first_status.id, second_status.id, third_status.id]
|
||||
})
|
||||
|
||||
{:ok, second_report} =
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"status_ids" => [first_status.id, second_status.id]
|
||||
})
|
||||
|
||||
{:ok, third_report} =
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"status_ids" => [first_status.id]
|
||||
})
|
||||
|
||||
%{
|
||||
conn: assign(conn, :user, admin),
|
||||
first_status: Activity.get_by_ap_id_with_object(first_status.data["id"]),
|
||||
second_status: Activity.get_by_ap_id_with_object(second_status.data["id"]),
|
||||
third_status: Activity.get_by_ap_id_with_object(third_status.data["id"]),
|
||||
first_status_reports: [first_report, second_report, third_report],
|
||||
second_status_reports: [first_report, second_report],
|
||||
third_status_reports: [first_report],
|
||||
target_user: target_user,
|
||||
reporter: reporter
|
||||
}
|
||||
end
|
||||
|
||||
test "returns reports grouped by status", %{
|
||||
conn: conn,
|
||||
first_status: first_status,
|
||||
second_status: second_status,
|
||||
third_status: third_status,
|
||||
first_status_reports: first_status_reports,
|
||||
second_status_reports: second_status_reports,
|
||||
third_status_reports: third_status_reports,
|
||||
target_user: target_user,
|
||||
reporter: reporter
|
||||
} do
|
||||
response =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/grouped_reports")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert length(response["reports"]) == 3
|
||||
|
||||
first_group =
|
||||
Enum.find(response["reports"], &(&1["status"]["id"] == first_status.data["id"]))
|
||||
|
||||
second_group =
|
||||
Enum.find(response["reports"], &(&1["status"]["id"] == second_status.data["id"]))
|
||||
|
||||
third_group =
|
||||
Enum.find(response["reports"], &(&1["status"]["id"] == third_status.data["id"]))
|
||||
|
||||
assert length(first_group["reports"]) == 3
|
||||
assert length(second_group["reports"]) == 2
|
||||
assert length(third_group["reports"]) == 1
|
||||
|
||||
assert first_group["date"] ==
|
||||
Enum.max_by(first_status_reports, fn act ->
|
||||
NaiveDateTime.from_iso8601!(act.data["published"])
|
||||
end).data["published"]
|
||||
|
||||
assert first_group["status"] == %{
|
||||
"id" => first_status.data["id"],
|
||||
"content" => first_status.object.data["content"],
|
||||
"published" => first_status.object.data["published"]
|
||||
}
|
||||
|
||||
assert first_group["account"]["id"] == target_user.id
|
||||
|
||||
assert length(first_group["actors"]) == 1
|
||||
assert hd(first_group["actors"])["id"] == reporter.id
|
||||
|
||||
assert Enum.map(first_group["reports"], & &1["id"]) --
|
||||
Enum.map(first_status_reports, & &1.id) == []
|
||||
|
||||
assert second_group["date"] ==
|
||||
Enum.max_by(second_status_reports, fn act ->
|
||||
NaiveDateTime.from_iso8601!(act.data["published"])
|
||||
end).data["published"]
|
||||
|
||||
assert second_group["status"] == %{
|
||||
"id" => second_status.data["id"],
|
||||
"content" => second_status.object.data["content"],
|
||||
"published" => second_status.object.data["published"]
|
||||
}
|
||||
|
||||
assert second_group["account"]["id"] == target_user.id
|
||||
|
||||
assert length(second_group["actors"]) == 1
|
||||
assert hd(second_group["actors"])["id"] == reporter.id
|
||||
|
||||
assert Enum.map(second_group["reports"], & &1["id"]) --
|
||||
Enum.map(second_status_reports, & &1.id) == []
|
||||
|
||||
assert third_group["date"] ==
|
||||
Enum.max_by(third_status_reports, fn act ->
|
||||
NaiveDateTime.from_iso8601!(act.data["published"])
|
||||
end).data["published"]
|
||||
|
||||
assert third_group["status"] == %{
|
||||
"id" => third_status.data["id"],
|
||||
"content" => third_status.object.data["content"],
|
||||
"published" => third_status.object.data["published"]
|
||||
}
|
||||
|
||||
assert third_group["account"]["id"] == target_user.id
|
||||
|
||||
assert length(third_group["actors"]) == 1
|
||||
assert hd(third_group["actors"])["id"] == reporter.id
|
||||
|
||||
assert Enum.map(third_group["reports"], & &1["id"]) --
|
||||
Enum.map(third_status_reports, & &1.id) == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/pleroma/admin/reports/:id/respond" do
|
||||
setup %{conn: conn} do
|
||||
admin = insert(:user, is_admin: true)
|
||||
|
|
@ -2269,6 +2464,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
Pleroma.Config.put([:instance, :dynamic_configuration], true)
|
||||
end
|
||||
|
||||
clear_config([:feed, :post_title]) do
|
||||
Pleroma.Config.put([:feed, :post_title], %{max_length: 100, omission: "…"})
|
||||
end
|
||||
|
||||
test "transfer settings to DB and to file", %{conn: conn, admin: admin} do
|
||||
assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == []
|
||||
conn = get(conn, "/api/pleroma/admin/config/migrate_to_db")
|
||||
|
|
|
|||
|
|
@ -227,6 +227,33 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
end
|
||||
|
||||
describe "reactions" do
|
||||
test "reacting to a status with an emoji" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
|
||||
|
||||
{:ok, reaction, _} = CommonAPI.react_with_emoji(activity.id, user, "👍")
|
||||
|
||||
assert reaction.data["actor"] == user.ap_id
|
||||
assert reaction.data["content"] == "👍"
|
||||
|
||||
# TODO: test error case.
|
||||
end
|
||||
|
||||
test "unreacting to a status with an emoji" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
|
||||
{:ok, reaction, _} = CommonAPI.react_with_emoji(activity.id, user, "👍")
|
||||
|
||||
{:ok, unreaction, _} = CommonAPI.unreact_with_emoji(activity.id, user, "👍")
|
||||
|
||||
assert unreaction.data["type"] == "Undo"
|
||||
assert unreaction.data["object"] == reaction.data["id"]
|
||||
end
|
||||
|
||||
test "repeating a status" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
|
@ -441,6 +468,35 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
assert CommonAPI.update_report_state(report_id, "test") == {:error, "Unsupported state"}
|
||||
end
|
||||
|
||||
test "updates state of multiple reports" do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
|
||||
{:ok, %Activity{id: first_report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"comment" => "I feel offended",
|
||||
"status_ids" => [activity.id]
|
||||
})
|
||||
|
||||
{:ok, %Activity{id: second_report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
"account_id" => target_user.id,
|
||||
"comment" => "I feel very offended!",
|
||||
"status_ids" => [activity.id]
|
||||
})
|
||||
|
||||
{:ok, report_ids} =
|
||||
CommonAPI.update_report_state([first_report_id, second_report_id], "resolved")
|
||||
|
||||
first_report = Activity.get_by_id(first_report_id)
|
||||
second_report = Activity.get_by_id(second_report_id)
|
||||
|
||||
assert report_ids -- [first_report_id, second_report_id] == []
|
||||
assert first_report.data["state"] == "resolved"
|
||||
assert second_report.data["state"] == "resolved"
|
||||
end
|
||||
end
|
||||
|
||||
describe "reblog muting" do
|
||||
|
|
|
|||
|
|
@ -84,6 +84,30 @@ defmodule Pleroma.Web.NodeInfoTest do
|
|||
Pleroma.Config.put([:instance, :safe_dm_mentions], option)
|
||||
end
|
||||
|
||||
test "it shows if federation is enabled/disabled", %{conn: conn} do
|
||||
original = Pleroma.Config.get([:instance, :federating])
|
||||
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/nodeinfo/2.1.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response["metadata"]["federation"]["enabled"] == true
|
||||
|
||||
Pleroma.Config.put([:instance, :federating], false)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/nodeinfo/2.1.json")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response["metadata"]["federation"]["enabled"] == false
|
||||
|
||||
Pleroma.Config.put([:instance, :federating], original)
|
||||
end
|
||||
|
||||
test "it shows MRF transparency data if enabled", %{conn: conn} do
|
||||
config = Pleroma.Config.get([:instance, :rewrite_policy])
|
||||
Pleroma.Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
|
||||
|
|
|
|||
|
|
@ -469,6 +469,29 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
|
|||
assert html_response(conn, 200) =~ ~s(type="submit")
|
||||
end
|
||||
|
||||
test "renders authentication page if user is already authenticated but user request with another client",
|
||||
%{
|
||||
app: app,
|
||||
conn: conn
|
||||
} do
|
||||
token = insert(:oauth_token, app_id: app.id)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_session(:oauth_token, token.token)
|
||||
|> get(
|
||||
"/oauth/authorize",
|
||||
%{
|
||||
"response_type" => "code",
|
||||
"client_id" => "another_client_id",
|
||||
"redirect_uri" => OAuthController.default_redirect_uri(app),
|
||||
"scope" => "read"
|
||||
}
|
||||
)
|
||||
|
||||
assert html_response(conn, 200) =~ ~s(type="submit")
|
||||
end
|
||||
|
||||
test "with existing authentication and non-OOB `redirect_uri`, redirects to app with `token` and `state` params",
|
||||
%{
|
||||
app: app,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,72 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
|
|||
|
||||
alias Pleroma.Conversation.Participation
|
||||
alias Pleroma.Notification
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "POST /api/v1/pleroma/statuses/:id/react_with_emoji", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> post("/api/v1/pleroma/statuses/#{activity.id}/react_with_emoji", %{"emoji" => "☕"})
|
||||
|
||||
assert %{"id" => id} = json_response(result, 200)
|
||||
assert to_string(activity.id) == id
|
||||
end
|
||||
|
||||
test "POST /api/v1/pleroma/statuses/:id/unreact_with_emoji", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
|
||||
{:ok, activity, _object} = CommonAPI.react_with_emoji(activity.id, other_user, "☕")
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> post("/api/v1/pleroma/statuses/#{activity.id}/unreact_with_emoji", %{"emoji" => "☕"})
|
||||
|
||||
assert %{"id" => id} = json_response(result, 200)
|
||||
assert to_string(activity.id) == id
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
assert object.data["reaction_count"] == 0
|
||||
end
|
||||
|
||||
test "GET /api/v1/pleroma/statuses/:id/emoji_reactions_by", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/emoji_reactions_by")
|
||||
|> json_response(200)
|
||||
|
||||
assert result == %{}
|
||||
|
||||
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/statuses/#{activity.id}/emoji_reactions_by")
|
||||
|> json_response(200)
|
||||
|
||||
[represented_user] = result["🎅"]
|
||||
assert represented_user["id"] == other_user.id
|
||||
end
|
||||
|
||||
test "/api/v1/pleroma/conversations/:id", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
|
|
|||
210
test/web/static_fe/static_fe_controller_test.exs
Normal file
210
test/web/static_fe/static_fe_controller_test.exs
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
clear_config_all([:static_fe, :enabled]) do
|
||||
Pleroma.Config.put([:static_fe, :enabled], true)
|
||||
end
|
||||
|
||||
describe "user profile page" do
|
||||
test "just the profile as HTML", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|
||||
assert html_response(conn, 200) =~ user.nickname
|
||||
end
|
||||
|
||||
test "renders json unless there's an html accept header", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "application/json")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|
||||
assert json_response(conn, 200)
|
||||
end
|
||||
|
||||
test "404 when user not found", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/users/limpopo")
|
||||
|
||||
assert html_response(conn, 404) =~ "not found"
|
||||
end
|
||||
|
||||
test "profile does not include private messages", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
CommonAPI.post(user, %{"status" => "public"})
|
||||
CommonAPI.post(user, %{"status" => "private", "visibility" => "private"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|
||||
html = html_response(conn, 200)
|
||||
|
||||
assert html =~ ">public<"
|
||||
refute html =~ ">private<"
|
||||
end
|
||||
|
||||
test "pagination", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
Enum.map(1..30, fn i -> CommonAPI.post(user, %{"status" => "test#{i}"}) end)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/users/#{user.nickname}")
|
||||
|
||||
html = html_response(conn, 200)
|
||||
|
||||
assert html =~ ">test30<"
|
||||
assert html =~ ">test11<"
|
||||
refute html =~ ">test10<"
|
||||
refute html =~ ">test1<"
|
||||
end
|
||||
|
||||
test "pagination, page 2", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
activities = Enum.map(1..30, fn i -> CommonAPI.post(user, %{"status" => "test#{i}"}) end)
|
||||
{:ok, a11} = Enum.at(activities, 11)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/users/#{user.nickname}?max_id=#{a11.id}")
|
||||
|
||||
html = html_response(conn, 200)
|
||||
|
||||
assert html =~ ">test1<"
|
||||
assert html =~ ">test10<"
|
||||
refute html =~ ">test20<"
|
||||
refute html =~ ">test29<"
|
||||
end
|
||||
end
|
||||
|
||||
describe "notice rendering" do
|
||||
test "single notice page", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "testing a thing!"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/notice/#{activity.id}")
|
||||
|
||||
html = html_response(conn, 200)
|
||||
assert html =~ "<header>"
|
||||
assert html =~ user.nickname
|
||||
assert html =~ "testing a thing!"
|
||||
end
|
||||
|
||||
test "shows the whole thread", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "space: the final frontier"})
|
||||
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "these are the voyages or something",
|
||||
"in_reply_to_status_id" => activity.id
|
||||
})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/notice/#{activity.id}")
|
||||
|
||||
html = html_response(conn, 200)
|
||||
assert html =~ "the final frontier"
|
||||
assert html =~ "voyages"
|
||||
end
|
||||
|
||||
test "redirect by AP object ID", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, %Activity{data: %{"object" => object_url}}} =
|
||||
CommonAPI.post(user, %{"status" => "beam me up"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get(URI.parse(object_url).path)
|
||||
|
||||
assert html_response(conn, 302) =~ "redirected"
|
||||
end
|
||||
|
||||
test "redirect by activity ID", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, %Activity{data: %{"id" => id}}} =
|
||||
CommonAPI.post(user, %{"status" => "I'm a doctor, not a devops!"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get(URI.parse(id).path)
|
||||
|
||||
assert html_response(conn, 302) =~ "redirected"
|
||||
end
|
||||
|
||||
test "404 when notice not found", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/notice/88c9c317")
|
||||
|
||||
assert html_response(conn, 404) =~ "not found"
|
||||
end
|
||||
|
||||
test "404 for private status", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{"status" => "don't show me!", "visibility" => "private"})
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/notice/#{activity.id}")
|
||||
|
||||
assert html_response(conn, 404) =~ "not found"
|
||||
end
|
||||
|
||||
test "302 for remote cached status", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
message = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"to" => user.follower_address,
|
||||
"cc" => "https://www.w3.org/ns/activitystreams#Public",
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "blah blah blah",
|
||||
"type" => "Note",
|
||||
"attributedTo" => user.ap_id,
|
||||
"inReplyTo" => nil
|
||||
},
|
||||
"actor" => user.ap_id
|
||||
}
|
||||
|
||||
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/notice/#{activity.id}")
|
||||
|
||||
assert html_response(conn, 302) =~ "redirected"
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue