diff options
Diffstat (limited to 'test/web')
109 files changed, 4947 insertions, 3720 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 1aa73d75c..bd8e0b5cc 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -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.ActivityPub.ActivityPubControllerTest do @@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do import Pleroma.Factory alias Pleroma.Activity + alias Pleroma.Config alias Pleroma.Delivery alias Pleroma.Instances alias Pleroma.Object @@ -25,9 +26,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do :ok end - clear_config_all([:instance, :federating], - do: Pleroma.Config.put([:instance, :federating], true) - ) + clear_config([:instance, :federating]) do + Config.put([:instance, :federating], true) + end describe "/relay" do clear_config([:instance, :allow_relay]) @@ -42,12 +43,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do end test "with the relay disabled, it returns 404", %{conn: conn} do - Pleroma.Config.put([:instance, :allow_relay], false) + Config.put([:instance, :allow_relay], false) conn |> get(activity_pub_path(conn, :relay)) |> json_response(404) - |> assert + end + + test "on non-federating instance, it returns 404", %{conn: conn} do + Config.put([:instance, :federating], false) + user = insert(:user) + + conn + |> assign(:user, user) + |> get(activity_pub_path(conn, :relay)) + |> json_response(404) end end @@ -60,6 +70,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert res["id"] =~ "/fetch" end + + test "on non-federating instance, it returns 404", %{conn: conn} do + Config.put([:instance, :federating], false) + user = insert(:user) + + conn + |> assign(:user, user) + |> get(activity_pub_path(conn, :internal_fetch)) + |> json_response(404) + end end describe "/users/:nickname" do @@ -123,9 +143,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert json_response(conn, 404) end + + test "it returns error when user is not found", %{conn: conn} do + response = + conn + |> put_req_header("accept", "application/json") + |> get("/users/jimm") + |> json_response(404) + + assert response == "Not found" + end + + test "it requires authentication if instance is NOT federating", %{ + conn: conn + } do + user = insert(:user) + + conn = + put_req_header( + conn, + "accept", + "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + ) + + ensure_federating_or_authenticated(conn, "/users/#{user.nickname}.json", user) + end end - describe "/object/:uuid" do + describe "/objects/:uuid" do test "it returns a json representation of the object with accept application/json", %{ conn: conn } do @@ -236,6 +281,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert "Not found" == json_response(conn2, :not_found) end + + test "it requires authentication if instance is NOT federating", %{ + conn: conn + } do + user = insert(:user) + note = insert(:note) + uuid = String.split(note.data["id"], "/") |> List.last() + + conn = put_req_header(conn, "accept", "application/activity+json") + + ensure_federating_or_authenticated(conn, "/objects/#{uuid}", user) + end end describe "/activities/:uuid" do @@ -298,7 +355,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert json_response(conn1, :ok) assert Enum.any?(conn1.resp_headers, &(&1 == {"x-cache", "MISS from Pleroma"})) - Activity.delete_by_ap_id(activity.object.data["id"]) + Activity.delete_all_by_object_ap_id(activity.object.data["id"]) conn2 = conn @@ -307,6 +364,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert "Not found" == json_response(conn2, :not_found) end + + test "it requires authentication if instance is NOT federating", %{ + conn: conn + } do + user = insert(:user) + activity = insert(:note_activity) + uuid = String.split(activity.data["id"], "/") |> List.last() + + conn = put_req_header(conn, "accept", "application/activity+json") + + ensure_federating_or_authenticated(conn, "/activities/#{uuid}", user) + end end describe "/inbox" do @@ -341,6 +410,72 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert "ok" == json_response(conn, 200) assert Instances.reachable?(sender_url) end + + test "accept follow activity", %{conn: conn} do + Pleroma.Config.put([:instance, :federating], true) + relay = Relay.get_actor() + + assert {:ok, %Activity{} = activity} = Relay.follow("https://relay.mastodon.host/actor") + + followed_relay = Pleroma.User.get_by_ap_id("https://relay.mastodon.host/actor") + relay = refresh_record(relay) + + accept = + File.read!("test/fixtures/relay/accept-follow.json") + |> String.replace("{{ap_id}}", relay.ap_id) + |> String.replace("{{activity_id}}", activity.data["id"]) + + assert "ok" == + conn + |> assign(:valid_signature, true) + |> put_req_header("content-type", "application/activity+json") + |> post("/inbox", accept) + |> json_response(200) + + ObanHelpers.perform(all_enqueued(worker: ReceiverWorker)) + + assert Pleroma.FollowingRelationship.following?( + relay, + followed_relay + ) + + Mix.shell(Mix.Shell.Process) + + on_exit(fn -> + Mix.shell(Mix.Shell.IO) + end) + + :ok = Mix.Tasks.Pleroma.Relay.run(["list"]) + assert_receive {:mix_shell, :info, ["relay.mastodon.host"]} + end + + test "without valid signature, " <> + "it only accepts Create activities and requires enabled federation", + %{conn: conn} do + data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() + non_create_data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!() + + conn = put_req_header(conn, "content-type", "application/activity+json") + + Config.put([:instance, :federating], false) + + conn + |> post("/inbox", data) + |> json_response(403) + + conn + |> post("/inbox", non_create_data) + |> json_response(403) + + Config.put([:instance, :federating], true) + + ret_conn = post(conn, "/inbox", data) + assert "ok" == json_response(ret_conn, 200) + + conn + |> post("/inbox", non_create_data) + |> json_response(400) + end end describe "/users/:nickname/inbox" do @@ -479,22 +614,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do test "it rejects reads from other users", %{conn: conn} do user = insert(:user) - otheruser = insert(:user) - - conn = - conn - |> assign(:user, otheruser) - |> put_req_header("accept", "application/activity+json") - |> get("/users/#{user.nickname}/inbox") - - assert json_response(conn, 403) - end - - test "it doesn't crash without an authenticated user", %{conn: conn} do - user = insert(:user) + other_user = insert(:user) conn = conn + |> assign(:user, other_user) |> put_req_header("accept", "application/activity+json") |> get("/users/#{user.nickname}/inbox") @@ -575,14 +699,30 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do refute recipient.follower_address in activity.data["cc"] refute recipient.follower_address in activity.data["to"] end + + test "it requires authentication", %{conn: conn} do + user = insert(:user) + conn = put_req_header(conn, "accept", "application/activity+json") + + ret_conn = get(conn, "/users/#{user.nickname}/inbox") + assert json_response(ret_conn, 403) + + ret_conn = + conn + |> assign(:user, user) + |> get("/users/#{user.nickname}/inbox") + + assert json_response(ret_conn, 200) + end end - describe "/users/:nickname/outbox" do - test "it will not bomb when there is no activity", %{conn: conn} do + describe "GET /users/:nickname/outbox" do + test "it returns 200 even if there're no activities", %{conn: conn} do user = insert(:user) conn = conn + |> assign(:user, user) |> put_req_header("accept", "application/activity+json") |> get("/users/#{user.nickname}/outbox") @@ -597,6 +737,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do conn = conn + |> assign(:user, user) |> put_req_header("accept", "application/activity+json") |> get("/users/#{user.nickname}/outbox?page=true") @@ -609,24 +750,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do conn = conn + |> assign(:user, user) |> put_req_header("accept", "application/activity+json") |> get("/users/#{user.nickname}/outbox?page=true") assert response(conn, 200) =~ announce_activity.data["object"] end - test "it rejects posts from other users", %{conn: conn} do + test "it requires authentication if instance is NOT federating", %{ + conn: conn + } do + user = insert(:user) + conn = put_req_header(conn, "accept", "application/activity+json") + + ensure_federating_or_authenticated(conn, "/users/#{user.nickname}/outbox", user) + end + end + + describe "POST /users/:nickname/outbox" do + test "it rejects posts from other users / unauuthenticated users", %{conn: conn} do data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!() user = insert(:user) - otheruser = insert(:user) + other_user = insert(:user) + conn = put_req_header(conn, "content-type", "application/activity+json") - conn = - conn - |> assign(:user, otheruser) - |> put_req_header("content-type", "application/activity+json") - |> post("/users/#{user.nickname}/outbox", data) + conn + |> post("/users/#{user.nickname}/outbox", data) + |> json_response(403) - assert json_response(conn, 403) + conn + |> assign(:user, other_user) + |> post("/users/#{user.nickname}/outbox", data) + |> json_response(403) end test "it inserts an incoming create activity into the database", %{conn: conn} do @@ -741,24 +896,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn - |> assign(:relay, true) |> get("/relay/followers") |> json_response(200) assert result["first"]["orderedItems"] == [user.ap_id] end + + test "on non-federating instance, it returns 404", %{conn: conn} do + Config.put([:instance, :federating], false) + user = insert(:user) + + conn + |> assign(:user, user) + |> get("/relay/followers") + |> json_response(404) + end end describe "/relay/following" do test "it returns relay following", %{conn: conn} do result = conn - |> assign(:relay, true) |> get("/relay/following") |> json_response(200) assert result["first"]["orderedItems"] == [] end + + test "on non-federating instance, it returns 404", %{conn: conn} do + Config.put([:instance, :federating], false) + user = insert(:user) + + conn + |> assign(:user, user) + |> get("/relay/following") + |> json_response(404) + end end describe "/users/:nickname/followers" do @@ -769,32 +942,36 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn + |> assign(:user, user_two) |> get("/users/#{user_two.nickname}/followers") |> json_response(200) assert result["first"]["orderedItems"] == [user.ap_id] end - test "it returns returns a uri if the user has 'hide_followers' set", %{conn: conn} do + test "it returns a uri if the user has 'hide_followers' set", %{conn: conn} do user = insert(:user) user_two = insert(:user, hide_followers: true) User.follow(user, user_two) result = conn + |> assign(:user, user) |> get("/users/#{user_two.nickname}/followers") |> json_response(200) assert is_binary(result["first"]) end - test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is not authenticated", + test "it returns a 403 error on pages, if the user has 'hide_followers' set and the request is from another user", %{conn: conn} do - user = insert(:user, hide_followers: true) + user = insert(:user) + other_user = insert(:user, hide_followers: true) result = conn - |> get("/users/#{user.nickname}/followers?page=1") + |> assign(:user, user) + |> get("/users/#{other_user.nickname}/followers?page=1") assert result.status == 403 assert result.resp_body == "" @@ -826,6 +1003,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn + |> assign(:user, user) |> get("/users/#{user.nickname}/followers") |> json_response(200) @@ -835,12 +1013,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn + |> assign(:user, user) |> get("/users/#{user.nickname}/followers?page=2") |> json_response(200) assert length(result["orderedItems"]) == 5 assert result["totalItems"] == 15 end + + test "returns 403 if requester is not logged in", %{conn: conn} do + user = insert(:user) + + conn + |> get("/users/#{user.nickname}/followers") + |> json_response(403) + end end describe "/users/:nickname/following" do @@ -851,6 +1038,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn + |> assign(:user, user) |> get("/users/#{user.nickname}/following") |> json_response(200) @@ -858,25 +1046,28 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do end test "it returns a uri if the user has 'hide_follows' set", %{conn: conn} do - user = insert(:user, hide_follows: true) - user_two = insert(:user) + user = insert(:user) + user_two = insert(:user, hide_follows: true) User.follow(user, user_two) result = conn - |> get("/users/#{user.nickname}/following") + |> assign(:user, user) + |> get("/users/#{user_two.nickname}/following") |> json_response(200) assert is_binary(result["first"]) end - test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is not authenticated", + test "it returns a 403 error on pages, if the user has 'hide_follows' set and the request is from another user", %{conn: conn} do - user = insert(:user, hide_follows: true) + user = insert(:user) + user_two = insert(:user, hide_follows: true) result = conn - |> get("/users/#{user.nickname}/following?page=1") + |> assign(:user, user) + |> get("/users/#{user_two.nickname}/following?page=1") assert result.status == 403 assert result.resp_body == "" @@ -909,6 +1100,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn + |> assign(:user, user) |> get("/users/#{user.nickname}/following") |> json_response(200) @@ -918,12 +1110,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do result = conn + |> assign(:user, user) |> get("/users/#{user.nickname}/following?page=2") |> json_response(200) assert length(result["orderedItems"]) == 5 assert result["totalItems"] == 15 end + + test "returns 403 if requester is not logged in", %{conn: conn} do + user = insert(:user) + + conn + |> get("/users/#{user.nickname}/following") + |> json_response(403) + end end describe "delivery tracking" do @@ -1008,8 +1209,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do end end - describe "Additionnal ActivityPub C2S endpoints" do - test "/api/ap/whoami", %{conn: conn} do + describe "Additional ActivityPub C2S endpoints" do + test "GET /api/ap/whoami", %{conn: conn} do user = insert(:user) conn = @@ -1020,12 +1221,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do user = User.get_cached_by_id(user.id) assert UserView.render("user.json", %{user: user}) == json_response(conn, 200) + + conn + |> get("/api/ap/whoami") + |> json_response(403) end clear_config([:media_proxy]) clear_config([Pleroma.Upload]) - test "uploadMedia", %{conn: conn} do + test "POST /api/ap/upload_media", %{conn: conn} do user = insert(:user) desc = "Description of the image" @@ -1045,6 +1250,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do assert object["name"] == desc assert object["type"] == "Document" assert object["actor"] == user.ap_id + + conn + |> post("/api/ap/upload_media", %{"file" => image, "description" => desc}) + |> json_response(403) end end end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 2677b9e36..d5dd44cc3 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -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.ActivityPub.ActivityPubTest do @@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do alias Pleroma.Activity alias Pleroma.Builders.ActivityBuilder + alias Pleroma.Config alias Pleroma.Notification alias Pleroma.Object alias Pleroma.User @@ -15,6 +16,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.CommonAPI + alias Pleroma.Web.Federator import Pleroma.Factory import Tesla.Mock @@ -224,7 +226,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do describe "insertion" do test "drops activities beyond a certain limit" do - limit = Pleroma.Config.get([:instance, :remote_limit]) + limit = Config.get([:instance, :remote_limit]) random_text = :crypto.strong_rand_bytes(limit + 1) @@ -385,6 +387,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "create activities" do + test "it reverts create" do + user = insert(:user) + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = + ActivityPub.create(%{ + to: ["user1", "user2"], + actor: user, + context: "", + object: %{ + "to" => ["user1", "user2"], + "type" => "Note", + "content" => "testing" + } + }) + end + + assert Repo.aggregate(Activity, :count, :id) == 0 + assert Repo.aggregate(Object, :count, :id) == 0 + end + test "removes doubled 'to' recipients" do user = insert(:user) @@ -487,7 +510,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do activity_five = insert(:note_activity) user = insert(:user) - {:ok, user} = User.block(user, %{ap_id: activity_five.data["actor"]}) + {:ok, _user_relationship} = User.block(user, %{ap_id: activity_five.data["actor"]}) activities = ActivityPub.fetch_activities_for_context("2hu", %{"blocking_user" => user}) assert activities == [activity_two, activity] @@ -500,7 +523,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do activity_three = insert(:note_activity) user = insert(:user) booster = insert(:user) - {:ok, user} = User.block(user, %{ap_id: activity_one.data["actor"]}) + {:ok, _user_relationship} = User.block(user, %{ap_id: activity_one.data["actor"]}) activities = ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) @@ -509,7 +532,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert Enum.member?(activities, activity_three) refute Enum.member?(activities, activity_one) - {:ok, user} = User.unblock(user, %{ap_id: activity_one.data["actor"]}) + {:ok, _user_block} = User.unblock(user, %{ap_id: activity_one.data["actor"]}) activities = ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) @@ -518,7 +541,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert Enum.member?(activities, activity_three) assert Enum.member?(activities, activity_one) - {:ok, user} = User.block(user, %{ap_id: activity_three.data["actor"]}) + {:ok, _user_relationship} = User.block(user, %{ap_id: activity_three.data["actor"]}) {:ok, _announce, %{data: %{"id" => 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) @@ -545,7 +568,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do blockee = insert(:user) friend = insert(:user) - {:ok, blocker} = User.block(blocker, blockee) + {:ok, _user_relationship} = User.block(blocker, blockee) {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey!"}) @@ -568,7 +591,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do blockee = insert(:user) friend = insert(:user) - {:ok, blocker} = User.block(blocker, blockee) + {:ok, _user_relationship} = User.block(blocker, blockee) {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey!"}) @@ -608,13 +631,48 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do refute repeat_activity in activities end + test "does return activities from followed users on blocked domains" do + domain = "meanies.social" + domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"}) + blocker = insert(:user) + + {:ok, blocker} = User.follow(blocker, domain_user) + {:ok, blocker} = User.block_domain(blocker, domain) + + assert User.following?(blocker, domain_user) + assert User.blocks_domain?(blocker, domain_user) + refute User.blocks?(blocker, domain_user) + + 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}) + + assert activity in activities + + # And check that if the guy we DO follow boosts someone else from their domain, + # that should be hidden + 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) + + activities = + ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true}) + + refute repeat_activity in activities + end + test "doesn't return muted activities" do activity_one = insert(:note_activity) activity_two = insert(:note_activity) activity_three = insert(:note_activity) user = insert(:user) booster = insert(:user) - {:ok, user} = User.mute(user, %User{ap_id: activity_one.data["actor"]}) + + 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}) @@ -635,7 +693,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert Enum.member?(activities, activity_three) assert Enum.member?(activities, activity_one) - {:ok, user} = User.unmute(user, %User{ap_id: activity_one.data["actor"]}) + {:ok, _user_mute} = User.unmute(user, activity_one_actor) activities = ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true}) @@ -644,7 +702,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert Enum.member?(activities, activity_three) assert Enum.member?(activities, activity_one) - {:ok, user} = User.mute(user, %User{ap_id: activity_three.data["actor"]}) + 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) %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id) activity_three = Activity.get_by_id(activity_three.id) @@ -791,7 +850,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do activity = insert(:note_activity) user = insert(:user) booster = insert(:user) - {:ok, user} = CommonAPI.hide_reblogs(user, booster) + {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster) {:ok, activity, _} = CommonAPI.repeat(activity.id, booster) @@ -804,8 +863,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do activity = insert(:note_activity) user = insert(:user) booster = insert(:user) - {:ok, user} = CommonAPI.hide_reblogs(user, booster) - {:ok, user} = CommonAPI.show_reblogs(user, booster) + {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, booster) + {:ok, _reblog_mute} = CommonAPI.show_reblogs(user, booster) {:ok, activity, _} = CommonAPI.repeat(activity.id, booster) @@ -816,8 +875,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "react to an object" do - test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do - Pleroma.Config.put([:instance, :federating], true) + test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do + Config.put([:instance, :federating], true) user = insert(:user) reactor = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) @@ -825,12 +884,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") - assert called(Pleroma.Web.Federator.publish(reaction_activity)) + assert called(Federator.publish(reaction_activity)) end test "adds an emoji reaction activity to the db" do user = insert(:user) reactor = insert(:user) + third_user = insert(:user) + fourth_user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) assert object = Object.normalize(activity) @@ -839,19 +900,48 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert reaction_activity assert reaction_activity.data["actor"] == reactor.ap_id - assert reaction_activity.data["type"] == "EmojiReaction" + assert reaction_activity.data["type"] == "EmojiReact" assert reaction_activity.data["content"] == "🔥" assert reaction_activity.data["object"] == object.data["id"] assert reaction_activity.data["to"] == [User.ap_followers(reactor), activity.data["actor"]] assert reaction_activity.data["context"] == object.data["context"] assert object.data["reaction_count"] == 1 - assert object.data["reactions"]["🔥"] == [reactor.ap_id] + assert object.data["reactions"] == [["🔥", [reactor.ap_id]]] + + {:ok, _reaction_activity, object} = ActivityPub.react_with_emoji(third_user, object, "☕") + + assert object.data["reaction_count"] == 2 + assert object.data["reactions"] == [["🔥", [reactor.ap_id]], ["☕", [third_user.ap_id]]] + + {:ok, _reaction_activity, object} = ActivityPub.react_with_emoji(fourth_user, object, "🔥") + + assert object.data["reaction_count"] == 3 + + assert object.data["reactions"] == [ + ["🔥", [fourth_user.ap_id, reactor.ap_id]], + ["☕", [third_user.ap_id]] + ] + end + + test "reverts emoji reaction on error" do + [user, reactor] = insert_list(2, :user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Status"}) + object = Object.normalize(activity) + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.react_with_emoji(reactor, object, "😀") + end + + object = Object.get_by_ap_id(object.data["id"]) + refute object.data["reaction_count"] + refute object.data["reactions"] end end describe "unreacting to an object" do - test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do - Pleroma.Config.put([:instance, :federating], true) + test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do + Config.put([:instance, :federating], true) user = insert(:user) reactor = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"}) @@ -859,12 +949,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥") - assert called(Pleroma.Web.Federator.publish(reaction_activity)) + assert called(Federator.publish(reaction_activity)) {:ok, unreaction_activity, _object} = ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"]) - assert called(Pleroma.Web.Federator.publish(unreaction_activity)) + assert called(Federator.publish(unreaction_activity)) end test "adds an undo activity to the db" do @@ -883,20 +973,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do object = Object.get_by_ap_id(object.data["id"]) assert object.data["reaction_count"] == 0 - assert object.data["reactions"] == %{} + assert object.data["reactions"] == [] + end + + test "reverts emoji unreact on error" do + [user, reactor] = insert_list(2, :user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "Status"}) + object = Object.normalize(activity) + + {:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "😀") + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = + ActivityPub.unreact_with_emoji(reactor, reaction_activity.data["id"]) + end + + object = Object.get_by_ap_id(object.data["id"]) + + assert object.data["reaction_count"] == 1 + assert object.data["reactions"] == [["😀", [reactor.ap_id]]] end end describe "like an object" do - test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do - Pleroma.Config.put([:instance, :federating], true) + test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do + Config.put([:instance, :federating], true) note_activity = insert(:note_activity) assert object_activity = Object.normalize(note_activity) user = insert(:user) {:ok, like_activity, _object} = ActivityPub.like(user, object_activity) - assert called(Pleroma.Web.Federator.publish(like_activity)) + assert called(Federator.publish(like_activity)) end test "returns exist activity if object already liked" do @@ -911,6 +1019,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert like_activity == like_activity_exist end + test "reverts like activity 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.like(user, object) + end + + assert Repo.aggregate(Activity, :count, :id) == 1 + assert Repo.get(Object, object.id) == object + end + test "adds a like activity to the db" do note_activity = insert(:note_activity) assert object = Object.normalize(note_activity) @@ -941,15 +1062,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "unliking" do - test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do - Pleroma.Config.put([:instance, :federating], true) + test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do + Config.put([:instance, :federating], true) note_activity = insert(:note_activity) object = Object.normalize(note_activity) user = insert(:user) {:ok, object} = ActivityPub.unlike(user, object) - refute called(Pleroma.Web.Federator.publish()) + refute called(Federator.publish()) {:ok, _like_activity, object} = ActivityPub.like(user, object) assert object.data["like_count"] == 1 @@ -957,7 +1078,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object) assert object.data["like_count"] == 0 - assert called(Pleroma.Web.Federator.publish(unlike_activity)) + assert called(Federator.publish(unlike_activity)) + end + + test "reverts unliking on error" do + note_activity = insert(:note_activity) + object = Object.normalize(note_activity) + user = insert(:user) + + {:ok, like_activity, object} = ActivityPub.like(user, object) + assert object.data["like_count"] == 1 + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.unlike(user, object) + end + + assert Object.get_by_ap_id(object.data["id"]) == object + assert object.data["like_count"] == 1 + assert Activity.get_by_id(like_activity.id) end test "unliking a previously liked object" do @@ -999,6 +1137,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do 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 @@ -1041,8 +1194,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do user = insert(:user) # Unannouncing an object that is not announced does nothing - # {:ok, object} = ActivityPub.unannounce(user, object) - # assert object.data["announcement_count"] == 0 + {:ok, object} = ActivityPub.unannounce(user, object) + refute object.data["announcement_count"] {:ok, announce_activity, object} = ActivityPub.announce(user, object) assert object.data["announcement_count"] == 1 @@ -1062,6 +1215,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert Activity.get_by_id(announce_activity.id) == nil end + + test "reverts unannouncing on error" 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 + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.unannounce(user, object) + end + + object = Object.get_by_ap_id(object.data["id"]) + assert object.data["announcement_count"] == 1 + end end describe "uploading files" do @@ -1096,6 +1265,35 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "following / unfollowing" do + test "it reverts follow activity" do + follower = insert(:user) + followed = insert(:user) + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.follow(follower, followed) + end + + assert Repo.aggregate(Activity, :count, :id) == 0 + assert Repo.aggregate(Object, :count, :id) == 0 + end + + test "it reverts unfollow activity" do + follower = insert(:user) + followed = insert(:user) + + {:ok, follow_activity} = ActivityPub.follow(follower, followed) + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.unfollow(follower, followed) + end + + activity = Activity.get_by_id(follow_activity.id) + assert activity.data["type"] == "Follow" + assert activity.data["actor"] == follower.ap_id + + assert activity.data["object"] == followed.ap_id + end + test "creates a follow activity" do follower = insert(:user) followed = insert(:user) @@ -1122,9 +1320,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert embedded_object["object"] == followed.ap_id assert embedded_object["id"] == follow_activity.data["id"] end + + test "creates an undo activity for a pending follow request" do + follower = insert(:user) + followed = insert(:user, %{locked: true}) + + {:ok, follow_activity} = ActivityPub.follow(follower, followed) + {:ok, activity} = ActivityPub.unfollow(follower, followed) + + assert activity.data["type"] == "Undo" + assert activity.data["actor"] == follower.ap_id + + embedded_object = activity.data["object"] + assert is_map(embedded_object) + assert embedded_object["type"] == "Follow" + assert embedded_object["object"] == followed.ap_id + assert embedded_object["id"] == follow_activity.data["id"] + end end describe "blocking / unblocking" 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 blocker = insert(:user) blocked = insert(:user) @@ -1136,6 +1362,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert activity.data["object"] == blocked.ap_id end + test "reverts unblock activity on error" do + [blocker, blocked] = insert_list(2, :user) + {:ok, block_activity} = ActivityPub.block(blocker, blocked) + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.unblock(blocker, blocked) + end + + assert block_activity.data["type"] == "Block" + assert block_activity.data["actor"] == blocker.ap_id + + assert Repo.aggregate(Activity, :count, :id) == 1 + assert Repo.aggregate(Object, :count, :id) == 1 + end + test "creates an undo activity for the last block" do blocker = insert(:user) blocked = insert(:user) @@ -1155,6 +1396,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "deletion" do + clear_config([:instance, :rewrite_policy]) + + test "it reverts deletion on error" do + note = insert(:note_activity) + object = Object.normalize(note) + + with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do + assert {:error, :reverted} = ActivityPub.delete(object) + end + + assert Repo.aggregate(Activity, :count, :id) == 1 + assert Repo.get(Object, object.id) == object + assert Activity.get_by_id(note.id) == note + end + test "it creates a delete activity and deletes the original object" do note = insert(:note_activity) object = Object.normalize(note) @@ -1256,6 +1512,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert %{data: data, object: object} = Activity.get_by_ap_id_with_object(ap_id) assert object.data["repliesCount"] == 0 end + + test "it passes delete activity through MRF before deleting the object" do + Pleroma.Config.put([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.DropPolicy) + + note = insert(:note_activity) + object = Object.normalize(note) + + {:error, {:reject, _}} = ActivityPub.delete(object) + + assert Activity.get_by_id(note.id) + assert Repo.get(Object, object.id).data["type"] == object.data["type"] + end end describe "timeline post-processing" do @@ -1312,6 +1580,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "update" 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) @@ -1334,7 +1604,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end test "returned pinned statuses" do - Pleroma.Config.put([:instance, :max_pinned_statuses], 3) + Config.put([:instance, :max_pinned_statuses], 3) user = insert(:user) {:ok, activity_one} = CommonAPI.post(user, %{"status" => "HI!!!"}) @@ -1572,6 +1842,73 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do assert follow_info.following_count == 32 assert follow_info.hide_follows == true end + + test "doesn't crash when follower and following counters are hidden" do + mock(fn env -> + case env.url do + "http://localhost:4001/users/masto_hidden_counters/following" -> + json(%{ + "@context" => "https://www.w3.org/ns/activitystreams", + "id" => "http://localhost:4001/users/masto_hidden_counters/followers" + }) + + "http://localhost:4001/users/masto_hidden_counters/following?page=1" -> + %Tesla.Env{status: 403, body: ""} + + "http://localhost:4001/users/masto_hidden_counters/followers" -> + json(%{ + "@context" => "https://www.w3.org/ns/activitystreams", + "id" => "http://localhost:4001/users/masto_hidden_counters/following" + }) + + "http://localhost:4001/users/masto_hidden_counters/followers?page=1" -> + %Tesla.Env{status: 403, body: ""} + end + end) + + user = + insert(:user, + local: false, + follower_address: "http://localhost:4001/users/masto_hidden_counters/followers", + following_address: "http://localhost:4001/users/masto_hidden_counters/following" + ) + + {:ok, follow_info} = ActivityPub.fetch_follow_information_for_user(user) + + assert follow_info.hide_followers == true + assert follow_info.follower_count == 0 + assert follow_info.hide_follows == true + assert follow_info.following_count == 0 + end + end + + describe "fetch_favourites/3" do + test "returns a favourite activities sorted by adds to favorite" do + user = insert(:user) + other_user = insert(:user) + user1 = insert(:user) + user2 = insert(:user) + {:ok, a1} = CommonAPI.post(user1, %{"status" => "bla"}) + {:ok, _a2} = CommonAPI.post(user2, %{"status" => "traps are happy"}) + {:ok, a3} = CommonAPI.post(user2, %{"status" => "Trees Are "}) + {:ok, a4} = CommonAPI.post(user2, %{"status" => "Agent Smith "}) + {:ok, a5} = CommonAPI.post(user1, %{"status" => "Red or Blue "}) + + {:ok, _} = CommonAPI.favorite(user, a4.id) + {:ok, _} = CommonAPI.favorite(other_user, a3.id) + {:ok, _} = CommonAPI.favorite(user, a3.id) + {:ok, _} = CommonAPI.favorite(other_user, a5.id) + {:ok, _} = CommonAPI.favorite(user, a5.id) + {:ok, _} = CommonAPI.favorite(other_user, a4.id) + {:ok, _} = CommonAPI.favorite(user, a1.id) + {:ok, _} = CommonAPI.favorite(other_user, a1.id) + result = ActivityPub.fetch_favourites(user) + + assert Enum.map(result, & &1.id) == [a1.id, a5.id, a3.id, a4.id] + + result = ActivityPub.fetch_favourites(user, %{"limit" => 2}) + assert Enum.map(result, & &1.id) == [a1.id, a5.id] + end end describe "Move activity" do @@ -1619,10 +1956,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do activity = %Activity{activity | object: nil} assert [%Notification{activity: ^activity}] = - Notification.for_user_since(follower, ~N[2019-04-13 11:22:33]) + Notification.for_user(follower, %{with_move: true}) assert [%Notification{activity: ^activity}] = - Notification.for_user_since(follower_move_opted_out, ~N[2019-04-13 11:22:33]) + Notification.for_user(follower_move_opted_out, %{with_move: true}) end test "old user must be in the new user's `also_known_as` list" do diff --git a/test/web/activity_pub/mrf/hellthread_policy_test.exs b/test/web/activity_pub/mrf/hellthread_policy_test.exs index eb6ee4d04..916b95692 100644 --- a/test/web/activity_pub/mrf/hellthread_policy_test.exs +++ b/test/web/activity_pub/mrf/hellthread_policy_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do @@ -26,6 +26,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do [user: user, message: message] end + clear_config(:mrf_hellthread) + describe "reject" do test "rejects the message if the recipient count is above reject_threshold", %{ message: message diff --git a/test/web/activity_pub/mrf/keyword_policy_test.exs b/test/web/activity_pub/mrf/keyword_policy_test.exs index 602892a37..18242a889 100644 --- a/test/web/activity_pub/mrf/keyword_policy_test.exs +++ b/test/web/activity_pub/mrf/keyword_policy_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do @@ -7,6 +7,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do alias Pleroma.Web.ActivityPub.MRF.KeywordPolicy + clear_config(:mrf_keyword) + setup do Pleroma.Config.put([:mrf_keyword], %{reject: [], federated_timeline_removal: [], replace: []}) end diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs index 95a809d25..313d59a66 100644 --- a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs +++ b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs @@ -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.ActivityPub.MRF.MediaProxyWarmingPolicyTest do diff --git a/test/web/activity_pub/mrf/mention_policy_test.exs b/test/web/activity_pub/mrf/mention_policy_test.exs index 9fd9c31df..08f7be542 100644 --- a/test/web/activity_pub/mrf/mention_policy_test.exs +++ b/test/web/activity_pub/mrf/mention_policy_test.exs @@ -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.ActivityPub.MRF.MentionPolicyTest do @@ -7,6 +7,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do alias Pleroma.Web.ActivityPub.MRF.MentionPolicy + clear_config(:mrf_mention) + test "pass filter if allow list is empty" do Pleroma.Config.delete([:mrf_mention]) diff --git a/test/web/activity_pub/mrf/subchain_policy_test.exs b/test/web/activity_pub/mrf/subchain_policy_test.exs index f7cbcad48..221b8958e 100644 --- a/test/web/activity_pub/mrf/subchain_policy_test.exs +++ b/test/web/activity_pub/mrf/subchain_policy_test.exs @@ -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.ActivityPub.MRF.SubchainPolicyTest do @@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicyTest do "object" => %{"content" => "hi"} } + clear_config([:mrf_subchain, :match_actor]) + test "it matches and processes subchains when the actor matches a configured target" do Pleroma.Config.put([:mrf_subchain, :match_actor], %{ ~r/^https:\/\/banned.com/s => [DropPolicy] diff --git a/test/web/activity_pub/mrf/tag_policy_test.exs b/test/web/activity_pub/mrf/tag_policy_test.exs index 4aa35311e..e7793641a 100644 --- a/test/web/activity_pub/mrf/tag_policy_test.exs +++ b/test/web/activity_pub/mrf/tag_policy_test.exs @@ -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.ActivityPub.MRF.TagPolicyTest do diff --git a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs index 72084c0fd..87c9e1b29 100644 --- a/test/web/activity_pub/mrf/user_allowlist_policy_test.exs +++ b/test/web/activity_pub/mrf/user_allowlist_policy_test.exs @@ -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.ActivityPub.MRF.UserAllowListPolicyTest do use Pleroma.DataCase diff --git a/test/web/activity_pub/mrf/vocabulary_policy_test.exs b/test/web/activity_pub/mrf/vocabulary_policy_test.exs index 38309f9f1..d9207b095 100644 --- a/test/web/activity_pub/mrf/vocabulary_policy_test.exs +++ b/test/web/activity_pub/mrf/vocabulary_policy_test.exs @@ -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.ActivityPub.MRF.VocabularyPolicyTest do diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index e885e5a5a..da26b13f7 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2019 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.ActivityPub.PublisherTest do @@ -23,6 +23,31 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do :ok end + clear_config_all([:instance, :federating]) do + Pleroma.Config.put([:instance, :federating], true) + end + + describe "gather_webfinger_links/1" do + test "it returns links" do + user = insert(:user) + + expected_links = [ + %{"href" => user.ap_id, "rel" => "self", "type" => "application/activity+json"}, + %{ + "href" => user.ap_id, + "rel" => "self", + "type" => "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + }, + %{ + "rel" => "http://ostatus.org/schema/1.0/subscribe", + "template" => "#{Pleroma.Web.base_url()}/ostatus_subscribe?acct={uri}" + } + ] + + assert expected_links == Publisher.gather_webfinger_links(user) + end + end + describe "determine_inbox/2" do test "it returns sharedInbox for messages involving as:Public in to" do user = diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs index 98dc78f46..e3115dcd8 100644 --- a/test/web/activity_pub/relay_test.exs +++ b/test/web/activity_pub/relay_test.exs @@ -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.ActivityPub.RelayTest do diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs index 75cfbea2e..c3d3f9830 100644 --- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs +++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs @@ -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.ActivityPub.Transmogrifier.FollowHandlingTest do @@ -19,6 +19,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do end describe "handle_incoming" do + clear_config([:user, :deny_follow_blocked]) + test "it works for osada follow request" do user = insert(:user) @@ -78,7 +80,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do ) |> Repo.all() - assert length(accepts) == 0 + assert Enum.empty?(accepts) end test "it works for follow requests when you are already followed, creating a new accept activity" do @@ -128,7 +130,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do user = insert(:user) {:ok, target} = User.get_or_fetch("http://mastodon.example.org/users/admin") - {:ok, user} = User.block(user, target) + {:ok, _user_relationship} = User.block(user, target) data = File.read!("test/fixtures/mastodon-follow-activity.json") diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 1910de6e0..83372ec7e 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -1,9 +1,11 @@ # 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.ActivityPub.TransmogrifierTest do + use Oban.Testing, repo: Pleroma.Repo use Pleroma.DataCase + alias Pleroma.Activity alias Pleroma.Object alias Pleroma.Object.Fetcher @@ -40,7 +42,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do end @tag capture_log: true - test "it fetches replied-to activities if we don't have them" do + test "it fetches reply-to activities if we don't have them" do data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() @@ -61,7 +63,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert returned_object.data["inReplyToAtomUri"] == "https://shitposter.club/notice/2827873" end - test "it does not fetch replied-to activities beyond max_replies_depth" do + test "it does not fetch reply-to activities beyond max replies depth limit" do data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!() @@ -73,7 +75,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do data = Map.put(data, "object", object) with_mock Pleroma.Web.Federator, - allowed_incoming_reply_depth?: fn _ -> false end do + allowed_thread_distance?: fn _ -> false end do {:ok, returned_activity} = Transmogrifier.handle_incoming(data) returned_object = Object.normalize(returned_activity, false) @@ -342,7 +344,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do assert data["object"] == activity.data["object"] end - test "it works for incoming misskey likes, turning them into EmojiReactions" do + test "it works for incoming misskey likes, turning them into EmojiReacts" do user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) @@ -354,13 +356,13 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) assert data["actor"] == data["actor"] - assert data["type"] == "EmojiReaction" + assert data["type"] == "EmojiReact" assert data["id"] == data["id"] assert data["object"] == activity.data["object"] assert data["content"] == "🍮" end - test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReactions" do + test "it works for incoming misskey likes that contain unicode emojis, turning them into EmojiReacts" do user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) @@ -373,7 +375,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) assert data["actor"] == data["actor"] - assert data["type"] == "EmojiReaction" + assert data["type"] == "EmojiReact" assert data["id"] == data["id"] assert data["object"] == activity.data["object"] assert data["content"] == "⭐" @@ -391,12 +393,31 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data) assert data["actor"] == "http://mastodon.example.org/users/admin" - assert data["type"] == "EmojiReaction" + assert data["type"] == "EmojiReact" assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2" assert data["object"] == activity.data["object"] assert data["content"] == "👌" end + test "it reject invalid emoji reactions" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) + + data = + File.read!("test/fixtures/emoji-reaction-too-long.json") + |> Poison.decode!() + |> Map.put("object", activity.data["object"]) + + assert :error = Transmogrifier.handle_incoming(data) + + data = + File.read!("test/fixtures/emoji-reaction-no-emoji.json") + |> Poison.decode!() + |> Map.put("object", activity.data["object"]) + + assert :error = Transmogrifier.handle_incoming(data) + end + test "it works for incoming emoji reaction undos" do user = insert(:user) @@ -1331,6 +1352,101 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do end end + describe "`handle_incoming/2`, Mastodon format `replies` handling" do + clear_config([:activitypub, :note_replies_output_limit]) do + Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5) + end + + clear_config([:instance, :federation_incoming_replies_max_depth]) + + setup do + data = + "test/fixtures/mastodon-post-activity.json" + |> File.read!() + |> Poison.decode!() + + items = get_in(data, ["object", "replies", "first", "items"]) + assert length(items) > 0 + + %{data: data, items: items} + end + + test "schedules background fetching of `replies` items if max thread depth limit allows", %{ + data: data, + items: items + } do + Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 10) + + {:ok, _activity} = Transmogrifier.handle_incoming(data) + + for id <- items do + job_args = %{"op" => "fetch_remote", "id" => id, "depth" => 1} + assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args) + end + end + + test "does NOT schedule background fetching of `replies` beyond max thread depth limit allows", + %{data: data} do + Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0) + + {:ok, _activity} = Transmogrifier.handle_incoming(data) + + assert all_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker) == [] + end + end + + describe "`handle_incoming/2`, Pleroma format `replies` handling" do + clear_config([:activitypub, :note_replies_output_limit]) do + Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5) + end + + clear_config([:instance, :federation_incoming_replies_max_depth]) + + setup do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "post1"}) + + {:ok, reply1} = + CommonAPI.post(user, %{"status" => "reply1", "in_reply_to_status_id" => activity.id}) + + {:ok, reply2} = + CommonAPI.post(user, %{"status" => "reply2", "in_reply_to_status_id" => activity.id}) + + replies_uris = Enum.map([reply1, reply2], fn a -> a.object.data["id"] end) + + {:ok, federation_output} = Transmogrifier.prepare_outgoing(activity.data) + + Repo.delete(activity.object) + Repo.delete(activity) + + %{federation_output: federation_output, replies_uris: replies_uris} + end + + test "schedules background fetching of `replies` items if max thread depth limit allows", %{ + federation_output: federation_output, + replies_uris: replies_uris + } do + Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 1) + + {:ok, _activity} = Transmogrifier.handle_incoming(federation_output) + + for id <- replies_uris do + job_args = %{"op" => "fetch_remote", "id" => id, "depth" => 1} + assert_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker, args: job_args) + end + end + + test "does NOT schedule background fetching of `replies` beyond max thread depth limit allows", + %{federation_output: federation_output} do + Pleroma.Config.put([:instance, :federation_incoming_replies_max_depth], 0) + + {:ok, _activity} = Transmogrifier.handle_incoming(federation_output) + + assert all_enqueued(worker: Pleroma.Workers.RemoteFetcherWorker) == [] + end + end + describe "prepare outgoing" do test "it inlines private announced objects" do user = insert(:user) @@ -2029,4 +2145,49 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do } end end + + describe "set_replies/1" do + clear_config([:activitypub, :note_replies_output_limit]) do + Pleroma.Config.put([:activitypub, :note_replies_output_limit], 2) + end + + test "returns unmodified object if activity doesn't have self-replies" do + data = Poison.decode!(File.read!("test/fixtures/mastodon-post-activity.json")) + assert Transmogrifier.set_replies(data) == data + end + + test "sets `replies` collection with a limited number of self-replies" do + [user, another_user] = insert_list(2, :user) + + {:ok, %{id: id1} = activity} = CommonAPI.post(user, %{"status" => "1"}) + + {:ok, %{id: id2} = self_reply1} = + CommonAPI.post(user, %{"status" => "self-reply 1", "in_reply_to_status_id" => id1}) + + {:ok, self_reply2} = + CommonAPI.post(user, %{"status" => "self-reply 2", "in_reply_to_status_id" => id1}) + + # Assuming to _not_ be present in `replies` due to :note_replies_output_limit is set to 2 + {:ok, _} = + CommonAPI.post(user, %{"status" => "self-reply 3", "in_reply_to_status_id" => id1}) + + {:ok, _} = + CommonAPI.post(user, %{ + "status" => "self-reply to self-reply", + "in_reply_to_status_id" => id2 + }) + + {:ok, _} = + CommonAPI.post(another_user, %{ + "status" => "another user's reply", + "in_reply_to_status_id" => id1 + }) + + object = Object.normalize(activity) + replies_uris = Enum.map([self_reply1, self_reply2], fn a -> a.object.data["id"] end) + + assert %{"type" => "Collection", "items" => ^replies_uris} = + Transmogrifier.set_replies(object.data)["replies"] + end + end end diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs index 1feb076ba..e913a5148 100644 --- a/test/web/activity_pub/utils_test.exs +++ b/test/web/activity_pub/utils_test.exs @@ -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.ActivityPub.UtilsTest do @@ -177,71 +177,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do end end - describe "fetch_ordered_collection" do - import Tesla.Mock - - test "fetches the first OrderedCollectionPage when an OrderedCollection is encountered" do - mock(fn - %{method: :get, url: "http://mastodon.com/outbox"} -> - json(%{"type" => "OrderedCollection", "first" => "http://mastodon.com/outbox?page=true"}) - - %{method: :get, url: "http://mastodon.com/outbox?page=true"} -> - json(%{"type" => "OrderedCollectionPage", "orderedItems" => ["ok"]}) - end) - - assert Utils.fetch_ordered_collection("http://mastodon.com/outbox", 1) == ["ok"] - end - - test "fetches several pages in the right order one after another, but only the specified amount" do - mock(fn - %{method: :get, url: "http://example.com/outbox"} -> - json(%{ - "type" => "OrderedCollectionPage", - "orderedItems" => [0], - "next" => "http://example.com/outbox?page=1" - }) - - %{method: :get, url: "http://example.com/outbox?page=1"} -> - json(%{ - "type" => "OrderedCollectionPage", - "orderedItems" => [1], - "next" => "http://example.com/outbox?page=2" - }) - - %{method: :get, url: "http://example.com/outbox?page=2"} -> - json(%{"type" => "OrderedCollectionPage", "orderedItems" => [2]}) - end) - - assert Utils.fetch_ordered_collection("http://example.com/outbox", 0) == [0] - assert Utils.fetch_ordered_collection("http://example.com/outbox", 1) == [0, 1] - end - - test "returns an error if the url doesn't have an OrderedCollection/Page" do - mock(fn - %{method: :get, url: "http://example.com/not-an-outbox"} -> - json(%{"type" => "NotAnOutbox"}) - end) - - assert {:error, _} = Utils.fetch_ordered_collection("http://example.com/not-an-outbox", 1) - end - - test "returns the what was collected if there are less pages than specified" do - mock(fn - %{method: :get, url: "http://example.com/outbox"} -> - json(%{ - "type" => "OrderedCollectionPage", - "orderedItems" => [0], - "next" => "http://example.com/outbox?page=1" - }) - - %{method: :get, url: "http://example.com/outbox?page=1"} -> - json(%{"type" => "OrderedCollectionPage", "orderedItems" => [1]}) - end) - - assert Utils.fetch_ordered_collection("http://example.com/outbox", 5) == [0, 1] - end - end - test "make_json_ld_header/0" do assert Utils.make_json_ld_header() == %{ "@context" => [ @@ -637,46 +572,16 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do end end - describe "get_reports_grouped_by_status/1" do - setup do - [reporter, target_user] = insert_pair(:user) - first_status = insert(:note_activity, user: target_user) - second_status = insert(:note_activity, user: target_user) - - CommonAPI.report(reporter, %{ - "account_id" => target_user.id, - "comment" => "I feel offended", - "status_ids" => [first_status.id] - }) - - CommonAPI.report(reporter, %{ - "account_id" => target_user.id, - "comment" => "I feel offended2", - "status_ids" => [second_status.id] - }) - - data = [%{activity: first_status.data["id"]}, %{activity: second_status.data["id"]}] - - {:ok, - %{ - first_status: first_status, - second_status: second_status, - data: data - }} - end - - test "works for deprecated reports format", %{ - first_status: first_status, - second_status: second_status, - data: data - } do - groups = Utils.get_reports_grouped_by_status(data).groups + describe "get_cached_emoji_reactions/1" do + test "returns the data or an emtpy list" do + object = insert(:note) + assert Utils.get_cached_emoji_reactions(object) == [] - first_group = Enum.find(groups, &(&1.status.id == first_status.data["id"])) - second_group = Enum.find(groups, &(&1.status.id == second_status.data["id"])) + object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]}) + assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]] - assert first_group.status.id == first_status.data["id"] - assert second_group.status.id == second_status.data["id"] + object = insert(:note, data: %{"reactions" => %{}}) + assert Utils.get_cached_emoji_reactions(object) == [] end end end diff --git a/test/web/activity_pub/views/object_view_test.exs b/test/web/activity_pub/views/object_view_test.exs index 998247c5c..f6796ad4a 100644 --- a/test/web/activity_pub/views/object_view_test.exs +++ b/test/web/activity_pub/views/object_view_test.exs @@ -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.ActivityPub.ObjectViewTest do @@ -36,6 +36,26 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do assert result["@context"] end + describe "note activity's `replies` collection rendering" do + clear_config([:activitypub, :note_replies_output_limit]) do + Pleroma.Config.put([:activitypub, :note_replies_output_limit], 5) + end + + test "renders `replies` collection for a note activity" do + user = insert(:user) + activity = insert(:note_activity, user: user) + + {:ok, self_reply1} = + CommonAPI.post(user, %{"status" => "self-reply 1", "in_reply_to_status_id" => activity.id}) + + replies_uris = [self_reply1.object.data["id"]] + result = ObjectView.render("object.json", %{object: refresh_record(activity)}) + + assert %{"type" => "Collection", "items" => ^replies_uris} = + get_in(result, ["object", "replies"]) + end + end + test "renders a like activity" do note = insert(:note_activity) object = Object.normalize(note) diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs index 3299be2d5..ecb2dc386 100644 --- a/test/web/activity_pub/views/user_view_test.exs +++ b/test/web/activity_pub/views/user_view_test.exs @@ -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.ActivityPub.UserViewTest do @@ -126,7 +126,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) assert %{"totalItems" => 1} = UserView.render("followers.json", %{user: user}) user = Map.merge(user, %{hide_followers_count: true, hide_followers: true}) - assert %{"totalItems" => 0} = UserView.render("followers.json", %{user: user}) + refute UserView.render("followers.json", %{user: user}) |> Map.has_key?("totalItems") end test "sets correct totalItems when followers are hidden but the follower counter is not" do diff --git a/test/web/activity_pub/visibilty_test.exs b/test/web/activity_pub/visibilty_test.exs index 4c2e0d207..5b91630d4 100644 --- a/test/web/activity_pub/visibilty_test.exs +++ b/test/web/activity_pub/visibilty_test.exs @@ -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.ActivityPub.VisibilityTest do diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 32577afee..e4c152fb7 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -1,22 +1,28 @@ # 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.AdminAPI.AdminAPIControllerTest do use Pleroma.Web.ConnCase use Oban.Testing, repo: Pleroma.Repo + import Pleroma.Factory + import ExUnit.CaptureLog + alias Pleroma.Activity + alias Pleroma.Config + alias Pleroma.ConfigDB alias Pleroma.HTML alias Pleroma.ModerationLog alias Pleroma.Repo + alias Pleroma.ReportNote alias Pleroma.Tests.ObanHelpers alias Pleroma.User alias Pleroma.UserInviteToken alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.CommonAPI + alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MediaProxy - import Pleroma.Factory setup_all do Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) @@ -24,14 +30,129 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do :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 "with [:auth, :enforce_oauth_admin_scope_usage]," do + clear_config([:auth, :enforce_oauth_admin_scope_usage]) do + Config.put([:auth, :enforce_oauth_admin_scope_usage], true) + end + + test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope", + %{admin: admin} do + user = insert(:user) + url = "/api/pleroma/admin/users/#{user.nickname}" + + good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"]) + good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"]) + good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"]) + + bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"]) + bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"]) + bad_token3 = nil + + for good_token <- [good_token1, good_token2, good_token3] do + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, good_token) + |> get(url) + + assert json_response(conn, 200) + end + + for good_token <- [good_token1, good_token2, good_token3] do + conn = + build_conn() + |> assign(:user, nil) + |> assign(:token, good_token) + |> get(url) + + assert json_response(conn, :forbidden) + end + + for bad_token <- [bad_token1, bad_token2, bad_token3] do + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, bad_token) + |> get(url) + + assert json_response(conn, :forbidden) + end + end + end + + describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do + clear_config([:auth, :enforce_oauth_admin_scope_usage]) do + Config.put([:auth, :enforce_oauth_admin_scope_usage], false) + end + + test "GET /api/pleroma/admin/users/:nickname requires " <> + "read:accounts or admin:read:accounts or broader scope", + %{admin: admin} do + user = insert(:user) + url = "/api/pleroma/admin/users/#{user.nickname}" + + good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"]) + good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"]) + good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"]) + good_token4 = insert(:oauth_token, user: admin, scopes: ["read:accounts"]) + good_token5 = insert(:oauth_token, user: admin, scopes: ["read"]) + + good_tokens = [good_token1, good_token2, good_token3, good_token4, good_token5] + + bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts:partial"]) + bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"]) + bad_token3 = nil + + for good_token <- good_tokens do + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, good_token) + |> get(url) + + assert json_response(conn, 200) + end + + for good_token <- good_tokens do + conn = + build_conn() + |> assign(:user, nil) + |> assign(:token, good_token) + |> get(url) + + assert json_response(conn, :forbidden) + end + + for bad_token <- [bad_token1, bad_token2, bad_token3] do + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, bad_token) + |> get(url) + + assert json_response(conn, :forbidden) + end + end + end + describe "DELETE /api/pleroma/admin/users" do - test "single user" do - admin = insert(:user, is_admin: true) + test "single user", %{admin: admin, conn: conn} do user = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}") @@ -43,14 +164,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == user.nickname end - test "multiple users" do - admin = insert(:user, is_admin: true) + test "multiple users", %{admin: admin, conn: conn} do user_one = insert(:user) user_two = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> delete("/api/pleroma/admin/users", %{ nicknames: [user_one.nickname, user_two.nickname] @@ -67,12 +186,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "/api/pleroma/admin/users" do - test "Create" do - admin = insert(:user, is_admin: true) - + test "Create", %{conn: conn} do conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users", %{ "users" => [ @@ -97,13 +213,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == [] end - test "Cannot create user with exisiting email" do - admin = insert(:user, is_admin: true) + test "Cannot create user with existing email", %{conn: conn} do user = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users", %{ "users" => [ @@ -128,13 +242,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ] end - test "Cannot create user with exisiting nickname" do - admin = insert(:user, is_admin: true) + test "Cannot create user with existing nickname", %{conn: conn} do user = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users", %{ "users" => [ @@ -159,13 +271,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ] end - test "Multiple user creation works in transaction" do - admin = insert(:user, is_admin: true) + test "Multiple user creation works in transaction", %{conn: conn} do user = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users", %{ "users" => [ @@ -209,13 +319,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do describe "/api/pleroma/admin/users/:nickname" do test "Show", %{conn: conn} do - admin = insert(:user, is_admin: true) user = insert(:user) - conn = - conn - |> assign(:user, admin) - |> get("/api/pleroma/admin/users/#{user.nickname}") + conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}") expected = %{ "deactivated" => false, @@ -233,26 +339,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end test "when the user doesn't exist", %{conn: conn} do - admin = insert(:user, is_admin: true) user = build(:user) - conn = - conn - |> assign(:user, admin) - |> get("/api/pleroma/admin/users/#{user.nickname}") + conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}") assert "Not found" == json_response(conn, 404) end end describe "/api/pleroma/admin/users/follow" do - test "allows to force-follow another user" do - admin = insert(:user, is_admin: true) + test "allows to force-follow another user", %{admin: admin, conn: conn} do user = insert(:user) follower = insert(:user) - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users/follow", %{ "follower" => follower.nickname, @@ -272,15 +372,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "/api/pleroma/admin/users/unfollow" do - test "allows to force-unfollow another user" do - admin = insert(:user, is_admin: true) + test "allows to force-unfollow another user", %{admin: admin, conn: conn} do user = insert(:user) follower = insert(:user) User.follow(follower, user) - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users/unfollow", %{ "follower" => follower.nickname, @@ -300,23 +398,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "PUT /api/pleroma/admin/users/tag" do - setup do - admin = insert(:user, is_admin: true) + setup %{conn: conn} do user1 = insert(:user, %{tags: ["x"]}) user2 = insert(:user, %{tags: ["y"]}) user3 = insert(:user, %{tags: ["unchanged"]}) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> put( - "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{ - user2.nickname - }&tags[]=foo&tags[]=bar" + "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> + "#{user2.nickname}&tags[]=foo&tags[]=bar" ) - %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3} + %{conn: conn, user1: user1, user2: user2, user3: user3} end test "it appends specified tags to users with specified nicknames", %{ @@ -349,23 +444,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "DELETE /api/pleroma/admin/users/tag" do - setup do - admin = insert(:user, is_admin: true) + setup %{conn: conn} do user1 = insert(:user, %{tags: ["x"]}) user2 = insert(:user, %{tags: ["y", "z"]}) user3 = insert(:user, %{tags: ["unchanged"]}) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> delete( - "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=#{ - user2.nickname - }&tags[]=x&tags[]=z" + "/api/pleroma/admin/users/tag?nicknames[]=#{user1.nickname}&nicknames[]=" <> + "#{user2.nickname}&tags[]=x&tags[]=z" ) - %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3} + %{conn: conn, user1: user1, user2: user2, user3: user3} end test "it removes specified tags from users with specified nicknames", %{ @@ -398,12 +490,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "/api/pleroma/admin/users/:nickname/permission_group" do - test "GET is giving user_info" do - admin = insert(:user, is_admin: true) - + test "GET is giving user_info", %{admin: admin, conn: conn} do conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> get("/api/pleroma/admin/users/#{admin.nickname}/permission_group/") @@ -413,13 +502,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } end - test "/:right POST, can add to a permission group" do - admin = insert(:user, is_admin: true) + test "/:right POST, can add to a permission group", %{admin: admin, conn: conn} do user = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin") @@ -433,22 +520,18 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} made @#{user.nickname} admin" end - test "/:right POST, can add to a permission group (multiple)" do - admin = insert(:user, is_admin: true) + test "/:right POST, can add to a permission group (multiple)", %{admin: admin, conn: conn} do user_one = insert(:user) user_two = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users/permission_group/admin", %{ nicknames: [user_one.nickname, user_two.nickname] }) - assert json_response(conn, 200) == %{ - "is_admin" => true - } + assert json_response(conn, 200) == %{"is_admin" => true} log_entry = Repo.one(ModerationLog) @@ -456,19 +539,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} made @#{user_one.nickname}, @#{user_two.nickname} admin" end - test "/:right DELETE, can remove from a permission group" do - admin = insert(:user, is_admin: true) + test "/:right DELETE, can remove from a permission group", %{admin: admin, conn: conn} do user = insert(:user, is_admin: true) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> delete("/api/pleroma/admin/users/#{user.nickname}/permission_group/admin") - assert json_response(conn, 200) == %{ - "is_admin" => false - } + assert json_response(conn, 200) == %{"is_admin" => false} log_entry = Repo.one(ModerationLog) @@ -476,22 +555,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} revoked admin role from @#{user.nickname}" end - test "/:right DELETE, can remove from a permission group (multiple)" do - admin = insert(:user, is_admin: true) + test "/:right DELETE, can remove from a permission group (multiple)", %{ + admin: admin, + conn: conn + } do user_one = insert(:user, is_admin: true) user_two = insert(:user, is_admin: true) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> delete("/api/pleroma/admin/users/permission_group/admin", %{ nicknames: [user_one.nickname, user_two.nickname] }) - assert json_response(conn, 200) == %{ - "is_admin" => false - } + assert json_response(conn, 200) == %{"is_admin" => false} log_entry = Repo.one(ModerationLog) @@ -503,41 +581,36 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "POST /api/pleroma/admin/email_invite, with valid config" do - setup do - [user: insert(:user, is_admin: true)] - end - clear_config([:instance, :registrations_open]) do - Pleroma.Config.put([:instance, :registrations_open], false) + Config.put([:instance, :registrations_open], false) end clear_config([:instance, :invites_enabled]) do - Pleroma.Config.put([:instance, :invites_enabled], true) + Config.put([:instance, :invites_enabled], true) end - test "sends invitation and returns 204", %{conn: conn, user: user} do + test "sends invitation and returns 204", %{admin: admin, conn: conn} do recipient_email = "foo@bar.com" recipient_name = "J. D." conn = - conn - |> assign(:user, user) - |> post( + post( + conn, "/api/pleroma/admin/users/email_invite?email=#{recipient_email}&name=#{recipient_name}" ) assert json_response(conn, :no_content) - token_record = List.last(Pleroma.Repo.all(Pleroma.UserInviteToken)) + token_record = List.last(Repo.all(Pleroma.UserInviteToken)) assert token_record refute token_record.used - notify_email = Pleroma.Config.get([:instance, :notify_email]) - instance_name = Pleroma.Config.get([:instance, :name]) + notify_email = Config.get([:instance, :notify_email]) + instance_name = Config.get([:instance, :name]) email = Pleroma.Emails.UserEmail.user_invitation_email( - user, + admin, token_record, recipient_email, recipient_name @@ -550,12 +623,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ) end - test "it returns 403 if requested by a non-admin", %{conn: conn} do + 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 = - conn + build_conn() |> assign(:user, non_admin_user) + |> assign(:token, token) |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD") assert json_response(conn, :forbidden) @@ -563,45 +638,33 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "POST /api/pleroma/admin/users/email_invite, with invalid config" do - setup do - [user: insert(:user, is_admin: true)] - end - clear_config([:instance, :registrations_open]) clear_config([:instance, :invites_enabled]) - test "it returns 500 if `invites_enabled` is not enabled", %{conn: conn, user: user} do - Pleroma.Config.put([:instance, :registrations_open], false) - Pleroma.Config.put([:instance, :invites_enabled], false) + 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 - |> assign(:user, user) - |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD") + conn = post(conn, "/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD") assert json_response(conn, :internal_server_error) end - test "it returns 500 if `registrations_open` is enabled", %{conn: conn, user: user} do - Pleroma.Config.put([:instance, :registrations_open], true) - Pleroma.Config.put([:instance, :invites_enabled], true) + 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 - |> assign(:user, user) - |> post("/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD") + conn = post(conn, "/api/pleroma/admin/users/email_invite?email=foo@bar.com&name=JD") assert json_response(conn, :internal_server_error) end end - test "/api/pleroma/admin/users/:nickname/password_reset" do - admin = insert(:user, is_admin: true) + test "/api/pleroma/admin/users/:nickname/password_reset", %{conn: conn} do user = insert(:user) conn = - build_conn() - |> assign(:user, admin) + conn |> put_req_header("accept", "application/json") |> get("/api/pleroma/admin/users/#{user.nickname}/password_reset") @@ -611,16 +674,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "GET /api/pleroma/admin/users" do - setup do - admin = insert(:user, is_admin: true) - - conn = - build_conn() - |> assign(:user, admin) - - {:ok, conn: conn, admin: admin} - end - test "renders users array for the first page", %{conn: conn, admin: admin} do user = insert(:user, local: false, tags: ["foo", "bar"]) conn = get(conn, "/api/pleroma/admin/users?page=1") @@ -842,6 +895,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do test "only local users" do admin = insert(:user, is_admin: true, nickname: "john") + token = insert(:oauth_admin_token, user: admin) user = insert(:user, nickname: "bob") insert(:user, nickname: "bobb", local: false) @@ -849,6 +903,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do conn = build_conn() |> assign(:user, admin) + |> assign(:token, token) |> get("/api/pleroma/admin/users?query=bo&filters=local") assert json_response(conn, 200) == %{ @@ -870,16 +925,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } end - test "only local users with no query", %{admin: old_admin} do + test "only local users with no query", %{conn: conn, admin: old_admin} do admin = insert(:user, is_admin: true, nickname: "john") user = insert(:user, nickname: "bob") insert(:user, nickname: "bobb", local: false) - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/users?filters=local") + conn = get(conn, "/api/pleroma/admin/users?filters=local") users = [ @@ -1037,6 +1089,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do test "it works with multiple filters" do admin = insert(:user, nickname: "john", is_admin: true) + token = insert(:oauth_admin_token, user: admin) user = insert(:user, nickname: "bob", local: false, deactivated: true) insert(:user, nickname: "ken", local: true, deactivated: true) @@ -1045,6 +1098,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do conn = build_conn() |> assign(:user, admin) + |> assign(:token, token) |> get("/api/pleroma/admin/users?filters=deactivated,external") assert json_response(conn, 200) == %{ @@ -1066,13 +1120,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } end - test "it omits relay user", %{admin: admin} do + test "it omits relay user", %{admin: admin, conn: conn} do assert %User{} = Relay.get_actor() - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/users") + conn = get(conn, "/api/pleroma/admin/users") assert json_response(conn, 200) == %{ "count" => 1, @@ -1094,15 +1145,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end end - test "PATCH /api/pleroma/admin/users/activate" do - admin = insert(:user, is_admin: true) + test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do user_one = insert(:user, deactivated: true) user_two = insert(:user, deactivated: true) conn = - build_conn() - |> assign(:user, admin) - |> patch( + patch( + conn, "/api/pleroma/admin/users/activate", %{nicknames: [user_one.nickname, user_two.nickname]} ) @@ -1116,15 +1165,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}" end - test "PATCH /api/pleroma/admin/users/deactivate" do - admin = insert(:user, is_admin: true) + test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do user_one = insert(:user, deactivated: false) user_two = insert(:user, deactivated: false) conn = - build_conn() - |> assign(:user, admin) - |> patch( + patch( + conn, "/api/pleroma/admin/users/deactivate", %{nicknames: [user_one.nickname, user_two.nickname]} ) @@ -1138,14 +1185,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}" end - test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation" do - admin = insert(:user, is_admin: true) + test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do user = insert(:user) - conn = - build_conn() - |> assign(:user, admin) - |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation") + conn = patch(conn, "/api/pleroma/admin/users/#{user.nickname}/toggle_activation") assert json_response(conn, 200) == %{ @@ -1167,16 +1210,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "POST /api/pleroma/admin/users/invite_token" do - setup do - admin = insert(:user, is_admin: true) - - conn = - build_conn() - |> assign(:user, admin) - - {:ok, conn: conn} - end - test "without options", %{conn: conn} do conn = post(conn, "/api/pleroma/admin/users/invite_token") @@ -1231,16 +1264,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "GET /api/pleroma/admin/users/invites" do - setup do - admin = insert(:user, is_admin: true) - - conn = - build_conn() - |> assign(:user, admin) - - {:ok, conn: conn} - end - test "no invites", %{conn: conn} do conn = get(conn, "/api/pleroma/admin/users/invites") @@ -1269,14 +1292,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "POST /api/pleroma/admin/users/revoke_invite" do - test "with token" do - admin = insert(:user, is_admin: true) + test "with token", %{conn: conn} do {:ok, invite} = UserInviteToken.create_invite() - conn = - build_conn() - |> assign(:user, admin) - |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token}) + conn = post(conn, "/api/pleroma/admin/users/revoke_invite", %{"token" => invite.token}) assert json_response(conn, 200) == %{ "expires_at" => nil, @@ -1289,25 +1308,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } end - test "with invalid token" do - admin = insert(:user, is_admin: true) - - conn = - build_conn() - |> assign(:user, admin) - |> post("/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"}) + test "with invalid token", %{conn: conn} do + conn = post(conn, "/api/pleroma/admin/users/revoke_invite", %{"token" => "foo"}) assert json_response(conn, :not_found) == "Not found" end end describe "GET /api/pleroma/admin/reports/:id" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) - - %{conn: assign(conn, :user, admin)} - end - test "returns report by its id", %{conn: conn} do [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) @@ -1335,8 +1343,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "PATCH /api/pleroma/admin/reports" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + setup do [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) @@ -1355,13 +1362,35 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do }) %{ - conn: assign(conn, :user, admin), id: report_id, - admin: admin, 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) + |> patch("/api/pleroma/admin/reports", %{ + "reports" => [%{"state" => "resolved", "id" => id}] + }) + |> json_response(403) + + assert response == %{ + "error" => "Insufficient permissions: admin:write:reports." + } + + conn + |> assign(:token, write_token) + |> patch("/api/pleroma/admin/reports", %{ + "reports" => [%{"state" => "resolved", "id" => id}] + }) + |> json_response(:no_content) + end + test "mark report as resolved", %{conn: conn, id: id, admin: admin} do conn |> patch("/api/pleroma/admin/reports", %{ @@ -1453,12 +1482,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "GET /api/pleroma/admin/reports" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) - - %{conn: assign(conn, :user, admin)} - end - test "returns empty response when no reports created", %{conn: conn} do response = conn @@ -1553,27 +1576,27 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do 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 admin."} + 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 = - build_conn() - |> get("/api/pleroma/admin/reports") + conn = get(build_conn(), "/api/pleroma/admin/reports") assert json_response(conn, :forbidden) == %{"error" => "Invalid credentials."} end end describe "GET /api/pleroma/admin/grouped_reports" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + setup do [reporter, target_user] = insert_pair(:user) date1 = (DateTime.to_unix(DateTime.utc_now()) + 1000) |> DateTime.from_unix!() @@ -1608,10 +1631,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do }) %{ - conn: assign(conn, :user, admin), first_status: Activity.get_by_ap_id_with_object(first_status.data["id"]), second_status: Activity.get_by_ap_id_with_object(second_status.data["id"]), third_status: Activity.get_by_ap_id_with_object(third_status.data["id"]), + first_report: first_report, first_status_reports: [first_report, second_report, third_report], second_status_reports: [first_report, second_report], third_status_reports: [first_report], @@ -1638,14 +1661,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert length(response["reports"]) == 3 - first_group = - Enum.find(response["reports"], &(&1["status"]["id"] == first_status.data["id"])) + first_group = Enum.find(response["reports"], &(&1["status"]["id"] == first_status.id)) - second_group = - Enum.find(response["reports"], &(&1["status"]["id"] == second_status.data["id"])) + second_group = Enum.find(response["reports"], &(&1["status"]["id"] == second_status.id)) - third_group = - Enum.find(response["reports"], &(&1["status"]["id"] == third_status.data["id"])) + third_group = Enum.find(response["reports"], &(&1["status"]["id"] == third_status.id)) assert length(first_group["reports"]) == 3 assert length(second_group["reports"]) == 2 @@ -1656,13 +1676,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do NaiveDateTime.from_iso8601!(act.data["published"]) end).data["published"] - assert first_group["status"] == %{ - "id" => first_status.data["id"], - "content" => first_status.object.data["content"], - "published" => first_status.object.data["published"] - } + assert first_group["status"] == + Map.put( + stringify_keys(StatusView.render("show.json", %{activity: first_status})), + "deleted", + false + ) - assert first_group["account"]["id"] == target_user.id + assert(first_group["account"]["id"] == target_user.id) assert length(first_group["actors"]) == 1 assert hd(first_group["actors"])["id"] == reporter.id @@ -1675,11 +1696,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do NaiveDateTime.from_iso8601!(act.data["published"]) end).data["published"] - assert second_group["status"] == %{ - "id" => second_status.data["id"], - "content" => second_status.object.data["content"], - "published" => second_status.object.data["published"] - } + assert second_group["status"] == + Map.put( + stringify_keys(StatusView.render("show.json", %{activity: second_status})), + "deleted", + false + ) assert second_group["account"]["id"] == target_user.id @@ -1694,11 +1716,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do NaiveDateTime.from_iso8601!(act.data["published"]) end).data["published"] - assert third_group["status"] == %{ - "id" => third_status.data["id"], - "content" => third_status.object.data["content"], - "published" => third_status.object.data["published"] - } + assert third_group["status"] == + Map.put( + stringify_keys(StatusView.render("show.json", %{activity: third_status})), + "deleted", + false + ) assert third_group["account"]["id"] == target_user.id @@ -1708,69 +1731,77 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert Enum.map(third_group["reports"], & &1["id"]) -- Enum.map(third_status_reports, & &1.id) == [] end - end - describe "POST /api/pleroma/admin/reports/:id/respond" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + test "reopened report renders status data", %{ + conn: conn, + first_report: first_report, + first_status: first_status + } do + {:ok, _} = CommonAPI.update_report_state(first_report.id, "resolved") + + response = + conn + |> get("/api/pleroma/admin/grouped_reports") + |> json_response(:ok) - %{conn: assign(conn, :user, admin), admin: admin} + first_group = Enum.find(response["reports"], &(&1["status"]["id"] == first_status.id)) + + assert first_group["status"] == + Map.put( + stringify_keys(StatusView.render("show.json", %{activity: first_status})), + "deleted", + false + ) end - test "returns created dm", %{conn: conn, admin: admin} do - [reporter, target_user] = insert_pair(:user) - activity = insert(:note_activity, user: target_user) + test "reopened report does not render status data if status has been deleted", %{ + conn: conn, + first_report: first_report, + first_status: first_status, + target_user: target_user + } do + {:ok, _} = CommonAPI.update_report_state(first_report.id, "resolved") + {:ok, _} = CommonAPI.delete(first_status.id, target_user) - {:ok, %{id: report_id}} = - CommonAPI.report(reporter, %{ - "account_id" => target_user.id, - "comment" => "I feel offended", - "status_ids" => [activity.id] - }) + refute Activity.get_by_ap_id(first_status.id) response = conn - |> post("/api/pleroma/admin/reports/#{report_id}/respond", %{ - "status" => "I will check it out" - }) + |> get("/api/pleroma/admin/grouped_reports") |> json_response(:ok) - recipients = Enum.map(response["mentions"], & &1["username"]) - - assert reporter.nickname in recipients - assert response["content"] == "I will check it out" - assert response["visibility"] == "direct" - - log_entry = Repo.one(ModerationLog) + assert Enum.find(response["reports"], &(&1["status"]["deleted"] == true))["status"][ + "deleted" + ] == true - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} responded with 'I will check it out' to report ##{ - response["id"] - }" + assert length(Enum.filter(response["reports"], &(&1["status"]["deleted"] == false))) == 2 end - test "returns 400 when status is missing", %{conn: conn} do - conn = post(conn, "/api/pleroma/admin/reports/test/respond") + test "account not empty if status was deleted", %{ + conn: conn, + first_report: first_report, + first_status: first_status, + target_user: target_user + } do + {:ok, _} = CommonAPI.update_report_state(first_report.id, "resolved") + {:ok, _} = CommonAPI.delete(first_status.id, target_user) - assert json_response(conn, :bad_request) == "Invalid parameters" - end + refute Activity.get_by_ap_id(first_status.id) - test "returns 404 when report id is invalid", %{conn: conn} do - conn = - post(conn, "/api/pleroma/admin/reports/test/respond", %{ - "status" => "foo" - }) + response = + conn + |> get("/api/pleroma/admin/grouped_reports") + |> json_response(:ok) - assert json_response(conn, :not_found) == "Not found" + assert Enum.find(response["reports"], &(&1["status"]["deleted"] == true))["account"] end end describe "PUT /api/pleroma/admin/statuses/:id" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + setup do activity = insert(:note_activity) - %{conn: assign(conn, :user, admin), id: activity.id, admin: admin} + %{id: activity.id} end test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do @@ -1823,20 +1854,17 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end test "returns 400 when visibility is unknown", %{conn: conn, id: id} do - conn = - conn - |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"}) + conn = put(conn, "/api/pleroma/admin/statuses/#{id}", %{"visibility" => "test"}) assert json_response(conn, :bad_request) == "Unsupported visibility" end end describe "DELETE /api/pleroma/admin/statuses/:id" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + setup do activity = insert(:note_activity) - %{conn: assign(conn, :user, admin), id: activity.id, admin: admin} + %{id: activity.id} end test "deletes status", %{conn: conn, id: id, admin: admin} do @@ -1852,41 +1880,41 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} deleted status ##{id}" end - test "returns error when status is not exist", %{conn: conn} do - conn = - conn - |> delete("/api/pleroma/admin/statuses/test") + test "returns 404 when the status does not exist", %{conn: conn} do + conn = delete(conn, "/api/pleroma/admin/statuses/test") - assert json_response(conn, :bad_request) == "Could not delete" + assert json_response(conn, :not_found) == "Not found" end end describe "GET /api/pleroma/admin/config" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) - - %{conn: assign(conn, :user, admin)} + clear_config(:configurable_from_database) do + Config.put(:configurable_from_database, true) end - test "without any settings in db", %{conn: conn} do + test "when configuration from database is off", %{conn: conn} do + Config.put(:configurable_from_database, false) conn = get(conn, "/api/pleroma/admin/config") - assert json_response(conn, 200) == %{"configs" => []} + assert json_response(conn, 400) == + "To use this endpoint you need to enable configuration from database." end - test "with settings in db", %{conn: conn} do + test "with settings only in db", %{conn: conn} do config1 = insert(:config) config2 = insert(:config) - conn = get(conn, "/api/pleroma/admin/config") + conn = get(conn, "/api/pleroma/admin/config", %{"only_db" => true}) %{ "configs" => [ %{ + "group" => ":pleroma", "key" => key1, "value" => _ }, %{ + "group" => ":pleroma", "key" => key2, "value" => _ } @@ -1896,13 +1924,107 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert key1 == config1.key assert key2 == config2.key end + + test "db is added to settings that are in db", %{conn: conn} do + _config = insert(:config, key: ":instance", value: ConfigDB.to_binary(name: "Some name")) + + %{"configs" => configs} = + conn + |> get("/api/pleroma/admin/config") + |> json_response(200) + + [instance_config] = + Enum.filter(configs, fn %{"group" => group, "key" => key} -> + group == ":pleroma" and key == ":instance" + end) + + assert instance_config["db"] == [":name"] + end + + test "merged default setting with db settings", %{conn: conn} do + config1 = insert(:config) + config2 = insert(:config) + + config3 = + insert(:config, + value: ConfigDB.to_binary(k1: :v1, k2: :v2) + ) + + %{"configs" => configs} = + conn + |> get("/api/pleroma/admin/config") + |> json_response(200) + + assert length(configs) > 3 + + received_configs = + Enum.filter(configs, fn %{"group" => group, "key" => key} -> + group == ":pleroma" and key in [config1.key, config2.key, config3.key] + end) + + assert length(received_configs) == 3 + + db_keys = + config3.value + |> ConfigDB.from_binary() + |> Keyword.keys() + |> ConfigDB.convert() + + Enum.each(received_configs, fn %{"value" => value, "db" => db} -> + assert db in [[config1.key], [config2.key], db_keys] + + assert value in [ + ConfigDB.from_binary_with_convert(config1.value), + ConfigDB.from_binary_with_convert(config2.value), + ConfigDB.from_binary_with_convert(config3.value) + ] + end) + end + + test "subkeys with full update right merge", %{conn: conn} do + config1 = + insert(:config, + key: ":emoji", + value: ConfigDB.to_binary(groups: [a: 1, b: 2], key: [a: 1]) + ) + + config2 = + insert(:config, + key: ":assets", + value: ConfigDB.to_binary(mascots: [a: 1, b: 2], key: [a: 1]) + ) + + %{"configs" => configs} = + conn + |> get("/api/pleroma/admin/config") + |> json_response(200) + + vals = + Enum.filter(configs, fn %{"group" => group, "key" => key} -> + group == ":pleroma" and key in [config1.key, config2.key] + end) + + emoji = Enum.find(vals, fn %{"key" => key} -> key == ":emoji" end) + assets = Enum.find(vals, fn %{"key" => key} -> key == ":assets" end) + + emoji_val = ConfigDB.transform_with_out_binary(emoji["value"]) + assets_val = ConfigDB.transform_with_out_binary(assets["value"]) + + assert emoji_val[:groups] == [a: 1, b: 2] + assert assets_val[:mascots] == [a: 1, b: 2] + end end - describe "POST /api/pleroma/admin/config" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + test "POST /api/pleroma/admin/config error", %{conn: conn} do + conn = post(conn, "/api/pleroma/admin/config", %{"configs" => []}) - temp_file = "config/test.exported_from_db.secret.exs" + assert json_response(conn, 400) == + "To use this endpoint you need to enable configuration from database." + end + + describe "POST /api/pleroma/admin/config" do + setup do + http = Application.get_env(:pleroma, :http) on_exit(fn -> Application.delete_env(:pleroma, :key1) @@ -1913,30 +2035,33 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do Application.delete_env(:pleroma, :keyaa2) Application.delete_env(:pleroma, Pleroma.Web.Endpoint.NotReal) Application.delete_env(:pleroma, Pleroma.Captcha.NotReal) - :ok = File.rm(temp_file) + Application.put_env(:pleroma, :http, http) + Application.put_env(:tesla, :adapter, Tesla.Mock) + Restarter.Pleroma.refresh() end) - - %{conn: assign(conn, :user, admin)} end - clear_config([:instance, :dynamic_configuration]) do - Pleroma.Config.put([:instance, :dynamic_configuration], true) + clear_config(:configurable_from_database) do + Config.put(:configurable_from_database, true) end @tag capture_log: true test "create new config setting in db", %{conn: conn} do + ueberauth = Application.get_env(:ueberauth, Ueberauth) + on_exit(fn -> Application.put_env(:ueberauth, Ueberauth, ueberauth) end) + conn = post(conn, "/api/pleroma/admin/config", %{ configs: [ - %{group: "pleroma", key: "key1", value: "value1"}, + %{group: ":pleroma", key: ":key1", value: "value1"}, %{ - group: "ueberauth", - key: "Ueberauth.Strategy.Twitter.OAuth", + group: ":ueberauth", + key: "Ueberauth", value: [%{"tuple" => [":consumer_secret", "aaaa"]}] }, %{ - group: "pleroma", - key: "key2", + group: ":pleroma", + key: ":key2", value: %{ ":nested_1" => "nested_value1", ":nested_2" => [ @@ -1946,21 +2071,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } }, %{ - group: "pleroma", - key: "key3", + group: ":pleroma", + key: ":key3", value: [ %{"nested_3" => ":nested_3", "nested_33" => "nested_33"}, %{"nested_4" => true} ] }, %{ - group: "pleroma", - key: "key4", + group: ":pleroma", + key: ":key4", value: %{":nested_5" => ":upload", "endpoint" => "https://example.com"} }, %{ - group: "idna", - key: "key5", + group: ":idna", + key: ":key5", value: %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]} } ] @@ -1969,43 +2094,49 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == %{ "configs" => [ %{ - "group" => "pleroma", - "key" => "key1", - "value" => "value1" + "group" => ":pleroma", + "key" => ":key1", + "value" => "value1", + "db" => [":key1"] }, %{ - "group" => "ueberauth", - "key" => "Ueberauth.Strategy.Twitter.OAuth", - "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}] + "group" => ":ueberauth", + "key" => "Ueberauth", + "value" => [%{"tuple" => [":consumer_secret", "aaaa"]}], + "db" => [":consumer_secret"] }, %{ - "group" => "pleroma", - "key" => "key2", + "group" => ":pleroma", + "key" => ":key2", "value" => %{ ":nested_1" => "nested_value1", ":nested_2" => [ %{":nested_22" => "nested_value222"}, %{":nested_33" => %{":nested_44" => "nested_444"}} ] - } + }, + "db" => [":key2"] }, %{ - "group" => "pleroma", - "key" => "key3", + "group" => ":pleroma", + "key" => ":key3", "value" => [ %{"nested_3" => ":nested_3", "nested_33" => "nested_33"}, %{"nested_4" => true} - ] + ], + "db" => [":key3"] }, %{ - "group" => "pleroma", - "key" => "key4", - "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"} + "group" => ":pleroma", + "key" => ":key4", + "value" => %{"endpoint" => "https://example.com", ":nested_5" => ":upload"}, + "db" => [":key4"] }, %{ - "group" => "idna", - "key" => "key5", - "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]} + "group" => ":idna", + "key" => ":key5", + "value" => %{"tuple" => ["string", "Pleroma.Captcha.NotReal", []]}, + "db" => [":key5"] } ] } @@ -2033,25 +2164,34 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []} end - test "update config setting & delete", %{conn: conn} do - config1 = insert(:config, key: "keyaa1") - config2 = insert(:config, key: "keyaa2") + test "save configs setting without explicit key", %{conn: conn} do + level = Application.get_env(:quack, :level) + meta = Application.get_env(:quack, :meta) + webhook_url = Application.get_env(:quack, :webhook_url) - insert(:config, - group: "ueberauth", - key: "Ueberauth.Strategy.Microsoft.OAuth", - value: :erlang.term_to_binary([]) - ) + on_exit(fn -> + Application.put_env(:quack, :level, level) + Application.put_env(:quack, :meta, meta) + Application.put_env(:quack, :webhook_url, webhook_url) + end) conn = post(conn, "/api/pleroma/admin/config", %{ configs: [ - %{group: config1.group, key: config1.key, value: "another_value"}, - %{group: config2.group, key: config2.key, delete: "true"}, %{ - group: "ueberauth", - key: "Ueberauth.Strategy.Microsoft.OAuth", - delete: "true" + group: ":quack", + key: ":level", + value: ":info" + }, + %{ + group: ":quack", + key: ":meta", + value: [":none"] + }, + %{ + group: ":quack", + key: ":webhook_url", + value: "https://hooks.slack.com/services/KEY" } ] }) @@ -2059,23 +2199,400 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == %{ "configs" => [ %{ - "group" => "pleroma", + "group" => ":quack", + "key" => ":level", + "value" => ":info", + "db" => [":level"] + }, + %{ + "group" => ":quack", + "key" => ":meta", + "value" => [":none"], + "db" => [":meta"] + }, + %{ + "group" => ":quack", + "key" => ":webhook_url", + "value" => "https://hooks.slack.com/services/KEY", + "db" => [":webhook_url"] + } + ] + } + + assert Application.get_env(:quack, :level) == :info + assert Application.get_env(:quack, :meta) == [:none] + assert Application.get_env(:quack, :webhook_url) == "https://hooks.slack.com/services/KEY" + end + + test "saving config with partial update", %{conn: conn} do + config = insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: 2)) + + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{group: config.group, key: config.key, value: [%{"tuple" => [":key3", 3]}]} + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":key1", + "value" => [ + %{"tuple" => [":key1", 1]}, + %{"tuple" => [":key2", 2]}, + %{"tuple" => [":key3", 3]} + ], + "db" => [":key1", ":key2", ":key3"] + } + ] + } + end + + test "saving config which need pleroma reboot", %{conn: conn} do + chat = Config.get(:chat) + on_exit(fn -> Config.put(:chat, chat) end) + + assert post( + conn, + "/api/pleroma/admin/config", + %{ + configs: [ + %{group: ":pleroma", key: ":chat", value: [%{"tuple" => [":enabled", true]}]} + ] + } + ) + |> json_response(200) == %{ + "configs" => [ + %{ + "db" => [":enabled"], + "group" => ":pleroma", + "key" => ":chat", + "value" => [%{"tuple" => [":enabled", true]}] + } + ], + "need_reboot" => true + } + + configs = + conn + |> get("/api/pleroma/admin/config") + |> json_response(200) + + assert configs["need_reboot"] + + capture_log(fn -> + assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{} + end) =~ "pleroma restarted" + + configs = + conn + |> get("/api/pleroma/admin/config") + |> json_response(200) + + refute Map.has_key?(configs, "need_reboot") + end + + test "update setting which need reboot, don't change reboot flag until reboot", %{conn: conn} do + chat = Config.get(:chat) + on_exit(fn -> Config.put(:chat, chat) end) + + assert post( + conn, + "/api/pleroma/admin/config", + %{ + configs: [ + %{group: ":pleroma", key: ":chat", value: [%{"tuple" => [":enabled", true]}]} + ] + } + ) + |> json_response(200) == %{ + "configs" => [ + %{ + "db" => [":enabled"], + "group" => ":pleroma", + "key" => ":chat", + "value" => [%{"tuple" => [":enabled", true]}] + } + ], + "need_reboot" => true + } + + assert post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{group: ":pleroma", key: ":key1", value: [%{"tuple" => [":key3", 3]}]} + ] + }) + |> json_response(200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":key1", + "value" => [ + %{"tuple" => [":key3", 3]} + ], + "db" => [":key3"] + } + ], + "need_reboot" => true + } + + capture_log(fn -> + assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{} + end) =~ "pleroma restarted" + + configs = + conn + |> get("/api/pleroma/admin/config") + |> json_response(200) + + refute Map.has_key?(configs, "need_reboot") + end + + test "saving config with nested merge", %{conn: conn} do + config = + insert(:config, key: ":key1", value: :erlang.term_to_binary(key1: 1, key2: [k1: 1, k2: 2])) + + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{ + group: config.group, + key: config.key, + value: [ + %{"tuple" => [":key3", 3]}, + %{ + "tuple" => [ + ":key2", + [ + %{"tuple" => [":k2", 1]}, + %{"tuple" => [":k3", 3]} + ] + ] + } + ] + } + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":key1", + "value" => [ + %{"tuple" => [":key1", 1]}, + %{"tuple" => [":key3", 3]}, + %{ + "tuple" => [ + ":key2", + [ + %{"tuple" => [":k1", 1]}, + %{"tuple" => [":k2", 1]}, + %{"tuple" => [":k3", 3]} + ] + ] + } + ], + "db" => [":key1", ":key3", ":key2"] + } + ] + } + end + + test "saving special atoms", %{conn: conn} do + conn = + post(conn, "/api/pleroma/admin/config", %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":key1", + "value" => [ + %{ + "tuple" => [ + ":ssl_options", + [%{"tuple" => [":versions", [":tlsv1", ":tlsv1.1", ":tlsv1.2"]]}] + ] + } + ] + } + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":key1", + "value" => [ + %{ + "tuple" => [ + ":ssl_options", + [%{"tuple" => [":versions", [":tlsv1", ":tlsv1.1", ":tlsv1.2"]]}] + ] + } + ], + "db" => [":ssl_options"] + } + ] + } + + assert Application.get_env(:pleroma, :key1) == [ + ssl_options: [versions: [:tlsv1, :"tlsv1.1", :"tlsv1.2"]] + ] + end + + test "saving full setting if value is in full_key_update list", %{conn: conn} do + backends = Application.get_env(:logger, :backends) + on_exit(fn -> Application.put_env(:logger, :backends, backends) end) + + config = + insert(:config, + group: ":logger", + key: ":backends", + value: :erlang.term_to_binary([]) + ) + + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{ + group: config.group, + key: config.key, + value: [":console", %{"tuple" => ["ExSyslogger", ":ex_syslogger"]}] + } + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":logger", + "key" => ":backends", + "value" => [ + ":console", + %{"tuple" => ["ExSyslogger", ":ex_syslogger"]} + ], + "db" => [":backends"] + } + ] + } + + assert Application.get_env(:logger, :backends) == [ + :console, + {ExSyslogger, :ex_syslogger} + ] + + capture_log(fn -> + require Logger + Logger.warn("Ooops...") + end) =~ "Ooops..." + end + + test "saving full setting if value is not keyword", %{conn: conn} do + config = + insert(:config, + group: ":tesla", + key: ":adapter", + value: :erlang.term_to_binary(Tesla.Adapter.Hackey) + ) + + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{group: config.group, key: config.key, value: "Tesla.Adapter.Httpc"} + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":tesla", + "key" => ":adapter", + "value" => "Tesla.Adapter.Httpc", + "db" => [":adapter"] + } + ] + } + end + + test "update config setting & delete with fallback to default value", %{ + conn: conn, + admin: admin, + token: token + } do + ueberauth = Application.get_env(:ueberauth, Ueberauth) + config1 = insert(:config, key: ":keyaa1") + config2 = insert(:config, key: ":keyaa2") + + config3 = + insert(:config, + group: ":ueberauth", + key: "Ueberauth" + ) + + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{group: config1.group, key: config1.key, value: "another_value"}, + %{group: config2.group, key: config2.key, value: "another_value"} + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", "key" => config1.key, - "value" => "another_value" + "value" => "another_value", + "db" => [":keyaa1"] + }, + %{ + "group" => ":pleroma", + "key" => config2.key, + "value" => "another_value", + "db" => [":keyaa2"] } ] } assert Application.get_env(:pleroma, :keyaa1) == "another_value" - refute Application.get_env(:pleroma, :keyaa2) + assert Application.get_env(:pleroma, :keyaa2) == "another_value" + assert Application.get_env(:ueberauth, Ueberauth) == ConfigDB.from_binary(config3.value) + + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, token) + |> post("/api/pleroma/admin/config", %{ + configs: [ + %{group: config2.group, key: config2.key, delete: true}, + %{ + group: ":ueberauth", + key: "Ueberauth", + delete: true + } + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [] + } + + assert Application.get_env(:ueberauth, Ueberauth) == ueberauth + refute Keyword.has_key?(Application.get_all_env(:pleroma), :keyaa2) end test "common config example", %{conn: conn} do + adapter = Application.get_env(:tesla, :adapter) + on_exit(fn -> Application.put_env(:tesla, :adapter, adapter) end) + conn = post(conn, "/api/pleroma/admin/config", %{ configs: [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => "Pleroma.Captcha.NotReal", "value" => [ %{"tuple" => [":enabled", false]}, @@ -2087,16 +2604,25 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do %{"tuple" => [":regex1", "~r/https:\/\/example.com/"]}, %{"tuple" => [":regex2", "~r/https:\/\/example.com/u"]}, %{"tuple" => [":regex3", "~r/https:\/\/example.com/i"]}, - %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]} + %{"tuple" => [":regex4", "~r/https:\/\/example.com/s"]}, + %{"tuple" => [":name", "Pleroma"]} ] + }, + %{ + "group" => ":tesla", + "key" => ":adapter", + "value" => "Tesla.Adapter.Httpc" } ] }) + assert Application.get_env(:tesla, :adapter) == Tesla.Adapter.Httpc + assert Config.get([Pleroma.Captcha.NotReal, :name]) == "Pleroma" + assert json_response(conn, 200) == %{ "configs" => [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => "Pleroma.Captcha.NotReal", "value" => [ %{"tuple" => [":enabled", false]}, @@ -2108,8 +2634,28 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do %{"tuple" => [":regex1", "~r/https:\\/\\/example.com/"]}, %{"tuple" => [":regex2", "~r/https:\\/\\/example.com/u"]}, %{"tuple" => [":regex3", "~r/https:\\/\\/example.com/i"]}, - %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]} + %{"tuple" => [":regex4", "~r/https:\\/\\/example.com/s"]}, + %{"tuple" => [":name", "Pleroma"]} + ], + "db" => [ + ":enabled", + ":method", + ":seconds_valid", + ":path", + ":key1", + ":partial_chain", + ":regex1", + ":regex2", + ":regex3", + ":regex4", + ":name" ] + }, + %{ + "group" => ":tesla", + "key" => ":adapter", + "value" => "Tesla.Adapter.Httpc", + "db" => [":adapter"] } ] } @@ -2120,7 +2666,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do post(conn, "/api/pleroma/admin/config", %{ configs: [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => "Pleroma.Web.Endpoint.NotReal", "value" => [ %{ @@ -2184,7 +2730,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == %{ "configs" => [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => "Pleroma.Web.Endpoint.NotReal", "value" => [ %{ @@ -2240,7 +2786,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ] ] } - ] + ], + "db" => [":http"] } ] } @@ -2251,7 +2798,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do post(conn, "/api/pleroma/admin/config", %{ configs: [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => ":key1", "value" => [ %{"tuple" => [":key2", "some_val"]}, @@ -2281,7 +2828,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do %{ "configs" => [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => ":key1", "value" => [ %{"tuple" => [":key2", "some_val"]}, @@ -2302,7 +2849,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } ] } - ] + ], + "db" => [":key2", ":key3"] } ] } @@ -2313,7 +2861,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do post(conn, "/api/pleroma/admin/config", %{ configs: [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => ":key1", "value" => %{"key" => "some_val"} } @@ -2324,83 +2872,21 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do %{ "configs" => [ %{ - "group" => "pleroma", + "group" => ":pleroma", "key" => ":key1", - "value" => %{"key" => "some_val"} + "value" => %{"key" => "some_val"}, + "db" => [":key1"] } ] } end - test "dispatch setting", %{conn: conn} do - conn = - post(conn, "/api/pleroma/admin/config", %{ - configs: [ - %{ - "group" => "pleroma", - "key" => "Pleroma.Web.Endpoint.NotReal", - "value" => [ - %{ - "tuple" => [ - ":http", - [ - %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]}, - %{"tuple" => [":dispatch", ["{:_, - [ - {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, - {Phoenix.Transports.WebSocket, - {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, - {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} - ]}"]]} - ] - ] - } - ] - } - ] - }) - - dispatch_string = - "{:_, [{\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, " <> - "{\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, {Phoenix.Transports.WebSocket, " <> - "{Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, " <> - "{:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}]}" - - assert json_response(conn, 200) == %{ - "configs" => [ - %{ - "group" => "pleroma", - "key" => "Pleroma.Web.Endpoint.NotReal", - "value" => [ - %{ - "tuple" => [ - ":http", - [ - %{"tuple" => [":ip", %{"tuple" => [127, 0, 0, 1]}]}, - %{ - "tuple" => [ - ":dispatch", - [ - dispatch_string - ] - ] - } - ] - ] - } - ] - } - ] - } - end - test "queues key as atom", %{conn: conn} do conn = post(conn, "/api/pleroma/admin/config", %{ configs: [ %{ - "group" => "oban", + "group" => ":oban", "key" => ":queues", "value" => [ %{"tuple" => [":federator_incoming", 50]}, @@ -2418,7 +2904,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == %{ "configs" => [ %{ - "group" => "oban", + "group" => ":oban", "key" => ":queues", "value" => [ %{"tuple" => [":federator_incoming", 50]}, @@ -2428,6 +2914,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do %{"tuple" => [":transmogrifier", 20]}, %{"tuple" => [":scheduled_activities", 10]}, %{"tuple" => [":background", 5]} + ], + "db" => [ + ":federator_incoming", + ":federator_outgoing", + ":web_push", + ":mailer", + ":transmogrifier", + ":scheduled_activities", + ":background" ] } ] @@ -2437,7 +2932,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do test "delete part of settings by atom subkeys", %{conn: conn} do config = insert(:config, - key: "keyaa1", + key: ":keyaa1", value: :erlang.term_to_binary(subkey1: "val1", subkey2: "val2", subkey3: "val3") ) @@ -2448,68 +2943,180 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do group: config.group, key: config.key, subkeys: [":subkey1", ":subkey3"], - delete: "true" + delete: true } ] }) - assert( - json_response(conn, 200) == %{ - "configs" => [ + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":keyaa1", + "value" => [%{"tuple" => [":subkey2", "val2"]}], + "db" => [":subkey2"] + } + ] + } + end + + test "proxy tuple localhost", %{conn: conn} do + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{ + group: ":pleroma", + key: ":http", + value: [ + %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]}, + %{"tuple" => [":send_user_agent", false]} + ] + } + ] + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":http", + "value" => [ + %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "localhost", 1234]}]}, + %{"tuple" => [":send_user_agent", false]} + ], + "db" => [":proxy_url", ":send_user_agent"] + } + ] + } + end + + test "proxy tuple domain", %{conn: conn} do + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ %{ - "group" => "pleroma", - "key" => "keyaa1", - "value" => [%{"tuple" => [":subkey2", "val2"]}] + group: ":pleroma", + key: ":http", + value: [ + %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]}, + %{"tuple" => [":send_user_agent", false]} + ] } ] - } - ) + }) + + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":http", + "value" => [ + %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "domain.com", 1234]}]}, + %{"tuple" => [":send_user_agent", false]} + ], + "db" => [":proxy_url", ":send_user_agent"] + } + ] + } end - end - describe "config mix tasks run" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + test "proxy tuple ip", %{conn: conn} do + conn = + post(conn, "/api/pleroma/admin/config", %{ + configs: [ + %{ + group: ":pleroma", + key: ":http", + value: [ + %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]}, + %{"tuple" => [":send_user_agent", false]} + ] + } + ] + }) - temp_file = "config/test.exported_from_db.secret.exs" + assert json_response(conn, 200) == %{ + "configs" => [ + %{ + "group" => ":pleroma", + "key" => ":http", + "value" => [ + %{"tuple" => [":proxy_url", %{"tuple" => [":socks5", "127.0.0.1", 1234]}]}, + %{"tuple" => [":send_user_agent", false]} + ], + "db" => [":proxy_url", ":send_user_agent"] + } + ] + } + end + end - Mix.shell(Mix.Shell.Quiet) + describe "GET /api/pleroma/admin/restart" do + clear_config(:configurable_from_database) do + Config.put(:configurable_from_database, true) + end - on_exit(fn -> - Mix.shell(Mix.Shell.IO) - :ok = File.rm(temp_file) - end) + test "pleroma restarts", %{conn: conn} do + capture_log(fn -> + assert conn |> get("/api/pleroma/admin/restart") |> json_response(200) == %{} + end) =~ "pleroma restarted" - %{conn: assign(conn, :user, admin), admin: admin} + refute Restarter.Pleroma.need_reboot?() 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(200) - clear_config([:instance, :dynamic_configuration]) do - Pleroma.Config.put([:instance, :dynamic_configuration], true) + refute "private" in Enum.map(response, & &1["visibility"]) + assert length(response) == 3 end - clear_config([:feed, :post_title]) do - Pleroma.Config.put([:feed, :post_title], %{max_length: 100, omission: "…"}) + 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(200) + + assert length(response) == 1 end - test "transfer settings to DB and to file", %{conn: conn, admin: admin} do - assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == [] - conn = get(conn, "/api/pleroma/admin/config/migrate_to_db") - assert json_response(conn, 200) == %{} - assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) > 0 + test "returns private and direct statuses with godmode on", %{conn: conn, admin: admin} do + user = insert(:user) - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/config/migrate_from_db") + {:ok, _} = + CommonAPI.post(user, %{"status" => "@#{admin.nickname}", "visibility" => "direct"}) - assert json_response(conn, 200) == %{} - assert Pleroma.Repo.all(Pleroma.Web.AdminAPI.Config) == [] + {: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(conn, 200) |> length() == 3 end end describe "GET /api/pleroma/admin/users/:nickname/statuses" do setup do - admin = insert(:user, is_admin: true) user = insert(:user) date1 = (DateTime.to_unix(DateTime.utc_now()) + 2000) |> DateTime.from_unix!() @@ -2520,11 +3127,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do insert(:note_activity, user: user, published: date2) insert(:note_activity, user: user, published: date3) - conn = - build_conn() - |> assign(:user, admin) - - {:ok, conn: conn, user: user} + %{user: user} end test "renders user's statuses", %{conn: conn, user: user} do @@ -2562,14 +3165,27 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) |> length() == 5 end + + test "excludes reblogs by default", %{conn: conn, user: user} do + other_user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "."}) + {:ok, %Activity{}, _} = CommonAPI.repeat(activity.id, other_user) + + conn_res = get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses") + assert json_response(conn_res, 200) |> length() == 0 + + conn_res = + get(conn, "/api/pleroma/admin/users/#{other_user.nickname}/statuses?with_reblogs=true") + + assert json_response(conn_res, 200) |> length() == 1 + end end describe "GET /api/pleroma/admin/moderation_log" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + setup do moderator = insert(:user, is_moderator: true) - %{conn: assign(conn, :user, admin), admin: admin, moderator: moderator} + %{moderator: moderator} end test "returns the log", %{conn: conn, admin: admin} do @@ -2774,20 +3390,12 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "PATCH /users/:nickname/force_password_reset" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + test "sets password_reset_pending to true", %{conn: conn} do user = insert(:user) - - %{conn: assign(conn, :user, admin), admin: admin, user: user} - end - - test "sets password_reset_pending to true", %{admin: admin, user: user} do assert user.password_reset_pending == false conn = - build_conn() - |> assign(:user, admin) - |> patch("/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]}) + patch(conn, "/api/pleroma/admin/users/force_password_reset", %{nicknames: [user.nickname]}) assert json_response(conn, 204) == "" @@ -2798,17 +3406,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "relays" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) - - %{conn: assign(conn, :user, admin), admin: admin} - end - - test "POST /relay", %{admin: admin} do + test "POST /relay", %{conn: conn, admin: admin} do conn = - build_conn() - |> assign(:user, admin) - |> post("/api/pleroma/admin/relay", %{ + post(conn, "/api/pleroma/admin/relay", %{ relay_url: "http://mastodon.example.org/users/admin" }) @@ -2820,7 +3420,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "@#{admin.nickname} followed relay: http://mastodon.example.org/users/admin" end - test "GET /relay", %{admin: admin} do + 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"] @@ -2829,25 +3429,18 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do User.follow(relay_user, user) end) - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/relay") + conn = get(conn, "/api/pleroma/admin/relay") assert json_response(conn, 200)["relays"] -- ["mastodon.example.org", "mstdn.io"] == [] end - test "DELETE /relay", %{admin: admin} do - build_conn() - |> assign(:user, admin) - |> post("/api/pleroma/admin/relay", %{ + test "DELETE /relay", %{conn: conn, admin: admin} do + post(conn, "/api/pleroma/admin/relay", %{ relay_url: "http://mastodon.example.org/users/admin" }) conn = - build_conn() - |> assign(:user, admin) - |> delete("/api/pleroma/admin/relay", %{ + delete(conn, "/api/pleroma/admin/relay", %{ relay_url: "http://mastodon.example.org/users/admin" }) @@ -2864,63 +3457,58 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "instances" do - test "GET /instances/:instance/statuses" do - admin = insert(:user, is_admin: true) + test "GET /instances/:instance/statuses", %{conn: conn} do user = insert(:user, local: false, nickname: "archaeme@archae.me") user2 = insert(:user, local: false, nickname: "test@test.com") insert_pair(:note_activity, user: user) - insert(:note_activity, user: user2) + activity = insert(:note_activity, user: user2) - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/instances/archae.me/statuses") + ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses") - response = json_response(conn, 200) + response = json_response(ret_conn, 200) assert length(response) == 2 - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/instances/test.com/statuses") + ret_conn = get(conn, "/api/pleroma/admin/instances/test.com/statuses") - response = json_response(conn, 200) + response = json_response(ret_conn, 200) assert length(response) == 1 - conn = - build_conn() - |> assign(:user, admin) - |> get("/api/pleroma/admin/instances/nonexistent.com/statuses") + ret_conn = get(conn, "/api/pleroma/admin/instances/nonexistent.com/statuses") - response = json_response(conn, 200) + response = json_response(ret_conn, 200) - assert length(response) == 0 - end - end + assert Enum.empty?(response) - describe "PATCH /confirm_email" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) + CommonAPI.repeat(activity.id, user) + + ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses") + response = json_response(ret_conn, 200) + assert length(response) == 2 - %{conn: assign(conn, :user, admin), admin: admin} + ret_conn = get(conn, "/api/pleroma/admin/instances/archae.me/statuses?with_reblogs=true") + response = json_response(ret_conn, 200) + assert length(response) == 3 end + end - test "it confirms emails of two users", %{admin: admin} do + describe "PATCH /confirm_email" do + test "it confirms emails of two users", %{conn: conn, admin: admin} do [first_user, second_user] = insert_pair(:user, confirmation_pending: true) assert first_user.confirmation_pending == true assert second_user.confirmation_pending == true - build_conn() - |> assign(:user, admin) - |> patch("/api/pleroma/admin/users/confirm_email", %{ - nicknames: [ - first_user.nickname, - second_user.nickname - ] - }) + ret_conn = + patch(conn, "/api/pleroma/admin/users/confirm_email", %{ + nicknames: [ + first_user.nickname, + second_user.nickname + ] + }) + + assert ret_conn.status == 200 assert first_user.confirmation_pending == true assert second_user.confirmation_pending == true @@ -2935,23 +3523,18 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end describe "PATCH /resend_confirmation_email" do - setup %{conn: conn} do - admin = insert(:user, is_admin: true) - - %{conn: assign(conn, :user, admin), admin: admin} - end - - test "it resend emails for two users", %{admin: admin} do + test "it resend emails for two users", %{conn: conn, admin: admin} do [first_user, second_user] = insert_pair(:user, confirmation_pending: true) - build_conn() - |> assign(:user, admin) - |> patch("/api/pleroma/admin/users/resend_confirmation_email", %{ - nicknames: [ - first_user.nickname, - second_user.nickname - ] - }) + ret_conn = + patch(conn, "/api/pleroma/admin/users/resend_confirmation_email", %{ + nicknames: [ + first_user.nickname, + second_user.nickname + ] + }) + + assert ret_conn.status == 200 log_entry = Repo.one(ModerationLog) @@ -2961,6 +3544,100 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do }" end end + + describe "POST /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] + }) + + post(conn, "/api/pleroma/admin/reports/#{report_id}/notes", %{ + content: "this is disgusting!" + }) + + post(conn, "/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 + [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(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 + + [note, _] = Repo.all(ReportNote) + + delete(conn, "/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}") + + assert ReportNote |> Repo.all() |> length() == 1 + end + end + + test "GET /api/pleroma/admin/config/descriptions", %{conn: conn} do + admin = insert(:user, is_admin: true) + + conn = + assign(conn, :user, admin) + |> get("/api/pleroma/admin/config/descriptions") + + assert [child | _others] = json_response(conn, 200) + + assert child["children"] + assert child["key"] + assert String.starts_with?(child["group"], ":") + assert child["description"] + end + + describe "/api/pleroma/admin/stats" do + test "status visibility count", %{conn: conn} do + admin = insert(:user, is_admin: true) + user = insert(:user) + CommonAPI.post(user, %{"visibility" => "public", "status" => "hey"}) + CommonAPI.post(user, %{"visibility" => "unlisted", "status" => "hey"}) + CommonAPI.post(user, %{"visibility" => "unlisted", "status" => "hey"}) + + response = + conn + |> assign(:user, admin) + |> get("/api/pleroma/admin/stats") + |> json_response(200) + + assert %{"direct" => 0, "private" => 0, "public" => 1, "unlisted" => 2} = + response["status_visibility"] + end + end end # Needed for testing diff --git a/test/web/admin_api/config_test.exs b/test/web/admin_api/config_test.exs deleted file mode 100644 index 204446b79..000000000 --- a/test/web/admin_api/config_test.exs +++ /dev/null @@ -1,497 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.AdminAPI.ConfigTest do - use Pleroma.DataCase, async: true - import Pleroma.Factory - alias Pleroma.Web.AdminAPI.Config - - test "get_by_key/1" do - config = insert(:config) - insert(:config) - - assert config == Config.get_by_params(%{group: config.group, key: config.key}) - end - - test "create/1" do - {:ok, config} = Config.create(%{group: "pleroma", key: "some_key", value: "some_value"}) - assert config == Config.get_by_params(%{group: "pleroma", key: "some_key"}) - end - - test "update/1" do - config = insert(:config) - {:ok, updated} = Config.update(config, %{value: "some_value"}) - loaded = Config.get_by_params(%{group: config.group, key: config.key}) - assert loaded == updated - end - - test "update_or_create/1" do - config = insert(:config) - key2 = "another_key" - - params = [ - %{group: "pleroma", key: key2, value: "another_value"}, - %{group: config.group, key: config.key, value: "new_value"} - ] - - assert Repo.all(Config) |> length() == 1 - - Enum.each(params, &Config.update_or_create(&1)) - - assert Repo.all(Config) |> length() == 2 - - config1 = Config.get_by_params(%{group: config.group, key: config.key}) - config2 = Config.get_by_params(%{group: "pleroma", key: key2}) - - assert config1.value == Config.transform("new_value") - assert config2.value == Config.transform("another_value") - end - - test "delete/1" do - config = insert(:config) - {:ok, _} = Config.delete(%{key: config.key, group: config.group}) - refute Config.get_by_params(%{key: config.key, group: config.group}) - end - - describe "transform/1" do - test "string" do - binary = Config.transform("value as string") - assert binary == :erlang.term_to_binary("value as string") - assert Config.from_binary(binary) == "value as string" - end - - test "boolean" do - binary = Config.transform(false) - assert binary == :erlang.term_to_binary(false) - assert Config.from_binary(binary) == false - end - - test "nil" do - binary = Config.transform(nil) - assert binary == :erlang.term_to_binary(nil) - assert Config.from_binary(binary) == nil - end - - test "integer" do - binary = Config.transform(150) - assert binary == :erlang.term_to_binary(150) - assert Config.from_binary(binary) == 150 - end - - test "atom" do - binary = Config.transform(":atom") - assert binary == :erlang.term_to_binary(:atom) - assert Config.from_binary(binary) == :atom - end - - test "pleroma module" do - binary = Config.transform("Pleroma.Bookmark") - assert binary == :erlang.term_to_binary(Pleroma.Bookmark) - assert Config.from_binary(binary) == Pleroma.Bookmark - end - - test "phoenix module" do - binary = Config.transform("Phoenix.Socket.V1.JSONSerializer") - assert binary == :erlang.term_to_binary(Phoenix.Socket.V1.JSONSerializer) - assert Config.from_binary(binary) == Phoenix.Socket.V1.JSONSerializer - end - - test "sigil" do - binary = Config.transform("~r/comp[lL][aA][iI][nN]er/") - assert binary == :erlang.term_to_binary(~r/comp[lL][aA][iI][nN]er/) - assert Config.from_binary(binary) == ~r/comp[lL][aA][iI][nN]er/ - end - - test "link sigil" do - binary = Config.transform("~r/https:\/\/example.com/") - assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/) - assert Config.from_binary(binary) == ~r/https:\/\/example.com/ - end - - test "link sigil with u modifier" do - binary = Config.transform("~r/https:\/\/example.com/u") - assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/u) - assert Config.from_binary(binary) == ~r/https:\/\/example.com/u - end - - test "link sigil with i modifier" do - binary = Config.transform("~r/https:\/\/example.com/i") - assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/i) - assert Config.from_binary(binary) == ~r/https:\/\/example.com/i - end - - test "link sigil with s modifier" do - binary = Config.transform("~r/https:\/\/example.com/s") - assert binary == :erlang.term_to_binary(~r/https:\/\/example.com/s) - assert Config.from_binary(binary) == ~r/https:\/\/example.com/s - end - - test "2 child tuple" do - binary = Config.transform(%{"tuple" => ["v1", ":v2"]}) - assert binary == :erlang.term_to_binary({"v1", :v2}) - assert Config.from_binary(binary) == {"v1", :v2} - end - - test "tuple with n childs" do - binary = - Config.transform(%{ - "tuple" => [ - "v1", - ":v2", - "Pleroma.Bookmark", - 150, - false, - "Phoenix.Socket.V1.JSONSerializer" - ] - }) - - assert binary == - :erlang.term_to_binary( - {"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer} - ) - - assert Config.from_binary(binary) == - {"v1", :v2, Pleroma.Bookmark, 150, false, Phoenix.Socket.V1.JSONSerializer} - end - - test "tuple with dispatch key" do - binary = Config.transform(%{"tuple" => [":dispatch", ["{:_, - [ - {\"/api/v1/streaming\", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {\"/websocket\", Phoenix.Endpoint.CowboyWebSocket, - {Phoenix.Transports.WebSocket, - {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: \"/websocket\"]}}}, - {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} - ]}"]]}) - - assert binary == - :erlang.term_to_binary( - {:dispatch, - [ - {:_, - [ - {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {"/websocket", Phoenix.Endpoint.CowboyWebSocket, - {Phoenix.Transports.WebSocket, - {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: "/websocket"]}}}, - {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} - ]} - ]} - ) - - assert Config.from_binary(binary) == - {:dispatch, - [ - {:_, - [ - {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {"/websocket", Phoenix.Endpoint.CowboyWebSocket, - {Phoenix.Transports.WebSocket, - {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, [path: "/websocket"]}}}, - {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} - ]} - ]} - end - - test "map with string key" do - binary = Config.transform(%{"key" => "value"}) - assert binary == :erlang.term_to_binary(%{"key" => "value"}) - assert Config.from_binary(binary) == %{"key" => "value"} - end - - test "map with atom key" do - binary = Config.transform(%{":key" => "value"}) - assert binary == :erlang.term_to_binary(%{key: "value"}) - assert Config.from_binary(binary) == %{key: "value"} - end - - test "list of strings" do - binary = Config.transform(["v1", "v2", "v3"]) - assert binary == :erlang.term_to_binary(["v1", "v2", "v3"]) - assert Config.from_binary(binary) == ["v1", "v2", "v3"] - end - - test "list of modules" do - binary = Config.transform(["Pleroma.Repo", "Pleroma.Activity"]) - assert binary == :erlang.term_to_binary([Pleroma.Repo, Pleroma.Activity]) - assert Config.from_binary(binary) == [Pleroma.Repo, Pleroma.Activity] - end - - test "list of atoms" do - binary = Config.transform([":v1", ":v2", ":v3"]) - assert binary == :erlang.term_to_binary([:v1, :v2, :v3]) - assert Config.from_binary(binary) == [:v1, :v2, :v3] - end - - test "list of mixed values" do - binary = - Config.transform([ - "v1", - ":v2", - "Pleroma.Repo", - "Phoenix.Socket.V1.JSONSerializer", - 15, - false - ]) - - assert binary == - :erlang.term_to_binary([ - "v1", - :v2, - Pleroma.Repo, - Phoenix.Socket.V1.JSONSerializer, - 15, - false - ]) - - assert Config.from_binary(binary) == [ - "v1", - :v2, - Pleroma.Repo, - Phoenix.Socket.V1.JSONSerializer, - 15, - false - ] - end - - test "simple keyword" do - binary = Config.transform([%{"tuple" => [":key", "value"]}]) - assert binary == :erlang.term_to_binary([{:key, "value"}]) - assert Config.from_binary(binary) == [{:key, "value"}] - assert Config.from_binary(binary) == [key: "value"] - end - - test "keyword with partial_chain key" do - binary = - Config.transform([%{"tuple" => [":partial_chain", "&:hackney_connect.partial_chain/1"]}]) - - assert binary == :erlang.term_to_binary(partial_chain: &:hackney_connect.partial_chain/1) - assert Config.from_binary(binary) == [partial_chain: &:hackney_connect.partial_chain/1] - end - - test "keyword" do - binary = - Config.transform([ - %{"tuple" => [":types", "Pleroma.PostgresTypes"]}, - %{"tuple" => [":telemetry_event", ["Pleroma.Repo.Instrumenter"]]}, - %{"tuple" => [":migration_lock", nil]}, - %{"tuple" => [":key1", 150]}, - %{"tuple" => [":key2", "string"]} - ]) - - assert binary == - :erlang.term_to_binary( - types: Pleroma.PostgresTypes, - telemetry_event: [Pleroma.Repo.Instrumenter], - migration_lock: nil, - key1: 150, - key2: "string" - ) - - assert Config.from_binary(binary) == [ - types: Pleroma.PostgresTypes, - telemetry_event: [Pleroma.Repo.Instrumenter], - migration_lock: nil, - key1: 150, - key2: "string" - ] - end - - test "complex keyword with nested mixed childs" do - binary = - Config.transform([ - %{"tuple" => [":uploader", "Pleroma.Uploaders.Local"]}, - %{"tuple" => [":filters", ["Pleroma.Upload.Filter.Dedupe"]]}, - %{"tuple" => [":link_name", true]}, - %{"tuple" => [":proxy_remote", false]}, - %{"tuple" => [":common_map", %{":key" => "value"}]}, - %{ - "tuple" => [ - ":proxy_opts", - [ - %{"tuple" => [":redirect_on_failure", false]}, - %{"tuple" => [":max_body_length", 1_048_576]}, - %{ - "tuple" => [ - ":http", - [%{"tuple" => [":follow_redirect", true]}, %{"tuple" => [":pool", ":upload"]}] - ] - } - ] - ] - } - ]) - - assert binary == - :erlang.term_to_binary( - uploader: Pleroma.Uploaders.Local, - filters: [Pleroma.Upload.Filter.Dedupe], - link_name: true, - proxy_remote: false, - common_map: %{key: "value"}, - proxy_opts: [ - redirect_on_failure: false, - max_body_length: 1_048_576, - http: [ - follow_redirect: true, - pool: :upload - ] - ] - ) - - assert Config.from_binary(binary) == - [ - uploader: Pleroma.Uploaders.Local, - filters: [Pleroma.Upload.Filter.Dedupe], - link_name: true, - proxy_remote: false, - common_map: %{key: "value"}, - proxy_opts: [ - redirect_on_failure: false, - max_body_length: 1_048_576, - http: [ - follow_redirect: true, - pool: :upload - ] - ] - ] - end - - test "common keyword" do - binary = - Config.transform([ - %{"tuple" => [":level", ":warn"]}, - %{"tuple" => [":meta", [":all"]]}, - %{"tuple" => [":path", ""]}, - %{"tuple" => [":val", nil]}, - %{"tuple" => [":webhook_url", "https://hooks.slack.com/services/YOUR-KEY-HERE"]} - ]) - - assert binary == - :erlang.term_to_binary( - level: :warn, - meta: [:all], - path: "", - val: nil, - webhook_url: "https://hooks.slack.com/services/YOUR-KEY-HERE" - ) - - assert Config.from_binary(binary) == [ - level: :warn, - meta: [:all], - path: "", - val: nil, - webhook_url: "https://hooks.slack.com/services/YOUR-KEY-HERE" - ] - end - - test "complex keyword with sigil" do - binary = - Config.transform([ - %{"tuple" => [":federated_timeline_removal", []]}, - %{"tuple" => [":reject", ["~r/comp[lL][aA][iI][nN]er/"]]}, - %{"tuple" => [":replace", []]} - ]) - - assert binary == - :erlang.term_to_binary( - federated_timeline_removal: [], - reject: [~r/comp[lL][aA][iI][nN]er/], - replace: [] - ) - - assert Config.from_binary(binary) == - [federated_timeline_removal: [], reject: [~r/comp[lL][aA][iI][nN]er/], replace: []] - end - - test "complex keyword with tuples with more than 2 values" do - binary = - Config.transform([ - %{ - "tuple" => [ - ":http", - [ - %{ - "tuple" => [ - ":key1", - [ - %{ - "tuple" => [ - ":_", - [ - %{ - "tuple" => [ - "/api/v1/streaming", - "Pleroma.Web.MastodonAPI.WebsocketHandler", - [] - ] - }, - %{ - "tuple" => [ - "/websocket", - "Phoenix.Endpoint.CowboyWebSocket", - %{ - "tuple" => [ - "Phoenix.Transports.WebSocket", - %{ - "tuple" => [ - "Pleroma.Web.Endpoint", - "Pleroma.Web.UserSocket", - [] - ] - } - ] - } - ] - }, - %{ - "tuple" => [ - ":_", - "Phoenix.Endpoint.Cowboy2Handler", - %{"tuple" => ["Pleroma.Web.Endpoint", []]} - ] - } - ] - ] - } - ] - ] - } - ] - ] - } - ]) - - assert binary == - :erlang.term_to_binary( - http: [ - key1: [ - _: [ - {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {"/websocket", Phoenix.Endpoint.CowboyWebSocket, - {Phoenix.Transports.WebSocket, - {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}}, - {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} - ] - ] - ] - ) - - assert Config.from_binary(binary) == [ - http: [ - key1: [ - {:_, - [ - {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {"/websocket", Phoenix.Endpoint.CowboyWebSocket, - {Phoenix.Transports.WebSocket, - {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, []}}}, - {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} - ]} - ] - ] - ] - end - end -end diff --git a/test/web/admin_api/search_test.exs b/test/web/admin_api/search_test.exs index 082e691c4..e0e3d4153 100644 --- a/test/web/admin_api/search_test.exs +++ b/test/web/admin_api/search_test.exs @@ -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.AdminAPI.SearchTest do diff --git a/test/web/admin_api/views/report_view_test.exs b/test/web/admin_api/views/report_view_test.exs index ef4a806e4..5db6629f2 100644 --- a/test/web/admin_api/views/report_view_test.exs +++ b/test/web/admin_api/views/report_view_test.exs @@ -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.AdminAPI.ReportViewTest do @@ -30,6 +30,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user}) ), statuses: [], + notes: [], state: "open", id: activity.id } @@ -65,6 +66,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do ), statuses: [StatusView.render("show.json", %{activity: activity})], state: "open", + notes: [], id: report_activity.id } diff --git a/test/web/auth/authenticator_test.exs b/test/web/auth/authenticator_test.exs index fea5c8209..d54253343 100644 --- a/test/web/auth/authenticator_test.exs +++ b/test/web/auth/authenticator_test.exs @@ -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.AuthenticatorTest do diff --git a/test/web/chat_channel_test.exs b/test/web/chat_channel_test.exs new file mode 100644 index 000000000..68c24a9f9 --- /dev/null +++ b/test/web/chat_channel_test.exs @@ -0,0 +1,37 @@ +defmodule Pleroma.Web.ChatChannelTest do + use Pleroma.Web.ChannelCase + alias Pleroma.Web.ChatChannel + alias Pleroma.Web.UserSocket + + import Pleroma.Factory + + setup do + user = insert(:user) + + {:ok, _, socket} = + socket(UserSocket, "", %{user_name: user.nickname}) + |> subscribe_and_join(ChatChannel, "chat:public") + + {:ok, socket: socket} + end + + test "it broadcasts a message", %{socket: socket} do + push(socket, "new_msg", %{"text" => "why is tenshi eating a corndog so cute?"}) + assert_broadcast("new_msg", %{text: "why is tenshi eating a corndog so cute?"}) + end + + describe "message lengths" do + clear_config([:instance, :chat_limit]) + + test "it ignores messages of length zero", %{socket: socket} do + push(socket, "new_msg", %{"text" => ""}) + refute_broadcast("new_msg", %{text: ""}) + end + + test "it ignores messages above a certain length", %{socket: socket} do + Pleroma.Config.put([:instance, :chat_limit], 2) + push(socket, "new_msg", %{"text" => "123"}) + refute_broadcast("new_msg", %{text: "123"}) + end + end +end diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index d641f7478..c2ed1c789 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -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.CommonAPITest do @@ -14,7 +14,6 @@ defmodule Pleroma.Web.CommonAPITest do alias Pleroma.Web.CommonAPI import Pleroma.Factory - import ExUnit.CaptureLog require Pleroma.Constants @@ -69,6 +68,7 @@ defmodule Pleroma.Web.CommonAPITest do har = insert(:user) jafnhar = insert(:user) tridi = insert(:user) + Pleroma.Config.put([:instance, :safe_dm_mentions], true) {:ok, activity} = @@ -202,13 +202,15 @@ defmodule Pleroma.Web.CommonAPITest do CommonAPI.post(user, %{"status" => ""}) end - test "it returns error when character limit is exceeded" do + test "it validates character limits are correctly enforced" do Pleroma.Config.put([:instance, :limit], 5) user = insert(:user) assert {:error, "The status is over the character limit"} = CommonAPI.post(user, %{"status" => "foobar"}) + + assert {:ok, activity} = CommonAPI.post(user, %{"status" => "12345"}) end test "it can handle activities that expire" do @@ -239,7 +241,9 @@ defmodule Pleroma.Web.CommonAPITest do assert reaction.data["actor"] == user.ap_id assert reaction.data["content"] == "👍" - # TODO: test error case. + {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) + + {:error, _} = CommonAPI.react_with_emoji(activity.id, user, ".") end test "unreacting to a status with an emoji" do @@ -288,25 +292,22 @@ defmodule Pleroma.Web.CommonAPITest do assert data["object"] == post_activity.data["object"] end - test "retweeting a status twice returns an error" do + test "retweeting a status twice returns the status" do user = insert(:user) other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) - {:ok, %Activity{}, _object} = CommonAPI.repeat(activity.id, user) - {:error, _} = CommonAPI.repeat(activity.id, user) + {:ok, %Activity{} = activity, object} = CommonAPI.repeat(activity.id, user) + {:ok, ^activity, ^object} = CommonAPI.repeat(activity.id, user) end - test "favoriting a status twice returns an error" do + test "favoriting a status twice returns ok, but without the like activity" do user = insert(:user) other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) {:ok, %Activity{}} = CommonAPI.favorite(user, activity.id) - - assert capture_log(fn -> - assert {:error, _} = CommonAPI.favorite(user, activity.id) - end) =~ "[error]" + assert {:ok, :already_liked} = CommonAPI.favorite(user, activity.id) end end @@ -329,6 +330,21 @@ defmodule Pleroma.Web.CommonAPITest do assert %User{pinned_activities: [^id]} = user end + test "pin poll", %{user: user} do + {:ok, activity} = + CommonAPI.post(user, %{ + "status" => "How is fediverse today?", + "poll" => %{"options" => ["Absolutely outstanding", "Not good"], "expires_in" => 20} + }) + + assert {:ok, ^activity} = CommonAPI.pin(activity.id, user) + + id = activity.id + user = refresh_record(user) + + assert %User{pinned_activities: [^id]} = user + end + test "unlisted statuses can be pinned", %{user: user} do {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!", "visibility" => "unlisted"}) assert {:ok, ^activity} = CommonAPI.pin(activity.id, user) @@ -516,14 +532,14 @@ defmodule Pleroma.Web.CommonAPITest do end test "add a reblog mute", %{muter: muter, muted: muted} do - {:ok, muter} = CommonAPI.hide_reblogs(muter, muted) + {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muter, muted) assert User.showing_reblogs?(muter, muted) == false end test "remove a reblog mute", %{muter: muter, muted: muted} do - {:ok, muter} = CommonAPI.hide_reblogs(muter, muted) - {:ok, muter} = CommonAPI.show_reblogs(muter, muted) + {:ok, _reblog_mute} = CommonAPI.hide_reblogs(muter, muted) + {:ok, _reblog_mute} = CommonAPI.show_reblogs(muter, muted) assert User.showing_reblogs?(muter, muted) == true end @@ -533,7 +549,7 @@ defmodule Pleroma.Web.CommonAPITest do test "also unsubscribes a user" do [follower, followed] = insert_pair(:user) {:ok, follower, followed, _} = CommonAPI.follow(follower, followed) - {:ok, followed} = User.subscribe(follower, followed) + {:ok, _subscription} = User.subscribe(follower, followed) assert User.subscribed_to?(follower, followed) @@ -541,6 +557,50 @@ defmodule Pleroma.Web.CommonAPITest do refute User.subscribed_to?(follower, followed) end + + test "cancels a pending follow for a local user" do + follower = insert(:user) + followed = insert(:user, locked: true) + + assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} = + CommonAPI.follow(follower, followed) + + assert User.get_follow_state(follower, followed) == "pending" + assert {:ok, follower} = CommonAPI.unfollow(follower, followed) + assert User.get_follow_state(follower, followed) == nil + + assert %{id: ^activity_id, data: %{"state" => "cancelled"}} = + Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(follower, followed) + + assert %{ + data: %{ + "type" => "Undo", + "object" => %{"type" => "Follow", "state" => "cancelled"} + } + } = Pleroma.Web.ActivityPub.Utils.fetch_latest_undo(follower) + end + + test "cancels a pending follow for a remote user" do + follower = insert(:user) + followed = insert(:user, locked: true, local: false, ap_enabled: true) + + assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} = + CommonAPI.follow(follower, followed) + + assert User.get_follow_state(follower, followed) == "pending" + assert {:ok, follower} = CommonAPI.unfollow(follower, followed) + assert User.get_follow_state(follower, followed) == nil + + assert %{id: ^activity_id, data: %{"state" => "cancelled"}} = + Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(follower, followed) + + assert %{ + data: %{ + "type" => "Undo", + "object" => %{"type" => "Follow", "state" => "cancelled"} + } + } = Pleroma.Web.ActivityPub.Utils.fetch_latest_undo(follower) + end end describe "accept_follow_request/2" do diff --git a/test/web/common_api/common_api_utils_test.exs b/test/web/common_api/common_api_utils_test.exs index 2588898d0..45fc94522 100644 --- a/test/web/common_api/common_api_utils_test.exs +++ b/test/web/common_api/common_api_utils_test.exs @@ -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.CommonAPI.UtilsTest do @@ -89,8 +89,8 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do assert output == expected - text = "<p>hello world!</p>\n\n<p>second paragraph</p>" - expected = "<p>hello world!</p>\n\n<p>second paragraph</p>" + text = "<p>hello world!</p><br/>\n<p>second paragraph</p>" + expected = "<p>hello world!</p><br/>\n<p>second paragraph</p>" {output, [], []} = Utils.format_input(text, "text/html") @@ -99,14 +99,14 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do test "works for bare text/markdown" do text = "**hello world**" - expected = "<p><strong>hello world</strong></p>\n" + expected = "<p><strong>hello world</strong></p>" {output, [], []} = Utils.format_input(text, "text/markdown") assert output == expected text = "**hello world**\n\n*another paragraph*" - expected = "<p><strong>hello world</strong></p>\n<p><em>another paragraph</em></p>\n" + expected = "<p><strong>hello world</strong></p><p><em>another paragraph</em></p>" {output, [], []} = Utils.format_input(text, "text/markdown") @@ -118,7 +118,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do by someone """ - expected = "<blockquote><p>cool quote</p>\n</blockquote>\n<p>by someone</p>\n" + expected = "<blockquote><p>cool quote</p></blockquote><p>by someone</p>" {output, [], []} = Utils.format_input(text, "text/markdown") @@ -134,7 +134,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do assert output == expected text = "[b]hello world![/b]\n\nsecond paragraph!" - expected = "<strong>hello world!</strong><br>\n<br>\nsecond paragraph!" + expected = "<strong>hello world!</strong><br><br>second paragraph!" {output, [], []} = Utils.format_input(text, "text/bbcode") @@ -143,7 +143,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do text = "[b]hello world![/b]\n\n<strong>second paragraph!</strong>" expected = - "<strong>hello world!</strong><br>\n<br>\n<strong>second paragraph!</strong>" + "<strong>hello world!</strong><br><br><strong>second paragraph!</strong>" {output, [], []} = Utils.format_input(text, "text/bbcode") @@ -156,16 +156,14 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do text = "**hello world**\n\n*another @user__test and @user__test google.com paragraph*" - expected = - ~s(<p><strong>hello world</strong></p>\n<p><em>another <span class="h-card"><a data-user="#{ - user.id - }" class="u-url mention" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> and <span class="h-card"><a data-user="#{ - user.id - }" class="u-url mention" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> <a href="http://google.com" rel="ugc">google.com</a> paragraph</em></p>\n) - {output, _, _} = Utils.format_input(text, "text/markdown") - assert output == expected + assert output == + ~s(<p><strong>hello world</strong></p><p><em>another <span class="h-card"><a data-user="#{ + user.id + }" class="u-url mention" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> and <span class="h-card"><a data-user="#{ + user.id + }" class="u-url mention" href="http://foo.com/user__test" rel="ugc">@<span>user__test</span></a></span> <a href="http://google.com" rel="ugc">google.com</a> paragraph</em></p>) end end @@ -307,7 +305,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "private", nil) assert length(to) == 2 - assert length(cc) == 0 + assert Enum.empty?(cc) assert mentioned_user.ap_id in to assert user.follower_address in to @@ -323,7 +321,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "private", nil) assert length(to) == 3 - assert length(cc) == 0 + assert Enum.empty?(cc) assert mentioned_user.ap_id in to assert third_user.ap_id in to @@ -338,7 +336,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do {to, cc} = Utils.get_to_and_cc(user, mentions, nil, "direct", nil) assert length(to) == 1 - assert length(cc) == 0 + assert Enum.empty?(cc) assert mentioned_user.ap_id in to end @@ -353,7 +351,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do {to, cc} = Utils.get_to_and_cc(user, mentions, activity, "direct", nil) assert length(to) == 2 - assert length(cc) == 0 + assert Enum.empty?(cc) assert mentioned_user.ap_id in to assert third_user.ap_id in to @@ -575,11 +573,11 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do end describe "maybe_add_attachments/3" do - test "returns parsed results when no_links is true" do + test "returns parsed results when attachment_links is false" do assert Utils.maybe_add_attachments( {"test", [], ["tags"]}, [], - true + false ) == {"test", [], ["tags"]} end @@ -589,7 +587,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do assert Utils.maybe_add_attachments( {"test", [], ["tags"]}, [attachment], - false + true ) == { "test<br><a href=\"SakuraPM.png\" class='attachment'>SakuraPM.png</a>", [], diff --git a/test/web/fallback_test.exs b/test/web/fallback_test.exs index c13db9526..3919ef93a 100644 --- a/test/web/fallback_test.exs +++ b/test/web/fallback_test.exs @@ -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.FallbackTest do diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs index c224197c3..d2ee2267c 100644 --- a/test/web/federator_test.exs +++ b/test/web/federator_test.exs @@ -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.FederatorTest do diff --git a/test/web/feed/feed_controller_test.exs b/test/web/feed/feed_controller_test.exs deleted file mode 100644 index 6f61acf43..000000000 --- a/test/web/feed/feed_controller_test.exs +++ /dev/null @@ -1,251 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.Feed.FeedControllerTest do - use Pleroma.Web.ConnCase - - import Pleroma.Factory - import SweetXml - - alias Pleroma.Object - alias Pleroma.User - - clear_config([:feed]) - - test "gets a feed", %{conn: conn} do - Pleroma.Config.put( - [:feed, :post_title], - %{max_length: 10, omission: "..."} - ) - - activity = insert(:note_activity) - - note = - insert(:note, - data: %{ - "content" => "This is :moominmamma: note ", - "attachment" => [ - %{ - "url" => [%{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"}] - } - ], - "inReplyTo" => activity.data["id"] - } - ) - - note_activity = insert(:note_activity, note: note) - user = User.get_cached_by_ap_id(note_activity.data["actor"]) - - note2 = - insert(:note, - user: user, - data: %{"content" => "42 This is :moominmamma: note ", "inReplyTo" => activity.data["id"]} - ) - - _note_activity2 = insert(:note_activity, note: note2) - object = Object.normalize(note_activity) - - resp = - conn - |> put_req_header("content-type", "application/atom+xml") - |> get("/users/#{user.nickname}/feed.atom") - |> response(200) - - activity_titles = - resp - |> SweetXml.parse() - |> SweetXml.xpath(~x"//entry/title/text()"l) - - assert activity_titles == ['42 This...', 'This is...'] - assert resp =~ object.data["content"] - end - - test "returns 404 for a missing feed", %{conn: conn} do - conn = - conn - |> put_req_header("content-type", "application/atom+xml") - |> get("/users/nonexisting/feed.atom") - - assert response(conn, 404) - end - - describe "feed_redirect" do - test "undefined format. it redirects to feed", %{conn: conn} do - note_activity = insert(:note_activity) - user = User.get_cached_by_ap_id(note_activity.data["actor"]) - - response = - conn - |> put_req_header("accept", "application/xml") - |> get("/users/#{user.nickname}") - |> response(302) - - assert response == - "<html><body>You are being <a href=\"#{Pleroma.Web.base_url()}/users/#{ - user.nickname - }/feed.atom\">redirected</a>.</body></html>" - end - - test "undefined format. it returns error when user not found", %{conn: conn} do - response = - conn - |> put_req_header("accept", "application/xml") - |> get("/users/jimm") - |> response(404) - - assert response == ~S({"error":"Not found"}) - end - - test "activity+json format. it redirects on actual feed of user", %{conn: conn} do - note_activity = insert(:note_activity) - user = User.get_cached_by_ap_id(note_activity.data["actor"]) - - response = - conn - |> put_req_header("accept", "application/activity+json") - |> get("/users/#{user.nickname}") - |> json_response(200) - - assert response["endpoints"] == %{ - "oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize", - "oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps", - "oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token", - "sharedInbox" => "#{Pleroma.Web.base_url()}/inbox", - "uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media" - } - - assert response["@context"] == [ - "https://www.w3.org/ns/activitystreams", - "http://localhost:4001/schemas/litepub-0.1.jsonld", - %{"@language" => "und"} - ] - - assert Map.take(response, [ - "followers", - "following", - "id", - "inbox", - "manuallyApprovesFollowers", - "name", - "outbox", - "preferredUsername", - "summary", - "tag", - "type", - "url" - ]) == %{ - "followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers", - "following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following", - "id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}", - "inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox", - "manuallyApprovesFollowers" => false, - "name" => user.name, - "outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox", - "preferredUsername" => user.nickname, - "summary" => user.bio, - "tag" => [], - "type" => "Person", - "url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}" - } - end - - test "activity+json format. it returns error whe use not found", %{conn: conn} do - response = - conn - |> put_req_header("accept", "application/activity+json") - |> get("/users/jimm") - |> json_response(404) - - assert response == "Not found" - end - - test "json format. it redirects on actual feed of user", %{conn: conn} do - note_activity = insert(:note_activity) - user = User.get_cached_by_ap_id(note_activity.data["actor"]) - - response = - conn - |> put_req_header("accept", "application/json") - |> get("/users/#{user.nickname}") - |> json_response(200) - - assert response["endpoints"] == %{ - "oauthAuthorizationEndpoint" => "#{Pleroma.Web.base_url()}/oauth/authorize", - "oauthRegistrationEndpoint" => "#{Pleroma.Web.base_url()}/api/v1/apps", - "oauthTokenEndpoint" => "#{Pleroma.Web.base_url()}/oauth/token", - "sharedInbox" => "#{Pleroma.Web.base_url()}/inbox", - "uploadMedia" => "#{Pleroma.Web.base_url()}/api/ap/upload_media" - } - - assert response["@context"] == [ - "https://www.w3.org/ns/activitystreams", - "http://localhost:4001/schemas/litepub-0.1.jsonld", - %{"@language" => "und"} - ] - - assert Map.take(response, [ - "followers", - "following", - "id", - "inbox", - "manuallyApprovesFollowers", - "name", - "outbox", - "preferredUsername", - "summary", - "tag", - "type", - "url" - ]) == %{ - "followers" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/followers", - "following" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/following", - "id" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}", - "inbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/inbox", - "manuallyApprovesFollowers" => false, - "name" => user.name, - "outbox" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}/outbox", - "preferredUsername" => user.nickname, - "summary" => user.bio, - "tag" => [], - "type" => "Person", - "url" => "#{Pleroma.Web.base_url()}/users/#{user.nickname}" - } - end - - test "json format. it returns error whe use not found", %{conn: conn} do - response = - conn - |> put_req_header("accept", "application/json") - |> get("/users/jimm") - |> json_response(404) - - assert response == "Not found" - end - - test "html format. it redirects on actual feed of user", %{conn: conn} do - note_activity = insert(:note_activity) - user = User.get_cached_by_ap_id(note_activity.data["actor"]) - - response = - conn - |> get("/users/#{user.nickname}") - |> response(200) - - assert response == - Fallback.RedirectController.redirector_with_meta( - conn, - %{user: user} - ).resp_body - end - - test "html format. it returns error when user not found", %{conn: conn} do - response = - conn - |> get("/users/jimm") - |> json_response(404) - - assert response == %{"error" => "Not found"} - end - end -end diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs new file mode 100644 index 000000000..5950605e8 --- /dev/null +++ b/test/web/feed/tag_controller_test.exs @@ -0,0 +1,154 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Feed.TagControllerTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + import SweetXml + + alias Pleroma.Web.Feed.FeedView + + clear_config([:feed]) + + test "gets a feed (ATOM)", %{conn: conn} do + Pleroma.Config.put( + [:feed, :post_title], + %{max_length: 25, omission: "..."} + ) + + user = insert(:user) + {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) + + object = Pleroma.Object.normalize(activity1) + + object_data = + Map.put(object.data, "attachment", [ + %{ + "url" => [ + %{ + "href" => + "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4", + "mediaType" => "video/mp4", + "type" => "Link" + } + ] + } + ]) + + object + |> Ecto.Changeset.change(data: object_data) + |> Pleroma.Repo.update() + + {:ok, _activity2} = + Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) + + {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"}) + + response = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get(tag_feed_path(conn, :feed, "pleromaart.atom")) + |> response(200) + + xml = parse(response) + + assert xpath(xml, ~x"//feed/title/text()") == '#pleromaart' + + assert xpath(xml, ~x"//feed/entry/title/text()"l) == [ + '42 This is :moominmamm...', + 'yeah #PleromaArt' + ] + + assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname] + assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id] + end + + test "gets a feed (RSS)", %{conn: conn} do + Pleroma.Config.put( + [:feed, :post_title], + %{max_length: 25, omission: "..."} + ) + + user = insert(:user) + {:ok, activity1} = Pleroma.Web.CommonAPI.post(user, %{"status" => "yeah #PleromaArt"}) + + object = Pleroma.Object.normalize(activity1) + + object_data = + Map.put(object.data, "attachment", [ + %{ + "url" => [ + %{ + "href" => + "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4", + "mediaType" => "video/mp4", + "type" => "Link" + } + ] + } + ]) + + object + |> Ecto.Changeset.change(data: object_data) + |> Pleroma.Repo.update() + + {:ok, activity2} = + Pleroma.Web.CommonAPI.post(user, %{"status" => "42 This is :moominmamma #PleromaArt"}) + + {:ok, _activity3} = Pleroma.Web.CommonAPI.post(user, %{"status" => "This is :moominmamma"}) + + response = + conn + |> put_req_header("content-type", "application/rss+xml") + |> get(tag_feed_path(conn, :feed, "pleromaart.rss")) + |> response(200) + + xml = parse(response) + assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart' + + assert xpath(xml, ~x"//channel/description/text()"s) == + "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse." + + assert xpath(xml, ~x"//channel/link/text()") == + '#{Pleroma.Web.base_url()}/tags/pleromaart.rss' + + assert xpath(xml, ~x"//channel/webfeeds:logo/text()") == + '#{Pleroma.Web.base_url()}/static/logo.png' + + assert xpath(xml, ~x"//channel/item/title/text()"l) == [ + '42 This is :moominmamm...', + 'yeah #PleromaArt' + ] + + assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [ + FeedView.pub_date(activity1.data["published"]), + FeedView.pub_date(activity2.data["published"]) + ] + + assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [ + "https://peertube.moe/static/webseed/df5f464b-be8d-46fb-ad81-2d4c2d1630e3-480.mp4" + ] + + obj1 = Pleroma.Object.normalize(activity1) + obj2 = Pleroma.Object.normalize(activity2) + + assert xpath(xml, ~x"//channel/item/description/text()"sl) == [ + HtmlEntities.decode(FeedView.activity_content(obj2)), + HtmlEntities.decode(FeedView.activity_content(obj1)) + ] + + response = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get(tag_feed_path(conn, :feed, "pleromaart")) + |> response(200) + + xml = parse(response) + assert xpath(xml, ~x"//channel/title/text()") == '#pleromaart' + + assert xpath(xml, ~x"//channel/description/text()"s) == + "These are public toots tagged with #pleromaart. You can interact with them if you have an account anywhere in the fediverse." + end +end diff --git a/test/web/feed/user_controller_test.exs b/test/web/feed/user_controller_test.exs new file mode 100644 index 000000000..00c50f003 --- /dev/null +++ b/test/web/feed/user_controller_test.exs @@ -0,0 +1,137 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Feed.UserControllerTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + import SweetXml + + alias Pleroma.Config + alias Pleroma.Object + alias Pleroma.User + + clear_config([:instance, :federating]) do + Config.put([:instance, :federating], true) + end + + describe "feed" do + clear_config([:feed]) + + test "gets a feed", %{conn: conn} do + Config.put( + [:feed, :post_title], + %{max_length: 10, omission: "..."} + ) + + activity = insert(:note_activity) + + note = + insert(:note, + data: %{ + "content" => "This is :moominmamma: note ", + "attachment" => [ + %{ + "url" => [ + %{"mediaType" => "image/png", "href" => "https://pleroma.gov/image.png"} + ] + } + ], + "inReplyTo" => activity.data["id"] + } + ) + + note_activity = insert(:note_activity, note: note) + user = User.get_cached_by_ap_id(note_activity.data["actor"]) + + note2 = + insert(:note, + user: user, + data: %{ + "content" => "42 This is :moominmamma: note ", + "inReplyTo" => activity.data["id"] + } + ) + + _note_activity2 = insert(:note_activity, note: note2) + object = Object.normalize(note_activity) + + resp = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get(user_feed_path(conn, :feed, user.nickname)) + |> response(200) + + activity_titles = + resp + |> SweetXml.parse() + |> SweetXml.xpath(~x"//entry/title/text()"l) + + assert activity_titles == ['42 This...', 'This is...'] + assert resp =~ object.data["content"] + end + + test "returns 404 for a missing feed", %{conn: conn} do + conn = + conn + |> put_req_header("content-type", "application/atom+xml") + |> get(user_feed_path(conn, :feed, "nonexisting")) + + assert response(conn, 404) + end + end + + # Note: see ActivityPubControllerTest for JSON format tests + describe "feed_redirect" do + test "with html format, it redirects to user feed", %{conn: conn} do + note_activity = insert(:note_activity) + user = User.get_cached_by_ap_id(note_activity.data["actor"]) + + response = + conn + |> get("/users/#{user.nickname}") + |> response(200) + + assert response == + Fallback.RedirectController.redirector_with_meta( + conn, + %{user: user} + ).resp_body + end + + test "with html format, it returns error when user is not found", %{conn: conn} do + response = + conn + |> get("/users/jimm") + |> json_response(404) + + assert response == %{"error" => "Not found"} + end + + test "with non-html / non-json format, it redirects to user feed in atom format", %{ + conn: conn + } do + note_activity = insert(:note_activity) + user = User.get_cached_by_ap_id(note_activity.data["actor"]) + + conn = + conn + |> put_req_header("accept", "application/xml") + |> get("/users/#{user.nickname}") + + assert conn.status == 302 + assert redirected_to(conn) == "#{Pleroma.Web.base_url()}/users/#{user.nickname}/feed.atom" + end + + test "with non-html / non-json format, it returns error when user is not found", %{conn: conn} do + response = + conn + |> put_req_header("accept", "application/xml") + |> get(user_feed_path(conn, :feed, "jimm")) + |> response(404) + + assert response == ~S({"error":"Not found"}) + end + end +end diff --git a/test/web/instances/instance_test.exs b/test/web/instances/instance_test.exs index e54d708ad..a3c93b986 100644 --- a/test/web/instances/instance_test.exs +++ b/test/web/instances/instance_test.exs @@ -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.Instances.InstanceTest do diff --git a/test/web/instances/instances_test.exs b/test/web/instances/instances_test.exs index 65b03b155..c5d6abc9c 100644 --- a/test/web/instances/instances_test.exs +++ b/test/web/instances/instances_test.exs @@ -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.InstancesTest do diff --git a/test/web/masto_fe_controller_test.exs b/test/web/masto_fe_controller_test.exs index b5dbd4a25..9a2d76e0b 100644 --- a/test/web/masto_fe_controller_test.exs +++ b/test/web/masto_fe_controller_test.exs @@ -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.MastodonAPI.MastoFEController do @@ -18,6 +18,7 @@ defmodule Pleroma.Web.MastodonAPI.MastoFEController do conn = conn |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:accounts"])) |> put("/api/web/settings", %{"data" => %{"programming" => "socks"}}) assert _result = json_response(conn, 200) @@ -63,12 +64,12 @@ defmodule Pleroma.Web.MastodonAPI.MastoFEController do end test "does not redirect logged in users to the login page", %{conn: conn, path: path} do - token = insert(:oauth_token) + token = insert(:oauth_token, scopes: ["read"]) conn = conn |> assign(:user, token.user) - |> put_session(:oauth_token, token.token) + |> assign(:token, token) |> get(path) assert conn.status == 200 diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index 77cfce4fa..cba68859e 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -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.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do @@ -12,13 +12,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do clear_config([:instance, :max_account_fields]) describe "updating credentials" do - test "sets user settings in a generic way", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) + test "sets user settings in a generic way", %{conn: conn} do res_conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ + patch(conn, "/api/v1/accounts/update_credentials", %{ "pleroma_settings_store" => %{ pleroma_fe: %{ theme: "bla" @@ -26,10 +24,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user = json_response(res_conn, 200) - assert user["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}} + assert user_data = json_response(res_conn, 200) + assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}} - user = Repo.get(User, user["id"]) + user = Repo.get(User, user_data["id"]) res_conn = conn @@ -42,15 +40,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user = json_response(res_conn, 200) + assert user_data = json_response(res_conn, 200) - assert user["pleroma"]["settings_store"] == + assert user_data["pleroma"]["settings_store"] == %{ "pleroma_fe" => %{"theme" => "bla"}, "masto_fe" => %{"theme" => "bla"} } - user = Repo.get(User, user["id"]) + user = Repo.get(User, user_data["id"]) res_conn = conn @@ -63,9 +61,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user = json_response(res_conn, 200) + assert user_data = json_response(res_conn, 200) - assert user["pleroma"]["settings_store"] == + assert user_data["pleroma"]["settings_store"] == %{ "pleroma_fe" => %{"theme" => "bla"}, "masto_fe" => %{"theme" => "blub"} @@ -73,97 +71,67 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do end test "updates the user's bio", %{conn: conn} do - user = insert(:user) user2 = insert(:user) conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ + patch(conn, "/api/v1/accounts/update_credentials", %{ "note" => "I drink #cofe with @#{user2.nickname}" }) - assert user = json_response(conn, 200) + assert user_data = json_response(conn, 200) - assert user["note"] == + assert user_data["note"] == ~s(I drink <a class="hashtag" data-tag="cofe" href="http://localhost:4001/tag/cofe">#cofe</a> with <span class="h-card"><a data-user="#{ user2.id }" class="u-url mention" href="#{user2.ap_id}" rel="ugc">@<span>#{user2.nickname}</span></a></span>) end test "updates the user's locking status", %{conn: conn} do - user = insert(:user) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"}) - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{locked: "true"}) - - assert user = json_response(conn, 200) - assert user["locked"] == true + assert user_data = json_response(conn, 200) + assert user_data["locked"] == true end - test "updates the user's allow_following_move", %{conn: conn} do - user = insert(:user) - + test "updates the user's allow_following_move", %{user: user, conn: conn} do assert user.allow_following_move == true - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{allow_following_move: "false"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"}) assert refresh_record(user).allow_following_move == false - assert user = json_response(conn, 200) - assert user["pleroma"]["allow_following_move"] == false + assert user_data = json_response(conn, 200) + assert user_data["pleroma"]["allow_following_move"] == false end test "updates the user's default scope", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{default_scope: "cofe"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "cofe"}) - assert user = json_response(conn, 200) - assert user["source"]["privacy"] == "cofe" + assert user_data = json_response(conn, 200) + assert user_data["source"]["privacy"] == "cofe" end test "updates the user's hide_followers status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{hide_followers: "true"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"}) - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_followers"] == true + assert user_data = json_response(conn, 200) + assert user_data["pleroma"]["hide_followers"] == true end test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do - user = insert(:user) - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ + patch(conn, "/api/v1/accounts/update_credentials", %{ hide_followers_count: "true", hide_follows_count: "true" }) - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_followers_count"] == true - assert user["pleroma"]["hide_follows_count"] == true + assert user_data = json_response(conn, 200) + assert user_data["pleroma"]["hide_followers_count"] == true + assert user_data["pleroma"]["hide_follows_count"] == true end - test "updates the user's skip_thread_containment option", %{conn: conn} do - user = insert(:user) - + test "updates the user's skip_thread_containment option", %{user: user, conn: conn} do response = conn - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"}) |> json_response(200) @@ -172,104 +140,68 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do end test "updates the user's hide_follows status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{hide_follows: "true"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"}) - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_follows"] == true + assert user_data = json_response(conn, 200) + assert user_data["pleroma"]["hide_follows"] == true end test "updates the user's hide_favorites status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{hide_favorites: "true"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"}) - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_favorites"] == true + assert user_data = json_response(conn, 200) + assert user_data["pleroma"]["hide_favorites"] == true end test "updates the user's show_role status", %{conn: conn} do - user = insert(:user) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"}) - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{show_role: "false"}) - - assert user = json_response(conn, 200) - assert user["source"]["pleroma"]["show_role"] == false + assert user_data = json_response(conn, 200) + assert user_data["source"]["pleroma"]["show_role"] == false end test "updates the user's no_rich_text status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{no_rich_text: "true"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"}) - assert user = json_response(conn, 200) - assert user["source"]["pleroma"]["no_rich_text"] == true + assert user_data = json_response(conn, 200) + assert user_data["source"]["pleroma"]["no_rich_text"] == true end test "updates the user's name", %{conn: conn} do - user = insert(:user) - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"}) + patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"}) - assert user = json_response(conn, 200) - assert user["display_name"] == "markorepairs" + assert user_data = json_response(conn, 200) + assert user_data["display_name"] == "markorepairs" end - test "updates the user's avatar", %{conn: conn} do - user = insert(:user) - + test "updates the user's avatar", %{user: user, conn: conn} do new_avatar = %Plug.Upload{ content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg" } - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) assert user_response = json_response(conn, 200) assert user_response["avatar"] != User.avatar_url(user) end - test "updates the user's banner", %{conn: conn} do - user = insert(:user) - + test "updates the user's banner", %{user: user, conn: conn} do new_header = %Plug.Upload{ content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg" } - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header}) assert user_response = json_response(conn, 200) assert user_response["header"] != User.banner_url(user) end test "updates the user's background", %{conn: conn} do - user = insert(:user) - new_header = %Plug.Upload{ content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), @@ -277,9 +209,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ + patch(conn, "/api/v1/accounts/update_credentials", %{ "pleroma_background_image" => new_header }) @@ -287,13 +217,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert user_response["pleroma"]["background_image"] end - test "requires 'write:accounts' permission", %{conn: conn} do + test "requires 'write:accounts' permission" do token1 = insert(:oauth_token, scopes: ["read"]) token2 = insert(:oauth_token, scopes: ["write", "follow"]) for token <- [token1, token2] do conn = - conn + build_conn() |> put_req_header("authorization", "Bearer #{token.token}") |> patch("/api/v1/accounts/update_credentials", %{}) @@ -306,53 +236,44 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do end end - test "updates profile emojos", %{conn: conn} do - user = insert(:user) - + test "updates profile emojos", %{user: user, conn: conn} do note = "*sips :blank:*" name = "I am :firefox:" - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ + ret_conn = + patch(conn, "/api/v1/accounts/update_credentials", %{ "note" => note, "display_name" => name }) - assert json_response(conn, 200) + assert json_response(ret_conn, 200) - conn = - conn - |> get("/api/v1/accounts/#{user.id}") + conn = get(conn, "/api/v1/accounts/#{user.id}") - assert user = json_response(conn, 200) + assert user_data = json_response(conn, 200) - assert user["note"] == note - assert user["display_name"] == name - assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user["emojis"] + assert user_data["note"] == note + assert user_data["display_name"] == name + assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user_data["emojis"] end test "update fields", %{conn: conn} do - user = insert(:user) - fields = [ %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>"}, %{"name" => "link", "value" => "cofe.io"} ] - account = + account_data = conn - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) |> json_response(200) - assert account["fields"] == [ - %{"name" => "foo", "value" => "bar"}, + assert account_data["fields"] == [ + %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"}, %{"name" => "link", "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)} ] - assert account["source"]["fields"] == [ + assert account_data["source"]["fields"] == [ %{ "name" => "<a href=\"http://google.com\">foo</a>", "value" => "<script>bar</script>" @@ -372,12 +293,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do account = conn |> put_req_header("content-type", "application/x-www-form-urlencoded") - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", fields) |> json_response(200) assert account["fields"] == [ - %{"name" => "foo", "value" => "bar"}, + %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"}, %{"name" => "link", "value" => ~S(<a href="http://cofe.io" rel="ugc">cofe.io</a>)} ] @@ -398,7 +318,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert %{"error" => "Invalid request"} == conn - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) |> json_response(403) @@ -408,7 +327,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert %{"error" => "Invalid request"} == conn - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) |> json_response(403) @@ -421,7 +339,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert %{"error" => "Invalid request"} == conn - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) |> json_response(403) @@ -432,7 +349,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do account = conn - |> assign(:user, user) |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) |> json_response(200) diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index 585cb8a9e..7efccd9c4 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -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.MastodonAPI.AccountControllerTest do @@ -15,6 +15,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do import Pleroma.Factory describe "account fetching" do + clear_config([:instance, :limit_to_local_content]) + test "works by id" do user = insert(:user) @@ -44,7 +46,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end test "works by nickname for remote users" do - limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content]) Pleroma.Config.put([:instance, :limit_to_local_content], false) user = insert(:user, nickname: "user@example.com", local: false) @@ -52,13 +53,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do build_conn() |> get("/api/v1/accounts/#{user.nickname}") - Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local) assert %{"id" => id} = json_response(conn, 200) assert id == user.id end test "respects limit_to_local_content == :all for remote user nicknames" do - limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content]) Pleroma.Config.put([:instance, :limit_to_local_content], :all) user = insert(:user, nickname: "user@example.com", local: false) @@ -67,12 +66,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do build_conn() |> get("/api/v1/accounts/#{user.nickname}") - Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local) assert json_response(conn, 404) end test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do - limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content]) Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated) user = insert(:user, nickname: "user@example.com", local: false) @@ -87,9 +84,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = build_conn() |> assign(:user, reading_user) + |> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.nickname}") - Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local) assert %{"id" => id} = json_response(conn, 200) assert id == user.id end @@ -144,12 +141,46 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "user timelines" do - test "gets a users statuses", %{conn: conn} do + setup do: oauth_access(["read:statuses"]) + + test "respects blocks", %{user: user_one, conn: conn} do + user_two = insert(:user) + user_three = insert(:user) + + User.block(user_one, user_two) + + {:ok, activity} = CommonAPI.post(user_two, %{"status" => "User one sux0rz"}) + {:ok, repeat, _} = CommonAPI.repeat(activity.id, user_three) + + resp = get(conn, "/api/v1/accounts/#{user_two.id}/statuses") + + assert [%{"id" => id}] = json_response(resp, 200) + assert id == activity.id + + # Even a blocked user will deliver the full user timeline, there would be + # no point in looking at a blocked users timeline otherwise + resp = get(conn, "/api/v1/accounts/#{user_two.id}/statuses") + + assert [%{"id" => id}] = json_response(resp, 200) + assert id == activity.id + + # Third user's timeline includes the repeat when viewed by unauthenticated user + resp = get(build_conn(), "/api/v1/accounts/#{user_three.id}/statuses") + assert [%{"id" => id}] = json_response(resp, 200) + assert id == repeat.id + + # When viewing a third user's timeline, the blocked users' statuses will NOT be shown + resp = get(conn, "/api/v1/accounts/#{user_three.id}/statuses") + + assert [] = json_response(resp, 200) + end + + test "gets users statuses", %{conn: conn} do user_one = insert(:user) user_two = insert(:user) user_three = insert(:user) - {:ok, user_three} = User.follow(user_three, user_one) + {:ok, _user_three} = User.follow(user_three, user_one) {:ok, activity} = CommonAPI.post(user_one, %{"status" => "HI!!!"}) @@ -162,9 +193,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, private_activity} = CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"}) - resp = - conn - |> get("/api/v1/accounts/#{user_one.id}/statuses") + resp = get(conn, "/api/v1/accounts/#{user_one.id}/statuses") assert [%{"id" => id}] = json_response(resp, 200) assert id == to_string(activity.id) @@ -172,6 +201,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do resp = conn |> assign(:user, user_two) + |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"])) |> get("/api/v1/accounts/#{user_one.id}/statuses") assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200) @@ -181,6 +211,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do resp = conn |> assign(:user, user_three) + |> assign(:token, insert(:oauth_token, user: user_three, scopes: ["read:statuses"])) |> get("/api/v1/accounts/#{user_one.id}/statuses") assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200) @@ -192,9 +223,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do note = insert(:note_activity) user = User.get_cached_by_ap_id(note.data["actor"]) - conn = - conn - |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?pinned=true") assert json_response(conn, 200) == [] end @@ -213,63 +242,51 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]}) - conn = - conn - |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"}) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "true"}) assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(image_post.id) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"}) + conn = get(build_conn(), "/api/v1/accounts/#{user.id}/statuses", %{"only_media" => "1"}) assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(image_post.id) end - test "gets a user's statuses without reblogs", %{conn: conn} do - user = insert(:user) + test "gets a user's statuses without reblogs", %{user: user, conn: conn} do {:ok, post} = CommonAPI.post(user, %{"status" => "HI!!!"}) {:ok, _, _} = CommonAPI.repeat(post.id, user) - conn = - conn - |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"}) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"}) assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(post.id) - conn = - conn - |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"}) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "1"}) assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(post.id) end - test "filters user's statuses by a hashtag", %{conn: conn} do - user = insert(:user) + test "filters user's statuses by a hashtag", %{user: user, conn: conn} do {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"}) {:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"}) - conn = - conn - |> get("/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"}) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"}) assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(post.id) end - test "the user views their own timelines and excludes direct messages", %{conn: conn} do - user = insert(:user) + test "the user views their own timelines and excludes direct messages", %{ + user: user, + conn: conn + } do {:ok, public_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "public"}) {:ok, _direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) conn = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/#{user.id}/statuses", %{"exclude_visibilities" => ["direct"]}) + get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_visibilities" => ["direct"]}) assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(public_activity.id) @@ -277,46 +294,42 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "followers" do - test "getting followers", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["read:accounts"]) + + test "getting followers", %{user: user, conn: conn} do other_user = insert(:user) {:ok, user} = User.follow(user, other_user) - conn = - conn - |> get("/api/v1/accounts/#{other_user.id}/followers") + conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers") assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(user.id) end - test "getting followers, hide_followers", %{conn: conn} do - user = insert(:user) + test "getting followers, hide_followers", %{user: user, conn: conn} do other_user = insert(:user, hide_followers: true) {:ok, _user} = User.follow(user, other_user) - conn = - conn - |> get("/api/v1/accounts/#{other_user.id}/followers") + conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers") assert [] == json_response(conn, 200) end - test "getting followers, hide_followers, same user requesting", %{conn: conn} do + test "getting followers, hide_followers, same user requesting" do user = insert(:user) other_user = insert(:user, hide_followers: true) {:ok, _user} = User.follow(user, other_user) conn = - conn + build_conn() |> assign(:user, other_user) + |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{other_user.id}/followers") refute [] == json_response(conn, 200) end - test "getting followers, pagination", %{conn: conn} do - user = insert(:user) + test "getting followers, pagination", %{user: user, conn: conn} do follower1 = insert(:user) follower2 = insert(:user) follower3 = insert(:user) @@ -324,29 +337,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, _} = User.follow(follower2, user) {:ok, _} = User.follow(follower3, user) - conn = - conn - |> assign(:user, user) - - res_conn = - conn - |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}") + res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?since_id=#{follower1.id}") assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200) assert id3 == follower3.id assert id2 == follower2.id - res_conn = - conn - |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}") + res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}") assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200) assert id2 == follower2.id assert id1 == follower1.id - res_conn = - conn - |> get("/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}") + res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?limit=1&max_id=#{follower3.id}") assert [%{"id" => id2}] = json_response(res_conn, 200) assert id2 == follower2.id @@ -358,46 +361,47 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "following" do - test "getting following", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["read:accounts"]) + + test "getting following", %{user: user, conn: conn} do other_user = insert(:user) {:ok, user} = User.follow(user, other_user) - conn = - conn - |> get("/api/v1/accounts/#{user.id}/following") + conn = get(conn, "/api/v1/accounts/#{user.id}/following") assert [%{"id" => id}] = json_response(conn, 200) assert id == to_string(other_user.id) end - test "getting following, hide_follows", %{conn: conn} do + test "getting following, hide_follows, other user requesting" do user = insert(:user, hide_follows: true) other_user = insert(:user) {:ok, user} = User.follow(user, other_user) conn = - conn + build_conn() + |> assign(:user, other_user) + |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.id}/following") assert [] == json_response(conn, 200) end - test "getting following, hide_follows, same user requesting", %{conn: conn} do + test "getting following, hide_follows, same user requesting" do user = insert(:user, hide_follows: true) other_user = insert(:user) {:ok, user} = User.follow(user, other_user) conn = - conn + build_conn() |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.id}/following") refute [] == json_response(conn, 200) end - test "getting following, pagination", %{conn: conn} do - user = insert(:user) + test "getting following, pagination", %{user: user, conn: conn} do following1 = insert(:user) following2 = insert(:user) following3 = insert(:user) @@ -405,29 +409,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, _} = User.follow(user, following2) {:ok, _} = User.follow(user, following3) - conn = - conn - |> assign(:user, user) - - res_conn = - conn - |> get("/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}") + res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?since_id=#{following1.id}") assert [%{"id" => id3}, %{"id" => id2}] = json_response(res_conn, 200) assert id3 == following3.id assert id2 == following2.id - res_conn = - conn - |> get("/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}") + res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?max_id=#{following3.id}") assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200) assert id2 == following2.id assert id1 == following1.id res_conn = - conn - |> get("/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}") + get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}") assert [%{"id" => id2}] = json_response(res_conn, 200) assert id2 == following2.id @@ -439,82 +434,62 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "follow/unfollow" do + setup do: oauth_access(["follow"]) + test "following / unfollowing a user", %{conn: conn} do - user = insert(:user) other_user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/follow") - - assert %{"id" => _id, "following" => true} = json_response(conn, 200) + ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/follow") - user = User.get_cached_by_id(user.id) + assert %{"id" => _id, "following" => true} = json_response(ret_conn, 200) - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/unfollow") + ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/unfollow") - assert %{"id" => _id, "following" => false} = json_response(conn, 200) + assert %{"id" => _id, "following" => false} = json_response(ret_conn, 200) - user = User.get_cached_by_id(user.id) - - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/follows", %{"uri" => other_user.nickname}) + conn = post(conn, "/api/v1/follows", %{"uri" => other_user.nickname}) assert %{"id" => id} = json_response(conn, 200) assert id == to_string(other_user.id) end + test "cancelling follow request", %{conn: conn} do + %{id: other_user_id} = insert(:user, %{locked: true}) + + assert %{"id" => ^other_user_id, "following" => false, "requested" => true} = + conn |> post("/api/v1/accounts/#{other_user_id}/follow") |> json_response(:ok) + + assert %{"id" => ^other_user_id, "following" => false, "requested" => false} = + conn |> post("/api/v1/accounts/#{other_user_id}/unfollow") |> json_response(:ok) + end + test "following without reblogs" do - follower = insert(:user) + %{conn: conn} = oauth_access(["follow", "read:statuses"]) followed = insert(:user) other_user = insert(:user) - conn = - build_conn() - |> assign(:user, follower) - |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=false") + ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=false") - assert %{"showing_reblogs" => false} = json_response(conn, 200) + assert %{"showing_reblogs" => false} = json_response(ret_conn, 200) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"}) {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed) - conn = - build_conn() - |> assign(:user, User.get_cached_by_id(follower.id)) - |> get("/api/v1/timelines/home") + ret_conn = get(conn, "/api/v1/timelines/home") - assert [] == json_response(conn, 200) + assert [] == json_response(ret_conn, 200) - conn = - build_conn() - |> assign(:user, User.get_cached_by_id(follower.id)) - |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true") + ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=true") - assert %{"showing_reblogs" => true} = json_response(conn, 200) + assert %{"showing_reblogs" => true} = json_response(ret_conn, 200) - conn = - build_conn() - |> assign(:user, User.get_cached_by_id(follower.id)) - |> get("/api/v1/timelines/home") + conn = get(conn, "/api/v1/timelines/home") expected_activity_id = reblog.id assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200) end - test "following / unfollowing errors" do - user = insert(:user) - - conn = - build_conn() - |> assign(:user, user) - + test "following / unfollowing errors", %{user: user, conn: conn} do # self follow conn_res = post(conn, "/api/v1/accounts/#{user.id}/follow") assert %{"error" => "Record not found"} = json_response(conn_res, 404) @@ -544,47 +519,34 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "mute/unmute" do + setup do: oauth_access(["write:mutes"]) + test "with notifications", %{conn: conn} do - user = insert(:user) other_user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/mute") + ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/mute") - response = json_response(conn, 200) + response = json_response(ret_conn, 200) assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response - user = User.get_cached_by_id(user.id) - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/unmute") + conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute") response = json_response(conn, 200) assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response end test "without notifications", %{conn: conn} do - user = insert(:user) other_user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) + ret_conn = + post(conn, "/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) - response = json_response(conn, 200) + response = json_response(ret_conn, 200) assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response - user = User.get_cached_by_id(user.id) - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/unmute") + conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute") response = json_response(conn, 200) assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response @@ -595,8 +557,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"}) + %{conn: conn} = oauth_access(["read:statuses"], user: user) - [user: user, activity: activity] + [conn: conn, user: user, activity: activity] end test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do @@ -604,7 +567,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do result = conn - |> assign(:user, user) |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") |> json_response(200) @@ -614,23 +576,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end end - test "blocking / unblocking a user", %{conn: conn} do - user = insert(:user) + test "blocking / unblocking a user" do + %{conn: conn} = oauth_access(["follow"]) other_user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/block") + ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/block") - assert %{"id" => _id, "blocking" => true} = json_response(conn, 200) + assert %{"id" => _id, "blocking" => true} = json_response(ret_conn, 200) - user = User.get_cached_by_id(user.id) - - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/accounts/#{other_user.id}/unblock") + conn = post(conn, "/api/v1/accounts/#{other_user.id}/unblock") assert %{"id" => _id, "blocking" => false} = json_response(conn, 200) end @@ -647,10 +601,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do [valid_params: valid_params] end + clear_config([:instance, :account_activation_required]) + test "Account registration via Application", %{conn: conn} do conn = - conn - |> post("/api/v1/apps", %{ + post(conn, "/api/v1/apps", %{ client_name: "client_name", redirect_uris: "urn:ietf:wg:oauth:2.0:oob", scopes: "read, write, follow" @@ -667,8 +622,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do } = json_response(conn, 200) conn = - conn - |> post("/oauth/token", %{ + post(conn, "/oauth/token", %{ grant_type: "client_credentials", client_id: client_id, client_secret: client_secret @@ -721,17 +675,102 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"} end - test "rate limit", %{conn: conn} do + test "returns bad_request if missing required params", %{ + conn: conn, + valid_params: valid_params + } do + app_token = insert(:oauth_token, user: nil) + + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = post(conn, "/api/v1/accounts", valid_params) + assert json_response(res, 200) + + [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}] + |> Stream.zip(Map.delete(valid_params, :email)) + |> Enum.each(fn {ip, {attr, _}} -> + res = + conn + |> Map.put(:remote_ip, ip) + |> post("/api/v1/accounts", Map.delete(valid_params, attr)) + |> json_response(400) + + assert res == %{"error" => "Missing parameters"} + end) + end + + clear_config([:instance, :account_activation_required]) + + test "returns bad_request if missing email params when :account_activation_required is enabled", + %{conn: conn, valid_params: valid_params} do + Pleroma.Config.put([:instance, :account_activation_required], true) + + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 5}) + |> post("/api/v1/accounts", Map.delete(valid_params, :email)) + + assert json_response(res, 400) == %{"error" => "Missing parameters"} + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 6}) + |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) + + assert json_response(res, 400) == %{"error" => "{\"email\":[\"can't be blank\"]}"} + end + + test "allow registration without an email", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 7}) + |> post("/api/v1/accounts", Map.delete(valid_params, :email)) + + assert json_response(res, 200) + end + + test "allow registration with an empty email", %{conn: conn, valid_params: valid_params} do + app_token = insert(:oauth_token, user: nil) + conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + + res = + conn + |> Map.put(:remote_ip, {127, 0, 0, 8}) + |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) + + assert json_response(res, 200) + end + + test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do + conn = put_req_header(conn, "authorization", "Bearer " <> "invalid-token") + + res = post(conn, "/api/v1/accounts", valid_params) + assert json_response(res, 403) == %{"error" => "Invalid credentials"} + end + end + + describe "create account by app / rate limit" do + clear_config([:rate_limit, :app_account_creation]) do + Pleroma.Config.put([:rate_limit, :app_account_creation], {10_000, 2}) + end + + test "respects rate limit setting", %{conn: conn} do app_token = insert(:oauth_token, user: nil) conn = - put_req_header(conn, "authorization", "Bearer " <> app_token.token) + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) |> Map.put(:remote_ip, {15, 15, 15, 15}) - for i <- 1..5 do + for i <- 1..2 do conn = - conn - |> post("/api/v1/accounts", %{ + post(conn, "/api/v1/accounts", %{ username: "#{i}lain", email: "#{i}lain@example.org", password: "PlzDontHackLain", @@ -754,8 +793,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end conn = - conn - |> post("/api/v1/accounts", %{ + post(conn, "/api/v1/accounts", %{ username: "6lain", email: "6lain@example.org", password: "PlzDontHackLain", @@ -764,53 +802,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"} end - - test "returns bad_request if missing required params", %{ - conn: conn, - valid_params: valid_params - } do - app_token = insert(:oauth_token, user: nil) - - conn = - conn - |> put_req_header("authorization", "Bearer " <> app_token.token) - - res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 200) - - [{127, 0, 0, 1}, {127, 0, 0, 2}, {127, 0, 0, 3}, {127, 0, 0, 4}] - |> Stream.zip(valid_params) - |> Enum.each(fn {ip, {attr, _}} -> - res = - conn - |> Map.put(:remote_ip, ip) - |> post("/api/v1/accounts", Map.delete(valid_params, attr)) - |> json_response(400) - - assert res == %{"error" => "Missing parameters"} - end) - end - - test "returns forbidden if token is invalid", %{conn: conn, valid_params: valid_params} do - conn = - conn - |> put_req_header("authorization", "Bearer " <> "invalid-token") - - res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 403) == %{"error" => "Invalid credentials"} - end end describe "GET /api/v1/accounts/:id/lists - account_lists" do - test "returns lists to which the account belongs", %{conn: conn} do - user = insert(:user) + test "returns lists to which the account belongs" do + %{user: user, conn: conn} = oauth_access(["read:lists"]) other_user = insert(:user) assert {:ok, %Pleroma.List{} = list} = Pleroma.List.create("Test List", user) {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user) res = conn - |> assign(:user, user) |> get("/api/v1/accounts/#{other_user.id}/lists") |> json_response(200) @@ -819,13 +821,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "verify_credentials" do - test "verify_credentials", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/verify_credentials") + test "verify_credentials" do + %{user: user, conn: conn} = oauth_access(["read:accounts"]) + conn = get(conn, "/api/v1/accounts/verify_credentials") response = json_response(conn, 200) @@ -834,25 +832,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do assert id == to_string(user.id) end - test "verify_credentials default scope unlisted", %{conn: conn} do + test "verify_credentials default scope unlisted" do user = insert(:user, default_scope: "unlisted") + %{conn: conn} = oauth_access(["read:accounts"], user: user) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/verify_credentials") + conn = get(conn, "/api/v1/accounts/verify_credentials") assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200) assert id == to_string(user.id) end - test "locked accounts", %{conn: conn} do + test "locked accounts" do user = insert(:user, default_scope: "private") + %{conn: conn} = oauth_access(["read:accounts"], user: user) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/verify_credentials") + conn = get(conn, "/api/v1/accounts/verify_credentials") assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200) assert id == to_string(user.id) @@ -860,15 +854,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end describe "user relationships" do - test "returns the relationships for the current user", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["read:follows"]) + + test "returns the relationships for the current user", %{user: user, conn: conn} do other_user = insert(:user) - {:ok, user} = User.follow(user, other_user) + {:ok, _user} = User.follow(user, other_user) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/relationships", %{"id" => [other_user.id]}) + conn = get(conn, "/api/v1/accounts/relationships", %{"id" => [other_user.id]}) assert [relationship] = json_response(conn, 200) @@ -876,37 +868,29 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do end test "returns an empty list on a bad request", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/relationships", %{}) + conn = get(conn, "/api/v1/accounts/relationships", %{}) assert [] = json_response(conn, 200) end end - test "getting a list of mutes", %{conn: conn} do - user = insert(:user) + test "getting a list of mutes" do + %{user: user, conn: conn} = oauth_access(["read:mutes"]) other_user = insert(:user) - {:ok, user} = User.mute(user, other_user) + {:ok, _user_relationships} = User.mute(user, other_user) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/mutes") + conn = get(conn, "/api/v1/mutes") other_user_id = to_string(other_user.id) assert [%{"id" => ^other_user_id}] = json_response(conn, 200) end - test "getting a list of blocks", %{conn: conn} do - user = insert(:user) + test "getting a list of blocks" do + %{user: user, conn: conn} = oauth_access(["read:blocks"]) other_user = insert(:user) - {:ok, user} = User.block(user, other_user) + {:ok, _user_relationship} = User.block(user, other_user) conn = conn diff --git a/test/web/mastodon_api/controllers/app_controller_test.exs b/test/web/mastodon_api/controllers/app_controller_test.exs index 51788155b..77d234d67 100644 --- a/test/web/mastodon_api/controllers/app_controller_test.exs +++ b/test/web/mastodon_api/controllers/app_controller_test.exs @@ -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.MastodonAPI.AppControllerTest do diff --git a/test/web/mastodon_api/controllers/auth_controller_test.exs b/test/web/mastodon_api/controllers/auth_controller_test.exs index 98b2a82e7..a485f8e41 100644 --- a/test/web/mastodon_api/controllers/auth_controller_test.exs +++ b/test/web/mastodon_api/controllers/auth_controller_test.exs @@ -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.MastodonAPI.AuthControllerTest do @@ -85,6 +85,37 @@ defmodule Pleroma.Web.MastodonAPI.AuthControllerTest do end end + describe "POST /auth/password, with nickname" do + test "it returns 204", %{conn: conn} do + user = insert(:user) + + assert conn + |> post("/auth/password?nickname=#{user.nickname}") + |> json_response(:no_content) + + ObanHelpers.perform_all() + token_record = Repo.get_by(Pleroma.PasswordResetToken, user_id: user.id) + + email = Pleroma.Emails.UserEmail.password_reset_email(user, token_record.token) + notify_email = Config.get([:instance, :notify_email]) + instance_name = Config.get([:instance, :name]) + + assert_email_sent( + from: {instance_name, notify_email}, + to: {user.name, user.email}, + html_body: email.html_body + ) + end + + test "it doesn't fail when a user has no email", %{conn: conn} do + user = insert(:user, %{email: nil}) + + assert conn + |> post("/auth/password?nickname=#{user.nickname}") + |> json_response(:no_content) + end + end + describe "POST /auth/password, with invalid parameters" do setup do user = insert(:user) diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/web/mastodon_api/controllers/conversation_controller_test.exs index 2a1223b18..801b0259b 100644 --- a/test/web/mastodon_api/controllers/conversation_controller_test.exs +++ b/test/web/mastodon_api/controllers/conversation_controller_test.exs @@ -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.MastodonAPI.ConversationControllerTest do @@ -10,8 +10,9 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do import Pleroma.Factory - test "returns a list of conversations", %{conn: conn} do - user_one = insert(:user) + 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) @@ -33,10 +34,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do "visibility" => "private" }) - res_conn = - conn - |> assign(:user, user_one) - |> get("/api/v1/conversations") + res_conn = get(conn, "/api/v1/conversations") assert response = json_response(res_conn, 200) @@ -59,8 +57,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0 end - test "filters conversations by recipients", %{conn: conn} do - user_one = insert(:user) + test "filters conversations by recipients", %{user: user_one, conn: conn} do user_two = insert(:user) user_three = insert(:user) @@ -96,7 +93,6 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do [conversation1, conversation2] = conn - |> assign(:user, user_one) |> get("/api/v1/conversations", %{"recipients" => [user_two.id]}) |> json_response(200) @@ -105,15 +101,13 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do [conversation1] = conn - |> assign(:user, user_one) |> get("/api/v1/conversations", %{"recipients" => [user_two.id, user_three.id]}) |> json_response(200) assert conversation1["last_status"]["id"] == direct3.id end - test "updates the last_status on reply", %{conn: conn} do - user_one = insert(:user) + test "updates the last_status on reply", %{user: user_one, conn: conn} do user_two = insert(:user) {:ok, direct} = @@ -131,15 +125,13 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do [%{"last_status" => res_last_status}] = conn - |> assign(:user, user_one) |> get("/api/v1/conversations") |> json_response(200) assert res_last_status["id"] == direct_reply.id end - test "the user marks a conversation as read", %{conn: conn} do - user_one = insert(:user) + test "the user marks a conversation as read", %{user: user_one, conn: conn} do user_two = insert(:user) {:ok, direct} = @@ -151,15 +143,21 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do 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 - [%{"id" => direct_conversation_id, "unread" => true}] = - conn + user_two_conn = + build_conn() |> assign(:user, user_two) + |> assign( + :token, + insert(:oauth_token, user: user_two, scopes: ["read:statuses", "write:conversations"]) + ) + + [%{"id" => direct_conversation_id, "unread" => true}] = + user_two_conn |> get("/api/v1/conversations") |> json_response(200) %{"unread" => false} = - conn - |> assign(:user, user_two) + user_two_conn |> post("/api/v1/conversations/#{direct_conversation_id}/read") |> json_response(200) @@ -176,7 +174,6 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do [%{"unread" => true}] = conn - |> assign(:user, user_one) |> get("/api/v1/conversations") |> json_response(200) @@ -195,8 +192,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0 end - test "(vanilla) Mastodon frontend behaviour", %{conn: conn} do - user_one = insert(:user) + test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do user_two = insert(:user) {:ok, direct} = @@ -205,10 +201,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do "visibility" => "direct" }) - res_conn = - conn - |> assign(:user, user_one) - |> get("/api/v1/statuses/#{direct.id}/context") + res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context") assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200) end diff --git a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs b/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs index 2d988b0b8..6567a0667 100644 --- a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs +++ b/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs @@ -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.MastodonAPI.CustomEmojiControllerTest do diff --git a/test/web/mastodon_api/controllers/domain_block_controller_test.exs b/test/web/mastodon_api/controllers/domain_block_controller_test.exs index 25a279cdc..8d24b3b88 100644 --- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs +++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs @@ -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.MastodonAPI.DomainBlockControllerTest do @@ -9,31 +9,25 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do import Pleroma.Factory - test "blocking / unblocking a domain", %{conn: conn} do - user = insert(:user) + test "blocking / unblocking a domain" do + %{user: user, conn: conn} = oauth_access(["write:blocks"]) other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"}) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) + ret_conn = post(conn, "/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) - assert %{} = json_response(conn, 200) + assert %{} = json_response(ret_conn, 200) user = User.get_cached_by_ap_id(user.ap_id) assert User.blocks?(user, other_user) - conn = - build_conn() - |> assign(:user, user) - |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) + ret_conn = delete(conn, "/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) - assert %{} = json_response(conn, 200) + assert %{} = json_response(ret_conn, 200) user = User.get_cached_by_ap_id(user.ap_id) refute User.blocks?(user, other_user) end - test "getting a list of domain blocks", %{conn: conn} do - user = insert(:user) + test "getting a list of domain blocks" do + %{user: user, conn: conn} = oauth_access(["read:blocks"]) {:ok, user} = User.block_domain(user, "bad.site") {:ok, user} = User.block_domain(user, "even.worse.site") diff --git a/test/web/mastodon_api/controllers/filter_controller_test.exs b/test/web/mastodon_api/controllers/filter_controller_test.exs index 550689788..97ab005e0 100644 --- a/test/web/mastodon_api/controllers/filter_controller_test.exs +++ b/test/web/mastodon_api/controllers/filter_controller_test.exs @@ -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.MastodonAPI.FilterControllerTest do @@ -7,20 +7,15 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do alias Pleroma.Web.MastodonAPI.FilterView - import Pleroma.Factory - - test "creating a filter", %{conn: conn} do - user = insert(:user) + test "creating a filter" do + %{conn: conn} = oauth_access(["write:filters"]) filter = %Pleroma.Filter{ phrase: "knights", context: ["home"] } - conn = - conn - |> assign(:user, user) - |> post("/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context}) + conn = post(conn, "/api/v1/filters", %{"phrase" => filter.phrase, context: filter.context}) assert response = json_response(conn, 200) assert response["phrase"] == filter.phrase @@ -30,8 +25,8 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do assert response["id"] != "" end - test "fetching a list of filters", %{conn: conn} do - user = insert(:user) + test "fetching a list of filters" do + %{user: user, conn: conn} = oauth_access(["read:filters"]) query_one = %Pleroma.Filter{ user_id: user.id, @@ -52,7 +47,6 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do response = conn - |> assign(:user, user) |> get("/api/v1/filters") |> json_response(200) @@ -64,8 +58,8 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do ) end - test "get a filter", %{conn: conn} do - user = insert(:user) + test "get a filter" do + %{user: user, conn: conn} = oauth_access(["read:filters"]) query = %Pleroma.Filter{ user_id: user.id, @@ -76,16 +70,13 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do {:ok, filter} = Pleroma.Filter.create(query) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/filters/#{filter.filter_id}") + conn = get(conn, "/api/v1/filters/#{filter.filter_id}") assert _response = json_response(conn, 200) end - test "update a filter", %{conn: conn} do - user = insert(:user) + test "update a filter" do + %{user: user, conn: conn} = oauth_access(["write:filters"]) query = %Pleroma.Filter{ user_id: user.id, @@ -102,9 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do } conn = - conn - |> assign(:user, user) - |> put("/api/v1/filters/#{query.filter_id}", %{ + put(conn, "/api/v1/filters/#{query.filter_id}", %{ phrase: new.phrase, context: new.context }) @@ -114,8 +103,8 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do assert response["context"] == new.context end - test "delete a filter", %{conn: conn} do - user = insert(:user) + test "delete a filter" do + %{user: user, conn: conn} = oauth_access(["write:filters"]) query = %Pleroma.Filter{ user_id: user.id, @@ -126,10 +115,7 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do {:ok, filter} = Pleroma.Filter.create(query) - conn = - conn - |> assign(:user, user) - |> delete("/api/v1/filters/#{filter.filter_id}") + conn = delete(conn, "/api/v1/filters/#{filter.filter_id}") assert response = json_response(conn, 200) assert response == %{} diff --git a/test/web/mastodon_api/controllers/follow_request_controller_test.exs b/test/web/mastodon_api/controllers/follow_request_controller_test.exs index 288cd9029..dd848821a 100644 --- a/test/web/mastodon_api/controllers/follow_request_controller_test.exs +++ b/test/web/mastodon_api/controllers/follow_request_controller_test.exs @@ -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.MastodonAPI.FollowRequestControllerTest do @@ -11,8 +11,13 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do import Pleroma.Factory describe "locked accounts" do - test "/api/v1/follow_requests works" do + setup do user = insert(:user, locked: true) + %{conn: conn} = oauth_access(["follow"], user: user) + %{user: user, conn: conn} + end + + test "/api/v1/follow_requests works", %{user: user, conn: conn} do other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) @@ -20,17 +25,13 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do assert User.following?(other_user, user) == false - conn = - build_conn() - |> assign(:user, user) - |> get("/api/v1/follow_requests") + conn = get(conn, "/api/v1/follow_requests") assert [relationship] = json_response(conn, 200) assert to_string(other_user.id) == relationship["id"] end - test "/api/v1/follow_requests/:id/authorize works" do - user = insert(:user, locked: true) + test "/api/v1/follow_requests/:id/authorize works", %{user: user, conn: conn} do other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) @@ -41,10 +42,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do assert User.following?(other_user, user) == false - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/follow_requests/#{other_user.id}/authorize") + conn = post(conn, "/api/v1/follow_requests/#{other_user.id}/authorize") assert relationship = json_response(conn, 200) assert to_string(other_user.id) == relationship["id"] @@ -55,18 +53,14 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do assert User.following?(other_user, user) == true end - test "/api/v1/follow_requests/:id/reject works" do - user = insert(:user, locked: true) + test "/api/v1/follow_requests/:id/reject works", %{user: user, conn: conn} do other_user = insert(:user) {:ok, _activity} = ActivityPub.follow(other_user, user) user = User.get_cached_by_id(user.id) - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/follow_requests/#{other_user.id}/reject") + conn = post(conn, "/api/v1/follow_requests/#{other_user.id}/reject") assert relationship = json_response(conn, 200) assert to_string(other_user.id) == relationship["id"] diff --git a/test/web/mastodon_api/controllers/instance_controller_test.exs b/test/web/mastodon_api/controllers/instance_controller_test.exs index e00de6b18..2737dcaba 100644 --- a/test/web/mastodon_api/controllers/instance_controller_test.exs +++ b/test/web/mastodon_api/controllers/instance_controller_test.exs @@ -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.MastodonAPI.InstanceControllerTest do diff --git a/test/web/mastodon_api/controllers/list_controller_test.exs b/test/web/mastodon_api/controllers/list_controller_test.exs index 093506309..c9c4cbb49 100644 --- a/test/web/mastodon_api/controllers/list_controller_test.exs +++ b/test/web/mastodon_api/controllers/list_controller_test.exs @@ -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.MastodonAPI.ListControllerTest do @@ -9,44 +9,35 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do import Pleroma.Factory - test "creating a list", %{conn: conn} do - user = insert(:user) + test "creating a list" do + %{conn: conn} = oauth_access(["write:lists"]) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/lists", %{"title" => "cuties"}) + conn = post(conn, "/api/v1/lists", %{"title" => "cuties"}) assert %{"title" => title} = json_response(conn, 200) assert title == "cuties" end - test "renders error for invalid params", %{conn: conn} do - user = insert(:user) + test "renders error for invalid params" do + %{conn: conn} = oauth_access(["write:lists"]) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/lists", %{"title" => nil}) + conn = post(conn, "/api/v1/lists", %{"title" => nil}) assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) end - test "listing a user's lists", %{conn: conn} do - user = insert(:user) + test "listing a user's lists" do + %{conn: conn} = oauth_access(["read:lists", "write:lists"]) conn - |> assign(:user, user) |> post("/api/v1/lists", %{"title" => "cuties"}) + |> json_response(:ok) conn - |> assign(:user, user) |> post("/api/v1/lists", %{"title" => "cofe"}) + |> json_response(:ok) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/lists") + conn = get(conn, "/api/v1/lists") assert [ %{"id" => _, "title" => "cofe"}, @@ -54,41 +45,35 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do ] = json_response(conn, :ok) end - test "adding users to a list", %{conn: conn} do - user = insert(:user) + test "adding users to a list" do + %{user: user, conn: conn} = oauth_access(["write:lists"]) other_user = insert(:user) {:ok, list} = Pleroma.List.create("name", user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + conn = post(conn, "/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) assert %{} == json_response(conn, 200) %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) assert following == [other_user.follower_address] end - test "removing users from a list", %{conn: conn} do - user = insert(:user) + test "removing users from a list" do + %{user: user, conn: conn} = oauth_access(["write:lists"]) other_user = insert(:user) third_user = insert(:user) {:ok, list} = Pleroma.List.create("name", user) {:ok, list} = Pleroma.List.follow(list, other_user) {:ok, list} = Pleroma.List.follow(list, third_user) - conn = - conn - |> assign(:user, user) - |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + conn = delete(conn, "/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) assert %{} == json_response(conn, 200) %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) assert following == [third_user.follower_address] end - test "listing users in a list", %{conn: conn} do - user = insert(:user) + test "listing users in a list" do + %{user: user, conn: conn} = oauth_access(["read:lists"]) other_user = insert(:user) {:ok, list} = Pleroma.List.create("name", user) {:ok, list} = Pleroma.List.follow(list, other_user) @@ -102,8 +87,8 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do assert id == to_string(other_user.id) end - test "retrieving a list", %{conn: conn} do - user = insert(:user) + test "retrieving a list" do + %{user: user, conn: conn} = oauth_access(["read:lists"]) {:ok, list} = Pleroma.List.create("name", user) conn = @@ -115,32 +100,26 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do assert id == to_string(list.id) end - test "renders 404 if list is not found", %{conn: conn} do - user = insert(:user) + test "renders 404 if list is not found" do + %{conn: conn} = oauth_access(["read:lists"]) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/lists/666") + conn = get(conn, "/api/v1/lists/666") assert %{"error" => "List not found"} = json_response(conn, :not_found) end - test "renaming a list", %{conn: conn} do - user = insert(:user) + test "renaming a list" do + %{user: user, conn: conn} = oauth_access(["write:lists"]) {:ok, list} = Pleroma.List.create("name", user) - conn = - conn - |> assign(:user, user) - |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"}) + conn = put(conn, "/api/v1/lists/#{list.id}", %{"title" => "newname"}) assert %{"title" => name} = json_response(conn, 200) assert name == "newname" end - test "validates title when renaming a list", %{conn: conn} do - user = insert(:user) + test "validates title when renaming a list" do + %{user: user, conn: conn} = oauth_access(["write:lists"]) {:ok, list} = Pleroma.List.create("name", user) conn = @@ -151,14 +130,11 @@ defmodule Pleroma.Web.MastodonAPI.ListControllerTest do assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) end - test "deleting a list", %{conn: conn} do - user = insert(:user) + test "deleting a list" do + %{user: user, conn: conn} = oauth_access(["write:lists"]) {:ok, list} = Pleroma.List.create("name", user) - conn = - conn - |> assign(:user, user) - |> delete("/api/v1/lists/#{list.id}") + conn = delete(conn, "/api/v1/lists/#{list.id}") assert %{} = json_response(conn, 200) assert is_nil(Repo.get(Pleroma.List, list.id)) diff --git a/test/web/mastodon_api/controllers/marker_controller_test.exs b/test/web/mastodon_api/controllers/marker_controller_test.exs index 1fcad873d..919f295bd 100644 --- a/test/web/mastodon_api/controllers/marker_controller_test.exs +++ b/test/web/mastodon_api/controllers/marker_controller_test.exs @@ -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.MastodonAPI.MarkerControllerTest do diff --git a/test/web/mastodon_api/controllers/media_controller_test.exs b/test/web/mastodon_api/controllers/media_controller_test.exs index 06c6a1cb3..203fa73b0 100644 --- a/test/web/mastodon_api/controllers/media_controller_test.exs +++ b/test/web/mastodon_api/controllers/media_controller_test.exs @@ -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.MastodonAPI.MediaControllerTest do @@ -9,23 +9,17 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do alias Pleroma.User alias Pleroma.Web.ActivityPub.ActivityPub - import Pleroma.Factory + setup do: oauth_access(["write:media"]) describe "media upload" do setup do - user = insert(:user) - - conn = - build_conn() - |> assign(:user, user) - image = %Plug.Upload{ content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), filename: "an_image.jpg" } - [conn: conn, image: image] + [image: image] end clear_config([:media_proxy]) @@ -49,9 +43,7 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do end describe "PUT /api/v1/media/:id" do - setup do - actor = insert(:user) - + setup %{user: actor} do file = %Plug.Upload{ content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), @@ -65,13 +57,12 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do description: "test-m" ) - [actor: actor, object: object] + [object: object] end - test "updates name of media", %{conn: conn, actor: actor, object: object} do + test "updates name of media", %{conn: conn, object: object} do media = conn - |> assign(:user, actor) |> put("/api/v1/media/#{object.id}", %{"description" => "test-media"}) |> json_response(:ok) @@ -79,10 +70,9 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do assert refresh_record(object).data["name"] == "test-media" end - test "returns error wheb request is bad", %{conn: conn, actor: actor, object: object} do + test "returns error when request is bad", %{conn: conn, object: object} do media = conn - |> assign(:user, actor) |> put("/api/v1/media/#{object.id}", %{}) |> json_response(400) diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index c0b3621de..3bc9aff16 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -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.MastodonAPI.NotificationControllerTest do @@ -12,8 +12,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do import Pleroma.Factory - test "list of notifications", %{conn: conn} do - user = insert(:user) + test "list of notifications" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) @@ -34,18 +34,15 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert response == expected_response end - test "getting a single notification", %{conn: conn} do - user = insert(:user) + test "getting a single notification" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) {:ok, [notification]} = Notification.create_notifications(activity) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/notifications/#{notification.id}") + conn = get(conn, "/api/v1/notifications/#{notification.id}") expected_response = "hi <span class=\"h-card\"><a data-user=\"#{user.id}\" class=\"u-url mention\" href=\"#{ @@ -56,8 +53,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert response == expected_response end - test "dismissing a single notification", %{conn: conn} do - user = insert(:user) + test "dismissing a single notification" do + %{user: user, conn: conn} = oauth_access(["write:notifications"]) other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) @@ -72,32 +69,26 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert %{} = json_response(conn, 200) end - test "clearing all notifications", %{conn: conn} do - user = insert(:user) + test "clearing all notifications" do + %{user: user, conn: conn} = oauth_access(["write:notifications", "read:notifications"]) other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) {:ok, [_notification]} = Notification.create_notifications(activity) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/notifications/clear") + ret_conn = post(conn, "/api/v1/notifications/clear") - assert %{} = json_response(conn, 200) + assert %{} = json_response(ret_conn, 200) - conn = - build_conn() - |> assign(:user, user) - |> get("/api/v1/notifications") + ret_conn = get(conn, "/api/v1/notifications") - assert all = json_response(conn, 200) + assert all = json_response(ret_conn, 200) assert all == [] end - test "paginates notifications using min_id, since_id, max_id, and limit", %{conn: conn} do - user = insert(:user) + test "paginates notifications using min_id, since_id, max_id, and limit" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) {:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) @@ -137,59 +128,148 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert [%{"id" => ^notification3_id}, %{"id" => ^notification2_id}] = result end - test "filters notifications using exclude_visibilities", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - - {:ok, public_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "public"}) + describe "exclude_visibilities" do + test "filters notifications for mentions" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + other_user = insert(:user) - {:ok, direct_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "direct"}) - - {:ok, unlisted_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "unlisted"}) - - {:ok, private_activity} = - CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "private"}) - - conn = assign(conn, :user, user) - - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["public", "unlisted", "private"] - }) - - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) - assert id == direct_activity.id - - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["public", "unlisted", "direct"] - }) - - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) - assert id == private_activity.id - - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["public", "private", "direct"] - }) - - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) - assert id == unlisted_activity.id - - conn_res = - get(conn, "/api/v1/notifications", %{ - exclude_visibilities: ["unlisted", "private", "direct"] - }) + {:ok, public_activity} = + CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "public"}) + + {:ok, direct_activity} = + CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "direct"}) + + {:ok, unlisted_activity} = + CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "unlisted"}) + + {:ok, private_activity} = + CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "private"}) + + conn_res = + get(conn, "/api/v1/notifications", %{ + exclude_visibilities: ["public", "unlisted", "private"] + }) + + assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert id == direct_activity.id + + conn_res = + get(conn, "/api/v1/notifications", %{ + exclude_visibilities: ["public", "unlisted", "direct"] + }) - assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) - assert id == public_activity.id + assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert id == private_activity.id + + conn_res = + get(conn, "/api/v1/notifications", %{ + exclude_visibilities: ["public", "private", "direct"] + }) + + assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert id == unlisted_activity.id + + conn_res = + get(conn, "/api/v1/notifications", %{ + exclude_visibilities: ["unlisted", "private", "direct"] + }) + + assert [%{"status" => %{"id" => id}}] = json_response(conn_res, 200) + assert id == public_activity.id + end + + test "filters notifications for Like activities" do + user = insert(:user) + %{user: other_user, conn: conn} = oauth_access(["read:notifications"]) + + {:ok, public_activity} = + CommonAPI.post(other_user, %{"status" => ".", "visibility" => "public"}) + + {:ok, direct_activity} = + CommonAPI.post(other_user, %{"status" => "@#{user.nickname}", "visibility" => "direct"}) + + {:ok, unlisted_activity} = + CommonAPI.post(other_user, %{"status" => ".", "visibility" => "unlisted"}) + + {:ok, private_activity} = + CommonAPI.post(other_user, %{"status" => ".", "visibility" => "private"}) + + {:ok, _} = CommonAPI.favorite(user, public_activity.id) + {:ok, _} = CommonAPI.favorite(user, direct_activity.id) + {:ok, _} = CommonAPI.favorite(user, unlisted_activity.id) + {:ok, _} = CommonAPI.favorite(user, private_activity.id) + + activity_ids = + conn + |> get("/api/v1/notifications", %{exclude_visibilities: ["direct"]}) + |> json_response(200) + |> Enum.map(& &1["status"]["id"]) + + assert public_activity.id in activity_ids + assert unlisted_activity.id in activity_ids + assert private_activity.id in activity_ids + refute direct_activity.id in activity_ids + + activity_ids = + conn + |> get("/api/v1/notifications", %{exclude_visibilities: ["unlisted"]}) + |> json_response(200) + |> Enum.map(& &1["status"]["id"]) + + assert public_activity.id in activity_ids + refute unlisted_activity.id in activity_ids + assert private_activity.id in activity_ids + assert direct_activity.id in activity_ids + + activity_ids = + conn + |> get("/api/v1/notifications", %{exclude_visibilities: ["private"]}) + |> json_response(200) + |> Enum.map(& &1["status"]["id"]) + + assert public_activity.id in activity_ids + assert unlisted_activity.id in activity_ids + refute private_activity.id in activity_ids + assert direct_activity.id in activity_ids + + activity_ids = + conn + |> get("/api/v1/notifications", %{exclude_visibilities: ["public"]}) + |> json_response(200) + |> Enum.map(& &1["status"]["id"]) + + refute public_activity.id in activity_ids + assert unlisted_activity.id in activity_ids + assert private_activity.id in activity_ids + assert direct_activity.id in activity_ids + end + + test "filters notifications for Announce activities" do + user = insert(:user) + %{user: other_user, conn: conn} = oauth_access(["read:notifications"]) + + {:ok, public_activity} = + CommonAPI.post(other_user, %{"status" => ".", "visibility" => "public"}) + + {:ok, unlisted_activity} = + CommonAPI.post(other_user, %{"status" => ".", "visibility" => "unlisted"}) + + {:ok, _, _} = CommonAPI.repeat(public_activity.id, user) + {:ok, _, _} = CommonAPI.repeat(unlisted_activity.id, user) + + activity_ids = + conn + |> get("/api/v1/notifications", %{exclude_visibilities: ["unlisted"]}) + |> json_response(200) + |> Enum.map(& &1["status"]["id"]) + + assert public_activity.id in activity_ids + refute unlisted_activity.id in activity_ids + end end - test "filters notifications using exclude_types", %{conn: conn} do - user = insert(:user) + test "filters notifications using exclude_types" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) {:ok, mention_activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"}) @@ -203,8 +283,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do reblog_notification_id = get_notification_id_by_activity(reblog_activity) follow_notification_id = get_notification_id_by_activity(follow_activity) - conn = assign(conn, :user, user) - conn_res = get(conn, "/api/v1/notifications", %{exclude_types: ["mention", "favourite", "reblog"]}) @@ -226,8 +304,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert [%{"id" => ^reblog_notification_id}] = json_response(conn_res, 200) end - test "destroy multiple", %{conn: conn} do - user = insert(:user) + test "destroy multiple" do + %{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"]) other_user = insert(:user) {:ok, activity1} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) @@ -240,8 +318,6 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do notification3_id = get_notification_id_by_activity(activity3) notification4_id = get_notification_id_by_activity(activity4) - conn = assign(conn, :user, user) - result = conn |> get("/api/v1/notifications") @@ -252,6 +328,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do conn2 = conn |> assign(:user, other_user) + |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:notifications"])) result = conn2 @@ -276,71 +353,134 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do assert [%{"id" => ^notification4_id}, %{"id" => ^notification3_id}] = result end - test "doesn't see notifications after muting user with notifications", %{conn: conn} do - user = insert(:user) + test "doesn't see notifications after muting user with notifications" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) user2 = insert(:user) {:ok, _, _, _} = CommonAPI.follow(user, user2) {:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) - conn = assign(conn, :user, user) - - conn = get(conn, "/api/v1/notifications") + ret_conn = get(conn, "/api/v1/notifications") - assert length(json_response(conn, 200)) == 1 + assert length(json_response(ret_conn, 200)) == 1 - {:ok, user} = User.mute(user, user2) + {:ok, _user_relationships} = User.mute(user, user2) - conn = assign(build_conn(), :user, user) conn = get(conn, "/api/v1/notifications") assert json_response(conn, 200) == [] end - test "see notifications after muting user without notifications", %{conn: conn} do - user = insert(:user) + test "see notifications after muting user without notifications" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) user2 = insert(:user) {:ok, _, _, _} = CommonAPI.follow(user, user2) {:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) - conn = assign(conn, :user, user) - - conn = get(conn, "/api/v1/notifications") + ret_conn = get(conn, "/api/v1/notifications") - assert length(json_response(conn, 200)) == 1 + assert length(json_response(ret_conn, 200)) == 1 - {:ok, user} = User.mute(user, user2, false) + {:ok, _user_relationships} = User.mute(user, user2, false) - conn = assign(build_conn(), :user, user) conn = get(conn, "/api/v1/notifications") assert length(json_response(conn, 200)) == 1 end - test "see notifications after muting user with notifications and with_muted parameter", %{ - conn: conn - } do - user = insert(:user) + test "see notifications after muting user with notifications and with_muted parameter" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) user2 = insert(:user) {:ok, _, _, _} = CommonAPI.follow(user, user2) {:ok, _} = CommonAPI.post(user2, %{"status" => "hey @#{user.nickname}"}) - conn = assign(conn, :user, user) + ret_conn = get(conn, "/api/v1/notifications") - conn = get(conn, "/api/v1/notifications") + assert length(json_response(ret_conn, 200)) == 1 + + {:ok, _user_relationships} = User.mute(user, user2) + + conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"}) assert length(json_response(conn, 200)) == 1 + end - {:ok, user} = User.mute(user, user2) + test "see move notifications with `with_move` parameter" do + old_user = insert(:user) + new_user = insert(:user, also_known_as: [old_user.ap_id]) + %{user: follower, conn: conn} = oauth_access(["read:notifications"]) - conn = assign(build_conn(), :user, user) - conn = get(conn, "/api/v1/notifications", %{"with_muted" => "true"}) + User.follow(follower, old_user) + Pleroma.Web.ActivityPub.ActivityPub.move(old_user, new_user) + Pleroma.Tests.ObanHelpers.perform_all() + + ret_conn = get(conn, "/api/v1/notifications") + + assert json_response(ret_conn, 200) == [] + + conn = get(conn, "/api/v1/notifications", %{"with_move" => "true"}) assert length(json_response(conn, 200)) == 1 end + describe "link headers" do + test "preserves parameters in link headers" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + other_user = insert(:user) + + {:ok, activity1} = + CommonAPI.post(other_user, %{ + "status" => "hi @#{user.nickname}", + "visibility" => "public" + }) + + {:ok, activity2} = + CommonAPI.post(other_user, %{ + "status" => "hi @#{user.nickname}", + "visibility" => "public" + }) + + notification1 = Repo.get_by(Notification, activity_id: activity1.id) + notification2 = Repo.get_by(Notification, activity_id: activity2.id) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/notifications", %{media_only: true}) + + assert [link_header] = get_resp_header(conn, "link") + assert link_header =~ ~r/media_only=true/ + assert link_header =~ ~r/min_id=#{notification2.id}/ + assert link_header =~ ~r/max_id=#{notification1.id}/ + end + end + + describe "from specified user" do + test "account_id" do + %{user: user, conn: conn} = oauth_access(["read:notifications"]) + + %{id: account_id} = other_user1 = insert(:user) + other_user2 = insert(:user) + + {:ok, _activity} = CommonAPI.post(other_user1, %{"status" => "hi @#{user.nickname}"}) + {:ok, _activity} = CommonAPI.post(other_user2, %{"status" => "bye @#{user.nickname}"}) + + assert [%{"account" => %{"id" => ^account_id}}] = + conn + |> assign(:user, user) + |> get("/api/v1/notifications", %{account_id: account_id}) + |> json_response(200) + + assert %{"error" => "Account is not found"} = + conn + |> assign(:user, user) + |> get("/api/v1/notifications", %{account_id: "cofe"}) + |> json_response(404) + end + end + defp get_notification_id_by_activity(%{id: id}) do Notification |> Repo.get_by(activity_id: id) diff --git a/test/web/mastodon_api/controllers/poll_controller_test.exs b/test/web/mastodon_api/controllers/poll_controller_test.exs index 40cf3e879..88b13a25a 100644 --- a/test/web/mastodon_api/controllers/poll_controller_test.exs +++ b/test/web/mastodon_api/controllers/poll_controller_test.exs @@ -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.MastodonAPI.PollControllerTest do @@ -11,9 +11,9 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do import Pleroma.Factory describe "GET /api/v1/polls/:id" do - test "returns poll entity for object id", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["read:statuses"]) + test "returns poll entity for object id", %{user: user, conn: conn} do {:ok, activity} = CommonAPI.post(user, %{ "status" => "Pleroma does", @@ -22,10 +22,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do object = Object.normalize(activity) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/polls/#{object.id}") + conn = get(conn, "/api/v1/polls/#{object.id}") response = json_response(conn, 200) id = to_string(object.id) @@ -33,11 +30,10 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do end test "does not expose polls for private statuses", %{conn: conn} do - user = insert(:user) other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{ + CommonAPI.post(other_user, %{ "status" => "Pleroma does", "poll" => %{"options" => ["what Mastodon't", "n't what Mastodoes"], "expires_in" => 20}, "visibility" => "private" @@ -45,22 +41,20 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do object = Object.normalize(activity) - conn = - conn - |> assign(:user, other_user) - |> get("/api/v1/polls/#{object.id}") + conn = get(conn, "/api/v1/polls/#{object.id}") assert json_response(conn, 404) end end describe "POST /api/v1/polls/:id/votes" do + setup do: oauth_access(["write:statuses"]) + test "votes are added to the poll", %{conn: conn} do - user = insert(:user) other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{ + CommonAPI.post(other_user, %{ "status" => "A very delicious sandwich", "poll" => %{ "options" => ["Lettuce", "Grilled Bacon", "Tomato"], @@ -71,10 +65,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do object = Object.normalize(activity) - conn = - conn - |> assign(:user, other_user) - |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1, 2]}) + conn = post(conn, "/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1, 2]}) assert json_response(conn, 200) object = Object.get_by_id(object.id) @@ -84,9 +75,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do end) end - test "author can't vote", %{conn: conn} do - user = insert(:user) - + test "author can't vote", %{user: user, conn: conn} do {:ok, activity} = CommonAPI.post(user, %{ "status" => "Am I cute?", @@ -96,7 +85,6 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do object = Object.normalize(activity) assert conn - |> assign(:user, user) |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [1]}) |> json_response(422) == %{"error" => "Poll's author can't vote"} @@ -106,11 +94,10 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do end test "does not allow multiple choices on a single-choice question", %{conn: conn} do - user = insert(:user) other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{ + CommonAPI.post(other_user, %{ "status" => "The glass is", "poll" => %{"options" => ["half empty", "half full"], "expires_in" => 20} }) @@ -118,7 +105,6 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do object = Object.normalize(activity) assert conn - |> assign(:user, other_user) |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1]}) |> json_response(422) == %{"error" => "Too many choices"} @@ -130,42 +116,32 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do end test "does not allow choice index to be greater than options count", %{conn: conn} do - user = insert(:user) other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{ + CommonAPI.post(other_user, %{ "status" => "Am I cute?", "poll" => %{"options" => ["Yes", "No"], "expires_in" => 20} }) object = Object.normalize(activity) - conn = - conn - |> assign(:user, other_user) - |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [2]}) + conn = post(conn, "/api/v1/polls/#{object.id}/votes", %{"choices" => [2]}) assert json_response(conn, 422) == %{"error" => "Invalid indices"} end test "returns 404 error when object is not exist", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> post("/api/v1/polls/1/votes", %{"choices" => [0]}) + conn = post(conn, "/api/v1/polls/1/votes", %{"choices" => [0]}) assert json_response(conn, 404) == %{"error" => "Record not found"} end test "returns 404 when poll is private and not available for user", %{conn: conn} do - user = insert(:user) other_user = insert(:user) {:ok, activity} = - CommonAPI.post(user, %{ + CommonAPI.post(other_user, %{ "status" => "Am I cute?", "poll" => %{"options" => ["Yes", "No"], "expires_in" => 20}, "visibility" => "private" @@ -173,10 +149,7 @@ defmodule Pleroma.Web.MastodonAPI.PollControllerTest do object = Object.normalize(activity) - conn = - conn - |> assign(:user, other_user) - |> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0]}) + conn = post(conn, "/api/v1/polls/#{object.id}/votes", %{"choices" => [0]}) assert json_response(conn, 404) == %{"error" => "Record not found"} end diff --git a/test/web/mastodon_api/controllers/report_controller_test.exs b/test/web/mastodon_api/controllers/report_controller_test.exs index 979ca48f3..34ec8119e 100644 --- a/test/web/mastodon_api/controllers/report_controller_test.exs +++ b/test/web/mastodon_api/controllers/report_controller_test.exs @@ -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.MastodonAPI.ReportControllerTest do @@ -9,32 +9,30 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do import Pleroma.Factory + setup do: oauth_access(["write:reports"]) + setup do - reporter = insert(:user) target_user = insert(:user) {:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"}) - [reporter: reporter, target_user: target_user, activity: activity] + [target_user: target_user, activity: activity] end - test "submit a basic report", %{conn: conn, reporter: reporter, target_user: target_user} do + test "submit a basic report", %{conn: conn, target_user: target_user} do assert %{"action_taken" => false, "id" => _} = conn - |> assign(:user, reporter) |> post("/api/v1/reports", %{"account_id" => target_user.id}) |> json_response(200) end test "submit a report with statuses and comment", %{ conn: conn, - reporter: reporter, target_user: target_user, activity: activity } do assert %{"action_taken" => false, "id" => _} = conn - |> assign(:user, reporter) |> post("/api/v1/reports", %{ "account_id" => target_user.id, "status_ids" => [activity.id], @@ -46,19 +44,16 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do test "account_id is required", %{ conn: conn, - reporter: reporter, activity: activity } do assert %{"error" => "Valid `account_id` required"} = conn - |> assign(:user, reporter) |> post("/api/v1/reports", %{"status_ids" => [activity.id]}) |> json_response(400) end test "comment must be up to the size specified in the config", %{ conn: conn, - reporter: reporter, target_user: target_user } do max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000) @@ -68,21 +63,25 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do assert ^error = conn - |> assign(:user, reporter) |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment}) |> json_response(400) end test "returns error when account is not exist", %{ conn: conn, - reporter: reporter, activity: activity } do - conn = - conn - |> assign(:user, reporter) - |> post("/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"}) + conn = post(conn, "/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"}) assert json_response(conn, 400) == %{"error" => "Account not found"} end + + test "doesn't fail if an admin has no email", %{conn: conn, target_user: target_user} do + insert(:user, %{is_admin: true, email: nil}) + + assert %{"action_taken" => false, "id" => _} = + conn + |> post("/api/v1/reports", %{"account_id" => target_user.id}) + |> json_response(200) + end end diff --git a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs index ae5fee2bc..3cd08c189 100644 --- a/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs +++ b/test/web/mastodon_api/controllers/scheduled_activity_controller_test.exs @@ -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.MastodonAPI.ScheduledActivityControllerTest do @@ -9,91 +9,106 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do alias Pleroma.ScheduledActivity import Pleroma.Factory + import Ecto.Query + + clear_config([ScheduledActivity, :enabled]) + + test "shows scheduled activities" do + %{user: user, conn: conn} = oauth_access(["read:statuses"]) - test "shows scheduled activities", %{conn: conn} do - user = insert(:user) scheduled_activity_id1 = insert(:scheduled_activity, user: user).id |> to_string() scheduled_activity_id2 = insert(:scheduled_activity, user: user).id |> to_string() scheduled_activity_id3 = insert(:scheduled_activity, user: user).id |> to_string() scheduled_activity_id4 = insert(:scheduled_activity, user: user).id |> to_string() - conn = - conn - |> assign(:user, user) - # min_id - conn_res = - conn - |> get("/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}") + conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}") result = json_response(conn_res, 200) assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result # since_id - conn_res = - conn - |> get("/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}") + conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}") result = json_response(conn_res, 200) assert [%{"id" => ^scheduled_activity_id4}, %{"id" => ^scheduled_activity_id3}] = result # max_id - conn_res = - conn - |> get("/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}") + conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}") result = json_response(conn_res, 200) assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result end - test "shows a scheduled activity", %{conn: conn} do - user = insert(:user) + test "shows a scheduled activity" do + %{user: user, conn: conn} = oauth_access(["read:statuses"]) scheduled_activity = insert(:scheduled_activity, user: user) - res_conn = - conn - |> assign(:user, user) - |> get("/api/v1/scheduled_statuses/#{scheduled_activity.id}") + res_conn = get(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}") assert %{"id" => scheduled_activity_id} = json_response(res_conn, 200) assert scheduled_activity_id == scheduled_activity.id |> to_string() - res_conn = - conn - |> assign(:user, user) - |> get("/api/v1/scheduled_statuses/404") + res_conn = get(conn, "/api/v1/scheduled_statuses/404") assert %{"error" => "Record not found"} = json_response(res_conn, 404) end - test "updates a scheduled activity", %{conn: conn} do - user = insert(:user) - scheduled_activity = insert(:scheduled_activity, user: user) + test "updates a scheduled activity" do + Pleroma.Config.put([ScheduledActivity, :enabled], true) + %{user: user, conn: conn} = oauth_access(["write:statuses"]) - new_scheduled_at = - NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond) + scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 60) + + {:ok, scheduled_activity} = + ScheduledActivity.create( + user, + %{ + scheduled_at: scheduled_at, + params: build(:note).data + } + ) + + job = Repo.one(from(j in Oban.Job, where: j.queue == "scheduled_activities")) + + assert job.args == %{"activity_id" => scheduled_activity.id} + assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(scheduled_at) + + new_scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 120) res_conn = - conn - |> assign(:user, user) - |> put("/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{ + put(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{ scheduled_at: new_scheduled_at }) assert %{"scheduled_at" => expected_scheduled_at} = json_response(res_conn, 200) assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(new_scheduled_at) + job = refresh_record(job) - res_conn = - conn - |> assign(:user, user) - |> put("/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at}) + assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(new_scheduled_at) + + res_conn = put(conn, "/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at}) assert %{"error" => "Record not found"} = json_response(res_conn, 404) end - test "deletes a scheduled activity", %{conn: conn} do - user = insert(:user) - scheduled_activity = insert(:scheduled_activity, user: user) + test "deletes a scheduled activity" do + Pleroma.Config.put([ScheduledActivity, :enabled], true) + %{user: user, conn: conn} = oauth_access(["write:statuses"]) + scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 60) + + {:ok, scheduled_activity} = + ScheduledActivity.create( + user, + %{ + scheduled_at: scheduled_at, + params: build(:note).data + } + ) + + job = Repo.one(from(j in Oban.Job, where: j.queue == "scheduled_activities")) + + assert job.args == %{"activity_id" => scheduled_activity.id} res_conn = conn @@ -101,7 +116,8 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do |> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}") assert %{} = json_response(res_conn, 200) - assert nil == Repo.get(ScheduledActivity, scheduled_activity.id) + refute Repo.get(ScheduledActivity, scheduled_activity.id) + refute Repo.get(Oban.Job, job.id) res_conn = conn diff --git a/test/web/mastodon_api/controllers/search_controller_test.exs b/test/web/mastodon_api/controllers/search_controller_test.exs index 7953fad62..11133ff66 100644 --- a/test/web/mastodon_api/controllers/search_controller_test.exs +++ b/test/web/mastodon_api/controllers/search_controller_test.exs @@ -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.MastodonAPI.SearchControllerTest do @@ -53,7 +53,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) results = - get(conn, "/api/v2/search", %{"q" => "2hu #private"}) + conn + |> get("/api/v2/search", %{"q" => "2hu #private"}) |> json_response(200) [account | _] = results["accounts"] @@ -73,17 +74,39 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do [status] = results["statuses"] assert status["id"] == to_string(activity.id) 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"}) + user_neo = insert(:user, %{nickname: "Agent Neo", name: "Agent"}) + + {:ok, act1} = CommonAPI.post(user, %{"status" => "This is about 2hu private 天子"}) + {:ok, act2} = CommonAPI.post(user_smith, %{"status" => "Agent Smith"}) + {:ok, act3} = CommonAPI.post(user_neo, %{"status" => "Agent Smith"}) + Pleroma.User.block(user, user_smith) + + results = + conn + |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"])) + |> get("/api/v2/search", %{"q" => "Agent"}) + |> json_response(200) + + status_ids = Enum.map(results["statuses"], fn g -> g["id"] end) + + assert act3.id in status_ids + refute act2.id in status_ids + refute act1.id in status_ids + end end describe ".account_search" do test "account search", %{conn: conn} do - user = insert(:user) user_two = insert(:user, %{nickname: "shp@shitposter.club"}) user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) results = conn - |> assign(:user, user) |> get("/api/v1/accounts/search", %{"q" => "shp"}) |> json_response(200) @@ -94,7 +117,6 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do results = conn - |> assign(:user, user) |> get("/api/v1/accounts/search", %{"q" => "2hu"}) |> json_response(200) @@ -104,11 +126,10 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do end test "returns account if query contains a space", %{conn: conn} do - user = insert(:user, %{nickname: "shp@shitposter.club"}) + insert(:user, %{nickname: "shp@shitposter.club"}) results = conn - |> assign(:user, user) |> get("/api/v1/accounts/search", %{"q" => "shp@shitposter.club xxx "}) |> json_response(200) @@ -150,11 +171,10 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) - conn = + results = conn |> get("/api/v1/search", %{"q" => "2hu"}) - - assert results = json_response(conn, 200) + |> json_response(200) [account | _] = results["accounts"] assert account["id"] == to_string(user_three.id) @@ -165,15 +185,19 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do assert status["id"] == to_string(activity.id) end - test "search fetches remote statuses", %{conn: conn} do + test "search fetches remote statuses and prefers them over other results", %{conn: conn} do capture_log(fn -> - conn = + {:ok, %{id: activity_id}} = + CommonAPI.post(insert(:user), %{ + "status" => "check out https://shitposter.club/notice/2827873" + }) + + results = conn |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"}) + |> json_response(200) - assert results = json_response(conn, 200) - - [status] = results["statuses"] + [status, %{"id" => ^activity_id}] = results["statuses"] assert status["uri"] == "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment" @@ -188,11 +212,10 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do }) capture_log(fn -> - conn = + results = conn |> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]}) - - assert results = json_response(conn, 200) + |> json_response(200) [] = results["statuses"] end) @@ -201,22 +224,23 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do test "search fetches remote accounts", %{conn: conn} do user = insert(:user) - conn = + results = conn |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"])) |> get("/api/v1/search", %{"q" => "mike@osada.macgirvin.com", "resolve" => "true"}) + |> json_response(200) - assert results = json_response(conn, 200) [account] = results["accounts"] assert account["acct"] == "mike@osada.macgirvin.com" end test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do - conn = + results = conn |> get("/api/v1/search", %{"q" => "mike@osada.macgirvin.com", "resolve" => "false"}) + |> json_response(200) - assert results = json_response(conn, 200) assert [] == results["accounts"] end diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index 2ce201e2e..f36552041 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -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.MastodonAPI.StatusControllerTest do @@ -18,30 +18,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do alias Pleroma.Web.CommonAPI import Pleroma.Factory - import ExUnit.CaptureLog clear_config([:instance, :federating]) clear_config([:instance, :allow_relay]) + clear_config([:rich_media, :enabled]) describe "posting statuses" do - setup do - user = insert(:user) - - conn = - build_conn() - |> assign(:user, user) - - [conn: conn] - end + setup do: oauth_access(["write:statuses"]) test "posting a status does not increment reblog_count when relaying", %{conn: conn} do Pleroma.Config.put([:instance, :federating], true) Pleroma.Config.get([:instance, :allow_relay], true) - user = insert(:user) response = conn - |> assign(:user, user) |> post("api/v1/statuses", %{ "content_type" => "text/plain", "source" => "Pleroma FE", @@ -55,7 +45,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn - |> assign(:user, user) |> get("api/v1/statuses/#{response["id"]}", %{}) |> json_response(200) @@ -133,9 +122,33 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do NaiveDateTime.to_iso8601(expiration.scheduled_at) end - test "posting an undefined status with an attachment", %{conn: conn} do - user = insert(:user) + test "it fails to create a status if `expires_in` is less or equal than an hour", %{ + conn: conn + } do + # 1 hour + expires_in = 60 * 60 + + assert %{"error" => "Expiry date is too soon"} = + conn + |> post("api/v1/statuses", %{ + "status" => "oolong", + "expires_in" => expires_in + }) + |> json_response(422) + # 30 minutes + expires_in = 30 * 60 + + assert %{"error" => "Expiry date is too soon"} = + conn + |> post("api/v1/statuses", %{ + "status" => "oolong", + "expires_in" => expires_in + }) + |> json_response(422) + end + + test "posting an undefined status with an attachment", %{user: user, conn: conn} do file = %Plug.Upload{ content_type: "image/jpg", path: Path.absname("test/fixtures/image.jpg"), @@ -145,17 +158,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "media_ids" => [to_string(upload.id)] }) assert json_response(conn, 200) end - test "replying to a status", %{conn: conn} do - user = insert(:user) + test "replying to a status", %{user: user, conn: conn} do {:ok, replied_to} = CommonAPI.post(user, %{"status" => "cofe"}) conn = @@ -170,8 +180,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert Activity.get_in_reply_to_activity(activity).id == replied_to.id end - test "replying to a direct message with visibility other than direct", %{conn: conn} do - user = insert(:user) + test "replying to a direct message with visibility other than direct", %{ + user: user, + conn: conn + } do {:ok, replied_to} = CommonAPI.post(user, %{"status" => "suya..", "visibility" => "direct"}) Enum.each(["public", "private", "unlisted"], fn visibility -> @@ -188,18 +200,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "posting a status with an invalid in_reply_to_id", %{conn: conn} do - conn = - conn - |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""}) + conn = post(conn, "/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => ""}) assert %{"content" => "xD", "id" => id} = json_response(conn, 200) assert Activity.get_by_id(id) end test "posting a sensitive status", %{conn: conn} do - conn = - conn - |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true}) + conn = post(conn, "/api/v1/statuses", %{"status" => "cofe", "sensitive" => true}) assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200) assert Activity.get_by_id(id) @@ -207,8 +215,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "posting a fake status", %{conn: conn} do real_conn = - conn - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it" }) @@ -227,8 +234,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do |> Kernel.put_in(["pleroma", "conversation_id"], nil) fake_conn = - conn - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "\"Tenshi Eating a Corndog\" is a much discussed concept on /jp/. The significance of it is disputed, so I will focus on one core concept: the symbolism behind it", "preview" => true @@ -255,8 +261,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do Config.put([:rich_media, :enabled], true) conn = - conn - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "https://example.com/ogp" }) @@ -268,9 +273,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do user2 = insert(:user) content = "direct cofe @#{user2.nickname}" - conn = - conn - |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"}) + conn = post(conn, "api/v1/statuses", %{"status" => content, "visibility" => "direct"}) assert %{"id" => id} = response = json_response(conn, 200) assert response["visibility"] == "direct" @@ -283,14 +286,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end describe "posting scheduled statuses" do + setup do: oauth_access(["write:statuses"]) + test "creates a scheduled activity", %{conn: conn} do - user = insert(:user) scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "scheduled", "scheduled_at" => scheduled_at }) @@ -300,8 +302,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert [] == Repo.all(Activity) end - test "creates a scheduled activity with a media attachment", %{conn: conn} do - user = insert(:user) + test "creates a scheduled activity with a media attachment", %{user: user, conn: conn} do scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(120), :millisecond) file = %Plug.Upload{ @@ -313,9 +314,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "media_ids" => [to_string(upload.id)], "status" => "scheduled", "scheduled_at" => scheduled_at @@ -327,15 +326,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "skips the scheduling and creates the activity if scheduled_at is earlier than 5 minutes from now", %{conn: conn} do - user = insert(:user) - scheduled_at = NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(5) - 1, :millisecond) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "not scheduled", "scheduled_at" => scheduled_at }) @@ -344,9 +339,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert [] == Repo.all(ScheduledActivity) end - test "returns error when daily user limit is exceeded", %{conn: conn} do - user = insert(:user) - + test "returns error when daily user limit is exceeded", %{user: user, conn: conn} do today = NaiveDateTime.utc_now() |> NaiveDateTime.add(:timer.minutes(6), :millisecond) @@ -356,17 +349,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _} = ScheduledActivity.create(user, attrs) {:ok, _} = ScheduledActivity.create(user, attrs) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today}) + conn = post(conn, "/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => today}) assert %{"error" => "daily limit exceeded"} == json_response(conn, 422) end - test "returns error when total user limit is exceeded", %{conn: conn} do - user = insert(:user) - + test "returns error when total user limit is exceeded", %{user: user, conn: conn} do today = NaiveDateTime.utc_now() |> NaiveDateTime.add(:timer.minutes(6), :millisecond) @@ -383,23 +371,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _} = ScheduledActivity.create(user, %{params: %{}, scheduled_at: tomorrow}) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow}) + post(conn, "/api/v1/statuses", %{"status" => "scheduled", "scheduled_at" => tomorrow}) assert %{"error" => "total limit exceeded"} == json_response(conn, 422) end end describe "posting polls" do + setup do: oauth_access(["write:statuses"]) + test "posting a poll", %{conn: conn} do - user = insert(:user) time = NaiveDateTime.utc_now() conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "Who is the #bestgrill?", "poll" => %{"options" => ["Rei", "Asuka", "Misato"], "expires_in" => 420} }) @@ -412,16 +397,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert NaiveDateTime.diff(NaiveDateTime.from_iso8601!(response["poll"]["expires_at"]), time) in 420..430 refute response["poll"]["expred"] + + question = Object.get_by_id(response["poll"]["id"]) + + # closed contains utc timezone + assert question.data["closed"] =~ "Z" end test "option limit is enforced", %{conn: conn} do - user = insert(:user) limit = Config.get([:instance, :poll_limits, :max_options]) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "desu~", "poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1} }) @@ -431,13 +418,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "option character limit is enforced", %{conn: conn} do - user = insert(:user) limit = Config.get([:instance, :poll_limits, :max_option_chars]) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "...", "poll" => %{ "options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)], @@ -450,13 +434,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "minimal date limit is enforced", %{conn: conn} do - user = insert(:user) limit = Config.get([:instance, :poll_limits, :min_expiration]) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "imagine arbitrary limits", "poll" => %{ "options" => ["this post was made by pleroma gang"], @@ -469,13 +450,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "maximum date limit is enforced", %{conn: conn} do - user = insert(:user) limit = Config.get([:instance, :poll_limits, :max_expiration]) conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses", %{ + post(conn, "/api/v1/statuses", %{ "status" => "imagine arbitrary limits", "poll" => %{ "options" => ["this post was made by pleroma gang"], @@ -488,19 +466,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end end - test "get a status", %{conn: conn} do + test "get a status" do + %{conn: conn} = oauth_access(["read:statuses"]) activity = insert(:note_activity) - conn = - conn - |> get("/api/v1/statuses/#{activity.id}") + conn = get(conn, "/api/v1/statuses/#{activity.id}") assert %{"id" => id} = json_response(conn, 200) assert id == to_string(activity.id) end - test "get a direct status", %{conn: conn} do - user = insert(:user) + test "getting a status that doesn't exist returns 404" do + %{conn: conn} = oauth_access(["read:statuses"]) + activity = insert(:note_activity) + + conn = get(conn, "/api/v1/statuses/#{String.downcase(activity.id)}") + + assert json_response(conn, 404) == %{"error" => "Record not found"} + end + + test "get a direct status" do + %{user: user, conn: conn} = oauth_access(["read:statuses"]) other_user = insert(:user) {:ok, activity} = @@ -517,7 +503,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert res["pleroma"]["direct_conversation_id"] == participation.id end - test "get statuses by IDs", %{conn: conn} do + test "get statuses by IDs" do + %{conn: conn} = oauth_access(["read:statuses"]) %{id: id1} = insert(:note_activity) %{id: id2} = insert(:note_activity) @@ -528,9 +515,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end describe "deleting a status" do - test "when you created it", %{conn: conn} do - activity = insert(:note_activity) - author = User.get_cached_by_ap_id(activity.data["actor"]) + test "when you created it" do + %{user: author, conn: conn} = oauth_access(["write:statuses"]) + activity = insert(:note_activity, user: author) conn = conn @@ -542,14 +529,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do refute Activity.get_by_id(activity.id) end - test "when you didn't create it", %{conn: conn} do - activity = insert(:note_activity) - user = insert(:user) + test "when it doesn't exist" do + %{user: author, conn: conn} = oauth_access(["write:statuses"]) + activity = insert(:note_activity, user: author) conn = conn - |> assign(:user, user) - |> delete("/api/v1/statuses/#{activity.id}") + |> assign(:user, author) + |> delete("/api/v1/statuses/#{String.downcase(activity.id)}") + + assert %{"error" => "Record not found"} == json_response(conn, 404) + end + + test "when you didn't create it" do + %{conn: conn} = oauth_access(["write:statuses"]) + activity = insert(:note_activity) + + conn = delete(conn, "/api/v1/statuses/#{activity.id}") assert %{"error" => _} = json_response(conn, 403) @@ -565,6 +561,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do res_conn = conn |> assign(:user, admin) + |> assign(:token, insert(:oauth_token, user: admin, scopes: ["write:statuses"])) |> delete("/api/v1/statuses/#{activity1.id}") assert %{} = json_response(res_conn, 200) @@ -572,6 +569,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do res_conn = conn |> assign(:user, moderator) + |> assign(:token, insert(:oauth_token, user: moderator, scopes: ["write:statuses"])) |> delete("/api/v1/statuses/#{activity2.id}") assert %{} = json_response(res_conn, 200) @@ -582,14 +580,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end describe "reblogging" do + setup do: oauth_access(["write:statuses"]) + test "reblogs and returns the reblogged status", %{conn: conn} do activity = insert(:note_activity) - user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{activity.id}/reblog") + conn = post(conn, "/api/v1/statuses/#{activity.id}/reblog") assert %{ "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}, @@ -599,14 +595,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert to_string(activity.id) == id end + test "returns 404 if the reblogged status doesn't exist", %{conn: conn} do + activity = insert(:note_activity) + + conn = post(conn, "/api/v1/statuses/#{String.downcase(activity.id)}/reblog") + + assert %{"error" => "Record not found"} = json_response(conn, 404) + end + test "reblogs privately and returns the reblogged status", %{conn: conn} do activity = insert(:note_activity) - user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{activity.id}/reblog", %{"visibility" => "private"}) + conn = post(conn, "/api/v1/statuses/#{activity.id}/reblog", %{"visibility" => "private"}) assert %{ "reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}, @@ -617,7 +617,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert to_string(activity.id) == id end - test "reblogged status for another user", %{conn: conn} do + test "reblogged status for another user" do activity = insert(:note_activity) user1 = insert(:user) user2 = insert(:user) @@ -628,8 +628,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _, _object} = CommonAPI.repeat(activity.id, user2) conn_res = - conn + build_conn() |> assign(:user, user3) + |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"])) |> get("/api/v1/statuses/#{reblog_activity1.id}") assert %{ @@ -640,8 +641,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } = json_response(conn_res, 200) conn_res = - conn + build_conn() |> assign(:user, user2) + |> assign(:token, insert(:oauth_token, user: user2, scopes: ["read:statuses"])) |> get("/api/v1/statuses/#{reblog_activity1.id}") assert %{ @@ -653,57 +655,37 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert to_string(activity.id) == id end - - test "returns 400 error when activity is not exist", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/foo/reblog") - - assert json_response(conn, 400) == %{"error" => "Could not repeat"} - end end describe "unreblogging" do - test "unreblogs and returns the unreblogged status", %{conn: conn} do + setup do: oauth_access(["write:statuses"]) + + test "unreblogs and returns the unreblogged status", %{user: user, conn: conn} do activity = insert(:note_activity) - user = insert(:user) {:ok, _, _} = CommonAPI.repeat(activity.id, user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{activity.id}/unreblog") + conn = post(conn, "/api/v1/statuses/#{activity.id}/unreblog") assert %{"id" => id, "reblogged" => false, "reblogs_count" => 0} = json_response(conn, 200) assert to_string(activity.id) == id end - test "returns 400 error when activity is not exist", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/foo/unreblog") + test "returns 404 error when activity does not exist", %{conn: conn} do + conn = post(conn, "/api/v1/statuses/foo/unreblog") - assert json_response(conn, 400) == %{"error" => "Could not unrepeat"} + assert json_response(conn, 404) == %{"error" => "Record not found"} end end describe "favoriting" do + setup do: oauth_access(["write:favourites"]) + test "favs a status and returns it", %{conn: conn} do activity = insert(:note_activity) - user = insert(:user) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{activity.id}/favourite") + conn = post(conn, "/api/v1/statuses/#{activity.id}/favourite") assert %{"id" => id, "favourites_count" => 1, "favourited" => true} = json_response(conn, 200) @@ -711,31 +693,33 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert to_string(activity.id) == id end - test "returns 400 error for a wrong id", %{conn: conn} do - user = insert(:user) + test "favoriting twice will just return 200", %{conn: conn} do + activity = insert(:note_activity) - assert capture_log(fn -> - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/1/favourite") + post(conn, "/api/v1/statuses/#{activity.id}/favourite") - assert json_response(conn, 400) == %{"error" => "Could not favorite"} - end) =~ "[error]" + assert post(conn, "/api/v1/statuses/#{activity.id}/favourite") + |> json_response(200) + end + + test "returns 404 error for a wrong id", %{conn: conn} do + conn = + conn + |> post("/api/v1/statuses/1/favourite") + + assert json_response(conn, 404) == %{"error" => "Record not found"} end end describe "unfavoriting" do - test "unfavorites a status and returns it", %{conn: conn} do + setup do: oauth_access(["write:favourites"]) + + test "unfavorites a status and returns it", %{user: user, conn: conn} do activity = insert(:note_activity) - user = insert(:user) {:ok, _} = CommonAPI.favorite(user, activity.id) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{activity.id}/unfavourite") + conn = post(conn, "/api/v1/statuses/#{activity.id}/unfavourite") assert %{"id" => id, "favourites_count" => 0, "favourited" => false} = json_response(conn, 200) @@ -743,24 +727,20 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert to_string(activity.id) == id end - test "returns 400 error for a wrong id", %{conn: conn} do - user = insert(:user) + test "returns 404 error for a wrong id", %{conn: conn} do + conn = post(conn, "/api/v1/statuses/1/unfavourite") - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/1/unfavourite") - - assert json_response(conn, 400) == %{"error" => "Could not unfavorite"} + assert json_response(conn, 404) == %{"error" => "Record not found"} end end describe "pinned statuses" do - setup do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) + + setup %{user: user} do {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!"}) - [user: user, activity: activity] + %{activity: activity} end clear_config([:instance, :max_pinned_statuses]) do @@ -772,13 +752,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert %{"id" => ^id_str, "pinned" => true} = conn - |> assign(:user, user) |> post("/api/v1/statuses/#{activity.id}/pin") |> json_response(200) assert [%{"id" => ^id_str, "pinned" => true}] = conn - |> assign(:user, user) |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") |> json_response(200) end @@ -786,19 +764,16 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "/pin: returns 400 error when activity is not public", %{conn: conn, user: user} do {:ok, dm} = CommonAPI.post(user, %{"status" => "test", "visibility" => "direct"}) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{dm.id}/pin") + conn = post(conn, "/api/v1/statuses/#{dm.id}/pin") assert json_response(conn, 400) == %{"error" => "Could not pin"} end test "unpin status", %{conn: conn, user: user, activity: activity} do {:ok, _} = CommonAPI.pin(activity.id, user) + user = refresh_record(user) id_str = to_string(activity.id) - user = refresh_record(user) assert %{"id" => ^id_str, "pinned" => false} = conn @@ -808,16 +783,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert [] = conn - |> assign(:user, user) |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") |> json_response(200) end - test "/unpin: returns 400 error when activity is not exist", %{conn: conn, user: user} do - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/1/unpin") + test "/unpin: returns 400 error when activity is not exist", %{conn: conn} do + conn = post(conn, "/api/v1/statuses/1/unpin") assert json_response(conn, 400) == %{"error" => "Could not unpin"} end @@ -829,7 +800,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert %{"id" => ^id_str_one, "pinned" => true} = conn - |> assign(:user, user) |> post("/api/v1/statuses/#{id_str_one}/pin") |> json_response(200) @@ -847,8 +817,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do setup do Config.put([:rich_media, :enabled], true) - user = insert(:user) - %{user: user} + oauth_access(["read:statuses"]) end test "returns rich-media card", %{conn: conn, user: user} do @@ -890,7 +859,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response_two = conn - |> assign(:user, user) |> get("/api/v1/statuses/#{activity.id}/card") |> json_response(200) @@ -928,72 +896,55 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "bookmarks" do - user = insert(:user) - for_user = insert(:user) + %{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"]) + author = insert(:user) {:ok, activity1} = - CommonAPI.post(user, %{ + CommonAPI.post(author, %{ "status" => "heweoo?" }) {:ok, activity2} = - CommonAPI.post(user, %{ + CommonAPI.post(author, %{ "status" => "heweoo!" }) - response1 = - build_conn() - |> assign(:user, for_user) - |> post("/api/v1/statuses/#{activity1.id}/bookmark") + response1 = post(conn, "/api/v1/statuses/#{activity1.id}/bookmark") assert json_response(response1, 200)["bookmarked"] == true - response2 = - build_conn() - |> assign(:user, for_user) - |> post("/api/v1/statuses/#{activity2.id}/bookmark") + response2 = post(conn, "/api/v1/statuses/#{activity2.id}/bookmark") assert json_response(response2, 200)["bookmarked"] == true - bookmarks = - build_conn() - |> assign(:user, for_user) - |> get("/api/v1/bookmarks") + bookmarks = get(conn, "/api/v1/bookmarks") assert [json_response(response2, 200), json_response(response1, 200)] == json_response(bookmarks, 200) - response1 = - build_conn() - |> assign(:user, for_user) - |> post("/api/v1/statuses/#{activity1.id}/unbookmark") + response1 = post(conn, "/api/v1/statuses/#{activity1.id}/unbookmark") assert json_response(response1, 200)["bookmarked"] == false - bookmarks = - build_conn() - |> assign(:user, for_user) - |> get("/api/v1/bookmarks") + bookmarks = get(conn, "/api/v1/bookmarks") assert [json_response(response2, 200)] == json_response(bookmarks, 200) end describe "conversation muting" do + setup do: oauth_access(["write:mutes"]) + setup do post_user = insert(:user) - user = insert(:user) - {:ok, activity} = CommonAPI.post(post_user, %{"status" => "HIE"}) - - [user: user, activity: activity] + %{activity: activity} end - test "mute conversation", %{conn: conn, user: user, activity: activity} do + test "mute conversation", %{conn: conn, activity: activity} do id_str = to_string(activity.id) assert %{"id" => ^id_str, "muted" => true} = conn - |> assign(:user, user) |> post("/api/v1/statuses/#{activity.id}/mute") |> json_response(200) end @@ -1001,10 +952,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do test "cannot mute already muted conversation", %{conn: conn, user: user, activity: activity} do {:ok, _} = CommonAPI.add_mute(user, activity) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/statuses/#{activity.id}/mute") + conn = post(conn, "/api/v1/statuses/#{activity.id}/mute") assert json_response(conn, 400) == %{"error" => "conversation is already muted"} end @@ -1013,11 +961,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _} = CommonAPI.add_mute(user, activity) id_str = to_string(activity.id) - user = refresh_record(user) assert %{"id" => ^id_str, "muted" => false} = conn - |> assign(:user, user) + # |> assign(:user, user) |> post("/api/v1/statuses/#{activity.id}/unmute") |> json_response(200) end @@ -1034,6 +981,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn1 = conn |> assign(:user, user2) + |> assign(:token, insert(:oauth_token, user: user2, scopes: ["write:statuses"])) |> post("/api/v1/statuses", %{"status" => "xD", "in_reply_to_id" => replied_to.id}) assert %{"content" => "xD", "id" => id} = json_response(conn1, 200) @@ -1047,6 +995,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn2 = conn |> assign(:user, user3) + |> assign(:token, insert(:oauth_token, user: user3, scopes: ["write:statuses"])) |> post("/api/v1/statuses/#{activity.id}/reblog") assert %{"reblog" => %{"id" => id, "reblogged" => true, "reblogs_count" => 1}} = @@ -1058,6 +1007,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do conn3 = conn |> assign(:user, user3) + |> assign(:token, insert(:oauth_token, user: user3, scopes: ["read:statuses"])) |> get("api/v1/timelines/home") [reblogged_activity] = json_response(conn3, 200) @@ -1069,15 +1019,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end describe "GET /api/v1/statuses/:id/favourited_by" do - setup do - user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) + setup do: oauth_access(["read:accounts"]) - conn = - build_conn() - |> assign(:user, user) + setup %{user: user} do + {:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) - [conn: conn, activity: activity, user: user] + %{activity: activity} end test "returns users who have favorited the status", %{conn: conn, activity: activity} do @@ -1111,26 +1058,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do activity: activity } do other_user = insert(:user) - {:ok, user} = User.block(user, other_user) + {:ok, _user_relationship} = User.block(user, other_user) {:ok, _} = CommonAPI.favorite(other_user, activity.id) response = conn - |> assign(:user, user) |> get("/api/v1/statuses/#{activity.id}/favourited_by") |> json_response(:ok) assert Enum.empty?(response) end - test "does not fail on an unauthenticated request", %{conn: conn, activity: activity} do + test "does not fail on an unauthenticated request", %{activity: activity} do other_user = insert(:user) {:ok, _} = CommonAPI.favorite(other_user, activity.id) response = - conn - |> assign(:user, nil) + build_conn() |> get("/api/v1/statuses/#{activity.id}/favourited_by") |> json_response(:ok) @@ -1138,7 +1083,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert id == other_user.id end - test "requires authentification for private posts", %{conn: conn, user: user} do + test "requires authentication for private posts", %{user: user} do other_user = insert(:user) {:ok, activity} = @@ -1149,15 +1094,25 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _} = CommonAPI.favorite(other_user, activity.id) - conn - |> assign(:user, nil) - |> get("/api/v1/statuses/#{activity.id}/favourited_by") + favourited_by_url = "/api/v1/statuses/#{activity.id}/favourited_by" + + build_conn() + |> get(favourited_by_url) |> json_response(404) - response = + conn = build_conn() |> assign(:user, other_user) - |> get("/api/v1/statuses/#{activity.id}/favourited_by") + |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) + + conn + |> assign(:token, nil) + |> get(favourited_by_url) + |> json_response(404) + + response = + conn + |> get(favourited_by_url) |> json_response(200) [%{"id" => id}] = response @@ -1166,15 +1121,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end describe "GET /api/v1/statuses/:id/reblogged_by" do - setup do - user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) + setup do: oauth_access(["read:accounts"]) - conn = - build_conn() - |> assign(:user, user) + setup %{user: user} do + {:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) - [conn: conn, activity: activity, user: user] + %{activity: activity} end test "returns users who have reblogged the status", %{conn: conn, activity: activity} do @@ -1208,13 +1160,12 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do activity: activity } do other_user = insert(:user) - {:ok, user} = User.block(user, other_user) + {:ok, _user_relationship} = User.block(user, other_user) {:ok, _, _} = CommonAPI.repeat(activity.id, other_user) response = conn - |> assign(:user, user) |> get("/api/v1/statuses/#{activity.id}/reblogged_by") |> json_response(:ok) @@ -1222,7 +1173,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "does not return users who have reblogged the status privately", %{ - conn: %{assigns: %{user: user}} = conn, + conn: conn, activity: activity } do other_user = insert(:user) @@ -1231,20 +1182,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = conn - |> assign(:user, user) |> get("/api/v1/statuses/#{activity.id}/reblogged_by") |> json_response(:ok) assert Enum.empty?(response) end - test "does not fail on an unauthenticated request", %{conn: conn, activity: activity} do + test "does not fail on an unauthenticated request", %{activity: activity} do other_user = insert(:user) {:ok, _, _} = CommonAPI.repeat(activity.id, other_user) response = - conn - |> assign(:user, nil) + build_conn() |> get("/api/v1/statuses/#{activity.id}/reblogged_by") |> json_response(:ok) @@ -1252,7 +1201,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert id == other_user.id end - test "requires authentification for private posts", %{conn: conn, user: user} do + test "requires authentication for private posts", %{user: user} do other_user = insert(:user) {:ok, activity} = @@ -1261,14 +1210,14 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do "visibility" => "direct" }) - conn - |> assign(:user, nil) + build_conn() |> get("/api/v1/statuses/#{activity.id}/reblogged_by") |> json_response(404) response = build_conn() |> assign(:user, other_user) + |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/statuses/#{activity.id}/reblogged_by") |> json_response(200) @@ -1287,7 +1236,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do response = build_conn() - |> assign(:user, nil) |> get("/api/v1/statuses/#{id3}/context") |> json_response(:ok) @@ -1297,8 +1245,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do } = response end - test "returns the favorites of a user", %{conn: conn} do - user = insert(:user) + 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"}) @@ -1306,10 +1254,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do {:ok, _} = CommonAPI.favorite(user, activity.id) - first_conn = - conn - |> assign(:user, user) - |> get("/api/v1/favourites") + first_conn = get(conn, "/api/v1/favourites") assert [status] = json_response(first_conn, 200) assert status["id"] == to_string(activity.id) @@ -1328,19 +1273,32 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do last_like = status["id"] - second_conn = - conn - |> assign(:user, user) - |> get("/api/v1/favourites?since_id=#{last_like}") + second_conn = get(conn, "/api/v1/favourites?since_id=#{last_like}") assert [second_status] = json_response(second_conn, 200) assert second_status["id"] == to_string(second_activity.id) - third_conn = - conn - |> assign(:user, user) - |> get("/api/v1/favourites?limit=0") + third_conn = get(conn, "/api/v1/favourites?limit=0") assert [] = json_response(third_conn, 200) end + + test "expires_at is nil for another user" do + %{conn: conn, user: user} = oauth_access(["read:statuses"]) + {:ok, activity} = CommonAPI.post(user, %{"status" => "foobar", "expires_in" => 1_000_000}) + + expires_at = + activity.id + |> ActivityExpiration.get_by_activity_id() + |> Map.get(:scheduled_at) + |> NaiveDateTime.to_iso8601() + + assert %{"pleroma" => %{"expires_at" => ^expires_at}} = + conn |> get("/api/v1/statuses/#{activity.id}") |> json_response(:ok) + + %{conn: conn} = oauth_access(["read:statuses"]) + + assert %{"pleroma" => %{"expires_at" => nil}} = + conn |> get("/api/v1/statuses/#{activity.id}") |> json_response(:ok) + end end diff --git a/test/web/mastodon_api/controllers/subscription_controller_test.exs b/test/web/mastodon_api/controllers/subscription_controller_test.exs index 7dfb02f63..987158a74 100644 --- a/test/web/mastodon_api/controllers/subscription_controller_test.exs +++ b/test/web/mastodon_api/controllers/subscription_controller_test.exs @@ -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.MastodonAPI.SubscriptionControllerTest do diff --git a/test/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/web/mastodon_api/controllers/suggestion_controller_test.exs index 78620a873..c697a39f8 100644 --- a/test/web/mastodon_api/controllers/suggestion_controller_test.exs +++ b/test/web/mastodon_api/controllers/suggestion_controller_test.exs @@ -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.MastodonAPI.SuggestionControllerTest do @@ -7,12 +7,12 @@ defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do alias Pleroma.Config - import ExUnit.CaptureLog import Pleroma.Factory import Tesla.Mock - setup do - user = insert(:user) + setup do: oauth_access(["read"]) + + setup %{user: user} do other_user = insert(:user) host = Config.get([Pleroma.Web.Endpoint, :url, :host]) url500 = "http://test500?#{host}&#{user.nickname}" @@ -32,61 +32,15 @@ defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do } end) - [user: user, other_user: other_user] + [other_user: other_user] end - clear_config(:suggestions) - - test "returns empty result when suggestions disabled", %{conn: conn, user: user} do - Config.put([:suggestions, :enabled], false) - + test "returns empty result", %{conn: conn} do res = conn - |> assign(:user, user) |> get("/api/v1/suggestions") |> json_response(200) assert res == [] end - - test "returns error", %{conn: conn, user: user} do - Config.put([:suggestions, :enabled], true) - Config.put([:suggestions, :third_party_engine], "http://test500?{{host}}&{{user}}") - - assert capture_log(fn -> - res = - conn - |> assign(:user, user) - |> get("/api/v1/suggestions") - |> json_response(500) - - assert res == "Something went wrong" - end) =~ "Could not retrieve suggestions" - end - - test "returns suggestions", %{conn: conn, user: user, other_user: other_user} do - Config.put([:suggestions, :enabled], true) - Config.put([:suggestions, :third_party_engine], "http://test200?{{host}}&{{user}}") - - res = - conn - |> assign(:user, user) - |> get("/api/v1/suggestions") - |> json_response(200) - - assert res == [ - %{ - "acct" => "yj455", - "avatar" => "https://social.heldscal.la/avatar/201.jpeg", - "avatar_static" => "https://social.heldscal.la/avatar/s/201.jpeg", - "id" => 0 - }, - %{ - "acct" => other_user.ap_id, - "avatar" => "https://social.heldscal.la/avatar/202.jpeg", - "avatar_static" => "https://social.heldscal.la/avatar/s/202.jpeg", - "id" => other_user.id - } - ] - end end diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs index 61b6cea75..2c03b0a75 100644 --- a/test/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -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.MastodonAPI.TimelineControllerTest do @@ -20,31 +20,25 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do end describe "home" do - test "the home timeline", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["read:statuses"]) + + test "the home timeline", %{user: user, conn: conn} do following = insert(:user) {:ok, _activity} = CommonAPI.post(following, %{"status" => "test"}) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/timelines/home") + ret_conn = get(conn, "/api/v1/timelines/home") - assert Enum.empty?(json_response(conn, :ok)) + assert Enum.empty?(json_response(ret_conn, :ok)) - {:ok, user} = User.follow(user, following) + {:ok, _user} = User.follow(user, following) - conn = - build_conn() - |> assign(:user, user) - |> get("/api/v1/timelines/home") + conn = get(conn, "/api/v1/timelines/home") assert [%{"content" => "test"}] = json_response(conn, :ok) end - test "the home timeline when the direct messages are excluded", %{conn: conn} do - user = insert(:user) + 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"}) @@ -54,10 +48,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do {:ok, private_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "private"}) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/timelines/home", %{"exclude_visibilities" => ["direct"]}) + conn = get(conn, "/api/v1/timelines/home", %{"exclude_visibilities" => ["direct"]}) assert status_ids = json_response(conn, :ok) |> Enum.map(& &1["id"]) assert public_activity.id in status_ids @@ -99,11 +90,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do end test "the public timeline includes only public statuses for an authenticated user" do - user = insert(:user) - - conn = - build_conn() - |> assign(:user, user) + %{user: user, conn: conn} = oauth_access(["read:statuses"]) {:ok, _activity} = CommonAPI.post(user, %{"status" => "test"}) {:ok, _activity} = CommonAPI.post(user, %{"status" => "test", "visibility" => "private"}) @@ -134,11 +121,13 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do "visibility" => "private" }) - # Only direct should be visible here - res_conn = + conn_user_two = conn |> assign(:user, user_two) - |> get("api/v1/timelines/direct") + |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"])) + + # Only direct should be visible here + res_conn = get(conn_user_two, "api/v1/timelines/direct") [status] = json_response(res_conn, :ok) @@ -149,6 +138,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do res_conn = build_conn() |> assign(:user, user_one) + |> assign(:token, insert(:oauth_token, user: user_one, scopes: ["read:statuses"])) |> get("api/v1/timelines/direct") [status] = json_response(res_conn, :ok) @@ -156,10 +146,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do assert %{"visibility" => "direct"} = status # Both should be visible here - res_conn = - conn - |> assign(:user, user_two) - |> get("api/v1/timelines/home") + res_conn = get(conn_user_two, "api/v1/timelines/home") [_s1, _s2] = json_response(res_conn, :ok) @@ -172,29 +159,24 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do }) end) - res_conn = - conn - |> assign(:user, user_two) - |> get("api/v1/timelines/direct") + res_conn = get(conn_user_two, "api/v1/timelines/direct") statuses = json_response(res_conn, :ok) assert length(statuses) == 20 res_conn = - conn - |> assign(:user, user_two) - |> get("api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]}) + get(conn_user_two, "api/v1/timelines/direct", %{max_id: List.last(statuses)["id"]}) [status] = json_response(res_conn, :ok) assert status["url"] != direct.data["id"] end - test "doesn't include DMs from blocked users", %{conn: conn} do - blocker = insert(:user) + test "doesn't include DMs from blocked users" do + %{user: blocker, conn: conn} = oauth_access(["read:statuses"]) blocked = insert(:user) - user = insert(:user) - {:ok, blocker} = User.block(blocker, blocked) + other_user = insert(:user) + {:ok, _user_relationship} = User.block(blocker, blocked) {:ok, _blocked_direct} = CommonAPI.post(blocked, %{ @@ -203,15 +185,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do }) {:ok, direct} = - CommonAPI.post(user, %{ + CommonAPI.post(other_user, %{ "status" => "Hi @#{blocker.nickname}!", "visibility" => "direct" }) - res_conn = - conn - |> assign(:user, user) - |> get("api/v1/timelines/direct") + res_conn = get(conn, "api/v1/timelines/direct") [status] = json_response(res_conn, :ok) assert status["id"] == direct.id @@ -219,26 +198,26 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do end describe "list" do - test "list timeline", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["read:lists"]) + + test "list timeline", %{user: user, conn: conn} do other_user = insert(:user) {:ok, _activity_one} = CommonAPI.post(user, %{"status" => "Marisa is cute."}) {:ok, activity_two} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."}) {:ok, list} = Pleroma.List.create("name", user) {:ok, list} = Pleroma.List.follow(list, other_user) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/timelines/list/#{list.id}") + conn = get(conn, "/api/v1/timelines/list/#{list.id}") assert [%{"id" => id}] = json_response(conn, :ok) assert id == to_string(activity_two.id) end - test "list timeline does not leak non-public statuses for unfollowed users", %{conn: conn} do - user = insert(:user) + test "list timeline does not leak non-public statuses for unfollowed users", %{ + user: user, + conn: conn + } do other_user = insert(:user) {:ok, activity_one} = CommonAPI.post(other_user, %{"status" => "Marisa is cute."}) @@ -251,10 +230,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do {:ok, list} = Pleroma.List.create("name", user) {:ok, list} = Pleroma.List.follow(list, other_user) - conn = - conn - |> assign(:user, user) - |> get("/api/v1/timelines/list/#{list.id}") + conn = get(conn, "/api/v1/timelines/list/#{list.id}") assert [%{"id" => id}] = json_response(conn, :ok) @@ -263,6 +239,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do end describe "hashtag" do + setup do: oauth_access(["n/a"]) + @tag capture_log: true test "hashtag timeline", %{conn: conn} do following = insert(:user) diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 42a8779c0..75f184242 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -1,73 +1,13 @@ # 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.MastodonAPI.MastodonAPIControllerTest do use Pleroma.Web.ConnCase - alias Pleroma.Notification - alias Pleroma.Repo - alias Pleroma.Web.CommonAPI - - import Pleroma.Factory - import Tesla.Mock - - setup do - mock(fn env -> apply(HttpRequestMock, :request, [env]) end) - :ok - end - - clear_config([:rich_media, :enabled]) - - test "unimplemented follow_requests, blocks, domain blocks" do - user = insert(:user) - - ["blocks", "domain_blocks", "follow_requests"] - |> Enum.each(fn endpoint -> - conn = - build_conn() - |> assign(:user, user) - |> get("/api/v1/#{endpoint}") - - assert [] = json_response(conn, 200) - end) - end - - describe "link headers" do - test "preserves parameters in link headers", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - - {:ok, activity1} = - CommonAPI.post(other_user, %{ - "status" => "hi @#{user.nickname}", - "visibility" => "public" - }) - - {:ok, activity2} = - CommonAPI.post(other_user, %{ - "status" => "hi @#{user.nickname}", - "visibility" => "public" - }) - - notification1 = Repo.get_by(Notification, activity_id: activity1.id) - notification2 = Repo.get_by(Notification, activity_id: activity2.id) - - conn = - conn - |> assign(:user, user) - |> get("/api/v1/notifications", %{media_only: true}) - - assert [link_header] = get_resp_header(conn, "link") - assert link_header =~ ~r/media_only=true/ - assert link_header =~ ~r/min_id=#{notification2.id}/ - assert link_header =~ ~r/max_id=#{notification1.id}/ - end - end - - describe "empty_array, stubs for mastodon api" do - test "GET /api/v1/accounts/:id/identity_proofs", %{conn: conn} do - user = insert(:user) + describe "empty_array/2 (stubs)" do + test "GET /api/v1/accounts/:id/identity_proofs" do + %{user: user, conn: conn} = oauth_access(["n/a"]) res = conn @@ -78,12 +18,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do assert res == [] end - test "GET /api/v1/endorsements", %{conn: conn} do - user = insert(:user) + test "GET /api/v1/endorsements" do + %{conn: conn} = oauth_access(["read:accounts"]) res = conn - |> assign(:user, user) |> get("/api/v1/endorsements") |> json_response(200) @@ -91,11 +30,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do end test "GET /api/v1/trends", %{conn: conn} do - user = insert(:user) - res = conn - |> assign(:user, user) |> get("/api/v1/trends") |> json_response(200) diff --git a/test/web/mastodon_api/mastodon_api_test.exs b/test/web/mastodon_api/mastodon_api_test.exs index 561ef05aa..cb971806a 100644 --- a/test/web/mastodon_api/mastodon_api_test.exs +++ b/test/web/mastodon_api/mastodon_api_test.exs @@ -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.MastodonAPI.MastodonAPITest do diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index 35aefb7dc..d60ed7b64 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -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.MastodonAPI.AccountViewTest do @@ -66,6 +66,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do note: "valid html", sensitive: false, pleroma: %{ + actor_type: "Person", discoverable: false }, fields: [] @@ -92,13 +93,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do test "Represent the user account for the account owner" do user = insert(:user) - notification_settings = %{ - "followers" => true, - "follows" => true, - "non_follows" => true, - "non_followers" => true - } - + notification_settings = %Pleroma.User.NotificationSetting{} privacy = user.default_scope assert %{ @@ -112,7 +107,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 3, note_count: 5, - source_data: %{"type" => "Service"}, + source_data: %{}, + actor_type: "Service", nickname: "shp@shitposter.club", inserted_at: ~N[2017-08-15 15:47:06.597036] }) @@ -140,6 +136,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do note: user.bio, sensitive: false, pleroma: %{ + actor_type: "Service", discoverable: false }, fields: [] @@ -190,9 +187,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do {:ok, user} = User.follow(user, other_user) {:ok, other_user} = User.follow(other_user, user) - {:ok, other_user} = User.subscribe(user, other_user) - {:ok, user} = User.mute(user, other_user, true) - {:ok, user} = CommonAPI.hide_reblogs(user, other_user) + {:ok, _subscription} = User.subscribe(user, other_user) + {:ok, _user_relationships} = User.mute(user, other_user, true) + {:ok, _reblog_mute} = CommonAPI.hide_reblogs(user, other_user) expected = %{ id: to_string(other_user.id), @@ -218,9 +215,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do other_user = insert(:user) {:ok, user} = User.follow(user, other_user) - {:ok, other_user} = User.subscribe(user, other_user) - {:ok, user} = User.block(user, other_user) - {:ok, other_user} = User.block(other_user, user) + {:ok, _subscription} = User.subscribe(user, other_user) + {:ok, _user_relationship} = User.block(user, other_user) + {:ok, _user_relationship} = User.block(other_user, user) expected = %{ id: to_string(other_user.id), @@ -284,14 +281,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 0, note_count: 5, - source_data: %{"type" => "Service"}, + source_data: %{}, + 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, other_user} = User.block(other_user, user) + {:ok, _user_relationship} = User.block(other_user, user) {:ok, _} = User.follow(insert(:user), user) expected = %{ @@ -317,6 +315,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do note: user.bio, sensitive: false, pleroma: %{ + actor_type: "Service", discoverable: false }, fields: [] @@ -369,10 +368,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do assert result.pleroma[:settings_store] == nil end - test "sanitizes display names" do + test "doesn't sanitize display names" do user = insert(:user, name: "<marquee> username </marquee>") result = AccountView.render("show.json", %{user: user}) - refute result.display_name == "<marquee> username </marquee>" + assert result.display_name == "<marquee> username </marquee>" end test "never display nil user follow counts" do diff --git a/test/web/mastodon_api/views/conversation_view_test.exs b/test/web/mastodon_api/views/conversation_view_test.exs index 6ed22597d..dbf3c51e2 100644 --- a/test/web/mastodon_api/views/conversation_view_test.exs +++ b/test/web/mastodon_api/views/conversation_view_test.exs @@ -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.MastodonAPI.ConversationViewTest do diff --git a/test/web/mastodon_api/views/list_view_test.exs b/test/web/mastodon_api/views/list_view_test.exs index 59e896a7c..ca99242cb 100644 --- a/test/web/mastodon_api/views/list_view_test.exs +++ b/test/web/mastodon_api/views/list_view_test.exs @@ -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.MastodonAPI.ListViewTest do diff --git a/test/web/mastodon_api/views/marker_view_test.exs b/test/web/mastodon_api/views/marker_view_test.exs index 8a5c89d56..893cf8857 100644 --- a/test/web/mastodon_api/views/marker_view_test.exs +++ b/test/web/mastodon_api/views/marker_view_test.exs @@ -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.MastodonAPI.MarkerViewTest do diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs index a741cc014..779126556 100644 --- a/test/web/mastodon_api/views/notification_view_test.exs +++ b/test/web/mastodon_api/views/notification_view_test.exs @@ -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.MastodonAPI.NotificationViewTest do @@ -109,8 +109,8 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do end test "Move notification" do - %{ap_id: old_ap_id} = old_user = insert(:user) - %{ap_id: _new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id]) + old_user = insert(:user) + new_user = insert(:user, also_known_as: [old_user.ap_id]) follower = insert(:user) User.follow(follower, old_user) @@ -120,7 +120,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do old_user = refresh_record(old_user) new_user = refresh_record(new_user) - [notification] = Notification.for_user(follower) + [notification] = Notification.for_user(follower, %{with_move: true}) expected = %{ id: to_string(notification.id), @@ -134,4 +134,31 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do assert [expected] == NotificationView.render("index.json", %{notifications: [notification], for: follower}) end + + test "EmojiReact notification" do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) + {:ok, _activity, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + + activity = Repo.get(Activity, activity.id) + + [notification] = Notification.for_user(user) + + assert notification + + expected = %{ + id: to_string(notification.id), + pleroma: %{is_seen: false}, + type: "pleroma:emoji_reaction", + emoji: "☕", + account: AccountView.render("show.json", %{user: other_user, for: user}), + status: StatusView.render("show.json", %{activity: activity, for: user}), + created_at: Utils.to_masto_date(notification.inserted_at) + } + + assert expected == + NotificationView.render("show.json", %{notification: notification, for: user}) + end end diff --git a/test/web/mastodon_api/views/poll_view_test.exs b/test/web/mastodon_api/views/poll_view_test.exs index 8cd7636a5..6211fa888 100644 --- a/test/web/mastodon_api/views/poll_view_test.exs +++ b/test/web/mastodon_api/views/poll_view_test.exs @@ -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.MastodonAPI.PollViewTest do diff --git a/test/web/mastodon_api/views/push_subscription_view_test.exs b/test/web/mastodon_api/views/push_subscription_view_test.exs index 4e4f5b7e6..10c6082a5 100644 --- a/test/web/mastodon_api/views/push_subscription_view_test.exs +++ b/test/web/mastodon_api/views/push_subscription_view_test.exs @@ -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.MastodonAPI.PushSubscriptionViewTest do diff --git a/test/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/web/mastodon_api/views/scheduled_activity_view_test.exs index 6387e4555..0c0987593 100644 --- a/test/web/mastodon_api/views/scheduled_activity_view_test.exs +++ b/test/web/mastodon_api/views/scheduled_activity_view_test.exs @@ -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.MastodonAPI.ScheduledActivityViewTest do diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs index d46ecc646..191895c6f 100644 --- a/test/web/mastodon_api/views/status_view_test.exs +++ b/test/web/mastodon_api/views/status_view_test.exs @@ -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.MastodonAPI.StatusViewTest do @@ -24,6 +24,31 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do :ok end + test "has an emoji reaction list" do + user = insert(:user) + other_user = insert(:user) + third_user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "dae cofe??"}) + + {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "☕") + {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵") + {:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + activity = Repo.get(Activity, activity.id) + status = StatusView.render("show.json", activity: activity) + + assert status[:pleroma][:emoji_reactions] == [ + %{name: "☕", count: 2, me: false}, + %{name: "🍵", count: 1, me: false} + ] + + status = StatusView.render("show.json", activity: activity, for: user) + + assert status[:pleroma][:emoji_reactions] == [ + %{name: "☕", count: 2, me: true}, + %{name: "🍵", count: 1, me: false} + ] + end + test "loads and returns the direct conversation id when given the `with_direct_conversation_id` option" do user = insert(:user) @@ -172,7 +197,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])}, expires_at: nil, direct_conversation_id: nil, - thread_muted: false + thread_muted: false, + emoji_reactions: [] } } @@ -183,7 +209,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do user = insert(:user) other_user = insert(:user) - {:ok, user} = User.mute(user, other_user) + {:ok, _user_relationships} = User.mute(user, other_user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) status = StatusView.render("show.json", %{activity: activity}) @@ -199,7 +225,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do user = insert(:user) other_user = insert(:user) - {:ok, user} = User.mute(user, other_user) + {:ok, _user_relationships} = User.mute(user, other_user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) status = StatusView.render("show.json", %{activity: activity, for: user}) @@ -394,6 +420,21 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do assert length(represented[:media_attachments]) == 1 end + test "a Mobilizon event" do + user = insert(:user) + + {:ok, object} = + Pleroma.Object.Fetcher.fetch_object_from_id( + "https://mobilizon.org/events/252d5816-00a3-4a89-a66f-15bf65c33e39" + ) + + %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"]) + + represented = StatusView.render("show.json", %{for: user, activity: activity}) + + assert represented[:id] == to_string(activity.id) + end + describe "build_tags/1" do test "it returns a a dictionary tags" do object_tags = [ @@ -450,7 +491,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do title: "Example website" } - %{provider_name: "Example site name"} = + %{provider_name: "example.com"} = StatusView.render("card.json", %{page_url: page_url, rich_media: card}) end @@ -465,7 +506,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do description: "Example description" } - %{provider_name: "Example site name"} = + %{provider_name: "example.com"} = StatusView.render("card.json", %{page_url: page_url, rich_media: card}) end end diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/web/media_proxy/media_proxy_controller_test.exs index fdfdb5ec6..7ac7e4af1 100644 --- a/test/web/media_proxy/media_proxy_controller_test.exs +++ b/test/web/media_proxy/media_proxy_controller_test.exs @@ -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.MediaProxy.MediaProxyControllerTest do @@ -7,11 +7,8 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do import Mock alias Pleroma.Config - setup do - media_proxy_config = Config.get([:media_proxy]) || [] - on_exit(fn -> Config.put([:media_proxy], media_proxy_config) end) - :ok - end + clear_config(:media_proxy) + clear_config([Pleroma.Web.Endpoint, :secret_key_base]) test "it returns 404 when MediaProxy disabled", %{conn: conn} do Config.put([:media_proxy, :enabled], false) @@ -55,9 +52,8 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do url = Pleroma.Web.MediaProxy.encode_url("https://google.fn/test.png") invalid_url = String.replace(url, "test.png", "test-file.png") response = get(conn, invalid_url) - html = "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>" assert response.status == 302 - assert response.resp_body == html + assert redirected_to(response) == url end test "it performs ReverseProxy.call when signature valid", %{conn: conn} do diff --git a/test/web/media_proxy/media_proxy_test.exs b/test/web/media_proxy/media_proxy_test.exs index 96bdde219..8f5fcf2eb 100644 --- a/test/web/media_proxy/media_proxy_test.exs +++ b/test/web/media_proxy/media_proxy_test.exs @@ -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.MediaProxyTest do @@ -9,6 +9,7 @@ defmodule Pleroma.Web.MediaProxyTest do alias Pleroma.Web.MediaProxy.MediaProxyController clear_config([:media_proxy, :enabled]) + clear_config(Pleroma.Upload) describe "when enabled" do setup do @@ -224,7 +225,6 @@ defmodule Pleroma.Web.MediaProxyTest do end test "ensure Pleroma.Upload base_url is always whitelisted" do - upload_config = Pleroma.Config.get([Pleroma.Upload]) media_url = "https://media.pleroma.social" Pleroma.Config.put([Pleroma.Upload, :base_url], media_url) @@ -232,8 +232,6 @@ defmodule Pleroma.Web.MediaProxyTest do encoded = url(url) assert String.starts_with?(encoded, media_url) - - Pleroma.Config.put([Pleroma.Upload], upload_config) end end end diff --git a/test/web/metadata/feed_test.exs b/test/web/metadata/feed_test.exs index 50e9ce52e..e6e5cc5ed 100644 --- a/test/web/metadata/feed_test.exs +++ b/test/web/metadata/feed_test.exs @@ -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.Metadata.Providers.FeedTest do diff --git a/test/web/metadata/opengraph_test.exs b/test/web/metadata/opengraph_test.exs index 4283f72cd..9d7c009eb 100644 --- a/test/web/metadata/opengraph_test.exs +++ b/test/web/metadata/opengraph_test.exs @@ -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.Metadata.Providers.OpenGraphTest do @@ -7,6 +7,8 @@ defmodule Pleroma.Web.Metadata.Providers.OpenGraphTest do import Pleroma.Factory alias Pleroma.Web.Metadata.Providers.OpenGraph + clear_config([Pleroma.Web.Metadata, :unfurl_nsfw]) + test "it renders all supported types of attachments and skips unknown types" do user = insert(:user) diff --git a/test/web/metadata/player_view_test.exs b/test/web/metadata/player_view_test.exs index 742b0ed8b..e6c990242 100644 --- a/test/web/metadata/player_view_test.exs +++ b/test/web/metadata/player_view_test.exs @@ -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.Metadata.PlayerViewTest do diff --git a/test/web/metadata/rel_me_test.exs b/test/web/metadata/rel_me_test.exs index 3874e077b..4107a8459 100644 --- a/test/web/metadata/rel_me_test.exs +++ b/test/web/metadata/rel_me_test.exs @@ -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.Metadata.Providers.RelMeTest do diff --git a/test/web/metadata/twitter_card_test.exs b/test/web/metadata/twitter_card_test.exs index 0814006d2..3d75d1ed5 100644 --- a/test/web/metadata/twitter_card_test.exs +++ b/test/web/metadata/twitter_card_test.exs @@ -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.Metadata.Providers.TwitterCardTest do @@ -13,6 +13,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do alias Pleroma.Web.Metadata.Utils alias Pleroma.Web.Router + clear_config([Pleroma.Web.Metadata, :unfurl_nsfw]) + test "it renders twitter card for user info" do user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994") avatar_url = Utils.attachment_url(User.avatar_url(user)) @@ -26,7 +28,32 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do ] end - test "it does not render attachments if post is nsfw" do + test "it uses summary twittercard if post has no attachment" do + user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994") + {:ok, activity} = CommonAPI.post(user, %{"status" => "HI"}) + + note = + insert(:note, %{ + data: %{ + "actor" => user.ap_id, + "tag" => [], + "id" => "https://pleroma.gov/objects/whatever", + "content" => "pleroma in a nutshell" + } + }) + + result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id}) + + assert [ + {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []}, + {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"], + []}, + {:meta, [property: "twitter:card", content: "summary"], []} + ] == result + end + + test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabled" do Pleroma.Config.put([Pleroma.Web.Metadata, :unfurl_nsfw], false) user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994") {:ok, activity} = CommonAPI.post(user, %{"status" => "HI"}) @@ -67,7 +94,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do {:meta, [property: "twitter:description", content: "“pleroma in a nutshell”"], []}, {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"], []}, - {:meta, [property: "twitter:card", content: "summary_large_image"], []} + {:meta, [property: "twitter:card", content: "summary"], []} ] == result end diff --git a/test/web/metadata/utils_test.exs b/test/web/metadata/utils_test.exs new file mode 100644 index 000000000..8183256d8 --- /dev/null +++ b/test/web/metadata/utils_test.exs @@ -0,0 +1,32 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Metadata.UtilsTest do + use Pleroma.DataCase + import Pleroma.Factory + alias Pleroma.Web.Metadata.Utils + + describe "scrub_html_and_truncate/1" do + test "it returns text without encode HTML" do + user = insert(:user) + + note = + insert(:note, %{ + data: %{ + "actor" => user.ap_id, + "id" => "https://pleroma.gov/objects/whatever", + "content" => "Pleroma's really cool!" + } + }) + + assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!" + end + end + + describe "scrub_html_and_truncate/2" do + test "it returns text without encode HTML" do + assert Utils.scrub_html_and_truncate("Pleroma's really cool!") == "Pleroma's really cool!" + end + end +end diff --git a/test/web/mongooseim/mongoose_im_controller_test.exs b/test/web/mongooseim/mongoose_im_controller_test.exs index eb83999bb..291ae54fc 100644 --- a/test/web/mongooseim/mongoose_im_controller_test.exs +++ b/test/web/mongooseim/mongoose_im_controller_test.exs @@ -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.MongooseIMController do diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs index 9a574a38d..ee10ad5db 100644 --- a/test/web/node_info_test.exs +++ b/test/web/node_info_test.exs @@ -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.NodeInfoTest do @@ -7,6 +7,9 @@ defmodule Pleroma.Web.NodeInfoTest do import Pleroma.Factory + clear_config([:mrf_simple]) + clear_config(:instance) + test "GET /.well-known/nodeinfo", %{conn: conn} do links = conn @@ -62,11 +65,6 @@ defmodule Pleroma.Web.NodeInfoTest do end test "returns fieldsLimits field", %{conn: conn} do - max_account_fields = Pleroma.Config.get([:instance, :max_account_fields]) - max_remote_account_fields = Pleroma.Config.get([:instance, :max_remote_account_fields]) - account_field_name_length = Pleroma.Config.get([:instance, :account_field_name_length]) - account_field_value_length = Pleroma.Config.get([:instance, :account_field_value_length]) - Pleroma.Config.put([:instance, :max_account_fields], 10) Pleroma.Config.put([:instance, :max_remote_account_fields], 15) Pleroma.Config.put([:instance, :account_field_name_length], 255) @@ -81,11 +79,6 @@ defmodule Pleroma.Web.NodeInfoTest do assert response["metadata"]["fieldsLimits"]["maxRemoteFields"] == 15 assert response["metadata"]["fieldsLimits"]["nameLength"] == 255 assert response["metadata"]["fieldsLimits"]["valueLength"] == 2048 - - Pleroma.Config.put([:instance, :max_account_fields], max_account_fields) - Pleroma.Config.put([:instance, :max_remote_account_fields], max_remote_account_fields) - Pleroma.Config.put([:instance, :account_field_name_length], account_field_name_length) - Pleroma.Config.put([:instance, :account_field_value_length], account_field_value_length) end test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do @@ -111,28 +104,28 @@ defmodule Pleroma.Web.NodeInfoTest do Pleroma.Config.put([:instance, :safe_dm_mentions], option) end - test "it shows if federation is enabled/disabled", %{conn: conn} do - original = Pleroma.Config.get([:instance, :federating]) + describe "`metadata/federation/enabled`" do + clear_config([:instance, :federating]) - Pleroma.Config.put([:instance, :federating], true) - - response = - conn - |> get("/nodeinfo/2.1.json") - |> json_response(:ok) + test "it shows if federation is enabled/disabled", %{conn: conn} do + Pleroma.Config.put([:instance, :federating], true) - assert response["metadata"]["federation"]["enabled"] == true + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) - Pleroma.Config.put([:instance, :federating], false) + assert response["metadata"]["federation"]["enabled"] == true - response = - conn - |> get("/nodeinfo/2.1.json") - |> json_response(:ok) + Pleroma.Config.put([:instance, :federating], false) - assert response["metadata"]["federation"]["enabled"] == false + response = + conn + |> get("/nodeinfo/2.1.json") + |> json_response(:ok) - Pleroma.Config.put([:instance, :federating], original) + assert response["metadata"]["federation"]["enabled"] == false + end end test "it shows MRF transparency data if enabled", %{conn: conn} do diff --git a/test/web/oauth/app_test.exs b/test/web/oauth/app_test.exs index 195b8c17f..899af648e 100644 --- a/test/web/oauth/app_test.exs +++ b/test/web/oauth/app_test.exs @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.OAuth.AppTest do diff --git a/test/web/oauth/authorization_test.exs b/test/web/oauth/authorization_test.exs index 2e82a7b79..d74b26cf8 100644 --- a/test/web/oauth/authorization_test.exs +++ b/test/web/oauth/authorization_test.exs @@ -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.OAuth.AuthorizationTest do diff --git a/test/web/oauth/ldap_authorization_test.exs b/test/web/oauth/ldap_authorization_test.exs index 1cbe133b7..c55b0ffc5 100644 --- a/test/web/oauth/ldap_authorization_test.exs +++ b/test/web/oauth/ldap_authorization_test.exs @@ -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.OAuth.LDAPAuthorizationTest do diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs index beb995cd8..cff469c28 100644 --- a/test/web/oauth/oauth_controller_test.exs +++ b/test/web/oauth/oauth_controller_test.exs @@ -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.OAuth.OAuthControllerTest do @@ -17,7 +17,8 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do key: "_test", signing_salt: "cooldude" ] - clear_config_all([:instance, :account_activation_required]) + + clear_config([:instance, :account_activation_required]) describe "in OAuth consumer mode, " do setup do @@ -450,7 +451,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do test "renders authentication page if user is already authenticated but `force_login` is tru-ish", %{app: app, conn: conn} do - token = insert(:oauth_token, app_id: app.id) + token = insert(:oauth_token, app: app) conn = conn @@ -474,7 +475,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do app: app, conn: conn } do - token = insert(:oauth_token, app_id: app.id) + token = insert(:oauth_token, app: app) conn = conn @@ -497,7 +498,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do app: app, conn: conn } do - token = insert(:oauth_token, app_id: app.id) + token = insert(:oauth_token, app: app) conn = conn @@ -523,7 +524,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do conn: conn } do unlisted_redirect_uri = "http://cross-site-request.com" - token = insert(:oauth_token, app_id: app.id) + token = insert(:oauth_token, app: app) conn = conn @@ -547,7 +548,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do app: app, conn: conn } do - token = insert(:oauth_token, app_id: app.id) + token = insert(:oauth_token, app: app) conn = conn @@ -567,33 +568,46 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do end describe "POST /oauth/authorize" do - test "redirects with oauth authorization" do - user = insert(:user) - app = insert(:oauth_app, scopes: ["read", "write", "follow"]) + test "redirects with oauth authorization, " <> + "granting requested app-supported scopes to both admin- and non-admin users" do + app_scopes = ["read", "write", "admin", "secret_scope"] + app = insert(:oauth_app, scopes: app_scopes) redirect_uri = OAuthController.default_redirect_uri(app) - conn = - build_conn() - |> post("/oauth/authorize", %{ - "authorization" => %{ - "name" => user.nickname, - "password" => "test", - "client_id" => app.client_id, - "redirect_uri" => redirect_uri, - "scope" => "read:subscope write", - "state" => "statepassed" - } - }) + non_admin = insert(:user, is_admin: false) + admin = insert(:user, is_admin: true) + scopes_subset = ["read:subscope", "write", "admin"] - target = redirected_to(conn) - assert target =~ redirect_uri + # In case scope param is missing, expecting _all_ app-supported scopes to be granted + for user <- [non_admin, admin], + {requested_scopes, expected_scopes} <- + %{scopes_subset => scopes_subset, nil => app_scopes} do + conn = + post( + build_conn(), + "/oauth/authorize", + %{ + "authorization" => %{ + "name" => user.nickname, + "password" => "test", + "client_id" => app.client_id, + "redirect_uri" => redirect_uri, + "scope" => requested_scopes, + "state" => "statepassed" + } + } + ) + + target = redirected_to(conn) + assert target =~ redirect_uri - query = URI.parse(target).query |> URI.query_decoder() |> Map.new() + query = URI.parse(target).query |> URI.query_decoder() |> Map.new() - assert %{"state" => "statepassed", "code" => code} = query - auth = Repo.get_by(Authorization, token: code) - assert auth - assert auth.scopes == ["read:subscope", "write"] + assert %{"state" => "statepassed", "code" => code} = query + auth = Repo.get_by(Authorization, token: code) + assert auth + assert auth.scopes == expected_scopes + end end test "returns 401 for wrong credentials", %{conn: conn} do @@ -623,13 +637,13 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do assert result =~ "Invalid Username/Password" end - test "returns 401 for missing scopes", %{conn: conn} do - user = insert(:user) - app = insert(:oauth_app) + test "returns 401 for missing scopes" do + user = insert(:user, is_admin: false) + app = insert(:oauth_app, scopes: ["read", "write", "admin"]) redirect_uri = OAuthController.default_redirect_uri(app) result = - conn + build_conn() |> post("/oauth/authorize", %{ "authorization" => %{ "name" => user.nickname, @@ -806,7 +820,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do |> User.confirmation_changeset(need_confirmation: true) |> User.update_and_set_cache() - refute Pleroma.User.auth_active?(user) + refute Pleroma.User.account_status(user) == :active app = insert(:oauth_app) @@ -836,7 +850,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do app = insert(:oauth_app) - conn = + resp = build_conn() |> post("/oauth/token", %{ "grant_type" => "password", @@ -845,10 +859,12 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do "client_id" => app.client_id, "client_secret" => app.client_secret }) + |> json_response(403) - assert resp = json_response(conn, 403) - assert %{"error" => _} = resp - refute Map.has_key?(resp, "access_token") + assert resp == %{ + "error" => "Your account is currently disabled", + "identifier" => "account_is_disabled" + } end test "rejects token exchange for user with password_reset_pending set to true" do @@ -862,7 +878,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do app = insert(:oauth_app, scopes: ["read", "write"]) - conn = + resp = build_conn() |> post("/oauth/token", %{ "grant_type" => "password", @@ -871,12 +887,41 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do "client_id" => app.client_id, "client_secret" => app.client_secret }) + |> json_response(403) - assert resp = json_response(conn, 403) + assert resp == %{ + "error" => "Password reset is required", + "identifier" => "password_reset_required" + } + end - assert resp["error"] == "Password reset is required" - assert resp["identifier"] == "password_reset_required" - refute Map.has_key?(resp, "access_token") + test "rejects token exchange for user with confirmation_pending set to true" do + Pleroma.Config.put([:instance, :account_activation_required], true) + password = "testpassword" + + user = + insert(:user, + password_hash: Comeonin.Pbkdf2.hashpwsalt(password), + confirmation_pending: true + ) + + app = insert(:oauth_app, scopes: ["read", "write"]) + + resp = + build_conn() + |> post("/oauth/token", %{ + "grant_type" => "password", + "username" => user.nickname, + "password" => password, + "client_id" => app.client_id, + "client_secret" => app.client_secret + }) + |> json_response(403) + + assert resp == %{ + "error" => "Your login is missing a confirmed e-mail address", + "identifier" => "missing_confirmed_email" + } end test "rejects an invalid authorization code" do diff --git a/test/web/oauth/token/utils_test.exs b/test/web/oauth/token/utils_test.exs index dc1f9a986..a610d92f8 100644 --- a/test/web/oauth/token/utils_test.exs +++ b/test/web/oauth/token/utils_test.exs @@ -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.OAuth.Token.UtilsTest do diff --git a/test/web/oauth/token_test.exs b/test/web/oauth/token_test.exs index 5359940f8..40d71eb59 100644 --- a/test/web/oauth/token_test.exs +++ b/test/web/oauth/token_test.exs @@ -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.OAuth.TokenTest do diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs index 567aabbf1..ae99e37fe 100644 --- a/test/web/ostatus/ostatus_controller_test.exs +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -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.OStatus.OStatusControllerTest do @@ -7,6 +7,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do import Pleroma.Factory + alias Pleroma.Config alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.CommonAPI @@ -16,22 +17,24 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do :ok end - clear_config_all([:instance, :federating]) do - Pleroma.Config.put([:instance, :federating], true) + clear_config([:instance, :federating]) do + Config.put([:instance, :federating], true) end - describe "GET object/2" do + # Note: see ActivityPubControllerTest for JSON format tests + describe "GET /objects/:uuid (text/html)" do + setup %{conn: conn} do + conn = put_req_header(conn, "accept", "text/html") + %{conn: conn} + end + test "redirects to /notice/id for html format", %{conn: conn} do note_activity = insert(:note_activity) object = Object.normalize(note_activity) [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"])) url = "/objects/#{uuid}" - conn = - conn - |> put_req_header("accept", "text/html") - |> get(url) - + conn = get(conn, url) assert redirected_to(conn) == "/notice/#{note_activity.id}" end @@ -45,23 +48,25 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> response(404) end - test "404s on nonexisting objects", %{conn: conn} do + test "404s on non-existing objects", %{conn: conn} do conn |> get("/objects/123") |> response(404) end end - describe "GET activity/2" do + # Note: see ActivityPubControllerTest for JSON format tests + describe "GET /activities/:uuid (text/html)" do + setup %{conn: conn} do + conn = put_req_header(conn, "accept", "text/html") + %{conn: conn} + end + test "redirects to /notice/id for html format", %{conn: conn} do note_activity = insert(:note_activity) [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/activities/#{uuid}") - + conn = get(conn, "/activities/#{uuid}") assert redirected_to(conn) == "/notice/#{note_activity.id}" end @@ -79,19 +84,6 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> get("/activities/123") |> response(404) end - - test "gets an activity in AS2 format", %{conn: conn} do - note_activity = insert(:note_activity) - [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["id"])) - url = "/activities/#{uuid}" - - conn = - conn - |> put_req_header("accept", "application/activity+json") - |> get(url) - - assert json_response(conn, 200) - end end describe "GET notice/2" do @@ -170,7 +162,7 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do assert response(conn, 404) end - test "404s a nonexisting notice", %{conn: conn} do + test "404s a non-existing notice", %{conn: conn} do url = "/notice/123" conn = @@ -179,10 +171,21 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do assert response(conn, 404) end + + test "it requires authentication if instance is NOT federating", %{ + conn: conn + } do + user = insert(:user) + note_activity = insert(:note_activity) + + conn = put_req_header(conn, "accept", "text/html") + + ensure_federating_or_authenticated(conn, "/notice/#{note_activity.id}", user) + end end describe "GET /notice/:id/embed_player" do - test "render embed player", %{conn: conn} do + setup do note_activity = insert(:note_activity) object = Pleroma.Object.normalize(note_activity) @@ -204,9 +207,11 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> Ecto.Changeset.change(data: object_data) |> Pleroma.Repo.update() - conn = - conn - |> get("/notice/#{note_activity.id}/embed_player") + %{note_activity: note_activity} + end + + test "renders embed player", %{conn: conn, note_activity: note_activity} do + conn = get(conn, "/notice/#{note_activity.id}/embed_player") assert Plug.Conn.get_resp_header(conn, "x-frame-options") == ["ALLOW"] @@ -272,9 +277,19 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do |> Ecto.Changeset.change(data: object_data) |> Pleroma.Repo.update() - assert conn - |> get("/notice/#{note_activity.id}/embed_player") - |> response(404) + conn + |> get("/notice/#{note_activity.id}/embed_player") + |> response(404) + end + + test "it requires authentication if instance is NOT federating", %{ + conn: conn, + note_activity: note_activity + } do + user = insert(:user) + conn = put_req_header(conn, "accept", "text/html") + + ensure_federating_or_authenticated(conn, "/notice/#{note_activity.id}/embed_player", user) end end end diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs index c9f67c280..3853a9bbb 100644 --- a/test/web/pleroma_api/controllers/account_controller_test.exs +++ b/test/web/pleroma_api/controllers/account_controller_test.exs @@ -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.PleromaAPI.AccountControllerTest do @@ -33,7 +33,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do test "resend account confirmation email", %{conn: conn, user: user} do conn - |> assign(:user, user) |> post("/api/v1/pleroma/accounts/confirmation_resend?email=#{user.email}") |> json_response(:no_content) @@ -52,14 +51,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do end describe "PATCH /api/v1/pleroma/accounts/update_avatar" do - test "user avatar can be set", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) + + test "user avatar can be set", %{user: user, conn: conn} do avatar_image = File.read!("test/fixtures/avatar_data_uri") - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image}) + conn = patch(conn, "/api/v1/pleroma/accounts/update_avatar", %{img: avatar_image}) user = refresh_record(user) @@ -78,13 +75,8 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do assert %{"url" => _} = json_response(conn, 200) end - test "user avatar can be reset", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/pleroma/accounts/update_avatar", %{img: ""}) + test "user avatar can be reset", %{user: user, conn: conn} do + conn = patch(conn, "/api/v1/pleroma/accounts/update_avatar", %{img: ""}) user = User.get_cached_by_id(user.id) @@ -95,13 +87,10 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do end describe "PATCH /api/v1/pleroma/accounts/update_banner" do - test "can set profile banner", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => @image}) + test "can set profile banner", %{user: user, conn: conn} do + conn = patch(conn, "/api/v1/pleroma/accounts/update_banner", %{"banner" => @image}) user = refresh_record(user) assert user.banner["type"] == "Image" @@ -109,13 +98,8 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do assert %{"url" => _} = json_response(conn, 200) end - test "can reset profile banner", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/pleroma/accounts/update_banner", %{"banner" => ""}) + test "can reset profile banner", %{user: user, conn: conn} do + conn = patch(conn, "/api/v1/pleroma/accounts/update_banner", %{"banner" => ""}) user = refresh_record(user) assert user.banner == %{} @@ -125,26 +109,18 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do end describe "PATCH /api/v1/pleroma/accounts/update_background" do - test "background image can be set", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => @image}) + test "background image can be set", %{user: user, conn: conn} do + conn = patch(conn, "/api/v1/pleroma/accounts/update_background", %{"img" => @image}) user = refresh_record(user) assert user.background["type"] == "Image" assert %{"url" => _} = json_response(conn, 200) end - test "background image can be reset", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/pleroma/accounts/update_background", %{"img" => ""}) + test "background image can be reset", %{user: user, conn: conn} do + conn = patch(conn, "/api/v1/pleroma/accounts/update_background", %{"img" => ""}) user = refresh_record(user) assert user.background == %{} @@ -155,12 +131,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do describe "getting favorites timeline of specified user" do setup do [current_user, user] = insert_pair(:user, hide_favorites: false) - [current_user: current_user, user: user] + %{user: current_user, conn: conn} = oauth_access(["read:favourites"], user: current_user) + [current_user: current_user, user: user, conn: conn] end test "returns list of statuses favorited by specified user", %{ conn: conn, - current_user: current_user, user: user } do [activity | _] = insert_pair(:note_activity) @@ -168,7 +144,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do response = conn - |> assign(:user, current_user) |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") |> json_response(:ok) @@ -178,23 +153,18 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do assert like["id"] == activity.id end - test "returns favorites for specified user_id when user is not logged in", %{ - conn: conn, + test "does not return favorites for specified user_id when user is not logged in", %{ user: user } do activity = insert(:note_activity) CommonAPI.favorite(user, activity.id) - response = - conn - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") - |> json_response(:ok) - - assert length(response) == 1 + build_conn() + |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") + |> json_response(403) end test "returns favorited DM only when user is logged in and he is one of recipients", %{ - conn: conn, current_user: current_user, user: user } do @@ -206,25 +176,24 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do CommonAPI.favorite(user, direct.id) - response = - conn - |> assign(:user, current_user) - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") - |> json_response(:ok) + for u <- [user, current_user] do + response = + build_conn() + |> assign(:user, u) + |> assign(:token, insert(:oauth_token, user: u, scopes: ["read:favourites"])) + |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") + |> json_response(:ok) - assert length(response) == 1 + assert length(response) == 1 + end - anonymous_response = - conn - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") - |> json_response(:ok) - - assert Enum.empty?(anonymous_response) + build_conn() + |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") + |> json_response(403) end test "does not return others' favorited DM when user is not one of recipients", %{ conn: conn, - current_user: current_user, user: user } do user_two = insert(:user) @@ -239,7 +208,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do response = conn - |> assign(:user, current_user) |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") |> json_response(:ok) @@ -248,7 +216,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do test "paginates favorites using since_id and max_id", %{ conn: conn, - current_user: current_user, user: user } do activities = insert_list(10, :note_activity) @@ -262,7 +229,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do response = conn - |> assign(:user, current_user) |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{ since_id: third_activity.id, max_id: seventh_activity.id @@ -276,7 +242,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do test "limits favorites using limit parameter", %{ conn: conn, - current_user: current_user, user: user } do 7 @@ -287,7 +252,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do response = conn - |> assign(:user, current_user) |> get("/api/v1/pleroma/accounts/#{user.id}/favourites", %{limit: "3"}) |> json_response(:ok) @@ -296,12 +260,10 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do test "returns empty response when user does not have any favorited statuses", %{ conn: conn, - current_user: current_user, user: user } do response = conn - |> assign(:user, current_user) |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") |> json_response(:ok) @@ -314,79 +276,61 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do assert json_response(conn, 404) == %{"error" => "Record not found"} end - test "returns 403 error when user has hidden own favorites", %{ - conn: conn, - current_user: current_user - } do + test "returns 403 error when user has hidden own favorites", %{conn: conn} do user = insert(:user, hide_favorites: true) activity = insert(:note_activity) CommonAPI.favorite(user, activity.id) - conn = - conn - |> assign(:user, current_user) - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") + conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites") assert json_response(conn, 403) == %{"error" => "Can't get favorites"} end - test "hides favorites for new users by default", %{conn: conn, current_user: current_user} do + test "hides favorites for new users by default", %{conn: conn} do user = insert(:user) activity = insert(:note_activity) CommonAPI.favorite(user, activity.id) - conn = - conn - |> assign(:user, current_user) - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") - assert user.hide_favorites + conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/favourites") + assert json_response(conn, 403) == %{"error" => "Can't get favorites"} end end describe "subscribing / unsubscribing" do - test "subscribing / unsubscribing to a user", %{conn: conn} do - user = insert(:user) + test "subscribing / unsubscribing to a user" do + %{user: user, conn: conn} = oauth_access(["follow"]) subscription_target = insert(:user) - conn = + ret_conn = conn |> assign(:user, user) |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/subscribe") - assert %{"id" => _id, "subscribing" => true} = json_response(conn, 200) + assert %{"id" => _id, "subscribing" => true} = json_response(ret_conn, 200) - conn = - build_conn() - |> assign(:user, user) - |> post("/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe") + conn = post(conn, "/api/v1/pleroma/accounts/#{subscription_target.id}/unsubscribe") assert %{"id" => _id, "subscribing" => false} = json_response(conn, 200) end end describe "subscribing" do - test "returns 404 when subscription_target not found", %{conn: conn} do - user = insert(:user) + test "returns 404 when subscription_target not found" do + %{conn: conn} = oauth_access(["write:follows"]) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/pleroma/accounts/target_id/subscribe") + conn = post(conn, "/api/v1/pleroma/accounts/target_id/subscribe") assert %{"error" => "Record not found"} = json_response(conn, 404) end end describe "unsubscribing" do - test "returns 404 when subscription_target not found", %{conn: conn} do - user = insert(:user) + test "returns 404 when subscription_target not found" do + %{conn: conn} = oauth_access(["follow"]) - conn = - conn - |> assign(:user, user) - |> post("/api/v1/pleroma/accounts/target_id/unsubscribe") + conn = post(conn, "/api/v1/pleroma/accounts/target_id/unsubscribe") assert %{"error" => "Record not found"} = json_response(conn, 404) end diff --git a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs index 3d3becefd..4b9f5cf9a 100644 --- a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs @@ -1,12 +1,11 @@ # 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.PleromaAPI.EmojiAPIControllerTest do use Pleroma.Web.ConnCase import Tesla.Mock - import Pleroma.Factory @emoji_dir_path Path.join( @@ -14,6 +13,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do "emoji" ) + clear_config([:auth, :enforce_oauth_admin_scope_usage]) do + Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false) + end + test "shared & non-shared pack information in list_packs is ok" do conn = build_conn() resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) @@ -39,9 +42,12 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do test "listing remote packs" do admin = insert(:user, is_admin: true) - conn = build_conn() |> assign(:user, admin) + %{conn: conn} = oauth_access(["admin:write"], user: admin) - resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + resp = + build_conn() + |> get(emoji_api_path(conn, :list_packs)) + |> json_response(200) mock(fn %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> @@ -123,7 +129,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do admin = insert(:user, is_admin: true) - conn = build_conn() |> assign(:user, admin) + conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, insert(:oauth_admin_token, user: admin, scopes: ["admin:write"])) assert (conn |> put_req_header("content-type", "application/json") @@ -168,8 +177,6 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do # non-shared, downloaded from the fallback URL - conn = build_conn() |> assign(:user, admin) - assert conn |> put_req_header("content-type", "application/json") |> post( @@ -205,8 +212,12 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do File.write!(pack_file, original_content) end) + admin = insert(:user, is_admin: true) + %{conn: conn} = oauth_access(["admin:write"], user: admin) + {:ok, - admin: insert(:user, is_admin: true), + admin: admin, + conn: conn, pack_file: pack_file, new_data: %{ "license" => "Test license changed", @@ -217,10 +228,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do end test "for a pack without a fallback source", ctx do - conn = build_conn() + conn = ctx[:conn] assert conn - |> assign(:user, ctx[:admin]) |> post( emoji_api_path(conn, :update_metadata, "test_pack"), %{ @@ -250,10 +260,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF" ) - conn = build_conn() + conn = ctx[:conn] assert conn - |> assign(:user, ctx[:admin]) |> post( emoji_api_path(conn, :update_metadata, "test_pack"), %{ @@ -277,10 +286,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack") - conn = build_conn() + conn = ctx[:conn] assert (conn - |> assign(:user, ctx[:admin]) |> post( emoji_api_path(conn, :update_metadata, "test_pack"), %{ @@ -304,8 +312,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do end) admin = insert(:user, is_admin: true) - - conn = build_conn() + %{conn: conn} = oauth_access(["admin:write"], user: admin) same_name = %{ "action" => "add", @@ -319,8 +326,6 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do different_name = %{same_name | "shortcode" => "blank_2"} - conn = conn |> assign(:user, admin) - assert (conn |> post(emoji_api_path(conn, :update_file, "test_pack"), same_name) |> json_response(:conflict))["error"] =~ "already exists" @@ -392,8 +397,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do end) admin = insert(:user, is_admin: true) - - conn = build_conn() |> assign(:user, admin) + %{conn: conn} = oauth_access(["admin:write"], user: admin) assert conn |> put_req_header("content-type", "application/json") @@ -432,9 +436,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do refute Map.has_key?(resp, "test_pack_for_import") admin = insert(:user, is_admin: true) + %{conn: conn} = oauth_access(["admin:write"], user: admin) assert conn - |> assign(:user, admin) |> post(emoji_api_path(conn, :import_from_fs)) |> json_response(200) == ["test_pack_for_import"] @@ -449,11 +453,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do File.write!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt", emoji_txt_content) assert conn - |> assign(:user, admin) |> post(emoji_api_path(conn, :import_from_fs)) |> json_response(200) == ["test_pack_for_import"] - resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + resp = build_conn() |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) assert resp["test_pack_for_import"]["files"] == %{ "blank" => "blank.png", diff --git a/test/web/pleroma_api/controllers/mascot_controller_test.exs b/test/web/pleroma_api/controllers/mascot_controller_test.exs index ae9539b04..617831b02 100644 --- a/test/web/pleroma_api/controllers/mascot_controller_test.exs +++ b/test/web/pleroma_api/controllers/mascot_controller_test.exs @@ -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.PleromaAPI.MascotControllerTest do @@ -7,10 +7,8 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do alias Pleroma.User - import Pleroma.Factory - - test "mascot upload", %{conn: conn} do - user = insert(:user) + test "mascot upload" do + %{conn: conn} = oauth_access(["write:accounts"]) non_image_file = %Plug.Upload{ content_type: "audio/mpeg", @@ -18,12 +16,9 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do filename: "sound.mp3" } - conn = - conn - |> assign(:user, user) - |> put("/api/v1/pleroma/mascot", %{"file" => non_image_file}) + ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => non_image_file}) - assert json_response(conn, 415) + assert json_response(ret_conn, 415) file = %Plug.Upload{ content_type: "image/jpg", @@ -31,23 +26,18 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do filename: "an_image.jpg" } - conn = - build_conn() - |> assign(:user, user) - |> put("/api/v1/pleroma/mascot", %{"file" => file}) + conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file}) assert %{"id" => _, "type" => image} = json_response(conn, 200) end - test "mascot retrieving", %{conn: conn} do - user = insert(:user) + test "mascot retrieving" do + %{user: user, conn: conn} = oauth_access(["read:accounts", "write:accounts"]) + # When user hasn't set a mascot, we should just get pleroma tan back - conn = - conn - |> assign(:user, user) - |> get("/api/v1/pleroma/mascot") + ret_conn = get(conn, "/api/v1/pleroma/mascot") - assert %{"url" => url} = json_response(conn, 200) + assert %{"url" => url} = json_response(ret_conn, 200) assert url =~ "pleroma-fox-tan-smol" # When a user sets their mascot, we should get that back @@ -57,17 +47,14 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do filename: "an_image.jpg" } - conn = - build_conn() - |> assign(:user, user) - |> put("/api/v1/pleroma/mascot", %{"file" => file}) + ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file}) - assert json_response(conn, 200) + assert json_response(ret_conn, 200) user = User.get_cached_by_id(user.id) conn = - build_conn() + conn |> assign(:user, user) |> get("/api/v1/pleroma/mascot") diff --git a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs index b1b59beed..32250f06f 100644 --- a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs @@ -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.PleromaAPI.PleromaAPIControllerTest do @@ -14,7 +14,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do import Pleroma.Factory - test "POST /api/v1/pleroma/statuses/:id/react_with_emoji", %{conn: conn} do + test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do user = insert(:user) other_user = insert(:user) @@ -23,13 +23,20 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do result = conn |> assign(:user, other_user) - |> post("/api/v1/pleroma/statuses/#{activity.id}/react_with_emoji", %{"emoji" => "☕"}) + |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"])) + |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕") + |> json_response(200) - assert %{"id" => id} = json_response(result, 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 "POST /api/v1/pleroma/statuses/:id/unreact_with_emoji", %{conn: conn} do + test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do user = insert(:user) other_user = insert(:user) @@ -39,7 +46,8 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do result = conn |> assign(:user, other_user) - |> post("/api/v1/pleroma/statuses/#{activity.id}/unreact_with_emoji", %{"emoji" => "☕"}) + |> 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 @@ -49,34 +57,75 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do assert object.data["reaction_count"] == 0 end - test "GET /api/v1/pleroma/statuses/:id/emoji_reactions_by", %{conn: conn} do + 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}/emoji_reactions_by") + |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") |> json_response(200) - assert result == %{} + 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}/emoji_reactions_by") + |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") |> json_response(200) - [represented_user] = result["🎅"] + [%{"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 "/api/v1/pleroma/conversations/:id", %{conn: conn} do + 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"}) @@ -84,16 +133,15 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do result = conn - |> assign(:user, other_user) |> 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", %{conn: conn} do + test "/api/v1/pleroma/conversations/:id/statuses" do user = insert(:user) - other_user = insert(:user) + %{user: other_user, conn: conn} = oauth_access(["read:statuses"]) third_user = insert(:user) {:ok, _activity} = @@ -113,7 +161,6 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do result = conn - |> assign(:user, other_user) |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses") |> json_response(200) @@ -124,8 +171,8 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result end - test "PATCH /api/v1/pleroma/conversations/:id", %{conn: conn} do - user = insert(:user) + 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"}) @@ -140,7 +187,6 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do result = conn - |> assign(:user, user) |> patch("/api/v1/pleroma/conversations/#{participation.id}", %{ "recipients" => [user.id, other_user.id] }) @@ -155,9 +201,9 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do assert other_user in participation.recipients end - test "POST /api/v1/pleroma/conversations/read", %{conn: conn} do + test "POST /api/v1/pleroma/conversations/read" do user = insert(:user) - other_user = insert(:user) + %{user: other_user, conn: conn} = oauth_access(["write:notifications"]) {:ok, _activity} = CommonAPI.post(user, %{"status" => "Hi @#{other_user.nickname}", "visibility" => "direct"}) @@ -172,7 +218,6 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do [%{"unread" => false}, %{"unread" => false}] = conn - |> assign(:user, other_user) |> post("/api/v1/pleroma/conversations/read", %{}) |> json_response(200) @@ -183,8 +228,9 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do end describe "POST /api/v1/pleroma/notifications/read" do - test "it marks a single notification as read", %{conn: conn} do - user1 = insert(:user) + 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}"}) @@ -193,7 +239,6 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do response = conn - |> assign(:user, user1) |> post("/api/v1/pleroma/notifications/read", %{"id" => "#{notification1.id}"}) |> json_response(:ok) @@ -202,8 +247,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do refute Repo.get(Notification, notification2.id).seen end - test "it marks multiple notifications as read", %{conn: conn} do - user1 = insert(:user) + 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}"}) @@ -213,7 +257,6 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do [response1, response2] = conn - |> assign(:user, user1) |> post("/api/v1/pleroma/notifications/read", %{"max_id" => "#{notification2.id}"}) |> json_response(:ok) @@ -225,11 +268,8 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do end test "it returns error when notification not found", %{conn: conn} do - user1 = insert(:user) - response = conn - |> assign(:user, user1) |> post("/api/v1/pleroma/notifications/read", %{"id" => "22222222222222"}) |> json_response(:bad_request) diff --git a/test/web/pleroma_api/controllers/scrobble_controller_test.exs b/test/web/pleroma_api/controllers/scrobble_controller_test.exs index 881f8012c..1b945040c 100644 --- a/test/web/pleroma_api/controllers/scrobble_controller_test.exs +++ b/test/web/pleroma_api/controllers/scrobble_controller_test.exs @@ -1,21 +1,18 @@ # 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.PleromaAPI.ScrobbleControllerTest do use Pleroma.Web.ConnCase alias Pleroma.Web.CommonAPI - import Pleroma.Factory describe "POST /api/v1/pleroma/scrobble" do - test "works correctly", %{conn: conn} do - user = insert(:user) + test "works correctly" do + %{conn: conn} = oauth_access(["write"]) conn = - conn - |> assign(:user, user) - |> post("/api/v1/pleroma/scrobble", %{ + post(conn, "/api/v1/pleroma/scrobble", %{ "title" => "lain radio episode 1", "artist" => "lain", "album" => "lain radio", @@ -27,8 +24,8 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do end describe "GET /api/v1/pleroma/accounts/:id/scrobbles" do - test "works correctly", %{conn: conn} do - user = insert(:user) + test "works correctly" do + %{user: user, conn: conn} = oauth_access(["read"]) {:ok, _activity} = CommonAPI.listen(user, %{ @@ -51,9 +48,7 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do "album" => "lain radio" }) - conn = - conn - |> get("/api/v1/pleroma/accounts/#{user.id}/scrobbles") + conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/scrobbles") result = json_response(conn, 200) diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs index 9dcab93da..13edc4359 100644 --- a/test/web/plugs/federating_plug_test.exs +++ b/test/web/plugs/federating_plug_test.exs @@ -1,10 +1,11 @@ # 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.FederatingPlugTest do use Pleroma.Web.ConnCase - clear_config_all([:instance, :federating]) + + clear_config([:instance, :federating]) test "returns and halt the conn when federating is disabled" do Pleroma.Config.put([:instance, :federating], false) diff --git a/test/web/push/impl_test.exs b/test/web/push/impl_test.exs index 37c45eda6..b90e31f94 100644 --- a/test/web/push/impl_test.exs +++ b/test/web/push/impl_test.exs @@ -1,11 +1,12 @@ # 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.Push.ImplTest do use Pleroma.DataCase alias Pleroma.Object + alias Pleroma.User alias Pleroma.Web.CommonAPI alias Pleroma.Web.Push.Impl alias Pleroma.Web.Push.Subscription @@ -97,6 +98,14 @@ defmodule Pleroma.Web.Push.ImplTest do refute Pleroma.Repo.get(Subscription, subscription.id) end + test "deletes subscription when token has been deleted" do + subscription = insert(:push_subscription) + + Pleroma.Repo.delete(subscription.token) + + refute Pleroma.Repo.get(Subscription, subscription.id) + end + test "renders title and body for create activity" do user = insert(:user, nickname: "Bob") @@ -182,4 +191,50 @@ defmodule Pleroma.Web.Push.ImplTest do assert Impl.format_title(%{activity: activity}) == "New Direct Message" end + + describe "build_content/3" do + test "returns info content for direct message with enabled privacy option" do + user = insert(:user, nickname: "Bob") + user2 = insert(:user, nickname: "Rob", notification_settings: %{privacy_option: true}) + + {:ok, activity} = + CommonAPI.post(user, %{ + "visibility" => "direct", + "status" => "<Lorem ipsum dolor sit amet." + }) + + notif = insert(:notification, user: user2, activity: activity) + + actor = User.get_cached_by_ap_id(notif.activity.data["actor"]) + object = Object.normalize(activity) + + assert Impl.build_content(notif, actor, object) == %{ + body: "@Bob", + title: "New Direct Message" + } + end + + test "returns regular content for direct message with disabled privacy option" do + user = insert(:user, nickname: "Bob") + user2 = insert(:user, nickname: "Rob", notification_settings: %{privacy_option: false}) + + {:ok, activity} = + CommonAPI.post(user, %{ + "visibility" => "direct", + "status" => + "<span>Lorem ipsum dolor sit amet</span>, consectetur :firefox: adipiscing elit. Fusce sagittis finibus turpis." + }) + + notif = insert(:notification, user: user2, activity: activity) + + actor = User.get_cached_by_ap_id(notif.activity.data["actor"]) + object = Object.normalize(activity) + + assert Impl.build_content(notif, actor, object) == %{ + body: + "@Bob: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis fini...", + title: "New Direct Message" + } + end + end end diff --git a/test/web/rel_me_test.exs b/test/web/rel_me_test.exs index 77b5d5dc6..e05a8863d 100644 --- a/test/web/rel_me_test.exs +++ b/test/web/rel_me_test.exs @@ -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.RelMeTest do diff --git a/test/web/rich_media/aws_signed_url_test.exs b/test/web/rich_media/aws_signed_url_test.exs index a3a50cbb1..b30f4400e 100644 --- a/test/web/rich_media/aws_signed_url_test.exs +++ b/test/web/rich_media/aws_signed_url_test.exs @@ -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.RichMedia.TTL.AwsSignedUrlTest do diff --git a/test/web/rich_media/helpers_test.exs b/test/web/rich_media/helpers_test.exs index 48884319d..8237802a7 100644 --- a/test/web/rich_media/helpers_test.exs +++ b/test/web/rich_media/helpers_test.exs @@ -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.RichMedia.HelpersTest do diff --git a/test/web/rich_media/parser_test.exs b/test/web/rich_media/parser_test.exs index b75bdf96f..e54a13bc8 100644 --- a/test/web/rich_media/parser_test.exs +++ b/test/web/rich_media/parser_test.exs @@ -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.RichMedia.ParserTest do diff --git a/test/web/rich_media/parsers/twitter_card_test.exs b/test/web/rich_media/parsers/twitter_card_test.exs index f8e1c9b40..87c767c15 100644 --- a/test/web/rich_media/parsers/twitter_card_test.exs +++ b/test/web/rich_media/parsers/twitter_card_test.exs @@ -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.RichMedia.Parsers.TwitterCardTest do @@ -7,11 +7,14 @@ 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("", %{}) == {:error, "No twitter card metadata found"} + assert TwitterCard.parse([{"html", [], [{"head", [], []}, {"body", [], []}]}], %{}) == + {:error, "No twitter card metadata found"} end test "parses twitter card with only name attributes" do - html = File.read!("test/fixtures/nypd-facial-recognition-children-teenagers3.html") + html = + File.read!("test/fixtures/nypd-facial-recognition-children-teenagers3.html") + |> Floki.parse_document!() assert TwitterCard.parse(html, %{}) == {:ok, @@ -26,7 +29,9 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do end test "parses twitter card with only property attributes" do - html = File.read!("test/fixtures/nypd-facial-recognition-children-teenagers2.html") + html = + File.read!("test/fixtures/nypd-facial-recognition-children-teenagers2.html") + |> Floki.parse_document!() assert TwitterCard.parse(html, %{}) == {:ok, @@ -45,7 +50,9 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do end test "parses twitter card with name & property attributes" do - html = File.read!("test/fixtures/nypd-facial-recognition-children-teenagers.html") + html = + File.read!("test/fixtures/nypd-facial-recognition-children-teenagers.html") + |> Floki.parse_document!() assert TwitterCard.parse(html, %{}) == {:ok, @@ -66,4 +73,41 @@ defmodule Pleroma.Web.RichMedia.Parsers.TwitterCardTest do "https://www.nytimes.com/2019/08/01/nyregion/nypd-facial-recognition-children-teenagers.html" }} end + + test "respect only first title tag on the page" do + image_path = + "https://assets.atlasobscura.com/media/W1siZiIsInVwbG9hZHMvYXNzZXRzLzkwYzgyMzI4LThlMDUtNGRiNS05MDg3LTUzMGUxZTM5N2RmMmVkOTM5ZDM4MGM4OTIx" <> + "YTQ5MF9EQVIgZXhodW1hdGlvbiBvZiBNYXJnYXJldCBDb3JiaW4gZ3JhdmUgMTkyNi5qcGciXSxbInAiLCJjb252ZXJ0IiwiIl0sWyJwIiwiY29udmVydCIsIi1xdWFsaXR5IDgxIC1hdXRvLW9" <> + "yaWVudCJdLFsicCIsInRodW1iIiwiNjAweD4iXV0/DAR%20exhumation%20of%20Margaret%20Corbin%20grave%201926.jpg" + + html = + 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 + }} + end + + test "takes first founded title in html head if there is html markup error" do + html = + File.read!("test/fixtures/nypd-facial-recognition-children-teenagers4.html") + |> 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" + }} + end end diff --git a/test/web/static_fe/static_fe_controller_test.exs b/test/web/static_fe/static_fe_controller_test.exs index 2ce8f9fa3..c3d2ae3b4 100644 --- a/test/web/static_fe/static_fe_controller_test.exs +++ b/test/web/static_fe/static_fe_controller_test.exs @@ -1,56 +1,46 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do use Pleroma.Web.ConnCase + alias Pleroma.Activity + alias Pleroma.Config alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.CommonAPI import Pleroma.Factory clear_config_all([:static_fe, :enabled]) do - Pleroma.Config.put([:static_fe, :enabled], true) + Config.put([:static_fe, :enabled], true) end - describe "user profile page" do - test "just the profile as HTML", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/users/#{user.nickname}") + clear_config([:instance, :federating]) do + Config.put([:instance, :federating], true) + end - assert html_response(conn, 200) =~ user.nickname - end + setup %{conn: conn} do + conn = put_req_header(conn, "accept", "text/html") + user = insert(:user) - test "renders json unless there's an html accept header", %{conn: conn} do - user = insert(:user) + %{conn: conn, user: user} + end - conn = - conn - |> put_req_header("accept", "application/json") - |> get("/users/#{user.nickname}") + describe "user profile html" do + test "just the profile as HTML", %{conn: conn, user: user} do + conn = get(conn, "/users/#{user.nickname}") - assert json_response(conn, 200) + assert html_response(conn, 200) =~ user.nickname end test "404 when user not found", %{conn: conn} do - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/users/limpopo") + conn = get(conn, "/users/limpopo") assert html_response(conn, 404) =~ "not found" end - test "profile does not include private messages", %{conn: conn} do - user = insert(:user) + test "profile does not include private messages", %{conn: conn, user: user} do CommonAPI.post(user, %{"status" => "public"}) CommonAPI.post(user, %{"status" => "private", "visibility" => "private"}) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/users/#{user.nickname}") + conn = get(conn, "/users/#{user.nickname}") html = html_response(conn, 200) @@ -58,14 +48,10 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do refute html =~ ">private<" end - test "pagination", %{conn: conn} do - user = insert(:user) + test "pagination", %{conn: conn, user: user} do Enum.map(1..30, fn i -> CommonAPI.post(user, %{"status" => "test#{i}"}) end) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/users/#{user.nickname}") + conn = get(conn, "/users/#{user.nickname}") html = html_response(conn, 200) @@ -75,15 +61,11 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do refute html =~ ">test1<" end - test "pagination, page 2", %{conn: conn} do - user = insert(:user) + test "pagination, page 2", %{conn: conn, user: user} do activities = Enum.map(1..30, fn i -> CommonAPI.post(user, %{"status" => "test#{i}"}) end) {:ok, a11} = Enum.at(activities, 11) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/users/#{user.nickname}?max_id=#{a11.id}") + conn = get(conn, "/users/#{user.nickname}?max_id=#{a11.id}") html = html_response(conn, 200) @@ -92,17 +74,17 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do refute html =~ ">test20<" refute html =~ ">test29<" end + + test "it requires authentication if instance is NOT federating", %{conn: conn, user: user} do + ensure_federating_or_authenticated(conn, "/users/#{user.nickname}", user) + end end - describe "notice rendering" do - test "single notice page", %{conn: conn} do - user = insert(:user) + describe "notice html" do + test "single notice page", %{conn: conn, user: user} do {:ok, activity} = CommonAPI.post(user, %{"status" => "testing a thing!"}) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/notice/#{activity.id}") + conn = get(conn, "/notice/#{activity.id}") html = html_response(conn, 200) assert html =~ "<header>" @@ -110,8 +92,20 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do assert html =~ "testing a thing!" end - test "shows the whole thread", %{conn: conn} do + test "filters HTML tags", %{conn: conn} do user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "<script>alert('xss')</script>"}) + + conn = + conn + |> put_req_header("accept", "text/html") + |> get("/notice/#{activity.id}") + + html = html_response(conn, 200) + assert html =~ ~s[<script>alert('xss')</script>] + end + + test "shows the whole thread", %{conn: conn, user: user} do {:ok, activity} = CommonAPI.post(user, %{"status" => "space: the final frontier"}) CommonAPI.post(user, %{ @@ -119,70 +113,47 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do "in_reply_to_status_id" => activity.id }) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/notice/#{activity.id}") + conn = get(conn, "/notice/#{activity.id}") html = html_response(conn, 200) assert html =~ "the final frontier" assert html =~ "voyages" end - test "redirect by AP object ID", %{conn: conn} do - user = insert(:user) - + test "redirect by AP object ID", %{conn: conn, user: user} do {:ok, %Activity{data: %{"object" => object_url}}} = CommonAPI.post(user, %{"status" => "beam me up"}) - conn = - conn - |> put_req_header("accept", "text/html") - |> get(URI.parse(object_url).path) + conn = get(conn, URI.parse(object_url).path) assert html_response(conn, 302) =~ "redirected" end - test "redirect by activity ID", %{conn: conn} do - user = insert(:user) - + test "redirect by activity ID", %{conn: conn, user: user} do {:ok, %Activity{data: %{"id" => id}}} = CommonAPI.post(user, %{"status" => "I'm a doctor, not a devops!"}) - conn = - conn - |> put_req_header("accept", "text/html") - |> get(URI.parse(id).path) + conn = get(conn, URI.parse(id).path) assert html_response(conn, 302) =~ "redirected" end test "404 when notice not found", %{conn: conn} do - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/notice/88c9c317") + conn = get(conn, "/notice/88c9c317") assert html_response(conn, 404) =~ "not found" end - test "404 for private status", %{conn: conn} do - user = insert(:user) - + test "404 for private status", %{conn: conn, user: user} do {:ok, activity} = CommonAPI.post(user, %{"status" => "don't show me!", "visibility" => "private"}) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/notice/#{activity.id}") + conn = get(conn, "/notice/#{activity.id}") assert html_response(conn, 404) =~ "not found" end - test "302 for remote cached status", %{conn: conn} do - user = insert(:user) - + test "302 for remote cached status", %{conn: conn, user: user} do message = %{ "@context" => "https://www.w3.org/ns/activitystreams", "to" => user.follower_address, @@ -199,12 +170,15 @@ defmodule Pleroma.Web.StaticFE.StaticFEControllerTest do assert {:ok, activity} = Transmogrifier.handle_incoming(message) - conn = - conn - |> put_req_header("accept", "text/html") - |> get("/notice/#{activity.id}") + conn = get(conn, "/notice/#{activity.id}") assert html_response(conn, 302) =~ "redirected" end + + test "it requires authentication if instance is NOT federating", %{conn: conn, user: user} do + {:ok, activity} = CommonAPI.post(user, %{"status" => "testing a thing!"}) + + ensure_federating_or_authenticated(conn, "/notice/#{activity.id}", user) + end end end diff --git a/test/web/streamer/ping_test.exs b/test/web/streamer/ping_test.exs index 3d52c00e4..5df6c1cc3 100644 --- a/test/web/streamer/ping_test.exs +++ b/test/web/streamer/ping_test.exs @@ -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.PingTest do diff --git a/test/web/streamer/state_test.exs b/test/web/streamer/state_test.exs index d1aeac541..a755e75c0 100644 --- a/test/web/streamer/state_test.exs +++ b/test/web/streamer/state_test.exs @@ -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.StateTest do diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs index 5a5b35147..f0bafc093 100644 --- a/test/web/streamer/streamer_test.exs +++ b/test/web/streamer/streamer_test.exs @@ -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.StreamerTest do @@ -16,7 +16,11 @@ defmodule Pleroma.Web.StreamerTest do alias Pleroma.Web.Streamer.Worker @moduletag needs_streamer: true, capture_log: true - clear_config_all([:instance, :skip_thread_containment]) + + @streamer_timeout 150 + @streamer_start_wait 10 + + clear_config([:instance, :skip_thread_containment]) describe "user streams" do setup do @@ -28,7 +32,7 @@ defmodule Pleroma.Web.StreamerTest do test "it sends notify to in the 'user' stream", %{user: user, notify: notify} do task = Task.async(fn -> - assert_receive {:text, _}, 4_000 + assert_receive {:text, _}, @streamer_timeout end) Streamer.add_socket( @@ -43,7 +47,7 @@ defmodule Pleroma.Web.StreamerTest do test "it sends notify to in the 'user:notification' stream", %{user: user, notify: notify} do task = Task.async(fn -> - assert_receive {:text, _}, 4_000 + assert_receive {:text, _}, @streamer_timeout end) Streamer.add_socket( @@ -59,9 +63,9 @@ defmodule Pleroma.Web.StreamerTest do user: user } do blocked = insert(:user) - {:ok, user} = User.block(user, blocked) + {:ok, _user_relationship} = User.block(user, blocked) - task = Task.async(fn -> refute_receive {:text, _}, 4_000 end) + task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end) Streamer.add_socket( "user:notification", @@ -79,7 +83,8 @@ defmodule Pleroma.Web.StreamerTest do user: user } do user2 = insert(:user) - task = Task.async(fn -> refute_receive {:text, _}, 4_000 end) + + task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end) Streamer.add_socket( "user:notification", @@ -89,6 +94,7 @@ defmodule Pleroma.Web.StreamerTest do {:ok, activity} = CommonAPI.post(user, %{"status" => "super hot take"}) {:ok, activity} = CommonAPI.add_mute(user, activity) {:ok, notif} = CommonAPI.favorite(user2, activity.id) + Streamer.stream("user:notification", notif) Task.await(task) end @@ -97,7 +103,8 @@ defmodule Pleroma.Web.StreamerTest do user: user } do user2 = insert(:user, %{ap_id: "https://hecking-lewd-place.com/user/meanie"}) - task = Task.async(fn -> refute_receive {:text, _}, 4_000 end) + + task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end) Streamer.add_socket( "user:notification", @@ -116,7 +123,9 @@ defmodule Pleroma.Web.StreamerTest do user: user } do user2 = insert(:user) - task = Task.async(fn -> assert_receive {:text, _}, 4_000 end) + task = Task.async(fn -> assert_receive {:text, _}, @streamer_timeout end) + + Process.sleep(@streamer_start_wait) Streamer.add_socket( "user:notification", @@ -137,7 +146,7 @@ defmodule Pleroma.Web.StreamerTest do task = Task.async(fn -> - assert_receive {:text, _}, 4_000 + assert_receive {:text, _}, @streamer_timeout end) fake_socket = %StreamerSocket{ @@ -164,7 +173,7 @@ defmodule Pleroma.Web.StreamerTest do } |> Jason.encode!() - assert_receive {:text, received_event}, 4_000 + assert_receive {:text, received_event}, @streamer_timeout assert received_event == expected_event end) @@ -259,7 +268,9 @@ defmodule Pleroma.Web.StreamerTest do test "it doesn't send messages involving blocked users" do user = insert(:user) blocked_user = insert(:user) - {:ok, user} = User.block(user, blocked_user) + {:ok, _user_relationship} = User.block(user, blocked_user) + + {:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"}) task = Task.async(fn -> @@ -271,8 +282,6 @@ defmodule Pleroma.Web.StreamerTest do user: user } - {:ok, activity} = CommonAPI.post(blocked_user, %{"status" => "Test"}) - topics = %{ "public" => [fake_socket] } @@ -301,7 +310,7 @@ defmodule Pleroma.Web.StreamerTest do "public" => [fake_socket] } - {:ok, blocker} = User.block(blocker, blockee) + {:ok, _user_relationship} = User.block(blocker, blockee) {:ok, activity_one} = CommonAPI.post(friend, %{"status" => "hey! @#{blockee.nickname}"}) @@ -329,6 +338,12 @@ defmodule Pleroma.Web.StreamerTest do {:ok, list} = List.create("Test", user_a) {:ok, list} = List.follow(list, user_b) + {:ok, activity} = + CommonAPI.post(user_b, %{ + "status" => "@#{user_c.nickname} Test", + "visibility" => "direct" + }) + task = Task.async(fn -> refute_receive {:text, _}, 1_000 @@ -339,12 +354,6 @@ defmodule Pleroma.Web.StreamerTest do user: user_a } - {:ok, activity} = - CommonAPI.post(user_b, %{ - "status" => "@#{user_c.nickname} Test", - "visibility" => "direct" - }) - topics = %{ "list:#{list.id}" => [fake_socket] } @@ -361,6 +370,12 @@ defmodule Pleroma.Web.StreamerTest do {:ok, list} = List.create("Test", user_a) {:ok, list} = List.follow(list, user_b) + {:ok, activity} = + CommonAPI.post(user_b, %{ + "status" => "Test", + "visibility" => "private" + }) + task = Task.async(fn -> refute_receive {:text, _}, 1_000 @@ -371,12 +386,6 @@ defmodule Pleroma.Web.StreamerTest do user: user_a } - {:ok, activity} = - CommonAPI.post(user_b, %{ - "status" => "Test", - "visibility" => "private" - }) - topics = %{ "list:#{list.id}" => [fake_socket] } @@ -395,6 +404,12 @@ defmodule Pleroma.Web.StreamerTest do {:ok, list} = List.create("Test", user_a) {:ok, list} = List.follow(list, user_b) + {:ok, activity} = + CommonAPI.post(user_b, %{ + "status" => "Test", + "visibility" => "private" + }) + task = Task.async(fn -> assert_receive {:text, _}, 1_000 @@ -405,12 +420,6 @@ defmodule Pleroma.Web.StreamerTest do user: user_a } - {:ok, activity} = - CommonAPI.post(user_b, %{ - "status" => "Test", - "visibility" => "private" - }) - Streamer.add_socket( "list:#{list.id}", fake_socket @@ -427,6 +436,9 @@ defmodule Pleroma.Web.StreamerTest do user3 = insert(:user) CommonAPI.hide_reblogs(user1, user2) + {:ok, create_activity} = CommonAPI.post(user3, %{"status" => "I'm kawen"}) + {:ok, announce_activity, _} = CommonAPI.repeat(create_activity.id, user2) + task = Task.async(fn -> refute_receive {:text, _}, 1_000 @@ -437,14 +449,39 @@ defmodule Pleroma.Web.StreamerTest do user: user1 } + topics = %{ + "public" => [fake_socket] + } + + Worker.push_to_socket(topics, "public", announce_activity) + + Task.await(task) + end + + test "it does send non-reblog notification for reblog-muted actors" do + user1 = insert(:user) + user2 = insert(:user) + user3 = insert(:user) + CommonAPI.hide_reblogs(user1, user2) + {:ok, create_activity} = CommonAPI.post(user3, %{"status" => "I'm kawen"}) - {:ok, announce_activity, _} = CommonAPI.repeat(create_activity.id, user2) + {:ok, favorite_activity} = CommonAPI.favorite(user2, create_activity.id) + + task = + Task.async(fn -> + assert_receive {:text, _}, 1_000 + end) + + fake_socket = %StreamerSocket{ + transport_pid: task.pid, + user: user1 + } topics = %{ "public" => [fake_socket] } - Worker.push_to_socket(topics, "public", announce_activity) + Worker.push_to_socket(topics, "public", favorite_activity) Task.await(task) end @@ -458,9 +495,7 @@ defmodule Pleroma.Web.StreamerTest do {:ok, activity} = CommonAPI.add_mute(user2, activity) - task = Task.async(fn -> refute_receive {:text, _}, 4_000 end) - - Process.sleep(4000) + task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end) Streamer.add_socket( "user", @@ -482,7 +517,7 @@ defmodule Pleroma.Web.StreamerTest do task = Task.async(fn -> - assert_receive {:text, received_event}, 4_000 + assert_receive {:text, received_event}, @streamer_timeout assert %{"event" => "conversation", "payload" => received_payload} = Jason.decode!(received_event) @@ -518,13 +553,13 @@ defmodule Pleroma.Web.StreamerTest do task = Task.async(fn -> - assert_receive {:text, received_event}, 4_000 + assert_receive {:text, received_event}, @streamer_timeout assert %{"event" => "delete", "payload" => _} = Jason.decode!(received_event) - refute_receive {:text, _}, 4_000 + refute_receive {:text, _}, @streamer_timeout end) - Process.sleep(1000) + Process.sleep(@streamer_start_wait) Streamer.add_socket( "direct", @@ -555,10 +590,10 @@ defmodule Pleroma.Web.StreamerTest do task = Task.async(fn -> - assert_receive {:text, received_event}, 4_000 + assert_receive {:text, received_event}, @streamer_timeout assert %{"event" => "delete", "payload" => _} = Jason.decode!(received_event) - assert_receive {:text, received_event}, 4_000 + assert_receive {:text, received_event}, @streamer_timeout assert %{"event" => "conversation", "payload" => received_payload} = Jason.decode!(received_event) @@ -567,7 +602,7 @@ defmodule Pleroma.Web.StreamerTest do assert last_status["id"] == to_string(create_activity.id) end) - Process.sleep(1000) + Process.sleep(@streamer_start_wait) Streamer.add_socket( "direct", diff --git a/test/web/twitter_api/password_controller_test.exs b/test/web/twitter_api/password_controller_test.exs index 840c84a05..0a24860d3 100644 --- a/test/web/twitter_api/password_controller_test.exs +++ b/test/web/twitter_api/password_controller_test.exs @@ -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.TwitterAPI.PasswordControllerTest do @@ -55,7 +55,7 @@ defmodule Pleroma.Web.TwitterAPI.PasswordControllerTest do user = refresh_record(user) assert Comeonin.Pbkdf2.checkpw("test", user.password_hash) - assert length(Token.get_user_tokens(user)) == 0 + assert Enum.empty?(Token.get_user_tokens(user)) end test "it sets password_reset_pending to false", %{conn: conn} do diff --git a/test/web/twitter_api/remote_follow_controller_test.exs b/test/web/twitter_api/remote_follow_controller_test.exs new file mode 100644 index 000000000..73062f18f --- /dev/null +++ b/test/web/twitter_api/remote_follow_controller_test.exs @@ -0,0 +1,237 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do + use Pleroma.Web.ConnCase + + alias Pleroma.Config + alias Pleroma.User + alias Pleroma.Web.CommonAPI + + import ExUnit.CaptureLog + import Pleroma.Factory + + setup do + Tesla.Mock.mock(fn env -> apply(HttpRequestMock, :request, [env]) end) + :ok + end + + clear_config_all([:instance, :federating]) do + Config.put([:instance, :federating], true) + end + + clear_config([:instance]) + clear_config([:frontend_configurations, :pleroma_fe]) + clear_config([:user, :deny_follow_blocked]) + + describe "GET /ostatus_subscribe - remote_follow/2" do + test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do + assert conn + |> get( + remote_follow_path(conn, :follow, %{ + acct: "https://mastodon.social/users/emelie/statuses/101849165031453009" + }) + ) + |> redirected_to() =~ "/notice/" + end + + test "show follow account page if the `acct` is a account link", %{conn: conn} do + response = + conn + |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"})) + |> html_response(200) + + assert response =~ "Log in to follow" + end + + test "show follow page if the `acct` is a account link", %{conn: conn} do + user = insert(:user) + + response = + conn + |> assign(:user, user) + |> get(remote_follow_path(conn, :follow, %{acct: "https://mastodon.social/users/emelie"})) + |> html_response(200) + + assert response =~ "Remote follow" + end + + test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do + user = insert(:user) + + assert capture_log(fn -> + response = + conn + |> assign(:user, user) + |> get( + remote_follow_path(conn, :follow, %{ + acct: "https://mastodon.social/users/not_found" + }) + ) + |> html_response(200) + + assert response =~ "Error fetching user" + end) =~ "Object has been deleted" + end + end + + describe "POST /ostatus_subscribe - do_follow/2 with assigned user " do + test "required `follow | write:follows` scope", %{conn: conn} do + user = insert(:user) + user2 = insert(:user) + read_token = insert(:oauth_token, user: user, scopes: ["read"]) + + assert capture_log(fn -> + response = + conn + |> assign(:user, user) + |> assign(:token, read_token) + |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) + |> response(200) + + assert response =~ "Error following account" + end) =~ "Insufficient permissions: follow | write:follows." + end + + test "follows user", %{conn: conn} do + user = insert(:user) + user2 = insert(:user) + + conn = + conn + |> assign(:user, user) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"])) + |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) + + assert redirected_to(conn) == "/users/#{user2.id}" + end + + test "returns error when user is deactivated", %{conn: conn} do + user = insert(:user, deactivated: true) + user2 = insert(:user) + + response = + conn + |> assign(:user, user) + |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) + |> response(200) + + assert response =~ "Error following account" + end + + test "returns error when user is blocked", %{conn: conn} do + Pleroma.Config.put([:user, :deny_follow_blocked], true) + user = insert(:user) + user2 = insert(:user) + + {:ok, _user_block} = Pleroma.User.block(user2, user) + + response = + conn + |> assign(:user, user) + |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) + |> response(200) + + assert response =~ "Error following account" + end + + test "returns error when followee not found", %{conn: conn} do + user = insert(:user) + + response = + conn + |> assign(:user, user) + |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => "jimm"}}) + |> response(200) + + assert response =~ "Error following account" + end + + test "returns success result when user already in followers", %{conn: conn} do + user = insert(:user) + user2 = insert(:user) + {:ok, _, _, _} = CommonAPI.follow(user, user2) + + conn = + conn + |> assign(:user, refresh_record(user)) + |> assign(:token, insert(:oauth_token, user: user, scopes: ["write:follows"])) + |> post(remote_follow_path(conn, :do_follow), %{"user" => %{"id" => user2.id}}) + + assert redirected_to(conn) == "/users/#{user2.id}" + end + end + + describe "POST /ostatus_subscribe - follow/2 without assigned user " do + test "follows", %{conn: conn} do + user = insert(:user) + user2 = insert(:user) + + conn = + conn + |> post(remote_follow_path(conn, :do_follow), %{ + "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} + }) + + assert redirected_to(conn) == "/users/#{user2.id}" + assert user2.follower_address in User.following(user) + end + + test "returns error when followee not found", %{conn: conn} do + user = insert(:user) + + response = + conn + |> post(remote_follow_path(conn, :do_follow), %{ + "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"} + }) + |> response(200) + + assert response =~ "Error following account" + end + + test "returns error when login invalid", %{conn: conn} do + user = insert(:user) + + response = + conn + |> post(remote_follow_path(conn, :do_follow), %{ + "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id} + }) + |> response(200) + + assert response =~ "Wrong username or password" + end + + test "returns error when password invalid", %{conn: conn} do + user = insert(:user) + user2 = insert(:user) + + response = + conn + |> post(remote_follow_path(conn, :do_follow), %{ + "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id} + }) + |> response(200) + + assert response =~ "Wrong username or password" + end + + test "returns error when user is blocked", %{conn: conn} do + Pleroma.Config.put([:user, :deny_follow_blocked], true) + user = insert(:user) + user2 = insert(:user) + {:ok, _user_block} = Pleroma.User.block(user2, user) + + response = + conn + |> post(remote_follow_path(conn, :do_follow), %{ + "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} + }) + |> response(200) + + assert response =~ "Error following account" + end + end +end diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs new file mode 100644 index 000000000..ab0a2c3df --- /dev/null +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -0,0 +1,142 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.TwitterAPI.ControllerTest do + use Pleroma.Web.ConnCase + + alias Pleroma.Builders.ActivityBuilder + alias Pleroma.Repo + alias Pleroma.User + alias Pleroma.Web.OAuth.Token + + import Pleroma.Factory + + describe "POST /api/qvitter/statuses/notifications/read" do + test "without valid credentials", %{conn: conn} do + conn = post(conn, "/api/qvitter/statuses/notifications/read", %{"latest_id" => 1_234_567}) + assert json_response(conn, 403) == %{"error" => "Invalid credentials."} + end + + test "with credentials, without any params" do + %{user: current_user, conn: conn} = + oauth_access(["read:notifications", "write:notifications"]) + + conn = + conn + |> assign(:user, current_user) + |> post("/api/qvitter/statuses/notifications/read") + + assert json_response(conn, 400) == %{ + "error" => "You need to specify latest_id", + "request" => "/api/qvitter/statuses/notifications/read" + } + end + + test "with credentials, with params" do + %{user: current_user, conn: conn} = + oauth_access(["read:notifications", "write:notifications"]) + + other_user = insert(:user) + + {:ok, _activity} = + ActivityBuilder.insert(%{"to" => [current_user.ap_id]}, %{user: other_user}) + + response_conn = + conn + |> assign(:user, current_user) + |> get("/api/v1/notifications") + + [notification] = response = json_response(response_conn, 200) + + assert length(response) == 1 + + assert notification["pleroma"]["is_seen"] == false + + response_conn = + conn + |> assign(:user, current_user) + |> post("/api/qvitter/statuses/notifications/read", %{"latest_id" => notification["id"]}) + + [notification] = response = json_response(response_conn, 200) + + assert length(response) == 1 + + assert notification["pleroma"]["is_seen"] == true + end + end + + describe "GET /api/account/confirm_email/:id/:token" do + setup do + {:ok, user} = + insert(:user) + |> User.confirmation_changeset(need_confirmation: true) + |> Repo.update() + + assert user.confirmation_pending + + [user: user] + end + + test "it redirects to root url", %{conn: conn, user: user} do + conn = get(conn, "/api/account/confirm_email/#{user.id}/#{user.confirmation_token}") + + assert 302 == conn.status + end + + test "it confirms the user account", %{conn: conn, user: user} do + get(conn, "/api/account/confirm_email/#{user.id}/#{user.confirmation_token}") + + user = User.get_cached_by_id(user.id) + + refute user.confirmation_pending + refute user.confirmation_token + end + + test "it returns 500 if user cannot be found by id", %{conn: conn, user: user} do + conn = get(conn, "/api/account/confirm_email/0/#{user.confirmation_token}") + + assert 500 == conn.status + end + + test "it returns 500 if token is invalid", %{conn: conn, user: user} do + conn = get(conn, "/api/account/confirm_email/#{user.id}/wrong_token") + + assert 500 == conn.status + end + end + + describe "GET /api/oauth_tokens" do + setup do + token = insert(:oauth_token) |> Repo.preload(:user) + + %{token: token} + end + + test "renders list", %{token: token} do + response = + build_conn() + |> assign(:user, token.user) + |> get("/api/oauth_tokens") + + keys = + json_response(response, 200) + |> hd() + |> Map.keys() + + assert keys -- ["id", "app_name", "valid_until"] == [] + end + + test "revoke token", %{token: token} do + response = + build_conn() + |> assign(:user, token.user) + |> delete("/api/oauth_tokens/#{token.id}") + + tokens = Token.get_user_tokens(token.user) + + assert tokens == [] + assert response.status == 201 + end + end +end diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 85a9be3e0..14eed5f27 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -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.TwitterAPI.TwitterAPITest do @@ -117,15 +117,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do end describe "register with one time token" do - setup do - setting = Pleroma.Config.get([:instance, :registrations_open]) - - if setting do - Pleroma.Config.put([:instance, :registrations_open], false) - on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end) - end - - :ok + clear_config([:instance, :registrations_open]) do + Pleroma.Config.put([:instance, :registrations_open], false) end test "returns user on success" do @@ -191,14 +184,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do end describe "registers with date limited token" do - setup do - setting = Pleroma.Config.get([:instance, :registrations_open]) - - if setting do - Pleroma.Config.put([:instance, :registrations_open], false) - on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end) - end + clear_config([:instance, :registrations_open]) do + Pleroma.Config.put([:instance, :registrations_open], false) + end + setup do data = %{ "nickname" => "vinny", "email" => "pasta@pizza.vs", @@ -256,15 +246,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do end describe "registers with reusable token" do - setup do - setting = Pleroma.Config.get([:instance, :registrations_open]) - - if setting do - Pleroma.Config.put([:instance, :registrations_open], false) - on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end) - end - - :ok + clear_config([:instance, :registrations_open]) do + Pleroma.Config.put([:instance, :registrations_open], false) end test "returns user on success, after him registration fails" do @@ -309,15 +292,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do end describe "registers with reusable date limited token" do - setup do - setting = Pleroma.Config.get([:instance, :registrations_open]) - - if setting do - Pleroma.Config.put([:instance, :registrations_open], false) - on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end) - end - - :ok + clear_config([:instance, :registrations_open]) do + Pleroma.Config.put([:instance, :registrations_open], false) end test "returns user on success" do diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index f0211f59c..9d757b5ef 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -1,16 +1,15 @@ # 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.TwitterAPI.UtilControllerTest do use Pleroma.Web.ConnCase use Oban.Testing, repo: Pleroma.Repo - alias Pleroma.Repo + alias Pleroma.Config alias Pleroma.Tests.ObanHelpers alias Pleroma.User - alias Pleroma.Web.CommonAPI - import ExUnit.CaptureLog + import Pleroma.Factory import Mock @@ -21,24 +20,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do clear_config([:instance]) clear_config([:frontend_configurations, :pleroma_fe]) - clear_config([:user, :deny_follow_blocked]) describe "POST /api/pleroma/follow_import" do + setup do: oauth_access(["follow"]) + test "it returns HTTP 200", %{conn: conn} do - user1 = insert(:user) user2 = insert(:user) response = conn - |> assign(:user, user1) |> post("/api/pleroma/follow_import", %{"list" => "#{user2.ap_id}"}) |> json_response(:ok) assert response == "job started" end - test "it imports follow lists from file", %{conn: conn} do - user1 = insert(:user) + test "it imports follow lists from file", %{user: user1, conn: conn} do user2 = insert(:user) with_mocks([ @@ -49,7 +46,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do ]) do response = conn - |> assign(:user, user1) |> post("/api/pleroma/follow_import", %{"list" => %Plug.Upload{path: "follow_list.txt"}}) |> json_response(:ok) @@ -67,12 +63,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end test "it imports new-style mastodon follow lists", %{conn: conn} do - user1 = insert(:user) user2 = insert(:user) response = conn - |> assign(:user, user1) |> post("/api/pleroma/follow_import", %{ "list" => "Account address,Show boosts\n#{user2.ap_id},true" }) @@ -81,7 +75,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert response == "job started" end - test "requires 'follow' or 'write:follows' permissions", %{conn: conn} do + test "requires 'follow' or 'write:follows' permissions" do token1 = insert(:oauth_token, scopes: ["read", "write"]) token2 = insert(:oauth_token, scopes: ["follow"]) token3 = insert(:oauth_token, scopes: ["something"]) @@ -89,7 +83,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do for token <- [token1, token2, token3] do conn = - conn + build_conn() |> put_req_header("authorization", "Bearer #{token.token}") |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"}) @@ -104,21 +98,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end describe "POST /api/pleroma/blocks_import" do + # Note: "follow" or "write:blocks" permission is required + setup do: oauth_access(["write:blocks"]) + test "it returns HTTP 200", %{conn: conn} do - user1 = insert(:user) user2 = insert(:user) response = conn - |> assign(:user, user1) |> post("/api/pleroma/blocks_import", %{"list" => "#{user2.ap_id}"}) |> json_response(:ok) assert response == "job started" end - test "it imports blocks users from file", %{conn: conn} do - user1 = insert(:user) + test "it imports blocks users from file", %{user: user1, conn: conn} do user2 = insert(:user) user3 = insert(:user) @@ -127,7 +121,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do ]) do response = conn - |> assign(:user, user1) |> post("/api/pleroma/blocks_import", %{"list" => %Plug.Upload{path: "blocks_list.txt"}}) |> json_response(:ok) @@ -146,31 +139,47 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end describe "PUT /api/pleroma/notification_settings" do - test "it updates notification settings", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) + test "it updates notification settings", %{user: user, conn: conn} do conn - |> assign(:user, user) |> put("/api/pleroma/notification_settings", %{ "followers" => false, "bar" => 1 }) |> json_response(:ok) - user = Repo.get(User, user.id) + user = refresh_record(user) - assert %{ - "followers" => false, - "follows" => true, - "non_follows" => true, - "non_followers" => true + assert %Pleroma.User.NotificationSetting{ + followers: false, + follows: true, + non_follows: true, + non_followers: true, + privacy_option: false + } == user.notification_settings + end + + test "it updates notification privacy option", %{user: user, conn: conn} do + conn + |> put("/api/pleroma/notification_settings", %{"privacy_option" => "1"}) + |> json_response(:ok) + + user = refresh_record(user) + + assert %Pleroma.User.NotificationSetting{ + followers: true, + follows: true, + non_follows: true, + non_followers: true, + privacy_option: true } == user.notification_settings end end describe "GET /api/statusnet/config" do test "it returns config in xml format", %{conn: conn} do - instance = Pleroma.Config.get(:instance) + instance = Config.get(:instance) response = conn @@ -187,12 +196,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end test "it returns config in json format", %{conn: conn} do - instance = Pleroma.Config.get(:instance) - Pleroma.Config.put([:instance, :managed_config], true) - Pleroma.Config.put([:instance, :registrations_open], false) - Pleroma.Config.put([:instance, :invites_enabled], true) - Pleroma.Config.put([:instance, :public], false) - Pleroma.Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"}) + instance = Config.get(:instance) + Config.put([:instance, :managed_config], true) + Config.put([:instance, :registrations_open], false) + Config.put([:instance, :invites_enabled], true) + Config.put([:instance, :public], false) + Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"}) response = conn @@ -226,7 +235,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end test "returns the state of safe_dm_mentions flag", %{conn: conn} do - Pleroma.Config.put([:instance, :safe_dm_mentions], true) + Config.put([:instance, :safe_dm_mentions], true) response = conn @@ -235,7 +244,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert response["site"]["safeDMMentionsEnabled"] == "1" - Pleroma.Config.put([:instance, :safe_dm_mentions], false) + Config.put([:instance, :safe_dm_mentions], false) response = conn @@ -246,8 +255,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end test "it returns the managed config", %{conn: conn} do - Pleroma.Config.put([:instance, :managed_config], false) - Pleroma.Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"}) + Config.put([:instance, :managed_config], false) + Config.put([:frontend_configurations, :pleroma_fe], %{theme: "asuka-hospital"}) response = conn @@ -256,7 +265,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do refute response["site"]["pleromafe"] - Pleroma.Config.put([:instance, :managed_config], true) + Config.put([:instance, :managed_config], true) response = conn @@ -279,7 +288,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do } ] - Pleroma.Config.put(:frontend_configurations, config) + Config.put(:frontend_configurations, config) response = conn @@ -308,201 +317,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end end - describe "GET /ostatus_subscribe - remote_follow/2" do - test "adds status to pleroma instance if the `acct` is a status", %{conn: conn} do - conn = - get( - conn, - "/ostatus_subscribe?acct=https://mastodon.social/users/emelie/statuses/101849165031453009" - ) - - assert redirected_to(conn) =~ "/notice/" - end - - test "show follow account page if the `acct` is a account link", %{conn: conn} do - response = - get( - conn, - "/ostatus_subscribe?acct=https://mastodon.social/users/emelie" - ) - - assert html_response(response, 200) =~ "Log in to follow" - end - - test "show follow page if the `acct` is a account link", %{conn: conn} do - user = insert(:user) - - response = - conn - |> assign(:user, user) - |> get("/ostatus_subscribe?acct=https://mastodon.social/users/emelie") - - assert html_response(response, 200) =~ "Remote follow" - end - - test "show follow page with error when user cannot fecth by `acct` link", %{conn: conn} do - user = insert(:user) - - assert capture_log(fn -> - response = - conn - |> assign(:user, user) - |> get("/ostatus_subscribe?acct=https://mastodon.social/users/not_found") - - assert html_response(response, 200) =~ "Error fetching user" - end) =~ "Object has been deleted" - end - end - - describe "POST /ostatus_subscribe - do_remote_follow/2 with assigned user " do - test "follows user", %{conn: conn} do - user = insert(:user) - user2 = insert(:user) - - response = - conn - |> assign(:user, user) - |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}}) - |> response(200) - - assert response =~ "Account followed!" - assert user2.follower_address in User.following(user) - end - - test "returns error when user is deactivated", %{conn: conn} do - user = insert(:user, deactivated: true) - user2 = insert(:user) - - response = - conn - |> assign(:user, user) - |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}}) - |> response(200) - - assert response =~ "Error following account" - end - - test "returns error when user is blocked", %{conn: conn} do - Pleroma.Config.put([:user, :deny_follow_blocked], true) - user = insert(:user) - user2 = insert(:user) - - {:ok, _user} = Pleroma.User.block(user2, user) - - response = - conn - |> assign(:user, user) - |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}}) - |> response(200) - - assert response =~ "Error following account" - end - - test "returns error when followee not found", %{conn: conn} do - user = insert(:user) - - response = - conn - |> assign(:user, user) - |> post("/ostatus_subscribe", %{"user" => %{"id" => "jimm"}}) - |> response(200) - - assert response =~ "Error following account" - end - - test "returns success result when user already in followers", %{conn: conn} do - user = insert(:user) - user2 = insert(:user) - {:ok, _, _, _} = CommonAPI.follow(user, user2) - - response = - conn - |> assign(:user, refresh_record(user)) - |> post("/ostatus_subscribe", %{"user" => %{"id" => user2.id}}) - |> response(200) - - assert response =~ "Account followed!" - end - end - - describe "POST /ostatus_subscribe - do_remote_follow/2 without assigned user " do - test "follows", %{conn: conn} do - user = insert(:user) - user2 = insert(:user) - - response = - conn - |> post("/ostatus_subscribe", %{ - "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} - }) - |> response(200) - - assert response =~ "Account followed!" - assert user2.follower_address in User.following(user) - end - - test "returns error when followee not found", %{conn: conn} do - user = insert(:user) - - response = - conn - |> post("/ostatus_subscribe", %{ - "authorization" => %{"name" => user.nickname, "password" => "test", "id" => "jimm"} - }) - |> response(200) - - assert response =~ "Error following account" - end - - test "returns error when login invalid", %{conn: conn} do - user = insert(:user) - - response = - conn - |> post("/ostatus_subscribe", %{ - "authorization" => %{"name" => "jimm", "password" => "test", "id" => user.id} - }) - |> response(200) - - assert response =~ "Wrong username or password" - end - - test "returns error when password invalid", %{conn: conn} do - user = insert(:user) - user2 = insert(:user) - - response = - conn - |> post("/ostatus_subscribe", %{ - "authorization" => %{"name" => user.nickname, "password" => "42", "id" => user2.id} - }) - |> response(200) - - assert response =~ "Wrong username or password" - end - - test "returns error when user is blocked", %{conn: conn} do - Pleroma.Config.put([:user, :deny_follow_blocked], true) - user = insert(:user) - user2 = insert(:user) - {:ok, _user} = Pleroma.User.block(user2, user) - - response = - conn - |> post("/ostatus_subscribe", %{ - "authorization" => %{"name" => user.nickname, "password" => "test", "id" => user2.id} - }) - |> response(200) - - assert response =~ "Error following account" - end - end - describe "GET /api/pleroma/healthcheck" do clear_config([:instance, :healthcheck]) test "returns 503 when healthcheck disabled", %{conn: conn} do - Pleroma.Config.put([:instance, :healthcheck], false) + Config.put([:instance, :healthcheck], false) response = conn @@ -513,7 +332,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end test "returns 200 when healthcheck enabled and all ok", %{conn: conn} do - Pleroma.Config.put([:instance, :healthcheck], true) + Config.put([:instance, :healthcheck], true) with_mock Pleroma.Healthcheck, system_info: fn -> %Pleroma.Healthcheck{healthy: true} end do @@ -532,8 +351,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end end - test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do - Pleroma.Config.put([:instance, :healthcheck], true) + test "returns 503 when healthcheck enabled and health is false", %{conn: conn} do + Config.put([:instance, :healthcheck], true) with_mock Pleroma.Healthcheck, system_info: fn -> %Pleroma.Healthcheck{healthy: false} end do @@ -554,12 +373,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end describe "POST /api/pleroma/disable_account" do - test "it returns HTTP 200", %{conn: conn} do - user = insert(:user) + setup do: oauth_access(["write:accounts"]) + test "with valid permissions and password, it disables the account", %{conn: conn, user: user} do response = conn - |> assign(:user, user) |> post("/api/pleroma/disable_account", %{"password" => "test"}) |> json_response(:ok) @@ -571,12 +389,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert user.deactivated == true end - test "it returns returns when password invalid", %{conn: conn} do + test "with valid permissions and invalid password, it returns an error", %{conn: conn} do user = insert(:user) response = conn - |> assign(:user, user) |> post("/api/pleroma/disable_account", %{"password" => "test1"}) |> json_response(:ok) @@ -610,6 +427,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end describe "POST /main/ostatus - remote_subscribe/2" do + clear_config([:instance, :federating]) do + Config.put([:instance, :federating], true) + end + test "renders subscribe form", %{conn: conn} do user = insert(:user) @@ -646,7 +467,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do "https://social.heldscal.la/main/ostatussub?profile=#{user.ap_id}" end - test "it renders form with error when use not found", %{conn: conn} do + test "it renders form with error when user not found", %{conn: conn} do user2 = insert(:user, ap_id: "shp@social.heldscal.la") response = @@ -671,29 +492,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end end - defp with_credentials(conn, username, password) do - header_content = "Basic " <> Base.encode64("#{username}:#{password}") - put_req_header(conn, "authorization", header_content) - end - - defp valid_user(_context) do - user = insert(:user) - [user: user] - end - describe "POST /api/pleroma/change_email" do - setup [:valid_user] + setup do: oauth_access(["write:accounts"]) - test "without credentials", %{conn: conn} do - conn = post(conn, "/api/pleroma/change_email") - assert json_response(conn, 403) == %{"error" => "Invalid credentials."} + test "without permissions", %{conn: conn} do + conn = + conn + |> assign(:token, nil) + |> post("/api/pleroma/change_email") + + assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} end - test "with credentials and invalid password", %{conn: conn, user: current_user} do + test "with proper permissions and invalid password", %{conn: conn} do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_email", %{ + post(conn, "/api/pleroma/change_email", %{ "password" => "hi", "email" => "test@test.com" }) @@ -701,14 +514,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert json_response(conn, 200) == %{"error" => "Invalid password."} end - test "with credentials, valid password and invalid email", %{ - conn: conn, - user: current_user + test "with proper permissions, valid password and invalid email", %{ + conn: conn } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_email", %{ + post(conn, "/api/pleroma/change_email", %{ "password" => "test", "email" => "foobar" }) @@ -716,28 +526,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert json_response(conn, 200) == %{"error" => "Email has invalid format."} end - test "with credentials, valid password and no email", %{ - conn: conn, - user: current_user + test "with proper permissions, valid password and no email", %{ + conn: conn } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_email", %{ + post(conn, "/api/pleroma/change_email", %{ "password" => "test" }) assert json_response(conn, 200) == %{"error" => "Email can't be blank."} end - test "with credentials, valid password and blank email", %{ - conn: conn, - user: current_user + test "with proper permissions, valid password and blank email", %{ + conn: conn } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_email", %{ + post(conn, "/api/pleroma/change_email", %{ "password" => "test", "email" => "" }) @@ -745,16 +549,13 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert json_response(conn, 200) == %{"error" => "Email can't be blank."} end - test "with credentials, valid password and non unique email", %{ - conn: conn, - user: current_user + test "with proper permissions, valid password and non unique email", %{ + conn: conn } do user = insert(:user) conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_email", %{ + post(conn, "/api/pleroma/change_email", %{ "password" => "test", "email" => user.email }) @@ -762,14 +563,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert json_response(conn, 200) == %{"error" => "Email has already been taken."} end - test "with credentials, valid password and valid email", %{ - conn: conn, - user: current_user + test "with proper permissions, valid password and valid email", %{ + conn: conn } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_email", %{ + post(conn, "/api/pleroma/change_email", %{ "password" => "test", "email" => "cofe@foobar.com" }) @@ -779,18 +577,20 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end describe "POST /api/pleroma/change_password" do - setup [:valid_user] + setup do: oauth_access(["write:accounts"]) + + test "without permissions", %{conn: conn} do + conn = + conn + |> assign(:token, nil) + |> post("/api/pleroma/change_password") - test "without credentials", %{conn: conn} do - conn = post(conn, "/api/pleroma/change_password") - assert json_response(conn, 403) == %{"error" => "Invalid credentials."} + assert json_response(conn, 403) == %{"error" => "Insufficient permissions: write:accounts."} end - test "with credentials and invalid password", %{conn: conn, user: current_user} do + test "with proper permissions and invalid password", %{conn: conn} do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_password", %{ + post(conn, "/api/pleroma/change_password", %{ "password" => "hi", "new_password" => "newpass", "new_password_confirmation" => "newpass" @@ -799,14 +599,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do assert json_response(conn, 200) == %{"error" => "Invalid password."} end - test "with credentials, valid password and new password and confirmation not matching", %{ - conn: conn, - user: current_user - } do + test "with proper permissions, valid password and new password and confirmation not matching", + %{ + conn: conn + } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_password", %{ + post(conn, "/api/pleroma/change_password", %{ "password" => "test", "new_password" => "newpass", "new_password_confirmation" => "notnewpass" @@ -817,14 +615,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do } end - test "with credentials, valid password and invalid new password", %{ - conn: conn, - user: current_user + test "with proper permissions, valid password and invalid new password", %{ + conn: conn } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_password", %{ + post(conn, "/api/pleroma/change_password", %{ "password" => "test", "new_password" => "", "new_password_confirmation" => "" @@ -835,51 +630,48 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do } end - test "with credentials, valid password and matching new password and confirmation", %{ + test "with proper permissions, valid password and matching new password and confirmation", %{ conn: conn, - user: current_user + user: user } do conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/change_password", %{ + post(conn, "/api/pleroma/change_password", %{ "password" => "test", "new_password" => "newpass", "new_password_confirmation" => "newpass" }) assert json_response(conn, 200) == %{"status" => "success"} - fetched_user = User.get_cached_by_id(current_user.id) + fetched_user = User.get_cached_by_id(user.id) assert Comeonin.Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true end end describe "POST /api/pleroma/delete_account" do - setup [:valid_user] - - test "without credentials", %{conn: conn} do - conn = post(conn, "/api/pleroma/delete_account") - assert json_response(conn, 403) == %{"error" => "Invalid credentials."} - end + setup do: oauth_access(["write:accounts"]) - test "with credentials and invalid password", %{conn: conn, user: current_user} do + test "without permissions", %{conn: conn} do conn = conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/delete_account", %{"password" => "hi"}) + |> assign(:token, nil) + |> post("/api/pleroma/delete_account") - assert json_response(conn, 200) == %{"error" => "Invalid password."} + assert json_response(conn, 403) == + %{"error" => "Insufficient permissions: write:accounts."} end - test "with credentials and valid password", %{conn: conn, user: current_user} do - conn = - conn - |> with_credentials(current_user.nickname, "test") - |> post("/api/pleroma/delete_account", %{"password" => "test"}) + test "with proper permissions and wrong or missing password", %{conn: conn} do + for params <- [%{"password" => "hi"}, %{}] do + ret_conn = post(conn, "/api/pleroma/delete_account", params) + + assert json_response(ret_conn, 200) == %{"error" => "Invalid password."} + end + end + + test "with proper permissions and valid password", %{conn: conn} do + conn = post(conn, "/api/pleroma/delete_account", %{"password" => "test"}) assert json_response(conn, 200) == %{"status" => "success"} - # Wait a second for the started task to end - :timer.sleep(1000) end end end diff --git a/test/web/uploader_controller_test.exs b/test/web/uploader_controller_test.exs index 7c7f9a6ea..21e518236 100644 --- a/test/web/uploader_controller_test.exs +++ b/test/web/uploader_controller_test.exs @@ -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.UploaderControllerTest do diff --git a/test/web/views/error_view_test.exs b/test/web/views/error_view_test.exs index 4e5398c83..8dbbd18b4 100644 --- a/test/web/views/error_view_test.exs +++ b/test/web/views/error_view_test.exs @@ -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.ErrorViewTest do diff --git a/test/web/web_finger/web_finger_controller_test.exs b/test/web/web_finger/web_finger_controller_test.exs index 49cd1460b..b65bf5904 100644 --- a/test/web/web_finger/web_finger_controller_test.exs +++ b/test/web/web_finger/web_finger_controller_test.exs @@ -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.WebFinger.WebFingerControllerTest do diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs index 5aa8c73cf..4b4282727 100644 --- a/test/web/web_finger/web_finger_test.exs +++ b/test/web/web_finger/web_finger_test.exs @@ -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.WebFingerTest do |