diff options
Diffstat (limited to 'test/web')
41 files changed, 2763 insertions, 1133 deletions
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index fbacb3993..6b5913f95 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -765,51 +765,87 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do 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!() + describe "POST /users/:nickname/outbox (C2S)" do + setup do + [ + activity: %{ + "@context" => "https://www.w3.org/ns/activitystreams", + "type" => "Create", + "object" => %{"type" => "Note", "content" => "AP C2S test"}, + "to" => "https://www.w3.org/ns/activitystreams#Public", + "cc" => [] + } + ] + end + + test "it rejects posts from other users / unauthenticated users", %{ + conn: conn, + activity: activity + } do user = insert(:user) other_user = insert(:user) conn = put_req_header(conn, "content-type", "application/activity+json") conn - |> post("/users/#{user.nickname}/outbox", data) + |> post("/users/#{user.nickname}/outbox", activity) |> json_response(403) conn |> assign(:user, other_user) - |> post("/users/#{user.nickname}/outbox", data) + |> post("/users/#{user.nickname}/outbox", activity) |> json_response(403) end - test "it inserts an incoming create activity into the database", %{conn: conn} do - data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!() + test "it inserts an incoming create activity into the database", %{ + conn: conn, + activity: activity + } do user = insert(:user) - conn = + result = conn |> assign(:user, user) |> put_req_header("content-type", "application/activity+json") - |> post("/users/#{user.nickname}/outbox", data) - - result = json_response(conn, 201) + |> post("/users/#{user.nickname}/outbox", activity) + |> json_response(201) assert Activity.get_by_ap_id(result["id"]) + assert result["object"] + assert %Object{data: object} = Object.normalize(result["object"]) + assert object["content"] == activity["object"]["content"] end - test "it rejects an incoming activity with bogus type", %{conn: conn} do - data = File.read!("test/fixtures/activitypub-client-post-activity.json") |> Poison.decode!() + test "it inserts an incoming sensitive activity into the database", %{ + conn: conn, + activity: activity + } do user = insert(:user) + object = Map.put(activity["object"], "sensitive", true) + activity = Map.put(activity, "object", object) - data = - data - |> Map.put("type", "BadType") + result = + conn + |> assign(:user, user) + |> put_req_header("content-type", "application/activity+json") + |> post("/users/#{user.nickname}/outbox", activity) + |> json_response(201) + + assert Activity.get_by_ap_id(result["id"]) + assert result["object"] + assert %Object{data: object} = Object.normalize(result["object"]) + assert object["sensitive"] == activity["object"]["sensitive"] + assert object["content"] == activity["object"]["content"] + end + + test "it rejects an incoming activity with bogus type", %{conn: conn, activity: activity} do + user = insert(:user) + activity = Map.put(activity, "type", "BadType") conn = conn |> assign(:user, user) |> put_req_header("content-type", "application/activity+json") - |> post("/users/#{user.nickname}/outbox", data) + |> post("/users/#{user.nickname}/outbox", activity) assert json_response(conn, 400) end diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 17e7b97de..edd7dfb22 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -180,7 +180,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, user} = ActivityPub.make_user_from_ap_id(user_id) assert user.ap_id == user_id assert user.nickname == "admin@mastodon.example.org" - assert user.source_data assert user.ap_enabled assert user.follower_address == "http://mastodon.example.org/users/admin/followers" end @@ -995,72 +994,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end end - describe "like an object" do - 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(Federator.publish(like_activity)) - end - - test "returns exist activity if object already liked" do - note_activity = insert(:note_activity) - assert object_activity = Object.normalize(note_activity) - - user = insert(:user) - - {:ok, like_activity, _object} = ActivityPub.like(user, object_activity) - - {:ok, like_activity_exist, _object} = ActivityPub.like(user, object_activity) - 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) - - user = insert(:user) - user_two = insert(:user) - - {:ok, like_activity, object} = ActivityPub.like(user, object) - - assert like_activity.data["actor"] == user.ap_id - assert like_activity.data["type"] == "Like" - assert like_activity.data["object"] == object.data["id"] - assert like_activity.data["to"] == [User.ap_followers(user), note_activity.data["actor"]] - assert like_activity.data["context"] == object.data["context"] - assert object.data["like_count"] == 1 - assert object.data["likes"] == [user.ap_id] - - # Just return the original activity if the user already liked it. - {:ok, same_like_activity, object} = ActivityPub.like(user, object) - - assert like_activity == same_like_activity - assert object.data["likes"] == [user.ap_id] - assert object.data["like_count"] == 1 - - {:ok, _like_activity, object} = ActivityPub.like(user_two, object) - assert object.data["like_count"] == 2 - end - end - describe "unliking" do test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do Config.put([:instance, :federating], true) @@ -1072,7 +1005,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, object} = ActivityPub.unlike(user, object) refute called(Federator.publish()) - {:ok, _like_activity, object} = ActivityPub.like(user, object) + {:ok, _like_activity} = CommonAPI.favorite(user, note_activity.id) + object = Object.get_by_id(object.id) assert object.data["like_count"] == 1 {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object) @@ -1083,10 +1017,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do 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) + {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id) + object = Object.normalize(note_activity) assert object.data["like_count"] == 1 with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do @@ -1107,7 +1041,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do {:ok, object} = ActivityPub.unlike(user, object) assert object.data["like_count"] == 0 - {:ok, like_activity, object} = ActivityPub.like(user, object) + {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id) + + object = Object.get_by_id(object.id) assert object.data["like_count"] == 1 {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object) @@ -1974,4 +1910,497 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do ActivityPub.move(old_user, new_user) end end + + test "doesn't retrieve replies activities with exclude_replies" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "yeah"}) + + {:ok, _reply} = + CommonAPI.post(user, %{"status" => "yeah", "in_reply_to_status_id" => activity.id}) + + [result] = ActivityPub.fetch_public_activities(%{"exclude_replies" => "true"}) + + assert result.id == activity.id + + assert length(ActivityPub.fetch_public_activities()) == 2 + end + + describe "replies filtering with public messages" do + setup :public_messages + + test "public timeline", %{users: %{u1: user}} do + activities_ids = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", false) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("reply_filtering_user", user) + |> ActivityPub.fetch_public_activities() + |> Enum.map(& &1.id) + + assert length(activities_ids) == 16 + end + + test "public timeline with reply_visibility `following`", %{ + users: %{u1: user}, + u1: u1, + u2: u2, + u3: u3, + u4: u4, + activities: activities + } do + activities_ids = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", false) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("reply_visibility", "following") + |> Map.put("reply_filtering_user", user) + |> ActivityPub.fetch_public_activities() + |> Enum.map(& &1.id) + + assert length(activities_ids) == 14 + + visible_ids = + Map.values(u1) ++ Map.values(u2) ++ Map.values(u4) ++ Map.values(activities) ++ [u3[:r1]] + + assert Enum.all?(visible_ids, &(&1 in activities_ids)) + end + + test "public timeline with reply_visibility `self`", %{ + users: %{u1: user}, + u1: u1, + u2: u2, + u3: u3, + u4: u4, + activities: activities + } do + activities_ids = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", false) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("reply_visibility", "self") + |> Map.put("reply_filtering_user", user) + |> ActivityPub.fetch_public_activities() + |> Enum.map(& &1.id) + + assert length(activities_ids) == 10 + visible_ids = Map.values(u1) ++ [u2[:r1], u3[:r1], u4[:r1]] ++ Map.values(activities) + assert Enum.all?(visible_ids, &(&1 in activities_ids)) + end + + test "home timeline", %{ + users: %{u1: user}, + activities: activities, + u1: u1, + u2: u2, + u3: u3, + u4: u4 + } do + params = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + |> Map.put("reply_filtering_user", user) + + activities_ids = + ActivityPub.fetch_activities([user.ap_id | User.following(user)], params) + |> Enum.map(& &1.id) + + assert length(activities_ids) == 13 + + visible_ids = + Map.values(u1) ++ + Map.values(u3) ++ + [ + activities[:a1], + activities[:a2], + activities[:a4], + u2[:r1], + u2[:r3], + u4[:r1], + u4[:r2] + ] + + assert Enum.all?(visible_ids, &(&1 in activities_ids)) + end + + test "home timeline with reply_visibility `following`", %{ + users: %{u1: user}, + activities: activities, + u1: u1, + u2: u2, + u3: u3, + u4: u4 + } do + params = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + |> Map.put("reply_visibility", "following") + |> Map.put("reply_filtering_user", user) + + activities_ids = + ActivityPub.fetch_activities([user.ap_id | User.following(user)], params) + |> Enum.map(& &1.id) + + assert length(activities_ids) == 11 + + visible_ids = + Map.values(u1) ++ + [ + activities[:a1], + activities[:a2], + activities[:a4], + u2[:r1], + u2[:r3], + u3[:r1], + u4[:r1], + u4[:r2] + ] + + assert Enum.all?(visible_ids, &(&1 in activities_ids)) + end + + test "home timeline with reply_visibility `self`", %{ + users: %{u1: user}, + activities: activities, + u1: u1, + u2: u2, + u3: u3, + u4: u4 + } do + params = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + |> Map.put("reply_visibility", "self") + |> Map.put("reply_filtering_user", user) + + activities_ids = + ActivityPub.fetch_activities([user.ap_id | User.following(user)], params) + |> Enum.map(& &1.id) + + assert length(activities_ids) == 9 + + visible_ids = + Map.values(u1) ++ + [ + activities[:a1], + activities[:a2], + activities[:a4], + u2[:r1], + u3[:r1], + u4[:r1] + ] + + assert Enum.all?(visible_ids, &(&1 in activities_ids)) + end + end + + describe "replies filtering with private messages" do + setup :private_messages + + test "public timeline", %{users: %{u1: user}} do + activities_ids = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", false) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + |> ActivityPub.fetch_public_activities() + |> Enum.map(& &1.id) + + assert activities_ids == [] + end + + test "public timeline with default reply_visibility `following`", %{users: %{u1: user}} do + activities_ids = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", false) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("reply_visibility", "following") + |> Map.put("reply_filtering_user", user) + |> Map.put("user", user) + |> ActivityPub.fetch_public_activities() + |> Enum.map(& &1.id) + + assert activities_ids == [] + end + + test "public timeline with default reply_visibility `self`", %{users: %{u1: user}} do + activities_ids = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("local_only", false) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("reply_visibility", "self") + |> Map.put("reply_filtering_user", user) + |> Map.put("user", user) + |> ActivityPub.fetch_public_activities() + |> Enum.map(& &1.id) + + assert activities_ids == [] + end + + test "home timeline", %{users: %{u1: user}} do + params = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + + activities_ids = + ActivityPub.fetch_activities([user.ap_id | User.following(user)], params) + |> Enum.map(& &1.id) + + assert length(activities_ids) == 12 + end + + test "home timeline with default reply_visibility `following`", %{users: %{u1: user}} do + params = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + |> Map.put("reply_visibility", "following") + |> Map.put("reply_filtering_user", user) + + activities_ids = + ActivityPub.fetch_activities([user.ap_id | User.following(user)], params) + |> Enum.map(& &1.id) + + assert length(activities_ids) == 12 + end + + test "home timeline with default reply_visibility `self`", %{ + users: %{u1: user}, + activities: activities, + u1: u1, + u2: u2, + u3: u3, + u4: u4 + } do + params = + %{} + |> Map.put("type", ["Create", "Announce"]) + |> Map.put("blocking_user", user) + |> Map.put("muting_user", user) + |> Map.put("user", user) + |> Map.put("reply_visibility", "self") + |> Map.put("reply_filtering_user", user) + + activities_ids = + ActivityPub.fetch_activities([user.ap_id | User.following(user)], params) + |> Enum.map(& &1.id) + + assert length(activities_ids) == 10 + + visible_ids = + Map.values(u1) ++ Map.values(u4) ++ [u2[:r1], u3[:r1]] ++ Map.values(activities) + + assert Enum.all?(visible_ids, &(&1 in activities_ids)) + end + end + + defp public_messages(_) do + [u1, u2, u3, u4] = insert_list(4, :user) + {:ok, u1} = User.follow(u1, u2) + {:ok, u2} = User.follow(u2, u1) + {:ok, u1} = User.follow(u1, u4) + {:ok, u4} = User.follow(u4, u1) + + {:ok, u2} = User.follow(u2, u3) + {:ok, u3} = User.follow(u3, u2) + + {:ok, a1} = CommonAPI.post(u1, %{"status" => "Status"}) + + {:ok, r1_1} = + CommonAPI.post(u2, %{ + "status" => "@#{u1.nickname} reply from u2 to u1", + "in_reply_to_status_id" => a1.id + }) + + {:ok, r1_2} = + CommonAPI.post(u3, %{ + "status" => "@#{u1.nickname} reply from u3 to u1", + "in_reply_to_status_id" => a1.id + }) + + {:ok, r1_3} = + CommonAPI.post(u4, %{ + "status" => "@#{u1.nickname} reply from u4 to u1", + "in_reply_to_status_id" => a1.id + }) + + {:ok, a2} = CommonAPI.post(u2, %{"status" => "Status"}) + + {:ok, r2_1} = + CommonAPI.post(u1, %{ + "status" => "@#{u2.nickname} reply from u1 to u2", + "in_reply_to_status_id" => a2.id + }) + + {:ok, r2_2} = + CommonAPI.post(u3, %{ + "status" => "@#{u2.nickname} reply from u3 to u2", + "in_reply_to_status_id" => a2.id + }) + + {:ok, r2_3} = + CommonAPI.post(u4, %{ + "status" => "@#{u2.nickname} reply from u4 to u2", + "in_reply_to_status_id" => a2.id + }) + + {:ok, a3} = CommonAPI.post(u3, %{"status" => "Status"}) + + {:ok, r3_1} = + CommonAPI.post(u1, %{ + "status" => "@#{u3.nickname} reply from u1 to u3", + "in_reply_to_status_id" => a3.id + }) + + {:ok, r3_2} = + CommonAPI.post(u2, %{ + "status" => "@#{u3.nickname} reply from u2 to u3", + "in_reply_to_status_id" => a3.id + }) + + {:ok, r3_3} = + CommonAPI.post(u4, %{ + "status" => "@#{u3.nickname} reply from u4 to u3", + "in_reply_to_status_id" => a3.id + }) + + {:ok, a4} = CommonAPI.post(u4, %{"status" => "Status"}) + + {:ok, r4_1} = + CommonAPI.post(u1, %{ + "status" => "@#{u4.nickname} reply from u1 to u4", + "in_reply_to_status_id" => a4.id + }) + + {:ok, r4_2} = + CommonAPI.post(u2, %{ + "status" => "@#{u4.nickname} reply from u2 to u4", + "in_reply_to_status_id" => a4.id + }) + + {:ok, r4_3} = + CommonAPI.post(u3, %{ + "status" => "@#{u4.nickname} reply from u3 to u4", + "in_reply_to_status_id" => a4.id + }) + + {:ok, + users: %{u1: u1, u2: u2, u3: u3, u4: u4}, + activities: %{a1: a1.id, a2: a2.id, a3: a3.id, a4: a4.id}, + u1: %{r1: r1_1.id, r2: r1_2.id, r3: r1_3.id}, + u2: %{r1: r2_1.id, r2: r2_2.id, r3: r2_3.id}, + u3: %{r1: r3_1.id, r2: r3_2.id, r3: r3_3.id}, + u4: %{r1: r4_1.id, r2: r4_2.id, r3: r4_3.id}} + end + + defp private_messages(_) do + [u1, u2, u3, u4] = insert_list(4, :user) + {:ok, u1} = User.follow(u1, u2) + {:ok, u2} = User.follow(u2, u1) + {:ok, u1} = User.follow(u1, u3) + {:ok, u3} = User.follow(u3, u1) + {:ok, u1} = User.follow(u1, u4) + {:ok, u4} = User.follow(u4, u1) + + {:ok, u2} = User.follow(u2, u3) + {:ok, u3} = User.follow(u3, u2) + + {:ok, a1} = CommonAPI.post(u1, %{"status" => "Status", "visibility" => "private"}) + + {:ok, r1_1} = + CommonAPI.post(u2, %{ + "status" => "@#{u1.nickname} reply from u2 to u1", + "in_reply_to_status_id" => a1.id, + "visibility" => "private" + }) + + {:ok, r1_2} = + CommonAPI.post(u3, %{ + "status" => "@#{u1.nickname} reply from u3 to u1", + "in_reply_to_status_id" => a1.id, + "visibility" => "private" + }) + + {:ok, r1_3} = + CommonAPI.post(u4, %{ + "status" => "@#{u1.nickname} reply from u4 to u1", + "in_reply_to_status_id" => a1.id, + "visibility" => "private" + }) + + {:ok, a2} = CommonAPI.post(u2, %{"status" => "Status", "visibility" => "private"}) + + {:ok, r2_1} = + CommonAPI.post(u1, %{ + "status" => "@#{u2.nickname} reply from u1 to u2", + "in_reply_to_status_id" => a2.id, + "visibility" => "private" + }) + + {:ok, r2_2} = + CommonAPI.post(u3, %{ + "status" => "@#{u2.nickname} reply from u3 to u2", + "in_reply_to_status_id" => a2.id, + "visibility" => "private" + }) + + {:ok, a3} = CommonAPI.post(u3, %{"status" => "Status", "visibility" => "private"}) + + {:ok, r3_1} = + CommonAPI.post(u1, %{ + "status" => "@#{u3.nickname} reply from u1 to u3", + "in_reply_to_status_id" => a3.id, + "visibility" => "private" + }) + + {:ok, r3_2} = + CommonAPI.post(u2, %{ + "status" => "@#{u3.nickname} reply from u2 to u3", + "in_reply_to_status_id" => a3.id, + "visibility" => "private" + }) + + {:ok, a4} = CommonAPI.post(u4, %{"status" => "Status", "visibility" => "private"}) + + {:ok, r4_1} = + CommonAPI.post(u1, %{ + "status" => "@#{u4.nickname} reply from u1 to u4", + "in_reply_to_status_id" => a4.id, + "visibility" => "private" + }) + + {:ok, + users: %{u1: u1, u2: u2, u3: u3, u4: u4}, + activities: %{a1: a1.id, a2: a2.id, a3: a3.id, a4: a4.id}, + u1: %{r1: r1_1.id, r2: r1_2.id, r3: r1_3.id}, + u2: %{r1: r2_1.id, r2: r2_2.id}, + u3: %{r1: r3_1.id, r2: r3_2.id}, + u4: %{r1: r4_1.id}} + end end diff --git a/test/web/activity_pub/mrf/object_age_policy_test.exs b/test/web/activity_pub/mrf/object_age_policy_test.exs index 7ee195eeb..b0fb753bd 100644 --- a/test/web/activity_pub/mrf/object_age_policy_test.exs +++ b/test/web/activity_pub/mrf/object_age_policy_test.exs @@ -20,26 +20,38 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do :ok end + defp get_old_message do + File.read!("test/fixtures/mastodon-post-activity.json") + |> Poison.decode!() + end + + defp get_new_message do + old_message = get_old_message() + + new_object = + old_message + |> Map.get("object") + |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + + old_message + |> Map.put("object", new_object) + end + describe "with reject action" do test "it rejects an old post" do Config.put([:mrf_object_age, :actions], [:reject]) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + data = get_old_message() - {:reject, _} = ObjectAgePolicy.filter(data) + assert match?({:reject, _}, ObjectAgePolicy.filter(data)) end test "it allows a new post" do Config.put([:mrf_object_age, :actions], [:reject]) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() - |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + data = get_new_message() - {:ok, _} = ObjectAgePolicy.filter(data) + assert match?({:ok, _}, ObjectAgePolicy.filter(data)) end end @@ -47,9 +59,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do test "it delists an old post" do Config.put([:mrf_object_age, :actions], [:delist]) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + data = get_old_message() {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) @@ -61,14 +71,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do test "it allows a new post" do Config.put([:mrf_object_age, :actions], [:delist]) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() - |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + data = get_new_message() {:ok, _user} = User.get_or_fetch_by_ap_id(data["actor"]) - {:ok, ^data} = ObjectAgePolicy.filter(data) + assert match?({:ok, ^data}, ObjectAgePolicy.filter(data)) end end @@ -76,9 +83,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do test "it strips followers collections from an old post" do Config.put([:mrf_object_age, :actions], [:strip_followers]) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + data = get_old_message() {:ok, user} = User.get_or_fetch_by_ap_id(data["actor"]) @@ -91,14 +96,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicyTest do test "it allows a new post" do Config.put([:mrf_object_age, :actions], [:strip_followers]) - data = - File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() - |> Map.put("published", DateTime.utc_now() |> DateTime.to_iso8601()) + data = get_new_message() {:ok, _u} = User.get_or_fetch_by_ap_id(data["actor"]) - {:ok, ^data} = ObjectAgePolicy.filter(data) + assert match?({:ok, ^data}, ObjectAgePolicy.filter(data)) end end end diff --git a/test/web/activity_pub/mrf/simple_policy_test.exs b/test/web/activity_pub/mrf/simple_policy_test.exs index 91c24c2d9..b7b9bc6a2 100644 --- a/test/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/web/activity_pub/mrf/simple_policy_test.exs @@ -17,7 +17,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do reject: [], accept: [], avatar_removal: [], - banner_removal: [] + banner_removal: [], + reject_deletes: [] ) describe "when :media_removal" do @@ -382,6 +383,66 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do end end + describe "when :reject_deletes is empty" do + setup do: Config.put([:mrf_simple, :reject_deletes], []) + + test "it accepts deletions even from rejected servers" do + Config.put([:mrf_simple, :reject], ["remote.instance"]) + + deletion_message = build_remote_deletion_message() + + assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message} + end + + test "it accepts deletions even from non-whitelisted servers" do + Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + + deletion_message = build_remote_deletion_message() + + assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message} + end + end + + describe "when :reject_deletes is not empty but it doesn't have a matching host" do + setup do: Config.put([:mrf_simple, :reject_deletes], ["non.matching.remote"]) + + test "it accepts deletions even from rejected servers" do + Config.put([:mrf_simple, :reject], ["remote.instance"]) + + deletion_message = build_remote_deletion_message() + + assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message} + end + + test "it accepts deletions even from non-whitelisted servers" do + Config.put([:mrf_simple, :accept], ["non.matching.remote"]) + + deletion_message = build_remote_deletion_message() + + assert SimplePolicy.filter(deletion_message) == {:ok, deletion_message} + end + end + + describe "when :reject_deletes has a matching host" do + setup do: Config.put([:mrf_simple, :reject_deletes], ["remote.instance"]) + + test "it rejects the deletion" do + deletion_message = build_remote_deletion_message() + + assert SimplePolicy.filter(deletion_message) == {:reject, nil} + end + end + + describe "when :reject_deletes match with wildcard domain" do + setup do: Config.put([:mrf_simple, :reject_deletes], ["*.remote.instance"]) + + test "it rejects the deletion" do + deletion_message = build_remote_deletion_message() + + assert SimplePolicy.filter(deletion_message) == {:reject, nil} + end + end + defp build_local_message do %{ "actor" => "#{Pleroma.Web.base_url()}/users/alice", @@ -408,4 +469,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicyTest do "type" => "Person" } end + + defp build_remote_deletion_message do + %{ + "type" => "Delete", + "actor" => "https://remote.instance/users/bob" + } + end end diff --git a/test/web/activity_pub/publisher_test.exs b/test/web/activity_pub/publisher_test.exs index 801da03c1..c2bc38d52 100644 --- a/test/web/activity_pub/publisher_test.exs +++ b/test/web/activity_pub/publisher_test.exs @@ -48,10 +48,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do describe "determine_inbox/2" do test "it returns sharedInbox for messages involving as:Public in to" do - user = - insert(:user, %{ - source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}} - }) + user = insert(:user, %{shared_inbox: "http://example.com/inbox"}) activity = %Activity{ data: %{"to" => [@as_public], "cc" => [user.follower_address]} @@ -61,10 +58,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do end test "it returns sharedInbox for messages involving as:Public in cc" do - user = - insert(:user, %{ - source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}} - }) + user = insert(:user, %{shared_inbox: "http://example.com/inbox"}) activity = %Activity{ data: %{"cc" => [@as_public], "to" => [user.follower_address]} @@ -74,11 +68,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do end test "it returns sharedInbox for messages involving multiple recipients in to" do - user = - insert(:user, %{ - source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}} - }) - + user = insert(:user, %{shared_inbox: "http://example.com/inbox"}) user_two = insert(:user) user_three = insert(:user) @@ -90,11 +80,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do end test "it returns sharedInbox for messages involving multiple recipients in cc" do - user = - insert(:user, %{ - source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}} - }) - + user = insert(:user, %{shared_inbox: "http://example.com/inbox"}) user_two = insert(:user) user_three = insert(:user) @@ -107,12 +93,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do test "it returns sharedInbox for messages involving multiple recipients in total" do user = - insert(:user, - source_data: %{ - "inbox" => "http://example.com/personal-inbox", - "endpoints" => %{"sharedInbox" => "http://example.com/inbox"} - } - ) + insert(:user, %{ + shared_inbox: "http://example.com/inbox", + inbox: "http://example.com/personal-inbox" + }) user_two = insert(:user) @@ -125,12 +109,10 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do test "it returns inbox for messages involving single recipients in total" do user = - insert(:user, - source_data: %{ - "inbox" => "http://example.com/personal-inbox", - "endpoints" => %{"sharedInbox" => "http://example.com/inbox"} - } - ) + insert(:user, %{ + shared_inbox: "http://example.com/inbox", + inbox: "http://example.com/personal-inbox" + }) activity = %Activity{ data: %{"to" => [user.ap_id], "cc" => []} @@ -258,11 +240,11 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do [:passthrough], [] do follower = - insert(:user, + insert(:user, %{ local: false, - source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"}, + inbox: "https://domain.com/users/nick1/inbox", ap_enabled: true - ) + }) actor = insert(:user, follower_address: follower.ap_id) user = insert(:user) @@ -295,14 +277,14 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do fetcher = insert(:user, local: false, - source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"}, + inbox: "https://domain.com/users/nick1/inbox", ap_enabled: true ) another_fetcher = insert(:user, local: false, - source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"}, + inbox: "https://domain2.com/users/nick1/inbox", ap_enabled: true ) diff --git a/test/web/activity_pub/side_effects_test.exs b/test/web/activity_pub/side_effects_test.exs index b67bd14b3..0b6b55156 100644 --- a/test/web/activity_pub/side_effects_test.exs +++ b/test/web/activity_pub/side_effects_test.exs @@ -5,7 +5,9 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do use Pleroma.DataCase + alias Pleroma.Notification alias Pleroma.Object + alias Pleroma.Repo alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Builder alias Pleroma.Web.ActivityPub.SideEffects @@ -15,13 +17,14 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do describe "like objects" do setup do + poster = insert(:user) user = insert(:user) - {:ok, post} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, post} = CommonAPI.post(poster, %{"status" => "hey"}) {:ok, like_data, _meta} = Builder.like(user, post.object) {:ok, like, _meta} = ActivityPub.persist(like_data, local: true) - %{like: like, user: user} + %{like: like, user: user, poster: poster} end test "add the like to the original object", %{like: like, user: user} do @@ -30,5 +33,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do assert object.data["like_count"] == 1 assert user.ap_id in object.data["likes"] end + + test "creates a notification", %{like: like, poster: poster} do + {:ok, like, _} = SideEffects.handle(like) + assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id) + end end end diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 0800305ce..10d86ee45 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -746,7 +746,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do user = User.get_cached_by_ap_id(activity.actor) - assert User.fields(user) == [ + assert user.fields == [ %{"name" => "foo", "value" => "bar"}, %{"name" => "foo1", "value" => "bar1"} ] @@ -767,7 +767,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do user = User.get_cached_by_ap_id(user.ap_id) - assert User.fields(user) == [ + assert user.fields == [ %{"name" => "foo", "value" => "updated"}, %{"name" => "foo1", "value" => "updated"} ] @@ -785,7 +785,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do user = User.get_cached_by_ap_id(user.ap_id) - assert User.fields(user) == [ + assert user.fields == [ %{"name" => "foo", "value" => "updated"}, %{"name" => "foo1", "value" => "updated"} ] @@ -796,7 +796,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do user = User.get_cached_by_ap_id(user.ap_id) - assert User.fields(user) == [] + assert user.fields == [] end test "it works for incoming update activities which lock the account" do @@ -2191,4 +2191,18 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do Transmogrifier.set_replies(object.data)["replies"] end end + + test "take_emoji_tags/1" do + user = insert(:user, %{emoji: %{"firefox" => "https://example.org/firefox.png"}}) + + assert Transmogrifier.take_emoji_tags(user) == [ + %{ + "icon" => %{"type" => "Image", "url" => "https://example.org/firefox.png"}, + "id" => "https://example.org/firefox.png", + "name" => ":firefox:", + "type" => "Emoji", + "updated" => "1970-01-01T00:00:00Z" + } + ] + end end diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs index e913a5148..b0bfed917 100644 --- a/test/web/activity_pub/utils_test.exs +++ b/test/web/activity_pub/utils_test.exs @@ -224,8 +224,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do object = Object.normalize(activity) {:ok, [vote], object} = CommonAPI.vote(other_user, object, [0]) - vote_object = Object.normalize(vote) - {:ok, _activity, _object} = ActivityPub.like(user, vote_object) + {:ok, _activity} = CommonAPI.favorite(user, activity.id) [fetched_vote] = Utils.get_existing_votes(other_user.ap_id, object) assert fetched_vote.id == vote.id end @@ -346,7 +345,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do user = insert(:user) refute Utils.get_existing_like(user.ap_id, object) - {:ok, like_activity, _object} = ActivityPub.like(user, object) + {:ok, like_activity} = CommonAPI.favorite(user, note_activity.id) assert ^like_activity = Utils.get_existing_like(user.ap_id, object) end diff --git a/test/web/activity_pub/views/user_view_test.exs b/test/web/activity_pub/views/user_view_test.exs index ecb2dc386..8d00893a5 100644 --- a/test/web/activity_pub/views/user_view_test.exs +++ b/test/web/activity_pub/views/user_view_test.exs @@ -29,7 +29,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do {:ok, user} = insert(:user) - |> User.upgrade_changeset(%{fields: fields}) + |> User.update_changeset(%{fields: fields}) |> User.update_and_set_cache() assert %{ @@ -38,7 +38,7 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do end test "Renders with emoji tags" do - user = insert(:user, emoji: [%{"bib" => "/test"}]) + user = insert(:user, emoji: %{"bib" => "/test"}) assert %{ "tag" => [ diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index f02f6ae7a..f80dbf8dd 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -2110,7 +2110,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do |> get("/api/pleroma/admin/config") |> json_response(200) - refute Map.has_key?(configs, "need_reboot") + assert configs["need_reboot"] == false end test "update setting which need reboot, don't change reboot flag until reboot", %{conn: conn} do @@ -2166,7 +2166,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do |> get("/api/pleroma/admin/config") |> json_response(200) - refute Map.has_key?(configs, "need_reboot") + assert configs["need_reboot"] == false end test "saving config with nested merge", %{conn: conn} do @@ -2273,13 +2273,17 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do value: :erlang.term_to_binary([]) ) + Pleroma.Config.TransferTask.load_and_update_env([], false) + + assert Application.get_env(:logger, :backends) == [] + conn = post(conn, "/api/pleroma/admin/config", %{ configs: [ %{ group: config.group, key: config.key, - value: [":console", %{"tuple" => ["ExSyslogger", ":ex_syslogger"]}] + value: [":console"] } ] }) @@ -2290,8 +2294,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "group" => ":logger", "key" => ":backends", "value" => [ - ":console", - %{"tuple" => ["ExSyslogger", ":ex_syslogger"]} + ":console" ], "db" => [":backends"] } @@ -2299,14 +2302,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } assert Application.get_env(:logger, :backends) == [ - :console, - {ExSyslogger, :ex_syslogger} + :console ] - - capture_log(fn -> - require Logger - Logger.warn("Ooops...") - end) =~ "Ooops..." end test "saving full setting if value is not keyword", %{conn: conn} do @@ -2864,6 +2861,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end end + test "need_reboot flag", %{conn: conn} do + assert conn + |> get("/api/pleroma/admin/need_reboot") + |> json_response(200) == %{"need_reboot" => false} + + Restarter.Pleroma.need_reboot() + + assert conn + |> get("/api/pleroma/admin/need_reboot") + |> json_response(200) == %{"need_reboot" => true} + + on_exit(fn -> Restarter.Pleroma.refresh() end) + end + describe "GET /api/pleroma/admin/statuses" do test "returns all public and unlisted statuses", %{conn: conn, admin: admin} do blocked = insert(:user) @@ -3506,6 +3517,191 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do response["status_visibility"] end end + + describe "POST /api/pleroma/admin/oauth_app" do + test "errors", %{conn: conn} do + response = conn |> post("/api/pleroma/admin/oauth_app", %{}) |> json_response(200) + + assert response == %{"name" => "can't be blank", "redirect_uris" => "can't be blank"} + end + + test "success", %{conn: conn} do + base_url = Pleroma.Web.base_url() + app_name = "Trusted app" + + response = + conn + |> post("/api/pleroma/admin/oauth_app", %{ + name: app_name, + redirect_uris: base_url + }) + |> json_response(200) + + assert %{ + "client_id" => _, + "client_secret" => _, + "name" => ^app_name, + "redirect_uri" => ^base_url, + "trusted" => false + } = response + end + + test "with trusted", %{conn: conn} do + base_url = Pleroma.Web.base_url() + app_name = "Trusted app" + + response = + conn + |> post("/api/pleroma/admin/oauth_app", %{ + name: app_name, + redirect_uris: base_url, + trusted: true + }) + |> json_response(200) + + assert %{ + "client_id" => _, + "client_secret" => _, + "name" => ^app_name, + "redirect_uri" => ^base_url, + "trusted" => true + } = response + end + end + + describe "GET /api/pleroma/admin/oauth_app" do + setup do + app = insert(:oauth_app) + {:ok, app: app} + end + + test "list", %{conn: conn} do + response = + conn + |> get("/api/pleroma/admin/oauth_app") + |> json_response(200) + + assert %{"apps" => apps, "count" => count, "page_size" => _} = response + + assert length(apps) == count + end + + test "with page size", %{conn: conn} do + insert(:oauth_app) + page_size = 1 + + response = + conn + |> get("/api/pleroma/admin/oauth_app", %{page_size: to_string(page_size)}) + |> json_response(200) + + assert %{"apps" => apps, "count" => _, "page_size" => ^page_size} = response + + assert length(apps) == page_size + end + + test "search by client name", %{conn: conn, app: app} do + response = + conn + |> get("/api/pleroma/admin/oauth_app", %{name: app.client_name}) + |> json_response(200) + + assert %{"apps" => [returned], "count" => _, "page_size" => _} = response + + assert returned["client_id"] == app.client_id + assert returned["name"] == app.client_name + end + + test "search by client id", %{conn: conn, app: app} do + response = + conn + |> get("/api/pleroma/admin/oauth_app", %{client_id: app.client_id}) + |> json_response(200) + + assert %{"apps" => [returned], "count" => _, "page_size" => _} = response + + assert returned["client_id"] == app.client_id + assert returned["name"] == app.client_name + end + + test "only trusted", %{conn: conn} do + app = insert(:oauth_app, trusted: true) + + response = + conn + |> get("/api/pleroma/admin/oauth_app", %{trusted: true}) + |> json_response(200) + + assert %{"apps" => [returned], "count" => _, "page_size" => _} = response + + assert returned["client_id"] == app.client_id + assert returned["name"] == app.client_name + end + end + + describe "DELETE /api/pleroma/admin/oauth_app/:id" do + test "with id", %{conn: conn} do + app = insert(:oauth_app) + + response = + conn + |> delete("/api/pleroma/admin/oauth_app/" <> to_string(app.id)) + |> json_response(:no_content) + + assert response == "" + end + + test "with non existance id", %{conn: conn} do + response = + conn + |> delete("/api/pleroma/admin/oauth_app/0") + |> json_response(:bad_request) + + assert response == "" + end + end + + describe "PATCH /api/pleroma/admin/oauth_app/:id" do + test "with id", %{conn: conn} do + app = insert(:oauth_app) + + name = "another name" + url = "https://example.com" + scopes = ["admin"] + id = app.id + website = "http://website.com" + + response = + conn + |> patch("/api/pleroma/admin/oauth_app/" <> to_string(app.id), %{ + name: name, + trusted: true, + redirect_uris: url, + scopes: scopes, + website: website + }) + |> json_response(200) + + assert %{ + "client_id" => _, + "client_secret" => _, + "id" => ^id, + "name" => ^name, + "redirect_uri" => ^url, + "trusted" => true, + "website" => ^website + } = response + end + + test "without id", %{conn: conn} do + response = + conn + |> patch("/api/pleroma/admin/oauth_app/0") + |> json_response(:bad_request) + + assert response == "" + end + end end # Needed for testing diff --git a/test/web/api_spec/app_operation_test.exs b/test/web/api_spec/app_operation_test.exs deleted file mode 100644 index 5b96abb44..000000000 --- a/test/web/api_spec/app_operation_test.exs +++ /dev/null @@ -1,45 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.ApiSpec.AppOperationTest do - use Pleroma.Web.ConnCase, async: true - - alias Pleroma.Web.ApiSpec - alias Pleroma.Web.ApiSpec.Schemas.AppCreateRequest - alias Pleroma.Web.ApiSpec.Schemas.AppCreateResponse - - import OpenApiSpex.TestAssertions - import Pleroma.Factory - - test "AppCreateRequest example matches schema" do - api_spec = ApiSpec.spec() - schema = AppCreateRequest.schema() - assert_schema(schema.example, "AppCreateRequest", api_spec) - end - - test "AppCreateResponse example matches schema" do - api_spec = ApiSpec.spec() - schema = AppCreateResponse.schema() - assert_schema(schema.example, "AppCreateResponse", api_spec) - end - - test "AppController produces a AppCreateResponse", %{conn: conn} do - api_spec = ApiSpec.spec() - app_attrs = build(:oauth_app) - - json = - conn - |> put_req_header("content-type", "application/json") - |> post( - "/api/v1/apps", - Jason.encode!(%{ - client_name: app_attrs.client_name, - redirect_uris: app_attrs.redirect_uris - }) - ) - |> json_response(200) - - assert_schema(json, "AppCreateResponse", api_spec) - end -end diff --git a/test/web/api_spec/schema_examples_test.exs b/test/web/api_spec/schema_examples_test.exs new file mode 100644 index 000000000..88b6f07cb --- /dev/null +++ b/test/web/api_spec/schema_examples_test.exs @@ -0,0 +1,43 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.SchemaExamplesTest do + use ExUnit.Case, async: true + import Pleroma.Tests.ApiSpecHelpers + + @content_type "application/json" + + for operation <- api_operations() do + describe operation.operationId <> " Request Body" do + if operation.requestBody do + @media_type operation.requestBody.content[@content_type] + @schema resolve_schema(@media_type.schema) + + if @media_type.example do + test "request body media type example matches schema" do + assert_schema(@media_type.example, @schema) + end + end + + if @schema.example do + test "request body schema example matches schema" do + assert_schema(@schema.example, @schema) + end + end + end + end + + for {status, response} <- operation.responses do + describe "#{operation.operationId} - #{status} Response" do + @schema resolve_schema(response.content[@content_type].schema) + + if @schema.example do + test "example matches schema" do + assert_schema(@schema.example, @schema) + end + end + end + end + end +end diff --git a/test/web/auth/auth_test_controller_test.exs b/test/web/auth/auth_test_controller_test.exs new file mode 100644 index 000000000..fed52b7f3 --- /dev/null +++ b/test/web/auth/auth_test_controller_test.exs @@ -0,0 +1,242 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Tests.AuthTestControllerTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + + describe "do_oauth_check" do + test "serves with proper OAuth token (fulfilling requested scopes)" do + %{conn: good_token_conn, user: user} = oauth_access(["read"]) + + assert %{"user_id" => user.id} == + good_token_conn + |> get("/test/authenticated_api/do_oauth_check") + |> json_response(200) + + # Unintended usage (:api) — use with :authenticated_api instead + assert %{"user_id" => user.id} == + good_token_conn + |> get("/test/api/do_oauth_check") + |> json_response(200) + end + + test "fails on no token / missing scope(s)" do + %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"]) + + bad_token_conn + |> get("/test/authenticated_api/do_oauth_check") + |> json_response(403) + + bad_token_conn + |> assign(:token, nil) + |> get("/test/api/do_oauth_check") + |> json_response(403) + end + end + + describe "fallback_oauth_check" do + test "serves with proper OAuth token (fulfilling requested scopes)" do + %{conn: good_token_conn, user: user} = oauth_access(["read"]) + + assert %{"user_id" => user.id} == + good_token_conn + |> get("/test/api/fallback_oauth_check") + |> json_response(200) + + # Unintended usage (:authenticated_api) — use with :api instead + assert %{"user_id" => user.id} == + good_token_conn + |> get("/test/authenticated_api/fallback_oauth_check") + |> json_response(200) + end + + test "for :api on public instance, drops :user and renders on no token / missing scope(s)" do + clear_config([:instance, :public], true) + + %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"]) + + assert %{"user_id" => nil} == + bad_token_conn + |> get("/test/api/fallback_oauth_check") + |> json_response(200) + + assert %{"user_id" => nil} == + bad_token_conn + |> assign(:token, nil) + |> get("/test/api/fallback_oauth_check") + |> json_response(200) + end + + test "for :api on private instance, fails on no token / missing scope(s)" do + clear_config([:instance, :public], false) + + %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"]) + + bad_token_conn + |> get("/test/api/fallback_oauth_check") + |> json_response(403) + + bad_token_conn + |> assign(:token, nil) + |> get("/test/api/fallback_oauth_check") + |> json_response(403) + end + end + + describe "skip_oauth_check" do + test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do + user = insert(:user) + + assert %{"user_id" => user.id} == + build_conn() + |> assign(:user, user) + |> get("/test/authenticated_api/skip_oauth_check") + |> json_response(200) + + %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"]) + + assert %{"user_id" => user.id} == + bad_token_conn + |> get("/test/authenticated_api/skip_oauth_check") + |> json_response(200) + end + + test "serves via :api on public instance if :user is not set" do + clear_config([:instance, :public], true) + + assert %{"user_id" => nil} == + build_conn() + |> get("/test/api/skip_oauth_check") + |> json_response(200) + + build_conn() + |> get("/test/authenticated_api/skip_oauth_check") + |> json_response(403) + end + + test "fails on private instance if :user is not set" do + clear_config([:instance, :public], false) + + build_conn() + |> get("/test/api/skip_oauth_check") + |> json_response(403) + + build_conn() + |> get("/test/authenticated_api/skip_oauth_check") + |> json_response(403) + end + end + + describe "fallback_oauth_skip_publicity_check" do + test "serves with proper OAuth token (fulfilling requested scopes)" do + %{conn: good_token_conn, user: user} = oauth_access(["read"]) + + assert %{"user_id" => user.id} == + good_token_conn + |> get("/test/api/fallback_oauth_skip_publicity_check") + |> json_response(200) + + # Unintended usage (:authenticated_api) + assert %{"user_id" => user.id} == + good_token_conn + |> get("/test/authenticated_api/fallback_oauth_skip_publicity_check") + |> json_response(200) + end + + test "for :api on private / public instance, drops :user and renders on token issue" do + %{conn: bad_token_conn} = oauth_access(["irrelevant_scope"]) + + for is_public <- [true, false] do + clear_config([:instance, :public], is_public) + + assert %{"user_id" => nil} == + bad_token_conn + |> get("/test/api/fallback_oauth_skip_publicity_check") + |> json_response(200) + + assert %{"user_id" => nil} == + bad_token_conn + |> assign(:token, nil) + |> get("/test/api/fallback_oauth_skip_publicity_check") + |> json_response(200) + end + end + end + + describe "skip_oauth_skip_publicity_check" do + test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do + user = insert(:user) + + assert %{"user_id" => user.id} == + build_conn() + |> assign(:user, user) + |> get("/test/authenticated_api/skip_oauth_skip_publicity_check") + |> json_response(200) + + %{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"]) + + assert %{"user_id" => user.id} == + bad_token_conn + |> get("/test/authenticated_api/skip_oauth_skip_publicity_check") + |> json_response(200) + end + + test "for :api, serves on private and public instances regardless of whether :user is set" do + user = insert(:user) + + for is_public <- [true, false] do + clear_config([:instance, :public], is_public) + + assert %{"user_id" => nil} == + build_conn() + |> get("/test/api/skip_oauth_skip_publicity_check") + |> json_response(200) + + assert %{"user_id" => user.id} == + build_conn() + |> assign(:user, user) + |> get("/test/api/skip_oauth_skip_publicity_check") + |> json_response(200) + end + end + end + + describe "missing_oauth_check_definition" do + def test_missing_oauth_check_definition_failure(endpoint, expected_error) do + %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"]) + + assert %{"error" => expected_error} == + conn + |> get(endpoint) + |> json_response(403) + end + + test "fails if served via :authenticated_api" do + test_missing_oauth_check_definition_failure( + "/test/authenticated_api/missing_oauth_check_definition", + "Security violation: OAuth scopes check was neither handled nor explicitly skipped." + ) + end + + test "fails if served via :api and the instance is private" do + clear_config([:instance, :public], false) + + test_missing_oauth_check_definition_failure( + "/test/api/missing_oauth_check_definition", + "This resource requires authentication." + ) + end + + test "succeeds with dropped :user if served via :api on public instance" do + %{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"]) + + assert %{"user_id" => nil} == + conn + |> get("/test/api/missing_oauth_check_definition") + |> json_response(200) + end + end +end diff --git a/test/web/auth/basic_auth_test.exs b/test/web/auth/basic_auth_test.exs new file mode 100644 index 000000000..64f8a6863 --- /dev/null +++ b/test/web/auth/basic_auth_test.exs @@ -0,0 +1,46 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Auth.BasicAuthTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + + test "with HTTP Basic Auth used, grants access to OAuth scope-restricted endpoints", %{ + conn: conn + } do + user = insert(:user) + assert Comeonin.Pbkdf2.checkpw("test", user.password_hash) + + basic_auth_contents = + (URI.encode_www_form(user.nickname) <> ":" <> URI.encode_www_form("test")) + |> Base.encode64() + + # Succeeds with HTTP Basic Auth + response = + conn + |> put_req_header("authorization", "Basic " <> basic_auth_contents) + |> get("/api/v1/accounts/verify_credentials") + |> json_response(200) + + user_nickname = user.nickname + assert %{"username" => ^user_nickname} = response + + # Succeeds with a properly scoped OAuth token + valid_token = insert(:oauth_token, scopes: ["read:accounts"]) + + conn + |> put_req_header("authorization", "Bearer #{valid_token.token}") + |> get("/api/v1/accounts/verify_credentials") + |> json_response(200) + + # Fails with a wrong-scoped OAuth token (proof of restriction) + invalid_token = insert(:oauth_token, scopes: ["read:something"]) + + conn + |> put_req_header("authorization", "Bearer #{invalid_token.token}") + |> get("/api/v1/accounts/verify_credentials") + |> json_response(403) + end +end diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index b12be973f..1758662b0 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -21,6 +21,60 @@ defmodule Pleroma.Web.CommonAPITest do setup do: clear_config([:instance, :limit]) setup do: clear_config([:instance, :max_pinned_statuses]) + test "favoriting race condition" do + user = insert(:user) + users_serial = insert_list(10, :user) + users = insert_list(10, :user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "."}) + + users_serial + |> Enum.map(fn user -> + CommonAPI.favorite(user, activity.id) + end) + + object = Object.get_by_ap_id(activity.data["object"]) + assert object.data["like_count"] == 10 + + users + |> Enum.map(fn user -> + Task.async(fn -> + CommonAPI.favorite(user, activity.id) + end) + end) + |> Enum.map(&Task.await/1) + + object = Object.get_by_ap_id(activity.data["object"]) + assert object.data["like_count"] == 20 + end + + test "repeating race condition" do + user = insert(:user) + users_serial = insert_list(10, :user) + users = insert_list(10, :user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "."}) + + users_serial + |> Enum.map(fn user -> + CommonAPI.repeat(activity.id, user) + end) + + object = Object.get_by_ap_id(activity.data["object"]) + assert object.data["announcement_count"] == 10 + + users + |> Enum.map(fn user -> + Task.async(fn -> + CommonAPI.repeat(activity.id, user) + end) + end) + |> Enum.map(&Task.await/1) + + object = Object.get_by_ap_id(activity.data["object"]) + assert object.data["announcement_count"] == 20 + end + test "when replying to a conversation / participation, it will set the correct context id even if no explicit reply_to is given" do user = insert(:user) {:ok, activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) @@ -97,18 +151,6 @@ defmodule Pleroma.Web.CommonAPITest do assert Object.normalize(activity).data["emoji"]["firefox"] end - test "it adds emoji when updating profiles" do - user = insert(:user, %{name: ":firefox:"}) - - {:ok, activity} = CommonAPI.update(user) - user = User.get_cached_by_ap_id(user.ap_id) - [firefox] = user.source_data["tag"] - - assert firefox["name"] == ":firefox:" - - assert Pleroma.Constants.as_public() in activity.recipients - end - describe "posting" do test "it supports explicit addressing" do user = insert(:user) @@ -268,6 +310,16 @@ defmodule Pleroma.Web.CommonAPITest do {:ok, %Activity{}, _} = CommonAPI.repeat(activity.id, user) end + test "can't repeat a repeat" do + user = insert(:user) + other_user = insert(:user) + {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) + + {:ok, %Activity{} = announce, _} = CommonAPI.repeat(activity.id, other_user) + + refute match?({:ok, %Activity{}, _}, CommonAPI.repeat(announce.id, user)) + end + test "repeating a status privately" do user = insert(:user) other_user = insert(:user) @@ -297,8 +349,8 @@ defmodule Pleroma.Web.CommonAPITest do other_user = insert(:user) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) - {:ok, %Activity{} = activity, object} = CommonAPI.repeat(activity.id, user) - {:ok, ^activity, ^object} = CommonAPI.repeat(activity.id, user) + {:ok, %Activity{} = announce, object} = CommonAPI.repeat(activity.id, user) + {:ok, ^announce, ^object} = CommonAPI.repeat(activity.id, user) end test "favoriting a status twice returns ok, but without the like activity" do @@ -372,7 +424,9 @@ defmodule Pleroma.Web.CommonAPITest do user = refresh_record(user) - assert {:ok, ^activity} = CommonAPI.unpin(activity.id, user) + id = activity.id + + assert match?({:ok, %{id: ^id}}, CommonAPI.unpin(activity.id, user)) user = refresh_record(user) diff --git a/test/web/common_api/common_api_utils_test.exs b/test/web/common_api/common_api_utils_test.exs index 98cf02d49..18a3b3b87 100644 --- a/test/web/common_api/common_api_utils_test.exs +++ b/test/web/common_api/common_api_utils_test.exs @@ -7,7 +7,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do alias Pleroma.Object alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.Endpoint use Pleroma.DataCase import ExUnit.CaptureLog @@ -42,28 +41,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do end end - test "parses emoji from name and bio" do - {:ok, user} = UserBuilder.insert(%{name: ":blank:", bio: ":firefox:"}) - - expected = [ - %{ - "type" => "Emoji", - "icon" => %{"type" => "Image", "url" => "#{Endpoint.url()}/emoji/Firefox.gif"}, - "name" => ":firefox:" - }, - %{ - "type" => "Emoji", - "icon" => %{ - "type" => "Image", - "url" => "#{Endpoint.url()}/emoji/blank.png" - }, - "name" => ":blank:" - } - ] - - assert expected == Utils.emoji_from_profile(user) - end - describe "format_input/3" do test "works for bare text/plain" do text = "hello world!" @@ -358,26 +335,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do end end - describe "get_by_id_or_ap_id/1" do - test "get activity by id" do - activity = insert(:note_activity) - %Pleroma.Activity{} = note = Utils.get_by_id_or_ap_id(activity.id) - assert note.id == activity.id - end - - test "get activity by ap_id" do - activity = insert(:note_activity) - %Pleroma.Activity{} = note = Utils.get_by_id_or_ap_id(activity.data["object"]) - assert note.id == activity.id - end - - test "get activity by object when type isn't `Create` " do - activity = insert(:like_activity) - %Pleroma.Activity{} = like = Utils.get_by_id_or_ap_id(activity.id) - assert like.data["object"] == activity.data["object"] - end - end - describe "to_master_date/1" do test "removes microseconds from date (NaiveDateTime)" do assert Utils.to_masto_date(~N[2015-01-23 23:50:07.123]) == "2015-01-23T23:50:07.000Z" diff --git a/test/web/federator_test.exs b/test/web/federator_test.exs index da844c24c..261518ef0 100644 --- a/test/web/federator_test.exs +++ b/test/web/federator_test.exs @@ -78,7 +78,7 @@ defmodule Pleroma.Web.FederatorTest do local: false, nickname: "nick1@domain.com", ap_id: "https://domain.com/users/nick1", - source_data: %{"inbox" => inbox1}, + inbox: inbox1, ap_enabled: true }) @@ -86,7 +86,7 @@ defmodule Pleroma.Web.FederatorTest do local: false, nickname: "nick2@domain2.com", ap_id: "https://domain2.com/users/nick2", - source_data: %{"inbox" => inbox2}, + inbox: inbox2, ap_enabled: true }) @@ -130,6 +130,9 @@ defmodule Pleroma.Web.FederatorTest do assert {:ok, job} = Federator.incoming_ap_doc(params) assert {:ok, _activity} = ObanHelpers.perform(job) + + assert {:ok, job} = Federator.incoming_ap_doc(params) + assert {:error, :already_present} = ObanHelpers.perform(job) end test "rejects incoming AP docs with incorrect origin" do @@ -148,7 +151,7 @@ defmodule Pleroma.Web.FederatorTest do } assert {:ok, job} = Federator.incoming_ap_doc(params) - assert :error = ObanHelpers.perform(job) + assert {:error, :origin_containment_failed} = ObanHelpers.perform(job) end test "it does not crash if MRF rejects the post" do @@ -164,7 +167,7 @@ defmodule Pleroma.Web.FederatorTest do |> Poison.decode!() assert {:ok, job} = Federator.incoming_ap_doc(params) - assert :error = ObanHelpers.perform(job) + assert {:error, _} = ObanHelpers.perform(job) end end end diff --git a/test/web/feed/tag_controller_test.exs b/test/web/feed/tag_controller_test.exs index e863df86b..d95aac108 100644 --- a/test/web/feed/tag_controller_test.exs +++ b/test/web/feed/tag_controller_test.exs @@ -150,8 +150,8 @@ defmodule Pleroma.Web.Feed.TagControllerTest do obj2 = Object.normalize(activity2) assert xpath(xml, ~x"//channel/item/description/text()"sl) == [ - HtmlEntities.decode(FeedView.activity_content(obj2)), - HtmlEntities.decode(FeedView.activity_content(obj1)) + HtmlEntities.decode(FeedView.activity_content(obj2.data)), + HtmlEntities.decode(FeedView.activity_content(obj1.data)) ] response = 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 2d256f63c..fdb6d4c5d 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 @@ -14,6 +14,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do describe "updating credentials" do setup do: oauth_access(["write:accounts"]) + setup :request_content_type test "sets user settings in a generic way", %{conn: conn} do res_conn = @@ -25,7 +26,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user_data = json_response(res_conn, 200) + assert user_data = json_response_and_validate_schema(res_conn, 200) assert user_data["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}} user = Repo.get(User, user_data["id"]) @@ -41,7 +42,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user_data = json_response(res_conn, 200) + assert user_data = json_response_and_validate_schema(res_conn, 200) assert user_data["pleroma"]["settings_store"] == %{ @@ -62,7 +63,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do } }) - assert user_data = json_response(res_conn, 200) + assert user_data = json_response_and_validate_schema(res_conn, 200) assert user_data["pleroma"]["settings_store"] == %{ @@ -79,7 +80,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do "note" => "I drink #cofe with @#{user2.nickname}\n\nsuya.." }) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) 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 class="u-url mention" data-user="#{ @@ -90,7 +91,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do test "updates the user's locking status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["locked"] == true end @@ -100,21 +101,21 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{allow_following_move: "false"}) assert refresh_record(user).allow_following_move == false - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["allow_following_move"] == false end test "updates the user's default scope", %{conn: conn} do - conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "cofe"}) + conn = patch(conn, "/api/v1/accounts/update_credentials", %{default_scope: "unlisted"}) - assert user_data = json_response(conn, 200) - assert user_data["source"]["privacy"] == "cofe" + assert user_data = json_response_and_validate_schema(conn, 200) + assert user_data["source"]["privacy"] == "unlisted" end test "updates the user's hide_followers status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_followers: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_followers"] == true end @@ -122,12 +123,12 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert %{"source" => %{"pleroma" => %{"discoverable" => true}}} = conn |> patch("/api/v1/accounts/update_credentials", %{discoverable: "true"}) - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) assert %{"source" => %{"pleroma" => %{"discoverable" => false}}} = conn |> patch("/api/v1/accounts/update_credentials", %{discoverable: "false"}) - |> json_response(:ok) + |> json_response_and_validate_schema(:ok) end test "updates the user's hide_followers_count and hide_follows_count", %{conn: conn} do @@ -137,7 +138,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do hide_follows_count: "true" }) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_followers_count"] == true assert user_data["pleroma"]["hide_follows_count"] == true end @@ -146,7 +147,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do response = conn |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert response["pleroma"]["skip_thread_containment"] == true assert refresh_record(user).skip_thread_containment @@ -155,28 +156,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do test "updates the user's hide_follows status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_follows: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_follows"] == true end test "updates the user's hide_favorites status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{hide_favorites: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["pleroma"]["hide_favorites"] == true end test "updates the user's show_role status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{show_role: "false"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["source"]["pleroma"]["show_role"] == false end test "updates the user's no_rich_text status", %{conn: conn} do conn = patch(conn, "/api/v1/accounts/update_credentials", %{no_rich_text: "true"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["source"]["pleroma"]["no_rich_text"] == true end @@ -184,7 +185,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"}) - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["display_name"] == "markorepairs" end @@ -197,7 +198,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) - assert user_response = json_response(conn, 200) + assert user_response = json_response_and_validate_schema(conn, 200) assert user_response["avatar"] != User.avatar_url(user) end @@ -210,7 +211,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header}) - assert user_response = json_response(conn, 200) + assert user_response = json_response_and_validate_schema(conn, 200) assert user_response["header"] != User.banner_url(user) end @@ -226,7 +227,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do "pleroma_background_image" => new_header }) - assert user_response = json_response(conn, 200) + assert user_response = json_response_and_validate_schema(conn, 200) assert user_response["pleroma"]["background_image"] end @@ -237,14 +238,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do for token <- [token1, token2] do conn = build_conn() + |> put_req_header("content-type", "multipart/form-data") |> put_req_header("authorization", "Bearer #{token.token}") |> patch("/api/v1/accounts/update_credentials", %{}) if token == token1 do assert %{"error" => "Insufficient permissions: write:accounts."} == - json_response(conn, 403) + json_response_and_validate_schema(conn, 403) else - assert json_response(conn, 200) + assert json_response_and_validate_schema(conn, 200) end end end @@ -259,11 +261,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do "display_name" => name }) - assert json_response(ret_conn, 200) + assert json_response_and_validate_schema(ret_conn, 200) conn = get(conn, "/api/v1/accounts/#{user.id}") - assert user_data = json_response(conn, 200) + assert user_data = json_response_and_validate_schema(conn, 200) assert user_data["note"] == note assert user_data["display_name"] == name @@ -279,7 +281,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do account_data = conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert account_data["fields"] == [ %{"name" => "<a href=\"http://google.com\">foo</a>", "value" => "bar"}, @@ -312,7 +314,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do conn |> put_req_header("content-type", "application/x-www-form-urlencoded") |> patch("/api/v1/accounts/update_credentials", fields) - |> json_response(200) + |> json_response_and_validate_schema(200) assert account["fields"] == [ %{"name" => "foo", "value" => "bar"}, @@ -337,7 +339,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do account = conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(200) + |> json_response_and_validate_schema(200) assert account["fields"] == [ %{"name" => "foo", "value" => ""} @@ -356,14 +358,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert %{"error" => "Invalid request"} == conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(403) + |> json_response_and_validate_schema(403) fields = [%{"name" => long_name, "value" => "bar"}] assert %{"error" => "Invalid request"} == conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(403) + |> json_response_and_validate_schema(403) Pleroma.Config.put([:instance, :max_account_fields], 1) @@ -375,7 +377,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do assert %{"error" => "Invalid request"} == conn |> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields}) - |> json_response(403) + |> json_response_and_validate_schema(403) end end end diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs index a450a732c..b9da7e924 100644 --- a/test/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/web/mastodon_api/controllers/account_controller_test.exs @@ -19,43 +19,37 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: clear_config([:instance, :limit_to_local_content]) test "works by id" do - user = insert(:user) - - conn = - build_conn() - |> get("/api/v1/accounts/#{user.id}") - - assert %{"id" => id} = json_response(conn, 200) - assert id == to_string(user.id) + %User{id: user_id} = insert(:user) - conn = - build_conn() - |> get("/api/v1/accounts/-1") + assert %{"id" => ^user_id} = + build_conn() + |> get("/api/v1/accounts/#{user_id}") + |> json_response_and_validate_schema(200) - assert %{"error" => "Can't find user"} = json_response(conn, 404) + assert %{"error" => "Can't find user"} = + build_conn() + |> get("/api/v1/accounts/-1") + |> json_response_and_validate_schema(404) end test "works by nickname" do user = insert(:user) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.nickname}") - - assert %{"id" => id} = json_response(conn, 200) - assert id == user.id + assert %{"id" => user_id} = + build_conn() + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(200) end test "works by nickname for remote users" do Config.put([:instance, :limit_to_local_content], false) - user = insert(:user, nickname: "user@example.com", local: false) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.nickname}") + user = insert(:user, nickname: "user@example.com", local: false) - assert %{"id" => id} = json_response(conn, 200) - assert id == user.id + assert %{"id" => user_id} = + build_conn() + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(200) end test "respects limit_to_local_content == :all for remote user nicknames" do @@ -63,11 +57,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do user = insert(:user, nickname: "user@example.com", local: false) - conn = - build_conn() - |> get("/api/v1/accounts/#{user.nickname}") - - assert json_response(conn, 404) + assert build_conn() + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(404) end test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do @@ -80,7 +72,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do build_conn() |> get("/api/v1/accounts/#{user.nickname}") - assert json_response(conn, 404) + assert json_response_and_validate_schema(conn, 404) conn = build_conn() @@ -88,7 +80,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.nickname}") - assert %{"id" => id} = json_response(conn, 200) + assert %{"id" => id} = json_response_and_validate_schema(conn, 200) assert id == user.id end @@ -99,21 +91,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do user_one = insert(:user, %{id: 1212}) user_two = insert(:user, %{nickname: "#{user_one.id}garbage"}) - resp_one = + acc_one = conn |> get("/api/v1/accounts/#{user_one.id}") + |> json_response_and_validate_schema(:ok) - resp_two = + acc_two = conn |> get("/api/v1/accounts/#{user_two.nickname}") + |> json_response_and_validate_schema(:ok) - resp_three = + acc_three = conn |> get("/api/v1/accounts/#{user_two.id}") + |> json_response_and_validate_schema(:ok) - acc_one = json_response(resp_one, 200) - acc_two = json_response(resp_two, 200) - acc_three = json_response(resp_three, 200) refute acc_one == acc_two assert acc_two == acc_three end @@ -121,23 +113,19 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "returns 404 when user is invisible", %{conn: conn} do user = insert(:user, %{invisible: true}) - resp = - conn - |> get("/api/v1/accounts/#{user.nickname}") - |> json_response(404) - - assert %{"error" => "Can't find user"} = resp + assert %{"error" => "Can't find user"} = + conn + |> get("/api/v1/accounts/#{user.nickname}") + |> json_response_and_validate_schema(404) end test "returns 404 for internal.fetch actor", %{conn: conn} do %User{nickname: "internal.fetch"} = InternalFetchActor.get_actor() - resp = - conn - |> get("/api/v1/accounts/internal.fetch") - |> json_response(404) - - assert %{"error" => "Can't find user"} = resp + assert %{"error" => "Can't find user"} = + conn + |> get("/api/v1/accounts/internal.fetch") + |> json_response_and_validate_schema(404) end end @@ -155,27 +143,25 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do - res_conn = get(conn, "/api/v1/accounts/#{local.id}") - - assert json_response(res_conn, :not_found) == %{ - "error" => "Can't find user" - } - - res_conn = get(conn, "/api/v1/accounts/#{remote.id}") - - assert json_response(res_conn, :not_found) == %{ - "error" => "Can't find user" - } + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{local.id}") + |> json_response_and_validate_schema(:not_found) + + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{remote.id}") + |> json_response_and_validate_schema(:not_found) end test "if user is authenticated", %{local: local, remote: remote} do %{conn: conn} = oauth_access(["read"]) res_conn = get(conn, "/api/v1/accounts/#{local.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) res_conn = get(conn, "/api/v1/accounts/#{remote.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) end end @@ -187,22 +173,22 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}") - assert json_response(res_conn, :not_found) == %{ + assert json_response_and_validate_schema(res_conn, :not_found) == %{ "error" => "Can't find user" } res_conn = get(conn, "/api/v1/accounts/#{remote.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) end test "if user is authenticated", %{local: local, remote: remote} do %{conn: conn} = oauth_access(["read"]) res_conn = get(conn, "/api/v1/accounts/#{local.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) res_conn = get(conn, "/api/v1/accounts/#{remote.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) end end @@ -213,11 +199,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) res_conn = get(conn, "/api/v1/accounts/#{remote.id}") - assert json_response(res_conn, :not_found) == %{ + assert json_response_and_validate_schema(res_conn, :not_found) == %{ "error" => "Can't find user" } end @@ -226,10 +212,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do %{conn: conn} = oauth_access(["read"]) res_conn = get(conn, "/api/v1/accounts/#{local.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) res_conn = get(conn, "/api/v1/accounts/#{remote.id}") - assert %{"id" => _} = json_response(res_conn, 200) + assert %{"id" => _} = json_response_and_validate_schema(res_conn, 200) end end @@ -245,27 +231,37 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {: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 resp = + conn + |> get("/api/v1/accounts/#{user_two.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id}] = json_response(resp, 200) + assert [%{"id" => id}] = resp 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 resp = + conn + |> get("/api/v1/accounts/#{user_two.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id}] = json_response(resp, 200) + assert [%{"id" => id}] = resp 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) + resp = + build_conn() + |> get("/api/v1/accounts/#{user_three.id}/statuses") + |> json_response_and_validate_schema(200) + + assert [%{"id" => id}] = resp 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) + assert [] == json_response_and_validate_schema(resp, 200) end test "gets users statuses", %{conn: conn} do @@ -286,9 +282,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, private_activity} = CommonAPI.post(user_one, %{"status" => "private", "visibility" => "private"}) - resp = get(conn, "/api/v1/accounts/#{user_one.id}/statuses") + # TODO!!! + resp = + conn + |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id}] = json_response(resp, 200) + assert [%{"id" => id}] = resp assert id == to_string(activity.id) resp = @@ -296,8 +296,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:user, user_two) |> assign(:token, insert(:oauth_token, user: user_two, scopes: ["read:statuses"])) |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200) + assert [%{"id" => id_one}, %{"id" => id_two}] = resp assert id_one == to_string(direct_activity.id) assert id_two == to_string(activity.id) @@ -306,8 +307,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:user, user_three) |> assign(:token, insert(:oauth_token, user: user_three, scopes: ["read:statuses"])) |> get("/api/v1/accounts/#{user_one.id}/statuses") + |> json_response_and_validate_schema(200) - assert [%{"id" => id_one}, %{"id" => id_two}] = json_response(resp, 200) + assert [%{"id" => id_one}, %{"id" => id_two}] = resp assert id_one == to_string(private_activity.id) assert id_two == to_string(activity.id) end @@ -318,7 +320,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?pinned=true") - assert json_response(conn, 200) == [] + assert json_response_and_validate_schema(conn, 200) == [] end test "gets an users media", %{conn: conn} do @@ -333,56 +335,48 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do {:ok, %{id: media_id}} = ActivityPub.upload(file, actor: user.ap_id) - {:ok, image_post} = CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]}) + {:ok, %{id: image_post_id}} = + CommonAPI.post(user, %{"status" => "cofe", "media_ids" => [media_id]}) - conn = get(conn, "/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) + assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200) - conn = get(build_conn(), "/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) + assert [%{"id" => ^image_post_id}] = json_response_and_validate_schema(conn, 200) end 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 = get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_reblogs" => "true"}) + {:ok, %{id: post_id}} = CommonAPI.post(user, %{"status" => "HI!!!"}) + {:ok, _, _} = CommonAPI.repeat(post_id, user) - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(post.id) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=true") + assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200) - 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) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_reblogs=1") + assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200) end test "filters user's statuses by a hashtag", %{user: user, conn: conn} do - {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"}) + {:ok, %{id: post_id}} = CommonAPI.post(user, %{"status" => "#hashtag"}) {:ok, _post} = CommonAPI.post(user, %{"status" => "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) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?tagged=hashtag") + assert [%{"id" => ^post_id}] = json_response_and_validate_schema(conn, 200) end 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"}) + {:ok, %{id: public_activity_id}} = + CommonAPI.post(user, %{"status" => ".", "visibility" => "public"}) - conn = - get(conn, "/api/v1/accounts/#{user.id}/statuses", %{"exclude_visibilities" => ["direct"]}) + {:ok, _direct_activity} = CommonAPI.post(user, %{"status" => ".", "visibility" => "direct"}) - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(public_activity.id) + conn = get(conn, "/api/v1/accounts/#{user.id}/statuses?exclude_visibilities[]=direct") + assert [%{"id" => ^public_activity_id}] = json_response_and_validate_schema(conn, 200) end end @@ -402,27 +396,25 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: clear_config([:restrict_unauthenticated, :profiles, :remote], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do - res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") - - assert json_response(res_conn, :not_found) == %{ - "error" => "Can't find user" - } - - res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") - - assert json_response(res_conn, :not_found) == %{ - "error" => "Can't find user" - } + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{local.id}/statuses") + |> json_response_and_validate_schema(:not_found) + + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{remote.id}/statuses") + |> json_response_and_validate_schema(:not_found) end test "if user is authenticated", %{local: local, remote: remote} do %{conn: conn} = oauth_access(["read"]) res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 end end @@ -433,24 +425,23 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: clear_config([:restrict_unauthenticated, :profiles, :local], true) test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do - res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") - - assert json_response(res_conn, :not_found) == %{ - "error" => "Can't find user" - } + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{local.id}/statuses") + |> json_response_and_validate_schema(:not_found) res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 end test "if user is authenticated", %{local: local, remote: remote} do %{conn: conn} = oauth_access(["read"]) res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 end end @@ -462,23 +453,22 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "if user is unauthenticated", %{conn: conn, local: local, remote: remote} do res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 - res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") - - assert json_response(res_conn, :not_found) == %{ - "error" => "Can't find user" - } + assert %{"error" => "Can't find user"} == + conn + |> get("/api/v1/accounts/#{remote.id}/statuses") + |> json_response_and_validate_schema(:not_found) end test "if user is authenticated", %{local: local, remote: remote} do %{conn: conn} = oauth_access(["read"]) res_conn = get(conn, "/api/v1/accounts/#{local.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 res_conn = get(conn, "/api/v1/accounts/#{remote.id}/statuses") - assert length(json_response(res_conn, 200)) == 1 + assert length(json_response_and_validate_schema(res_conn, 200)) == 1 end end @@ -487,12 +477,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "getting followers", %{user: user, conn: conn} do other_user = insert(:user) - {:ok, user} = User.follow(user, other_user) + {:ok, %{id: user_id}} = User.follow(user, other_user) conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers") - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(user.id) + assert [%{"id" => ^user_id}] = json_response_and_validate_schema(conn, 200) end test "getting followers, hide_followers", %{user: user, conn: conn} do @@ -501,7 +490,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/#{other_user.id}/followers") - assert [] == json_response(conn, 200) + assert [] == json_response_and_validate_schema(conn, 200) end test "getting followers, hide_followers, same user requesting" do @@ -515,37 +504,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{other_user.id}/followers") - refute [] == json_response(conn, 200) + refute [] == json_response_and_validate_schema(conn, 200) end test "getting followers, pagination", %{user: user, conn: conn} do - follower1 = insert(:user) - follower2 = insert(:user) - follower3 = insert(:user) - {:ok, _} = User.follow(follower1, user) - {:ok, _} = User.follow(follower2, user) - {:ok, _} = User.follow(follower3, user) - - 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 + {:ok, %User{id: follower1_id}} = :user |> insert() |> User.follow(user) + {:ok, %User{id: follower2_id}} = :user |> insert() |> User.follow(user) + {:ok, %User{id: follower3_id}} = :user |> insert() |> User.follow(user) - res_conn = get(conn, "/api/v1/accounts/#{user.id}/followers?max_id=#{follower3.id}") + assert [%{"id" => ^follower3_id}, %{"id" => ^follower2_id}] = + conn + |> get("/api/v1/accounts/#{user.id}/followers?since_id=#{follower1_id}") + |> json_response_and_validate_schema(200) - assert [%{"id" => id2}, %{"id" => id1}] = json_response(res_conn, 200) - assert id2 == follower2.id - assert id1 == follower1.id + assert [%{"id" => ^follower2_id}, %{"id" => ^follower1_id}] = + conn + |> get("/api/v1/accounts/#{user.id}/followers?max_id=#{follower3_id}") + |> json_response_and_validate_schema(200) - res_conn = get(conn, "/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 + assert [%{"id" => ^follower2_id}] = json_response_and_validate_schema(res_conn, 200) assert [link_header] = get_resp_header(res_conn, "link") - assert link_header =~ ~r/min_id=#{follower2.id}/ - assert link_header =~ ~r/max_id=#{follower2.id}/ + assert link_header =~ ~r/min_id=#{follower2_id}/ + assert link_header =~ ~r/max_id=#{follower2_id}/ end end @@ -558,7 +541,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/#{user.id}/following") - assert [%{"id" => id}] = json_response(conn, 200) + assert [%{"id" => id}] = json_response_and_validate_schema(conn, 200) assert id == to_string(other_user.id) end @@ -573,7 +556,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.id}/following") - assert [] == json_response(conn, 200) + assert [] == json_response_and_validate_schema(conn, 200) end test "getting following, hide_follows, same user requesting" do @@ -587,7 +570,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> assign(:token, insert(:oauth_token, user: user, scopes: ["read:accounts"])) |> get("/api/v1/accounts/#{user.id}/following") - refute [] == json_response(conn, 200) + refute [] == json_response_and_validate_schema(conn, 200) end test "getting following, pagination", %{user: user, conn: conn} do @@ -600,20 +583,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do 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 [%{"id" => id3}, %{"id" => id2}] = json_response_and_validate_schema(res_conn, 200) assert id3 == following3.id assert id2 == following2.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 [%{"id" => id2}, %{"id" => id1}] = json_response_and_validate_schema(res_conn, 200) assert id2 == following2.id assert id1 == following1.id res_conn = get(conn, "/api/v1/accounts/#{user.id}/following?limit=1&max_id=#{following3.id}") - assert [%{"id" => id2}] = json_response(res_conn, 200) + assert [%{"id" => id2}] = json_response_and_validate_schema(res_conn, 200) assert id2 == following2.id assert [link_header] = get_resp_header(res_conn, "link") @@ -626,30 +609,37 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: oauth_access(["follow"]) test "following / unfollowing a user", %{conn: conn} do - other_user = insert(:user) - - ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/follow") - - assert %{"id" => _id, "following" => true} = json_response(ret_conn, 200) - - ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/unfollow") - - assert %{"id" => _id, "following" => false} = json_response(ret_conn, 200) - - conn = post(conn, "/api/v1/follows", %{"uri" => other_user.nickname}) - - assert %{"id" => id} = json_response(conn, 200) - assert id == to_string(other_user.id) + %{id: other_user_id, nickname: other_user_nickname} = insert(:user) + + assert %{"id" => _id, "following" => true} = + conn + |> post("/api/v1/accounts/#{other_user_id}/follow") + |> json_response_and_validate_schema(200) + + assert %{"id" => _id, "following" => false} = + conn + |> post("/api/v1/accounts/#{other_user_id}/unfollow") + |> json_response_and_validate_schema(200) + + assert %{"id" => ^other_user_id} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/follows", %{"uri" => other_user_nickname}) + |> json_response_and_validate_schema(200) 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) + conn + |> post("/api/v1/accounts/#{other_user_id}/follow") + |> json_response_and_validate_schema(:ok) assert %{"id" => ^other_user_id, "following" => false, "requested" => false} = - conn |> post("/api/v1/accounts/#{other_user_id}/unfollow") |> json_response(:ok) + conn + |> post("/api/v1/accounts/#{other_user_id}/unfollow") + |> json_response_and_validate_schema(:ok) end test "following without reblogs" do @@ -659,51 +649,65 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=false") - assert %{"showing_reblogs" => false} = json_response(ret_conn, 200) + assert %{"showing_reblogs" => false} = json_response_and_validate_schema(ret_conn, 200) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"}) - {:ok, reblog, _} = CommonAPI.repeat(activity.id, followed) - - ret_conn = get(conn, "/api/v1/timelines/home") - - assert [] == json_response(ret_conn, 200) - - ret_conn = post(conn, "/api/v1/accounts/#{followed.id}/follow?reblogs=true") - - assert %{"showing_reblogs" => true} = json_response(ret_conn, 200) - - conn = get(conn, "/api/v1/timelines/home") - - expected_activity_id = reblog.id - assert [%{"id" => ^expected_activity_id}] = json_response(conn, 200) + {:ok, %{id: reblog_id}, _} = CommonAPI.repeat(activity.id, followed) + + assert [] == + conn + |> get("/api/v1/timelines/home") + |> json_response(200) + + assert %{"showing_reblogs" => true} = + conn + |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true") + |> json_response_and_validate_schema(200) + + assert [%{"id" => ^reblog_id}] = + conn + |> get("/api/v1/timelines/home") + |> json_response(200) end 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) + + assert %{"error" => "Can not follow yourself"} = + json_response_and_validate_schema(conn_res, 400) # self unfollow user = User.get_cached_by_id(user.id) conn_res = post(conn, "/api/v1/accounts/#{user.id}/unfollow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + + assert %{"error" => "Can not unfollow yourself"} = + json_response_and_validate_schema(conn_res, 400) # self follow via uri user = User.get_cached_by_id(user.id) - conn_res = post(conn, "/api/v1/follows", %{"uri" => user.nickname}) - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + + assert %{"error" => "Can not follow yourself"} = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/follows", %{"uri" => user.nickname}) + |> json_response_and_validate_schema(400) # follow non existing user conn_res = post(conn, "/api/v1/accounts/doesntexist/follow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) # follow non existing user via uri - conn_res = post(conn, "/api/v1/follows", %{"uri" => "doesntexist"}) - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + conn_res = + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/follows", %{"uri" => "doesntexist"}) + + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) # unfollow non existing user conn_res = post(conn, "/api/v1/accounts/doesntexist/unfollow") - assert %{"error" => "Record not found"} = json_response(conn_res, 404) + assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404) end end @@ -713,32 +717,33 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do test "with notifications", %{conn: conn} do other_user = insert(:user) - ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/mute") - - response = json_response(ret_conn, 200) - - assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = response + assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{other_user.id}/mute") + |> json_response_and_validate_schema(200) conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute") - response = json_response(conn, 200) - assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response + assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = + json_response_and_validate_schema(conn, 200) end test "without notifications", %{conn: conn} do other_user = insert(:user) ret_conn = - post(conn, "/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) - - response = json_response(ret_conn, 200) + conn + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts/#{other_user.id}/mute", %{"notifications" => "false"}) - assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = response + assert %{"id" => _id, "muting" => true, "muting_notifications" => false} = + json_response_and_validate_schema(ret_conn, 200) conn = post(conn, "/api/v1/accounts/#{other_user.id}/unmute") - response = json_response(conn, 200) - assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = response + assert %{"id" => _id, "muting" => false, "muting_notifications" => false} = + json_response_and_validate_schema(conn, 200) end end @@ -751,17 +756,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do [conn: conn, user: user, activity: activity] end - test "returns pinned statuses", %{conn: conn, user: user, activity: activity} do - {:ok, _} = CommonAPI.pin(activity.id, user) - - result = - conn - |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") - |> json_response(200) - - id_str = to_string(activity.id) + test "returns pinned statuses", %{conn: conn, user: user, activity: %{id: activity_id}} do + {:ok, _} = CommonAPI.pin(activity_id, user) - assert [%{"id" => ^id_str, "pinned" => true}] = result + assert [%{"id" => ^activity_id, "pinned" => true}] = + conn + |> get("/api/v1/accounts/#{user.id}/statuses?pinned=true") + |> json_response_and_validate_schema(200) end end @@ -771,11 +772,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do ret_conn = post(conn, "/api/v1/accounts/#{other_user.id}/block") - assert %{"id" => _id, "blocking" => true} = json_response(ret_conn, 200) + assert %{"id" => _id, "blocking" => true} = json_response_and_validate_schema(ret_conn, 200) conn = post(conn, "/api/v1/accounts/#{other_user.id}/unblock") - assert %{"id" => _id, "blocking" => false} = json_response(conn, 200) + assert %{"id" => _id, "blocking" => false} = json_response_and_validate_schema(conn, 200) end describe "create account by app" do @@ -802,15 +803,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do scopes: "read, write, follow" }) - %{ - "client_id" => client_id, - "client_secret" => client_secret, - "id" => _, - "name" => "client_name", - "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob", - "vapid_key" => _, - "website" => nil - } = json_response(conn, 200) + assert %{ + "client_id" => client_id, + "client_secret" => client_secret, + "id" => _, + "name" => "client_name", + "redirect_uri" => "urn:ietf:wg:oauth:2.0:oob", + "vapid_key" => _, + "website" => nil + } = json_response_and_validate_schema(conn, 200) conn = post(conn, "/oauth/token", %{ @@ -830,6 +831,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = build_conn() + |> put_req_header("content-type", "multipart/form-data") |> put_req_header("authorization", "Bearer " <> token) |> post("/api/v1/accounts", %{ username: "lain", @@ -844,7 +846,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do "created_at" => _created_at, "scope" => _scope, "token_type" => "Bearer" - } = json_response(conn, 200) + } = json_response_and_validate_schema(conn, 200) token_from_db = Repo.get_by(Token, token: token) assert token_from_db @@ -858,12 +860,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do _user = insert(:user, email: "lain@example.org") app_token = insert(:oauth_token, user: nil) - conn = + res = conn |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts", valid_params) - res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"} + assert json_response_and_validate_schema(res, 400) == %{ + "error" => "{\"email\":[\"has already been taken\"]}" + } end test "returns bad_request if missing required params", %{ @@ -872,10 +877,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do } do app_token = insert(:oauth_token, user: nil) - conn = put_req_header(conn, "authorization", "Bearer " <> app_token.token) + conn = + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "application/json") res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 200) + assert json_response_and_validate_schema(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)) @@ -884,9 +892,18 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn |> Map.put(:remote_ip, ip) |> post("/api/v1/accounts", Map.delete(valid_params, attr)) - |> json_response(400) - - assert res == %{"error" => "Missing parameters"} + |> json_response_and_validate_schema(400) + + assert res == %{ + "error" => "Missing field: #{attr}.", + "errors" => [ + %{ + "message" => "Missing field: #{attr}", + "source" => %{"pointer" => "/#{attr}"}, + "title" => "Invalid value" + } + ] + } end) end @@ -897,21 +914,28 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest 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) + + conn = + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "application/json") 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"} + assert json_response_and_validate_schema(res, 400) == + %{"error" => "Missing parameter: email"} 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\"]}"} + assert json_response_and_validate_schema(res, 400) == %{ + "error" => "{\"email\":[\"can't be blank\"]}" + } end test "allow registration without an email", %{conn: conn, valid_params: valid_params} do @@ -920,10 +944,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do res = conn + |> put_req_header("content-type", "application/json") |> Map.put(:remote_ip, {127, 0, 0, 7}) |> post("/api/v1/accounts", Map.delete(valid_params, :email)) - assert json_response(res, 200) + assert json_response_and_validate_schema(res, 200) end test "allow registration with an empty email", %{conn: conn, valid_params: valid_params} do @@ -932,17 +957,89 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do res = conn + |> put_req_header("content-type", "application/json") |> Map.put(:remote_ip, {127, 0, 0, 8}) |> post("/api/v1/accounts", Map.put(valid_params, :email, "")) - assert json_response(res, 200) + assert json_response_and_validate_schema(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 = + conn + |> put_req_header("authorization", "Bearer " <> "invalid-token") + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts", valid_params) - res = post(conn, "/api/v1/accounts", valid_params) - assert json_response(res, 403) == %{"error" => "Invalid credentials"} + assert json_response_and_validate_schema(res, 403) == %{"error" => "Invalid credentials"} + end + + test "registration from trusted app" do + clear_config([Pleroma.Captcha, :enabled], true) + app = insert(:oauth_app, trusted: true, scopes: ["read", "write", "follow", "push"]) + + conn = + build_conn() + |> post("/oauth/token", %{ + "grant_type" => "client_credentials", + "client_id" => app.client_id, + "client_secret" => app.client_secret + }) + + assert %{"access_token" => token, "token_type" => "Bearer"} = json_response(conn, 200) + + response = + build_conn() + |> Plug.Conn.put_req_header("authorization", "Bearer " <> token) + |> put_req_header("content-type", "multipart/form-data") + |> post("/api/v1/accounts", %{ + nickname: "nickanme", + agreement: true, + email: "email@example.com", + fullname: "Lain", + username: "Lain", + password: "some_password", + confirm: "some_password" + }) + |> json_response_and_validate_schema(200) + + assert %{ + "access_token" => access_token, + "created_at" => _, + "scope" => ["read", "write", "follow", "push"], + "token_type" => "Bearer" + } = response + + response = + build_conn() + |> Plug.Conn.put_req_header("authorization", "Bearer " <> access_token) + |> get("/api/v1/accounts/verify_credentials") + |> json_response_and_validate_schema(200) + + assert %{ + "acct" => "Lain", + "bot" => false, + "display_name" => "Lain", + "follow_requests_count" => 0, + "followers_count" => 0, + "following_count" => 0, + "locked" => false, + "note" => "", + "source" => %{ + "fields" => [], + "note" => "", + "pleroma" => %{ + "actor_type" => "Person", + "discoverable" => false, + "no_rich_text" => false, + "show_role" => true + }, + "privacy" => "public", + "sensitive" => false + }, + "statuses_count" => 0, + "username" => "Lain" + } = response end end @@ -956,10 +1053,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn |> put_req_header("authorization", "Bearer " <> app_token.token) |> Map.put(:remote_ip, {15, 15, 15, 15}) + |> put_req_header("content-type", "multipart/form-data") for i <- 1..2 do conn = - post(conn, "/api/v1/accounts", %{ + conn + |> post("/api/v1/accounts", %{ username: "#{i}lain", email: "#{i}lain@example.org", password: "PlzDontHackLain", @@ -971,7 +1070,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do "created_at" => _created_at, "scope" => _scope, "token_type" => "Bearer" - } = json_response(conn, 200) + } = json_response_and_validate_schema(conn, 200) token_from_db = Repo.get_by(Token, token: token) assert token_from_db @@ -989,7 +1088,94 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do agreement: true }) - assert json_response(conn, :too_many_requests) == %{"error" => "Throttled"} + assert json_response_and_validate_schema(conn, :too_many_requests) == %{ + "error" => "Throttled" + } + end + end + + describe "create account with enabled captcha" do + setup %{conn: conn} do + app_token = insert(:oauth_token, user: nil) + + conn = + conn + |> put_req_header("authorization", "Bearer " <> app_token.token) + |> put_req_header("content-type", "multipart/form-data") + + [conn: conn] + end + + setup do: clear_config([Pleroma.Captcha, :enabled], true) + + test "creates an account and returns 200 if captcha is valid", %{conn: conn} do + %{token: token, answer_data: answer_data} = Pleroma.Captcha.new() + + params = %{ + username: "lain", + email: "lain@example.org", + password: "PlzDontHackLain", + agreement: true, + captcha_solution: Pleroma.Captcha.Mock.solution(), + captcha_token: token, + captcha_answer_data: answer_data + } + + assert %{ + "access_token" => access_token, + "created_at" => _, + "scope" => ["read"], + "token_type" => "Bearer" + } = + conn + |> post("/api/v1/accounts", params) + |> json_response_and_validate_schema(:ok) + + assert Token |> Repo.get_by(token: access_token) |> Repo.preload(:user) |> Map.get(:user) + + Cachex.del(:used_captcha_cache, token) + end + + test "returns 400 if any captcha field is not provided", %{conn: conn} do + captcha_fields = [:captcha_solution, :captcha_token, :captcha_answer_data] + + valid_params = %{ + username: "lain", + email: "lain@example.org", + password: "PlzDontHackLain", + agreement: true, + captcha_solution: "xx", + captcha_token: "xx", + captcha_answer_data: "xx" + } + + for field <- captcha_fields do + expected = %{ + "error" => "{\"captcha\":[\"Invalid CAPTCHA (Missing parameter: #{field})\"]}" + } + + assert expected == + conn + |> post("/api/v1/accounts", Map.delete(valid_params, field)) + |> json_response_and_validate_schema(:bad_request) + end + end + + test "returns an error if captcha is invalid", %{conn: conn} do + params = %{ + username: "lain", + email: "lain@example.org", + password: "PlzDontHackLain", + agreement: true, + captcha_solution: "cofe", + captcha_token: "cofe", + captcha_answer_data: "cofe" + } + + assert %{"error" => "{\"captcha\":[\"Invalid answer data\"]}"} == + conn + |> post("/api/v1/accounts", params) + |> json_response_and_validate_schema(:bad_request) end end @@ -997,15 +1183,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do 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) + assert {:ok, %Pleroma.List{id: list_id} = list} = Pleroma.List.create("Test List", user) {:ok, %{following: _following}} = Pleroma.List.follow(list, other_user) - res = - conn - |> get("/api/v1/accounts/#{other_user.id}/lists") - |> json_response(200) - - assert res == [%{"id" => to_string(list.id), "title" => "Test List"}] + assert [%{"id" => list_id, "title" => "Test List"}] = + conn + |> get("/api/v1/accounts/#{other_user.id}/lists") + |> json_response_and_validate_schema(200) end end @@ -1014,7 +1198,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do %{user: user, conn: conn} = oauth_access(["read:accounts"]) conn = get(conn, "/api/v1/accounts/verify_credentials") - response = json_response(conn, 200) + response = json_response_and_validate_schema(conn, 200) assert %{"id" => id, "source" => %{"privacy" => "public"}} = response assert response["pleroma"]["chat_token"] @@ -1027,7 +1211,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/verify_credentials") - assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = json_response(conn, 200) + assert %{"id" => id, "source" => %{"privacy" => "unlisted"}} = + json_response_and_validate_schema(conn, 200) + assert id == to_string(user.id) end @@ -1037,7 +1223,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/accounts/verify_credentials") - assert %{"id" => id, "source" => %{"privacy" => "private"}} = json_response(conn, 200) + assert %{"id" => id, "source" => %{"privacy" => "private"}} = + json_response_and_validate_schema(conn, 200) + assert id == to_string(user.id) end end @@ -1046,20 +1234,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do setup do: oauth_access(["read:follows"]) test "returns the relationships for the current user", %{user: user, conn: conn} do - other_user = insert(:user) + %{id: other_user_id} = other_user = insert(:user) {:ok, _user} = User.follow(user, other_user) - conn = get(conn, "/api/v1/accounts/relationships", %{"id" => [other_user.id]}) - - assert [relationship] = json_response(conn, 200) + assert [%{"id" => ^other_user_id}] = + conn + |> get("/api/v1/accounts/relationships?id=#{other_user.id}") + |> json_response_and_validate_schema(200) - assert to_string(other_user.id) == relationship["id"] + assert [%{"id" => ^other_user_id}] = + conn + |> get("/api/v1/accounts/relationships?id[]=#{other_user.id}") + |> json_response_and_validate_schema(200) end test "returns an empty list on a bad request", %{conn: conn} do conn = get(conn, "/api/v1/accounts/relationships", %{}) - assert [] = json_response(conn, 200) + assert [] = json_response_and_validate_schema(conn, 200) end end @@ -1072,7 +1264,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do conn = get(conn, "/api/v1/mutes") other_user_id = to_string(other_user.id) - assert [%{"id" => ^other_user_id}] = json_response(conn, 200) + assert [%{"id" => ^other_user_id}] = json_response_and_validate_schema(conn, 200) end test "getting a list of blocks" do @@ -1087,6 +1279,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do |> get("/api/v1/blocks") other_user_id = to_string(other_user.id) - assert [%{"id" => ^other_user_id}] = json_response(conn, 200) + assert [%{"id" => ^other_user_id}] = json_response_and_validate_schema(conn, 200) end end diff --git a/test/web/mastodon_api/controllers/app_controller_test.exs b/test/web/mastodon_api/controllers/app_controller_test.exs index e7b11d14e..a0b8b126c 100644 --- a/test/web/mastodon_api/controllers/app_controller_test.exs +++ b/test/web/mastodon_api/controllers/app_controller_test.exs @@ -27,7 +27,7 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key) } - assert expected == json_response(conn, 200) + assert expected == json_response_and_validate_schema(conn, 200) end test "creates an oauth app", %{conn: conn} do @@ -55,6 +55,6 @@ defmodule Pleroma.Web.MastodonAPI.AppControllerTest do "vapid_key" => Push.vapid_config() |> Keyword.get(:public_key) } - assert expected == json_response(conn, 200) + assert expected == json_response_and_validate_schema(conn, 200) end 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 6567a0667..ab0027f90 100644 --- a/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs +++ b/test/web/mastodon_api/controllers/custom_emoji_controller_test.exs @@ -6,11 +6,12 @@ defmodule Pleroma.Web.MastodonAPI.CustomEmojiControllerTest do use Pleroma.Web.ConnCase, async: true test "with tags", %{conn: conn} do - [emoji | _body] = - conn - |> get("/api/v1/custom_emojis") - |> json_response(200) + assert resp = + conn + |> get("/api/v1/custom_emojis") + |> json_response_and_validate_schema(200) + assert [emoji | _body] = resp assert Map.has_key?(emoji, "shortcode") assert Map.has_key?(emoji, "static_url") assert Map.has_key?(emoji, "tags") 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 8d24b3b88..01a24afcf 100644 --- a/test/web/mastodon_api/controllers/domain_block_controller_test.exs +++ b/test/web/mastodon_api/controllers/domain_block_controller_test.exs @@ -13,15 +13,21 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do %{user: user, conn: conn} = oauth_access(["write:blocks"]) other_user = insert(:user, %{ap_id: "https://dogwhistle.zone/@pundit"}) - ret_conn = post(conn, "/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) + ret_conn = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) - assert %{} = json_response(ret_conn, 200) + assert %{} == json_response_and_validate_schema(ret_conn, 200) user = User.get_cached_by_ap_id(user.ap_id) assert User.blocks?(user, other_user) - ret_conn = delete(conn, "/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) + ret_conn = + conn + |> put_req_header("content-type", "application/json") + |> delete("/api/v1/domain_blocks", %{"domain" => "dogwhistle.zone"}) - assert %{} = json_response(ret_conn, 200) + assert %{} == json_response_and_validate_schema(ret_conn, 200) user = User.get_cached_by_ap_id(user.ap_id) refute User.blocks?(user, other_user) end @@ -32,14 +38,10 @@ defmodule Pleroma.Web.MastodonAPI.DomainBlockControllerTest do {:ok, user} = User.block_domain(user, "bad.site") {:ok, user} = User.block_domain(user, "even.worse.site") - conn = - conn - |> assign(:user, user) - |> get("/api/v1/domain_blocks") - - domain_blocks = json_response(conn, 200) - - assert "bad.site" in domain_blocks - assert "even.worse.site" in domain_blocks + assert ["even.worse.site", "bad.site"] == + conn + |> assign(:user, user) + |> get("/api/v1/domain_blocks") + |> json_response_and_validate_schema(200) end end diff --git a/test/web/mastodon_api/controllers/notification_controller_test.exs b/test/web/mastodon_api/controllers/notification_controller_test.exs index 1557937d8..8c815b415 100644 --- a/test/web/mastodon_api/controllers/notification_controller_test.exs +++ b/test/web/mastodon_api/controllers/notification_controller_test.exs @@ -12,6 +12,26 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do import Pleroma.Factory + test "does NOT render account/pleroma/relationship if this is disabled by default" do + clear_config([:extensions, :output_relationships_in_statuses_by_default], false) + + %{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) + + response = + conn + |> assign(:user, user) + |> get("/api/v1/notifications") + |> json_response(200) + + assert Enum.all?(response, fn n -> + get_in(n, ["account", "pleroma", "relationship"]) == %{} + end) + end + test "list of notifications" do %{user: user, conn: conn} = oauth_access(["read:notifications"]) other_user = insert(:user) diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index cd9ca4973..85068edd0 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -302,6 +302,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert [] == Repo.all(Activity) end + test "ignores nil values", %{conn: conn} do + conn = + post(conn, "/api/v1/statuses", %{ + "status" => "not scheduled", + "scheduled_at" => nil + }) + + assert result = json_response(conn, 200) + assert Activity.get_by_id(result["id"]) + end + 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) @@ -1047,6 +1058,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do end test "bookmarks" do + bookmarks_uri = "/api/v1/bookmarks?with_relationships=true" + %{conn: conn} = oauth_access(["write:bookmarks", "read:bookmarks"]) author = insert(:user) @@ -1068,7 +1081,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert json_response(response2, 200)["bookmarked"] == true - bookmarks = get(conn, "/api/v1/bookmarks") + bookmarks = get(conn, bookmarks_uri) assert [json_response(response2, 200), json_response(response1, 200)] == json_response(bookmarks, 200) @@ -1077,7 +1090,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert json_response(response1, 200)["bookmarked"] == false - bookmarks = get(conn, "/api/v1/bookmarks") + bookmarks = get(conn, bookmarks_uri) assert [json_response(response2, 200)] == json_response(bookmarks, 200) end diff --git a/test/web/mastodon_api/controllers/subscription_controller_test.exs b/test/web/mastodon_api/controllers/subscription_controller_test.exs index 987158a74..5682498c0 100644 --- a/test/web/mastodon_api/controllers/subscription_controller_test.exs +++ b/test/web/mastodon_api/controllers/subscription_controller_test.exs @@ -35,7 +35,10 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do quote do vapid_details = Application.get_env(:web_push_encryption, :vapid_details, []) Application.put_env(:web_push_encryption, :vapid_details, []) - assert "Something went wrong" == unquote(yield) + + assert %{"error" => "Web push subscription is disabled on this Pleroma instance"} == + unquote(yield) + Application.put_env(:web_push_encryption, :vapid_details, vapid_details) end end @@ -45,7 +48,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> post("/api/v1/push/subscription", %{}) - |> json_response(500) + |> json_response(403) end end @@ -74,7 +77,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> get("/api/v1/push/subscription", %{}) - |> json_response(500) + |> json_response(403) end end @@ -127,7 +130,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}}) - |> json_response(500) + |> json_response(403) end end @@ -155,7 +158,7 @@ defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do assert_error_when_disable_push do conn |> delete("/api/v1/push/subscription", %{}) - |> json_response(500) + |> json_response(403) end end diff --git a/test/web/mastodon_api/controllers/suggestion_controller_test.exs b/test/web/mastodon_api/controllers/suggestion_controller_test.exs index c697a39f8..8d0e70db8 100644 --- a/test/web/mastodon_api/controllers/suggestion_controller_test.exs +++ b/test/web/mastodon_api/controllers/suggestion_controller_test.exs @@ -7,34 +7,8 @@ defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do alias Pleroma.Config - import Pleroma.Factory - import Tesla.Mock - 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}" - url200 = "http://test200?#{host}&#{user.nickname}" - - mock(fn - %{method: :get, url: ^url500} -> - %Tesla.Env{status: 500, body: "bad request"} - - %{method: :get, url: ^url200} -> - %Tesla.Env{ - status: 200, - body: - ~s([{"acct":"yj455","avatar":"https://social.heldscal.la/avatar/201.jpeg","avatar_static":"https://social.heldscal.la/avatar/s/201.jpeg"}, {"acct":"#{ - other_user.ap_id - }","avatar":"https://social.heldscal.la/avatar/202.jpeg","avatar_static":"https://social.heldscal.la/avatar/s/202.jpeg"}]) - } - end) - - [other_user: other_user] - end - test "returns empty result", %{conn: conn} do res = conn diff --git a/test/web/mastodon_api/controllers/timeline_controller_test.exs b/test/web/mastodon_api/controllers/timeline_controller_test.exs index 97b1c3e66..06efdc901 100644 --- a/test/web/mastodon_api/controllers/timeline_controller_test.exs +++ b/test/web/mastodon_api/controllers/timeline_controller_test.exs @@ -20,7 +20,30 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do describe "home" do setup do: oauth_access(["read:statuses"]) + test "does NOT render account/pleroma/relationship if this is disabled by default", %{ + user: user, + conn: conn + } do + clear_config([:extensions, :output_relationships_in_statuses_by_default], false) + + other_user = insert(:user) + + {:ok, _} = CommonAPI.post(other_user, %{"status" => "hi @#{user.nickname}"}) + + response = + conn + |> assign(:user, user) + |> get("/api/v1/timelines/home") + |> json_response(200) + + assert Enum.all?(response, fn n -> + get_in(n, ["account", "pleroma", "relationship"]) == %{} + end) + end + test "the home timeline", %{user: user, conn: conn} do + uri = "/api/v1/timelines/home?with_relationships=true" + following = insert(:user, nickname: "followed") third_user = insert(:user, nickname: "repeated") @@ -28,13 +51,13 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do {:ok, activity} = CommonAPI.post(third_user, %{"status" => "repeated post"}) {:ok, _, _} = CommonAPI.repeat(activity.id, following) - ret_conn = get(conn, "/api/v1/timelines/home") + ret_conn = get(conn, uri) assert Enum.empty?(json_response(ret_conn, :ok)) {:ok, _user} = User.follow(user, following) - ret_conn = get(conn, "/api/v1/timelines/home") + ret_conn = get(conn, uri) assert [ %{ @@ -59,7 +82,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do {:ok, _user} = User.follow(third_user, user) - ret_conn = get(conn, "/api/v1/timelines/home") + ret_conn = get(conn, uri) assert [ %{ diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 75f184242..bb4bc4396 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -7,35 +7,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do describe "empty_array/2 (stubs)" do test "GET /api/v1/accounts/:id/identity_proofs" do - %{user: user, conn: conn} = oauth_access(["n/a"]) + %{user: user, conn: conn} = oauth_access(["read:accounts"]) - res = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/#{user.id}/identity_proofs") - |> json_response(200) - - assert res == [] + assert [] == + conn + |> get("/api/v1/accounts/#{user.id}/identity_proofs") + |> json_response(200) end test "GET /api/v1/endorsements" do %{conn: conn} = oauth_access(["read:accounts"]) - res = - conn - |> get("/api/v1/endorsements") - |> json_response(200) - - assert res == [] + assert [] == + conn + |> get("/api/v1/endorsements") + |> json_response(200) end test "GET /api/v1/trends", %{conn: conn} do - res = - conn - |> get("/api/v1/trends") - |> json_response(200) - - assert res == [] + assert [] == + conn + |> get("/api/v1/trends") + |> json_response(200) end end end diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs index 4435f69ff..85fa4f6a2 100644 --- a/test/web/mastodon_api/views/account_view_test.exs +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -19,16 +19,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do end test "Represent a user account" do - source_data = %{ - "tag" => [ - %{ - "type" => "Emoji", - "icon" => %{"url" => "/file.png"}, - "name" => ":karjalanpiirakka:" - } - ] - } - background_image = %{ "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}] } @@ -37,13 +27,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 3, note_count: 5, - source_data: source_data, background: background_image, nickname: "shp@shitposter.club", name: ":karjalanpiirakka: shp", bio: "<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f", - inserted_at: ~N[2017-08-15 15:47:06.597036] + inserted_at: ~N[2017-08-15 15:47:06.597036], + emoji: %{"karjalanpiirakka" => "/file.png"} }) expected = %{ @@ -117,7 +107,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 3, note_count: 5, - source_data: %{}, actor_type: "Service", nickname: "shp@shitposter.club", inserted_at: ~N[2017-08-15 15:47:06.597036] @@ -311,7 +300,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do insert(:user, %{ follower_count: 0, note_count: 5, - source_data: %{}, actor_type: "Service", nickname: "shp@shitposter.club", inserted_at: ~N[2017-08-15 15:47:06.597036] diff --git a/test/web/mastodon_api/views/poll_view_test.exs b/test/web/mastodon_api/views/poll_view_test.exs index 6211fa888..63b204387 100644 --- a/test/web/mastodon_api/views/poll_view_test.exs +++ b/test/web/mastodon_api/views/poll_view_test.exs @@ -43,7 +43,8 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do %{title: "why are you even asking?", votes_count: 0} ], voted: false, - votes_count: 0 + votes_count: 0, + voters_count: nil } result = PollView.render("show.json", %{object: object}) @@ -69,9 +70,20 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do } }) + voter = insert(:user) + object = Object.normalize(activity) - assert %{multiple: true} = PollView.render("show.json", %{object: object}) + {:ok, _votes, object} = CommonAPI.vote(voter, object, [0, 1]) + + assert match?( + %{ + multiple: true, + voters_count: 1, + votes_count: 2 + }, + PollView.render("show.json", %{object: object}) + ) end test "detects emoji" do diff --git a/test/web/mastodon_api/views/push_subscription_view_test.exs b/test/web/mastodon_api/views/subscription_view_test.exs index 10c6082a5..981524c0e 100644 --- a/test/web/mastodon_api/views/push_subscription_view_test.exs +++ b/test/web/mastodon_api/views/subscription_view_test.exs @@ -2,10 +2,10 @@ # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do +defmodule Pleroma.Web.MastodonAPI.SubscriptionViewTest do use Pleroma.DataCase import Pleroma.Factory - alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View + alias Pleroma.Web.MastodonAPI.SubscriptionView, as: View alias Pleroma.Web.Push test "Represent a subscription" do @@ -18,6 +18,6 @@ defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do server_key: Keyword.get(Push.vapid_config(), :public_key) } - assert expected == View.render("push_subscription.json", %{subscription: subscription}) + assert expected == View.render("show.json", %{subscription: subscription}) end end diff --git a/test/web/mongooseim/mongoose_im_controller_test.exs b/test/web/mongooseim/mongoose_im_controller_test.exs index 291ae54fc..1ac2f2c27 100644 --- a/test/web/mongooseim/mongoose_im_controller_test.exs +++ b/test/web/mongooseim/mongoose_im_controller_test.exs @@ -9,6 +9,7 @@ defmodule Pleroma.Web.MongooseIMController do test "/user_exists", %{conn: conn} do _user = insert(:user, nickname: "lain") _remote_user = insert(:user, nickname: "alice", local: false) + _deactivated_user = insert(:user, nickname: "konata", deactivated: true) res = conn @@ -30,11 +31,25 @@ defmodule Pleroma.Web.MongooseIMController do |> json_response(404) assert res == false + + res = + conn + |> get(mongoose_im_path(conn, :user_exists), user: "konata") + |> json_response(404) + + assert res == false end test "/check_password", %{conn: conn} do user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt("cool")) + _deactivated_user = + insert(:user, + nickname: "konata", + deactivated: true, + password_hash: Comeonin.Pbkdf2.hashpwsalt("cool") + ) + res = conn |> get(mongoose_im_path(conn, :check_password), user: user.nickname, pass: "cool") @@ -51,6 +66,13 @@ defmodule Pleroma.Web.MongooseIMController do res = conn + |> get(mongoose_im_path(conn, :check_password), user: "konata", pass: "cool") + |> json_response(404) + + assert res == false + + res = + conn |> get(mongoose_im_path(conn, :check_password), user: "nobody", pass: "cool") |> json_response(404) diff --git a/test/web/pleroma_api/controllers/account_controller_test.exs b/test/web/pleroma_api/controllers/account_controller_test.exs index ae5334015..6b671a667 100644 --- a/test/web/pleroma_api/controllers/account_controller_test.exs +++ b/test/web/pleroma_api/controllers/account_controller_test.exs @@ -151,15 +151,18 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do assert like["id"] == activity.id end - test "does not return favorites for specified user_id when user is not logged in", %{ + test "returns favorites for specified user_id when requester is not logged in", %{ user: user } do activity = insert(:note_activity) CommonAPI.favorite(user, activity.id) - build_conn() - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") - |> json_response(403) + response = + build_conn() + |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") + |> json_response(200) + + assert length(response) == 1 end test "returns favorited DM only when user is logged in and he is one of recipients", %{ @@ -185,9 +188,12 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do assert length(response) == 1 end - build_conn() - |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") - |> json_response(403) + response = + build_conn() + |> get("/api/v1/pleroma/accounts/#{user.id}/favourites") + |> json_response(200) + + assert length(response) == 0 end test "does not return others' favorited DM when user is not one of recipients", %{ 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 435fb6592..d343256fe 100644 --- a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/emoji_api_controller_test.exs @@ -8,213 +8,298 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do import Tesla.Mock import Pleroma.Factory - @emoji_dir_path Path.join( - Pleroma.Config.get!([:instance, :static_dir]), - "emoji" - ) + @emoji_path Path.join( + Pleroma.Config.get!([:instance, :static_dir]), + "emoji" + ) setup do: clear_config([:auth, :enforce_oauth_admin_scope_usage], false) - 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) - - assert Map.has_key?(resp, "test_pack") + setup do + admin = insert(:user, is_admin: true) + token = insert(:oauth_admin_token, user: admin) - pack = resp["test_pack"] + admin_conn = + build_conn() + |> assign(:user, admin) + |> assign(:token, token) - assert Map.has_key?(pack["pack"], "download-sha256") - assert pack["pack"]["can-download"] + Pleroma.Emoji.reload() + {:ok, %{admin_conn: admin_conn}} + end - assert pack["files"] == %{"blank" => "blank.png"} + test "GET /api/pleroma/emoji/packs", %{conn: conn} do + resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) - # Non-shared pack + shared = resp["test_pack"] + assert shared["files"] == %{"blank" => "blank.png"} + assert Map.has_key?(shared["pack"], "download-sha256") + assert shared["pack"]["can-download"] + assert shared["pack"]["share-files"] - assert Map.has_key?(resp, "test_pack_nonshared") + non_shared = resp["test_pack_nonshared"] + assert non_shared["pack"]["share-files"] == false + assert non_shared["pack"]["can-download"] == false + end - pack = resp["test_pack_nonshared"] + describe "GET /api/pleroma/emoji/packs/remote" do + test "shareable instance", %{admin_conn: admin_conn, conn: conn} do + resp = + conn + |> get("/api/pleroma/emoji/packs") + |> json_response(200) - refute pack["pack"]["shared"] - refute pack["pack"]["can-download"] - end + mock(fn + %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> + json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) - test "listing remote packs" do - admin = insert(:user, is_admin: true) - %{conn: conn} = oauth_access(["admin:write"], user: admin) + %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> + json(%{metadata: %{features: ["shareable_emoji_packs"]}}) - resp = - build_conn() - |> get(emoji_api_path(conn, :list_packs)) - |> json_response(200) + %{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} -> + json(resp) + end) - mock(fn - %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> - json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) + assert admin_conn + |> get("/api/pleroma/emoji/packs/remote", %{ + url: "https://example.com" + }) + |> json_response(200) == resp + end - %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> - json(%{metadata: %{features: ["shareable_emoji_packs"]}}) + test "non shareable instance", %{admin_conn: admin_conn} do + mock(fn + %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> + json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) - %{method: :get, url: "https://example.com/api/pleroma/emoji/packs"} -> - json(resp) - end) + %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> + json(%{metadata: %{features: []}}) + end) - assert conn - |> post(emoji_api_path(conn, :list_from), %{instance_address: "https://example.com"}) - |> json_response(200) == resp + assert admin_conn + |> get("/api/pleroma/emoji/packs/remote", %{url: "https://example.com"}) + |> json_response(500) == %{ + "error" => "The requested instance does not support sharing emoji packs" + } + end end - test "downloading a shared pack from download_shared" do - conn = build_conn() + describe "GET /api/pleroma/emoji/packs/:name/archive" do + test "download shared pack", %{conn: conn} do + resp = + conn + |> get("/api/pleroma/emoji/packs/test_pack/archive") + |> response(200) + + {:ok, arch} = :zip.unzip(resp, [:memory]) - resp = - conn - |> get(emoji_api_path(conn, :download_shared, "test_pack")) - |> response(200) + assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end) + assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end) + end - {:ok, arch} = :zip.unzip(resp, [:memory]) + test "non existing pack", %{conn: conn} do + assert conn + |> get("/api/pleroma/emoji/packs/test_pack_for_import/archive") + |> json_response(:not_found) == %{ + "error" => "Pack test_pack_for_import does not exist" + } + end - assert Enum.find(arch, fn {n, _} -> n == 'pack.json' end) - assert Enum.find(arch, fn {n, _} -> n == 'blank.png' end) + test "non downloadable pack", %{conn: conn} do + assert conn + |> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive") + |> json_response(:forbidden) == %{ + "error" => + "Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing" + } + end end - test "downloading shared & unshared packs from another instance via download_from, deleting them" do - on_exit(fn -> - File.rm_rf!("#{@emoji_dir_path}/test_pack2") - File.rm_rf!("#{@emoji_dir_path}/test_pack_nonshared2") - end) + describe "POST /api/pleroma/emoji/packs/download" do + test "shared pack from remote and non shared from fallback-src", %{ + admin_conn: admin_conn, + conn: conn + } do + mock(fn + %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> + json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) - mock(fn - %{method: :get, url: "https://old-instance/.well-known/nodeinfo"} -> - json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]}) + %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> + json(%{metadata: %{features: ["shareable_emoji_packs"]}}) - %{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} -> - json(%{metadata: %{features: []}}) + %{ + method: :get, + url: "https://example.com/api/pleroma/emoji/packs/test_pack" + } -> + conn + |> get("/api/pleroma/emoji/packs/test_pack") + |> json_response(200) + |> json() - %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> - json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) + %{ + method: :get, + url: "https://example.com/api/pleroma/emoji/packs/test_pack/archive" + } -> + conn + |> get("/api/pleroma/emoji/packs/test_pack/archive") + |> response(200) + |> text() - %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> - json(%{metadata: %{features: ["shareable_emoji_packs"]}}) + %{ + method: :get, + url: "https://example.com/api/pleroma/emoji/packs/test_pack_nonshared" + } -> + conn + |> get("/api/pleroma/emoji/packs/test_pack_nonshared") + |> json_response(200) + |> json() - %{ - method: :get, - url: "https://example.com/api/pleroma/emoji/packs/list" - } -> - conn = build_conn() + %{ + method: :get, + url: "https://nonshared-pack" + } -> + text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip")) + end) - conn - |> get(emoji_api_path(conn, :list_packs)) - |> json_response(200) - |> json() + assert admin_conn + |> post("/api/pleroma/emoji/packs/download", %{ + url: "https://example.com", + name: "test_pack", + as: "test_pack2" + }) + |> json_response(200) == "ok" - %{ - method: :get, - url: "https://example.com/api/pleroma/emoji/packs/download_shared/test_pack" - } -> - conn = build_conn() + assert File.exists?("#{@emoji_path}/test_pack2/pack.json") + assert File.exists?("#{@emoji_path}/test_pack2/blank.png") - conn - |> get(emoji_api_path(conn, :download_shared, "test_pack")) - |> response(200) - |> text() + assert admin_conn + |> delete("/api/pleroma/emoji/packs/test_pack2") + |> json_response(200) == "ok" - %{ - method: :get, - url: "https://nonshared-pack" - } -> - text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip")) - end) + refute File.exists?("#{@emoji_path}/test_pack2") - admin = insert(:user, is_admin: true) + assert admin_conn + |> post( + "/api/pleroma/emoji/packs/download", + %{ + url: "https://example.com", + name: "test_pack_nonshared", + as: "test_pack_nonshared2" + } + ) + |> json_response(200) == "ok" - 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") - |> post( - emoji_api_path( - conn, - :download_from - ), - %{ - instance_address: "https://old-instance", - pack_name: "test_pack", - as: "test_pack2" - } - |> Jason.encode!() - ) - |> json_response(500))["error"] =~ "does not support" - - assert conn - |> put_req_header("content-type", "application/json") - |> post( - emoji_api_path( - conn, - :download_from - ), - %{ - instance_address: "https://example.com", - pack_name: "test_pack", - as: "test_pack2" + assert File.exists?("#{@emoji_path}/test_pack_nonshared2/pack.json") + assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png") + + assert admin_conn + |> delete("/api/pleroma/emoji/packs/test_pack_nonshared2") + |> json_response(200) == "ok" + + refute File.exists?("#{@emoji_path}/test_pack_nonshared2") + end + + test "nonshareable instance", %{admin_conn: admin_conn} do + mock(fn + %{method: :get, url: "https://old-instance/.well-known/nodeinfo"} -> + json(%{links: [%{href: "https://old-instance/nodeinfo/2.1.json"}]}) + + %{method: :get, url: "https://old-instance/nodeinfo/2.1.json"} -> + json(%{metadata: %{features: []}}) + end) + + assert admin_conn + |> post( + "/api/pleroma/emoji/packs/download", + %{ + url: "https://old-instance", + name: "test_pack", + as: "test_pack2" + } + ) + |> json_response(500) == %{ + "error" => "The requested instance does not support sharing emoji packs" } - |> Jason.encode!() - ) - |> json_response(200) == "ok" - - assert File.exists?("#{@emoji_dir_path}/test_pack2/pack.json") - assert File.exists?("#{@emoji_dir_path}/test_pack2/blank.png") - - assert conn - |> delete(emoji_api_path(conn, :delete, "test_pack2")) - |> json_response(200) == "ok" - - refute File.exists?("#{@emoji_dir_path}/test_pack2") - - # non-shared, downloaded from the fallback URL - - assert conn - |> put_req_header("content-type", "application/json") - |> post( - emoji_api_path( - conn, - :download_from - ), - %{ - instance_address: "https://example.com", - pack_name: "test_pack_nonshared", - as: "test_pack_nonshared2" + end + + test "checksum fail", %{admin_conn: admin_conn} do + mock(fn + %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> + json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) + + %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> + json(%{metadata: %{features: ["shareable_emoji_packs"]}}) + + %{ + method: :get, + url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha" + } -> + %Tesla.Env{ + status: 200, + body: Pleroma.Emoji.Pack.load_pack("pack_bad_sha") |> Jason.encode!() + } + + %{ + method: :get, + url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha/archive" + } -> + %Tesla.Env{ + status: 200, + body: File.read!("test/instance_static/emoji/pack_bad_sha/pack_bad_sha.zip") + } + end) + + assert admin_conn + |> post("/api/pleroma/emoji/packs/download", %{ + url: "https://example.com", + name: "pack_bad_sha", + as: "pack_bad_sha2" + }) + |> json_response(:internal_server_error) == %{ + "error" => "SHA256 for the pack doesn't match the one sent by the server" } - |> Jason.encode!() - ) - |> json_response(200) == "ok" + end + + test "other error", %{admin_conn: admin_conn} do + mock(fn + %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> + json(%{links: [%{href: "https://example.com/nodeinfo/2.1.json"}]}) - assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/pack.json") - assert File.exists?("#{@emoji_dir_path}/test_pack_nonshared2/blank.png") + %{method: :get, url: "https://example.com/nodeinfo/2.1.json"} -> + json(%{metadata: %{features: ["shareable_emoji_packs"]}}) - assert conn - |> delete(emoji_api_path(conn, :delete, "test_pack_nonshared2")) - |> json_response(200) == "ok" + %{ + method: :get, + url: "https://example.com/api/pleroma/emoji/packs/test_pack" + } -> + %Tesla.Env{ + status: 200, + body: Pleroma.Emoji.Pack.load_pack("test_pack") |> Jason.encode!() + } + end) - refute File.exists?("#{@emoji_dir_path}/test_pack_nonshared2") + assert admin_conn + |> post("/api/pleroma/emoji/packs/download", %{ + url: "https://example.com", + name: "test_pack", + as: "test_pack2" + }) + |> json_response(:internal_server_error) == %{ + "error" => + "The pack was not set as shared and there is no fallback src to download from" + } + end end - describe "updating pack metadata" do + describe "PATCH /api/pleroma/emoji/packs/:name" do setup do - pack_file = "#{@emoji_dir_path}/test_pack/pack.json" + pack_file = "#{@emoji_path}/test_pack/pack.json" original_content = File.read!(pack_file) on_exit(fn -> File.write!(pack_file, original_content) end) - admin = insert(:user, is_admin: true) - %{conn: conn} = oauth_access(["admin:write"], user: admin) - {:ok, - admin: admin, - conn: conn, pack_file: pack_file, new_data: %{ "license" => "Test license changed", @@ -225,15 +310,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do end test "for a pack without a fallback source", ctx do - conn = ctx[:conn] - - assert conn - |> post( - emoji_api_path(conn, :update_metadata, "test_pack"), - %{ - "new_data" => ctx[:new_data] - } - ) + assert ctx[:admin_conn] + |> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]}) |> json_response(200) == ctx[:new_data] assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data] @@ -245,7 +323,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do method: :get, url: "https://nonshared-pack" } -> - text(File.read!("#{@emoji_dir_path}/test_pack_nonshared/nonshared.zip")) + text(File.read!("#{@emoji_path}/test_pack_nonshared/nonshared.zip")) end) new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack") @@ -257,15 +335,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF" ) - conn = ctx[:conn] - - assert conn - |> post( - emoji_api_path(conn, :update_metadata, "test_pack"), - %{ - "new_data" => new_data - } - ) + assert ctx[:admin_conn] + |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data}) |> json_response(200) == new_data_with_sha assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha @@ -283,181 +354,377 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack") - conn = ctx[:conn] - - assert (conn - |> post( - emoji_api_path(conn, :update_metadata, "test_pack"), - %{ - "new_data" => new_data - } - ) - |> json_response(:bad_request))["error"] =~ "does not have all" + assert ctx[:admin_conn] + |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data}) + |> json_response(:bad_request) == %{ + "error" => "The fallback archive does not have all files specified in pack.json" + } end end - test "updating pack files" do - pack_file = "#{@emoji_dir_path}/test_pack/pack.json" - original_content = File.read!(pack_file) + describe "POST/PATCH/DELETE /api/pleroma/emoji/packs/:name/files" do + setup do + pack_file = "#{@emoji_path}/test_pack/pack.json" + original_content = File.read!(pack_file) - on_exit(fn -> - File.write!(pack_file, original_content) + on_exit(fn -> + File.write!(pack_file, original_content) + end) - File.rm_rf!("#{@emoji_dir_path}/test_pack/blank_url.png") - File.rm_rf!("#{@emoji_dir_path}/test_pack/dir") - File.rm_rf!("#{@emoji_dir_path}/test_pack/dir_2") - end) + :ok + end - admin = insert(:user, is_admin: true) - %{conn: conn} = oauth_access(["admin:write"], user: admin) - - same_name = %{ - "action" => "add", - "shortcode" => "blank", - "filename" => "dir/blank.png", - "file" => %Plug.Upload{ - filename: "blank.png", - path: "#{@emoji_dir_path}/test_pack/blank.png" - } - } - - different_name = %{same_name | "shortcode" => "blank_2"} - - assert (conn - |> post(emoji_api_path(conn, :update_file, "test_pack"), same_name) - |> json_response(:conflict))["error"] =~ "already exists" - - assert conn - |> post(emoji_api_path(conn, :update_file, "test_pack"), different_name) - |> json_response(200) == %{"blank" => "blank.png", "blank_2" => "dir/blank.png"} - - assert File.exists?("#{@emoji_dir_path}/test_pack/dir/blank.png") - - assert conn - |> post(emoji_api_path(conn, :update_file, "test_pack"), %{ - "action" => "update", - "shortcode" => "blank_2", - "new_shortcode" => "blank_3", - "new_filename" => "dir_2/blank_3.png" - }) - |> json_response(200) == %{"blank" => "blank.png", "blank_3" => "dir_2/blank_3.png"} - - refute File.exists?("#{@emoji_dir_path}/test_pack/dir/") - assert File.exists?("#{@emoji_dir_path}/test_pack/dir_2/blank_3.png") - - assert conn - |> post(emoji_api_path(conn, :update_file, "test_pack"), %{ - "action" => "remove", - "shortcode" => "blank_3" - }) - |> json_response(200) == %{"blank" => "blank.png"} - - refute File.exists?("#{@emoji_dir_path}/test_pack/dir_2/") - - mock(fn - %{ - method: :get, - url: "https://test-blank/blank_url.png" - } -> - text(File.read!("#{@emoji_dir_path}/test_pack/blank.png")) - end) + test "create shortcode exists", %{admin_conn: admin_conn} do + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank", + filename: "dir/blank.png", + file: %Plug.Upload{ + filename: "blank.png", + path: "#{@emoji_path}/test_pack/blank.png" + } + }) + |> json_response(:conflict) == %{ + "error" => "An emoji with the \"blank\" shortcode already exists" + } + end - # The name should be inferred from the URL ending - from_url = %{ - "action" => "add", - "shortcode" => "blank_url", - "file" => "https://test-blank/blank_url.png" - } + test "don't rewrite old emoji", %{admin_conn: admin_conn} do + on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end) - assert conn - |> post(emoji_api_path(conn, :update_file, "test_pack"), from_url) - |> json_response(200) == %{ - "blank" => "blank.png", - "blank_url" => "blank_url.png" - } + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank2", + filename: "dir/blank.png", + file: %Plug.Upload{ + filename: "blank.png", + path: "#{@emoji_path}/test_pack/blank.png" + } + }) + |> json_response(200) == %{"blank" => "blank.png", "blank2" => "dir/blank.png"} + + assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png") + + assert admin_conn + |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank", + new_shortcode: "blank2", + new_filename: "dir_2/blank_3.png" + }) + |> json_response(:conflict) == %{ + "error" => + "New shortcode \"blank2\" is already used. If you want to override emoji use 'force' option" + } + end + + test "rewrite old emoji with force option", %{admin_conn: admin_conn} do + on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end) + + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank2", + filename: "dir/blank.png", + file: %Plug.Upload{ + filename: "blank.png", + path: "#{@emoji_path}/test_pack/blank.png" + } + }) + |> json_response(200) == %{"blank" => "blank.png", "blank2" => "dir/blank.png"} + + assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png") + + assert admin_conn + |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank2", + new_shortcode: "blank3", + new_filename: "dir_2/blank_3.png", + force: true + }) + |> json_response(200) == %{ + "blank" => "blank.png", + "blank3" => "dir_2/blank_3.png" + } + + assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png") + end + + test "with empty filename", %{admin_conn: admin_conn} do + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank2", + filename: "", + file: %Plug.Upload{ + filename: "blank.png", + path: "#{@emoji_path}/test_pack/blank.png" + } + }) + |> json_response(:bad_request) == %{ + "error" => "pack name, shortcode or filename cannot be empty" + } + end + + test "add file with not loaded pack", %{admin_conn: admin_conn} do + assert admin_conn + |> post("/api/pleroma/emoji/packs/not_loaded/files", %{ + shortcode: "blank2", + filename: "dir/blank.png", + file: %Plug.Upload{ + filename: "blank.png", + path: "#{@emoji_path}/test_pack/blank.png" + } + }) + |> json_response(:bad_request) == %{ + "error" => "pack \"not_loaded\" is not found" + } + end + + test "remove file with not loaded pack", %{admin_conn: admin_conn} do + assert admin_conn + |> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: "blank3"}) + |> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"} + end + + test "remove file with empty shortcode", %{admin_conn: admin_conn} do + assert admin_conn + |> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: ""}) + |> json_response(:bad_request) == %{ + "error" => "pack name or shortcode cannot be empty" + } + end + + test "update file with not loaded pack", %{admin_conn: admin_conn} do + assert admin_conn + |> patch("/api/pleroma/emoji/packs/not_loaded/files", %{ + shortcode: "blank4", + new_shortcode: "blank3", + new_filename: "dir_2/blank_3.png" + }) + |> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"} + end + + test "new with shortcode as file with update", %{admin_conn: admin_conn} do + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank4", + filename: "dir/blank.png", + file: %Plug.Upload{ + filename: "blank.png", + path: "#{@emoji_path}/test_pack/blank.png" + } + }) + |> json_response(200) == %{"blank" => "blank.png", "blank4" => "dir/blank.png"} + + assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png") + + assert admin_conn + |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank4", + new_shortcode: "blank3", + new_filename: "dir_2/blank_3.png" + }) + |> json_response(200) == %{"blank3" => "dir_2/blank_3.png", "blank" => "blank.png"} + + refute File.exists?("#{@emoji_path}/test_pack/dir/") + assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png") - assert File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png") + assert admin_conn + |> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank3"}) + |> json_response(200) == %{"blank" => "blank.png"} - assert conn - |> post(emoji_api_path(conn, :update_file, "test_pack"), %{ - "action" => "remove", - "shortcode" => "blank_url" - }) - |> json_response(200) == %{"blank" => "blank.png"} + refute File.exists?("#{@emoji_path}/test_pack/dir_2/") - refute File.exists?("#{@emoji_dir_path}/test_pack/blank_url.png") + on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir") end) + end + + test "new with shortcode from url", %{admin_conn: admin_conn} do + mock(fn + %{ + method: :get, + url: "https://test-blank/blank_url.png" + } -> + text(File.read!("#{@emoji_path}/test_pack/blank.png")) + end) + + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank_url", + file: "https://test-blank/blank_url.png" + }) + |> json_response(200) == %{ + "blank_url" => "blank_url.png", + "blank" => "blank.png" + } + + assert File.exists?("#{@emoji_path}/test_pack/blank_url.png") + + on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/blank_url.png") end) + end + + test "new without shortcode", %{admin_conn: admin_conn} do + on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end) + + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_pack/files", %{ + file: %Plug.Upload{ + filename: "shortcode.png", + path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png" + } + }) + |> json_response(200) == %{"shortcode" => "shortcode.png", "blank" => "blank.png"} + end + + test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do + assert admin_conn + |> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank2"}) + |> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"} + end + + test "update non existing emoji", %{admin_conn: admin_conn} do + assert admin_conn + |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank2", + new_shortcode: "blank3", + new_filename: "dir_2/blank_3.png" + }) + |> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"} + end + + test "update with empty shortcode", %{admin_conn: admin_conn} do + assert admin_conn + |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ + shortcode: "blank", + new_filename: "dir_2/blank_3.png" + }) + |> json_response(:bad_request) == %{ + "error" => "new_shortcode or new_filename cannot be empty" + } + end end - test "creating and deleting a pack" do - on_exit(fn -> - File.rm_rf!("#{@emoji_dir_path}/test_created") - end) + describe "POST/DELETE /api/pleroma/emoji/packs/:name" do + test "creating and deleting a pack", %{admin_conn: admin_conn} do + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_created") + |> json_response(200) == "ok" - admin = insert(:user, is_admin: true) - %{conn: conn} = oauth_access(["admin:write"], user: admin) - - assert conn - |> put_req_header("content-type", "application/json") - |> put( - emoji_api_path( - conn, - :create, - "test_created" - ) - ) - |> json_response(200) == "ok" + assert File.exists?("#{@emoji_path}/test_created/pack.json") + + assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{ + "pack" => %{}, + "files" => %{} + } - assert File.exists?("#{@emoji_dir_path}/test_created/pack.json") + assert admin_conn + |> delete("/api/pleroma/emoji/packs/test_created") + |> json_response(200) == "ok" - assert Jason.decode!(File.read!("#{@emoji_dir_path}/test_created/pack.json")) == %{ - "pack" => %{}, - "files" => %{} - } + refute File.exists?("#{@emoji_path}/test_created/pack.json") + end + + test "if pack exists", %{admin_conn: admin_conn} do + path = Path.join(@emoji_path, "test_created") + File.mkdir(path) + pack_file = Jason.encode!(%{files: %{}, pack: %{}}) + File.write!(Path.join(path, "pack.json"), pack_file) + + assert admin_conn + |> post("/api/pleroma/emoji/packs/test_created") + |> json_response(:conflict) == %{ + "error" => "A pack named \"test_created\" already exists" + } + + on_exit(fn -> File.rm_rf(path) end) + end + + test "with empty name", %{admin_conn: admin_conn} do + assert admin_conn + |> post("/api/pleroma/emoji/packs/ ") + |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} + end + end - assert conn - |> delete(emoji_api_path(conn, :delete, "test_created")) - |> json_response(200) == "ok" + test "deleting nonexisting pack", %{admin_conn: admin_conn} do + assert admin_conn + |> delete("/api/pleroma/emoji/packs/non_existing") + |> json_response(:not_found) == %{"error" => "Pack non_existing does not exist"} + end - refute File.exists?("#{@emoji_dir_path}/test_created/pack.json") + test "deleting with empty name", %{admin_conn: admin_conn} do + assert admin_conn + |> delete("/api/pleroma/emoji/packs/ ") + |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} end - test "filesystem import" do + test "filesystem import", %{admin_conn: admin_conn, conn: conn} do on_exit(fn -> - File.rm!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt") - File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json") + File.rm!("#{@emoji_path}/test_pack_for_import/emoji.txt") + File.rm!("#{@emoji_path}/test_pack_for_import/pack.json") end) - conn = build_conn() - resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) 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 - |> post(emoji_api_path(conn, :import_from_fs)) + assert admin_conn + |> get("/api/pleroma/emoji/packs/import") |> json_response(200) == ["test_pack_for_import"] - resp = conn |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"} - File.rm!("#{@emoji_dir_path}/test_pack_for_import/pack.json") - refute File.exists?("#{@emoji_dir_path}/test_pack_for_import/pack.json") + File.rm!("#{@emoji_path}/test_pack_for_import/pack.json") + refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json") - emoji_txt_content = "blank, blank.png, Fun\n\nblank2, blank.png" + emoji_txt_content = """ + blank, blank.png, Fun + blank2, blank.png + foo, /emoji/test_pack_for_import/blank.png + bar + """ - File.write!("#{@emoji_dir_path}/test_pack_for_import/emoji.txt", emoji_txt_content) + File.write!("#{@emoji_path}/test_pack_for_import/emoji.txt", emoji_txt_content) - assert conn - |> post(emoji_api_path(conn, :import_from_fs)) + assert admin_conn + |> get("/api/pleroma/emoji/packs/import") |> json_response(200) == ["test_pack_for_import"] - resp = build_conn() |> get(emoji_api_path(conn, :list_packs)) |> json_response(200) + resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) assert resp["test_pack_for_import"]["files"] == %{ "blank" => "blank.png", - "blank2" => "blank.png" + "blank2" => "blank.png", + "foo" => "blank.png" } end + + describe "GET /api/pleroma/emoji/packs/:name" do + test "shows pack.json", %{conn: conn} do + assert %{ + "files" => %{"blank" => "blank.png"}, + "pack" => %{ + "can-download" => true, + "description" => "Test description", + "download-sha256" => _, + "homepage" => "https://pleroma.social", + "license" => "Test license", + "share-files" => true + } + } = + conn + |> get("/api/pleroma/emoji/packs/test_pack") + |> json_response(200) + end + + test "non existing pack", %{conn: conn} do + assert conn + |> get("/api/pleroma/emoji/packs/non_existing") + |> json_response(:not_found) == %{"error" => "Pack non_existing does not exist"} + end + + test "error name", %{conn: conn} do + assert conn + |> get("/api/pleroma/emoji/packs/ ") + |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} + end + end end 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 8bf7eb3be..61a1689b9 100644 --- a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs @@ -220,7 +220,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do test "POST /api/v1/pleroma/conversations/read" do user = insert(:user) - %{user: other_user, conn: conn} = oauth_access(["write:notifications"]) + %{user: other_user, conn: conn} = oauth_access(["write:conversations"]) {:ok, _activity} = CommonAPI.post(user, %{"status" => "Hi @#{other_user.nickname}", "visibility" => "direct"}) diff --git a/test/web/push/impl_test.exs b/test/web/push/impl_test.exs index 9121d90e7..b2664bf28 100644 --- a/test/web/push/impl_test.exs +++ b/test/web/push/impl_test.exs @@ -63,12 +63,12 @@ defmodule Pleroma.Web.Push.ImplTest do activity: activity ) - assert Impl.perform(notif) == [:ok, :ok] + assert Impl.perform(notif) == {:ok, [:ok, :ok]} end @tag capture_log: true test "returns error if notif does not match " do - assert Impl.perform(%{}) == :error + assert Impl.perform(%{}) == {:error, :unknown_type} end test "successful message sending" do diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs index eb082b79f..8b8d8af6c 100644 --- a/test/web/streamer/streamer_test.exs +++ b/test/web/streamer/streamer_test.exs @@ -28,6 +28,42 @@ defmodule Pleroma.Web.StreamerTest do {:ok, %{user: user, notify: notify}} end + test "it streams the user's post in the 'user' stream", %{user: user} do + task = + Task.async(fn -> + assert_receive {:text, _}, @streamer_timeout + end) + + Streamer.add_socket( + "user", + %{transport_pid: task.pid, assigns: %{user: user}} + ) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "hey"}) + + Streamer.stream("user", activity) + Task.await(task) + end + + test "it streams boosts of the user in the 'user' stream", %{user: user} do + task = + Task.async(fn -> + assert_receive {:text, _}, @streamer_timeout + end) + + Streamer.add_socket( + "user", + %{transport_pid: task.pid, assigns: %{user: user}} + ) + + other_user = insert(:user) + {:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey"}) + {:ok, announce, _} = CommonAPI.repeat(activity.id, user) + + Streamer.stream("user", announce) + Task.await(task) + end + test "it sends notify to in the 'user' stream", %{user: user, notify: notify} do task = Task.async(fn -> diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index ab0a2c3df..464d0ea2e 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -19,13 +19,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do end test "with credentials, without any params" do - %{user: current_user, conn: conn} = - oauth_access(["read:notifications", "write:notifications"]) + %{conn: conn} = oauth_access(["write:notifications"]) - conn = - conn - |> assign(:user, current_user) - |> post("/api/qvitter/statuses/notifications/read") + conn = post(conn, "/api/qvitter/statuses/notifications/read") assert json_response(conn, 400) == %{ "error" => "You need to specify latest_id", diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index f6e13b661..368533292 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -18,11 +18,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do test "it registers a new user and returns the user." do data = %{ - "nickname" => "lain", - "email" => "lain@wired.jp", - "fullname" => "lain iwakura", - "password" => "bear", - "confirm" => "bear" + :username => "lain", + :email => "lain@wired.jp", + :fullname => "lain iwakura", + :password => "bear", + :confirm => "bear" } {:ok, user} = TwitterAPI.register_user(data) @@ -35,12 +35,12 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do test "it registers a new user with empty string in bio and returns the user." do data = %{ - "nickname" => "lain", - "email" => "lain@wired.jp", - "fullname" => "lain iwakura", - "bio" => "", - "password" => "bear", - "confirm" => "bear" + :username => "lain", + :email => "lain@wired.jp", + :fullname => "lain iwakura", + :bio => "", + :password => "bear", + :confirm => "bear" } {:ok, user} = TwitterAPI.register_user(data) @@ -60,12 +60,12 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do end data = %{ - "nickname" => "lain", - "email" => "lain@wired.jp", - "fullname" => "lain iwakura", - "bio" => "", - "password" => "bear", - "confirm" => "bear" + :username => "lain", + :email => "lain@wired.jp", + :fullname => "lain iwakura", + :bio => "", + :password => "bear", + :confirm => "bear" } {:ok, user} = TwitterAPI.register_user(data) @@ -87,23 +87,23 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do test "it registers a new user and parses mentions in the bio" do data1 = %{ - "nickname" => "john", - "email" => "john@gmail.com", - "fullname" => "John Doe", - "bio" => "test", - "password" => "bear", - "confirm" => "bear" + :username => "john", + :email => "john@gmail.com", + :fullname => "John Doe", + :bio => "test", + :password => "bear", + :confirm => "bear" } {:ok, user1} = TwitterAPI.register_user(data1) data2 = %{ - "nickname" => "lain", - "email" => "lain@wired.jp", - "fullname" => "lain iwakura", - "bio" => "@john test", - "password" => "bear", - "confirm" => "bear" + :username => "lain", + :email => "lain@wired.jp", + :fullname => "lain iwakura", + :bio => "@john test", + :password => "bear", + :confirm => "bear" } {:ok, user2} = TwitterAPI.register_user(data2) @@ -123,13 +123,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do {:ok, invite} = UserInviteToken.create_invite() data = %{ - "nickname" => "vinny", - "email" => "pasta@pizza.vs", - "fullname" => "Vinny Vinesauce", - "bio" => "streamer", - "password" => "hiptofbees", - "confirm" => "hiptofbees", - "token" => invite.token + :username => "vinny", + :email => "pasta@pizza.vs", + :fullname => "Vinny Vinesauce", + :bio => "streamer", + :password => "hiptofbees", + :confirm => "hiptofbees", + :token => invite.token } {:ok, user} = TwitterAPI.register_user(data) @@ -145,13 +145,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do test "returns error on invalid token" do data = %{ - "nickname" => "GrimReaper", - "email" => "death@reapers.afterlife", - "fullname" => "Reaper Grim", - "bio" => "Your time has come", - "password" => "scythe", - "confirm" => "scythe", - "token" => "DudeLetMeInImAFairy" + :username => "GrimReaper", + :email => "death@reapers.afterlife", + :fullname => "Reaper Grim", + :bio => "Your time has come", + :password => "scythe", + :confirm => "scythe", + :token => "DudeLetMeInImAFairy" } {:error, msg} = TwitterAPI.register_user(data) @@ -165,13 +165,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do UserInviteToken.update_invite!(invite, used: true) data = %{ - "nickname" => "GrimReaper", - "email" => "death@reapers.afterlife", - "fullname" => "Reaper Grim", - "bio" => "Your time has come", - "password" => "scythe", - "confirm" => "scythe", - "token" => invite.token + :username => "GrimReaper", + :email => "death@reapers.afterlife", + :fullname => "Reaper Grim", + :bio => "Your time has come", + :password => "scythe", + :confirm => "scythe", + :token => invite.token } {:error, msg} = TwitterAPI.register_user(data) @@ -186,16 +186,16 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do setup do data = %{ - "nickname" => "vinny", - "email" => "pasta@pizza.vs", - "fullname" => "Vinny Vinesauce", - "bio" => "streamer", - "password" => "hiptofbees", - "confirm" => "hiptofbees" + :username => "vinny", + :email => "pasta@pizza.vs", + :fullname => "Vinny Vinesauce", + :bio => "streamer", + :password => "hiptofbees", + :confirm => "hiptofbees" } check_fn = fn invite -> - data = Map.put(data, "token", invite.token) + data = Map.put(data, :token, invite.token) {:ok, user} = TwitterAPI.register_user(data) fetched_user = User.get_cached_by_nickname("vinny") @@ -250,13 +250,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do UserInviteToken.update_invite!(invite, uses: 99) data = %{ - "nickname" => "vinny", - "email" => "pasta@pizza.vs", - "fullname" => "Vinny Vinesauce", - "bio" => "streamer", - "password" => "hiptofbees", - "confirm" => "hiptofbees", - "token" => invite.token + :username => "vinny", + :email => "pasta@pizza.vs", + :fullname => "Vinny Vinesauce", + :bio => "streamer", + :password => "hiptofbees", + :confirm => "hiptofbees", + :token => invite.token } {:ok, user} = TwitterAPI.register_user(data) @@ -269,13 +269,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do AccountView.render("show.json", %{user: fetched_user}) data = %{ - "nickname" => "GrimReaper", - "email" => "death@reapers.afterlife", - "fullname" => "Reaper Grim", - "bio" => "Your time has come", - "password" => "scythe", - "confirm" => "scythe", - "token" => invite.token + :username => "GrimReaper", + :email => "death@reapers.afterlife", + :fullname => "Reaper Grim", + :bio => "Your time has come", + :password => "scythe", + :confirm => "scythe", + :token => invite.token } {:error, msg} = TwitterAPI.register_user(data) @@ -292,13 +292,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do {:ok, invite} = UserInviteToken.create_invite(%{expires_at: Date.utc_today(), max_use: 100}) data = %{ - "nickname" => "vinny", - "email" => "pasta@pizza.vs", - "fullname" => "Vinny Vinesauce", - "bio" => "streamer", - "password" => "hiptofbees", - "confirm" => "hiptofbees", - "token" => invite.token + :username => "vinny", + :email => "pasta@pizza.vs", + :fullname => "Vinny Vinesauce", + :bio => "streamer", + :password => "hiptofbees", + :confirm => "hiptofbees", + :token => invite.token } {:ok, user} = TwitterAPI.register_user(data) @@ -317,13 +317,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do UserInviteToken.update_invite!(invite, uses: 99) data = %{ - "nickname" => "vinny", - "email" => "pasta@pizza.vs", - "fullname" => "Vinny Vinesauce", - "bio" => "streamer", - "password" => "hiptofbees", - "confirm" => "hiptofbees", - "token" => invite.token + :username => "vinny", + :email => "pasta@pizza.vs", + :fullname => "Vinny Vinesauce", + :bio => "streamer", + :password => "hiptofbees", + :confirm => "hiptofbees", + :token => invite.token } {:ok, user} = TwitterAPI.register_user(data) @@ -335,13 +335,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do AccountView.render("show.json", %{user: fetched_user}) data = %{ - "nickname" => "GrimReaper", - "email" => "death@reapers.afterlife", - "fullname" => "Reaper Grim", - "bio" => "Your time has come", - "password" => "scythe", - "confirm" => "scythe", - "token" => invite.token + :username => "GrimReaper", + :email => "death@reapers.afterlife", + :fullname => "Reaper Grim", + :bio => "Your time has come", + :password => "scythe", + :confirm => "scythe", + :token => invite.token } {:error, msg} = TwitterAPI.register_user(data) @@ -355,13 +355,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do UserInviteToken.create_invite(%{expires_at: Date.add(Date.utc_today(), -1), max_use: 100}) data = %{ - "nickname" => "GrimReaper", - "email" => "death@reapers.afterlife", - "fullname" => "Reaper Grim", - "bio" => "Your time has come", - "password" => "scythe", - "confirm" => "scythe", - "token" => invite.token + :username => "GrimReaper", + :email => "death@reapers.afterlife", + :fullname => "Reaper Grim", + :bio => "Your time has come", + :password => "scythe", + :confirm => "scythe", + :token => invite.token } {:error, msg} = TwitterAPI.register_user(data) @@ -377,13 +377,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do UserInviteToken.update_invite!(invite, uses: 100) data = %{ - "nickname" => "GrimReaper", - "email" => "death@reapers.afterlife", - "fullname" => "Reaper Grim", - "bio" => "Your time has come", - "password" => "scythe", - "confirm" => "scythe", - "token" => invite.token + :username => "GrimReaper", + :email => "death@reapers.afterlife", + :fullname => "Reaper Grim", + :bio => "Your time has come", + :password => "scythe", + :confirm => "scythe", + :token => invite.token } {:error, msg} = TwitterAPI.register_user(data) @@ -395,16 +395,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do test "it returns the error on registration problems" do data = %{ - "nickname" => "lain", - "email" => "lain@wired.jp", - "fullname" => "lain iwakura", - "bio" => "close the world.", - "password" => "bear" + :username => "lain", + :email => "lain@wired.jp", + :fullname => "lain iwakura", + :bio => "close the world." } - {:error, error_object} = TwitterAPI.register_user(data) + {:error, error} = TwitterAPI.register_user(data) - assert is_binary(error_object[:error]) + assert is_binary(error) refute User.get_cached_by_nickname("lain") end diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index 30e54bebd..b701239a0 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -95,6 +95,30 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do end end end + + test "it imports follows with different nickname variations", %{conn: conn} do + [user2, user3, user4, user5, user6] = insert_list(5, :user) + + identifiers = + [ + user2.ap_id, + user3.nickname, + " ", + "@" <> user4.nickname, + user5.nickname <> "@localhost", + "@" <> user6.nickname <> "@localhost" + ] + |> Enum.join("\n") + + response = + conn + |> post("/api/pleroma/follow_import", %{"list" => identifiers}) + |> json_response(:ok) + + assert response == "job started" + assert [{:ok, job_result}] = ObanHelpers.perform_all() + assert job_result == [user2, user3, user4, user5, user6] + end end describe "POST /api/pleroma/blocks_import" do @@ -136,6 +160,29 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do ) end end + + test "it imports blocks with different nickname variations", %{conn: conn} do + [user2, user3, user4, user5, user6] = insert_list(5, :user) + + identifiers = + [ + user2.ap_id, + user3.nickname, + "@" <> user4.nickname, + user5.nickname <> "@localhost", + "@" <> user6.nickname <> "@localhost" + ] + |> Enum.join(" ") + + response = + conn + |> post("/api/pleroma/blocks_import", %{"list" => identifiers}) + |> json_response(:ok) + + assert response == "job started" + assert [{:ok, job_result}] = ObanHelpers.perform_all() + assert job_result == [user2, user3, user4, user5, user6] + end end describe "PUT /api/pleroma/notification_settings" do |