Merge branch 'develop' into feature/reports-groups-and-multiple-state-update

This commit is contained in:
Maxim Filippov 2019-10-07 15:41:41 +03:00
commit 35068baf65
148 changed files with 2629 additions and 1322 deletions

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Conversation.Participation
alias Pleroma.User
alias Pleroma.Web.CommonAPI
test "getting a participation will also preload things" do
@ -30,6 +31,8 @@ defmodule Pleroma.Conversation.ParticipationTest do
{:ok, activity} =
CommonAPI.post(user, %{"status" => "Hey @#{other_user.nickname}.", "visibility" => "direct"})
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(user.id)
[participation] = Participation.for_user(user)
participation = Pleroma.Repo.preload(participation, :recipients)
@ -155,6 +158,7 @@ defmodule Pleroma.Conversation.ParticipationTest do
[participation] = Participation.for_user_with_last_activity_id(user)
participation = Repo.preload(participation, :recipients)
user = User.get_cached_by_id(user.id)
assert participation.recipients |> length() == 1
assert user in participation.recipients

View file

@ -19,8 +19,8 @@ defmodule Pleroma.Emails.AdminEmailTest do
AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")
status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12")
reporter_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.nickname)
account_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, account.nickname)
reporter_url = Helpers.feed_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id)
account_url = Helpers.feed_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)
assert res.to == [{to_user.name, to_user.email}]
assert res.from == {config[:name], config[:notify_email]}

View file

@ -0,0 +1,43 @@
{
"type": "Announce",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"published": "2018-02-17T19:39:15Z",
"object": {
"type": "Note",
"id": "https://mastodon.social/users/emelie/statuses/101849165031453404",
"attributedTo": "https://mastodon.social/users/emelie",
"content": "this is a public toot",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://mastodon.social/users/emelie",
"https://mastodon.social/users/emelie/followers"
]
},
"id": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity",
"cc": [
"http://mastodon.example.org/users/admin",
"http://mastodon.example.org/users/admin/followers"
],
"atomUri": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity",
"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"
}
]
}

View file

@ -0,0 +1,35 @@
{
"type": "Announce",
"to": [
"http://mastodon.example.org/users/admin/followers"
],
"published": "2018-02-17T19:39:15Z",
"object": {
"type": "Note",
"id": "http://mastodon.example.org/@admin/99541947525187368",
"attributedTo": "http://mastodon.example.org/users/admin",
"content": "this is a private toot",
"to": [
"http://mastodon.example.org/users/admin/followers"
]
},
"id": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity",
"atomUri": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity",
"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"
}
]
}

View file

@ -9,7 +9,14 @@ defmodule Pleroma.HealthcheckTest do
test "system_info/0" do
result = Healthcheck.system_info() |> Map.from_struct()
assert Map.keys(result) == [:active, :healthy, :idle, :memory_used, :pool_size]
assert Map.keys(result) == [
:active,
:healthy,
:idle,
:job_queue_stats,
:memory_used,
:pool_size
]
end
describe "check_health/1" do

View file

@ -0,0 +1,70 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.JobQueueMonitorTest do
use ExUnit.Case, async: true
alias Pleroma.JobQueueMonitor
@success {:process_event, :success, 1337,
%{
args: %{"op" => "refresh_subscriptions"},
attempt: 1,
id: 339,
max_attempts: 5,
queue: "federator_outgoing",
worker: "Pleroma.Workers.SubscriberWorker"
}}
@failure {:process_event, :failure, 22_521_134,
%{
args: %{"op" => "force_password_reset", "user_id" => "9nJG6n6Nbu7tj9GJX6"},
attempt: 1,
error: %RuntimeError{message: "oops"},
id: 345,
kind: :exception,
max_attempts: 1,
queue: "background",
stack: [
{Pleroma.Workers.BackgroundWorker, :perform, 2,
[file: 'lib/pleroma/workers/background_worker.ex', line: 31]},
{Oban.Queue.Executor, :safe_call, 1,
[file: 'lib/oban/queue/executor.ex', line: 42]},
{:timer, :tc, 3, [file: 'timer.erl', line: 197]},
{Oban.Queue.Executor, :call, 2, [file: 'lib/oban/queue/executor.ex', line: 23]},
{Task.Supervised, :invoke_mfa, 2, [file: 'lib/task/supervised.ex', line: 90]},
{:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}
],
worker: "Pleroma.Workers.BackgroundWorker"
}}
test "stats/0" do
assert %{processed_jobs: _, queues: _, workers: _} = JobQueueMonitor.stats()
end
test "handle_cast/2" do
state = %{workers: %{}, queues: %{}, processed_jobs: 0}
assert {:noreply, state} = JobQueueMonitor.handle_cast(@success, state)
assert {:noreply, state} = JobQueueMonitor.handle_cast(@failure, state)
assert {:noreply, state} = JobQueueMonitor.handle_cast(@success, state)
assert {:noreply, state} = JobQueueMonitor.handle_cast(@failure, state)
assert state == %{
processed_jobs: 4,
queues: %{
"background" => %{failure: 2, processed_jobs: 2, success: 0},
"federator_outgoing" => %{failure: 0, processed_jobs: 2, success: 2}
},
workers: %{
"Pleroma.Workers.BackgroundWorker" => %{
"force_password_reset" => %{failure: 2, processed_jobs: 2, success: 0}
},
"Pleroma.Workers.SubscriberWorker" => %{
"refresh_subscriptions" => %{failure: 0, processed_jobs: 2, success: 2}
}
}
}
end
end

View file

@ -5,24 +5,48 @@
defmodule Pleroma.Plugs.OAuthScopesPlugTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.Repo
import Mock
import Pleroma.Factory
test "proceeds with no op if `assigns[:token]` is nil", %{conn: conn} do
conn =
conn
|> assign(:user, insert(:user))
|> OAuthScopesPlug.call(%{scopes: ["read"]})
refute conn.halted
assert conn.assigns[:user]
setup_with_mocks([{EnsurePublicOrAuthenticatedPlug, [], [call: fn conn, _ -> conn end]}]) do
:ok
end
test "proceeds with no op if `token.scopes` fulfill specified 'any of' conditions", %{
conn: conn
} do
describe "when `assigns[:token]` is nil, " do
test "with :skip_instance_privacy_check option, proceeds with no op", %{conn: conn} do
conn =
conn
|> assign(:user, insert(:user))
|> OAuthScopesPlug.call(%{scopes: ["read"], skip_instance_privacy_check: true})
refute conn.halted
assert conn.assigns[:user]
refute called(EnsurePublicOrAuthenticatedPlug.call(conn, :_))
end
test "without :skip_instance_privacy_check option, calls EnsurePublicOrAuthenticatedPlug", %{
conn: conn
} do
conn =
conn
|> assign(:user, insert(:user))
|> OAuthScopesPlug.call(%{scopes: ["read"]})
refute conn.halted
assert conn.assigns[:user]
assert called(EnsurePublicOrAuthenticatedPlug.call(conn, :_))
end
end
test "if `token.scopes` fulfills specified 'any of' conditions, " <>
"proceeds with no op",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
conn =
@ -35,9 +59,9 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do
assert conn.assigns[:user]
end
test "proceeds with no op if `token.scopes` fulfill specified 'all of' conditions", %{
conn: conn
} do
test "if `token.scopes` fulfills specified 'all of' conditions, " <>
"proceeds with no op",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
conn =
@ -50,73 +74,154 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do
assert conn.assigns[:user]
end
test "proceeds with cleared `assigns[:user]` if `token.scopes` doesn't fulfill specified 'any of' conditions " <>
"and `fallback: :proceed_unauthenticated` option is specified",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
describe "with `fallback: :proceed_unauthenticated` option, " do
test "if `token.scopes` doesn't fulfill specified 'any of' conditions, " <>
"clears `assigns[:user]` and calls EnsurePublicOrAuthenticatedPlug",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: ["follow"], fallback: :proceed_unauthenticated})
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: ["follow"], fallback: :proceed_unauthenticated})
refute conn.halted
refute conn.assigns[:user]
refute conn.halted
refute conn.assigns[:user]
assert called(EnsurePublicOrAuthenticatedPlug.call(conn, :_))
end
test "if `token.scopes` doesn't fulfill specified 'all of' conditions, " <>
"clears `assigns[:user] and calls EnsurePublicOrAuthenticatedPlug",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{
scopes: ["read", "follow"],
op: :&,
fallback: :proceed_unauthenticated
})
refute conn.halted
refute conn.assigns[:user]
assert called(EnsurePublicOrAuthenticatedPlug.call(conn, :_))
end
test "with :skip_instance_privacy_check option, " <>
"if `token.scopes` doesn't fulfill specified conditions, " <>
"clears `assigns[:user]` and does not call EnsurePublicOrAuthenticatedPlug",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read:statuses", "write"]) |> Repo.preload(:user)
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{
scopes: ["read"],
fallback: :proceed_unauthenticated,
skip_instance_privacy_check: true
})
refute conn.halted
refute conn.assigns[:user]
refute called(EnsurePublicOrAuthenticatedPlug.call(conn, :_))
end
end
test "proceeds with cleared `assigns[:user]` if `token.scopes` doesn't fulfill specified 'all of' conditions " <>
"and `fallback: :proceed_unauthenticated` option is specified",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
describe "without :fallback option, " do
test "if `token.scopes` does not fulfill specified 'any of' conditions, " <>
"returns 403 and halts",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"])
any_of_scopes = ["follow"]
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{
scopes: ["read", "follow"],
op: :&,
fallback: :proceed_unauthenticated
})
conn =
conn
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: any_of_scopes})
refute conn.halted
refute conn.assigns[:user]
assert conn.halted
assert 403 == conn.status
expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, ", ")}."
assert Jason.encode!(%{error: expected_error}) == conn.resp_body
end
test "if `token.scopes` does not fulfill specified 'all of' conditions, " <>
"returns 403 and halts",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"])
all_of_scopes = ["write", "follow"]
conn =
conn
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: all_of_scopes, op: :&})
assert conn.halted
assert 403 == conn.status
expected_error =
"Insufficient permissions: #{Enum.join(all_of_scopes -- token.scopes, ", ")}."
assert Jason.encode!(%{error: expected_error}) == conn.resp_body
end
end
test "returns 403 and halts in case of no :fallback option and `token.scopes` not fulfilling specified 'any of' conditions",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"])
any_of_scopes = ["follow"]
describe "with hierarchical scopes, " do
test "if `token.scopes` fulfills specified 'any of' conditions, " <>
"proceeds with no op",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
conn =
conn
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: any_of_scopes})
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: ["read:something"]})
assert conn.halted
assert 403 == conn.status
refute conn.halted
assert conn.assigns[:user]
end
expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, ", ")}."
assert Jason.encode!(%{error: expected_error}) == conn.resp_body
test "if `token.scopes` fulfills specified 'all of' conditions, " <>
"proceeds with no op",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
conn =
conn
|> assign(:user, token.user)
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: ["scope1:subscope", "scope2:subscope"], op: :&})
refute conn.halted
assert conn.assigns[:user]
end
end
test "returns 403 and halts in case of no :fallback option and `token.scopes` not fulfilling specified 'all of' conditions",
%{conn: conn} do
token = insert(:oauth_token, scopes: ["read", "write"])
all_of_scopes = ["write", "follow"]
describe "filter_descendants/2" do
test "filters scopes which directly match or are ancestors of supported scopes" do
f = fn scopes, supported_scopes ->
OAuthScopesPlug.filter_descendants(scopes, supported_scopes)
end
conn =
conn
|> assign(:token, token)
|> OAuthScopesPlug.call(%{scopes: all_of_scopes, op: :&})
assert f.(["read", "follow"], ["write", "read"]) == ["read"]
assert conn.halted
assert 403 == conn.status
assert f.(["read", "write:something", "follow"], ["write", "read"]) ==
["read", "write:something"]
expected_error =
"Insufficient permissions: #{Enum.join(all_of_scopes -- token.scopes, ", ")}."
assert f.(["admin:read"], ["write", "read"]) == []
assert Jason.encode!(%{error: expected_error}) == conn.resp_body
assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"]
end
end
end

View file

@ -80,7 +80,7 @@ defmodule Pleroma.SignatureTest do
user =
insert(:user, %{
ap_id: "https://mastodon.social/users/lambadalambda",
info: %{keys: @private_key}
keys: @private_key
})
assert Signature.sign(
@ -94,8 +94,7 @@ defmodule Pleroma.SignatureTest do
end
test "it returns error" do
user =
insert(:user, %{ap_id: "https://mastodon.social/users/lambadalambda", info: %{keys: ""}})
user = insert(:user, %{ap_id: "https://mastodon.social/users/lambadalambda", keys: ""})
assert Signature.sign(
user,

View file

@ -324,6 +324,7 @@ defmodule Pleroma.Factory do
%Pleroma.Web.OAuth.Token{
token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),
scopes: ["read"],
refresh_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),
user: build(:user),
app_id: oauth_app.id,

View file

@ -46,6 +46,14 @@ defmodule HttpRequestMock do
}}
end
def get("https://mastodon.social/users/emelie/statuses/101849165031453404", _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
def get("https://mastodon.social/users/emelie", _, _, _) do
{:ok,
%Tesla.Env{
@ -349,6 +357,14 @@ defmodule HttpRequestMock do
}}
end
def get("http://mastodon.example.org/@admin/99541947525187368", _, _, _) do
{:ok,
%Tesla.Env{
status: 404,
body: ""
}}
end
def get("https://shitposter.club/notice/7369654", _, _, _) do
{:ok,
%Tesla.Env{

View file

@ -515,7 +515,7 @@ defmodule Pleroma.UserTest do
user = insert(:user)
assert User.ap_id(user) ==
Pleroma.Web.Router.Helpers.o_status_url(
Pleroma.Web.Router.Helpers.feed_url(
Pleroma.Web.Endpoint,
:feed_redirect,
user.nickname
@ -526,7 +526,7 @@ defmodule Pleroma.UserTest do
user = insert(:user)
assert User.ap_followers(user) ==
Pleroma.Web.Router.Helpers.o_status_url(
Pleroma.Web.Router.Helpers.feed_url(
Pleroma.Web.Endpoint,
:feed_redirect,
user.nickname
@ -1457,15 +1457,15 @@ defmodule Pleroma.UserTest do
describe "ensure_keys_present" do
test "it creates keys for a user and stores them in info" do
user = insert(:user)
refute is_binary(user.info.keys)
refute is_binary(user.keys)
{:ok, user} = User.ensure_keys_present(user)
assert is_binary(user.info.keys)
assert is_binary(user.keys)
end
test "it doesn't create keys if there already are some" do
user = insert(:user, %{info: %{keys: "xxx"}})
user = insert(:user, keys: "xxx")
{:ok, user} = User.ensure_keys_present(user)
assert user.info.keys == "xxx"
assert user.keys == "xxx"
end
end
@ -1725,4 +1725,61 @@ defmodule Pleroma.UserTest do
assert %{info: %{hide_follows: true}} = Repo.get(User, user.id)
assert {:ok, %{info: %{hide_follows: true}}} = Cachex.get(:user_cache, "ap_id:#{user.ap_id}")
end
describe "get_cached_by_nickname_or_id" do
setup do
limit_to_local_content = Pleroma.Config.get([:instance, :limit_to_local_content])
local_user = insert(:user)
remote_user = insert(:user, nickname: "nickname@example.com", local: false)
on_exit(fn ->
Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local_content)
end)
[local_user: local_user, remote_user: remote_user]
end
test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
remote_user: remote_user
} do
Pleroma.Config.put([:instance, :limit_to_local_content], false)
assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
Pleroma.Config.put([:instance, :limit_to_local_content], true)
assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
assert %User{} = User.get_cached_by_nickname_or_id(remote_user.id)
end
test "disallows getting remote users by nickname without authentication when :limit_to_local_content is set to :unauthenticated",
%{remote_user: remote_user} do
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
end
test "allows getting remote users by nickname with authentication when :limit_to_local_content is set to :unauthenticated",
%{remote_user: remote_user, local_user: local_user} do
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
assert %User{} = User.get_cached_by_nickname_or_id(remote_user.nickname, for: local_user)
end
test "disallows getting remote users by nickname when :limit_to_local_content is set to true",
%{remote_user: remote_user} do
Pleroma.Config.put([:instance, :limit_to_local_content], true)
assert nil == User.get_cached_by_nickname_or_id(remote_user.nickname)
end
test "allows getting local users by nickname no matter what :limit_to_local_content is set to",
%{local_user: local_user} do
Pleroma.Config.put([:instance, :limit_to_local_content], false)
assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
Pleroma.Config.put([:instance, :limit_to_local_content], true)
assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
assert %User{} = User.get_cached_by_nickname_or_id(local_user.nickname)
end
end
end

View file

@ -225,69 +225,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
end
describe "/object/:uuid/likes" do
setup do
like = insert(:like_activity)
like_object_ap_id = Object.normalize(like).data["id"]
uuid =
like_object_ap_id
|> String.split("/")
|> List.last()
[id: like.data["id"], uuid: uuid]
end
test "it returns the like activities in a collection", %{conn: conn, id: id, uuid: uuid} do
result =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}/likes")
|> json_response(200)
assert List.first(result["first"]["orderedItems"])["id"] == id
assert result["type"] == "OrderedCollection"
assert result["totalItems"] == 1
refute result["first"]["next"]
end
test "it does not crash when page number is exceeded total pages", %{conn: conn, uuid: uuid} do
result =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}/likes?page=2")
|> json_response(200)
assert result["type"] == "OrderedCollectionPage"
assert result["totalItems"] == 1
refute result["next"]
assert Enum.empty?(result["orderedItems"])
end
test "it contains the next key when likes count is more than 10", %{conn: conn} do
note = insert(:note_activity)
insert_list(11, :like_activity, note_activity: note)
uuid =
note
|> Object.normalize()
|> Map.get(:data)
|> Map.get("id")
|> String.split("/")
|> List.last()
result =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/objects/#{uuid}/likes?page=1")
|> json_response(200)
assert result["totalItems"] == 11
assert length(result["orderedItems"]) == 10
assert result["next"]
end
end
describe "/activities/:uuid" do
test "it returns a json representation of the activity", %{conn: conn} do
activity = insert(:note_activity)

View file

@ -811,10 +811,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, like_activity, object} = ActivityPub.like(user, object)
assert object.data["like_count"] == 1
{:ok, _, _, object} = ActivityPub.unlike(user, object)
{:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object)
assert object.data["like_count"] == 0
assert Activity.get_by_id(like_activity.id) == nil
assert note_activity.actor in unlike_activity.recipients
end
end
@ -890,7 +891,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert unannounce_activity.data["to"] == [
User.ap_followers(user),
announce_activity.data["actor"]
object.data["actor"]
]
assert unannounce_activity.data["type"] == "Undo"

View file

@ -236,7 +236,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "has a matching host" do
test "activity has a matching host" do
Config.put([:mrf_simple, :reject], ["remote.instance"])
remote_message = build_remote_message()
@ -244,13 +244,21 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
assert SimplePolicy.filter(remote_message) == {:reject, nil}
end
test "match with wildcard domain" do
test "activity matches with wildcard domain" do
Config.put([:mrf_simple, :reject], ["*.remote.instance"])
remote_message = build_remote_message()
assert SimplePolicy.filter(remote_message) == {:reject, nil}
end
test "actor has a matching host" do
Config.put([:mrf_simple, :reject], ["remote.instance"])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:reject, nil}
end
end
describe "when :accept" do
@ -264,7 +272,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "is not empty but it doesn't have a matching host" do
test "is not empty but activity doesn't have a matching host" do
Config.put([:mrf_simple, :accept], ["non.matching.remote"])
local_message = build_local_message()
@ -274,7 +282,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
assert SimplePolicy.filter(remote_message) == {:reject, nil}
end
test "has a matching host" do
test "activity has a matching host" do
Config.put([:mrf_simple, :accept], ["remote.instance"])
local_message = build_local_message()
@ -284,7 +292,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "match with wildcard domain" do
test "activity matches with wildcard domain" do
Config.put([:mrf_simple, :accept], ["*.remote.instance"])
local_message = build_local_message()
@ -293,6 +301,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do
assert SimplePolicy.filter(local_message) == {:ok, local_message}
assert SimplePolicy.filter(remote_message) == {:ok, remote_message}
end
test "actor has a matching host" do
Config.put([:mrf_simple, :accept], ["remote.instance"])
remote_user = build_remote_user()
assert SimplePolicy.filter(remote_user) == {:ok, remote_user}
end
end
describe "when :avatar_removal" do

View file

@ -442,6 +442,33 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert Activity.get_create_by_object_ap_id(data["object"]).id == activity.id
end
test "it works for incoming announces with an inlined activity" do
data =
File.read!("test/fixtures/mastodon-announce-private.json")
|> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["actor"] == "http://mastodon.example.org/users/admin"
assert data["type"] == "Announce"
assert data["id"] ==
"http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
object = Object.normalize(data["object"])
assert object.data["id"] == "http://mastodon.example.org/@admin/99541947525187368"
assert object.data["content"] == "this is a private toot"
end
test "it rejects incoming announces with an inlined activity from another origin" do
data =
File.read!("test/fixtures/bogus-mastodon-announce.json")
|> Poison.decode!()
assert :error = Transmogrifier.handle_incoming(data)
end
test "it does not clobber the addressing on announce activities" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey"})
@ -546,6 +573,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
assert data["id"] == update_data["id"]
user = User.get_cached_by_ap_id(data["actor"])
assert user.name == "gargle"

View file

@ -106,11 +106,13 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user = insert(:user)
like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"})
object = Object.normalize(like_activity.data["object"])
assert Utils.make_unlike_data(user, like_activity, nil) == %{
"type" => "Undo",
"actor" => user.ap_id,
"object" => like_activity.data,
"to" => [user.follower_address, like_activity.data["actor"]],
"to" => [user.follower_address, object.data["actor"]],
"cc" => [Pleroma.Constants.as_public()],
"context" => like_activity.data["context"]
}
@ -119,7 +121,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
"type" => "Undo",
"actor" => user.ap_id,
"object" => like_activity.data,
"to" => [user.follower_address, like_activity.data["actor"]],
"to" => [user.follower_address, object.data["actor"]],
"cc" => [Pleroma.Constants.as_public()],
"context" => like_activity.data["context"],
"id" => "9mJEZK0tky1w2xD2vY"

View file

@ -14,6 +14,8 @@ defmodule Pleroma.Web.CommonAPITest do
import Pleroma.Factory
require Pleroma.Constants
clear_config([:instance, :safe_dm_mentions])
clear_config([:instance, :limit])
clear_config([:instance, :max_pinned_statuses])
@ -96,11 +98,13 @@ defmodule Pleroma.Web.CommonAPITest do
test "it adds emoji when updating profiles" do
user = insert(:user, %{name: ":firefox:"})
CommonAPI.update(user)
{:ok, activity} = CommonAPI.update(user)
user = User.get_cached_by_ap_id(user.ap_id)
[firefox] = user.info.source_data["tag"]
assert firefox["name"] == ":firefox:"
assert Pleroma.Constants.as_public() in activity.recipients
end
describe "posting" do

View file

@ -0,0 +1,227 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Feed.FeedControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.Object
alias Pleroma.User
test "gets a feed", %{conn: conn} do
activity = insert(:note_activity)
note =
insert(:note,
data: %{
"attachment" => [
%{
"url" => [%{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}]
}
],
"inReplyTo" => activity.data["id"]
}
)
note_activity = insert(:note_activity, note: note)
object = Object.normalize(note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
conn =
conn
|> put_req_header("content-type", "application/atom+xml")
|> get("/users/#{user.nickname}/feed.atom")
assert response(conn, 200) =~ object.data["content"]
end
test "returns 404 for a missing feed", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/atom+xml")
|> get("/users/nonexisting/feed.atom")
assert response(conn, 404)
end
describe "feed_redirect" do
test "undefined format. it redirects to feed", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> put_req_header("accept", "application/xml")
|> get("/users/#{user.nickname}")
|> response(302)
assert response ==
"<html><body>You are being <a href=\"#{Pleroma.Web.base_url()}/users/#{
user.nickname
}/feed.atom\">redirected</a>.</body></html>"
end
test "undefined format. it returns error when user not found", %{conn: conn} do
response =
conn
|> put_req_header("accept", "application/xml")
|> get("/users/jimm")
|> response(404)
assert response == ~S({"error":"Not found"})
end
test "activity+json format. it redirects on actual feed of user", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}")
|> json_response(200)
assert response["endpoints"] == %{
"oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
"oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
"oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
"sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
"uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
}
assert response["@context"] == [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{"@language" => "und"}
]
assert Map.take(response, [
"followers",
"following",
"id",
"inbox",
"manuallyApprovesFollowers",
"name",
"outbox",
"preferredUsername",
"summary",
"tag",
"type",
"url"
]) == %{
"followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
"following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
"id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
"inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
"manuallyApprovesFollowers" => false,
"name" => user.name,
"outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
"preferredUsername" => user.nickname,
"summary" => user.bio,
"tag" => [],
"type" => "Person",
"url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
}
end
test "activity+json format. it returns error whe use not found", %{conn: conn} do
response =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/jimm")
|> json_response(404)
assert response == "Not found"
end
test "json format. it redirects on actual feed of user", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> put_req_header("accept", "application/json")
|> get("/users/#{user.nickname}")
|> json_response(200)
assert response["endpoints"] == %{
"oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
"oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
"oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
"sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
"uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
}
assert response["@context"] == [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{"@language" => "und"}
]
assert Map.take(response, [
"followers",
"following",
"id",
"inbox",
"manuallyApprovesFollowers",
"name",
"outbox",
"preferredUsername",
"summary",
"tag",
"type",
"url"
]) == %{
"followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
"following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
"id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
"inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
"manuallyApprovesFollowers" => false,
"name" => user.name,
"outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
"preferredUsername" => user.nickname,
"summary" => user.bio,
"tag" => [],
"type" => "Person",
"url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
}
end
test "json format. it returns error whe use not found", %{conn: conn} do
response =
conn
|> put_req_header("accept", "application/json")
|> get("/users/jimm")
|> json_response(404)
assert response == "Not found"
end
test "html format. it redirects on actual feed of user", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> get("/users/#{user.nickname}")
|> response(200)
assert response ==
Fallback.RedirectController.redirector_with_meta(
conn,
%{user: user}
).resp_body
end
test "html format. it returns error when user not found", %{conn: conn} do
response =
conn
|> get("/users/jimm")
|> json_response(404)
assert response == %{"error" => "Not found"}
end
end
end

View file

@ -272,7 +272,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert user_response["pleroma"]["background_image"]
end
test "requires 'write' permission", %{conn: conn} do
test "requires 'write:accounts' permission", %{conn: conn} do
token1 = insert(:oauth_token, scopes: ["read"])
token2 = insert(:oauth_token, scopes: ["write", "follow"])
@ -283,7 +283,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|> patch("/api/v1/accounts/update_credentials", %{})
if token == token1 do
assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403)
assert %{"error" => "Insufficient permissions: write:accounts."} ==
json_response(conn, 403)
else
assert json_response(conn, 200)
end
@ -328,7 +329,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
account =
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"fields" => fields})
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response(200)
assert account["fields"] == [
@ -344,6 +345,35 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
%{"name" => "link", "value" => "cofe.io"}
]
fields =
[
"fields_attributes[1][name]=link",
"fields_attributes[1][value]=cofe.io",
"fields_attributes[0][name]=<a href=\"http://google.com\">foo</a>",
"fields_attributes[0][value]=bar"
]
|> Enum.join("&")
account =
conn
|> put_req_header("content-type", "application/x-www-form-urlencoded")
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", fields)
|> json_response(200)
assert account["fields"] == [
%{"name" => "foo", "value" => "bar"},
%{"name" => "link", "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)}
]
assert account["source"]["fields"] == [
%{
"name" => "<a href=\"http://google.com\">foo</a>",
"value" => "bar"
},
%{"name" => "link", "value" => "cofe.io"}
]
name_limit = Pleroma.Config.get([:instance, :account_field_name_length])
value_limit = Pleroma.Config.get([:instance, :account_field_value_length])
@ -354,7 +384,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert %{"error" => "Invalid request"} ==
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"fields" => fields})
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response(403)
long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join()
@ -364,7 +394,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert %{"error" => "Invalid request"} ==
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"fields" => fields})
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response(403)
Pleroma.Config.put([:instance, :max_account_fields], 1)
@ -377,8 +407,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert %{"error" => "Invalid request"} ==
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"fields" => fields})
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response(403)
fields = [
%{"name" => "foo", "value" => ""},
%{"name" => "", "value" => "bar"}
]
account =
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response(200)
assert account["fields"] == [
%{"name" => "foo", "value" => ""}
]
end
end
end

View file

@ -849,4 +849,34 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert [] = json_response(conn, 200)
end
end
test "getting a list of mutes", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.mute(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/mutes")
other_user_id = to_string(other_user.id)
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
test "getting a list of blocks", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.block(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/blocks")
other_user_id = to_string(other_user.id)
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
end

View file

@ -10,19 +10,23 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
import Pleroma.Factory
test "Conversations", %{conn: conn} do
test "returns a list of conversations", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)
user_three = insert(:user)
{:ok, user_two} = User.follow(user_two, user_one)
assert User.get_cached_by_id(user_two.id).info.unread_conversation_count == 0
{:ok, direct} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
"visibility" => "direct"
})
assert User.get_cached_by_id(user_two.id).info.unread_conversation_count == 1
{:ok, _follower_only} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}!",
@ -52,23 +56,100 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
assert is_binary(res_id)
assert unread == true
assert res_last_status["id"] == direct.id
assert User.get_cached_by_id(user_one.id).info.unread_conversation_count == 1
end
test "updates the last_status on reply", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)
{:ok, direct} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}",
"visibility" => "direct"
})
{:ok, direct_reply} =
CommonAPI.post(user_two, %{
"status" => "reply",
"visibility" => "direct",
"in_reply_to_status_id" => direct.id
})
[%{"last_status" => res_last_status}] =
conn
|> assign(:user, user_one)
|> get("/api/v1/conversations")
|> json_response(200)
assert res_last_status["id"] == direct_reply.id
end
test "the user marks a conversation as read", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)
{:ok, direct} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}",
"visibility" => "direct"
})
[%{"id" => direct_conversation_id, "unread" => true}] =
conn
|> assign(:user, user_one)
|> get("/api/v1/conversations")
|> json_response(200)
%{"unread" => false} =
conn
|> assign(:user, user_one)
|> post("/api/v1/conversations/#{direct_conversation_id}/read")
|> json_response(200)
assert User.get_cached_by_id(user_one.id).info.unread_conversation_count == 0
# The conversation is marked as unread on reply
{:ok, _} =
CommonAPI.post(user_two, %{
"status" => "reply",
"visibility" => "direct",
"in_reply_to_status_id" => direct.id
})
[%{"unread" => true}] =
conn
|> assign(:user, user_one)
|> get("/api/v1/conversations")
|> json_response(200)
assert User.get_cached_by_id(user_one.id).info.unread_conversation_count == 1
# A reply doesn't increment the user's unread_conversation_count if the conversation is unread
{:ok, _} =
CommonAPI.post(user_two, %{
"status" => "reply",
"visibility" => "direct",
"in_reply_to_status_id" => direct.id
})
assert User.get_cached_by_id(user_one.id).info.unread_conversation_count == 1
end
test "(vanilla) Mastodon frontend behaviour", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)
{:ok, direct} =
CommonAPI.post(user_one, %{
"status" => "Hi @#{user_two.nickname}!",
"visibility" => "direct"
})
# Apparently undocumented API endpoint
res_conn =
conn
|> assign(:user, user_one)
|> post("/api/v1/conversations/#{res_id}/read")
assert response = json_response(res_conn, 200)
assert length(response["accounts"]) == 2
assert response["last_status"]["id"] == direct.id
assert response["unread"] == false
# (vanilla) Mastodon frontend behaviour
res_conn =
conn
|> assign(:user, user_one)
|> get("/api/v1/statuses/#{res_last_status["id"]}/context")
|> get("/api/v1/statuses/#{direct.id}/context")
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
end

View file

@ -1242,4 +1242,51 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
"descendants" => [%{"id" => ^id4}, %{"id" => ^id5}]
} = response
end
test "returns the favorites of a user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"})
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"})
{:ok, _, _} = CommonAPI.favorite(activity.id, user)
first_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites")
assert [status] = json_response(first_conn, 200)
assert status["id"] == to_string(activity.id)
assert [{"link", _link_header}] =
Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end)
# Honours query params
{:ok, second_activity} =
CommonAPI.post(other_user, %{
"status" =>
"Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
})
{:ok, _, _} = CommonAPI.favorite(second_activity.id, user)
last_like = status["id"]
second_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites?since_id=#{last_like}")
assert [second_status] = json_response(second_conn, 200)
assert second_status["id"] == to_string(second_activity.id)
third_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites?limit=0")
assert [] = json_response(third_conn, 200)
end
end

View file

@ -7,7 +7,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
@ -20,36 +19,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
clear_config([:rich_media, :enabled])
test "getting a list of mutes", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.mute(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/mutes")
other_user_id = to_string(other_user.id)
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
test "getting a list of blocks", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, user} = User.block(user, other_user)
conn =
conn
|> assign(:user, user)
|> get("/api/v1/blocks")
other_user_id = to_string(other_user.id)
assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
end
test "unimplemented follow_requests, blocks, domain blocks" do
user = insert(:user)
@ -64,53 +33,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end)
end
test "returns the favorites of a user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{"status" => "bla"})
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "traps are happy"})
{:ok, _, _} = CommonAPI.favorite(activity.id, user)
first_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites")
assert [status] = json_response(first_conn, 200)
assert status["id"] == to_string(activity.id)
assert [{"link", _link_header}] =
Enum.filter(first_conn.resp_headers, fn element -> match?({"link", _}, element) end)
# Honours query params
{:ok, second_activity} =
CommonAPI.post(other_user, %{
"status" =>
"Trees Are Never Sad Look At Them Every Once In Awhile They're Quite Beautiful."
})
{:ok, _, _} = CommonAPI.favorite(second_activity.id, user)
last_like = status["id"]
second_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites?since_id=#{last_like}")
assert [second_status] = json_response(second_conn, 200)
assert second_status["id"] == to_string(second_activity.id)
third_conn =
conn
|> assign(:user, user)
|> get("/api/v1/favourites?limit=0")
assert [] = json_response(third_conn, 200)
end
describe "link headers" do
test "preserves parameters in link headers", %{conn: conn} do
user = insert(:user)

View file

@ -418,6 +418,27 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
following_count: 1
} = AccountView.render("show.json", %{user: user, for: user})
end
test "shows unread_conversation_count only to the account owner" do
user = insert(:user)
other_user = insert(:user)
{:ok, _activity} =
CommonAPI.post(user, %{
"status" => "Hey @#{other_user.nickname}.",
"visibility" => "direct"
})
user = User.get_cached_by_ap_id(user.ap_id)
assert AccountView.render("show.json", %{user: user, for: other_user})[:pleroma][
:unread_conversation_count
] == nil
assert AccountView.render("show.json", %{user: user, for: user})[:pleroma][
:unread_conversation_count
] == 1
end
end
describe "follow requests counter" do

View file

@ -100,5 +100,11 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
NotificationView.render("index.json", %{notifications: [notification], for: followed})
assert [expected] == result
User.perform(:delete, follower)
notification = Notification |> Repo.one() |> Repo.preload(:activity)
assert [] ==
NotificationView.render("index.json", %{notifications: [notification], for: followed})
end
end

View file

@ -0,0 +1,18 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Metadata.Providers.FeedTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.Metadata.Providers.Feed
test "it renders a link to user's atom feed" do
user = insert(:user, nickname: "lain")
assert Feed.build_tags(%{user: user}) == [
{:link,
[rel: "alternate", type: "application/atom+xml", href: "/users/lain/feed.atom"], []}
]
end
end

View file

@ -557,7 +557,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => redirect_uri,
"scope" => "read write",
"scope" => "read:subscope write",
"state" => "statepassed"
}
})
@ -570,7 +570,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
assert %{"state" => "statepassed", "code" => code} = query
auth = Repo.get_by(Authorization, token: code)
assert auth
assert auth.scopes == ["read", "write"]
assert auth.scopes == ["read:subscope", "write"]
end
test "returns 401 for wrong credentials", %{conn: conn} do
@ -627,7 +627,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
assert result =~ "This action is outside the authorized scopes"
end
test "returns 401 for scopes beyond app scopes", %{conn: conn} do
test "returns 401 for scopes beyond app scopes hierarchy", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write"])
redirect_uri = OAuthController.default_redirect_uri(app)

View file

@ -72,28 +72,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
end
end
test "gets a feed", %{conn: conn} do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
conn =
conn
|> put_req_header("content-type", "application/atom+xml")
|> get("/users/#{user.nickname}/feed.atom")
assert response(conn, 200) =~ object.data["content"]
end
test "returns 404 for a missing feed", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/atom+xml")
|> get("/users/nonexisting/feed.atom")
assert response(conn, 404)
end
describe "GET object/2" do
test "gets an object", %{conn: conn} do
note_activity = insert(:note_activity)
@ -355,185 +333,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
end
end
describe "feed_redirect" do
test "undefined format. it redirects to feed", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> put_req_header("accept", "application/xml")
|> get("/users/#{user.nickname}")
|> response(302)
assert response ==
"<html><body>You are being <a href=\"#{Pleroma.Web.base_url()}/users/#{
user.nickname
}/feed.atom\">redirected</a>.</body></html>"
end
test "undefined format. it returns error when user not found", %{conn: conn} do
response =
conn
|> put_req_header("accept", "application/xml")
|> get("/users/jimm")
|> response(404)
assert response == ~S({"error":"Not found"})
end
test "activity+json format. it redirects on actual feed of user", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}")
|> json_response(200)
assert response["endpoints"] == %{
"oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
"oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
"oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
"sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
"uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
}
assert response["@context"] == [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{"@language" => "und"}
]
assert Map.take(response, [
"followers",
"following",
"id",
"inbox",
"manuallyApprovesFollowers",
"name",
"outbox",
"preferredUsername",
"summary",
"tag",
"type",
"url"
]) == %{
"followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
"following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
"id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
"inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
"manuallyApprovesFollowers" => false,
"name" => user.name,
"outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
"preferredUsername" => user.nickname,
"summary" => user.bio,
"tag" => [],
"type" => "Person",
"url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
}
end
test "activity+json format. it returns error whe use not found", %{conn: conn} do
response =
conn
|> put_req_header("accept", "application/activity+json")
|> get("/users/jimm")
|> json_response(404)
assert response == "Not found"
end
test "json format. it redirects on actual feed of user", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> put_req_header("accept", "application/json")
|> get("/users/#{user.nickname}")
|> json_response(200)
assert response["endpoints"] == %{
"oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize",
"oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps",
"oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token",
"sharedInbox" => "#{Pleroma.Web.base_url()}/inbox",
"uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media"
}
assert response["@context"] == [
"https://www.w3.org/ns/activitystreams",
"http://localhost:4001/schemas/litepub-0.1.jsonld",
%{"@language" => "und"}
]
assert Map.take(response, [
"followers",
"following",
"id",
"inbox",
"manuallyApprovesFollowers",
"name",
"outbox",
"preferredUsername",
"summary",
"tag",
"type",
"url"
]) == %{
"followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers",
"following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following",
"id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}",
"inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox",
"manuallyApprovesFollowers" => false,
"name" => user.name,
"outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox",
"preferredUsername" => user.nickname,
"summary" => user.bio,
"tag" => [],
"type" => "Person",
"url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}"
}
end
test "json format. it returns error whe use not found", %{conn: conn} do
response =
conn
|> put_req_header("accept", "application/json")
|> get("/users/jimm")
|> json_response(404)
assert response == "Not found"
end
test "html format. it redirects on actual feed of user", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
response =
conn
|> get("/users/#{user.nickname}")
|> response(200)
assert response ==
Fallback.RedirectController.redirector_with_meta(
conn,
%{user: user}
).resp_body
end
test "html format. it returns error when user not found", %{conn: conn} do
response =
conn
|> get("/users/jimm")
|> json_response(404)
assert response == %{"error" => "Not found"}
end
end
describe "GET /notice/:id/embed_player" do
test "render embed player", %{conn: conn} do
note_activity = insert(:note_activity)

View file

@ -8,6 +8,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
alias Pleroma.Conversation.Participation
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
@ -73,6 +74,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
participation = Repo.preload(participation, :recipients)
user = User.get_cached_by_id(user.id)
assert [user] == participation.recipients
assert other_user not in participation.recipients

View file

@ -233,30 +233,68 @@ defmodule Pleroma.Web.StreamerTest do
end
end
test "it doesn't send to blocked users" do
user = insert(:user)
blocked_user = insert(:user)
{:ok, user} = User.block(user, blocked_user)
describe "blocks" do
test "it doesn't send messages involving blocked users" do
user = insert(:user)
blocked_user = insert(:user)
{:ok, user} = User.block(user, blocked_user)
task =
Task.async(fn ->
refute_receive {:text, _}, 1_000
end)
task =
Task.async(fn ->
refute_receive {:text, _}, 1_000
end)
fake_socket = %StreamerSocket{
transport_pid: task.pid,
user: user
}
fake_socket = %StreamerSocket{
transport_pid: task.pid,
user: user
}
{:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
{:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"})
topics = %{
"public" => [fake_socket]
}
topics = %{
"public" => [fake_socket]
}
Worker.push_to_socket(topics, "public", activity)
Worker.push_to_socket(topics, "public", activity)
Task.await(task)
Task.await(task)
end
test "it doesn't send messages transitively involving blocked users" do
blocker = insert(:user)
blockee = insert(:user)
friend = insert(:user)
task =
Task.async(fn ->
refute_receive {:text, _}, 1_000
end)
fake_socket = %StreamerSocket{
transport_pid: task.pid,
user: blocker
}
topics = %{
"public" => [fake_socket]
}
{:ok, blocker} = User.block(blocker, blockee)
{:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey! @#{blockee.nickname}"})
Worker.push_to_socket(topics, "public", activity_one)
{:ok, activity_two} = CommonAPI.post(blockee, %{"status" => "hey! @#{friend.nickname}"})
Worker.push_to_socket(topics, "public", activity_two)
{:ok, activity_three} = CommonAPI.post(blockee, %{"status" => "hey! @#{blocker.nickname}"})
Worker.push_to_socket(topics, "public", activity_three)
Task.await(task)
end
end
test "it doesn't send unwanted DMs to list" do

View file

@ -81,19 +81,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
assert response == "job started"
end
test "requires 'follow' permission", %{conn: conn} do
test "requires 'follow' or 'write:follows' permissions", %{conn: conn} do
token1 = insert(:oauth_token, scopes: ["read", "write"])
token2 = insert(:oauth_token, scopes: ["follow"])
token3 = insert(:oauth_token, scopes: ["something"])
another_user = insert(:user)
for token <- [token1, token2] do
for token <- [token1, token2, token3] do
conn =
conn
|> put_req_header("authorization", "Bearer #{token.token}")
|> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
if token == token1 do
assert %{"error" => "Insufficient permissions: follow."} == json_response(conn, 403)
if token == token3 do
assert %{"error" => "Insufficient permissions: follow | write:follows."} ==
json_response(conn, 403)
else
assert json_response(conn, 200)
end