Merge branch 'develop' into remove-twitter-api

This commit is contained in:
Egor Kislitsyn 2020-06-29 16:09:49 +04:00
commit 4a306720e8
No known key found for this signature in database
GPG key ID: 1B49CB15B71E7805
1023 changed files with 24510 additions and 11967 deletions

View file

@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
use Pleroma.Web.ConnCase
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Delivery
@ -14,13 +13,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.Relay
alias Pleroma.Web.ActivityPub.UserView
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Endpoint
alias Pleroma.Workers.ReceiverWorker
import Pleroma.Factory
require Pleroma.Constants
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
@ -168,6 +173,60 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
end
describe "mastodon compatibility routes" do
test "it returns a json representation of the object with accept application/json", %{
conn: conn
} do
{:ok, object} =
%{
"type" => "Note",
"content" => "hey",
"id" => Endpoint.url() <> "/users/raymoo/statuses/999999999",
"actor" => Endpoint.url() <> "/users/raymoo",
"to" => [Pleroma.Constants.as_public()]
}
|> Object.create()
conn =
conn
|> put_req_header("accept", "application/json")
|> get("/users/raymoo/statuses/999999999")
assert json_response(conn, 200) == ObjectView.render("object.json", %{object: object})
end
test "it returns a json representation of the activity with accept application/json", %{
conn: conn
} do
{:ok, object} =
%{
"type" => "Note",
"content" => "hey",
"id" => Endpoint.url() <> "/users/raymoo/statuses/999999999",
"actor" => Endpoint.url() <> "/users/raymoo",
"to" => [Pleroma.Constants.as_public()]
}
|> Object.create()
{:ok, activity, _} =
%{
"id" => object.data["id"] <> "/activity",
"type" => "Create",
"object" => object.data["id"],
"actor" => object.data["actor"],
"to" => object.data["to"]
}
|> ActivityPub.persist(local: true)
conn =
conn
|> put_req_header("accept", "application/json")
|> get("/users/raymoo/statuses/999999999/activity")
assert json_response(conn, 200) == ObjectView.render("object.json", %{object: activity})
end
end
describe "/objects/:uuid" do
test "it returns a json representation of the object with accept application/json", %{
conn: conn
@ -392,6 +451,36 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert Activity.get_by_ap_id(data["id"])
end
@tag capture_log: true
test "it inserts an incoming activity into the database" <>
"even if we can't fetch the user but have it in our db",
%{conn: conn} do
user =
insert(:user,
ap_id: "https://mastodon.example.org/users/raymoo",
ap_enabled: true,
local: false,
last_refreshed_at: nil
)
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("actor", user.ap_id)
|> put_in(["object", "attridbutedTo"], user.ap_id)
conn =
conn
|> assign(:valid_signature, true)
|> put_req_header("content-type", "application/activity+json")
|> post("/inbox", data)
assert "ok" == json_response(conn, 200)
ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
assert Activity.get_by_ap_id(data["id"])
end
test "it clears `unreachable` federation status of the sender", %{conn: conn} do
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
@ -447,6 +536,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert_receive {:mix_shell, :info, ["relay.mastodon.host"]}
end
@tag capture_log: true
test "without valid signature, " <>
"it only accepts Create activities and requires enabled federation",
%{conn: conn} do
@ -559,11 +649,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
test "it accepts announces with to as string instead of array", %{conn: conn} do
user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "hey"})
announcer = insert(:user, local: false)
data = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"actor" => "http://mastodon.example.org/users/admin",
"id" => "http://mastodon.example.org/users/admin/statuses/19512778738411822/activity",
"object" => "https://mastodon.social/users/emelie/statuses/101849165031453009",
"actor" => announcer.ap_id,
"id" => "#{announcer.ap_id}/statuses/19512778738411822/activity",
"object" => post.data["object"],
"to" => "https://www.w3.org/ns/activitystreams#Public",
"cc" => [user.ap_id],
"type" => "Announce"
@ -715,17 +808,63 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
describe "GET /users/:nickname/outbox" do
test "it paginates correctly", %{conn: conn} do
user = insert(:user)
conn = assign(conn, :user, user)
outbox_endpoint = user.ap_id <> "/outbox"
_posts =
for i <- 0..25 do
{:ok, activity} = CommonAPI.post(user, %{status: "post #{i}"})
activity
end
result =
conn
|> put_req_header("accept", "application/activity+json")
|> get(outbox_endpoint <> "?page=true")
|> json_response(200)
result_ids = Enum.map(result["orderedItems"], fn x -> x["id"] end)
assert length(result["orderedItems"]) == 20
assert length(result_ids) == 20
assert result["next"]
assert String.starts_with?(result["next"], outbox_endpoint)
result_next =
conn
|> put_req_header("accept", "application/activity+json")
|> get(result["next"])
|> json_response(200)
result_next_ids = Enum.map(result_next["orderedItems"], fn x -> x["id"] end)
assert length(result_next["orderedItems"]) == 6
assert length(result_next_ids) == 6
refute Enum.find(result_next_ids, fn x -> x in result_ids end)
refute Enum.find(result_ids, fn x -> x in result_next_ids end)
assert String.starts_with?(result["id"], outbox_endpoint)
result_next_again =
conn
|> put_req_header("accept", "application/activity+json")
|> get(result_next["id"])
|> json_response(200)
assert result_next == result_next_again
end
test "it returns 200 even if there're no activities", %{conn: conn} do
user = insert(:user)
outbox_endpoint = user.ap_id <> "/outbox"
conn =
conn
|> assign(:user, user)
|> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}/outbox")
|> get(outbox_endpoint)
result = json_response(conn, 200)
assert user.ap_id <> "/outbox" == result["id"]
assert outbox_endpoint == result["id"]
end
test "it returns a note activity in a collection", %{conn: conn} do

View file

@ -82,30 +82,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, private_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
activities =
ActivityPub.fetch_activities([], %{:visibility => "direct", "actor_id" => user.ap_id})
activities = ActivityPub.fetch_activities([], %{visibility: "direct", actor_id: user.ap_id})
assert activities == [direct_activity]
activities =
ActivityPub.fetch_activities([], %{:visibility => "unlisted", "actor_id" => user.ap_id})
ActivityPub.fetch_activities([], %{visibility: "unlisted", actor_id: user.ap_id})
assert activities == [unlisted_activity]
activities =
ActivityPub.fetch_activities([], %{:visibility => "private", "actor_id" => user.ap_id})
ActivityPub.fetch_activities([], %{visibility: "private", actor_id: user.ap_id})
assert activities == [private_activity]
activities =
ActivityPub.fetch_activities([], %{:visibility => "public", "actor_id" => user.ap_id})
activities = ActivityPub.fetch_activities([], %{visibility: "public", actor_id: user.ap_id})
assert activities == [public_activity]
activities =
ActivityPub.fetch_activities([], %{
:visibility => ~w[private public],
"actor_id" => user.ap_id
visibility: ~w[private public],
actor_id: user.ap_id
})
assert activities == [public_activity, private_activity]
@ -126,8 +124,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities =
ActivityPub.fetch_activities([], %{
"exclude_visibilities" => "direct",
"actor_id" => user.ap_id
exclude_visibilities: "direct",
actor_id: user.ap_id
})
assert public_activity in activities
@ -137,8 +135,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities =
ActivityPub.fetch_activities([], %{
"exclude_visibilities" => "unlisted",
"actor_id" => user.ap_id
exclude_visibilities: "unlisted",
actor_id: user.ap_id
})
assert public_activity in activities
@ -148,8 +146,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities =
ActivityPub.fetch_activities([], %{
"exclude_visibilities" => "private",
"actor_id" => user.ap_id
exclude_visibilities: "private",
actor_id: user.ap_id
})
assert public_activity in activities
@ -159,8 +157,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activities =
ActivityPub.fetch_activities([], %{
"exclude_visibilities" => "public",
"actor_id" => user.ap_id
exclude_visibilities: "public",
actor_id: user.ap_id
})
refute public_activity in activities
@ -193,23 +191,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, status_two} = CommonAPI.post(user, %{status: ". #essais"})
{:ok, status_three} = CommonAPI.post(user, %{status: ". #test #reject"})
fetch_one = ActivityPub.fetch_activities([], %{"type" => "Create", "tag" => "test"})
fetch_one = ActivityPub.fetch_activities([], %{type: "Create", tag: "test"})
fetch_two =
ActivityPub.fetch_activities([], %{"type" => "Create", "tag" => ["test", "essais"]})
fetch_two = ActivityPub.fetch_activities([], %{type: "Create", tag: ["test", "essais"]})
fetch_three =
ActivityPub.fetch_activities([], %{
"type" => "Create",
"tag" => ["test", "essais"],
"tag_reject" => ["reject"]
type: "Create",
tag: ["test", "essais"],
tag_reject: ["reject"]
})
fetch_four =
ActivityPub.fetch_activities([], %{
"type" => "Create",
"tag" => ["test"],
"tag_all" => ["test", "reject"]
type: "Create",
tag: ["test"],
tag_all: ["test", "reject"]
})
assert fetch_one == [status_one, status_three]
@ -375,7 +372,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
_listen_activity_2 = insert(:listen)
_listen_activity_3 = insert(:listen)
timeline = ActivityPub.fetch_activities([], %{"type" => ["Listen"]})
timeline = ActivityPub.fetch_activities([], %{type: ["Listen"]})
assert length(timeline) == 3
end
@ -507,7 +504,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _user_relationship} = User.block(user, %{ap_id: activity_five.data["actor"]})
activities = ActivityPub.fetch_activities_for_context("2hu", %{"blocking_user" => user})
activities = ActivityPub.fetch_activities_for_context("2hu", %{blocking_user: user})
assert activities == [activity_two, activity]
end
end
@ -520,8 +517,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
booster = insert(:user)
{:ok, _user_relationship} = User.block(user, %{ap_id: activity_one.data["actor"]})
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@ -529,28 +525,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _user_block} = User.unblock(user, %{ap_id: activity_one.data["actor"]})
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
assert Enum.member?(activities, activity_one)
{:ok, _user_relationship} = User.block(user, %{ap_id: activity_three.data["actor"]})
{:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
{:ok, %{data: %{"object" => id}}} = CommonAPI.repeat(activity_three.id, booster)
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Activity.get_by_id(activity_three.id)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
assert Enum.member?(activities, activity_two)
refute Enum.member?(activities, activity_three)
refute Enum.member?(activities, boost_activity)
assert Enum.member?(activities, activity_one)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => nil, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: nil, skip_preload: true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@ -573,7 +566,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, activity_four} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
activities = ActivityPub.fetch_activities([], %{"blocking_user" => blocker})
activities = ActivityPub.fetch_activities([], %{blocking_user: blocker})
assert Enum.member?(activities, activity_one)
refute Enum.member?(activities, activity_two)
@ -581,7 +574,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute Enum.member?(activities, activity_four)
end
test "doesn't return announce activities concerning blocked users" do
test "doesn't return announce activities with blocked users in 'to'" do
blocker = insert(:user)
blockee = insert(:user)
friend = insert(:user)
@ -592,10 +585,43 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
{:ok, activity_three, _} = CommonAPI.repeat(activity_two.id, friend)
{:ok, activity_three} = CommonAPI.repeat(activity_two.id, friend)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => blocker})
ActivityPub.fetch_activities([], %{blocking_user: blocker})
|> Enum.map(fn act -> act.id end)
assert Enum.member?(activities, activity_one.id)
refute Enum.member?(activities, activity_two.id)
refute Enum.member?(activities, activity_three.id)
end
test "doesn't return announce activities with blocked users in 'cc'" do
blocker = insert(:user)
blockee = insert(:user)
friend = insert(:user)
{:ok, _user_relationship} = User.block(blocker, blockee)
{:ok, activity_one} = CommonAPI.post(friend, %{status: "hey!"})
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
assert object = Pleroma.Object.normalize(activity_two)
data = %{
"actor" => friend.ap_id,
"object" => object.data["id"],
"context" => object.data["context"],
"type" => "Announce",
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [blockee.ap_id]
}
assert {:ok, activity_three} = ActivityPub.insert(data)
activities =
ActivityPub.fetch_activities([], %{blocking_user: blocker})
|> Enum.map(fn act -> act.id end)
assert Enum.member?(activities, activity_one.id)
@ -611,17 +637,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
user = insert(:user)
{:ok, user} = User.block_domain(user, domain)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
refute activity in activities
followed_user = insert(:user)
ActivityPub.follow(user, followed_user)
{:ok, repeat_activity, _} = CommonAPI.repeat(activity.id, followed_user)
{:ok, repeat_activity} = CommonAPI.repeat(activity.id, followed_user)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: user, skip_preload: true})
refute repeat_activity in activities
end
@ -641,8 +665,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
activity = insert(:note_activity, %{note: note})
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: blocker, skip_preload: true})
assert activity in activities
@ -651,10 +674,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
another_user = insert(:user, %{ap_id: "https://#{domain}/@meanie2"})
bad_note = insert(:note, %{data: %{"actor" => another_user.ap_id}})
bad_activity = insert(:note_activity, %{note: bad_note})
{:ok, repeat_activity, _} = CommonAPI.repeat(bad_activity.id, domain_user)
{:ok, repeat_activity} = CommonAPI.repeat(bad_activity.id, domain_user)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{blocking_user: blocker, skip_preload: true})
refute repeat_activity in activities
end
@ -669,8 +691,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activity_one_actor = User.get_by_ap_id(activity_one.data["actor"])
{:ok, _user_relationships} = User.mute(user, activity_one_actor)
activities =
ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{muting_user: user, skip_preload: true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@ -679,9 +700,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
# Calling with 'with_muted' will deliver muted activities, too.
activities =
ActivityPub.fetch_activities([], %{
"muting_user" => user,
"with_muted" => true,
"skip_preload" => true
muting_user: user,
with_muted: true,
skip_preload: true
})
assert Enum.member?(activities, activity_two)
@ -690,8 +711,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _user_mute} = User.unmute(user, activity_one_actor)
activities =
ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{muting_user: user, skip_preload: true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@ -699,19 +719,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activity_three_actor = User.get_by_ap_id(activity_three.data["actor"])
{:ok, _user_relationships} = User.mute(user, activity_three_actor)
{:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
{:ok, %{data: %{"object" => id}}} = CommonAPI.repeat(activity_three.id, booster)
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Activity.get_by_id(activity_three.id)
activities =
ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{muting_user: user, skip_preload: true})
assert Enum.member?(activities, activity_two)
refute Enum.member?(activities, activity_three)
refute Enum.member?(activities, boost_activity)
assert Enum.member?(activities, activity_one)
activities = ActivityPub.fetch_activities([], %{"muting_user" => nil, "skip_preload" => true})
activities = ActivityPub.fetch_activities([], %{muting_user: nil, skip_preload: true})
assert Enum.member?(activities, activity_two)
assert Enum.member?(activities, activity_three)
@ -727,7 +746,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
assert [_activity_one] = ActivityPub.fetch_activities([], %{"muting_user" => user})
assert [_activity_one] = ActivityPub.fetch_activities([], %{muting_user: user})
end
test "returns thread muted activities when with_muted is set" do
@ -739,7 +758,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _activity_two} = CommonAPI.add_mute(user, activity_two)
assert [_activity_two, _activity_one] =
ActivityPub.fetch_activities([], %{"muting_user" => user, "with_muted" => true})
ActivityPub.fetch_activities([], %{muting_user: user, with_muted: true})
end
test "does include announces on request" do
@ -749,7 +768,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = User.follow(user, booster)
{:ok, announce, _object} = CommonAPI.repeat(activity_three.id, booster)
{:ok, announce} = CommonAPI.repeat(activity_three.id, booster)
[announce_activity] = ActivityPub.fetch_activities([user.ap_id | User.following(user)])
@ -761,7 +780,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, expected_activity} = ActivityBuilder.insert(%{"type" => "Create"}, %{:user => user})
{:ok, _} = ActivityBuilder.insert(%{"type" => "Announce"}, %{:user => user})
[activity] = ActivityPub.fetch_user_activities(user, nil, %{"exclude_reblogs" => "true"})
[activity] = ActivityPub.fetch_user_activities(user, nil, %{exclude_reblogs: true})
assert activity == expected_activity
end
@ -804,7 +823,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
expected_activities = ActivityBuilder.insert_list(10)
since_id = List.last(activities).id
activities = ActivityPub.fetch_public_activities(%{"since_id" => since_id})
activities = ActivityPub.fetch_public_activities(%{since_id: since_id})
assert collect_ids(activities) == collect_ids(expected_activities)
assert length(activities) == 10
@ -819,7 +838,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|> ActivityBuilder.insert_list()
|> List.first()
activities = ActivityPub.fetch_public_activities(%{"max_id" => max_id})
activities = ActivityPub.fetch_public_activities(%{max_id: max_id})
assert length(activities) == 20
assert collect_ids(activities) == collect_ids(expected_activities)
@ -831,8 +850,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
later_activities = ActivityBuilder.insert_list(10)
activities =
ActivityPub.fetch_public_activities(%{"page" => "2", "page_size" => "20"}, :offset)
activities = ActivityPub.fetch_public_activities(%{page: "2", page_size: "20"}, :offset)
assert length(activities) == 20
@ -846,9 +864,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
booster = insert(:user)
{:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
{:ok, activity, _} = CommonAPI.repeat(activity.id, booster)
{:ok, activity} = CommonAPI.repeat(activity.id, booster)
activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
activities = ActivityPub.fetch_activities([], %{muting_user: user})
refute Enum.any?(activities, fn %{id: id} -> id == activity.id end)
end
@ -860,83 +878,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster)
{:ok, _reblog_mute} = CommonAPI.show_reblogs(user, booster)
{:ok, activity, _} = CommonAPI.repeat(activity.id, booster)
{:ok, activity} = CommonAPI.repeat(activity.id, booster)
activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
activities = ActivityPub.fetch_activities([], %{muting_user: user})
assert Enum.any?(activities, fn %{id: id} -> id == activity.id end)
end
end
describe "announcing an object" do
test "adds an announce activity to the db" do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
user = insert(:user)
{:ok, announce_activity, object} = ActivityPub.announce(user, object)
assert object.data["announcement_count"] == 1
assert object.data["announcements"] == [user.ap_id]
assert announce_activity.data["to"] == [
User.ap_followers(user),
note_activity.data["actor"]
]
assert announce_activity.data["object"] == object.data["id"]
assert announce_activity.data["actor"] == user.ap_id
assert announce_activity.data["context"] == object.data["context"]
end
test "reverts annouce from object on error" do
note_activity = insert(:note_activity)
object = Object.normalize(note_activity)
user = insert(:user)
with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
assert {:error, :reverted} = ActivityPub.announce(user, object)
end
reloaded_object = Object.get_by_ap_id(object.data["id"])
assert reloaded_object == object
refute reloaded_object.data["announcement_count"]
refute reloaded_object.data["announcements"]
end
end
describe "announcing a private object" do
test "adds an announce activity to the db if the audience is not widened" do
user = insert(:user)
{:ok, note_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
object = Object.normalize(note_activity)
{:ok, announce_activity, object} = ActivityPub.announce(user, object, nil, true, false)
assert announce_activity.data["to"] == [User.ap_followers(user)]
assert announce_activity.data["object"] == object.data["id"]
assert announce_activity.data["actor"] == user.ap_id
assert announce_activity.data["context"] == object.data["context"]
end
test "does not add an announce activity to the db if the audience is widened" do
user = insert(:user)
{:ok, note_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
object = Object.normalize(note_activity)
assert {:error, _} = ActivityPub.announce(user, object, nil, true, true)
end
test "does not add an announce activity to the db if the announcer is not the author" do
user = insert(:user)
announcer = insert(:user)
{:ok, note_activity} = CommonAPI.post(user, %{status: ".", visibility: "private"})
object = Object.normalize(note_activity)
assert {:error, _} = ActivityPub.announce(announcer, object, nil, true, false)
end
end
describe "uploading files" do
test "copies the file to the configured folder" do
file = %Plug.Upload{
@ -1043,54 +992,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
describe "blocking" do
test "reverts block activity on error" do
[blocker, blocked] = insert_list(2, :user)
with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
assert {:error, :reverted} = ActivityPub.block(blocker, blocked)
end
assert Repo.aggregate(Activity, :count, :id) == 0
assert Repo.aggregate(Object, :count, :id) == 0
end
test "creates a block activity" do
clear_config([:instance, :federating], true)
blocker = insert(:user)
blocked = insert(:user)
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
{:ok, activity} = ActivityPub.block(blocker, blocked)
assert activity.data["type"] == "Block"
assert activity.data["actor"] == blocker.ap_id
assert activity.data["object"] == blocked.ap_id
assert called(Pleroma.Web.Federator.publish(activity))
end
end
test "works with outgoing blocks disabled, but doesn't federate" do
clear_config([:instance, :federating], true)
clear_config([:activitypub, :outgoing_blocks], false)
blocker = insert(:user)
blocked = insert(:user)
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
{:ok, activity} = ActivityPub.block(blocker, blocked)
assert activity.data["type"] == "Block"
assert activity.data["actor"] == blocker.ap_id
assert activity.data["object"] == blocked.ap_id
refute called(Pleroma.Web.Federator.publish(:_))
end
end
end
describe "timeline post-processing" do
test "it filters broken threads" do
user1 = insert(:user)
@ -1135,7 +1036,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert length(activities) == 3
activities =
ActivityPub.fetch_activities([user1.ap_id | User.following(user1)], %{"user" => user1})
ActivityPub.fetch_activities([user1.ap_id | User.following(user1)], %{user: user1})
|> Enum.map(fn a -> a.id end)
assert [public_activity.id, private_activity_1.id] == activities
@ -1143,52 +1044,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
describe "update" do
setup do: clear_config([:instance, :max_pinned_statuses])
test "it creates an update activity with the new user data" do
user = insert(:user)
{:ok, user} = User.ensure_keys_present(user)
user_data = Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})
{:ok, update} =
ActivityPub.update(%{
actor: user_data["id"],
to: [user.follower_address],
cc: [],
object: user_data
})
assert update.data["actor"] == user.ap_id
assert update.data["to"] == [user.follower_address]
assert embedded_object = update.data["object"]
assert embedded_object["id"] == user_data["id"]
assert embedded_object["type"] == user_data["type"]
end
end
test "returned pinned statuses" do
Config.put([:instance, :max_pinned_statuses], 3)
user = insert(:user)
{:ok, activity_one} = CommonAPI.post(user, %{status: "HI!!!"})
{:ok, activity_two} = CommonAPI.post(user, %{status: "HI!!!"})
{:ok, activity_three} = CommonAPI.post(user, %{status: "HI!!!"})
CommonAPI.pin(activity_one.id, user)
user = refresh_record(user)
CommonAPI.pin(activity_two.id, user)
user = refresh_record(user)
CommonAPI.pin(activity_three.id, user)
user = refresh_record(user)
activities = ActivityPub.fetch_user_activities(user, nil, %{"pinned" => "true"})
assert 3 = length(activities)
end
describe "flag/1" do
setup do
reporter = insert(:user)
@ -1295,7 +1150,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
activity = Repo.preload(activity, :bookmark)
activity = %Activity{activity | thread_muted?: !!activity.thread_muted?}
assert ActivityPub.fetch_activities([], %{"user" => user}) == [activity]
assert ActivityPub.fetch_activities([], %{user: user}) == [activity]
end
def data_uri do
@ -1469,7 +1324,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert Enum.map(result, & &1.id) == [a1.id, a5.id, a3.id, a4.id]
result = ActivityPub.fetch_favourites(user, %{"limit" => 2})
result = ActivityPub.fetch_favourites(user, %{limit: 2})
assert Enum.map(result, & &1.id) == [a1.id, a5.id]
end
end
@ -1539,7 +1394,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, _reply} = CommonAPI.post(user, %{status: "yeah", in_reply_to_status_id: activity.id})
[result] = ActivityPub.fetch_public_activities(%{"exclude_replies" => "true"})
[result] = ActivityPub.fetch_public_activities(%{exclude_replies: true})
assert result.id == activity.id
@ -1552,11 +1407,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "public timeline", %{users: %{u1: user}} do
activities_ids =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", false)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:reply_filtering_user, user)
|> ActivityPub.fetch_public_activities()
|> Enum.map(& &1.id)
@ -1573,12 +1428,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
} do
activities_ids =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", false)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("reply_visibility", "following")
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:reply_visibility, "following")
|> Map.put(:reply_filtering_user, user)
|> ActivityPub.fetch_public_activities()
|> Enum.map(& &1.id)
@ -1600,12 +1455,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
} do
activities_ids =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", false)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("reply_visibility", "self")
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:reply_visibility, "self")
|> Map.put(:reply_filtering_user, user)
|> ActivityPub.fetch_public_activities()
|> Enum.map(& &1.id)
@ -1624,11 +1479,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
} do
params =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
|> Map.put(:reply_filtering_user, user)
activities_ids =
ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
@ -1662,12 +1517,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
} do
params =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put("reply_visibility", "following")
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
|> Map.put(:reply_visibility, "following")
|> Map.put(:reply_filtering_user, user)
activities_ids =
ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
@ -1701,12 +1556,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
} do
params =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put("reply_visibility", "self")
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
|> Map.put(:reply_visibility, "self")
|> Map.put(:reply_filtering_user, user)
activities_ids =
ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
@ -1727,6 +1582,40 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert Enum.all?(visible_ids, &(&1 in activities_ids))
end
test "filtering out announces where the user is the actor of the announced message" do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
User.follow(user, other_user)
{:ok, post} = CommonAPI.post(user, %{status: "yo"})
{:ok, other_post} = CommonAPI.post(third_user, %{status: "yo"})
{:ok, _announce} = CommonAPI.repeat(post.id, other_user)
{:ok, _announce} = CommonAPI.repeat(post.id, third_user)
{:ok, announce} = CommonAPI.repeat(other_post.id, other_user)
params = %{
type: ["Announce"]
}
results =
[user.ap_id | User.following(user)]
|> ActivityPub.fetch_activities(params)
assert length(results) == 3
params = %{
type: ["Announce"],
announce_filtering_user: user
}
[result] =
[user.ap_id | User.following(user)]
|> ActivityPub.fetch_activities(params)
assert result.id == announce.id
end
end
describe "replies filtering with private messages" do
@ -1735,11 +1624,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "public timeline", %{users: %{u1: user}} do
activities_ids =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", false)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
|> ActivityPub.fetch_public_activities()
|> Enum.map(& &1.id)
@ -1749,13 +1638,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "public timeline with default reply_visibility `following`", %{users: %{u1: user}} do
activities_ids =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", false)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("reply_visibility", "following")
|> Map.put("reply_filtering_user", user)
|> Map.put("user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:reply_visibility, "following")
|> Map.put(:reply_filtering_user, user)
|> Map.put(:user, user)
|> ActivityPub.fetch_public_activities()
|> Enum.map(& &1.id)
@ -1765,13 +1654,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "public timeline with default reply_visibility `self`", %{users: %{u1: user}} do
activities_ids =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("local_only", false)
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("reply_visibility", "self")
|> Map.put("reply_filtering_user", user)
|> Map.put("user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:reply_visibility, "self")
|> Map.put(:reply_filtering_user, user)
|> Map.put(:user, user)
|> ActivityPub.fetch_public_activities()
|> Enum.map(& &1.id)
@ -1781,10 +1670,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "home timeline", %{users: %{u1: user}} do
params =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
activities_ids =
ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
@ -1796,12 +1685,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
test "home timeline with default reply_visibility `following`", %{users: %{u1: user}} do
params =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put("reply_visibility", "following")
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
|> Map.put(:reply_visibility, "following")
|> Map.put(:reply_filtering_user, user)
activities_ids =
ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
@ -1820,12 +1709,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
} do
params =
%{}
|> Map.put("type", ["Create", "Announce"])
|> Map.put("blocking_user", user)
|> Map.put("muting_user", user)
|> Map.put("user", user)
|> Map.put("reply_visibility", "self")
|> Map.put("reply_filtering_user", user)
|> Map.put(:type, ["Create", "Announce"])
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:user, user)
|> Map.put(:reply_visibility, "self")
|> Map.put(:reply_filtering_user, user)
activities_ids =
ActivityPub.fetch_activities([user.ap_id | User.following(user)], params)
@ -2070,4 +1959,20 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end) =~ "Follower/Following counter update for #{user.ap_id} failed"
end
end
describe "global activity expiration" do
setup do: clear_config([:mrf, :policies])
test "creates an activity expiration for local Create activities" do
Pleroma.Config.put(
[:mrf, :policies],
Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
)
{:ok, %{id: id_create}} = ActivityBuilder.insert(%{"type" => "Create", "context" => "3hu"})
{:ok, _follow} = ActivityBuilder.insert(%{"type" => "Follow", "context" => "3hu"})
assert [%{activity_id: ^id_create}] = Pleroma.ActivityExpiration |> Repo.all()
end
end
end

View file

@ -0,0 +1,77 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicyTest do
use ExUnit.Case, async: true
alias Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy
@id Pleroma.Web.Endpoint.url() <> "/activities/cofe"
test "adds `expires_at` property" do
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
"type" => "Create",
"object" => %{"type" => "Note"}
})
assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
end
test "keeps existing `expires_at` if it less than the config setting" do
expires_at = NaiveDateTime.utc_now() |> Timex.shift(days: 1)
assert {:ok, %{"type" => "Create", "expires_at" => ^expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
"type" => "Create",
"expires_at" => expires_at,
"object" => %{"type" => "Note"}
})
end
test "overwrites existing `expires_at` if it greater than the config setting" do
too_distant_future = NaiveDateTime.utc_now() |> Timex.shift(years: 2)
assert {:ok, %{"type" => "Create", "expires_at" => expires_at}} =
ActivityExpirationPolicy.filter(%{
"id" => @id,
"type" => "Create",
"expires_at" => too_distant_future,
"object" => %{"type" => "Note"}
})
assert Timex.diff(expires_at, NaiveDateTime.utc_now(), :days) == 364
end
test "ignores remote activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
"type" => "Create",
"object" => %{"type" => "Note"}
})
refute Map.has_key?(activity, "expires_at")
end
test "ignores non-Create/Note activities" do
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
"type" => "Follow"
})
refute Map.has_key?(activity, "expires_at")
assert {:ok, activity} =
ActivityExpirationPolicy.filter(%{
"id" => "https://example.com/123",
"type" => "Create",
"object" => %{"type" => "Cofe"}
})
refute Map.has_key?(activity, "expires_at")
end
end

View file

@ -33,7 +33,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
describe "with new user" do
test "it allows posts without links" do
user = insert(:user)
user = insert(:user, local: false)
assert user.note_count == 0
@ -45,7 +45,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
end
test "it disallows posts with links" do
user = insert(:user)
user = insert(:user, local: false)
assert user.note_count == 0
@ -55,6 +55,18 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
{:reject, _} = AntiLinkSpamPolicy.filter(message)
end
test "it allows posts with links for local users" do
user = insert(:user)
assert user.note_count == 0
message =
@linkful_message
|> Map.put("actor", user.ap_id)
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
end
end
describe "with old user" do

View file

@ -8,6 +8,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
import Pleroma.Web.ActivityPub.MRF.HellthreadPolicy
alias Pleroma.Web.CommonAPI
setup do
user = insert(:user)
@ -20,7 +22,10 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
"https://instance.tld/users/user1",
"https://instance.tld/users/user2",
"https://instance.tld/users/user3"
]
],
"object" => %{
"type" => "Note"
}
}
[user: user, message: message]
@ -28,6 +33,17 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
setup do: clear_config(:mrf_hellthread)
test "doesn't die on chat messages" do
Pleroma.Config.put([:mrf_hellthread], %{delist_threshold: 2, reject_threshold: 0})
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post_chat_message(user, other_user, "moin")
assert {:ok, _} = filter(activity.data)
end
describe "reject" do
test "rejects the message if the recipient count is above reject_threshold", %{
message: message

View file

@ -60,8 +60,6 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
end
describe "describe/0" do
setup do: clear_config([:instance, :rewrite_policy])
test "it works as expected with noop policy" do
expected = %{
mrf_policies: ["NoOpPolicy"],
@ -72,7 +70,7 @@ defmodule Pleroma.Web.ActivityPub.MRFTest do
end
test "it works as expected with mock policy" do
Pleroma.Config.put([:instance, :rewrite_policy], [MRFModuleMock])
clear_config([:mrf, :policies], [MRFModuleMock])
expected = %{
mrf_policies: ["MRFModuleMock"],

View file

@ -0,0 +1,68 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.StealEmojiPolicyTest do
use Pleroma.DataCase
alias Pleroma.Config
alias Pleroma.Web.ActivityPub.MRF.StealEmojiPolicy
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
setup do
emoji_path = Path.join(Config.get([:instance, :static_dir]), "emoji/stolen")
File.rm_rf!(emoji_path)
File.mkdir!(emoji_path)
Pleroma.Emoji.reload()
on_exit(fn ->
File.rm_rf!(emoji_path)
end)
:ok
end
test "does nothing by default" do
installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
refute "firedfox" in installed_emoji
message = %{
"type" => "Create",
"object" => %{
"emoji" => [{"firedfox", "https://example.org/emoji/firedfox.png"}],
"actor" => "https://example.org/users/admin"
}
}
assert {:ok, message} == StealEmojiPolicy.filter(message)
installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
refute "firedfox" in installed_emoji
end
test "Steals emoji on unknown shortcode from allowed remote host" do
installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
refute "firedfox" in installed_emoji
message = %{
"type" => "Create",
"object" => %{
"emoji" => [{"firedfox", "https://example.org/emoji/firedfox.png"}],
"actor" => "https://example.org/users/admin"
}
}
clear_config([:mrf_steal_emoji, :hosts], ["example.org"])
clear_config([:mrf_steal_emoji, :size_limit], 284_468)
assert {:ok, message} == StealEmojiPolicy.filter(message)
installed_emoji = Pleroma.Emoji.get_all() |> Enum.map(fn {k, _} -> k end)
assert "firedfox" in installed_emoji
end
end

View file

@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.UserAllowListPolicy
setup do: clear_config([:mrf_user_allowlist, :localhost])
setup do: clear_config(:mrf_user_allowlist)
test "pass filter if allow list is empty" do
actor = insert(:user)
@ -17,14 +17,14 @@ defmodule Pleroma.Web.ActivityPub.MRF.UserAllowListPolicyTest do
test "pass filter if allow list isn't empty and user in allow list" do
actor = insert(:user)
Pleroma.Config.put([:mrf_user_allowlist, :localhost], [actor.ap_id, "test-ap-id"])
Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => [actor.ap_id, "test-ap-id"]})
message = %{"actor" => actor.ap_id}
assert UserAllowListPolicy.filter(message) == {:ok, message}
end
test "rejected if allow list isn't empty and user not in allow list" do
actor = insert(:user)
Pleroma.Config.put([:mrf_user_allowlist, :localhost], ["test-ap-id"])
Pleroma.Config.put([:mrf_user_allowlist], %{"localhost" => ["test-ap-id"]})
message = %{"actor" => actor.ap_id}
assert UserAllowListPolicy.filter(message) == {:reject, nil}
end

View file

@ -2,14 +2,264 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
use Pleroma.DataCase
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Builder
alias Pleroma.Web.ActivityPub.ObjectValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "attachments" do
test "works with honkerific attachments" do
attachment = %{
"mediaType" => "",
"name" => "",
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
"type" => "Document",
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
}
assert {:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "application/octet-stream"
end
test "it turns mastodon attachments into our attachments" do
attachment = %{
"url" =>
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
"type" => "Document",
"name" => nil,
"mediaType" => "image/jpeg"
}
{:ok, attachment} =
AttachmentValidator.cast_and_validate(attachment)
|> Ecto.Changeset.apply_action(:insert)
assert [
%{
href:
"http://mastodon.example.org/system/media_attachments/files/000/000/002/original/334ce029e7bfb920.jpg",
type: "Link",
mediaType: "image/jpeg"
}
] = attachment.url
assert attachment.mediaType == "image/jpeg"
end
test "it handles our own uploads" do
user = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, attachment} =
attachment.data
|> AttachmentValidator.cast_and_validate()
|> Ecto.Changeset.apply_action(:insert)
assert attachment.mediaType == "image/jpeg"
end
end
describe "chat message create activities" do
test "it is invalid if the object already exists" do
user = insert(:user)
recipient = insert(:user)
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "hey")
object = Object.normalize(activity, false)
{:ok, create_data, _} = Builder.create(user, object.data, [recipient.ap_id])
{:error, cng} = ObjectValidator.validate(create_data, [])
assert {:object, {"The object to create already exists", []}} in cng.errors
end
test "it is invalid if the object data has a different `to` or `actor` field" do
user = insert(:user)
recipient = insert(:user)
{:ok, object_data, _} = Builder.chat_message(recipient, user.ap_id, "Hey")
{:ok, create_data, _} = Builder.create(user, object_data, [recipient.ap_id])
{:error, cng} = ObjectValidator.validate(create_data, [])
assert {:to, {"Recipients don't match with object recipients", []}} in cng.errors
assert {:actor, {"Actor doesn't match with object actor", []}} in cng.errors
end
end
describe "chat messages" do
setup do
clear_config([:instance, :remote_limit])
user = insert(:user)
recipient = insert(:user, local: false)
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey :firefox:")
%{user: user, recipient: recipient, valid_chat_message: valid_chat_message}
end
test "let's through some basic html", %{user: user, recipient: recipient} do
{:ok, valid_chat_message, _} =
Builder.chat_message(
user,
recipient.ap_id,
"hey <a href='https://example.org'>example</a> <script>alert('uguu')</script>"
)
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["content"] ==
"hey <a href=\"https://example.org\">example</a> alert(&#39;uguu&#39;)"
end
test "validates for a basic object we build", %{valid_chat_message: valid_chat_message} do
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert Map.put(valid_chat_message, "attachment", nil) == object
end
test "validates for a basic object with an attachment", %{
valid_chat_message: valid_chat_message,
user: user
} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
valid_chat_message =
valid_chat_message
|> Map.put("attachment", attachment.data)
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["attachment"]
end
test "validates for a basic object with an attachment in an array", %{
valid_chat_message: valid_chat_message,
user: user
} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
valid_chat_message =
valid_chat_message
|> Map.put("attachment", [attachment.data])
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["attachment"]
end
test "validates for a basic object with an attachment but without content", %{
valid_chat_message: valid_chat_message,
user: user
} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, attachment} = ActivityPub.upload(file, actor: user.ap_id)
valid_chat_message =
valid_chat_message
|> Map.put("attachment", attachment.data)
|> Map.delete("content")
assert {:ok, object, _meta} = ObjectValidator.validate(valid_chat_message, [])
assert object["attachment"]
end
test "does not validate if the message has no content", %{
valid_chat_message: valid_chat_message
} do
contentless =
valid_chat_message
|> Map.delete("content")
refute match?({:ok, _object, _meta}, ObjectValidator.validate(contentless, []))
end
test "does not validate if the message is longer than the remote_limit", %{
valid_chat_message: valid_chat_message
} do
Pleroma.Config.put([:instance, :remote_limit], 2)
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
end
test "does not validate if the recipient is blocking the actor", %{
valid_chat_message: valid_chat_message,
user: user,
recipient: recipient
} do
Pleroma.User.block(recipient, user)
refute match?({:ok, _object, _meta}, ObjectValidator.validate(valid_chat_message, []))
end
test "does not validate if the actor or the recipient is not in our system", %{
valid_chat_message: valid_chat_message
} do
chat_message =
valid_chat_message
|> Map.put("actor", "https://raymoo.com/raymoo")
{:error, _} = ObjectValidator.validate(chat_message, [])
chat_message =
valid_chat_message
|> Map.put("to", ["https://raymoo.com/raymoo"])
{:error, _} = ObjectValidator.validate(chat_message, [])
end
test "does not validate for a message with multiple recipients", %{
valid_chat_message: valid_chat_message,
user: user,
recipient: recipient
} do
chat_message =
valid_chat_message
|> Map.put("to", [user.ap_id, recipient.ap_id])
assert {:error, _} = ObjectValidator.validate(chat_message, [])
end
test "does not validate if it doesn't concern local users" do
user = insert(:user, local: false)
recipient = insert(:user, local: false)
{:ok, valid_chat_message, _} = Builder.chat_message(user, recipient.ap_id, "hey")
assert {:error, _} = ObjectValidator.validate(valid_chat_message, [])
end
end
describe "EmojiReacts" do
setup do
user = insert(:user)
@ -280,4 +530,155 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
assert {:object, valid_like["object"]} in validated.changes
end
end
describe "announces" do
setup do
user = insert(:user)
announcer = insert(:user)
{:ok, post_activity} = CommonAPI.post(user, %{status: "uguu"})
object = Object.normalize(post_activity, false)
{:ok, valid_announce, []} = Builder.announce(announcer, object)
%{
valid_announce: valid_announce,
user: user,
post_activity: post_activity,
announcer: announcer
}
end
test "returns ok for a valid announce", %{valid_announce: valid_announce} do
assert {:ok, _object, _meta} = ObjectValidator.validate(valid_announce, [])
end
test "returns an error if the object can't be found", %{valid_announce: valid_announce} do
without_object =
valid_announce
|> Map.delete("object")
{:error, cng} = ObjectValidator.validate(without_object, [])
assert {:object, {"can't be blank", [validation: :required]}} in cng.errors
nonexisting_object =
valid_announce
|> Map.put("object", "https://gensokyo.2hu/objects/99999999")
{:error, cng} = ObjectValidator.validate(nonexisting_object, [])
assert {:object, {"can't find object", []}} in cng.errors
end
test "returns an error if we don't have the actor", %{valid_announce: valid_announce} do
nonexisting_actor =
valid_announce
|> Map.put("actor", "https://gensokyo.2hu/users/raymoo")
{:error, cng} = ObjectValidator.validate(nonexisting_actor, [])
assert {:actor, {"can't find user", []}} in cng.errors
end
test "returns an error if the actor already announced the object", %{
valid_announce: valid_announce,
announcer: announcer,
post_activity: post_activity
} do
_announce = CommonAPI.repeat(post_activity.id, announcer)
{:error, cng} = ObjectValidator.validate(valid_announce, [])
assert {:actor, {"already announced this object", []}} in cng.errors
assert {:object, {"already announced by this actor", []}} in cng.errors
end
test "returns an error if the actor can't announce the object", %{
announcer: announcer,
user: user
} do
{:ok, post_activity} =
CommonAPI.post(user, %{status: "a secret post", visibility: "private"})
object = Object.normalize(post_activity, false)
# Another user can't announce it
{:ok, announce, []} = Builder.announce(announcer, object, public: false)
{:error, cng} = ObjectValidator.validate(announce, [])
assert {:actor, {"can not announce this object", []}} in cng.errors
# The actor of the object can announce it
{:ok, announce, []} = Builder.announce(user, object, public: false)
assert {:ok, _, _} = ObjectValidator.validate(announce, [])
# The actor of the object can not announce it publicly
{:ok, announce, []} = Builder.announce(user, object, public: true)
{:error, cng} = ObjectValidator.validate(announce, [])
assert {:actor, {"can not announce this object publicly", []}} in cng.errors
end
end
describe "updates" do
setup do
user = insert(:user)
object = %{
"id" => user.ap_id,
"name" => "A new name",
"summary" => "A new bio"
}
{:ok, valid_update, []} = Builder.update(user, object)
%{user: user, valid_update: valid_update}
end
test "validates a basic object", %{valid_update: valid_update} do
assert {:ok, _update, []} = ObjectValidator.validate(valid_update, [])
end
test "returns an error if the object can't be updated by the actor", %{
valid_update: valid_update
} do
other_user = insert(:user)
update =
valid_update
|> Map.put("actor", other_user.ap_id)
assert {:error, _cng} = ObjectValidator.validate(update, [])
end
end
describe "blocks" do
setup do
user = insert(:user, local: false)
blocked = insert(:user)
{:ok, valid_block, []} = Builder.block(user, blocked)
%{user: user, valid_block: valid_block}
end
test "validates a basic object", %{
valid_block: valid_block
} do
assert {:ok, _block, []} = ObjectValidator.validate(valid_block, [])
end
test "returns an error if we don't know the blocked user", %{
valid_block: valid_block
} do
block =
valid_block
|> Map.put("object", "https://gensokyo.2hu/users/raymoo")
assert {:error, _cng} = ObjectValidator.validate(block, [])
end
end
end

View file

@ -1,5 +1,5 @@
defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTimeTest do
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.DateTime
alias Pleroma.EctoType.ActivityPub.ObjectValidators.DateTime
use Pleroma.DataCase
test "it validates an xsd:Datetime" do

View file

@ -1,5 +1,9 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ObjectValidators.Types.ObjectIDTest do
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.ObjectID
alias Pleroma.EctoType.ActivityPub.ObjectValidators.ObjectID
use Pleroma.DataCase
@uris [

View file

@ -1,5 +1,5 @@
defmodule Pleroma.Web.ObjectValidators.Types.RecipientsTest do
alias Pleroma.Web.ActivityPub.ObjectValidators.Types.Recipients
alias Pleroma.EctoType.ActivityPub.ObjectValidators.Recipients
use Pleroma.DataCase
test "it asserts that all elements of the list are object ids" do

View file

@ -0,0 +1,30 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.SafeTextTest do
use Pleroma.DataCase
alias Pleroma.EctoType.ActivityPub.ObjectValidators.SafeText
test "it lets normal text go through" do
text = "hey how are you"
assert {:ok, text} == SafeText.cast(text)
end
test "it removes html tags from text" do
text = "hey look xss <script>alert('foo')</script>"
assert {:ok, "hey look xss alert(&#39;foo&#39;)"} == SafeText.cast(text)
end
test "it keeps basic html tags" do
text = "hey <a href='http://gensokyo.2hu'>look</a> xss <script>alert('foo')</script>"
assert {:ok, "hey <a href=\"http://gensokyo.2hu\">look</a> xss alert(&#39;foo&#39;)"} ==
SafeText.cast(text)
end
test "errors for non-text" do
assert :error == SafeText.cast(1)
end
end

View file

@ -9,6 +9,11 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
import Pleroma.Factory
describe "common_pipeline/2" do
setup do
clear_config([:instance, :federating], true)
:ok
end
test "it goes through validation, filtering, persisting, side effects and federation for local activities" do
activity = insert(:note_activity)
meta = [local: true]
@ -28,7 +33,10 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.SideEffects,
[],
[handle: fn o, m -> {:ok, o, m} end]
[
handle: fn o, m -> {:ok, o, m} end,
handle_after_transaction: fn m -> m end
]
},
{
Pleroma.Web.Federator,
@ -66,7 +74,46 @@ defmodule Pleroma.Web.ActivityPub.PipelineTest do
{
Pleroma.Web.ActivityPub.SideEffects,
[],
[handle: fn o, m -> {:ok, o, m} end]
[handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
},
{
Pleroma.Web.Federator,
[],
[]
}
]) do
assert {:ok, ^activity, ^meta} =
Pleroma.Web.ActivityPub.Pipeline.common_pipeline(activity, meta)
assert_called(Pleroma.Web.ActivityPub.ObjectValidator.validate(activity, meta))
assert_called(Pleroma.Web.ActivityPub.MRF.filter(activity))
assert_called(Pleroma.Web.ActivityPub.ActivityPub.persist(activity, meta))
assert_called(Pleroma.Web.ActivityPub.SideEffects.handle(activity, meta))
end
end
test "it goes through validation, filtering, persisting, side effects without federation for local activities if federation is deactivated" do
clear_config([:instance, :federating], false)
activity = insert(:note_activity)
meta = [local: true]
with_mocks([
{Pleroma.Web.ActivityPub.ObjectValidator, [], [validate: fn o, m -> {:ok, o, m} end]},
{
Pleroma.Web.ActivityPub.MRF,
[],
[filter: fn o -> {:ok, o} end]
},
{
Pleroma.Web.ActivityPub.ActivityPub,
[],
[persist: fn o, m -> {:ok, o, m} end]
},
{
Pleroma.Web.ActivityPub.SideEffects,
[],
[handle: fn o, m -> {:ok, o, m} end, handle_after_transaction: fn m -> m end]
},
{
Pleroma.Web.Federator,

View file

@ -6,7 +6,6 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay
@ -95,21 +94,21 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
end)
assert capture_log(fn ->
assert Relay.publish(activity) == {:error, nil}
end) =~ "[error] error: nil"
assert Relay.publish(activity) == {:error, false}
end) =~ "[error] error: false"
end
test_with_mock "returns announce activity and publish to federate",
Pleroma.Web.Federator,
[:passthrough],
[] do
Pleroma.Config.put([:instance, :federating], true)
clear_config([:instance, :federating], true)
service_actor = Relay.get_actor()
note = insert(:note_activity)
assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)
assert {:ok, %Activity{} = activity} = Relay.publish(note)
assert activity.data["type"] == "Announce"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["object"] == obj.data["id"]
assert activity.data["to"] == [service_actor.follower_address]
assert called(Pleroma.Web.Federator.publish(activity))
end
@ -117,13 +116,12 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
Pleroma.Web.Federator,
[:passthrough],
[] do
Pleroma.Config.put([:instance, :federating], false)
clear_config([:instance, :federating], false)
service_actor = Relay.get_actor()
note = insert(:note_activity)
assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note)
assert {:ok, %Activity{} = activity} = Relay.publish(note)
assert activity.data["type"] == "Announce"
assert activity.data["actor"] == service_actor.ap_id
assert activity.data["object"] == obj.data["id"]
refute called(Pleroma.Web.Federator.publish(activity))
end
end

View file

@ -7,6 +7,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
@ -20,6 +22,114 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
import Pleroma.Factory
import Mock
describe "handle_after_transaction" do
test "it streams out notifications and streams" do
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
assert [notification] = meta[:notifications]
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ -> nil end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
SideEffects.handle_after_transaction(meta)
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
assert called(Pleroma.Web.Push.send(notification))
end
end
end
describe "blocking users" do
setup do
user = insert(:user)
blocked = insert(:user)
User.follow(blocked, user)
User.follow(user, blocked)
{:ok, block_data, []} = Builder.block(user, blocked)
{:ok, block, _meta} = ActivityPub.persist(block_data, local: true)
%{user: user, blocked: blocked, block: block}
end
test "it unfollows and blocks", %{user: user, blocked: blocked, block: block} do
assert User.following?(user, blocked)
assert User.following?(blocked, user)
{:ok, _, _} = SideEffects.handle(block)
refute User.following?(user, blocked)
refute User.following?(blocked, user)
assert User.blocks?(user, blocked)
end
test "it blocks but does not unfollow if the relevant setting is set", %{
user: user,
blocked: blocked,
block: block
} do
clear_config([:activitypub, :unfollow_blocked], false)
assert User.following?(user, blocked)
assert User.following?(blocked, user)
{:ok, _, _} = SideEffects.handle(block)
refute User.following?(user, blocked)
assert User.following?(blocked, user)
assert User.blocks?(user, blocked)
end
end
describe "update users" do
setup do
user = insert(:user)
{:ok, update_data, []} = Builder.update(user, %{"id" => user.ap_id, "name" => "new name!"})
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
%{user: user, update_data: update_data, update: update}
end
test "it updates the user", %{user: user, update: update} do
{:ok, _, _} = SideEffects.handle(update)
user = User.get_by_id(user.id)
assert user.name == "new name!"
end
test "it uses a given changeset to update", %{user: user, update: update} do
changeset = Ecto.Changeset.change(user, %{default_scope: "direct"})
assert user.default_scope == "public"
{:ok, _, _} = SideEffects.handle(update, user_update_changeset: changeset)
user = User.get_by_id(user.id)
assert user.default_scope == "direct"
end
end
describe "delete objects" do
setup do
user = insert(:user)
@ -140,6 +250,31 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
end
end
describe "delete users with confirmation pending" do
setup do
user = insert(:user, confirmation_pending: true)
{:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
{:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
{:ok, delete: delete_user, user: user}
end
test "when activation is not required", %{delete: delete, user: user} do
clear_config([:instance, :account_activation_required], false)
{:ok, _, _} = SideEffects.handle(delete)
ObanHelpers.perform_all()
assert User.get_cached_by_id(user.id).deactivated
end
test "when activation is required", %{delete: delete, user: user} do
clear_config([:instance, :account_activation_required], true)
{:ok, _, _} = SideEffects.handle(delete)
ObanHelpers.perform_all()
refute User.get_cached_by_id(user.id)
end
end
describe "Undo objects" do
setup do
poster = insert(:user)
@ -147,9 +282,8 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
{:ok, like} = CommonAPI.favorite(user, post.id)
{:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
{:ok, announce, _} = CommonAPI.repeat(post.id, user)
{:ok, block} = ActivityPub.block(user, poster)
User.block(user, poster)
{:ok, announce} = CommonAPI.repeat(post.id, user)
{:ok, block} = CommonAPI.block(user, poster)
{:ok, undo_data, _meta} = Builder.undo(user, like)
{:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
@ -264,4 +398,202 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id)
end
end
describe "creation of ChatMessages" do
test "notifies the recipient" do
author = insert(:user, local: false)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
assert Repo.get_by(Notification, user_id: recipient.id, activity_id: create_activity.id)
end
test "it streams the created ChatMessage" do
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
assert [_, _] = meta[:streamables]
end
test "it creates a Chat and MessageReferences for the local users and bumps the unread count, except for the author" do
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ -> nil end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
{:ok, _create_activity, meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
# The notification gets created
assert [notification] = meta[:notifications]
assert notification.activity_id == create_activity.id
# But it is not sent out
refute called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
refute called(Pleroma.Web.Push.send(notification))
# Same for the user chat stream
assert [{topics, _}, _] = meta[:streamables]
assert topics == ["user", "user:pleroma_chat"]
refute called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
chat = Chat.get(author.id, recipient.ap_id)
[cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all()
assert cm_ref.object.data["content"] == "hey"
assert cm_ref.unread == false
chat = Chat.get(recipient.id, author.ap_id)
[cm_ref] = MessageReference.for_chat_query(chat) |> Repo.all()
assert cm_ref.object.data["content"] == "hey"
assert cm_ref.unread == true
end
end
test "it creates a Chat for the local users and bumps the unread count" do
author = insert(:user, local: false)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
# An object is created
assert Object.get_by_ap_id(chat_message_data["id"])
# The remote user won't get a chat
chat = Chat.get(author.id, recipient.ap_id)
refute chat
# The local user will get a chat
chat = Chat.get(recipient.id, author.ap_id)
assert chat
author = insert(:user, local: true)
recipient = insert(:user, local: true)
{:ok, chat_message_data, _meta} = Builder.chat_message(author, recipient.ap_id, "hey")
{:ok, create_activity_data, _meta} =
Builder.create(author, chat_message_data["id"], [recipient.ap_id])
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
{:ok, _create_activity, _meta} =
SideEffects.handle(create_activity, local: false, object_data: chat_message_data)
# Both users are local and get the chat
chat = Chat.get(author.id, recipient.ap_id)
assert chat
chat = Chat.get(recipient.id, author.ap_id)
assert chat
end
end
describe "announce objects" do
setup do
poster = insert(:user)
user = insert(:user)
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
{:ok, private_post} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
{:ok, announce_data, _meta} = Builder.announce(user, post.object, public: true)
{:ok, private_announce_data, _meta} =
Builder.announce(user, private_post.object, public: false)
{:ok, relay_announce_data, _meta} =
Builder.announce(Pleroma.Web.ActivityPub.Relay.get_actor(), post.object, public: true)
{:ok, announce, _meta} = ActivityPub.persist(announce_data, local: true)
{:ok, private_announce, _meta} = ActivityPub.persist(private_announce_data, local: true)
{:ok, relay_announce, _meta} = ActivityPub.persist(relay_announce_data, local: true)
%{
announce: announce,
user: user,
poster: poster,
private_announce: private_announce,
relay_announce: relay_announce
}
end
test "adds the announce to the original object", %{announce: announce, user: user} do
{:ok, announce, _} = SideEffects.handle(announce)
object = Object.get_by_ap_id(announce.data["object"])
assert object.data["announcement_count"] == 1
assert user.ap_id in object.data["announcements"]
end
test "does not add the announce to the original object if the actor is a service actor", %{
relay_announce: announce
} do
{:ok, announce, _} = SideEffects.handle(announce)
object = Object.get_by_ap_id(announce.data["object"])
assert object.data["announcement_count"] == nil
end
test "creates a notification", %{announce: announce, poster: poster} do
{:ok, announce, _} = SideEffects.handle(announce)
assert Repo.get_by(Notification, user_id: poster.id, activity_id: announce.id)
end
test "it streams out the announce", %{announce: announce} do
with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough], stream_out: fn _ -> nil end do
{:ok, announce, _} = SideEffects.handle(announce)
assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(announce))
end
end
end
end

View file

@ -0,0 +1,172 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.AnnounceHandlingTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "it works for incoming honk announces" do
user = insert(:user, ap_id: "https://honktest/u/test", local: false)
other_user = insert(:user)
{:ok, post} = CommonAPI.post(other_user, %{status: "bonkeronk"})
announce = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"actor" => "https://honktest/u/test",
"id" => "https://honktest/u/test/bonk/1793M7B9MQ48847vdx",
"object" => post.data["object"],
"published" => "2019-06-25T19:33:58Z",
"to" => "https://www.w3.org/ns/activitystreams#Public",
"type" => "Announce"
}
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(announce)
object = Object.get_by_ap_id(post.data["object"])
assert length(object.data["announcements"]) == 1
assert user.ap_id in object.data["announcements"]
end
test "it works for incoming announces with actor being inlined (kroeg)" do
data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Poison.decode!()
_user = insert(:user, local: false, ap_id: data["actor"]["id"])
other_user = insert(:user)
{:ok, post} = CommonAPI.post(other_user, %{status: "kroegeroeg"})
data =
data
|> put_in(["object", "id"], post.data["object"])
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["actor"] == "https://puckipedia.com/"
end
test "it works for incoming announces, fetching the announced object" do
data =
File.read!("test/fixtures/mastodon-announce.json")
|> Poison.decode!()
|> Map.put("object", "http://mastodon.example.org/users/admin/statuses/99541947525187367")
Tesla.Mock.mock(fn
%{method: :get} ->
%Tesla.Env{status: 200, body: File.read!("test/fixtures/mastodon-note-object.json")}
end)
_user = insert(:user, local: false, ap_id: data["actor"])
{: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"
assert data["object"] ==
"http://mastodon.example.org/users/admin/statuses/99541947525187367"
assert(Activity.get_create_by_object_ap_id(data["object"]))
end
@tag capture_log: true
test "it works for incoming announces with an existing activity" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
data =
File.read!("test/fixtures/mastodon-announce.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
_user = insert(:user, local: false, ap_id: data["actor"])
{: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"
assert data["object"] == activity.data["object"]
assert Activity.get_create_by_object_ap_id(data["object"]).id == activity.id
end
# Ignore inlined activities for now
@tag skip: true
test "it works for incoming announces with an inlined activity" do
data =
File.read!("test/fixtures/mastodon-announce-private.json")
|> Poison.decode!()
_user =
insert(:user,
local: false,
ap_id: data["actor"],
follower_address: data["actor"] <> "/followers"
)
{: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
@tag capture_log: true
test "it rejects incoming announces with an inlined activity from another origin" do
Tesla.Mock.mock(fn
%{method: :get} -> %Tesla.Env{status: 404, body: ""}
end)
data =
File.read!("test/fixtures/bogus-mastodon-announce.json")
|> Poison.decode!()
_user = insert(:user, local: false, ap_id: data["actor"])
assert {:error, e} = 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"})
data =
File.read!("test/fixtures/mastodon-announce.json")
|> Poison.decode!()
|> Map.put("object", Object.normalize(activity).data["id"])
|> Map.put("to", ["http://mastodon.example.org/users/admin/followers"])
|> Map.put("cc", [])
_user =
insert(:user,
local: false,
ap_id: data["actor"],
follower_address: "http://mastodon.example.org/users/admin/followers"
)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["to"] == ["http://mastodon.example.org/users/admin/followers"]
end
end

View file

@ -0,0 +1,63 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.BlockHandlingTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
import Pleroma.Factory
test "it works for incoming blocks" do
user = insert(:user)
data =
File.read!("test/fixtures/mastodon-block-activity.json")
|> Poison.decode!()
|> Map.put("object", user.ap_id)
blocker = insert(:user, ap_id: data["actor"])
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["type"] == "Block"
assert data["object"] == user.ap_id
assert data["actor"] == "http://mastodon.example.org/users/admin"
assert User.blocks?(blocker, user)
end
test "incoming blocks successfully tear down any follow relationship" do
blocker = insert(:user)
blocked = insert(:user)
data =
File.read!("test/fixtures/mastodon-block-activity.json")
|> Poison.decode!()
|> Map.put("object", blocked.ap_id)
|> Map.put("actor", blocker.ap_id)
{:ok, blocker} = User.follow(blocker, blocked)
{:ok, blocked} = User.follow(blocked, blocker)
assert User.following?(blocker, blocked)
assert User.following?(blocked, blocker)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["type"] == "Block"
assert data["object"] == blocked.ap_id
assert data["actor"] == blocker.ap_id
blocker = User.get_cached_by_ap_id(data["actor"])
blocked = User.get_cached_by_ap_id(data["object"])
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
end
end

View file

@ -0,0 +1,153 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.ChatMessageTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Transmogrifier
describe "handle_incoming" do
test "handles chonks with attachment" do
data = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"actor" => "https://honk.tedunangst.com/u/tedu",
"id" => "https://honk.tedunangst.com/u/tedu/honk/x6gt8X8PcyGkQcXxzg1T",
"object" => %{
"attachment" => [
%{
"mediaType" => "image/jpeg",
"name" => "298p3RG7j27tfsZ9RQ.jpg",
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
"type" => "Document",
"url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
}
],
"attributedTo" => "https://honk.tedunangst.com/u/tedu",
"content" => "",
"id" => "https://honk.tedunangst.com/u/tedu/chonk/26L4wl5yCbn4dr4y1b",
"published" => "2020-05-18T01:13:03Z",
"to" => [
"https://dontbulling.me/users/lain"
],
"type" => "ChatMessage"
},
"published" => "2020-05-18T01:13:03Z",
"to" => [
"https://dontbulling.me/users/lain"
],
"type" => "Create"
}
_user = insert(:user, ap_id: data["actor"])
_user = insert(:user, ap_id: hd(data["to"]))
assert {:ok, _activity} = Transmogrifier.handle_incoming(data)
end
test "it rejects messages that don't contain content" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
object =
data["object"]
|> Map.delete("content")
data =
data
|> Map.put("object", object)
_author =
insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
_recipient =
insert(:user,
ap_id: List.first(data["to"]),
local: true,
last_refreshed_at: DateTime.utc_now()
)
{:error, _} = Transmogrifier.handle_incoming(data)
end
test "it rejects messages that don't concern local users" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
_author =
insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
_recipient =
insert(:user,
ap_id: List.first(data["to"]),
local: false,
last_refreshed_at: DateTime.utc_now()
)
{:error, _} = Transmogrifier.handle_incoming(data)
end
test "it rejects messages where the `to` field of activity and object don't match" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
author = insert(:user, ap_id: data["actor"])
_recipient = insert(:user, ap_id: List.first(data["to"]))
data =
data
|> Map.put("to", author.ap_id)
assert match?({:error, _}, Transmogrifier.handle_incoming(data))
refute Object.get_by_ap_id(data["object"]["id"])
end
test "it fetches the actor if they aren't in our system" do
Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
|> Map.put("actor", "http://mastodon.example.org/users/admin")
|> put_in(["object", "actor"], "http://mastodon.example.org/users/admin")
_recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
{:ok, %Activity{} = _activity} = Transmogrifier.handle_incoming(data)
end
test "it inserts it and creates a chat" do
data =
File.read!("test/fixtures/create-chat-message.json")
|> Poison.decode!()
author =
insert(:user, ap_id: data["actor"], local: false, last_refreshed_at: DateTime.utc_now())
recipient = insert(:user, ap_id: List.first(data["to"]), local: true)
{:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(data)
assert activity.local == false
assert activity.actor == author.ap_id
assert activity.recipients == [recipient.ap_id, author.ap_id]
%Object{} = object = Object.get_by_ap_id(activity.data["object"])
assert object
assert object.data["content"] == "You expected a cute girl? Too bad. alert(&#39;XSS&#39;)"
assert match?(%{"firefox" => _}, object.data["emoji"])
refute Chat.get(author.id, recipient.ap_id)
assert Chat.get(recipient.id, author.ap_id)
end
end
end

View file

@ -5,6 +5,7 @@
defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
@ -12,6 +13,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
import Pleroma.Factory
import Ecto.Query
import Mock
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -57,9 +59,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
activity = Repo.get(Activity, activity.id)
assert activity.data["state"] == "accept"
assert User.following?(User.get_cached_by_ap_id(data["actor"]), user)
[notification] = Notification.for_user(user)
assert notification.type == "follow"
end
test "with locked accounts, it does not create a follow or an accept" do
test "with locked accounts, it does create a Follow, but not an Accept" do
user = insert(:user, locked: true)
data =
@ -81,6 +86,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
|> Repo.all()
assert Enum.empty?(accepts)
[notification] = Notification.for_user(user)
assert notification.type == "follow_request"
end
test "it works for follow requests when you are already followed, creating a new accept activity" do
@ -144,6 +152,23 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
assert activity.data["state"] == "reject"
end
test "it rejects incoming follow requests if the following errors for some reason" do
user = insert(:user)
data =
File.read!("test/fixtures/mastodon-follow-activity.json")
|> Poison.decode!()
|> Map.put("object", user.ap_id)
with_mock Pleroma.User, [:passthrough], follow: fn _, _ -> {:error, :testing} end do
{:ok, %Activity{data: %{"id" => id}}} = Transmogrifier.handle_incoming(data)
%Activity{} = activity = Activity.get_by_ap_id(id)
assert activity.data["state"] == "reject"
end
end
test "it works for incoming follow requests from hubzilla" do
user = insert(:user)

View file

@ -0,0 +1,159 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.UserUpdateHandlingTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
import Pleroma.Factory
test "it works for incoming update activities" do
user = insert(:user, local: false)
update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
object =
update_data["object"]
|> Map.put("actor", user.ap_id)
|> Map.put("id", user.ap_id)
update_data =
update_data
|> Map.put("actor", user.ap_id)
|> Map.put("object", object)
{: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"
assert user.avatar["url"] == [
%{
"href" =>
"https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
}
]
assert user.banner["url"] == [
%{
"href" =>
"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
}
]
assert user.bio == "<p>Some bio</p>"
end
test "it works with alsoKnownAs" do
%{ap_id: actor} = insert(:user, local: false)
assert User.get_cached_by_ap_id(actor).also_known_as == []
{:ok, _activity} =
"test/fixtures/mastodon-update.json"
|> File.read!()
|> Poison.decode!()
|> Map.put("actor", actor)
|> Map.update!("object", fn object ->
object
|> Map.put("actor", actor)
|> Map.put("id", actor)
|> Map.put("alsoKnownAs", [
"http://mastodon.example.org/users/foo",
"http://example.org/users/bar"
])
end)
|> Transmogrifier.handle_incoming()
assert User.get_cached_by_ap_id(actor).also_known_as == [
"http://mastodon.example.org/users/foo",
"http://example.org/users/bar"
]
end
test "it works with custom profile fields" do
user = insert(:user, local: false)
assert user.fields == []
update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
object =
update_data["object"]
|> Map.put("actor", user.ap_id)
|> Map.put("id", user.ap_id)
update_data =
update_data
|> Map.put("actor", user.ap_id)
|> Map.put("object", object)
{:ok, _update_activity} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == [
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
]
Pleroma.Config.put([:instance, :max_remote_account_fields], 2)
update_data =
update_data
|> put_in(["object", "attachment"], [
%{"name" => "foo", "type" => "PropertyValue", "value" => "bar"},
%{"name" => "foo11", "type" => "PropertyValue", "value" => "bar11"},
%{"name" => "foo22", "type" => "PropertyValue", "value" => "bar22"}
])
|> Map.put("id", update_data["id"] <> ".")
{:ok, _} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == [
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
]
update_data =
update_data
|> put_in(["object", "attachment"], [])
|> Map.put("id", update_data["id"] <> ".")
{:ok, _} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == []
end
test "it works for incoming update activities which lock the account" do
user = insert(:user, local: false)
update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
object =
update_data["object"]
|> Map.put("actor", user.ap_id)
|> Map.put("id", user.ap_id)
|> Map.put("manuallyApprovesFollowers", true)
update_data =
update_data
|> Map.put("actor", user.ap_id)
|> Map.put("object", object)
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.locked == true
end
end

View file

@ -28,6 +28,63 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
setup do: clear_config([:instance, :max_remote_account_fields])
describe "handle_incoming" do
test "it works for incoming notices with tag not being an array (kroeg)" do
data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"])
assert object.data["emoji"] == %{
"icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png"
}
data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"])
assert "test" in object.data["tag"]
end
test "it works for incoming notices with url not being a string (prismo)" do
data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"])
assert object.data["url"] == "https://prismo.news/posts/83"
end
test "it cleans up incoming notices which are not really DMs" do
user = insert(:user)
other_user = insert(:user)
to = [user.ap_id, other_user.ap_id]
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("to", to)
|> Map.put("cc", [])
object =
data["object"]
|> Map.put("to", to)
|> Map.put("cc", [])
data = Map.put(data, "object", object)
{:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
assert data["to"] == []
assert data["cc"] == to
object_data = Object.normalize(activity).data
assert object_data["to"] == []
assert object_data["cc"] == to
end
test "it ignores an incoming notice if we already have it" do
activity = insert(:note_activity)
@ -260,172 +317,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
"<p>henlo from my Psion netBook</p><p>message sent from my Psion netBook</p>"
end
test "it works for incoming honk announces" do
_user = insert(:user, ap_id: "https://honktest/u/test", local: false)
other_user = insert(:user)
{:ok, post} = CommonAPI.post(other_user, %{status: "bonkeronk"})
announce = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"actor" => "https://honktest/u/test",
"id" => "https://honktest/u/test/bonk/1793M7B9MQ48847vdx",
"object" => post.data["object"],
"published" => "2019-06-25T19:33:58Z",
"to" => "https://www.w3.org/ns/activitystreams#Public",
"type" => "Announce"
}
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(announce)
end
test "it works for incoming announces with actor being inlined (kroeg)" do
data = File.read!("test/fixtures/kroeg-announce-with-inline-actor.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["actor"] == "https://puckipedia.com/"
end
test "it works for incoming notices with tag not being an array (kroeg)" do
data = File.read!("test/fixtures/kroeg-array-less-emoji.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"])
assert object.data["emoji"] == %{
"icon_e_smile" => "https://puckipedia.com/forum/images/smilies/icon_e_smile.png"
}
data = File.read!("test/fixtures/kroeg-array-less-hashtag.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"])
assert "test" in object.data["tag"]
end
test "it works for incoming notices with url not being a string (prismo)" do
data = File.read!("test/fixtures/prismo-url-map.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
object = Object.normalize(data["object"])
assert object.data["url"] == "https://prismo.news/posts/83"
end
test "it cleans up incoming notices which are not really DMs" do
user = insert(:user)
other_user = insert(:user)
to = [user.ap_id, other_user.ap_id]
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Map.put("to", to)
|> Map.put("cc", [])
object =
data["object"]
|> Map.put("to", to)
|> Map.put("cc", [])
data = Map.put(data, "object", object)
{:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data)
assert data["to"] == []
assert data["cc"] == to
object_data = Object.normalize(activity).data
assert object_data["to"] == []
assert object_data["cc"] == to
end
test "it works for incoming announces" do
data = File.read!("test/fixtures/mastodon-announce.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"
assert data["object"] ==
"http://mastodon.example.org/users/admin/statuses/99541947525187367"
assert Activity.get_create_by_object_ap_id(data["object"])
end
test "it works for incoming announces with an existing activity" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
data =
File.read!("test/fixtures/mastodon-announce.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"] == "Announce"
assert data["id"] ==
"http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
assert data["object"] == activity.data["object"]
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
@tag capture_log: true
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"})
data =
File.read!("test/fixtures/mastodon-announce.json")
|> Poison.decode!()
|> Map.put("object", Object.normalize(activity).data["id"])
|> Map.put("to", ["http://mastodon.example.org/users/admin/followers"])
|> Map.put("cc", [])
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["to"] == ["http://mastodon.example.org/users/admin/followers"]
end
test "it ensures that as:Public activities make it to their followers collection" do
user = insert(:user)
@ -510,162 +401,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
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!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
object =
update_data["object"]
|> Map.put("actor", data["actor"])
|> Map.put("id", data["actor"])
update_data =
update_data
|> Map.put("actor", data["actor"])
|> Map.put("object", object)
{: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"
assert user.avatar["url"] == [
%{
"href" =>
"https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
}
]
assert user.banner["url"] == [
%{
"href" =>
"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
}
]
assert user.bio == "<p>Some bio</p>"
end
test "it works with alsoKnownAs" do
{:ok, %Activity{data: %{"actor" => actor}}} =
"test/fixtures/mastodon-post-activity.json"
|> File.read!()
|> Poison.decode!()
|> Transmogrifier.handle_incoming()
assert User.get_cached_by_ap_id(actor).also_known_as == ["http://example.org/users/foo"]
{:ok, _activity} =
"test/fixtures/mastodon-update.json"
|> File.read!()
|> Poison.decode!()
|> Map.put("actor", actor)
|> Map.update!("object", fn object ->
object
|> Map.put("actor", actor)
|> Map.put("id", actor)
|> Map.put("alsoKnownAs", [
"http://mastodon.example.org/users/foo",
"http://example.org/users/bar"
])
end)
|> Transmogrifier.handle_incoming()
assert User.get_cached_by_ap_id(actor).also_known_as == [
"http://mastodon.example.org/users/foo",
"http://example.org/users/bar"
]
end
test "it works with custom profile fields" do
{:ok, activity} =
"test/fixtures/mastodon-post-activity.json"
|> File.read!()
|> Poison.decode!()
|> Transmogrifier.handle_incoming()
user = User.get_cached_by_ap_id(activity.actor)
assert user.fields == [
%{"name" => "foo", "value" => "bar"},
%{"name" => "foo1", "value" => "bar1"}
]
update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
object =
update_data["object"]
|> Map.put("actor", user.ap_id)
|> Map.put("id", user.ap_id)
update_data =
update_data
|> Map.put("actor", user.ap_id)
|> Map.put("object", object)
{:ok, _update_activity} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == [
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
]
Pleroma.Config.put([:instance, :max_remote_account_fields], 2)
update_data =
put_in(update_data, ["object", "attachment"], [
%{"name" => "foo", "type" => "PropertyValue", "value" => "bar"},
%{"name" => "foo11", "type" => "PropertyValue", "value" => "bar11"},
%{"name" => "foo22", "type" => "PropertyValue", "value" => "bar22"}
])
{:ok, _} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == [
%{"name" => "foo", "value" => "updated"},
%{"name" => "foo1", "value" => "updated"}
]
update_data = put_in(update_data, ["object", "attachment"], [])
{:ok, _} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(user.ap_id)
assert user.fields == []
end
test "it works for incoming update activities which lock the account" do
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
update_data = File.read!("test/fixtures/mastodon-update.json") |> Poison.decode!()
object =
update_data["object"]
|> Map.put("actor", data["actor"])
|> Map.put("id", data["actor"])
|> Map.put("manuallyApprovesFollowers", true)
update_data =
update_data
|> Map.put("actor", data["actor"])
|> Map.put("object", object)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(data["actor"])
assert user.locked == true
end
test "it works for incomming unfollows with an existing follow" do
user = insert(:user)
@ -710,56 +445,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert [^pending_follower] = User.get_follow_requests(user)
end
test "it works for incoming blocks" do
user = insert(:user)
data =
File.read!("test/fixtures/mastodon-block-activity.json")
|> Poison.decode!()
|> Map.put("object", user.ap_id)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["type"] == "Block"
assert data["object"] == user.ap_id
assert data["actor"] == "http://mastodon.example.org/users/admin"
blocker = User.get_cached_by_ap_id(data["actor"])
assert User.blocks?(blocker, user)
end
test "incoming blocks successfully tear down any follow relationship" do
blocker = insert(:user)
blocked = insert(:user)
data =
File.read!("test/fixtures/mastodon-block-activity.json")
|> Poison.decode!()
|> Map.put("object", blocked.ap_id)
|> Map.put("actor", blocker.ap_id)
{:ok, blocker} = User.follow(blocker, blocked)
{:ok, blocked} = User.follow(blocked, blocker)
assert User.following?(blocker, blocked)
assert User.following?(blocked, blocker)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["type"] == "Block"
assert data["object"] == blocked.ap_id
assert data["actor"] == blocker.ap_id
blocker = User.get_cached_by_ap_id(data["actor"])
blocked = User.get_cached_by_ap_id(data["object"])
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
end
test "it works for incoming accepts which were pre-accepted" do
follower = insert(:user)
followed = insert(:user)
@ -1188,7 +873,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} = CommonAPI.post(user, %{status: "hey", visibility: "private"})
{:ok, announce_activity, _} = CommonAPI.repeat(activity.id, user)
{:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
{:ok, modified} = Transmogrifier.prepare_outgoing(announce_activity.data)
@ -1203,23 +888,28 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
{:ok, activity} =
CommonAPI.post(user, %{status: "hey, @#{other_user.nickname}, how are ya? #2hu"})
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
object = modified["object"]
with_mock Pleroma.Notification,
get_notified_from_activity: fn _, _ -> [] end do
{:ok, modified} = Transmogrifier.prepare_outgoing(activity.data)
expected_mention = %{
"href" => other_user.ap_id,
"name" => "@#{other_user.nickname}",
"type" => "Mention"
}
object = modified["object"]
expected_tag = %{
"href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
"type" => "Hashtag",
"name" => "#2hu"
}
expected_mention = %{
"href" => other_user.ap_id,
"name" => "@#{other_user.nickname}",
"type" => "Mention"
}
assert Enum.member?(object["tag"], expected_tag)
assert Enum.member?(object["tag"], expected_mention)
expected_tag = %{
"href" => Pleroma.Web.Endpoint.url() <> "/tags/2hu",
"type" => "Hashtag",
"name" => "#2hu"
}
refute called(Pleroma.Notification.get_notified_from_activity(:_, :_))
assert Enum.member?(object["tag"], expected_tag)
assert Enum.member?(object["tag"], expected_mention)
end
end
test "it adds the sensitive property" do
@ -1438,7 +1128,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
assert capture_log(fn ->
:error = Transmogrifier.handle_incoming(data)
{:error, _} = Transmogrifier.handle_incoming(data)
end) =~ "Object containment failed"
end
@ -1453,7 +1143,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
assert capture_log(fn ->
:error = Transmogrifier.handle_incoming(data)
{:error, _} = Transmogrifier.handle_incoming(data)
end) =~ "Object containment failed"
end
@ -1468,7 +1158,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
assert capture_log(fn ->
:error = Transmogrifier.handle_incoming(data)
{:error, _} = Transmogrifier.handle_incoming(data)
end) =~ "Object containment failed"
end
end
@ -1675,9 +1365,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert modified_object["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873"
assert modified_object["conversation"] ==
"tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
assert modified_object["context"] ==
"tag:shitposter.club,2017-05-05:objectType=thread:nonce=3c16e9c2681f6d26"
end

View file

@ -27,16 +27,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
end
end
describe "fetch the latest Block" do
test "fetches the latest Block activity" do
blocker = insert(:user)
blocked = insert(:user)
{:ok, activity} = ActivityPub.block(blocker, blocked)
assert activity == Utils.fetch_latest_block(blocker, blocked)
end
end
describe "determine_explicit_mentions()" do
test "works with an object that has mentions" do
object = %{
@ -334,7 +324,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
assert object = Object.normalize(note_activity)
actor = insert(:user)
{:ok, announce, _object} = ActivityPub.announce(actor, object)
{:ok, announce} = CommonAPI.repeat(note_activity.id, actor)
assert Utils.get_existing_announce(actor.ap_id, object) == announce
end
end
@ -344,9 +334,9 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
user1 = insert(:user)
user2 = insert(:user)
assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
assert {:ok, %Activity{} = activity} = ActivityPub.block(user1, user2)
assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
assert {:ok, %Activity{} = _} = CommonAPI.block(user1, user2)
assert {:ok, %Activity{} = activity} = CommonAPI.block(user1, user2)
assert Utils.fetch_latest_block(user1, user2) == activity
end

View file

@ -73,7 +73,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
object = Object.normalize(note)
user = insert(:user)
{:ok, announce_activity, _} = CommonAPI.repeat(note.id, user)
{:ok, announce_activity} = CommonAPI.repeat(note.id, user)
result = ObjectView.render("object.json", %{object: announce_activity})

View file

@ -158,35 +158,4 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
assert %{"totalItems" => 1} = UserView.render("following.json", %{user: user})
end
end
test "activity collection page aginates correctly" do
user = insert(:user)
posts =
for i <- 0..25 do
{:ok, activity} = CommonAPI.post(user, %{status: "post #{i}"})
activity
end
# outbox sorts chronologically, newest first, with ten per page
posts = Enum.reverse(posts)
%{"next" => next_url} =
UserView.render("activity_collection_page.json", %{
iri: "#{user.ap_id}/outbox",
activities: Enum.take(posts, 10)
})
next_id = Enum.at(posts, 9).id
assert next_url =~ next_id
%{"next" => next_url} =
UserView.render("activity_collection_page.json", %{
iri: "#{user.ap_id}/outbox",
activities: Enum.take(Enum.drop(posts, 10), 10)
})
next_id = Enum.at(posts, 19).id
assert next_url =~ next_id
end
end

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,281 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.InviteControllerTest do
use Pleroma.Web.ConnCase, async: true
import Pleroma.Factory
alias Pleroma.Config
alias Pleroma.Repo
alias Pleroma.UserInviteToken
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "POST /api/pleroma/admin/users/email_invite, with valid config" do
setup do: clear_config([:instance, :registrations_open], false)
setup do: clear_config([:instance, :invites_enabled], true)
test "sends invitation and returns 204", %{admin: admin, conn: conn} do
recipient_email = "foo@bar.com"
recipient_name = "J. D."
conn =
conn
|> put_req_header("content-type", "application/json;charset=utf-8")
|> post("/api/pleroma/admin/users/email_invite", %{
email: recipient_email,
name: recipient_name
})
assert json_response_and_validate_schema(conn, :no_content)
token_record = List.last(Repo.all(Pleroma.UserInviteToken))
assert token_record
refute token_record.used
notify_email = Config.get([:instance, :notify_email])
instance_name = Config.get([:instance, :name])
email =
Pleroma.Emails.UserEmail.user_invitation_email(
admin,
token_record,
recipient_email,
recipient_name
)
Swoosh.TestAssertions.assert_email_sent(
from: {instance_name, notify_email},
to: {recipient_name, recipient_email},
html_body: email.html_body
)
end
test "it returns 403 if requested by a non-admin" do
non_admin_user = insert(:user)
token = insert(:oauth_token, user: non_admin_user)
conn =
build_conn()
|> assign(:user, non_admin_user)
|> assign(:token, token)
|> put_req_header("content-type", "application/json;charset=utf-8")
|> post("/api/pleroma/admin/users/email_invite", %{
email: "foo@bar.com",
name: "JD"
})
assert json_response(conn, :forbidden)
end
test "email with +", %{conn: conn, admin: admin} do
recipient_email = "foo+bar@baz.com"
conn
|> put_req_header("content-type", "application/json;charset=utf-8")
|> post("/api/pleroma/admin/users/email_invite", %{email: recipient_email})
|> json_response_and_validate_schema(:no_content)
token_record =
Pleroma.UserInviteToken
|> Repo.all()
|> List.last()
assert token_record
refute token_record.used
notify_email = Config.get([:instance, :notify_email])
instance_name = Config.get([:instance, :name])
email =
Pleroma.Emails.UserEmail.user_invitation_email(
admin,
token_record,
recipient_email
)
Swoosh.TestAssertions.assert_email_sent(
from: {instance_name, notify_email},
to: recipient_email,
html_body: email.html_body
)
end
end
describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do
setup do: clear_config([:instance, :registrations_open])
setup do: clear_config([:instance, :invites_enabled])
test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn} do
Config.put([:instance, :registrations_open], false)
Config.put([:instance, :invites_enabled], false)
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/email_invite", %{
email: "foo@bar.com",
name: "JD"
})
assert json_response_and_validate_schema(conn, :bad_request) ==
%{
"error" =>
"To send invites you need to set the `invites_enabled` option to true."
}
end
test "it returns 500 if `registrations_open` is enabled", %{conn: conn} do
Config.put([:instance, :registrations_open], true)
Config.put([:instance, :invites_enabled], true)
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/email_invite", %{
email: "foo@bar.com",
name: "JD"
})
assert json_response_and_validate_schema(conn, :bad_request) ==
%{
"error" =>
"To send invites you need to set the `registrations_open` option to false."
}
end
end
describe "POST /api/pleroma/admin/users/invite_token" do
test "without options", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/invite_token")
invite_json = json_response_and_validate_schema(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
refute invite.expires_at
refute invite.max_use
assert invite.invite_type == "one_time"
end
test "with expires_at", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/invite_token", %{
"expires_at" => Date.to_string(Date.utc_today())
})
invite_json = json_response_and_validate_schema(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
assert invite.expires_at == Date.utc_today()
refute invite.max_use
assert invite.invite_type == "date_limited"
end
test "with max_use", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/invite_token", %{"max_use" => 150})
invite_json = json_response_and_validate_schema(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
refute invite.expires_at
assert invite.max_use == 150
assert invite.invite_type == "reusable"
end
test "with max use and expires_at", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/invite_token", %{
"max_use" => 150,
"expires_at" => Date.to_string(Date.utc_today())
})
invite_json = json_response_and_validate_schema(conn, 200)
invite = UserInviteToken.find_by_token!(invite_json["token"])
refute invite.used
assert invite.expires_at == Date.utc_today()
assert invite.max_use == 150
assert invite.invite_type == "reusable_date_limited"
end
end
describe "GET /api/pleroma/admin/users/invites" do
test "no invites", %{conn: conn} do
conn = get(conn, "/api/pleroma/admin/users/invites")
assert json_response_and_validate_schema(conn, 200) == %{"invites" => []}
end
test "with invite", %{conn: conn} do
{:ok, invite} = UserInviteToken.create_invite()
conn = get(conn, "/api/pleroma/admin/users/invites")
assert json_response_and_validate_schema(conn, 200) == %{
"invites" => [
%{
"expires_at" => nil,
"id" => invite.id,
"invite_type" => "one_time",
"max_use" => nil,
"token" => invite.token,
"used" => false,
"uses" => 0
}
]
}
end
end
describe "POST /api/pleroma/admin/users/revoke_invite" do
test "with token", %{conn: conn} do
{:ok, invite} = UserInviteToken.create_invite()
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token})
assert json_response_and_validate_schema(conn, 200) == %{
"expires_at" => nil,
"id" => invite.id,
"invite_type" => "one_time",
"max_use" => nil,
"token" => invite.token,
"used" => true,
"uses" => 0
}
end
test "with invalid token", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"})
assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
end
end
end

View file

@ -0,0 +1,145 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.MediaProxyCacheControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
import Mock
alias Pleroma.Web.MediaProxy
setup do: clear_config([:media_proxy])
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
Config.put([:media_proxy, :enabled], true)
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], MediaProxy.Invalidation.Script)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "GET /api/pleroma/admin/media_proxy_caches" do
test "shows banned MediaProxy URLs", %{conn: conn} do
MediaProxy.put_in_banned_urls([
"http://localhost:4001/media/a688346.jpg",
"http://localhost:4001/media/fb1f4d.jpg"
])
MediaProxy.put_in_banned_urls("http://localhost:4001/media/gb1f44.jpg")
MediaProxy.put_in_banned_urls("http://localhost:4001/media/tb13f47.jpg")
MediaProxy.put_in_banned_urls("http://localhost:4001/media/wb1f46.jpg")
response =
conn
|> get("/api/pleroma/admin/media_proxy_caches?page_size=2")
|> json_response_and_validate_schema(200)
assert response["urls"] == [
"http://localhost:4001/media/fb1f4d.jpg",
"http://localhost:4001/media/a688346.jpg"
]
response =
conn
|> get("/api/pleroma/admin/media_proxy_caches?page_size=2&page=2")
|> json_response_and_validate_schema(200)
assert response["urls"] == [
"http://localhost:4001/media/gb1f44.jpg",
"http://localhost:4001/media/tb13f47.jpg"
]
response =
conn
|> get("/api/pleroma/admin/media_proxy_caches?page_size=2&page=3")
|> json_response_and_validate_schema(200)
assert response["urls"] == ["http://localhost:4001/media/wb1f46.jpg"]
end
end
describe "POST /api/pleroma/admin/media_proxy_caches/delete" do
test "deleted MediaProxy URLs from banned", %{conn: conn} do
MediaProxy.put_in_banned_urls([
"http://localhost:4001/media/a688346.jpg",
"http://localhost:4001/media/fb1f4d.jpg"
])
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/media_proxy_caches/delete", %{
urls: ["http://localhost:4001/media/a688346.jpg"]
})
|> json_response_and_validate_schema(200)
assert response["urls"] == ["http://localhost:4001/media/a688346.jpg"]
refute MediaProxy.in_banned_urls("http://localhost:4001/media/a688346.jpg")
assert MediaProxy.in_banned_urls("http://localhost:4001/media/fb1f4d.jpg")
end
end
describe "POST /api/pleroma/admin/media_proxy_caches/purge" do
test "perform invalidates cache of MediaProxy", %{conn: conn} do
urls = [
"http://example.com/media/a688346.jpg",
"http://example.com/media/fb1f4d.jpg"
]
with_mocks [
{MediaProxy.Invalidation.Script, [],
[
purge: fn _, _ -> {"ok", 0} end
]}
] do
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/media_proxy_caches/purge", %{urls: urls, ban: false})
|> json_response_and_validate_schema(200)
assert response["urls"] == urls
refute MediaProxy.in_banned_urls("http://example.com/media/a688346.jpg")
refute MediaProxy.in_banned_urls("http://example.com/media/fb1f4d.jpg")
end
end
test "perform invalidates cache of MediaProxy and adds url to banned", %{conn: conn} do
urls = [
"http://example.com/media/a688346.jpg",
"http://example.com/media/fb1f4d.jpg"
]
with_mocks [{MediaProxy.Invalidation.Script, [], [purge: fn _, _ -> {"ok", 0} end]}] do
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/media_proxy_caches/purge", %{
urls: urls,
ban: true
})
|> json_response_and_validate_schema(200)
assert response["urls"] == urls
assert MediaProxy.in_banned_urls("http://example.com/media/a688346.jpg")
assert MediaProxy.in_banned_urls("http://example.com/media/fb1f4d.jpg")
end
end
end
end

View file

@ -0,0 +1,220 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.OAuthAppControllerTest do
use Pleroma.Web.ConnCase, async: true
use Oban.Testing, repo: Pleroma.Repo
import Pleroma.Factory
alias Pleroma.Config
alias Pleroma.Web
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "POST /api/pleroma/admin/oauth_app" do
test "errors", %{conn: conn} do
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/oauth_app", %{})
|> json_response_and_validate_schema(400)
assert %{
"error" => "Missing field: name. Missing field: redirect_uris."
} = response
end
test "success", %{conn: conn} do
base_url = Web.base_url()
app_name = "Trusted app"
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/oauth_app", %{
name: app_name,
redirect_uris: base_url
})
|> json_response_and_validate_schema(200)
assert %{
"client_id" => _,
"client_secret" => _,
"name" => ^app_name,
"redirect_uri" => ^base_url,
"trusted" => false
} = response
end
test "with trusted", %{conn: conn} do
base_url = Web.base_url()
app_name = "Trusted app"
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/oauth_app", %{
name: app_name,
redirect_uris: base_url,
trusted: true
})
|> json_response_and_validate_schema(200)
assert %{
"client_id" => _,
"client_secret" => _,
"name" => ^app_name,
"redirect_uri" => ^base_url,
"trusted" => true
} = response
end
end
describe "GET /api/pleroma/admin/oauth_app" do
setup do
app = insert(:oauth_app)
{:ok, app: app}
end
test "list", %{conn: conn} do
response =
conn
|> get("/api/pleroma/admin/oauth_app")
|> json_response_and_validate_schema(200)
assert %{"apps" => apps, "count" => count, "page_size" => _} = response
assert length(apps) == count
end
test "with page size", %{conn: conn} do
insert(:oauth_app)
page_size = 1
response =
conn
|> get("/api/pleroma/admin/oauth_app?page_size=#{page_size}")
|> json_response_and_validate_schema(200)
assert %{"apps" => apps, "count" => _, "page_size" => ^page_size} = response
assert length(apps) == page_size
end
test "search by client name", %{conn: conn, app: app} do
response =
conn
|> get("/api/pleroma/admin/oauth_app?name=#{app.client_name}")
|> json_response_and_validate_schema(200)
assert %{"apps" => [returned], "count" => _, "page_size" => _} = response
assert returned["client_id"] == app.client_id
assert returned["name"] == app.client_name
end
test "search by client id", %{conn: conn, app: app} do
response =
conn
|> get("/api/pleroma/admin/oauth_app?client_id=#{app.client_id}")
|> json_response_and_validate_schema(200)
assert %{"apps" => [returned], "count" => _, "page_size" => _} = response
assert returned["client_id"] == app.client_id
assert returned["name"] == app.client_name
end
test "only trusted", %{conn: conn} do
app = insert(:oauth_app, trusted: true)
response =
conn
|> get("/api/pleroma/admin/oauth_app?trusted=true")
|> json_response_and_validate_schema(200)
assert %{"apps" => [returned], "count" => _, "page_size" => _} = response
assert returned["client_id"] == app.client_id
assert returned["name"] == app.client_name
end
end
describe "DELETE /api/pleroma/admin/oauth_app/:id" do
test "with id", %{conn: conn} do
app = insert(:oauth_app)
response =
conn
|> delete("/api/pleroma/admin/oauth_app/" <> to_string(app.id))
|> json_response_and_validate_schema(:no_content)
assert response == ""
end
test "with non existance id", %{conn: conn} do
response =
conn
|> delete("/api/pleroma/admin/oauth_app/0")
|> json_response_and_validate_schema(:bad_request)
assert response == ""
end
end
describe "PATCH /api/pleroma/admin/oauth_app/:id" do
test "with id", %{conn: conn} do
app = insert(:oauth_app)
name = "another name"
url = "https://example.com"
scopes = ["admin"]
id = app.id
website = "http://website.com"
response =
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/oauth_app/#{id}", %{
name: name,
trusted: true,
redirect_uris: url,
scopes: scopes,
website: website
})
|> json_response_and_validate_schema(200)
assert %{
"client_id" => _,
"client_secret" => _,
"id" => ^id,
"name" => ^name,
"redirect_uri" => ^url,
"trusted" => true,
"website" => ^website
} = response
end
test "without id", %{conn: conn} do
response =
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/oauth_app/0")
|> json_response_and_validate_schema(:bad_request)
assert response == ""
end
end
end

View file

@ -0,0 +1,92 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.RelayControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.Config
alias Pleroma.ModerationLog
alias Pleroma.Repo
alias Pleroma.User
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
:ok
end
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "relays" do
test "POST /relay", %{conn: conn, admin: admin} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/relay", %{
relay_url: "http://mastodon.example.org/users/admin"
})
assert json_response_and_validate_schema(conn, 200) ==
"http://mastodon.example.org/users/admin"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
end
test "GET /relay", %{conn: conn} do
relay_user = Pleroma.Web.ActivityPub.Relay.get_actor()
["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
|> Enum.each(fn ap_id ->
{:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
User.follow(relay_user, user)
end)
conn = get(conn, "/api/pleroma/admin/relay")
assert json_response_and_validate_schema(conn, 200)["relays"] --
["mastodon.example.org", "mstdn.io"] == []
end
test "DELETE /relay", %{conn: conn, admin: admin} do
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/relay", %{
relay_url: "http://mastodon.example.org/users/admin"
})
conn =
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/pleroma/admin/relay", %{
relay_url: "http://mastodon.example.org/users/admin"
})
assert json_response_and_validate_schema(conn, 200) ==
"http://mastodon.example.org/users/admin"
[log_entry_one, log_entry_two] = Repo.all(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry_one) ==
"@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin"
assert ModerationLog.get_log_entry_message(log_entry_two) ==
"@#{admin.nickname} unfollowed relay: http://mastodon.example.org/users/admin"
end
end
end

View file

@ -0,0 +1,374 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.ModerationLog
alias Pleroma.Repo
alias Pleroma.ReportNote
alias Pleroma.Web.CommonAPI
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "GET /api/pleroma/admin/reports/:id" do
test "returns report by its id", %{conn: conn} do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id]
})
response =
conn
|> get("/api/pleroma/admin/reports/#{report_id}")
|> json_response_and_validate_schema(:ok)
assert response["id"] == report_id
end
test "returns 404 when report id is invalid", %{conn: conn} do
conn = get(conn, "/api/pleroma/admin/reports/test")
assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
end
end
describe "PATCH /api/pleroma/admin/reports" do
setup do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id]
})
{:ok, %{id: second_report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel very offended",
status_ids: [activity.id]
})
%{
id: report_id,
second_report_id: second_report_id
}
end
test "requires admin:write:reports scope", %{conn: conn, id: id, admin: admin} do
read_token = insert(:oauth_token, user: admin, scopes: ["admin:read"])
write_token = insert(:oauth_token, user: admin, scopes: ["admin:write:reports"])
response =
conn
|> assign(:token, read_token)
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [%{"state" => "resolved", "id" => id}]
})
|> json_response_and_validate_schema(403)
assert response == %{
"error" => "Insufficient permissions: admin:write:reports."
}
conn
|> assign(:token, write_token)
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [%{"state" => "resolved", "id" => id}]
})
|> json_response_and_validate_schema(:no_content)
end
test "mark report as resolved", %{conn: conn, id: id, admin: admin} do
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "resolved", "id" => id}
]
})
|> json_response_and_validate_schema(:no_content)
activity = Activity.get_by_id(id)
assert activity.data["state"] == "resolved"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated report ##{id} with 'resolved' state"
end
test "closes report", %{conn: conn, id: id, admin: admin} do
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "closed", "id" => id}
]
})
|> json_response_and_validate_schema(:no_content)
activity = Activity.get_by_id(id)
assert activity.data["state"] == "closed"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated report ##{id} with 'closed' state"
end
test "returns 400 when state is unknown", %{conn: conn, id: id} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "test", "id" => id}
]
})
assert "Unsupported state" =
hd(json_response_and_validate_schema(conn, :bad_request))["error"]
end
test "returns 404 when report is not exist", %{conn: conn} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "closed", "id" => "test"}
]
})
assert hd(json_response_and_validate_schema(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
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "resolved", "id" => id},
%{"state" => "closed", "id" => second_report_id}
]
})
|> json_response_and_validate_schema(: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
describe "GET /api/pleroma/admin/reports" do
test "returns empty response when no reports created", %{conn: conn} do
response =
conn
|> get("/api/pleroma/admin/reports")
|> json_response_and_validate_schema(:ok)
assert Enum.empty?(response["reports"])
assert response["total"] == 0
end
test "returns reports", %{conn: conn} do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id]
})
response =
conn
|> get("/api/pleroma/admin/reports")
|> json_response_and_validate_schema(:ok)
[report] = response["reports"]
assert length(response["reports"]) == 1
assert report["id"] == report_id
assert response["total"] == 1
end
test "returns reports with specified state", %{conn: conn} do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: first_report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id]
})
{:ok, %{id: second_report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I don't like this user"
})
CommonAPI.update_report_state(second_report_id, "closed")
response =
conn
|> get("/api/pleroma/admin/reports?state=open")
|> json_response_and_validate_schema(:ok)
assert [open_report] = response["reports"]
assert length(response["reports"]) == 1
assert open_report["id"] == first_report_id
assert response["total"] == 1
response =
conn
|> get("/api/pleroma/admin/reports?state=closed")
|> json_response_and_validate_schema(:ok)
assert [closed_report] = response["reports"]
assert length(response["reports"]) == 1
assert closed_report["id"] == second_report_id
assert response["total"] == 1
assert %{"total" => 0, "reports" => []} ==
conn
|> get("/api/pleroma/admin/reports?state=resolved", %{
"" => ""
})
|> json_response_and_validate_schema(:ok)
end
test "returns 403 when requested by a non-admin" do
user = insert(:user)
token = insert(:oauth_token, user: user)
conn =
build_conn()
|> assign(:user, user)
|> assign(:token, token)
|> get("/api/pleroma/admin/reports")
assert json_response(conn, :forbidden) ==
%{"error" => "User is not an admin or OAuth admin scope is not granted."}
end
test "returns 403 when requested by anonymous" do
conn = get(build_conn(), "/api/pleroma/admin/reports")
assert json_response(conn, :forbidden) == %{
"error" => "Invalid credentials."
}
end
end
describe "POST /api/pleroma/admin/reports/:id/notes" do
setup %{conn: conn, admin: admin} do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id]
})
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
content: "this is disgusting!"
})
conn
|> put_req_header("content-type", "application/json")
|> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
content: "this is disgusting2!"
})
%{
admin_id: admin.id,
report_id: report_id
}
end
test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
assert [note, _] = Repo.all(ReportNote)
assert %{
activity_id: ^report_id,
content: "this is disgusting!",
user_id: ^admin_id
} = note
end
test "it returns reports with notes", %{conn: conn, admin: admin} do
conn = get(conn, "/api/pleroma/admin/reports")
response = json_response_and_validate_schema(conn, 200)
notes = hd(response["reports"])["notes"]
[note, _] = notes
assert note["user"]["nickname"] == admin.nickname
assert note["content"] == "this is disgusting!"
assert note["created_at"]
assert response["total"] == 1
end
test "it deletes the note", %{conn: conn, report_id: report_id} do
assert ReportNote |> Repo.all() |> length() == 2
assert [note, _] = Repo.all(ReportNote)
delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}")
assert ReportNote |> Repo.all() |> length() == 1
end
end
end

View file

@ -0,0 +1,202 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.AdminAPI.StatusControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.ModerationLog
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
setup do
admin = insert(:user, is_admin: true)
token = insert(:oauth_admin_token, user: admin)
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, token)
{:ok, %{admin: admin, token: token, conn: conn}}
end
describe "GET /api/pleroma/admin/statuses/:id" do
test "not found", %{conn: conn} do
assert conn
|> get("/api/pleroma/admin/statuses/not_found")
|> json_response_and_validate_schema(:not_found)
end
test "shows activity", %{conn: conn} do
activity = insert(:note_activity)
response =
conn
|> get("/api/pleroma/admin/statuses/#{activity.id}")
|> json_response_and_validate_schema(200)
assert response["id"] == activity.id
account = response["account"]
actor = User.get_by_ap_id(activity.actor)
assert account["id"] == actor.id
assert account["nickname"] == actor.nickname
assert account["deactivated"] == actor.deactivated
assert account["confirmation_pending"] == actor.confirmation_pending
end
end
describe "PUT /api/pleroma/admin/statuses/:id" do
setup do
activity = insert(:note_activity)
%{id: activity.id}
end
test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put_req_header("content-type", "application/json")
|> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"})
|> json_response_and_validate_schema(:ok)
assert response["sensitive"]
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated status ##{id}, set sensitive: 'true'"
response =
conn
|> put_req_header("content-type", "application/json")
|> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"})
|> json_response_and_validate_schema(:ok)
refute response["sensitive"]
end
test "change visibility flag", %{conn: conn, id: id, admin: admin} do
response =
conn
|> put_req_header("content-type", "application/json")
|> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "public"})
|> json_response_and_validate_schema(:ok)
assert response["visibility"] == "public"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} updated status ##{id}, set visibility: 'public'"
response =
conn
|> put_req_header("content-type", "application/json")
|> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "private"})
|> json_response_and_validate_schema(:ok)
assert response["visibility"] == "private"
response =
conn
|> put_req_header("content-type", "application/json")
|> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "unlisted"})
|> json_response_and_validate_schema(:ok)
assert response["visibility"] == "unlisted"
end
test "returns 400 when visibility is unknown", %{conn: conn, id: id} do
conn =
conn
|> put_req_header("content-type", "application/json")
|> put("/api/pleroma/admin/statuses/#{id}", %{visibility: "test"})
assert %{"error" => "test - Invalid value for enum."} =
json_response_and_validate_schema(conn, :bad_request)
end
end
describe "DELETE /api/pleroma/admin/statuses/:id" do
setup do
activity = insert(:note_activity)
%{id: activity.id}
end
test "deletes status", %{conn: conn, id: id, admin: admin} do
conn
|> delete("/api/pleroma/admin/statuses/#{id}")
|> json_response_and_validate_schema(:ok)
refute Activity.get_by_id(id)
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} deleted status ##{id}"
end
test "returns 404 when the status does not exist", %{conn: conn} do
conn = delete(conn, "/api/pleroma/admin/statuses/test")
assert json_response_and_validate_schema(conn, :not_found) == %{"error" => "Not found"}
end
end
describe "GET /api/pleroma/admin/statuses" do
test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do
blocked = insert(:user)
user = insert(:user)
User.block(admin, blocked)
{:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"})
{:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
{:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"})
{:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:ok, _} = CommonAPI.post(blocked, %{status: ".", visibility: "public"})
response =
conn
|> get("/api/pleroma/admin/statuses")
|> json_response_and_validate_schema(200)
refute "private" in Enum.map(response, & &1["visibility"])
assert length(response) == 3
end
test "returns only local statuses with local_only on", %{conn: conn} do
user = insert(:user)
remote_user = insert(:user, local: false, nickname: "archaeme@archae.me")
insert(:note_activity, user: user, local: true)
insert(:note_activity, user: remote_user, local: false)
response =
conn
|> get("/api/pleroma/admin/statuses?local_only=true")
|> json_response_and_validate_schema(200)
assert length(response) == 1
end
test "returns private and direct statuses with godmode on", %{conn: conn, admin: admin} do
user = insert(:user)
{:ok, _} = CommonAPI.post(user, %{status: "@#{admin.nickname}", visibility: "direct"})
{:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "private"})
{:ok, _} = CommonAPI.post(user, %{status: ".", visibility: "public"})
conn = get(conn, "/api/pleroma/admin/statuses?godmode=true")
assert json_response_and_validate_schema(conn, 200) |> length() == 3
end
end
end

View file

@ -28,7 +28,7 @@ defmodule Pleroma.Web.ApiSpec.SchemaExamplesTest do
end
end
for {status, response} <- operation.responses do
for {status, response} <- operation.responses, is_map(response.content[@content_type]) do
describe "#{operation.operationId} - #{status} Response" do
@schema resolve_schema(response.content[@content_type].schema)

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do
@ -15,11 +15,16 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do
{:ok, [user: user, name: name, password: password]}
end
test "get_user/authorization", %{user: user, name: name, password: password} do
test "get_user/authorization", %{name: name, password: password} do
name = name <> "1"
user = insert(:user, nickname: name, password_hash: Bcrypt.hash_pwd_salt(password))
params = %{"authorization" => %{"name" => name, "password" => password}}
res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
assert {:ok, user} == res
assert {:ok, returned_user} = res
assert returned_user.id == user.id
assert "$pbkdf2" <> _ = returned_user.password_hash
end
test "get_user/authorization with invalid password", %{name: name} do

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.TOTPAuthenticatorTest do

View file

@ -5,7 +5,9 @@
defmodule Pleroma.Web.CommonAPITest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Conversation.Participation
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
@ -23,6 +25,196 @@ defmodule Pleroma.Web.CommonAPITest do
setup do: clear_config([:instance, :limit])
setup do: clear_config([:instance, :max_pinned_statuses])
describe "blocking" do
setup do
blocker = insert(:user)
blocked = insert(:user)
User.follow(blocker, blocked)
User.follow(blocked, blocker)
%{blocker: blocker, blocked: blocked}
end
test "it blocks and federates", %{blocker: blocker, blocked: blocked} do
clear_config([:instance, :federating], true)
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
assert {:ok, block} = CommonAPI.block(blocker, blocked)
assert block.local
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
assert called(Pleroma.Web.Federator.publish(block))
end
end
test "it blocks and does not federate if outgoing blocks are disabled", %{
blocker: blocker,
blocked: blocked
} do
clear_config([:instance, :federating], true)
clear_config([:activitypub, :outgoing_blocks], false)
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
assert {:ok, block} = CommonAPI.block(blocker, blocked)
assert block.local
assert User.blocks?(blocker, blocked)
refute User.following?(blocker, blocked)
refute User.following?(blocked, blocker)
refute called(Pleroma.Web.Federator.publish(block))
end
end
end
describe "posting chat messages" do
setup do: clear_config([:instance, :chat_limit])
test "it posts a chat message without content but with an attachment" do
author = insert(:user)
recipient = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: author.ap_id)
with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ ->
nil
end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
nil,
media_id: upload.id
)
notification =
Notification.for_user_and_activity(recipient, activity)
|> Repo.preload(:activity)
assert called(Pleroma.Web.Push.send(notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
assert called(Pleroma.Web.Streamer.stream(["user", "user:pleroma_chat"], :_))
assert activity
end
end
test "it adds html newlines" do
author = insert(:user)
recipient = insert(:user)
other_user = insert(:user)
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
"uguu\nuguuu"
)
assert other_user.ap_id not in activity.recipients
object = Object.normalize(activity, false)
assert object.data["content"] == "uguu<br/>uguuu"
end
test "it linkifies" do
author = insert(:user)
recipient = insert(:user)
other_user = insert(:user)
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
"https://example.org is the site of @#{other_user.nickname} #2hu"
)
assert other_user.ap_id not in activity.recipients
object = Object.normalize(activity, false)
assert object.data["content"] ==
"<a href=\"https://example.org\" rel=\"ugc\">https://example.org</a> is the site of <span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{
other_user.id
}\" href=\"#{other_user.ap_id}\" rel=\"ugc\">@<span>#{other_user.nickname}</span></a></span> <a class=\"hashtag\" data-tag=\"2hu\" href=\"http://localhost:4001/tag/2hu\">#2hu</a>"
end
test "it posts a chat message" do
author = insert(:user)
recipient = insert(:user)
{:ok, activity} =
CommonAPI.post_chat_message(
author,
recipient,
"a test message <script>alert('uuu')</script> :firefox:"
)
assert activity.data["type"] == "Create"
assert activity.local
object = Object.normalize(activity)
assert object.data["type"] == "ChatMessage"
assert object.data["to"] == [recipient.ap_id]
assert object.data["content"] ==
"a test message &lt;script&gt;alert(&#39;uuu&#39;)&lt;/script&gt; :firefox:"
assert object.data["emoji"] == %{
"firefox" => "http://localhost:4001/emoji/Firefox.gif"
}
assert Chat.get(author.id, recipient.ap_id)
assert Chat.get(recipient.id, author.ap_id)
assert :ok == Pleroma.Web.Federator.perform(:publish, activity)
end
test "it reject messages over the local limit" do
Pleroma.Config.put([:instance, :chat_limit], 2)
author = insert(:user)
recipient = insert(:user)
{:error, message} =
CommonAPI.post_chat_message(
author,
recipient,
"123"
)
assert message == :content_too_long
end
end
describe "unblocking" do
test "it works even without an existing block activity" do
blocked = insert(:user)
@ -41,6 +233,8 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
clear_config([:instance, :federating], true)
Object.normalize(post, false)
|> Object.prune()
@ -59,6 +253,8 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
clear_config([:instance, :federating], true)
with_mock Pleroma.Web.Federator,
publish: fn _ -> nil end do
assert {:ok, delete} = CommonAPI.delete(post.id, user)
@ -335,6 +531,32 @@ defmodule Pleroma.Web.CommonAPITest do
end)
end
test "replying with a direct message will NOT auto-add the author of the reply to the recipient list" do
user = insert(:user)
other_user = insert(:user)
third_user = insert(:user)
{:ok, post} = CommonAPI.post(user, %{status: "I'm stupid"})
{:ok, open_answer} =
CommonAPI.post(other_user, %{status: "No ur smart", in_reply_to_status_id: post.id})
# The OP is implicitly added
assert user.ap_id in open_answer.recipients
{:ok, secret_answer} =
CommonAPI.post(other_user, %{
status: "lol, that guy really is stupid, right, @#{third_user.nickname}?",
in_reply_to_status_id: post.id,
visibility: "direct"
})
assert third_user.ap_id in secret_answer.recipients
# The OP is not added
refute user.ap_id in secret_answer.recipients
end
test "it allows to address a list" do
user = insert(:user)
{:ok, list} = Pleroma.List.create("foo", user)
@ -416,7 +638,8 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
{:ok, %Activity{}, _} = CommonAPI.repeat(activity.id, user)
{:ok, %Activity{} = announce_activity} = CommonAPI.repeat(activity.id, user)
assert Visibility.is_public?(announce_activity)
end
test "can't repeat a repeat" do
@ -424,9 +647,9 @@ defmodule Pleroma.Web.CommonAPITest do
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
{:ok, %Activity{} = announce, _} = CommonAPI.repeat(activity.id, other_user)
{:ok, %Activity{} = announce} = CommonAPI.repeat(activity.id, other_user)
refute match?({:ok, %Activity{}, _}, CommonAPI.repeat(announce.id, user))
refute match?({:ok, %Activity{}}, CommonAPI.repeat(announce.id, user))
end
test "repeating a status privately" do
@ -435,10 +658,11 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
{:ok, %Activity{} = announce_activity, _} =
{:ok, %Activity{} = announce_activity} =
CommonAPI.repeat(activity.id, user, %{visibility: "private"})
assert Visibility.is_private?(announce_activity)
refute Visibility.visible_for_user?(announce_activity, nil)
end
test "favoriting a status" do
@ -458,8 +682,8 @@ defmodule Pleroma.Web.CommonAPITest do
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{status: "cofe"})
{:ok, %Activity{} = announce, object} = CommonAPI.repeat(activity.id, user)
{:ok, ^announce, ^object} = CommonAPI.repeat(activity.id, user)
{:ok, %Activity{} = announce} = CommonAPI.repeat(activity.id, user)
{:ok, ^announce} = CommonAPI.repeat(activity.id, user)
end
test "favoriting a status twice returns ok, but without the like activity" do
@ -841,10 +1065,10 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 1",
"album" => "lain radio",
"artist" => "lain",
"length" => 180_000
title: "lain radio episode 1",
album: "lain radio",
artist: "lain",
length: 180_000
})
object = Object.normalize(activity)
@ -859,11 +1083,11 @@ defmodule Pleroma.Web.CommonAPITest do
{:ok, activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 1",
"album" => "lain radio",
"artist" => "lain",
"length" => 180_000,
"visibility" => "private"
title: "lain radio episode 1",
album: "lain radio",
artist: "lain",
length: 180_000,
visibility: "private"
})
object = Object.normalize(activity)

View file

@ -14,18 +14,41 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
@public_address "https://www.w3.org/ns/activitystreams#Public"
test "it adds attachment links to a given text and attachment set" do
name =
"Sakura%20Mana%20%E2%80%93%20Turned%20on%20by%20a%20Senior%20OL%20with%20a%20Temptating%20Tight%20Skirt-s%20Full%20Hipline%20and%20Panty%20Shot-%20Beautiful%20Thick%20Thighs-%20and%20Erotic%20Ass-%20-2015-%20--%20Oppaitime%208-28-2017%206-50-33%20PM.png"
describe "add_attachments/2" do
setup do
name =
"Sakura Mana Turned on by a Senior OL with a Temptating Tight Skirt-s Full Hipline and Panty Shot- Beautiful Thick Thighs- and Erotic Ass- -2015- -- Oppaitime 8-28-2017 6-50-33 PM.png"
attachment = %{
"url" => [%{"href" => name}]
}
attachment = %{
"url" => [%{"href" => URI.encode(name)}]
}
res = Utils.add_attachments("", [attachment])
%{name: name, attachment: attachment}
end
assert res ==
"<br><a href=\"#{name}\" class='attachment'>Sakura Mana Turned on by a Se…</a>"
test "it adds attachment links to a given text and attachment set", %{
name: name,
attachment: attachment
} do
len = 10
clear_config([Pleroma.Upload, :filename_display_max_length], len)
expected =
"<br><a href=\"#{URI.encode(name)}\" class='attachment'>#{String.slice(name, 0..len)}…</a>"
assert Utils.add_attachments("", [attachment]) == expected
end
test "doesn't truncate file name if config for truncate is set to 0", %{
name: name,
attachment: attachment
} do
clear_config([Pleroma.Upload, :filename_display_max_length], 0)
expected = "<br><a href=\"#{URI.encode(name)}\" class='attachment'>#{name}</a>"
assert Utils.add_attachments("", [attachment]) == expected
end
end
describe "it confirms the password given is the current users password" do
@ -297,11 +320,10 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil)
assert length(to) == 3
assert length(to) == 2
assert Enum.empty?(cc)
assert mentioned_user.ap_id in to
assert third_user.ap_id in to
assert user.follower_address in to
end
@ -327,6 +349,15 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
{to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil)
assert length(to) == 1
assert Enum.empty?(cc)
assert mentioned_user.ap_id in to
{:ok, direct_activity} = CommonAPI.post(third_user, %{status: "uguu", visibility: "direct"})
{to, cc} = Utils.get_to_and_cc(user, mentions, direct_activity, "direct", nil)
assert length(to) == 2
assert Enum.empty?(cc)

View file

@ -6,22 +6,56 @@ defmodule Pleroma.Web.FallbackTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
test "GET /registration/:token", %{conn: conn} do
assert conn
|> get("/registration/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
describe "neither preloaded data nor metadata attached to" do
test "GET /registration/:token", %{conn: conn} do
response = get(conn, "/registration/foo")
assert html_response(response, 200) =~ "<!--server-generated-meta-->"
end
test "GET /*path", %{conn: conn} do
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
end
end
test "GET /:maybe_nickname_or_id", %{conn: conn} do
user = insert(:user)
describe "preloaded data and metadata attached to" do
test "GET /:maybe_nickname_or_id", %{conn: conn} do
user = insert(:user)
user_missing = get(conn, "/foo")
user_present = get(conn, "/#{user.nickname}")
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
assert(html_response(user_missing, 200) =~ "<!--server-generated-meta-->")
refute html_response(user_present, 200) =~ "<!--server-generated-meta-->"
assert html_response(user_present, 200) =~ "initial-results"
end
refute conn
|> get("/" <> user.nickname)
|> html_response(200) =~ "<!--server-generated-meta-->"
test "GET /*path", %{conn: conn} do
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
refute conn
|> get("/foo/bar")
|> html_response(200) =~ "<!--server-generated-meta-->"
end
end
describe "preloaded data is attached to" do
test "GET /main/public", %{conn: conn} do
public_page = get(conn, "/main/public")
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
assert html_response(public_page, 200) =~ "initial-results"
end
test "GET /main/all", %{conn: conn} do
public_page = get(conn, "/main/all")
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
assert html_response(public_page, 200) =~ "initial-results"
end
end
test "GET /api*path", %{conn: conn} do
@ -34,16 +68,6 @@ defmodule Pleroma.Web.FallbackTest do
assert redirected_to(get(conn, "/pleroma/admin")) =~ "/pleroma/admin/"
end
test "GET /*path", %{conn: conn} do
assert conn
|> get("/foo")
|> html_response(200) =~ "<!--server-generated-meta-->"
assert conn
|> get("/foo/bar")
|> html_response(200) =~ "<!--server-generated-meta-->"
end
test "OPTIONS /*path", %{conn: conn} do
assert conn
|> options("/foo")

View file

@ -23,7 +23,7 @@ defmodule Pleroma.Web.FederatorTest do
setup_all do: clear_config([:instance, :federating], true)
setup do: clear_config([:instance, :allow_relay])
setup do: clear_config([:instance, :rewrite_policy])
setup do: clear_config([:mrf, :policies])
setup do: clear_config([:mrf_keyword])
describe "Publish an activity" do
@ -158,7 +158,7 @@ defmodule Pleroma.Web.FederatorTest do
Pleroma.Config.put([:mrf_keyword, :reject], ["lain"])
Pleroma.Config.put(
[:instance, :rewrite_policy],
[:mrf, :policies],
Pleroma.Web.ActivityPub.MRF.KeywordPolicy
)

View file

@ -11,13 +11,14 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
alias Pleroma.Config
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.CommonAPI
setup do: clear_config([:instance, :federating], true)
describe "feed" do
setup do: clear_config([:feed])
test "gets a feed", %{conn: conn} do
test "gets an atom feed", %{conn: conn} do
Config.put(
[:feed, :post_title],
%{max_length: 10, omission: "..."}
@ -157,6 +158,29 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
assert response(conn, 404)
end
test "returns feed with public and unlisted activities", %{conn: conn} do
user = insert(:user)
{:ok, _} = CommonAPI.post(user, %{status: "public", visibility: "public"})
{:ok, _} = CommonAPI.post(user, %{status: "direct", visibility: "direct"})
{:ok, _} = CommonAPI.post(user, %{status: "unlisted", visibility: "unlisted"})
{:ok, _} = CommonAPI.post(user, %{status: "private", visibility: "private"})
resp =
conn
|> put_req_header("accept", "application/atom+xml")
|> get(user_feed_path(conn, :feed, user.nickname))
|> response(200)
activity_titles =
resp
|> SweetXml.parse()
|> SweetXml.xpath(~x"//entry/title/text()"l)
|> Enum.sort()
assert activity_titles == ['public', 'unlisted']
end
end
# Note: see ActivityPubControllerTest for JSON format tests

View file

@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
use Pleroma.Web.ConnCase
import Mock
import Pleroma.Factory
setup do: clear_config([:instance, :max_account_fields])
@ -52,33 +53,39 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
user = Repo.get(User, user_data["id"])
res_conn =
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{
"pleroma_settings_store" => %{
masto_fe: %{
theme: "blub"
clear_config([:instance, :federating], true)
with_mock Pleroma.Web.Federator,
publish: fn _activity -> :ok end do
res_conn =
conn
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{
"pleroma_settings_store" => %{
masto_fe: %{
theme: "blub"
}
}
}
})
})
assert user_data = json_response_and_validate_schema(res_conn, 200)
assert user_data = json_response_and_validate_schema(res_conn, 200)
assert user_data["pleroma"]["settings_store"] ==
%{
"pleroma_fe" => %{"theme" => "bla"},
"masto_fe" => %{"theme" => "blub"}
}
assert user_data["pleroma"]["settings_store"] ==
%{
"pleroma_fe" => %{"theme" => "bla"},
"masto_fe" => %{"theme" => "blub"}
}
assert_called(Pleroma.Web.Federator.publish(:_))
end
end
test "updates the user's bio", %{conn: conn} do
user2 = insert(:user)
conn =
patch(conn, "/api/v1/accounts/update_credentials", %{
"note" => "I drink #cofe with @#{user2.nickname}\n\nsuya.."
})
raw_bio = "I drink #cofe with @#{user2.nickname}\n\nsuya.."
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
assert user_data = json_response_and_validate_schema(conn, 200)
@ -86,6 +93,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a class="u-url mention" data-user="#{
user2.id
}" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span><br/><br/>suya..)
assert user_data["source"]["note"] == raw_bio
user = Repo.get(User, user_data["id"])
assert user.raw_bio == raw_bio
end
test "updates the user's locking status", %{conn: conn} do
@ -112,6 +125,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
assert user_data["source"]["privacy"] == "unlisted"
end
test "updates the user's privacy", %{conn: conn} do
conn = patch(conn, "/api/v1/accounts/update_credentials", %{source: %{privacy: "unlisted"}})
assert user_data = json_response_and_validate_schema(conn, 200)
assert user_data["source"]["privacy"] == "unlisted"
end
test "updates the user's hide_followers status", %{conn: conn} do
conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"})
@ -196,10 +216,20 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
filename: "an_image.jpg"
}
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
assert user_response = json_response_and_validate_schema(conn, 200)
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["avatar"] != User.avatar_url(user)
# Also removes it
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => nil})
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["avatar"] == User.avatar_url(user)
end
test "updates the user's banner", %{user: user, conn: conn} do
@ -209,10 +239,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
filename: "an_image.jpg"
}
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
assert user_response = json_response_and_validate_schema(conn, 200)
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["header"] != User.banner_url(user)
# Also removes it
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{"header" => nil})
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["header"] == User.banner_url(user)
end
test "updates the user's background", %{conn: conn} do
@ -222,13 +263,25 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
filename: "an_image.jpg"
}
conn =
patch(conn, "/api/v1/accounts/update_credentials", %{
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{
"pleroma_background_image" => new_header
})
assert user_response = json_response_and_validate_schema(conn, 200)
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["pleroma"]["background_image"]
# Also removes it
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{
"pleroma_background_image" => nil
})
assert user_response = json_response_and_validate_schema(res, 200)
refute user_response["pleroma"]["background_image"]
end
test "requires 'write:accounts' permission" do
@ -380,4 +433,71 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do
|> json_response_and_validate_schema(403)
end
end
describe "Mark account as bot" do
setup do: oauth_access(["write:accounts"])
setup :request_content_type
test "changing actor_type to Service makes account a bot", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Service"})
|> json_response_and_validate_schema(200)
assert account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Service"
end
test "changing actor_type to Person makes account a human", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Person"})
|> json_response_and_validate_schema(200)
refute account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
test "changing actor_type to Application causes error", %{conn: conn} do
response =
conn
|> patch("/api/v1/accounts/update_credentials", %{actor_type: "Application"})
|> json_response_and_validate_schema(403)
assert %{"error" => "Invalid request"} == response
end
test "changing bot field to true changes actor_type to Service", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{bot: "true"})
|> json_response_and_validate_schema(200)
assert account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Service"
end
test "changing bot field to false changes actor_type to Person", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{bot: "false"})
|> json_response_and_validate_schema(200)
refute account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
test "actor_type field has a higher priority than bot", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{
actor_type: "Person",
bot: "true"
})
|> json_response_and_validate_schema(200)
refute account["bot"]
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
end
end

View file

@ -127,6 +127,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> get("/api/v1/accounts/internal.fetch")
|> json_response_and_validate_schema(404)
end
test "returns 404 for deactivated user", %{conn: conn} do
user = insert(:user, deactivated: true)
assert %{"error" => "Can't find user"} =
conn
|> get("/api/v1/accounts/#{user.id}")
|> json_response_and_validate_schema(:not_found)
end
end
defp local_and_remote_users do
@ -143,15 +152,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@ -173,8 +182,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
res_conn = get(conn, "/api/v1/accounts/#{local.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Can't find user"
assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
"error" => "This API requires an authenticated user"
}
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
@ -203,8 +212,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
res_conn = get(conn, "/api/v1/accounts/#{remote.id}")
assert json_response_and_validate_schema(res_conn, :not_found) == %{
"error" => "Can't find user"
assert json_response_and_validate_schema(res_conn, :unauthorized) == %{
"error" => "This API requires an authenticated user"
}
end
@ -249,6 +258,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert id == announce.id
end
test "deactivated user", %{conn: conn} do
user = insert(:user, deactivated: true)
assert %{"error" => "Can't find user"} ==
conn
|> get("/api/v1/accounts/#{user.id}/statuses")
|> json_response_and_validate_schema(:not_found)
end
test "returns 404 when user is invisible", %{conn: conn} do
user = insert(:user, %{invisible: true})
assert %{"error" => "Can't find user"} =
conn
|> get("/api/v1/accounts/#{user.id}")
|> json_response_and_validate_schema(404)
end
test "respects blocks", %{user: user_one, conn: conn} do
user_two = insert(:user)
user_three = insert(:user)
@ -256,7 +283,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
User.block(user_one, user_two)
{:ok, activity} = CommonAPI.post(user_two, %{status: "User one sux0rz"})
{:ok, repeat, _} = CommonAPI.repeat(activity.id, user_three)
{:ok, repeat} = CommonAPI.repeat(activity.id, user_three)
assert resp =
conn
@ -350,9 +377,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert json_response_and_validate_schema(conn, 200) == []
end
test "gets an users media", %{conn: conn} do
test "gets an users media, excludes reblogs", %{conn: conn} do
note = insert(:note_activity)
user = User.get_cached_by_ap_id(note.data["actor"])
other_user = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
@ -364,6 +392,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
{:ok, %{id: image_post_id}} = CommonAPI.post(user, %{status: "cofe", media_ids: [media_id]})
{:ok, %{id: media_id}} = ActivityPub.upload(file, actor: other_user.ap_id)
{:ok, %{id: other_image_post_id}} =
CommonAPI.post(other_user, %{status: "cofe2", media_ids: [media_id]})
{:ok, _announce} = CommonAPI.repeat(other_image_post_id, user)
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?only_media=true")
assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200)
@ -375,7 +410,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
test "gets a user's statuses without reblogs", %{user: user, conn: conn} do
{:ok, %{id: post_id}} = CommonAPI.post(user, %{status: "HI!!!"})
{:ok, _, _} = CommonAPI.repeat(post_id, user)
{:ok, _} = CommonAPI.repeat(post_id, user)
conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=true")
assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200)
@ -422,15 +457,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@ -451,10 +486,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true)
test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{local.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
@ -481,10 +516,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
assert %{"error" => "Can't find user"} ==
assert %{"error" => "This API requires an authenticated user"} ==
conn
|> get("/api/v1/accounts/#{remote.id}/statuses")
|> json_response_and_validate_schema(:not_found)
|> json_response_and_validate_schema(:unauthorized)
end
test "if user is authenticated", %{local: local, remote: remote} do
@ -678,7 +713,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert %{"showing_reblogs" => false} = json_response_and_validate_schema(ret_conn, 200)
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
{:ok, %{id: reblog_id}, _} = CommonAPI.repeat(activity.id, followed)
{:ok, %{id: reblog_id}} = CommonAPI.repeat(activity.id, followed)
assert [] ==
conn

View file

@ -12,84 +12,88 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
setup do: oauth_access(["read:statuses"])
test "returns a list of conversations", %{user: user_one, conn: conn} do
user_two = insert(:user)
user_three = insert(:user)
describe "returns a list of conversations" do
setup(%{user: user_one, conn: conn}) do
user_two = insert(:user)
user_three = insert(:user)
{:ok, user_two} = User.follow(user_two, user_one)
{:ok, user_two} = User.follow(user_two, user_one)
assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
{:ok, %{user: user_one, user_two: user_two, user_three: user_three, conn: conn}}
end
{:ok, direct} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
visibility: "direct"
})
test "returns correct conversations", %{
user: user_one,
user_two: user_two,
user_three: user_three,
conn: conn
} do
assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
{:ok, direct} = create_direct_message(user_one, [user_two, user_three])
assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
{:ok, _follower_only} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}!",
visibility: "private"
})
{:ok, _follower_only} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}!",
visibility: "private"
})
res_conn = get(conn, "/api/v1/conversations")
res_conn = get(conn, "/api/v1/conversations")
assert response = json_response_and_validate_schema(res_conn, 200)
assert response = json_response_and_validate_schema(res_conn, 200)
assert [
%{
"id" => res_id,
"accounts" => res_accounts,
"last_status" => res_last_status,
"unread" => unread
}
] = response
assert [
%{
"id" => res_id,
"accounts" => res_accounts,
"last_status" => res_last_status,
"unread" => unread
}
] = response
account_ids = Enum.map(res_accounts, & &1["id"])
assert length(res_accounts) == 2
assert user_two.id in account_ids
assert user_three.id in account_ids
assert is_binary(res_id)
assert unread == false
assert res_last_status["id"] == direct.id
assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
account_ids = Enum.map(res_accounts, & &1["id"])
assert length(res_accounts) == 2
assert user_two.id in account_ids
assert user_three.id in account_ids
assert is_binary(res_id)
assert unread == false
assert res_last_status["id"] == direct.id
assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
end
test "observes limit params", %{
user: user_one,
user_two: user_two,
user_three: user_three,
conn: conn
} do
{:ok, _} = create_direct_message(user_one, [user_two, user_three])
{:ok, _} = create_direct_message(user_two, [user_one, user_three])
{:ok, _} = create_direct_message(user_three, [user_two, user_one])
res_conn = get(conn, "/api/v1/conversations?limit=1")
assert response = json_response_and_validate_schema(res_conn, 200)
assert Enum.count(response) == 1
res_conn = get(conn, "/api/v1/conversations?limit=2")
assert response = json_response_and_validate_schema(res_conn, 200)
assert Enum.count(response) == 2
end
end
test "filters conversations by recipients", %{user: user_one, conn: conn} do
user_two = insert(:user)
user_three = insert(:user)
{:ok, direct1} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}!",
visibility: "direct"
})
{:ok, _direct2} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_three.nickname}!",
visibility: "direct"
})
{:ok, direct3} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
visibility: "direct"
})
{:ok, _direct4} =
CommonAPI.post(user_two, %{
status: "Hi @#{user_three.nickname}!",
visibility: "direct"
})
{:ok, direct5} =
CommonAPI.post(user_two, %{
status: "Hi @#{user_one.nickname}!",
visibility: "direct"
})
{:ok, direct1} = create_direct_message(user_one, [user_two])
{:ok, _direct2} = create_direct_message(user_one, [user_three])
{:ok, direct3} = create_direct_message(user_one, [user_two, user_three])
{:ok, _direct4} = create_direct_message(user_two, [user_three])
{:ok, direct5} = create_direct_message(user_two, [user_one])
assert [conversation1, conversation2] =
conn
@ -109,12 +113,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
test "updates the last_status on reply", %{user: user_one, conn: conn} do
user_two = insert(:user)
{:ok, direct} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}",
visibility: "direct"
})
{:ok, direct} = create_direct_message(user_one, [user_two])
{:ok, direct_reply} =
CommonAPI.post(user_two, %{
@ -133,12 +132,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
test "the user marks a conversation as read", %{user: user_one, conn: conn} do
user_two = insert(:user)
{:ok, direct} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}",
visibility: "direct"
})
{:ok, direct} = create_direct_message(user_one, [user_two])
assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
@ -194,15 +188,22 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
user_two = insert(:user)
{:ok, direct} =
CommonAPI.post(user_one, %{
status: "Hi @#{user_two.nickname}!",
visibility: "direct"
})
{:ok, direct} = create_direct_message(user_one, [user_two])
res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
end
defp create_direct_message(sender, recips) do
hellos =
recips
|> Enum.map(fn s -> "@#{s.nickname}" end)
|> Enum.join(", ")
CommonAPI.post(sender, %{
status: "Hi #{hellos}!",
visibility: "direct"
})
end
end

View file

@ -31,7 +31,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
"upload_limit" => _,
"avatar_upload_limit" => _,
"background_upload_limit" => _,
"banner_upload_limit" => _
"banner_upload_limit" => _,
"background_image" => _
} = result
assert result["pleroma"]["metadata"]["features"]

View file

@ -9,9 +9,9 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
setup do: oauth_access(["write:media"])
describe "Upload media" do
setup do: oauth_access(["write:media"])
describe "media upload" do
setup do
image = %Plug.Upload{
content_type: "image/jpg",
@ -25,13 +25,14 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
setup do: clear_config([:media_proxy])
setup do: clear_config([Pleroma.Upload])
test "returns uploaded image", %{conn: conn, image: image} do
test "/api/v1/media", %{conn: conn, image: image} do
desc = "Description of the image"
media =
conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/v1/media", %{"file" => image, "description" => desc})
|> json_response(:ok)
|> json_response_and_validate_schema(:ok)
assert media["type"] == "image"
assert media["description"] == desc
@ -40,9 +41,37 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
object = Object.get_by_id(media["id"])
assert object.data["actor"] == User.ap_id(conn.assigns[:user])
end
test "/api/v2/media", %{conn: conn, user: user, image: image} do
desc = "Description of the image"
response =
conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/v2/media", %{"file" => image, "description" => desc})
|> json_response_and_validate_schema(202)
assert media_id = response["id"]
%{conn: conn} = oauth_access(["read:media"], user: user)
media =
conn
|> get("/api/v1/media/#{media_id}")
|> json_response_and_validate_schema(200)
assert media["type"] == "image"
assert media["description"] == desc
assert media["id"]
object = Object.get_by_id(media["id"])
assert object.data["actor"] == user.ap_id
end
end
describe "PUT /api/v1/media/:id" do
describe "Update media description" do
setup do: oauth_access(["write:media"])
setup %{user: actor} do
file = %Plug.Upload{
content_type: "image/jpg",
@ -60,23 +89,58 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
[object: object]
end
test "updates name of media", %{conn: conn, object: object} do
test "/api/v1/media/:id good request", %{conn: conn, object: object} do
media =
conn
|> put_req_header("content-type", "multipart/form-data")
|> put("/api/v1/media/#{object.id}", %{"description" => "test-media"})
|> json_response(:ok)
|> json_response_and_validate_schema(:ok)
assert media["description"] == "test-media"
assert refresh_record(object).data["name"] == "test-media"
end
end
test "returns error when request is bad", %{conn: conn, object: object} do
describe "Get media by id (/api/v1/media/:id)" do
setup do: oauth_access(["read:media"])
setup %{user: actor} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, %Object{} = object} =
ActivityPub.upload(
file,
actor: User.ap_id(actor),
description: "test-media"
)
[object: object]
end
test "it returns media object when requested by owner", %{conn: conn, object: object} do
media =
conn
|> put("/api/v1/media/#{object.id}", %{})
|> json_response(400)
|> get("/api/v1/media/#{object.id}")
|> json_response_and_validate_schema(:ok)
assert media == %{"error" => "bad_request"}
assert media["description"] == "test-media"
assert media["type"] == "image"
assert media["id"]
end
test "it returns 403 if media object requested by non-owner", %{object: object, user: user} do
%{conn: conn, user: other_user} = oauth_access(["read:media"])
assert object.data["actor"] == user.ap_id
refute user.id == other_user.id
conn
|> get("/api/v1/media/#{object.id}")
|> json_response(403)
end
end
end

View file

@ -12,9 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
import Pleroma.Factory
test "does NOT render account/pleroma/relationship if this is disabled by default" do
clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
test "does NOT render account/pleroma/relationship by default" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
@ -56,6 +54,27 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert response == expected_response
end
test "by default, does not contain pleroma:chat_mention" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
{:ok, _activity} = CommonAPI.post_chat_message(other_user, user, "hey")
result =
conn
|> get("/api/v1/notifications")
|> json_response_and_validate_schema(200)
assert [] == result
result =
conn
|> get("/api/v1/notifications?include_types[]=pleroma:chat_mention")
|> json_response_and_validate_schema(200)
assert [_] = result
end
test "getting a single notification" do
%{user: user, conn: conn} = oauth_access(["read:notifications"])
other_user = insert(:user)
@ -282,8 +301,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, unlisted_activity} =
CommonAPI.post(other_user, %{status: ".", visibility: "unlisted"})
{:ok, _, _} = CommonAPI.repeat(public_activity.id, user)
{:ok, _, _} = CommonAPI.repeat(unlisted_activity.id, user)
{:ok, _} = CommonAPI.repeat(public_activity.id, user)
{:ok, _} = CommonAPI.repeat(unlisted_activity.id, user)
activity_ids =
conn
@ -294,6 +313,33 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
assert public_activity.id in activity_ids
refute unlisted_activity.id in activity_ids
end
test "doesn't return less than the requested amount of records when the user's reply is liked" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["read:notifications"])
{:ok, mention} =
CommonAPI.post(user, %{status: "@#{other_user.nickname}", visibility: "public"})
{:ok, activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:ok, reply} =
CommonAPI.post(other_user, %{
status: ".",
visibility: "public",
in_reply_to_status_id: activity.id
})
{:ok, _favorite} = CommonAPI.favorite(user, reply.id)
activity_ids =
conn
|> get("/api/v1/notifications?exclude_visibilities[]=direct&limit=2")
|> json_response_and_validate_schema(200)
|> Enum.map(& &1["status"]["id"])
assert [reply.id, mention.id] == activity_ids
end
end
test "filters notifications using exclude_types" do
@ -303,7 +349,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id)
{:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
{:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, other_user)
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
mention_notification_id = get_notification_id_by_activity(mention_activity)
@ -341,7 +387,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
{:ok, mention_activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, favorite_activity} = CommonAPI.favorite(other_user, create_activity.id)
{:ok, reblog_activity, _} = CommonAPI.repeat(create_activity.id, other_user)
{:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, other_user)
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
mention_notification_id = get_notification_id_by_activity(mention_activity)

View file

@ -71,10 +71,102 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
get(conn, "/api/v2/search?q=天子")
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "天子", "url" => "#{Web.base_url()}/tag/天子"}
]
[status] = results["statuses"]
assert status["id"] == to_string(activity.id)
end
test "constructs hashtags from search query", %{conn: conn} do
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "some text with #explicit #hashtags"})}")
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "explicit", "url" => "#{Web.base_url()}/tag/explicit"},
%{"name" => "hashtags", "url" => "#{Web.base_url()}/tag/hashtags"}
]
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "john doe JOHN DOE"})}")
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "john", "url" => "#{Web.base_url()}/tag/john"},
%{"name" => "doe", "url" => "#{Web.base_url()}/tag/doe"},
%{"name" => "JohnDoe", "url" => "#{Web.base_url()}/tag/JohnDoe"}
]
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "accident-prone"})}")
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "accident", "url" => "#{Web.base_url()}/tag/accident"},
%{"name" => "prone", "url" => "#{Web.base_url()}/tag/prone"},
%{"name" => "AccidentProne", "url" => "#{Web.base_url()}/tag/AccidentProne"}
]
results =
conn
|> get("/api/v2/search?#{URI.encode_query(%{q: "https://shpposter.club/users/shpuld"})}")
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "shpuld", "url" => "#{Web.base_url()}/tag/shpuld"}
]
results =
conn
|> get(
"/api/v2/search?#{
URI.encode_query(%{
q:
"https://www.washingtonpost.com/sports/2020/06/10/" <>
"nascar-ban-display-confederate-flag-all-events-properties/"
})
}"
)
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "nascar", "url" => "#{Web.base_url()}/tag/nascar"},
%{"name" => "ban", "url" => "#{Web.base_url()}/tag/ban"},
%{"name" => "display", "url" => "#{Web.base_url()}/tag/display"},
%{"name" => "confederate", "url" => "#{Web.base_url()}/tag/confederate"},
%{"name" => "flag", "url" => "#{Web.base_url()}/tag/flag"},
%{"name" => "all", "url" => "#{Web.base_url()}/tag/all"},
%{"name" => "events", "url" => "#{Web.base_url()}/tag/events"},
%{"name" => "properties", "url" => "#{Web.base_url()}/tag/properties"},
%{
"name" => "NascarBanDisplayConfederateFlagAllEventsProperties",
"url" =>
"#{Web.base_url()}/tag/NascarBanDisplayConfederateFlagAllEventsProperties"
}
]
end
test "supports pagination of hashtags search results", %{conn: conn} do
results =
conn
|> get(
"/api/v2/search?#{
URI.encode_query(%{q: "#some #text #with #hashtags", limit: 2, offset: 1})
}"
)
|> json_response_and_validate_schema(200)
assert results["hashtags"] == [
%{"name" => "text", "url" => "#{Web.base_url()}/tag/text"},
%{"name" => "with", "url" => "#{Web.base_url()}/tag/with"}
]
end
test "excludes a blocked users from search results", %{conn: conn} do
user = insert(:user)
user_smith = insert(:user, %{nickname: "Agent", name: "I love 2hu"})
@ -179,7 +271,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
[account | _] = results["accounts"]
assert account["id"] == to_string(user_three.id)
assert results["hashtags"] == []
assert results["hashtags"] == ["2hu"]
[status] = results["statuses"]
assert status["id"] == to_string(activity.id)

View file

@ -62,7 +62,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> post("/api/v1/statuses", %{
"status" => "cofe",
"spoiler_text" => "2hu",
"sensitive" => "false"
"sensitive" => "0"
})
{:ok, ttl} = Cachex.ttl(:idempotency_cache, idempotency_key)
@ -81,7 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> post("/api/v1/statuses", %{
"status" => "cofe",
"spoiler_text" => "2hu",
"sensitive" => "false"
"sensitive" => 0
})
assert %{"id" => second_id} = json_response(conn_two, 200)
@ -93,7 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> post("/api/v1/statuses", %{
"status" => "cofe",
"spoiler_text" => "2hu",
"sensitive" => "false"
"sensitive" => "False"
})
assert %{"id" => third_id} = json_response_and_validate_schema(conn_three, 200)
@ -878,8 +878,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
user3 = insert(:user)
{:ok, _} = CommonAPI.favorite(user2, activity.id)
{:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id)
{:ok, reblog_activity1, _object} = CommonAPI.repeat(activity.id, user1)
{:ok, _, _object} = CommonAPI.repeat(activity.id, user2)
{:ok, reblog_activity1} = CommonAPI.repeat(activity.id, user1)
{:ok, _} = CommonAPI.repeat(activity.id, user2)
conn_res =
build_conn()
@ -917,7 +917,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "unreblogs and returns the unreblogged status", %{user: user, conn: conn} do
activity = insert(:note_activity)
{:ok, _, _} = CommonAPI.repeat(activity.id, user)
{:ok, _} = CommonAPI.repeat(activity.id, user)
conn =
conn
@ -1176,7 +1176,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "bookmarks" do
bookmarks_uri = "/api/v1/bookmarks?with_relationships=true"
bookmarks_uri = "/api/v1/bookmarks"
%{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"])
author = insert(:user)
@ -1427,7 +1427,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "returns users who have reblogged the status", %{conn: conn, activity: activity} do
other_user = insert(:user)
{:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
{:ok, _} = CommonAPI.repeat(activity.id, other_user)
response =
conn
@ -1458,7 +1458,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
other_user = insert(:user)
{:ok, _user_relationship} = User.block(user, other_user)
{:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
{:ok, _} = CommonAPI.repeat(activity.id, other_user)
response =
conn
@ -1469,12 +1469,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
test "does not return users who have reblogged the status privately", %{
conn: conn,
activity: activity
conn: conn
} do
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{status: "my secret post"})
{:ok, _, _} = CommonAPI.repeat(activity.id, other_user, %{visibility: "private"})
{:ok, _} = CommonAPI.repeat(activity.id, other_user, %{visibility: "private"})
response =
conn
@ -1486,7 +1486,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
test "does not fail on an unauthenticated request", %{activity: activity} do
other_user = insert(:user)
{:ok, _, _} = CommonAPI.repeat(activity.id, other_user)
{:ok, _} = CommonAPI.repeat(activity.id, other_user)
response =
build_conn()
@ -1541,14 +1541,49 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
} = response
end
test "favorites paginate correctly" do
%{user: user, conn: conn} = oauth_access(["read:favourites"])
other_user = insert(:user)
{:ok, first_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, second_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, third_post} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, _first_favorite} = CommonAPI.favorite(user, third_post.id)
{:ok, _second_favorite} = CommonAPI.favorite(user, first_post.id)
{:ok, third_favorite} = CommonAPI.favorite(user, second_post.id)
result =
conn
|> get("/api/v1/favourites?limit=1")
assert [%{"id" => post_id}] = json_response_and_validate_schema(result, 200)
assert post_id == second_post.id
# Using the header for pagination works correctly
[next, _] = get_resp_header(result, "link") |> hd() |> String.split(", ")
[_, max_id] = Regex.run(~r/max_id=([^&]+)/, next)
assert max_id == third_favorite.id
result =
conn
|> get("/api/v1/favourites?max_id=#{max_id}")
assert [%{"id" => first_post_id}, %{"id" => third_post_id}] =
json_response_and_validate_schema(result, 200)
assert first_post_id == first_post.id
assert third_post_id == third_post.id
end
test "returns the favorites of a user" do
%{user: user, conn: conn} = oauth_access(["read:favourites"])
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{status: "bla"})
{:ok, activity} = CommonAPI.post(other_user, %{status: "traps are happy"})
{:ok, activity} = CommonAPI.post(other_user, %{status: "trees are happy"})
{:ok, _} = CommonAPI.favorite(user, activity.id)
{:ok, last_like} = CommonAPI.favorite(user, activity.id)
first_conn = get(conn, "/api/v1/favourites")
@ -1566,9 +1601,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, _} = CommonAPI.favorite(user, second_activity.id)
last_like = status["id"]
second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like}")
second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like.id}")
assert [second_status] = json_response_and_validate_schema(second_conn, 200)
assert second_status["id"] == to_string(second_activity.id)

View file

@ -58,7 +58,9 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
result =
conn
|> post("/api/v1/push/subscription", %{
"data" => %{"alerts" => %{"mention" => true, "test" => true}},
"data" => %{
"alerts" => %{"mention" => true, "test" => true, "pleroma:chat_mention" => true}
},
"subscription" => @sub
})
|> json_response_and_validate_schema(200)
@ -66,7 +68,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do
[subscription] = Pleroma.Repo.all(Subscription)
assert %{
"alerts" => %{"mention" => true},
"alerts" => %{"mention" => true, "pleroma:chat_mention" => true},
"endpoint" => subscription.endpoint,
"id" => to_string(subscription.id),
"server_key" => @server_key

View file

@ -20,12 +20,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
describe "home" do
setup do: oauth_access(["read:statuses"])
test "does NOT render account/pleroma/relationship if this is disabled by default", %{
test "does NOT embed account/pleroma/relationship in statuses", %{
user: user,
conn: conn
} do
clear_config([:extensions, :output_relationships_in_statuses_by_default], false)
other_user = insert(:user)
{:ok, _} = CommonAPI.post(other_user, %{status: "hi @#{user.nickname}"})
@ -41,72 +39,6 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
end)
end
test "the home timeline", %{user: user, conn: conn} do
uri = "/api/v1/timelines/home?with_relationships=1"
following = insert(:user, nickname: "followed")
third_user = insert(:user, nickname: "repeated")
{:ok, _activity} = CommonAPI.post(following, %{status: "post"})
{:ok, activity} = CommonAPI.post(third_user, %{status: "repeated post"})
{:ok, _, _} = CommonAPI.repeat(activity.id, following)
ret_conn = get(conn, uri)
assert Enum.empty?(json_response_and_validate_schema(ret_conn, :ok))
{:ok, _user} = User.follow(user, following)
ret_conn = get(conn, uri)
assert [
%{
"reblog" => %{
"content" => "repeated post",
"account" => %{
"pleroma" => %{
"relationship" => %{"following" => false, "followed_by" => false}
}
}
},
"account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
},
%{
"content" => "post",
"account" => %{
"acct" => "followed",
"pleroma" => %{"relationship" => %{"following" => true}}
}
}
] = json_response_and_validate_schema(ret_conn, :ok)
{:ok, _user} = User.follow(third_user, user)
ret_conn = get(conn, uri)
assert [
%{
"reblog" => %{
"content" => "repeated post",
"account" => %{
"acct" => "repeated",
"pleroma" => %{
"relationship" => %{"following" => false, "followed_by" => true}
}
}
},
"account" => %{"pleroma" => %{"relationship" => %{"following" => true}}}
},
%{
"content" => "post",
"account" => %{
"acct" => "followed",
"pleroma" => %{"relationship" => %{"following" => true}}
}
}
] = json_response_and_validate_schema(ret_conn, :ok)
end
test "the home timeline when the direct messages are excluded", %{user: user, conn: conn} do
{:ok, public_activity} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:ok, direct_activity} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
@ -128,9 +60,9 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
describe "public" do
@tag capture_log: true
test "the public timeline", %{conn: conn} do
following = insert(:user)
user = insert(:user)
{:ok, _activity} = CommonAPI.post(following, %{status: "test"})
{:ok, activity} = CommonAPI.post(user, %{status: "test"})
_activity = insert(:note_activity, local: false)
@ -145,6 +77,13 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
conn = get(build_conn(), "/api/v1/timelines/public?local=1")
assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok)
# does not contain repeats
{:ok, _} = CommonAPI.repeat(activity.id, user)
conn = get(build_conn(), "/api/v1/timelines/public?local=true")
assert [_] = json_response_and_validate_schema(conn, :ok)
end
test "the public timeline includes only public statuses for an authenticated user" do
@ -158,6 +97,49 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
res_conn = get(conn, "/api/v1/timelines/public")
assert length(json_response_and_validate_schema(res_conn, 200)) == 1
end
test "doesn't return replies if follower is posting with blocked user" do
%{conn: conn, user: blocker} = oauth_access(["read:statuses"])
[blockee, friend] = insert_list(2, :user)
{:ok, blocker} = User.follow(blocker, friend)
{:ok, _} = User.block(blocker, blockee)
conn = assign(conn, :user, blocker)
{:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
{:ok, reply_from_blockee} =
CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
{:ok, _reply_from_friend} =
CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
res_conn = get(conn, "/api/v1/timelines/public")
[%{"id" => ^activity_id}] = json_response_and_validate_schema(res_conn, 200)
end
test "doesn't return replies if follow is posting with users from blocked domain" do
%{conn: conn, user: blocker} = oauth_access(["read:statuses"])
friend = insert(:user)
blockee = insert(:user, ap_id: "https://example.com/users/blocked")
{:ok, blocker} = User.follow(blocker, friend)
{:ok, blocker} = User.block_domain(blocker, "example.com")
conn = assign(conn, :user, blocker)
{:ok, %{id: activity_id} = activity} = CommonAPI.post(friend, %{status: "hey!"})
{:ok, reply_from_blockee} =
CommonAPI.post(blockee, %{status: "heya", in_reply_to_status_id: activity})
{:ok, _reply_from_friend} =
CommonAPI.post(friend, %{status: "status", in_reply_to_status_id: reply_from_blockee})
res_conn = get(conn, "/api/v1/timelines/public")
activities = json_response_and_validate_schema(res_conn, 200)
[%{"id" => ^activity_id}] = activities
end
end
defp local_and_remote_activities do

View file

@ -33,7 +33,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
bio:
"<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f '&<>\"",
inserted_at: ~N[2017-08-15 15:47:06.597036],
emoji: %{"karjalanpiirakka" => "/file.png"}
emoji: %{"karjalanpiirakka" => "/file.png"},
raw_bio: "valid html. a\nb\nc\nd\nf '&<>\""
})
expected = %{
@ -54,10 +55,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
header_static: "http://localhost:4001/images/banner.png",
emojis: [
%{
"static_url" => "/file.png",
"url" => "/file.png",
"shortcode" => "karjalanpiirakka",
"visible_in_picker" => false
static_url: "/file.png",
url: "/file.png",
shortcode: "karjalanpiirakka",
visible_in_picker: false
}
],
fields: [],
@ -72,6 +73,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
fields: []
},
pleroma: %{
ap_id: user.ap_id,
background_image: "https://example.com/images/asuka_hospital.png",
confirmation_pending: false,
tags: [],
@ -148,6 +150,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
fields: []
},
pleroma: %{
ap_id: user.ap_id,
background_image: nil,
confirmation_pending: false,
tags: [],
@ -302,82 +305,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
end
end
test "represent an embedded relationship" do
user =
insert(:user, %{
follower_count: 0,
note_count: 5,
actor_type: "Service",
nickname: "shp@shitposter.club",
inserted_at: ~N[2017-08-15 15:47:06.597036]
})
other_user = insert(:user)
{:ok, other_user} = User.follow(other_user, user)
{:ok, _user_relationship} = User.block(other_user, user)
{:ok, _} = User.follow(insert(:user), user)
expected = %{
id: to_string(user.id),
username: "shp",
acct: user.nickname,
display_name: user.name,
locked: false,
created_at: "2017-08-15T15:47:06.000Z",
followers_count: 1,
following_count: 0,
statuses_count: 5,
note: user.bio,
url: user.ap_id,
avatar: "http://localhost:4001/images/avi.png",
avatar_static: "http://localhost:4001/images/avi.png",
header: "http://localhost:4001/images/banner.png",
header_static: "http://localhost:4001/images/banner.png",
emojis: [],
fields: [],
bot: true,
source: %{
note: user.bio,
sensitive: false,
pleroma: %{
actor_type: "Service",
discoverable: false
},
fields: []
},
pleroma: %{
background_image: nil,
confirmation_pending: false,
tags: [],
is_admin: false,
is_moderator: false,
hide_favorites: true,
hide_followers: false,
hide_follows: false,
hide_followers_count: false,
hide_follows_count: false,
relationship: %{
id: to_string(user.id),
following: false,
followed_by: false,
blocking: true,
blocked_by: false,
subscribing: false,
muting: false,
muting_notifications: false,
requested: false,
domain_blocking: false,
showing_reblogs: true,
endorsed: false
},
skip_thread_containment: false
}
}
assert expected ==
AccountView.render("show.json", %{user: refresh_record(user), for: other_user})
end
test "returns the settings store if the requesting user is the represented user and it's requested specifically" do
user = insert(:user, pleroma_settings_store: %{fe: "test"})
@ -567,4 +494,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
AccountView.render("show.json", %{user: user, for: user})
end
end
test "uses mediaproxy urls when it's enabled" do
clear_config([:media_proxy, :enabled], true)
user =
insert(:user,
avatar: %{"url" => [%{"href" => "https://evil.website/avatar.png"}]},
banner: %{"url" => [%{"href" => "https://evil.website/banner.png"}]},
emoji: %{"joker_smile" => "https://evil.website/society.png"}
)
AccountView.render("show.json", %{user: user})
|> Enum.all?(fn
{key, url} when key in [:avatar, :avatar_static, :header, :header_static] ->
String.starts_with?(url, Pleroma.Web.base_url())
{:emojis, emojis} ->
Enum.all?(emojis, fn %{url: url, static_url: static_url} ->
String.starts_with?(url, Pleroma.Web.base_url()) &&
String.starts_with?(static_url, Pleroma.Web.base_url())
end)
_ ->
true
end)
|> assert()
end
end

View file

@ -15,8 +15,17 @@ defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do
user = insert(:user)
other_user = insert(:user)
{:ok, parent} = CommonAPI.post(user, %{status: "parent"})
{:ok, activity} =
CommonAPI.post(user, %{status: "hey @#{other_user.nickname}", visibility: "direct"})
CommonAPI.post(user, %{
status: "hey @#{other_user.nickname}",
visibility: "direct",
in_reply_to_id: parent.id
})
{:ok, _reply_activity} =
CommonAPI.post(user, %{status: "hu", visibility: "public", in_reply_to_id: parent.id})
[participation] = Participation.for_user_with_last_activity_id(user)

View file

@ -6,7 +6,10 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
@ -14,6 +17,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.NotificationView
alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
import Pleroma.Factory
defp test_notifications_rendering(notifications, user, expected_result) do
@ -31,6 +35,30 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
assert expected_result == result
end
test "ChatMessage notification" do
user = insert(:user)
recipient = insert(:user)
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "what's up my dude")
{:ok, [notification]} = Notification.create_notifications(activity)
object = Object.normalize(activity)
chat = Chat.get(recipient.id, user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false, is_muted: false},
type: "pleroma:chat_mention",
account: AccountView.render("show.json", %{user: user, for: recipient}),
chat_message: MessageReferenceView.render("show.json", %{chat_message_reference: cm_ref}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
test_notifications_rendering([notification], recipient, [expected])
end
test "Mention notification" do
user = insert(:user)
mentioned_user = insert(:user)
@ -40,9 +68,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "mention",
account: AccountView.render("show.json", %{user: user, for: mentioned_user}),
account:
AccountView.render("show.json", %{
user: user,
for: mentioned_user
}),
status: StatusView.render("show.json", %{activity: activity, for: mentioned_user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
@ -60,7 +92,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "favourite",
account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: create_activity, for: user}),
@ -74,13 +106,13 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
user = insert(:user)
another_user = insert(:user)
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user)
{:ok, reblog_activity} = CommonAPI.repeat(create_activity.id, another_user)
{:ok, [notification]} = Notification.create_notifications(reblog_activity)
reblog_activity = Activity.get_by_id(create_activity.id)
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "reblog",
account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: reblog_activity, for: user}),
@ -98,7 +130,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "follow",
account: AccountView.render("show.json", %{user: follower, for: followed}),
created_at: Utils.to_masto_date(notification.inserted_at)
@ -107,9 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], followed, [expected])
User.perform(:delete, follower)
notification = Notification |> Repo.one() |> Repo.preload(:activity)
test_notifications_rendering([notification], followed, [])
refute Repo.one(Notification)
end
@tag capture_log: true
@ -141,7 +171,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "move",
account: AccountView.render("show.json", %{user: old_user, for: follower}),
target: AccountView.render("show.json", %{user: new_user, for: follower}),
@ -166,7 +196,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false},
pleroma: %{is_seen: false, is_muted: false},
type: "pleroma:emoji_reaction",
emoji: "",
account: AccountView.render("show.json", %{user: other_user, for: user}),
@ -176,4 +206,26 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
test_notifications_rendering([notification], user, [expected])
end
test "muted notification" do
user = insert(:user)
another_user = insert(:user)
{:ok, _} = Pleroma.UserRelationship.create_mute(user, another_user)
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, favorite_activity} = CommonAPI.favorite(another_user, create_activity.id)
{:ok, [notification]} = Notification.create_notifications(favorite_activity)
create_activity = Activity.get_by_id(create_activity.id)
expected = %{
id: to_string(notification.id),
pleroma: %{is_seen: false, is_muted: true},
type: "favourite",
account: AccountView.render("show.json", %{user: another_user, for: user}),
status: StatusView.render("show.json", %{activity: create_activity, for: user}),
created_at: Utils.to_masto_date(notification.inserted_at)
}
test_notifications_rendering([notification], user, [expected])
end
end

View file

@ -226,7 +226,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
expires_at: nil,
direct_conversation_id: nil,
thread_muted: false,
emoji_reactions: []
emoji_reactions: [],
parent_visible: false
}
}
@ -442,7 +443,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
user = insert(:user)
activity = insert(:note_activity)
{:ok, reblog, _} = CommonAPI.repeat(activity.id, user)
{:ok, reblog} = CommonAPI.repeat(activity.id, user)
represented = StatusView.render("show.json", %{for: user, activity: reblog})
@ -576,7 +577,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
end
end
test "embeds a relationship in the account" do
test "does not embed a relationship in the account" do
user = insert(:user)
other_user = insert(:user)
@ -587,13 +588,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
result = StatusView.render("show.json", %{activity: activity, for: other_user})
assert result[:account][:pleroma][:relationship] ==
AccountView.render("relationship.json", %{user: other_user, target: user})
assert result[:account][:pleroma][:relationship] == %{}
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
end
test "embeds a relationship in the account in reposts" do
test "does not embed a relationship in the account in reposts" do
user = insert(:user)
other_user = insert(:user)
@ -602,16 +601,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
status: "˙˙ɐʎns"
})
{:ok, activity, _object} = CommonAPI.repeat(activity.id, other_user)
{:ok, activity} = CommonAPI.repeat(activity.id, other_user)
result = StatusView.render("show.json", %{activity: activity, for: user})
assert result[:account][:pleroma][:relationship] ==
AccountView.render("relationship.json", %{user: user, target: other_user})
assert result[:reblog][:account][:pleroma][:relationship] ==
AccountView.render("relationship.json", %{user: user, target: user})
assert result[:account][:pleroma][:relationship] == %{}
assert result[:reblog][:account][:pleroma][:relationship] == %{}
assert_schema(result, "Status", Pleroma.Web.ApiSpec.spec())
end
@ -627,13 +622,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert status.visibility == "list"
end
test "successfully renders a Listen activity (pleroma extension)" do
listen_activity = insert(:listen)
test "has a field for parent visibility" do
user = insert(:user)
poster = insert(:user)
status = StatusView.render("listen.json", activity: listen_activity)
{:ok, invisible} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
assert status.length == listen_activity.data["object"]["length"]
assert status.title == listen_activity.data["object"]["title"]
assert_schema(status, "Status", Pleroma.Web.ApiSpec.spec())
{:ok, visible} =
CommonAPI.post(poster, %{status: "hey", visibility: "private", in_reply_to_id: invisible.id})
status = StatusView.render("show.json", activity: visible, for: user)
refute status.pleroma.parent_visible
status = StatusView.render("show.json", activity: visible, for: poster)
assert status.pleroma.parent_visible
end
end

View file

@ -0,0 +1,64 @@
defmodule Pleroma.Web.MediaProxy.InvalidationTest do
use ExUnit.Case
use Pleroma.Tests.Helpers
alias Pleroma.Config
alias Pleroma.Web.MediaProxy.Invalidation
import ExUnit.CaptureLog
import Mock
import Tesla.Mock
setup do: clear_config([:media_proxy])
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
describe "Invalidation.Http" do
test "perform request to clear cache" do
Config.put([:media_proxy, :enabled], false)
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], Invalidation.Http)
Config.put([Invalidation.Http], method: :purge, headers: [{"x-refresh", 1}])
image_url = "http://example.com/media/example.jpg"
Pleroma.Web.MediaProxy.put_in_banned_urls(image_url)
mock(fn
%{
method: :purge,
url: "http://example.com/media/example.jpg",
headers: [{"x-refresh", 1}]
} ->
%Tesla.Env{status: 200}
end)
assert capture_log(fn ->
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
assert Invalidation.purge([image_url]) == {:ok, [image_url]}
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
end) =~ "Running cache purge: [\"#{image_url}\"]"
end
end
describe "Invalidation.Script" do
test "run script to clear cache" do
Config.put([:media_proxy, :enabled], false)
Config.put([:media_proxy, :invalidation, :enabled], true)
Config.put([:media_proxy, :invalidation, :provider], Invalidation.Script)
Config.put([Invalidation.Script], script_path: "purge-nginx")
image_url = "http://example.com/media/example.jpg"
Pleroma.Web.MediaProxy.put_in_banned_urls(image_url)
with_mocks [{System, [], [cmd: fn _, _ -> {"ok", 0} end]}] do
assert capture_log(fn ->
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
assert Invalidation.purge([image_url]) == {:ok, [image_url]}
assert Pleroma.Web.MediaProxy.in_banned_urls(image_url)
end) =~ "Running cache purge: [\"#{image_url}\"]"
end
end
end
end

View file

@ -0,0 +1,39 @@
defmodule Pleroma.Web.MediaProxy.Invalidation.HttpTest do
use ExUnit.Case
alias Pleroma.Web.MediaProxy.Invalidation
import ExUnit.CaptureLog
import Tesla.Mock
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "logs hasn't error message when request is valid" do
mock(fn
%{method: :purge, url: "http://example.com/media/example.jpg"} ->
%Tesla.Env{status: 200}
end)
refute capture_log(fn ->
assert Invalidation.Http.purge(
["http://example.com/media/example.jpg"],
[]
) == {:ok, ["http://example.com/media/example.jpg"]}
end) =~ "Error while cache purge"
end
test "it write error message in logs when request invalid" do
mock(fn
%{method: :purge, url: "http://example.com/media/example1.jpg"} ->
%Tesla.Env{status: 404}
end)
assert capture_log(fn ->
assert Invalidation.Http.purge(
["http://example.com/media/example1.jpg"],
[]
) == {:ok, ["http://example.com/media/example1.jpg"]}
end) =~ "Error while cache purge: url - http://example.com/media/example1.jpg"
end
end

View file

@ -0,0 +1,26 @@
defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
use ExUnit.Case
alias Pleroma.Web.MediaProxy.Invalidation
import ExUnit.CaptureLog
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "it logger error when script not found" do
assert capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
script_path: "./example"
) == {:error, "%ErlangError{original: :enoent}"}
end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
capture_log(fn ->
assert Invalidation.Script.purge(
["http://example.com/media/example.jpg"],
[]
) == {:error, "\"not found script path\""}
end)
end
end

View file

@ -10,6 +10,10 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
setup do: clear_config(:media_proxy)
setup do: clear_config([Pleroma.Web.Endpoint, :secret_key_base])
setup do
on_exit(fn -> Cachex.clear(:banned_urls_cache) end)
end
test "it returns 404 when MediaProxy disabled", %{conn: conn} do
Config.put([:media_proxy, :enabled], false)
@ -66,4 +70,16 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
assert %Plug.Conn{status: :success} = get(conn, url)
end
end
test "it returns 404 when url contains in banned_urls cache", %{conn: conn} do
Config.put([:media_proxy, :enabled], true)
Config.put([Pleroma.Web.Endpoint, :secret_key_base], "00000000000")
url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png")
Pleroma.Web.MediaProxy.put_in_banned_urls("https://google.fn/test.png")
with_mock Pleroma.ReverseProxy,
call: fn _conn, _url, _opts -> %Plug.Conn{status: :success} end do
assert %Plug.Conn{status: 404, resp_body: "Not Found"} = get(conn, url)
end
end
end

View file

@ -124,15 +124,7 @@ defmodule Pleroma.Web.MediaProxyTest do
end
test "uses the configured base_url" do
base_url = Pleroma.Config.get([:media_proxy, :base_url])
if base_url do
on_exit(fn ->
Pleroma.Config.put([:media_proxy, :base_url], base_url)
end)
end
Pleroma.Config.put([:media_proxy, :base_url], "https://cache.pleroma.social")
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")
url = "https://pleroma.soykaf.com/static/logo.png"
encoded = url(url)
@ -213,8 +205,8 @@ defmodule Pleroma.Web.MediaProxyTest do
end
test "does not change whitelisted urls" do
Pleroma.Config.put([:media_proxy, :whitelist], ["mycdn.akamai.com"])
Pleroma.Config.put([:media_proxy, :base_url], "https://cache.pleroma.social")
clear_config([:media_proxy, :whitelist], ["mycdn.akamai.com"])
clear_config([:media_proxy, :base_url], "https://cache.pleroma.social")
media_url = "https://mycdn.akamai.com"

View file

@ -67,10 +67,10 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "returns fieldsLimits field", %{conn: conn} do
Config.put([:instance, :max_account_fields], 10)
Config.put([:instance, :max_remote_account_fields], 15)
Config.put([:instance, :account_field_name_length], 255)
Config.put([:instance, :account_field_value_length], 2048)
clear_config([:instance, :max_account_fields], 10)
clear_config([:instance, :max_remote_account_fields], 15)
clear_config([:instance, :account_field_name_length], 255)
clear_config([:instance, :account_field_value_length], 2048)
response =
conn
@ -84,8 +84,7 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
option = Config.get([:instance, :safe_dm_mentions])
Config.put([:instance, :safe_dm_mentions], true)
clear_config([:instance, :safe_dm_mentions], true)
response =
conn
@ -102,8 +101,6 @@ defmodule Pleroma.Web.NodeInfoTest do
|> json_response(:ok)
refute "safe_dm_mentions" in response["metadata"]["features"]
Config.put([:instance, :safe_dm_mentions], option)
end
describe "`metadata/federation/enabled`" do
@ -145,7 +142,8 @@ defmodule Pleroma.Web.NodeInfoTest do
"shareable_emoji_packs",
"multifetch",
"pleroma_emoji_reactions",
"pleroma:api/v1/notifications:include_types_filter"
"pleroma:api/v1/notifications:include_types_filter",
"pleroma_chat_messages"
]
assert MapSet.subset?(
@ -155,14 +153,11 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "it shows MRF transparency data if enabled", %{conn: conn} do
config = Config.get([:instance, :rewrite_policy])
Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
option = Config.get([:instance, :mrf_transparency])
Config.put([:instance, :mrf_transparency], true)
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
clear_config([:mrf, :transparency], true)
simple_config = %{"reject" => ["example.com"]}
Config.put(:mrf_simple, simple_config)
clear_config(:mrf_simple, simple_config)
response =
conn
@ -170,26 +165,17 @@ defmodule Pleroma.Web.NodeInfoTest do
|> json_response(:ok)
assert response["metadata"]["federation"]["mrf_simple"] == simple_config
Config.put([:instance, :rewrite_policy], config)
Config.put([:instance, :mrf_transparency], option)
Config.put(:mrf_simple, %{})
end
test "it performs exclusions from MRF transparency data if configured", %{conn: conn} do
config = Config.get([:instance, :rewrite_policy])
Config.put([:instance, :rewrite_policy], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
option = Config.get([:instance, :mrf_transparency])
Config.put([:instance, :mrf_transparency], true)
exclusions = Config.get([:instance, :mrf_transparency_exclusions])
Config.put([:instance, :mrf_transparency_exclusions], ["other.site"])
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.SimplePolicy])
clear_config([:mrf, :transparency], true)
clear_config([:mrf, :transparency_exclusions], ["other.site"])
simple_config = %{"reject" => ["example.com", "other.site"]}
expected_config = %{"reject" => ["example.com"]}
clear_config(:mrf_simple, simple_config)
Config.put(:mrf_simple, simple_config)
expected_config = %{"reject" => ["example.com"]}
response =
conn
@ -198,10 +184,5 @@ defmodule Pleroma.Web.NodeInfoTest do
assert response["metadata"]["federation"]["mrf_simple"] == expected_config
assert response["metadata"]["federation"]["exclusions"] == true
Config.put([:instance, :rewrite_policy], config)
Config.put([:instance, :mrf_transparency], option)
Config.put([:instance, :mrf_transparency_exclusions], exclusions)
Config.put(:mrf_simple, %{})
end
end

View file

@ -10,7 +10,11 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
alias Pleroma.Config
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Endpoint
require Pleroma.Constants
setup_all do
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
@ -19,6 +23,47 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
setup do: clear_config([:instance, :federating], true)
describe "Mastodon compatibility routes" do
setup %{conn: conn} do
conn = put_req_header(conn, "accept", "text/html")
{:ok, object} =
%{
"type" => "Note",
"content" => "hey",
"id" => Endpoint.url() <> "/users/raymoo/statuses/999999999",
"actor" => Endpoint.url() <> "/users/raymoo",
"to" => [Pleroma.Constants.as_public()]
}
|> Object.create()
{:ok, activity, _} =
%{
"id" => object.data["id"] <> "/activity",
"type" => "Create",
"object" => object.data["id"],
"actor" => object.data["actor"],
"to" => object.data["to"]
}
|> ActivityPub.persist(local: true)
%{conn: conn, activity: activity}
end
test "redirects to /notice/:id for html format", %{conn: conn, activity: activity} do
conn = get(conn, "/users/raymoo/statuses/999999999")
assert redirected_to(conn) == "/notice/#{activity.id}"
end
test "redirects to /notice/:id for html format for activity", %{
conn: conn,
activity: activity
} do
conn = get(conn, "/users/raymoo/statuses/999999999/activity")
assert redirected_to(conn) == "/notice/#{activity.id}"
end
end
# Note: see ActivityPubControllerTest for JSON format tests
describe "GET /objects/:uuid (text/html)" do
setup %{conn: conn} do

View file

@ -0,0 +1,336 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
use Pleroma.Web.ConnCase, async: true
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "POST /api/v1/pleroma/chats/:id/messages/:message_id/read" do
setup do: oauth_access(["write:chats"])
test "it marks one message as read", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
{:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
object = Object.normalize(create, false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == true
result =
conn
|> post("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}/read")
|> json_response_and_validate_schema(200)
assert result["unread"] == false
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == false
end
end
describe "POST /api/v1/pleroma/chats/:id/read" do
setup do: oauth_access(["write:chats"])
test "given a `last_read_id`, it marks everything until then as read", %{
conn: conn,
user: user
} do
other_user = insert(:user)
{:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup")
{:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2")
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
object = Object.normalize(create, false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == true
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/read", %{"last_read_id" => cm_ref.id})
|> json_response_and_validate_schema(200)
assert result["unread"] == 1
cm_ref = MessageReference.for_chat_and_object(chat, object)
assert cm_ref.unread == false
end
end
describe "POST /api/v1/pleroma/chats/:id/messages" do
setup do: oauth_access(["write:chats"])
test "it posts a message to the chat", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "Hallo!!"})
|> json_response_and_validate_schema(200)
assert result["content"] == "Hallo!!"
assert result["chat_id"] == chat.id |> to_string()
end
test "it fails if there is no content", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(400)
assert result
end
test "it works with an attachment", %{conn: conn, user: user} do
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{
"media_id" => to_string(upload.id)
})
|> json_response_and_validate_schema(200)
assert result["attachment"]
end
end
describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do
setup do: oauth_access(["write:chats"])
test "it deletes a message from the chat", %{conn: conn, user: user} do
recipient = insert(:user)
{:ok, message} =
CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend")
{:ok, other_message} = CommonAPI.post_chat_message(recipient, user, "nico nico ni")
object = Object.normalize(message, false)
chat = Chat.get(user.id, recipient.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
# Deleting your own message removes the message and the reference
result =
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == cm_ref.id
refute MessageReference.get_by_id(cm_ref.id)
assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id)
# Deleting other people's messages just removes the reference
object = Object.normalize(other_message, false)
cm_ref = MessageReference.for_chat_and_object(chat, object)
result =
conn
|> put_req_header("content-type", "application/json")
|> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == cm_ref.id
refute MessageReference.get_by_id(cm_ref.id)
assert Object.get_by_id(object.id)
end
end
describe "GET /api/v1/pleroma/chats/:id/messages" do
setup do: oauth_access(["read:chats"])
test "it paginates", %{conn: conn, user: user} do
recipient = insert(:user)
Enum.each(1..30, fn _ ->
{:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey")
end)
chat = Chat.get(user.id, recipient.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(200)
assert length(result) == 20
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}")
|> json_response_and_validate_schema(200)
assert length(result) == 10
end
test "it returns the messages for a given chat", %{conn: conn, user: user} do
other_user = insert(:user)
third_user = insert(:user)
{:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey")
{:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey")
{:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?")
{:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?")
chat = Chat.get(user.id, other_user.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}/messages")
|> json_response_and_validate_schema(200)
result
|> Enum.each(fn message ->
assert message["chat_id"] == chat.id |> to_string()
end)
assert length(result) == 3
# Trying to get the chat of a different user
result =
conn
|> assign(:user, other_user)
|> get("/api/v1/pleroma/chats/#{chat.id}/messages")
assert result |> json_response(404)
end
end
describe "POST /api/v1/pleroma/chats/by-account-id/:id" do
setup do: oauth_access(["write:chats"])
test "it creates or returns a chat", %{conn: conn} do
other_user = insert(:user)
result =
conn
|> post("/api/v1/pleroma/chats/by-account-id/#{other_user.id}")
|> json_response_and_validate_schema(200)
assert result["id"]
end
end
describe "GET /api/v1/pleroma/chats/:id" do
setup do: oauth_access(["read:chats"])
test "it returns a chat", %{conn: conn, user: user} do
other_user = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats/#{chat.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == to_string(chat.id)
end
end
describe "GET /api/v1/pleroma/chats" do
setup do: oauth_access(["read:chats"])
test "it does not return chats with users you blocked", %{conn: conn, user: user} do
recipient = insert(:user)
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
assert length(result) == 1
User.block(user, recipient)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
assert length(result) == 0
end
test "it returns all chats", %{conn: conn, user: user} do
Enum.each(1..30, fn _ ->
recipient = insert(:user)
{:ok, _} = Chat.get_or_create(user.id, recipient.ap_id)
end)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
assert length(result) == 30
end
test "it return a list of chats the current user is participating in, in descending order of updates",
%{conn: conn, user: user} do
har = insert(:user)
jafnhar = insert(:user)
tridi = insert(:user)
{:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id)
:timer.sleep(1000)
{:ok, _chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id)
:timer.sleep(1000)
{:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id)
:timer.sleep(1000)
# bump the second one
{:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id)
result =
conn
|> get("/api/v1/pleroma/chats")
|> json_response_and_validate_schema(200)
ids = Enum.map(result, & &1["id"])
assert ids == [
chat_2.id |> to_string(),
chat_3.id |> to_string(),
chat_1.id |> to_string()
]
end
end
end

View file

@ -0,0 +1,136 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ConversationControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Conversation.Participation
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "/api/v1/pleroma/conversations/:id" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["read:statuses"])
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"})
[participation] = Participation.for_user(other_user)
result =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}")
|> json_response_and_validate_schema(200)
assert result["id"] == participation.id |> to_string()
end
test "/api/v1/pleroma/conversations/:id/statuses" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["read:statuses"])
third_user = insert(:user)
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{third_user.nickname}!", visibility: "direct"})
{:ok, activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"})
[participation] = Participation.for_user(other_user)
{:ok, activity_two} =
CommonAPI.post(other_user, %{
status: "Hi!",
in_reply_to_status_id: activity.id,
in_reply_to_conversation_id: participation.id
})
result =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses")
|> json_response_and_validate_schema(200)
assert length(result) == 2
id_one = activity.id
id_two = activity_two.id
assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result
{:ok, %{id: id_three}} =
CommonAPI.post(other_user, %{
status: "Bye!",
in_reply_to_status_id: activity.id,
in_reply_to_conversation_id: participation.id
})
assert [%{"id" => ^id_two}, %{"id" => ^id_three}] =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?limit=2")
|> json_response_and_validate_schema(:ok)
assert [%{"id" => ^id_three}] =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?min_id=#{id_two}")
|> json_response_and_validate_schema(:ok)
end
test "PATCH /api/v1/pleroma/conversations/:id" do
%{user: user, conn: conn} = oauth_access(["write:conversations"])
other_user = insert(:user)
{:ok, _activity} = CommonAPI.post(user, %{status: "Hi", visibility: "direct"})
[participation] = Participation.for_user(user)
participation = Repo.preload(participation, :recipients)
user = User.get_cached_by_id(user.id)
assert [user] == participation.recipients
assert other_user not in participation.recipients
query = "recipients[]=#{user.id}&recipients[]=#{other_user.id}"
result =
conn
|> patch("/api/v1/pleroma/conversations/#{participation.id}?#{query}")
|> json_response_and_validate_schema(200)
assert result["id"] == participation.id |> to_string
[participation] = Participation.for_user(user)
participation = Repo.preload(participation, :recipients)
assert user in participation.recipients
assert other_user in participation.recipients
end
test "POST /api/v1/pleroma/conversations/read" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["write:conversations"])
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"})
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"})
[participation2, participation1] = Participation.for_user(other_user)
assert Participation.get(participation2.id).read == false
assert Participation.get(participation1.id).read == false
assert User.get_cached_by_id(other_user.id).unread_conversation_count == 2
[%{"unread" => false}, %{"unread" => false}] =
conn
|> post("/api/v1/pleroma/conversations/read", %{})
|> json_response_and_validate_schema(200)
[participation2, participation1] = Participation.for_user(other_user)
assert Participation.get(participation2.id).read == true
assert Participation.get(participation1.id).read == true
assert User.get_cached_by_id(other_user.id).unread_conversation_count == 0
end
end

View file

@ -2,7 +2,7 @@
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do
use Pleroma.Web.ConnCase
import Tesla.Mock
@ -28,17 +28,57 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end
test "GET /api/pleroma/emoji/packs", %{conn: conn} do
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200)
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
shared = resp["test_pack"]
assert shared["files"] == %{"blank" => "blank.png"}
assert resp["count"] == 3
assert resp["packs"]
|> Map.keys()
|> length() == 3
shared = resp["packs"]["test_pack"]
assert shared["files"] == %{"blank" => "blank.png", "blank2" => "blank2.png"}
assert Map.has_key?(shared["pack"], "download-sha256")
assert shared["pack"]["can-download"]
assert shared["pack"]["share-files"]
non_shared = resp["test_pack_nonshared"]
non_shared = resp["packs"]["test_pack_nonshared"]
assert non_shared["pack"]["share-files"] == false
assert non_shared["pack"]["can-download"] == false
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack1] = packs
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1&page=2")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack2] = packs
resp =
conn
|> get("/api/pleroma/emoji/packs?page_size=1&page=3")
|> json_response_and_validate_schema(200)
assert resp["count"] == 3
packs = Map.keys(resp["packs"])
assert length(packs) == 1
[pack3] = packs
assert [pack1, pack2, pack3] |> Enum.uniq() |> length() == 3
end
describe "GET /api/pleroma/emoji/packs/remote" do
@ -46,7 +86,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
resp =
conn
|> get("/api/pleroma/emoji/packs")
|> json_response(200)
|> json_response_and_validate_schema(200)
mock(fn
%{method: :get, url: "https://example.com/.well-known/nodeinfo"} ->
@ -60,10 +100,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end)
assert admin_conn
|> get("/api/pleroma/emoji/packs/remote", %{
url: "https://example.com"
})
|> json_response(200) == resp
|> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
|> json_response_and_validate_schema(200) == resp
end
test "non shareable instance", %{admin_conn: admin_conn} do
@ -76,8 +114,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end)
assert admin_conn
|> get("/api/pleroma/emoji/packs/remote", %{url: "https://example.com"})
|> json_response(500) == %{
|> get("/api/pleroma/emoji/packs/remote?url=https://example.com")
|> json_response_and_validate_schema(500) == %{
"error" => "The requested instance does not support sharing emoji packs"
}
end
@ -99,7 +137,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "non existing pack", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/test_pack_for_import/archive")
|> json_response(:not_found) == %{
|> json_response_and_validate_schema(:not_found) == %{
"error" => "Pack test_pack_for_import does not exist"
}
end
@ -107,7 +145,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "non downloadable pack", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive")
|> json_response(:forbidden) == %{
|> json_response_and_validate_schema(:forbidden) == %{
"error" =>
"Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
}
@ -132,7 +170,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
} ->
conn
|> get("/api/pleroma/emoji/packs/test_pack")
|> json_response(200)
|> json_response_and_validate_schema(200)
|> json()
%{
@ -150,7 +188,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
} ->
conn
|> get("/api/pleroma/emoji/packs/test_pack_nonshared")
|> json_response(200)
|> json_response_and_validate_schema(200)
|> json()
%{
@ -161,23 +199,25 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/download", %{
url: "https://example.com",
name: "test_pack",
as: "test_pack2"
})
|> json_response(200) == "ok"
|> json_response_and_validate_schema(200) == "ok"
assert File.exists?("#{@emoji_path}/test_pack2/pack.json")
assert File.exists?("#{@emoji_path}/test_pack2/blank.png")
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack2")
|> json_response(200) == "ok"
|> json_response_and_validate_schema(200) == "ok"
refute File.exists?("#{@emoji_path}/test_pack2")
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post(
"/api/pleroma/emoji/packs/download",
%{
@ -186,14 +226,14 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
as: "test_pack_nonshared2"
}
)
|> json_response(200) == "ok"
|> json_response_and_validate_schema(200) == "ok"
assert File.exists?("#{@emoji_path}/test_pack_nonshared2/pack.json")
assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png")
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack_nonshared2")
|> json_response(200) == "ok"
|> json_response_and_validate_schema(200) == "ok"
refute File.exists?("#{@emoji_path}/test_pack_nonshared2")
end
@ -208,6 +248,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post(
"/api/pleroma/emoji/packs/download",
%{
@ -216,7 +257,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
as: "test_pack2"
}
)
|> json_response(500) == %{
|> json_response_and_validate_schema(500) == %{
"error" => "The requested instance does not support sharing emoji packs"
}
end
@ -233,10 +274,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha"
} ->
%Tesla.Env{
status: 200,
body: Pleroma.Emoji.Pack.load_pack("pack_bad_sha") |> Jason.encode!()
}
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha")
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
%{
method: :get,
@ -249,12 +288,13 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/download", %{
url: "https://example.com",
name: "pack_bad_sha",
as: "pack_bad_sha2"
})
|> json_response(:internal_server_error) == %{
|> json_response_and_validate_schema(:internal_server_error) == %{
"error" => "SHA256 for the pack doesn't match the one sent by the server"
}
end
@ -271,19 +311,18 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
method: :get,
url: "https://example.com/api/pleroma/emoji/packs/test_pack"
} ->
%Tesla.Env{
status: 200,
body: Pleroma.Emoji.Pack.load_pack("test_pack") |> Jason.encode!()
}
{:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack")
%Tesla.Env{status: 200, body: Jason.encode!(pack)}
end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/download", %{
url: "https://example.com",
name: "test_pack",
as: "test_pack2"
})
|> json_response(:internal_server_error) == %{
|> json_response_and_validate_schema(:internal_server_error) == %{
"error" =>
"The pack was not set as shared and there is no fallback src to download from"
}
@ -311,8 +350,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "for a pack without a fallback source", ctx do
assert ctx[:admin_conn]
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]})
|> json_response(200) == ctx[:new_data]
|> json_response_and_validate_schema(200) == ctx[:new_data]
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]
end
@ -332,12 +372,13 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
Map.put(
new_data,
"fallback-src-sha256",
"74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF"
"1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D"
)
assert ctx[:admin_conn]
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
|> json_response(200) == new_data_with_sha
|> json_response_and_validate_schema(200) == new_data_with_sha
assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha
end
@ -355,8 +396,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")
assert ctx[:admin_conn]
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data})
|> json_response(:bad_request) == %{
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "The fallback archive does not have all files specified in pack.json"
}
end
@ -376,6 +418,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "create shortcode exists", %{admin_conn: admin_conn} do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank",
filename: "dir/blank.png",
@ -384,7 +427,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
path: "#{@emoji_path}/test_pack/blank.png"
}
})
|> json_response(:conflict) == %{
|> json_response_and_validate_schema(:conflict) == %{
"error" => "An emoji with the \"blank\" shortcode already exists"
}
end
@ -393,25 +436,31 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
shortcode: "blank3",
filename: "dir/blank.png",
file: %Plug.Upload{
filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png"
}
})
|> json_response(200) == %{"blank" => "blank.png", "blank2" => "dir/blank.png"}
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank2" => "blank2.png",
"blank3" => "dir/blank.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank",
new_shortcode: "blank2",
new_filename: "dir_2/blank_3.png"
})
|> json_response(:conflict) == %{
|> json_response_and_validate_schema(:conflict) == %{
"error" =>
"New shortcode \"blank2\" is already used. If you want to override emoji use 'force' option"
}
@ -421,28 +470,35 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
shortcode: "blank3",
filename: "dir/blank.png",
file: %Plug.Upload{
filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png"
}
})
|> json_response(200) == %{"blank" => "blank.png", "blank2" => "dir/blank.png"}
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank2" => "blank2.png",
"blank3" => "dir/blank.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
new_shortcode: "blank3",
shortcode: "blank3",
new_shortcode: "blank4",
new_filename: "dir_2/blank_3.png",
force: true
})
|> json_response(200) == %{
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank3" => "dir_2/blank_3.png"
"blank2" => "blank2.png",
"blank4" => "dir_2/blank_3.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
@ -450,6 +506,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "with empty filename", %{admin_conn: admin_conn} do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
filename: "",
@ -458,52 +515,59 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
path: "#{@emoji_path}/test_pack/blank.png"
}
})
|> json_response(:bad_request) == %{
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name, shortcode or filename cannot be empty"
}
end
test "add file with not loaded pack", %{admin_conn: admin_conn} do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/not_loaded/files", %{
shortcode: "blank2",
shortcode: "blank3",
filename: "dir/blank.png",
file: %Plug.Upload{
filename: "blank.png",
path: "#{@emoji_path}/test_pack/blank.png"
}
})
|> json_response(:bad_request) == %{
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack \"not_loaded\" is not found"
}
end
test "remove file with not loaded pack", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: "blank3"})
|> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"}
|> delete("/api/pleroma/emoji/packs/not_loaded/files?shortcode=blank3")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack \"not_loaded\" is not found"
}
end
test "remove file with empty shortcode", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: ""})
|> json_response(:bad_request) == %{
|> delete("/api/pleroma/emoji/packs/not_loaded/files?shortcode=")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name or shortcode cannot be empty"
}
end
test "update file with not loaded pack", %{admin_conn: admin_conn} do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/not_loaded/files", %{
shortcode: "blank4",
new_shortcode: "blank3",
new_filename: "dir_2/blank_3.png"
})
|> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"}
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack \"not_loaded\" is not found"
}
end
test "new with shortcode as file with update", %{admin_conn: admin_conn} do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank4",
filename: "dir/blank.png",
@ -512,24 +576,36 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
path: "#{@emoji_path}/test_pack/blank.png"
}
})
|> json_response(200) == %{"blank" => "blank.png", "blank4" => "dir/blank.png"}
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank4" => "dir/blank.png",
"blank2" => "blank2.png"
}
assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank4",
new_shortcode: "blank3",
new_filename: "dir_2/blank_3.png"
})
|> json_response(200) == %{"blank3" => "dir_2/blank_3.png", "blank" => "blank.png"}
|> json_response_and_validate_schema(200) == %{
"blank3" => "dir_2/blank_3.png",
"blank" => "blank.png",
"blank2" => "blank2.png"
}
refute File.exists?("#{@emoji_path}/test_pack/dir/")
assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank3"})
|> json_response(200) == %{"blank" => "blank.png"}
|> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3")
|> json_response_and_validate_schema(200) == %{
"blank" => "blank.png",
"blank2" => "blank2.png"
}
refute File.exists?("#{@emoji_path}/test_pack/dir_2/")
@ -546,13 +622,15 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank_url",
file: "https://test-blank/blank_url.png"
})
|> json_response(200) == %{
|> json_response_and_validate_schema(200) == %{
"blank_url" => "blank_url.png",
"blank" => "blank.png"
"blank" => "blank.png",
"blank2" => "blank2.png"
}
assert File.exists?("#{@emoji_path}/test_pack/blank_url.png")
@ -564,40 +642,52 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end)
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/pleroma/emoji/packs/test_pack/files", %{
file: %Plug.Upload{
filename: "shortcode.png",
path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"
}
})
|> json_response(200) == %{"shortcode" => "shortcode.png", "blank" => "blank.png"}
|> json_response_and_validate_schema(200) == %{
"shortcode" => "shortcode.png",
"blank" => "blank.png",
"blank2" => "blank2.png"
}
end
test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank2"})
|> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"}
|> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3")
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "Emoji \"blank3\" does not exist"
}
end
test "update non existing emoji", %{admin_conn: admin_conn} do
assert admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank2",
new_shortcode: "blank3",
shortcode: "blank3",
new_shortcode: "blank4",
new_filename: "dir_2/blank_3.png"
})
|> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"}
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "Emoji \"blank3\" does not exist"
}
end
test "update with empty shortcode", %{admin_conn: admin_conn} do
assert admin_conn
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank",
new_filename: "dir_2/blank_3.png"
})
|> json_response(:bad_request) == %{
"error" => "new_shortcode or new_filename cannot be empty"
}
assert %{
"error" => "Missing field: new_shortcode."
} =
admin_conn
|> put_req_header("content-type", "multipart/form-data")
|> patch("/api/pleroma/emoji/packs/test_pack/files", %{
shortcode: "blank",
new_filename: "dir_2/blank_3.png"
})
|> json_response_and_validate_schema(:bad_request)
end
end
@ -605,18 +695,19 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "creating and deleting a pack", %{admin_conn: admin_conn} do
assert admin_conn
|> post("/api/pleroma/emoji/packs/test_created")
|> json_response(200) == "ok"
|> json_response_and_validate_schema(200) == "ok"
assert File.exists?("#{@emoji_path}/test_created/pack.json")
assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{
"pack" => %{},
"files" => %{}
"files" => %{},
"files_count" => 0
}
assert admin_conn
|> delete("/api/pleroma/emoji/packs/test_created")
|> json_response(200) == "ok"
|> json_response_and_validate_schema(200) == "ok"
refute File.exists?("#{@emoji_path}/test_created/pack.json")
end
@ -629,7 +720,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
assert admin_conn
|> post("/api/pleroma/emoji/packs/test_created")
|> json_response(:conflict) == %{
|> json_response_and_validate_schema(:conflict) == %{
"error" => "A pack named \"test_created\" already exists"
}
@ -639,20 +730,26 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
test "with empty name", %{admin_conn: admin_conn} do
assert admin_conn
|> post("/api/pleroma/emoji/packs/ ")
|> json_response(:bad_request) == %{"error" => "pack name cannot be empty"}
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name cannot be empty"
}
end
end
test "deleting nonexisting pack", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/non_existing")
|> json_response(:not_found) == %{"error" => "Pack non_existing does not exist"}
|> json_response_and_validate_schema(:not_found) == %{
"error" => "Pack non_existing does not exist"
}
end
test "deleting with empty name", %{admin_conn: admin_conn} do
assert admin_conn
|> delete("/api/pleroma/emoji/packs/ ")
|> json_response(:bad_request) == %{"error" => "pack name cannot be empty"}
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name cannot be empty"
}
end
test "filesystem import", %{admin_conn: admin_conn, conn: conn} do
@ -661,16 +758,16 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
end)
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200)
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
refute Map.has_key?(resp, "test_pack_for_import")
refute Map.has_key?(resp["packs"], "test_pack_for_import")
assert admin_conn
|> get("/api/pleroma/emoji/packs/import")
|> json_response(200) == ["test_pack_for_import"]
|> json_response_and_validate_schema(200) == ["test_pack_for_import"]
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200)
assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
assert resp["packs"]["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}
File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")
refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json")
@ -686,11 +783,11 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
assert admin_conn
|> get("/api/pleroma/emoji/packs/import")
|> json_response(200) == ["test_pack_for_import"]
|> json_response_and_validate_schema(200) == ["test_pack_for_import"]
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200)
resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200)
assert resp["test_pack_for_import"]["files"] == %{
assert resp["packs"]["test_pack_for_import"]["files"] == %{
"blank" => "blank.png",
"blank2" => "blank.png",
"foo" => "blank.png"
@ -700,7 +797,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
describe "GET /api/pleroma/emoji/packs/:name" do
test "shows pack.json", %{conn: conn} do
assert %{
"files" => %{"blank" => "blank.png"},
"files" => files,
"files_count" => 2,
"pack" => %{
"can-download" => true,
"description" => "Test description",
@ -712,19 +810,45 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack")
|> json_response(200)
|> json_response_and_validate_schema(200)
assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"}
assert %{
"files" => files,
"files_count" => 2
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack?page_size=1")
|> json_response_and_validate_schema(200)
assert files |> Map.keys() |> length() == 1
assert %{
"files" => files,
"files_count" => 2
} =
conn
|> get("/api/pleroma/emoji/packs/test_pack?page_size=1&page=2")
|> json_response_and_validate_schema(200)
assert files |> Map.keys() |> length() == 1
end
test "non existing pack", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/non_existing")
|> json_response(:not_found) == %{"error" => "Pack non_existing does not exist"}
|> json_response_and_validate_schema(:not_found) == %{
"error" => "Pack non_existing does not exist"
}
end
test "error name", %{conn: conn} do
assert conn
|> get("/api/pleroma/emoji/packs/ ")
|> json_response(:bad_request) == %{"error" => "pack name cannot be empty"}
|> json_response_and_validate_schema(:bad_request) == %{
"error" => "pack name cannot be empty"
}
end
end
end

View file

@ -0,0 +1,132 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.Web.ConnCase
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
|> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
|> json_response_and_validate_schema(200)
# We return the status, but this our implementation detail.
assert %{"id" => id} = result
assert to_string(activity.id) == id
assert result["pleroma"]["emoji_reactions"] == [
%{"name" => "", "count" => 1, "me" => true}
]
# Reacting with a non-emoji
assert conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
|> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/x")
|> json_response_and_validate_schema(400)
end
test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
{:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "")
ObanHelpers.perform_all()
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
|> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
assert %{"id" => id} = json_response_and_validate_schema(result, 200)
assert to_string(activity.id) == id
ObanHelpers.perform_all()
object = Object.get_by_ap_id(activity.data["object"])
assert object.data["reaction_count"] == 0
end
test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
doomed_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
result =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response_and_validate_schema(200)
assert result == []
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅")
User.perform(:delete, doomed_user)
result =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response_and_validate_schema(200)
[%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result
assert represented_user["id"] == other_user.id
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:statuses"]))
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response_and_validate_schema(200)
assert [%{"name" => "🎅", "count" => 1, "accounts" => [_represented_user], "me" => true}] =
result
end
test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{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}/reactions/🎅")
|> json_response_and_validate_schema(200)
assert result == []
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "")
assert [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
|> json_response_and_validate_schema(200)
assert represented_user["id"] == other_user.id
end
end

View file

@ -16,9 +16,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
filename: "sound.mp3"
}
ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => non_image_file})
ret_conn =
conn
|> put_req_header("content-type", "multipart/form-data")
|> put("/api/v1/pleroma/mascot", %{"file" => non_image_file})
assert json_response(ret_conn, 415)
assert json_response_and_validate_schema(ret_conn, 415)
file = %Plug.Upload{
content_type: "image/jpg",
@ -26,9 +29,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
filename: "an_image.jpg"
}
conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file})
conn =
conn
|> put_req_header("content-type", "multipart/form-data")
|> put("/api/v1/pleroma/mascot", %{"file" => file})
assert %{"id" => _, "type" => image} = json_response(conn, 200)
assert %{"id" => _, "type" => image} = json_response_and_validate_schema(conn, 200)
end
test "mascot retrieving" do
@ -37,7 +43,7 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
# When user hasn't set a mascot, we should just get pleroma tan back
ret_conn = get(conn, "/api/v1/pleroma/mascot")
assert %{"url" => url} = json_response(ret_conn, 200)
assert %{"url" => url} = json_response_and_validate_schema(ret_conn, 200)
assert url =~ "pleroma-fox-tan-smol"
# When a user sets their mascot, we should get that back
@ -47,9 +53,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
filename: "an_image.jpg"
}
ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file})
ret_conn =
conn
|> put_req_header("content-type", "multipart/form-data")
|> put("/api/v1/pleroma/mascot", %{"file" => file})
assert json_response(ret_conn, 200)
assert json_response_and_validate_schema(ret_conn, 200)
user = User.get_cached_by_id(user.id)
@ -58,7 +67,7 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do
|> assign(:user, user)
|> get("/api/v1/pleroma/mascot")
assert %{"url" => url, "type" => "image"} = json_response(conn, 200)
assert %{"url" => url, "type" => "image"} = json_response_and_validate_schema(conn, 200)
assert url =~ "an_image"
end
end

View file

@ -0,0 +1,68 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.NotificationControllerTest do
use Pleroma.Web.ConnCase
alias Pleroma.Notification
alias Pleroma.Repo
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
describe "POST /api/v1/pleroma/notifications/read" do
setup do: oauth_access(["write:notifications"])
test "it marks a single notification as read", %{user: user1, conn: conn} do
user2 = insert(:user)
{:ok, activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, [notification1]} = Notification.create_notifications(activity1)
{:ok, [notification2]} = Notification.create_notifications(activity2)
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/notifications/read", %{id: notification1.id})
|> json_response_and_validate_schema(:ok)
assert %{"pleroma" => %{"is_seen" => true}} = response
assert Repo.get(Notification, notification1.id).seen
refute Repo.get(Notification, notification2.id).seen
end
test "it marks multiple notifications as read", %{user: user1, conn: conn} do
user2 = insert(:user)
{:ok, _activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, _activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, _activity3} = CommonAPI.post(user2, %{status: "HIE @#{user1.nickname}"})
[notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
[response1, response2] =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/notifications/read", %{max_id: notification2.id})
|> json_response_and_validate_schema(:ok)
assert %{"pleroma" => %{"is_seen" => true}} = response1
assert %{"pleroma" => %{"is_seen" => true}} = response2
assert Repo.get(Notification, notification1.id).seen
assert Repo.get(Notification, notification2.id).seen
refute Repo.get(Notification, notification3.id).seen
end
test "it returns error when notification not found", %{conn: conn} do
response =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/notifications/read", %{
id: 22_222_222_222_222
})
|> json_response_and_validate_schema(:bad_request)
assert response == %{"error" => "Cannot get notification"}
end
end
end

View file

@ -1,302 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.Web.ConnCase
alias Pleroma.Conversation.Participation
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
|> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
|> json_response(200)
# We return the status, but this our implementation detail.
assert %{"id" => id} = result
assert to_string(activity.id) == id
assert result["pleroma"]["emoji_reactions"] == [
%{"name" => "", "count" => 1, "me" => true}
]
end
test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
{:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "")
ObanHelpers.perform_all()
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"]))
|> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕")
assert %{"id" => id} = json_response(result, 200)
assert to_string(activity.id) == id
ObanHelpers.perform_all()
object = Object.get_by_ap_id(activity.data["object"])
assert object.data["reaction_count"] == 0
end
test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
doomed_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#cofe"})
result =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response(200)
assert result == []
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅")
User.perform(:delete, doomed_user)
result =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response(200)
[%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result
assert represented_user["id"] == other_user.id
result =
conn
|> assign(:user, other_user)
|> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:statuses"]))
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
|> json_response(200)
assert [%{"name" => "🎅", "count" => 1, "accounts" => [_represented_user], "me" => true}] =
result
end
test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{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}/reactions/🎅")
|> json_response(200)
assert result == []
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "")
result =
conn
|> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅")
|> json_response(200)
[%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result
assert represented_user["id"] == other_user.id
end
test "/api/v1/pleroma/conversations/:id" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["read:statuses"])
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"})
[participation] = Participation.for_user(other_user)
result =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}")
|> json_response(200)
assert result["id"] == participation.id |> to_string()
end
test "/api/v1/pleroma/conversations/:id/statuses" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["read:statuses"])
third_user = insert(:user)
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{third_user.nickname}!", visibility: "direct"})
{:ok, activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"})
[participation] = Participation.for_user(other_user)
{:ok, activity_two} =
CommonAPI.post(other_user, %{
status: "Hi!",
in_reply_to_status_id: activity.id,
in_reply_to_conversation_id: participation.id
})
result =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses")
|> json_response(200)
assert length(result) == 2
id_one = activity.id
id_two = activity_two.id
assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result
{:ok, %{id: id_three}} =
CommonAPI.post(other_user, %{
status: "Bye!",
in_reply_to_status_id: activity.id,
in_reply_to_conversation_id: participation.id
})
assert [%{"id" => ^id_two}, %{"id" => ^id_three}] =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?limit=2")
|> json_response(:ok)
assert [%{"id" => ^id_three}] =
conn
|> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?min_id=#{id_two}")
|> json_response(:ok)
end
test "PATCH /api/v1/pleroma/conversations/:id" do
%{user: user, conn: conn} = oauth_access(["write:conversations"])
other_user = insert(:user)
{:ok, _activity} = CommonAPI.post(user, %{status: "Hi", visibility: "direct"})
[participation] = Participation.for_user(user)
participation = Repo.preload(participation, :recipients)
user = User.get_cached_by_id(user.id)
assert [user] == participation.recipients
assert other_user not in participation.recipients
result =
conn
|> patch("/api/v1/pleroma/conversations/#{participation.id}", %{
"recipients" => [user.id, other_user.id]
})
|> json_response(200)
assert result["id"] == participation.id |> to_string
[participation] = Participation.for_user(user)
participation = Repo.preload(participation, :recipients)
assert user in participation.recipients
assert other_user in participation.recipients
end
test "POST /api/v1/pleroma/conversations/read" do
user = insert(:user)
%{user: other_user, conn: conn} = oauth_access(["write:conversations"])
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"})
{:ok, _activity} =
CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"})
[participation2, participation1] = Participation.for_user(other_user)
assert Participation.get(participation2.id).read == false
assert Participation.get(participation1.id).read == false
assert User.get_cached_by_id(other_user.id).unread_conversation_count == 2
[%{"unread" => false}, %{"unread" => false}] =
conn
|> post("/api/v1/pleroma/conversations/read", %{})
|> json_response(200)
[participation2, participation1] = Participation.for_user(other_user)
assert Participation.get(participation2.id).read == true
assert Participation.get(participation1.id).read == true
assert User.get_cached_by_id(other_user.id).unread_conversation_count == 0
end
describe "POST /api/v1/pleroma/notifications/read" do
setup do: oauth_access(["write:notifications"])
test "it marks a single notification as read", %{user: user1, conn: conn} do
user2 = insert(:user)
{:ok, activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, [notification1]} = Notification.create_notifications(activity1)
{:ok, [notification2]} = Notification.create_notifications(activity2)
response =
conn
|> post("/api/v1/pleroma/notifications/read", %{"id" => "#{notification1.id}"})
|> json_response(:ok)
assert %{"pleroma" => %{"is_seen" => true}} = response
assert Repo.get(Notification, notification1.id).seen
refute Repo.get(Notification, notification2.id).seen
end
test "it marks multiple notifications as read", %{user: user1, conn: conn} do
user2 = insert(:user)
{:ok, _activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, _activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"})
{:ok, _activity3} = CommonAPI.post(user2, %{status: "HIE @#{user1.nickname}"})
[notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3})
[response1, response2] =
conn
|> post("/api/v1/pleroma/notifications/read", %{"max_id" => "#{notification2.id}"})
|> json_response(:ok)
assert %{"pleroma" => %{"is_seen" => true}} = response1
assert %{"pleroma" => %{"is_seen" => true}} = response2
assert Repo.get(Notification, notification1.id).seen
assert Repo.get(Notification, notification2.id).seen
refute Repo.get(Notification, notification3.id).seen
end
test "it returns error when notification not found", %{conn: conn} do
response =
conn
|> post("/api/v1/pleroma/notifications/read", %{"id" => "22222222222222"})
|> json_response(:bad_request)
assert response == %{"error" => "Cannot get notification"}
end
end
end

View file

@ -12,14 +12,16 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
%{conn: conn} = oauth_access(["write"])
conn =
post(conn, "/api/v1/pleroma/scrobble", %{
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/pleroma/scrobble", %{
"title" => "lain radio episode 1",
"artist" => "lain",
"album" => "lain radio",
"length" => "180000"
})
assert %{"title" => "lain radio episode 1"} = json_response(conn, 200)
assert %{"title" => "lain radio episode 1"} = json_response_and_validate_schema(conn, 200)
end
end
@ -29,28 +31,28 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do
{:ok, _activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 1",
"artist" => "lain",
"album" => "lain radio"
title: "lain radio episode 1",
artist: "lain",
album: "lain radio"
})
{:ok, _activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 2",
"artist" => "lain",
"album" => "lain radio"
title: "lain radio episode 2",
artist: "lain",
album: "lain radio"
})
{:ok, _activity} =
CommonAPI.listen(user, %{
"title" => "lain radio episode 3",
"artist" => "lain",
"album" => "lain radio"
title: "lain radio episode 3",
artist: "lain",
album: "lain radio"
})
conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/scrobbles")
result = json_response(conn, 200)
result = json_response_and_validate_schema(conn, 200)
assert length(result) == 3
end

View file

@ -0,0 +1,61 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.Chat.MessageReferenceViewTest do
use Pleroma.DataCase
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
import Pleroma.Factory
test "it displays a chat message" do
user = insert(:user)
recipient = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, activity} = CommonAPI.post_chat_message(user, recipient, "kippis :firefox:")
chat = Chat.get(user.id, recipient.ap_id)
object = Object.normalize(activity)
cm_ref = MessageReference.for_chat_and_object(chat, object)
chat_message = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
assert chat_message[:id] == cm_ref.id
assert chat_message[:content] == "kippis :firefox:"
assert chat_message[:account_id] == user.id
assert chat_message[:chat_id]
assert chat_message[:created_at]
assert chat_message[:unread] == false
assert match?([%{shortcode: "firefox"}], chat_message[:emojis])
{:ok, activity} = CommonAPI.post_chat_message(recipient, user, "gkgkgk", media_id: upload.id)
object = Object.normalize(activity)
cm_ref = MessageReference.for_chat_and_object(chat, object)
chat_message_two = MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
assert chat_message_two[:id] == cm_ref.id
assert chat_message_two[:content] == "gkgkgk"
assert chat_message_two[:account_id] == recipient.id
assert chat_message_two[:chat_id] == chat_message[:chat_id]
assert chat_message_two[:attachment]
assert chat_message_two[:unread] == true
end
end

View file

@ -0,0 +1,48 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ChatViewTest do
use Pleroma.DataCase
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Object
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.PleromaAPI.Chat.MessageReferenceView
alias Pleroma.Web.PleromaAPI.ChatView
import Pleroma.Factory
test "it represents a chat" do
user = insert(:user)
recipient = insert(:user)
{:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
represented_chat = ChatView.render("show.json", chat: chat)
assert represented_chat == %{
id: "#{chat.id}",
account: AccountView.render("show.json", user: recipient),
unread: 0,
last_message: nil,
updated_at: Utils.to_masto_date(chat.updated_at)
}
{:ok, chat_message_creation} = CommonAPI.post_chat_message(user, recipient, "hello")
chat_message = Object.normalize(chat_message_creation, false)
{:ok, chat} = Chat.get_or_create(user.id, recipient.ap_id)
represented_chat = ChatView.render("show.json", chat: chat)
cm_ref = MessageReference.for_chat_and_object(chat, chat_message)
assert represented_chat[:last_message] ==
MessageReferenceView.render("show.json", chat_message_reference: cm_ref)
end
end

View file

@ -0,0 +1,20 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.StatusViewTest do
use Pleroma.DataCase
alias Pleroma.Web.PleromaAPI.ScrobbleView
import Pleroma.Factory
test "successfully renders a Listen activity (pleroma extension)" do
listen_activity = insert(:listen)
status = ScrobbleView.render("show.json", activity: listen_activity)
assert status.length == listen_activity.data["object"]["length"]
assert status.title == listen_activity.data["object"]["title"]
end
end

View file

@ -0,0 +1,37 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.InstanceTest do
use Pleroma.DataCase
alias Pleroma.Web.Preload.Providers.Instance
setup do: {:ok, Instance.generate_terms(nil)}
test "it renders the info", %{"/api/v1/instance": info} do
assert %{
description: description,
email: "admin@example.com",
registrations: true
} = info
assert String.equivalent?(description, "Pleroma: An efficient and flexible fediverse server")
end
test "it renders the panel", %{"/instance/panel.html": panel} do
assert String.contains?(
panel,
"<p>Welcome to <a href=\"https://pleroma.social\" target=\"_blank\">Pleroma!</a></p>"
)
end
test "it renders the node_info", %{"/nodeinfo/2.0": nodeinfo} do
%{
metadata: metadata,
version: "2.0"
} = nodeinfo
assert metadata.private == false
assert metadata.suggestions == %{enabled: false}
end
end

View file

@ -0,0 +1,14 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.StatusNetTest do
use Pleroma.DataCase
alias Pleroma.Web.Preload.Providers.StatusNet
setup do: {:ok, StatusNet.generate_terms(nil)}
test "it renders the info", %{"/api/statusnet/config.json": info} do
assert info =~ "<name>Pleroma</name>"
end
end

View file

@ -0,0 +1,74 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.TimelineTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Preload.Providers.Timelines
@public_url :"/api/v1/timelines/public"
describe "unauthenticated timeliness when restricted" do
setup do
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{local: true, federated: true})
on_exit(fn ->
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
end)
:ok
end
test "return nothing" do
tl_data = Timelines.generate_terms(%{})
refute Map.has_key?(tl_data, "/api/v1/timelines/public")
end
end
describe "unauthenticated timeliness when unrestricted" do
setup do
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{
local: false,
federated: false
})
on_exit(fn ->
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
end)
{:ok, user: insert(:user)}
end
test "returns the timeline when not restricted" do
assert Timelines.generate_terms(%{})
|> Map.has_key?(@public_url)
end
test "returns public items", %{user: user} do
{:ok, _} = CommonAPI.post(user, %{status: "it's post 1!"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 2!"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
assert Timelines.generate_terms(%{})
|> Map.fetch!(@public_url)
|> Enum.count() == 3
end
test "does not return non-public items", %{user: user} do
{:ok, _} = CommonAPI.post(user, %{status: "it's post 1!", visibility: "unlisted"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 2!", visibility: "direct"})
{:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
assert Timelines.generate_terms(%{})
|> Map.fetch!(@public_url)
|> Enum.count() == 1
end
end
end

View file

@ -0,0 +1,33 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.UserTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.Preload.Providers.User
describe "returns empty when user doesn't exist" do
test "nil user specified" do
refute User.generate_terms(%{user: nil})
|> Map.has_key?("/api/v1/accounts")
end
test "missing user specified" do
refute User.generate_terms(%{user: :not_a_user})
|> Map.has_key?("/api/v1/accounts")
end
end
describe "specified user exists" do
setup do
user = insert(:user)
{:ok, User.generate_terms(%{user: user})}
end
test "account is rendered", %{"/api/v1/accounts": accounts} do
assert %{acct: user, username: user} = accounts
end
end
end

View file

@ -5,8 +5,10 @@
defmodule Pleroma.Web.Push.ImplTest do
use Pleroma.DataCase
alias Pleroma.Notification
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Push.Impl
alias Pleroma.Web.Push.Subscription
@ -60,7 +62,8 @@ defmodule Pleroma.Web.Push.ImplTest do
notif =
insert(:notification,
user: user,
activity: activity
activity: activity,
type: "mention"
)
assert Impl.perform(notif) == {:ok, [:ok, :ok]}
@ -126,7 +129,7 @@ defmodule Pleroma.Web.Push.ImplTest do
) ==
"@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
assert Impl.format_title(%{activity: activity}) ==
assert Impl.format_title(%{activity: activity, type: "mention"}) ==
"New Mention"
end
@ -136,9 +139,10 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, _, _, activity} = CommonAPI.follow(user, other_user)
object = Object.normalize(activity, false)
assert Impl.format_body(%{activity: activity}, user, object) == "@Bob has followed you"
assert Impl.format_body(%{activity: activity, type: "follow"}, user, object) ==
"@Bob has followed you"
assert Impl.format_title(%{activity: activity}) ==
assert Impl.format_title(%{activity: activity, type: "follow"}) ==
"New Follower"
end
@ -151,13 +155,13 @@ defmodule Pleroma.Web.Push.ImplTest do
"<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
})
{:ok, announce_activity, _} = CommonAPI.repeat(activity.id, user)
{:ok, announce_activity} = CommonAPI.repeat(activity.id, user)
object = Object.normalize(activity)
assert Impl.format_body(%{activity: announce_activity}, user, object) ==
"@#{user.nickname} repeated: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini..."
assert Impl.format_title(%{activity: announce_activity}) ==
assert Impl.format_title(%{activity: announce_activity, type: "reblog"}) ==
"New Repeat"
end
@ -173,9 +177,10 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.favorite(user, activity.id)
object = Object.normalize(activity)
assert Impl.format_body(%{activity: activity}, user, object) == "@Bob has favorited your post"
assert Impl.format_body(%{activity: activity, type: "favourite"}, user, object) ==
"@Bob has favorited your post"
assert Impl.format_title(%{activity: activity}) ==
assert Impl.format_title(%{activity: activity, type: "favourite"}) ==
"New Favorite"
end
@ -193,6 +198,46 @@ defmodule Pleroma.Web.Push.ImplTest do
end
describe "build_content/3" do
test "builds content for chat messages" do
user = insert(:user)
recipient = insert(:user)
{:ok, chat} = CommonAPI.post_chat_message(user, recipient, "hey")
object = Object.normalize(chat, false)
[notification] = Notification.for_user(recipient)
res = Impl.build_content(notification, user, object)
assert res == %{
body: "@#{user.nickname}: hey",
title: "New Chat Message"
}
end
test "builds content for chat messages with no content" do
user = insert(:user)
recipient = insert(:user)
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, chat} = CommonAPI.post_chat_message(user, recipient, nil, media_id: upload.id)
object = Object.normalize(chat, false)
[notification] = Notification.for_user(recipient)
res = Impl.build_content(notification, user, object)
assert res == %{
body: "@#{user.nickname}: (Attachment)",
title: "New Chat Message"
}
end
test "hides details for notifications when privacy option enabled" do
user = insert(:user, nickname: "Bob")
user2 = insert(:user, nickname: "Rob", notification_settings: %{privacy_option: true})
@ -218,7 +263,7 @@ defmodule Pleroma.Web.Push.ImplTest do
status: "<Lorem ipsum dolor sit amet."
})
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "mention")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)
@ -229,7 +274,7 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.favorite(user, activity.id)
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "favourite")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)
@ -268,7 +313,7 @@ defmodule Pleroma.Web.Push.ImplTest do
"<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis."
})
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "mention")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)
@ -281,7 +326,7 @@ defmodule Pleroma.Web.Push.ImplTest do
{:ok, activity} = CommonAPI.favorite(user, activity.id)
notif = insert(:notification, user: user2, activity: activity)
notif = insert(:notification, user: user2, activity: activity, type: "favourite")
actor = User.get_cached_by_ap_id(notif.activity.data["actor"])
object = Object.normalize(activity)

View file

@ -60,19 +60,19 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
test "doesn't just add a title" do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/non-ogp") ==
{:error,
"Found metadata was invalid or incomplete: %{url: \"http://example.com/non-ogp\"}"}
"Found metadata was invalid or incomplete: %{\"url\" => \"http://example.com/non-ogp\"}"}
end
test "parses ogp" do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/ogp") ==
{:ok,
%{
image: "http://ia.media-imdb.com/images/rock.jpg",
title: "The Rock",
description:
"image" => "http://ia.media-imdb.com/images/rock.jpg",
"title" => "The Rock",
"description" =>
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
type: "video.movie",
url: "http://example.com/ogp"
"type" => "video.movie",
"url" => "http://example.com/ogp"
}}
end
@ -80,12 +80,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/ogp-missing-title") ==
{:ok,
%{
image: "http://ia.media-imdb.com/images/rock.jpg",
title: "The Rock (1996)",
description:
"image" => "http://ia.media-imdb.com/images/rock.jpg",
"title" => "The Rock (1996)",
"description" =>
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
type: "video.movie",
url: "http://example.com/ogp-missing-title"
"type" => "video.movie",
"url" => "http://example.com/ogp-missing-title"
}}
end
@ -93,12 +93,12 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/twitter-card") ==
{:ok,
%{
card: "summary",
site: "@flickr",
image: "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
title: "Small Island Developing States Photo Submission",
description: "View the album on Flickr.",
url: "http://example.com/twitter-card"
"card" => "summary",
"site" => "@flickr",
"image" => "https://farm6.staticflickr.com/5510/14338202952_93595258ff_z.jpg",
"title" => "Small Island Developing States Photo Submission",
"description" => "View the album on Flickr.",
"url" => "http://example.com/twitter-card"
}}
end
@ -106,27 +106,28 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
assert Pleroma.Web.RichMedia.Parser.parse("http://example.com/oembed") ==
{:ok,
%{
author_name: "bees",
author_url: "https://www.flickr.com/photos/bees/",
cache_age: 3600,
flickr_type: "photo",
height: "768",
html:
"author_name" => "bees",
"author_url" => "https://www.flickr.com/photos/bees/",
"cache_age" => 3600,
"flickr_type" => "photo",
"height" => "768",
"html" =>
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by bees, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>",
license: "All Rights Reserved",
license_id: 0,
provider_name: "Flickr",
provider_url: "https://www.flickr.com/",
thumbnail_height: 150,
thumbnail_url: "https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_q.jpg",
thumbnail_width: 150,
title: "Bacon Lollys",
type: "photo",
url: "http://example.com/oembed",
version: "1.0",
web_page: "https://www.flickr.com/photos/bees/2362225867/",
web_page_short_url: "https://flic.kr/p/4AK2sc",
width: "1024"
"license" => "All Rights Reserved",
"license_id" => 0,
"provider_name" => "Flickr",
"provider_url" => "https://www.flickr.com/",
"thumbnail_height" => 150,
"thumbnail_url" =>
"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_q.jpg",
"thumbnail_width" => 150,
"title" => "Bacon Lollys",
"type" => "photo",
"url" => "http://example.com/oembed",
"version" => "1.0",
"web_page" => "https://www.flickr.com/photos/bees/2362225867/",
"web_page_short_url" => "https://flic.kr/p/4AK2sc",
"width" => "1024"
}}
end

View file

@ -7,8 +7,7 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
alias Pleroma.Web.RichMedia.Parsers.TwitterCard
test "returns error when html not contains twitter card" do
assert TwitterCard.parse([{"html", [], [{"head", [], []}, {"body", [], []}]}], %{}) ==
{:error, "No twitter card metadata found"}
assert TwitterCard.parse([{"html", [], [{"head", [], []}, {"body", [], []}]}], %{}) == %{}
end
test "parses twitter card with only name attributes" do
@ -17,15 +16,21 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
"app:id:googleplay": "com.nytimes.android",
"app:name:googleplay": "NYTimes",
"app:url:googleplay": "nytimes://reader/id/100000006583622",
site: nil,
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database. - The New York Times"
}}
%{
"app:id:googleplay" => "com.nytimes.android",
"app:name:googleplay" => "NYTimes",
"app:url:googleplay" => "nytimes://reader/id/100000006583622",
"site" => nil,
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-facebookJumbo.jpg",
"type" => "article",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database."
}
end
test "parses twitter card with only property attributes" do
@ -34,19 +39,19 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
card: "summary_large_image",
description:
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
image:
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt": "",
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
url:
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
}}
%{
"card" => "summary_large_image",
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt" => "",
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
"type" => "article"
}
end
test "parses twitter card with name & property attributes" do
@ -55,23 +60,23 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
"app:id:googleplay": "com.nytimes.android",
"app:name:googleplay": "NYTimes",
"app:url:googleplay": "nytimes://reader/id/100000006583622",
card: "summary_large_image",
description:
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
image:
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt": "",
site: nil,
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
url:
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
}}
%{
"app:id:googleplay" => "com.nytimes.android",
"app:name:googleplay" => "NYTimes",
"app:url:googleplay" => "nytimes://reader/id/100000006583622",
"card" => "summary_large_image",
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-videoSixteenByNineJumbo1600.jpg",
"image:alt" => "",
"site" => nil,
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html",
"type" => "article"
}
end
test "respect only first title tag on the page" do
@ -84,14 +89,17 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
File.read!("test/fixtures/margaret-corbin-grave-west-point.html") |> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
site: "@atlasobscura",
title:
"The Missing Grave of Margaret Corbin, Revolutionary War Veteran - Atlas Obscura",
card: "summary_large_image",
image: image_path
}}
%{
"site" => "@atlasobscura",
"title" => "The Missing Grave of Margaret Corbin, Revolutionary War Veteran",
"card" => "summary_large_image",
"image" => image_path,
"description" =>
"She's the only woman veteran honored with a monument at West Point. But where was she buried?",
"site_name" => "Atlas Obscura",
"type" => "article",
"url" => "http://www.atlasobscura.com/articles/margaret-corbin-grave-west-point"
}
end
test "takes first founded title in html head if there is html markup error" do
@ -100,14 +108,20 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do
|> Floki.parse_document!()
assert TwitterCard.parse(html, %{}) ==
{:ok,
%{
site: nil,
title:
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database. - The New York Times",
"app:id:googleplay": "com.nytimes.android",
"app:name:googleplay": "NYTimes",
"app:url:googleplay": "nytimes://reader/id/100000006583622"
}}
%{
"site" => nil,
"title" =>
"She Was Arrested at 14. Then Her Photo Went to a Facial Recognition Database.",
"app:id:googleplay" => "com.nytimes.android",
"app:name:googleplay" => "NYTimes",
"app:url:googleplay" => "nytimes://reader/id/100000006583622",
"description" =>
"With little oversight, the N.Y.P.D. has been using powerful surveillance technology on photos of children and teenagers.",
"image" =>
"https://static01.nyt.com/images/2019/08/01/nyregion/01nypd-juveniles-promo/01nypd-juveniles-promo-facebookJumbo.jpg",
"type" => "article",
"url" =>
"https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html"
}
end
end

View file

@ -7,11 +7,15 @@ defmodule Pleroma.Web.StreamerTest do
import Pleroma.Factory
alias Pleroma.Chat
alias Pleroma.Chat.MessageReference
alias Pleroma.Conversation.Participation
alias Pleroma.List
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Streamer
alias Pleroma.Web.StreamerView
@moduletag needs_streamer: true, capture_log: true
@ -106,7 +110,26 @@ defmodule Pleroma.Web.StreamerTest do
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
{:ok, announce, _} = CommonAPI.repeat(activity.id, user)
{:ok, announce} = CommonAPI.repeat(activity.id, user)
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
refute Streamer.filtered_by_user?(user, announce)
end
test "it streams boosts of mastodon user in the 'user' stream", %{user: user} do
Streamer.get_topic_and_add_socket("user", user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
data =
File.read!("test/fixtures/mastodon-announce.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
|> Map.put("actor", user.ap_id)
{:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
refute Streamer.filtered_by_user?(user, announce)
@ -126,6 +149,57 @@ defmodule Pleroma.Web.StreamerTest do
refute Streamer.filtered_by_user?(user, notify)
end
test "it sends chat messages to the 'user:pleroma_chat' stream", %{user: user} do
other_user = insert(:user)
{:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
object = Object.normalize(create_activity, false)
chat = Chat.get(user.id, other_user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
cm_ref = %{cm_ref | chat: chat, object: object}
Streamer.get_topic_and_add_socket("user:pleroma_chat", user)
Streamer.stream("user:pleroma_chat", {user, cm_ref})
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
assert text =~ "hey cirno"
assert_receive {:text, ^text}
end
test "it sends chat messages to the 'user' stream", %{user: user} do
other_user = insert(:user)
{:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey cirno")
object = Object.normalize(create_activity, false)
chat = Chat.get(user.id, other_user.ap_id)
cm_ref = MessageReference.for_chat_and_object(chat, object)
cm_ref = %{cm_ref | chat: chat, object: object}
Streamer.get_topic_and_add_socket("user", user)
Streamer.stream("user", {user, cm_ref})
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
assert text =~ "hey cirno"
assert_receive {:text, ^text}
end
test "it sends chat message notifications to the 'user:notification' stream", %{user: user} do
other_user = insert(:user)
{:ok, create_activity} = CommonAPI.post_chat_message(other_user, user, "hey")
notify =
Repo.get_by(Pleroma.Notification, user_id: user.id, activity_id: create_activity.id)
|> Repo.preload(:activity)
Streamer.get_topic_and_add_socket("user:notification", user)
Streamer.stream("user:notification", notify)
assert_receive {:render_with_user, _, _, ^notify}
refute Streamer.filtered_by_user?(user, notify)
end
test "it doesn't send notify to the 'user:notification' stream when a user is blocked", %{
user: user
} do
@ -427,7 +501,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, create_activity} = CommonAPI.post(user3, %{status: "I'm kawen"})
Streamer.get_topic_and_add_socket("user", user1)
{:ok, announce_activity, _} = CommonAPI.repeat(create_activity.id, user2)
{:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
assert_receive {:render_with_user, _, _, ^announce_activity}
assert Streamer.filtered_by_user?(user1, announce_activity)
end
@ -440,7 +514,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, create_activity} = CommonAPI.post(user1, %{status: "I'm kawen"})
Streamer.get_topic_and_add_socket("user", user1)
{:ok, _favorite_activity, _} = CommonAPI.repeat(create_activity.id, user2)
{:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
assert_receive {:render_with_user, _, "notification.json", notif}
assert Streamer.filtered_by_user?(user1, notif)