diff options
Diffstat (limited to 'test/web/pleroma_api/controllers')
| -rw-r--r-- | test/web/pleroma_api/controllers/chat_controller_test.exs | 336 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/conversation_controller_test.exs | 136 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/emoji_pack_controller_test.exs (renamed from test/web/pleroma_api/controllers/emoji_api_controller_test.exs) | 308 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs | 132 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/mascot_controller_test.exs | 25 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/notification_controller_test.exs | 68 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/pleroma_api_controller_test.exs | 302 | ||||
| -rw-r--r-- | test/web/pleroma_api/controllers/scrobble_controller_test.exs | 26 | 
8 files changed, 919 insertions, 414 deletions
| diff --git a/test/web/pleroma_api/controllers/chat_controller_test.exs b/test/web/pleroma_api/controllers/chat_controller_test.exs new file mode 100644 index 000000000..82e16741d --- /dev/null +++ b/test/web/pleroma_api/controllers/chat_controller_test.exs @@ -0,0 +1,336 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only +defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do +  use Pleroma.Web.ConnCase, async: true + +  alias Pleroma.Chat +  alias Pleroma.Chat.MessageReference +  alias Pleroma.Object +  alias Pleroma.User +  alias Pleroma.Web.ActivityPub.ActivityPub +  alias Pleroma.Web.CommonAPI + +  import Pleroma.Factory + +  describe "POST /api/v1/pleroma/chats/:id/messages/:message_id/read" do +    setup do: oauth_access(["write:chats"]) + +    test "it marks one message as read", %{conn: conn, user: user} do +      other_user = insert(:user) + +      {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup") +      {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2") +      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) +      object = Object.normalize(create, false) +      cm_ref = MessageReference.for_chat_and_object(chat, object) + +      assert cm_ref.unread == true + +      result = +        conn +        |> post("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}/read") +        |> json_response_and_validate_schema(200) + +      assert result["unread"] == false + +      cm_ref = MessageReference.for_chat_and_object(chat, object) + +      assert cm_ref.unread == false +    end +  end + +  describe "POST /api/v1/pleroma/chats/:id/read" do +    setup do: oauth_access(["write:chats"]) + +    test "given a `last_read_id`, it marks everything until then as read", %{ +      conn: conn, +      user: user +    } do +      other_user = insert(:user) + +      {:ok, create} = CommonAPI.post_chat_message(other_user, user, "sup") +      {:ok, _create} = CommonAPI.post_chat_message(other_user, user, "sup part 2") +      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) +      object = Object.normalize(create, false) +      cm_ref = MessageReference.for_chat_and_object(chat, object) + +      assert cm_ref.unread == true + +      result = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/chats/#{chat.id}/read", %{"last_read_id" => cm_ref.id}) +        |> json_response_and_validate_schema(200) + +      assert result["unread"] == 1 + +      cm_ref = MessageReference.for_chat_and_object(chat, object) + +      assert cm_ref.unread == false +    end +  end + +  describe "POST /api/v1/pleroma/chats/:id/messages" do +    setup do: oauth_access(["write:chats"]) + +    test "it posts a message to the chat", %{conn: conn, user: user} do +      other_user = insert(:user) + +      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) + +      result = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{"content" => "Hallo!!"}) +        |> json_response_and_validate_schema(200) + +      assert result["content"] == "Hallo!!" +      assert result["chat_id"] == chat.id |> to_string() +    end + +    test "it fails if there is no content", %{conn: conn, user: user} do +      other_user = insert(:user) + +      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) + +      result = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/chats/#{chat.id}/messages") +        |> json_response_and_validate_schema(400) + +      assert result +    end + +    test "it works with an attachment", %{conn: conn, user: user} do +      file = %Plug.Upload{ +        content_type: "image/jpg", +        path: Path.absname("test/fixtures/image.jpg"), +        filename: "an_image.jpg" +      } + +      {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) + +      other_user = insert(:user) + +      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) + +      result = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/chats/#{chat.id}/messages", %{ +          "media_id" => to_string(upload.id) +        }) +        |> json_response_and_validate_schema(200) + +      assert result["attachment"] +    end +  end + +  describe "DELETE /api/v1/pleroma/chats/:id/messages/:message_id" do +    setup do: oauth_access(["write:chats"]) + +    test "it deletes a message from the chat", %{conn: conn, user: user} do +      recipient = insert(:user) + +      {:ok, message} = +        CommonAPI.post_chat_message(user, recipient, "Hello darkness my old friend") + +      {:ok, other_message} = CommonAPI.post_chat_message(recipient, user, "nico nico ni") + +      object = Object.normalize(message, false) + +      chat = Chat.get(user.id, recipient.ap_id) + +      cm_ref = MessageReference.for_chat_and_object(chat, object) + +      # Deleting your own message removes the message and the reference +      result = +        conn +        |> put_req_header("content-type", "application/json") +        |> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}") +        |> json_response_and_validate_schema(200) + +      assert result["id"] == cm_ref.id +      refute MessageReference.get_by_id(cm_ref.id) +      assert %{data: %{"type" => "Tombstone"}} = Object.get_by_id(object.id) + +      # Deleting other people's messages just removes the reference +      object = Object.normalize(other_message, false) +      cm_ref = MessageReference.for_chat_and_object(chat, object) + +      result = +        conn +        |> put_req_header("content-type", "application/json") +        |> delete("/api/v1/pleroma/chats/#{chat.id}/messages/#{cm_ref.id}") +        |> json_response_and_validate_schema(200) + +      assert result["id"] == cm_ref.id +      refute MessageReference.get_by_id(cm_ref.id) +      assert Object.get_by_id(object.id) +    end +  end + +  describe "GET /api/v1/pleroma/chats/:id/messages" do +    setup do: oauth_access(["read:chats"]) + +    test "it paginates", %{conn: conn, user: user} do +      recipient = insert(:user) + +      Enum.each(1..30, fn _ -> +        {:ok, _} = CommonAPI.post_chat_message(user, recipient, "hey") +      end) + +      chat = Chat.get(user.id, recipient.ap_id) + +      result = +        conn +        |> get("/api/v1/pleroma/chats/#{chat.id}/messages") +        |> json_response_and_validate_schema(200) + +      assert length(result) == 20 + +      result = +        conn +        |> get("/api/v1/pleroma/chats/#{chat.id}/messages?max_id=#{List.last(result)["id"]}") +        |> json_response_and_validate_schema(200) + +      assert length(result) == 10 +    end + +    test "it returns the messages for a given chat", %{conn: conn, user: user} do +      other_user = insert(:user) +      third_user = insert(:user) + +      {:ok, _} = CommonAPI.post_chat_message(user, other_user, "hey") +      {:ok, _} = CommonAPI.post_chat_message(user, third_user, "hey") +      {:ok, _} = CommonAPI.post_chat_message(user, other_user, "how are you?") +      {:ok, _} = CommonAPI.post_chat_message(other_user, user, "fine, how about you?") + +      chat = Chat.get(user.id, other_user.ap_id) + +      result = +        conn +        |> get("/api/v1/pleroma/chats/#{chat.id}/messages") +        |> json_response_and_validate_schema(200) + +      result +      |> Enum.each(fn message -> +        assert message["chat_id"] == chat.id |> to_string() +      end) + +      assert length(result) == 3 + +      # Trying to get the chat of a different user +      result = +        conn +        |> assign(:user, other_user) +        |> get("/api/v1/pleroma/chats/#{chat.id}/messages") + +      assert result |> json_response(404) +    end +  end + +  describe "POST /api/v1/pleroma/chats/by-account-id/:id" do +    setup do: oauth_access(["write:chats"]) + +    test "it creates or returns a chat", %{conn: conn} do +      other_user = insert(:user) + +      result = +        conn +        |> post("/api/v1/pleroma/chats/by-account-id/#{other_user.id}") +        |> json_response_and_validate_schema(200) + +      assert result["id"] +    end +  end + +  describe "GET /api/v1/pleroma/chats/:id" do +    setup do: oauth_access(["read:chats"]) + +    test "it returns a chat", %{conn: conn, user: user} do +      other_user = insert(:user) + +      {:ok, chat} = Chat.get_or_create(user.id, other_user.ap_id) + +      result = +        conn +        |> get("/api/v1/pleroma/chats/#{chat.id}") +        |> json_response_and_validate_schema(200) + +      assert result["id"] == to_string(chat.id) +    end +  end + +  describe "GET /api/v1/pleroma/chats" do +    setup do: oauth_access(["read:chats"]) + +    test "it does not return chats with users you blocked", %{conn: conn, user: user} do +      recipient = insert(:user) + +      {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id) + +      result = +        conn +        |> get("/api/v1/pleroma/chats") +        |> json_response_and_validate_schema(200) + +      assert length(result) == 1 + +      User.block(user, recipient) + +      result = +        conn +        |> get("/api/v1/pleroma/chats") +        |> json_response_and_validate_schema(200) + +      assert length(result) == 0 +    end + +    test "it returns all chats", %{conn: conn, user: user} do +      Enum.each(1..30, fn _ -> +        recipient = insert(:user) +        {:ok, _} = Chat.get_or_create(user.id, recipient.ap_id) +      end) + +      result = +        conn +        |> get("/api/v1/pleroma/chats") +        |> json_response_and_validate_schema(200) + +      assert length(result) == 30 +    end + +    test "it return a list of chats the current user is participating in, in descending order of updates", +         %{conn: conn, user: user} do +      har = insert(:user) +      jafnhar = insert(:user) +      tridi = insert(:user) + +      {:ok, chat_1} = Chat.get_or_create(user.id, har.ap_id) +      :timer.sleep(1000) +      {:ok, _chat_2} = Chat.get_or_create(user.id, jafnhar.ap_id) +      :timer.sleep(1000) +      {:ok, chat_3} = Chat.get_or_create(user.id, tridi.ap_id) +      :timer.sleep(1000) + +      # bump the second one +      {:ok, chat_2} = Chat.bump_or_create(user.id, jafnhar.ap_id) + +      result = +        conn +        |> get("/api/v1/pleroma/chats") +        |> json_response_and_validate_schema(200) + +      ids = Enum.map(result, & &1["id"]) + +      assert ids == [ +               chat_2.id |> to_string(), +               chat_3.id |> to_string(), +               chat_1.id |> to_string() +             ] +    end +  end +end diff --git a/test/web/pleroma_api/controllers/conversation_controller_test.exs b/test/web/pleroma_api/controllers/conversation_controller_test.exs new file mode 100644 index 000000000..e6d0b3e37 --- /dev/null +++ b/test/web/pleroma_api/controllers/conversation_controller_test.exs @@ -0,0 +1,136 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.ConversationControllerTest do +  use Pleroma.Web.ConnCase + +  alias Pleroma.Conversation.Participation +  alias Pleroma.Repo +  alias Pleroma.User +  alias Pleroma.Web.CommonAPI + +  import Pleroma.Factory + +  test "/api/v1/pleroma/conversations/:id" do +    user = insert(:user) +    %{user: other_user, conn: conn} = oauth_access(["read:statuses"]) + +    {:ok, _activity} = +      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"}) + +    [participation] = Participation.for_user(other_user) + +    result = +      conn +      |> get("/api/v1/pleroma/conversations/#{participation.id}") +      |> json_response_and_validate_schema(200) + +    assert result["id"] == participation.id |> to_string() +  end + +  test "/api/v1/pleroma/conversations/:id/statuses" do +    user = insert(:user) +    %{user: other_user, conn: conn} = oauth_access(["read:statuses"]) +    third_user = insert(:user) + +    {:ok, _activity} = +      CommonAPI.post(user, %{status: "Hi @#{third_user.nickname}!", visibility: "direct"}) + +    {:ok, activity} = +      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"}) + +    [participation] = Participation.for_user(other_user) + +    {:ok, activity_two} = +      CommonAPI.post(other_user, %{ +        status: "Hi!", +        in_reply_to_status_id: activity.id, +        in_reply_to_conversation_id: participation.id +      }) + +    result = +      conn +      |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses") +      |> json_response_and_validate_schema(200) + +    assert length(result) == 2 + +    id_one = activity.id +    id_two = activity_two.id +    assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result + +    {:ok, %{id: id_three}} = +      CommonAPI.post(other_user, %{ +        status: "Bye!", +        in_reply_to_status_id: activity.id, +        in_reply_to_conversation_id: participation.id +      }) + +    assert [%{"id" => ^id_two}, %{"id" => ^id_three}] = +             conn +             |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?limit=2") +             |> json_response_and_validate_schema(:ok) + +    assert [%{"id" => ^id_three}] = +             conn +             |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?min_id=#{id_two}") +             |> json_response_and_validate_schema(:ok) +  end + +  test "PATCH /api/v1/pleroma/conversations/:id" do +    %{user: user, conn: conn} = oauth_access(["write:conversations"]) +    other_user = insert(:user) + +    {:ok, _activity} = CommonAPI.post(user, %{status: "Hi", visibility: "direct"}) + +    [participation] = Participation.for_user(user) + +    participation = Repo.preload(participation, :recipients) + +    user = User.get_cached_by_id(user.id) +    assert [user] == participation.recipients +    assert other_user not in participation.recipients + +    query = "recipients[]=#{user.id}&recipients[]=#{other_user.id}" + +    result = +      conn +      |> patch("/api/v1/pleroma/conversations/#{participation.id}?#{query}") +      |> json_response_and_validate_schema(200) + +    assert result["id"] == participation.id |> to_string + +    [participation] = Participation.for_user(user) +    participation = Repo.preload(participation, :recipients) + +    assert user in participation.recipients +    assert other_user in participation.recipients +  end + +  test "POST /api/v1/pleroma/conversations/read" do +    user = insert(:user) +    %{user: other_user, conn: conn} = oauth_access(["write:conversations"]) + +    {:ok, _activity} = +      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"}) + +    {:ok, _activity} = +      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"}) + +    [participation2, participation1] = Participation.for_user(other_user) +    assert Participation.get(participation2.id).read == false +    assert Participation.get(participation1.id).read == false +    assert User.get_cached_by_id(other_user.id).unread_conversation_count == 2 + +    [%{"unread" => false}, %{"unread" => false}] = +      conn +      |> post("/api/v1/pleroma/conversations/read", %{}) +      |> json_response_and_validate_schema(200) + +    [participation2, participation1] = Participation.for_user(other_user) +    assert Participation.get(participation2.id).read == true +    assert Participation.get(participation1.id).read == true +    assert User.get_cached_by_id(other_user.id).unread_conversation_count == 0 +  end +end diff --git a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs b/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs index d343256fe..df58a5eb6 100644 --- a/test/web/pleroma_api/controllers/emoji_api_controller_test.exs +++ b/test/web/pleroma_api/controllers/emoji_pack_controller_test.exs @@ -2,7 +2,7 @@  # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>  # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do +defmodule Pleroma.Web.PleromaAPI.EmojiPackControllerTest do    use Pleroma.Web.ConnCase    import Tesla.Mock @@ -28,17 +28,57 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do    end    test "GET /api/pleroma/emoji/packs", %{conn: conn} do -    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) +    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200) -    shared = resp["test_pack"] -    assert shared["files"] == %{"blank" => "blank.png"} +    assert resp["count"] == 3 + +    assert resp["packs"] +           |> Map.keys() +           |> length() == 3 + +    shared = resp["packs"]["test_pack"] +    assert shared["files"] == %{"blank" => "blank.png", "blank2" => "blank2.png"}      assert Map.has_key?(shared["pack"], "download-sha256")      assert shared["pack"]["can-download"]      assert shared["pack"]["share-files"] -    non_shared = resp["test_pack_nonshared"] +    non_shared = resp["packs"]["test_pack_nonshared"]      assert non_shared["pack"]["share-files"] == false      assert non_shared["pack"]["can-download"] == false + +    resp = +      conn +      |> get("/api/pleroma/emoji/packs?page_size=1") +      |> json_response_and_validate_schema(200) + +    assert resp["count"] == 3 + +    packs = Map.keys(resp["packs"]) + +    assert length(packs) == 1 + +    [pack1] = packs + +    resp = +      conn +      |> get("/api/pleroma/emoji/packs?page_size=1&page=2") +      |> json_response_and_validate_schema(200) + +    assert resp["count"] == 3 +    packs = Map.keys(resp["packs"]) +    assert length(packs) == 1 +    [pack2] = packs + +    resp = +      conn +      |> get("/api/pleroma/emoji/packs?page_size=1&page=3") +      |> json_response_and_validate_schema(200) + +    assert resp["count"] == 3 +    packs = Map.keys(resp["packs"]) +    assert length(packs) == 1 +    [pack3] = packs +    assert [pack1, pack2, pack3] |> Enum.uniq() |> length() == 3    end    describe "GET /api/pleroma/emoji/packs/remote" do @@ -46,7 +86,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        resp =          conn          |> get("/api/pleroma/emoji/packs") -        |> json_response(200) +        |> json_response_and_validate_schema(200)        mock(fn          %{method: :get, url: "https://example.com/.well-known/nodeinfo"} -> @@ -60,10 +100,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        end)        assert admin_conn -             |> get("/api/pleroma/emoji/packs/remote", %{ -               url: "https://example.com" -             }) -             |> json_response(200) == resp +             |> get("/api/pleroma/emoji/packs/remote?url=https://example.com") +             |> json_response_and_validate_schema(200) == resp      end      test "non shareable instance", %{admin_conn: admin_conn} do @@ -76,8 +114,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        end)        assert admin_conn -             |> get("/api/pleroma/emoji/packs/remote", %{url: "https://example.com"}) -             |> json_response(500) == %{ +             |> get("/api/pleroma/emoji/packs/remote?url=https://example.com") +             |> json_response_and_validate_schema(500) == %{                 "error" => "The requested instance does not support sharing emoji packs"               }      end @@ -99,7 +137,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "non existing pack", %{conn: conn} do        assert conn               |> get("/api/pleroma/emoji/packs/test_pack_for_import/archive") -             |> json_response(:not_found) == %{ +             |> json_response_and_validate_schema(:not_found) == %{                 "error" => "Pack test_pack_for_import does not exist"               }      end @@ -107,7 +145,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "non downloadable pack", %{conn: conn} do        assert conn               |> get("/api/pleroma/emoji/packs/test_pack_nonshared/archive") -             |> json_response(:forbidden) == %{ +             |> json_response_and_validate_schema(:forbidden) == %{                 "error" =>                   "Pack test_pack_nonshared cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"               } @@ -132,7 +170,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do          } ->            conn            |> get("/api/pleroma/emoji/packs/test_pack") -          |> json_response(200) +          |> json_response_and_validate_schema(200)            |> json()          %{ @@ -150,7 +188,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do          } ->            conn            |> get("/api/pleroma/emoji/packs/test_pack_nonshared") -          |> json_response(200) +          |> json_response_and_validate_schema(200)            |> json()          %{ @@ -161,23 +199,25 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/download", %{                 url: "https://example.com",                 name: "test_pack",                 as: "test_pack2"               }) -             |> json_response(200) == "ok" +             |> json_response_and_validate_schema(200) == "ok"        assert File.exists?("#{@emoji_path}/test_pack2/pack.json")        assert File.exists?("#{@emoji_path}/test_pack2/blank.png")        assert admin_conn               |> delete("/api/pleroma/emoji/packs/test_pack2") -             |> json_response(200) == "ok" +             |> json_response_and_validate_schema(200) == "ok"        refute File.exists?("#{@emoji_path}/test_pack2")        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post(                 "/api/pleroma/emoji/packs/download",                 %{ @@ -186,14 +226,14 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do                   as: "test_pack_nonshared2"                 }               ) -             |> json_response(200) == "ok" +             |> json_response_and_validate_schema(200) == "ok"        assert File.exists?("#{@emoji_path}/test_pack_nonshared2/pack.json")        assert File.exists?("#{@emoji_path}/test_pack_nonshared2/blank.png")        assert admin_conn               |> delete("/api/pleroma/emoji/packs/test_pack_nonshared2") -             |> json_response(200) == "ok" +             |> json_response_and_validate_schema(200) == "ok"        refute File.exists?("#{@emoji_path}/test_pack_nonshared2")      end @@ -208,6 +248,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post(                 "/api/pleroma/emoji/packs/download",                 %{ @@ -216,7 +257,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do                   as: "test_pack2"                 }               ) -             |> json_response(500) == %{ +             |> json_response_and_validate_schema(500) == %{                 "error" => "The requested instance does not support sharing emoji packs"               }      end @@ -233,10 +274,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do            method: :get,            url: "https://example.com/api/pleroma/emoji/packs/pack_bad_sha"          } -> -          %Tesla.Env{ -            status: 200, -            body: Pleroma.Emoji.Pack.load_pack("pack_bad_sha") |> Jason.encode!() -          } +          {:ok, pack} = Pleroma.Emoji.Pack.load_pack("pack_bad_sha") +          %Tesla.Env{status: 200, body: Jason.encode!(pack)}          %{            method: :get, @@ -249,12 +288,13 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/download", %{                 url: "https://example.com",                 name: "pack_bad_sha",                 as: "pack_bad_sha2"               }) -             |> json_response(:internal_server_error) == %{ +             |> json_response_and_validate_schema(:internal_server_error) == %{                 "error" => "SHA256 for the pack doesn't match the one sent by the server"               }      end @@ -271,19 +311,18 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do            method: :get,            url: "https://example.com/api/pleroma/emoji/packs/test_pack"          } -> -          %Tesla.Env{ -            status: 200, -            body: Pleroma.Emoji.Pack.load_pack("test_pack") |> Jason.encode!() -          } +          {:ok, pack} = Pleroma.Emoji.Pack.load_pack("test_pack") +          %Tesla.Env{status: 200, body: Jason.encode!(pack)}        end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/download", %{                 url: "https://example.com",                 name: "test_pack",                 as: "test_pack2"               }) -             |> json_response(:internal_server_error) == %{ +             |> json_response_and_validate_schema(:internal_server_error) == %{                 "error" =>                   "The pack was not set as shared and there is no fallback src to download from"               } @@ -311,8 +350,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "for a pack without a fallback source", ctx do        assert ctx[:admin_conn] +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack", %{"metadata" => ctx[:new_data]}) -             |> json_response(200) == ctx[:new_data] +             |> json_response_and_validate_schema(200) == ctx[:new_data]        assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == ctx[:new_data]      end @@ -332,12 +372,13 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do          Map.put(            new_data,            "fallback-src-sha256", -          "74409E2674DAA06C072729C6C8426C4CB3B7E0B85ED77792DB7A436E11D76DAF" +          "1967BB4E42BCC34BCC12D57BE7811D3B7BE52F965BCE45C87BD377B9499CE11D"          )        assert ctx[:admin_conn] +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data}) -             |> json_response(200) == new_data_with_sha +             |> json_response_and_validate_schema(200) == new_data_with_sha        assert Jason.decode!(File.read!(ctx[:pack_file]))["pack"] == new_data_with_sha      end @@ -355,8 +396,9 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        new_data = Map.put(ctx[:new_data], "fallback-src", "https://nonshared-pack")        assert ctx[:admin_conn] +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack", %{metadata: new_data}) -             |> json_response(:bad_request) == %{ +             |> json_response_and_validate_schema(:bad_request) == %{                 "error" => "The fallback archive does not have all files specified in pack.json"               }      end @@ -376,6 +418,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "create shortcode exists", %{admin_conn: admin_conn} do        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{                 shortcode: "blank",                 filename: "dir/blank.png", @@ -384,7 +427,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do                   path: "#{@emoji_path}/test_pack/blank.png"                 }               }) -             |> json_response(:conflict) == %{ +             |> json_response_and_validate_schema(:conflict) == %{                 "error" => "An emoji with the \"blank\" shortcode already exists"               }      end @@ -393,25 +436,31 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir/") end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{ -               shortcode: "blank2", +               shortcode: "blank3",                 filename: "dir/blank.png",                 file: %Plug.Upload{                   filename: "blank.png",                   path: "#{@emoji_path}/test_pack/blank.png"                 }               }) -             |> json_response(200) == %{"blank" => "blank.png", "blank2" => "dir/blank.png"} +             |> json_response_and_validate_schema(200) == %{ +               "blank" => "blank.png", +               "blank2" => "blank2.png", +               "blank3" => "dir/blank.png" +             }        assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack/files", %{                 shortcode: "blank",                 new_shortcode: "blank2",                 new_filename: "dir_2/blank_3.png"               }) -             |> json_response(:conflict) == %{ +             |> json_response_and_validate_schema(:conflict) == %{                 "error" =>                   "New shortcode \"blank2\" is already used. If you want to override emoji use 'force' option"               } @@ -421,28 +470,35 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/dir_2/") end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{ -               shortcode: "blank2", +               shortcode: "blank3",                 filename: "dir/blank.png",                 file: %Plug.Upload{                   filename: "blank.png",                   path: "#{@emoji_path}/test_pack/blank.png"                 }               }) -             |> json_response(200) == %{"blank" => "blank.png", "blank2" => "dir/blank.png"} +             |> json_response_and_validate_schema(200) == %{ +               "blank" => "blank.png", +               "blank2" => "blank2.png", +               "blank3" => "dir/blank.png" +             }        assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ -               shortcode: "blank2", -               new_shortcode: "blank3", +               shortcode: "blank3", +               new_shortcode: "blank4",                 new_filename: "dir_2/blank_3.png",                 force: true               }) -             |> json_response(200) == %{ +             |> json_response_and_validate_schema(200) == %{                 "blank" => "blank.png", -               "blank3" => "dir_2/blank_3.png" +               "blank2" => "blank2.png", +               "blank4" => "dir_2/blank_3.png"               }        assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png") @@ -450,6 +506,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "with empty filename", %{admin_conn: admin_conn} do        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{                 shortcode: "blank2",                 filename: "", @@ -458,52 +515,59 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do                   path: "#{@emoji_path}/test_pack/blank.png"                 }               }) -             |> json_response(:bad_request) == %{ +             |> json_response_and_validate_schema(:bad_request) == %{                 "error" => "pack name, shortcode or filename cannot be empty"               }      end      test "add file with not loaded pack", %{admin_conn: admin_conn} do        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/not_loaded/files", %{ -               shortcode: "blank2", +               shortcode: "blank3",                 filename: "dir/blank.png",                 file: %Plug.Upload{                   filename: "blank.png",                   path: "#{@emoji_path}/test_pack/blank.png"                 }               }) -             |> json_response(:bad_request) == %{ +             |> json_response_and_validate_schema(:bad_request) == %{                 "error" => "pack \"not_loaded\" is not found"               }      end      test "remove file with not loaded pack", %{admin_conn: admin_conn} do        assert admin_conn -             |> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: "blank3"}) -             |> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"} +             |> delete("/api/pleroma/emoji/packs/not_loaded/files?shortcode=blank3") +             |> json_response_and_validate_schema(:bad_request) == %{ +               "error" => "pack \"not_loaded\" is not found" +             }      end      test "remove file with empty shortcode", %{admin_conn: admin_conn} do        assert admin_conn -             |> delete("/api/pleroma/emoji/packs/not_loaded/files", %{shortcode: ""}) -             |> json_response(:bad_request) == %{ +             |> delete("/api/pleroma/emoji/packs/not_loaded/files?shortcode=") +             |> json_response_and_validate_schema(:bad_request) == %{                 "error" => "pack name or shortcode cannot be empty"               }      end      test "update file with not loaded pack", %{admin_conn: admin_conn} do        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/not_loaded/files", %{                 shortcode: "blank4",                 new_shortcode: "blank3",                 new_filename: "dir_2/blank_3.png"               }) -             |> json_response(:bad_request) == %{"error" => "pack \"not_loaded\" is not found"} +             |> json_response_and_validate_schema(:bad_request) == %{ +               "error" => "pack \"not_loaded\" is not found" +             }      end      test "new with shortcode as file with update", %{admin_conn: admin_conn} do        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{                 shortcode: "blank4",                 filename: "dir/blank.png", @@ -512,24 +576,36 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do                   path: "#{@emoji_path}/test_pack/blank.png"                 }               }) -             |> json_response(200) == %{"blank" => "blank.png", "blank4" => "dir/blank.png"} +             |> json_response_and_validate_schema(200) == %{ +               "blank" => "blank.png", +               "blank4" => "dir/blank.png", +               "blank2" => "blank2.png" +             }        assert File.exists?("#{@emoji_path}/test_pack/dir/blank.png")        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack/files", %{                 shortcode: "blank4",                 new_shortcode: "blank3",                 new_filename: "dir_2/blank_3.png"               }) -             |> json_response(200) == %{"blank3" => "dir_2/blank_3.png", "blank" => "blank.png"} +             |> json_response_and_validate_schema(200) == %{ +               "blank3" => "dir_2/blank_3.png", +               "blank" => "blank.png", +               "blank2" => "blank2.png" +             }        refute File.exists?("#{@emoji_path}/test_pack/dir/")        assert File.exists?("#{@emoji_path}/test_pack/dir_2/blank_3.png")        assert admin_conn -             |> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank3"}) -             |> json_response(200) == %{"blank" => "blank.png"} +             |> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3") +             |> json_response_and_validate_schema(200) == %{ +               "blank" => "blank.png", +               "blank2" => "blank2.png" +             }        refute File.exists?("#{@emoji_path}/test_pack/dir_2/") @@ -546,13 +622,15 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{                 shortcode: "blank_url",                 file: "https://test-blank/blank_url.png"               }) -             |> json_response(200) == %{ +             |> json_response_and_validate_schema(200) == %{                 "blank_url" => "blank_url.png", -               "blank" => "blank.png" +               "blank" => "blank.png", +               "blank2" => "blank2.png"               }        assert File.exists?("#{@emoji_path}/test_pack/blank_url.png") @@ -564,40 +642,52 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        on_exit(fn -> File.rm_rf!("#{@emoji_path}/test_pack/shortcode.png") end)        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> post("/api/pleroma/emoji/packs/test_pack/files", %{                 file: %Plug.Upload{                   filename: "shortcode.png",                   path: "#{Pleroma.Config.get([:instance, :static_dir])}/add/shortcode.png"                 }               }) -             |> json_response(200) == %{"shortcode" => "shortcode.png", "blank" => "blank.png"} +             |> json_response_and_validate_schema(200) == %{ +               "shortcode" => "shortcode.png", +               "blank" => "blank.png", +               "blank2" => "blank2.png" +             }      end      test "remove non existing shortcode in pack.json", %{admin_conn: admin_conn} do        assert admin_conn -             |> delete("/api/pleroma/emoji/packs/test_pack/files", %{shortcode: "blank2"}) -             |> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"} +             |> delete("/api/pleroma/emoji/packs/test_pack/files?shortcode=blank3") +             |> json_response_and_validate_schema(:bad_request) == %{ +               "error" => "Emoji \"blank3\" does not exist" +             }      end      test "update non existing emoji", %{admin_conn: admin_conn} do        assert admin_conn +             |> put_req_header("content-type", "multipart/form-data")               |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ -               shortcode: "blank2", -               new_shortcode: "blank3", +               shortcode: "blank3", +               new_shortcode: "blank4",                 new_filename: "dir_2/blank_3.png"               }) -             |> json_response(:bad_request) == %{"error" => "Emoji \"blank2\" does not exist"} +             |> json_response_and_validate_schema(:bad_request) == %{ +               "error" => "Emoji \"blank3\" does not exist" +             }      end      test "update with empty shortcode", %{admin_conn: admin_conn} do -      assert admin_conn -             |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ -               shortcode: "blank", -               new_filename: "dir_2/blank_3.png" -             }) -             |> json_response(:bad_request) == %{ -               "error" => "new_shortcode or new_filename cannot be empty" -             } +      assert %{ +               "error" => "Missing field: new_shortcode." +             } = +               admin_conn +               |> put_req_header("content-type", "multipart/form-data") +               |> patch("/api/pleroma/emoji/packs/test_pack/files", %{ +                 shortcode: "blank", +                 new_filename: "dir_2/blank_3.png" +               }) +               |> json_response_and_validate_schema(:bad_request)      end    end @@ -605,18 +695,19 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "creating and deleting a pack", %{admin_conn: admin_conn} do        assert admin_conn               |> post("/api/pleroma/emoji/packs/test_created") -             |> json_response(200) == "ok" +             |> json_response_and_validate_schema(200) == "ok"        assert File.exists?("#{@emoji_path}/test_created/pack.json")        assert Jason.decode!(File.read!("#{@emoji_path}/test_created/pack.json")) == %{                 "pack" => %{}, -               "files" => %{} +               "files" => %{}, +               "files_count" => 0               }        assert admin_conn               |> delete("/api/pleroma/emoji/packs/test_created") -             |> json_response(200) == "ok" +             |> json_response_and_validate_schema(200) == "ok"        refute File.exists?("#{@emoji_path}/test_created/pack.json")      end @@ -629,7 +720,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        assert admin_conn               |> post("/api/pleroma/emoji/packs/test_created") -             |> json_response(:conflict) == %{ +             |> json_response_and_validate_schema(:conflict) == %{                 "error" => "A pack named \"test_created\" already exists"               } @@ -639,20 +730,26 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      test "with empty name", %{admin_conn: admin_conn} do        assert admin_conn               |> post("/api/pleroma/emoji/packs/ ") -             |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} +             |> json_response_and_validate_schema(:bad_request) == %{ +               "error" => "pack name cannot be empty" +             }      end    end    test "deleting nonexisting pack", %{admin_conn: admin_conn} do      assert admin_conn             |> delete("/api/pleroma/emoji/packs/non_existing") -           |> json_response(:not_found) == %{"error" => "Pack non_existing does not exist"} +           |> json_response_and_validate_schema(:not_found) == %{ +             "error" => "Pack non_existing does not exist" +           }    end    test "deleting with empty name", %{admin_conn: admin_conn} do      assert admin_conn             |> delete("/api/pleroma/emoji/packs/ ") -           |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} +           |> json_response_and_validate_schema(:bad_request) == %{ +             "error" => "pack name cannot be empty" +           }    end    test "filesystem import", %{admin_conn: admin_conn, conn: conn} do @@ -661,16 +758,16 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do        File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")      end) -    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) +    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200) -    refute Map.has_key?(resp, "test_pack_for_import") +    refute Map.has_key?(resp["packs"], "test_pack_for_import")      assert admin_conn             |> get("/api/pleroma/emoji/packs/import") -           |> json_response(200) == ["test_pack_for_import"] +           |> json_response_and_validate_schema(200) == ["test_pack_for_import"] -    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) -    assert resp["test_pack_for_import"]["files"] == %{"blank" => "blank.png"} +    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200) +    assert resp["packs"]["test_pack_for_import"]["files"] == %{"blank" => "blank.png"}      File.rm!("#{@emoji_path}/test_pack_for_import/pack.json")      refute File.exists?("#{@emoji_path}/test_pack_for_import/pack.json") @@ -686,11 +783,11 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do      assert admin_conn             |> get("/api/pleroma/emoji/packs/import") -           |> json_response(200) == ["test_pack_for_import"] +           |> json_response_and_validate_schema(200) == ["test_pack_for_import"] -    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response(200) +    resp = conn |> get("/api/pleroma/emoji/packs") |> json_response_and_validate_schema(200) -    assert resp["test_pack_for_import"]["files"] == %{ +    assert resp["packs"]["test_pack_for_import"]["files"] == %{               "blank" => "blank.png",               "blank2" => "blank.png",               "foo" => "blank.png" @@ -700,7 +797,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do    describe "GET /api/pleroma/emoji/packs/:name" do      test "shows pack.json", %{conn: conn} do        assert %{ -               "files" => %{"blank" => "blank.png"}, +               "files" => files, +               "files_count" => 2,                 "pack" => %{                   "can-download" => true,                   "description" => "Test description", @@ -712,19 +810,45 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIControllerTest do               } =                 conn                 |> get("/api/pleroma/emoji/packs/test_pack") -               |> json_response(200) +               |> json_response_and_validate_schema(200) + +      assert files == %{"blank" => "blank.png", "blank2" => "blank2.png"} + +      assert %{ +               "files" => files, +               "files_count" => 2 +             } = +               conn +               |> get("/api/pleroma/emoji/packs/test_pack?page_size=1") +               |> json_response_and_validate_schema(200) + +      assert files |> Map.keys() |> length() == 1 + +      assert %{ +               "files" => files, +               "files_count" => 2 +             } = +               conn +               |> get("/api/pleroma/emoji/packs/test_pack?page_size=1&page=2") +               |> json_response_and_validate_schema(200) + +      assert files |> Map.keys() |> length() == 1      end      test "non existing pack", %{conn: conn} do        assert conn               |> get("/api/pleroma/emoji/packs/non_existing") -             |> json_response(:not_found) == %{"error" => "Pack non_existing does not exist"} +             |> json_response_and_validate_schema(:not_found) == %{ +               "error" => "Pack non_existing does not exist" +             }      end      test "error name", %{conn: conn} do        assert conn               |> get("/api/pleroma/emoji/packs/ ") -             |> json_response(:bad_request) == %{"error" => "pack name cannot be empty"} +             |> json_response_and_validate_schema(:bad_request) == %{ +               "error" => "pack name cannot be empty" +             }      end    end  end diff --git a/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs new file mode 100644 index 000000000..e1bb5ebfe --- /dev/null +++ b/test/web/pleroma_api/controllers/emoji_reaction_controller_test.exs @@ -0,0 +1,132 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do +  use Oban.Testing, repo: Pleroma.Repo +  use Pleroma.Web.ConnCase + +  alias Pleroma.Object +  alias Pleroma.Tests.ObanHelpers +  alias Pleroma.User +  alias Pleroma.Web.CommonAPI + +  import Pleroma.Factory + +  test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) + +    result = +      conn +      |> assign(:user, other_user) +      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"])) +      |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕") +      |> json_response_and_validate_schema(200) + +    # We return the status, but this our implementation detail. +    assert %{"id" => id} = result +    assert to_string(activity.id) == id + +    assert result["pleroma"]["emoji_reactions"] == [ +             %{"name" => "☕", "count" => 1, "me" => true} +           ] + +    # Reacting with a non-emoji +    assert conn +           |> assign(:user, other_user) +           |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"])) +           |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/x") +           |> json_response_and_validate_schema(400) +  end + +  test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) +    {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + +    ObanHelpers.perform_all() + +    result = +      conn +      |> assign(:user, other_user) +      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"])) +      |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕") + +    assert %{"id" => id} = json_response_and_validate_schema(result, 200) +    assert to_string(activity.id) == id + +    ObanHelpers.perform_all() + +    object = Object.get_by_ap_id(activity.data["object"]) + +    assert object.data["reaction_count"] == 0 +  end + +  test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) +    doomed_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) + +    result = +      conn +      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") +      |> json_response_and_validate_schema(200) + +    assert result == [] + +    {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") +    {:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅") + +    User.perform(:delete, doomed_user) + +    result = +      conn +      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") +      |> json_response_and_validate_schema(200) + +    [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result + +    assert represented_user["id"] == other_user.id + +    result = +      conn +      |> assign(:user, other_user) +      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:statuses"])) +      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") +      |> json_response_and_validate_schema(200) + +    assert [%{"name" => "🎅", "count" => 1, "accounts" => [_represented_user], "me" => true}] = +             result +  end + +  test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do +    user = insert(:user) +    other_user = insert(:user) + +    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) + +    result = +      conn +      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅") +      |> json_response_and_validate_schema(200) + +    assert result == [] + +    {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") +    {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") + +    assert [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = +             conn +             |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅") +             |> json_response_and_validate_schema(200) + +    assert represented_user["id"] == other_user.id +  end +end diff --git a/test/web/pleroma_api/controllers/mascot_controller_test.exs b/test/web/pleroma_api/controllers/mascot_controller_test.exs index 617831b02..e2ead6e15 100644 --- a/test/web/pleroma_api/controllers/mascot_controller_test.exs +++ b/test/web/pleroma_api/controllers/mascot_controller_test.exs @@ -16,9 +16,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do        filename: "sound.mp3"      } -    ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => non_image_file}) +    ret_conn = +      conn +      |> put_req_header("content-type", "multipart/form-data") +      |> put("/api/v1/pleroma/mascot", %{"file" => non_image_file}) -    assert json_response(ret_conn, 415) +    assert json_response_and_validate_schema(ret_conn, 415)      file = %Plug.Upload{        content_type: "image/jpg", @@ -26,9 +29,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do        filename: "an_image.jpg"      } -    conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file}) +    conn = +      conn +      |> put_req_header("content-type", "multipart/form-data") +      |> put("/api/v1/pleroma/mascot", %{"file" => file}) -    assert %{"id" => _, "type" => image} = json_response(conn, 200) +    assert %{"id" => _, "type" => image} = json_response_and_validate_schema(conn, 200)    end    test "mascot retrieving" do @@ -37,7 +43,7 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do      # When user hasn't set a mascot, we should just get pleroma tan back      ret_conn = get(conn, "/api/v1/pleroma/mascot") -    assert %{"url" => url} = json_response(ret_conn, 200) +    assert %{"url" => url} = json_response_and_validate_schema(ret_conn, 200)      assert url =~ "pleroma-fox-tan-smol"      # When a user sets their mascot, we should get that back @@ -47,9 +53,12 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do        filename: "an_image.jpg"      } -    ret_conn = put(conn, "/api/v1/pleroma/mascot", %{"file" => file}) +    ret_conn = +      conn +      |> put_req_header("content-type", "multipart/form-data") +      |> put("/api/v1/pleroma/mascot", %{"file" => file}) -    assert json_response(ret_conn, 200) +    assert json_response_and_validate_schema(ret_conn, 200)      user = User.get_cached_by_id(user.id) @@ -58,7 +67,7 @@ defmodule Pleroma.Web.PleromaAPI.MascotControllerTest do        |> assign(:user, user)        |> get("/api/v1/pleroma/mascot") -    assert %{"url" => url, "type" => "image"} = json_response(conn, 200) +    assert %{"url" => url, "type" => "image"} = json_response_and_validate_schema(conn, 200)      assert url =~ "an_image"    end  end diff --git a/test/web/pleroma_api/controllers/notification_controller_test.exs b/test/web/pleroma_api/controllers/notification_controller_test.exs new file mode 100644 index 000000000..bb4fe6c49 --- /dev/null +++ b/test/web/pleroma_api/controllers/notification_controller_test.exs @@ -0,0 +1,68 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.NotificationControllerTest do +  use Pleroma.Web.ConnCase + +  alias Pleroma.Notification +  alias Pleroma.Repo +  alias Pleroma.Web.CommonAPI + +  import Pleroma.Factory + +  describe "POST /api/v1/pleroma/notifications/read" do +    setup do: oauth_access(["write:notifications"]) + +    test "it marks a single notification as read", %{user: user1, conn: conn} do +      user2 = insert(:user) +      {:ok, activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) +      {:ok, activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) +      {:ok, [notification1]} = Notification.create_notifications(activity1) +      {:ok, [notification2]} = Notification.create_notifications(activity2) + +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/notifications/read", %{id: notification1.id}) +        |> json_response_and_validate_schema(:ok) + +      assert %{"pleroma" => %{"is_seen" => true}} = response +      assert Repo.get(Notification, notification1.id).seen +      refute Repo.get(Notification, notification2.id).seen +    end + +    test "it marks multiple notifications as read", %{user: user1, conn: conn} do +      user2 = insert(:user) +      {:ok, _activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) +      {:ok, _activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) +      {:ok, _activity3} = CommonAPI.post(user2, %{status: "HIE @#{user1.nickname}"}) + +      [notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3}) + +      [response1, response2] = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/notifications/read", %{max_id: notification2.id}) +        |> json_response_and_validate_schema(:ok) + +      assert %{"pleroma" => %{"is_seen" => true}} = response1 +      assert %{"pleroma" => %{"is_seen" => true}} = response2 +      assert Repo.get(Notification, notification1.id).seen +      assert Repo.get(Notification, notification2.id).seen +      refute Repo.get(Notification, notification3.id).seen +    end + +    test "it returns error when notification not found", %{conn: conn} do +      response = +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/notifications/read", %{ +          id: 22_222_222_222_222 +        }) +        |> json_response_and_validate_schema(:bad_request) + +      assert response == %{"error" => "Cannot get notification"} +    end +  end +end diff --git a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs b/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs deleted file mode 100644 index cfd1dbd24..000000000 --- a/test/web/pleroma_api/controllers/pleroma_api_controller_test.exs +++ /dev/null @@ -1,302 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do -  use Oban.Testing, repo: Pleroma.Repo -  use Pleroma.Web.ConnCase - -  alias Pleroma.Conversation.Participation -  alias Pleroma.Notification -  alias Pleroma.Object -  alias Pleroma.Repo -  alias Pleroma.Tests.ObanHelpers -  alias Pleroma.User -  alias Pleroma.Web.CommonAPI - -  import Pleroma.Factory - -  test "PUT /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do -    user = insert(:user) -    other_user = insert(:user) - -    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) - -    result = -      conn -      |> assign(:user, other_user) -      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"])) -      |> put("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕") -      |> json_response(200) - -    # We return the status, but this our implementation detail. -    assert %{"id" => id} = result -    assert to_string(activity.id) == id - -    assert result["pleroma"]["emoji_reactions"] == [ -             %{"name" => "☕", "count" => 1, "me" => true} -           ] -  end - -  test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do -    user = insert(:user) -    other_user = insert(:user) - -    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) -    {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") - -    ObanHelpers.perform_all() - -    result = -      conn -      |> assign(:user, other_user) -      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["write:statuses"])) -      |> delete("/api/v1/pleroma/statuses/#{activity.id}/reactions/☕") - -    assert %{"id" => id} = json_response(result, 200) -    assert to_string(activity.id) == id - -    ObanHelpers.perform_all() - -    object = Object.get_by_ap_id(activity.data["object"]) - -    assert object.data["reaction_count"] == 0 -  end - -  test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do -    user = insert(:user) -    other_user = insert(:user) -    doomed_user = insert(:user) - -    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) - -    result = -      conn -      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") -      |> json_response(200) - -    assert result == [] - -    {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") -    {:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅") - -    User.perform(:delete, doomed_user) - -    result = -      conn -      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") -      |> json_response(200) - -    [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result - -    assert represented_user["id"] == other_user.id - -    result = -      conn -      |> assign(:user, other_user) -      |> assign(:token, insert(:oauth_token, user: other_user, scopes: ["read:statuses"])) -      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions") -      |> json_response(200) - -    assert [%{"name" => "🎅", "count" => 1, "accounts" => [_represented_user], "me" => true}] = -             result -  end - -  test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do -    user = insert(:user) -    other_user = insert(:user) - -    {:ok, activity} = CommonAPI.post(user, %{status: "#cofe"}) - -    result = -      conn -      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅") -      |> json_response(200) - -    assert result == [] - -    {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") -    {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "☕") - -    result = -      conn -      |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions/🎅") -      |> json_response(200) - -    [%{"name" => "🎅", "count" => 1, "accounts" => [represented_user], "me" => false}] = result - -    assert represented_user["id"] == other_user.id -  end - -  test "/api/v1/pleroma/conversations/:id" do -    user = insert(:user) -    %{user: other_user, conn: conn} = oauth_access(["read:statuses"]) - -    {:ok, _activity} = -      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"}) - -    [participation] = Participation.for_user(other_user) - -    result = -      conn -      |> get("/api/v1/pleroma/conversations/#{participation.id}") -      |> json_response(200) - -    assert result["id"] == participation.id |> to_string() -  end - -  test "/api/v1/pleroma/conversations/:id/statuses" do -    user = insert(:user) -    %{user: other_user, conn: conn} = oauth_access(["read:statuses"]) -    third_user = insert(:user) - -    {:ok, _activity} = -      CommonAPI.post(user, %{status: "Hi @#{third_user.nickname}!", visibility: "direct"}) - -    {:ok, activity} = -      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}!", visibility: "direct"}) - -    [participation] = Participation.for_user(other_user) - -    {:ok, activity_two} = -      CommonAPI.post(other_user, %{ -        status: "Hi!", -        in_reply_to_status_id: activity.id, -        in_reply_to_conversation_id: participation.id -      }) - -    result = -      conn -      |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses") -      |> json_response(200) - -    assert length(result) == 2 - -    id_one = activity.id -    id_two = activity_two.id -    assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result - -    {:ok, %{id: id_three}} = -      CommonAPI.post(other_user, %{ -        status: "Bye!", -        in_reply_to_status_id: activity.id, -        in_reply_to_conversation_id: participation.id -      }) - -    assert [%{"id" => ^id_two}, %{"id" => ^id_three}] = -             conn -             |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?limit=2") -             |> json_response(:ok) - -    assert [%{"id" => ^id_three}] = -             conn -             |> get("/api/v1/pleroma/conversations/#{participation.id}/statuses?min_id=#{id_two}") -             |> json_response(:ok) -  end - -  test "PATCH /api/v1/pleroma/conversations/:id" do -    %{user: user, conn: conn} = oauth_access(["write:conversations"]) -    other_user = insert(:user) - -    {:ok, _activity} = CommonAPI.post(user, %{status: "Hi", visibility: "direct"}) - -    [participation] = Participation.for_user(user) - -    participation = Repo.preload(participation, :recipients) - -    user = User.get_cached_by_id(user.id) -    assert [user] == participation.recipients -    assert other_user not in participation.recipients - -    result = -      conn -      |> patch("/api/v1/pleroma/conversations/#{participation.id}", %{ -        "recipients" => [user.id, other_user.id] -      }) -      |> json_response(200) - -    assert result["id"] == participation.id |> to_string - -    [participation] = Participation.for_user(user) -    participation = Repo.preload(participation, :recipients) - -    assert user in participation.recipients -    assert other_user in participation.recipients -  end - -  test "POST /api/v1/pleroma/conversations/read" do -    user = insert(:user) -    %{user: other_user, conn: conn} = oauth_access(["write:conversations"]) - -    {:ok, _activity} = -      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"}) - -    {:ok, _activity} = -      CommonAPI.post(user, %{status: "Hi @#{other_user.nickname}", visibility: "direct"}) - -    [participation2, participation1] = Participation.for_user(other_user) -    assert Participation.get(participation2.id).read == false -    assert Participation.get(participation1.id).read == false -    assert User.get_cached_by_id(other_user.id).unread_conversation_count == 2 - -    [%{"unread" => false}, %{"unread" => false}] = -      conn -      |> post("/api/v1/pleroma/conversations/read", %{}) -      |> json_response(200) - -    [participation2, participation1] = Participation.for_user(other_user) -    assert Participation.get(participation2.id).read == true -    assert Participation.get(participation1.id).read == true -    assert User.get_cached_by_id(other_user.id).unread_conversation_count == 0 -  end - -  describe "POST /api/v1/pleroma/notifications/read" do -    setup do: oauth_access(["write:notifications"]) - -    test "it marks a single notification as read", %{user: user1, conn: conn} do -      user2 = insert(:user) -      {:ok, activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) -      {:ok, activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) -      {:ok, [notification1]} = Notification.create_notifications(activity1) -      {:ok, [notification2]} = Notification.create_notifications(activity2) - -      response = -        conn -        |> post("/api/v1/pleroma/notifications/read", %{"id" => "#{notification1.id}"}) -        |> json_response(:ok) - -      assert %{"pleroma" => %{"is_seen" => true}} = response -      assert Repo.get(Notification, notification1.id).seen -      refute Repo.get(Notification, notification2.id).seen -    end - -    test "it marks multiple notifications as read", %{user: user1, conn: conn} do -      user2 = insert(:user) -      {:ok, _activity1} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) -      {:ok, _activity2} = CommonAPI.post(user2, %{status: "hi @#{user1.nickname}"}) -      {:ok, _activity3} = CommonAPI.post(user2, %{status: "HIE @#{user1.nickname}"}) - -      [notification3, notification2, notification1] = Notification.for_user(user1, %{limit: 3}) - -      [response1, response2] = -        conn -        |> post("/api/v1/pleroma/notifications/read", %{"max_id" => "#{notification2.id}"}) -        |> json_response(:ok) - -      assert %{"pleroma" => %{"is_seen" => true}} = response1 -      assert %{"pleroma" => %{"is_seen" => true}} = response2 -      assert Repo.get(Notification, notification1.id).seen -      assert Repo.get(Notification, notification2.id).seen -      refute Repo.get(Notification, notification3.id).seen -    end - -    test "it returns error when notification not found", %{conn: conn} do -      response = -        conn -        |> post("/api/v1/pleroma/notifications/read", %{"id" => "22222222222222"}) -        |> json_response(:bad_request) - -      assert response == %{"error" => "Cannot get notification"} -    end -  end -end diff --git a/test/web/pleroma_api/controllers/scrobble_controller_test.exs b/test/web/pleroma_api/controllers/scrobble_controller_test.exs index 1b945040c..f39c07ac6 100644 --- a/test/web/pleroma_api/controllers/scrobble_controller_test.exs +++ b/test/web/pleroma_api/controllers/scrobble_controller_test.exs @@ -12,14 +12,16 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do        %{conn: conn} = oauth_access(["write"])        conn = -        post(conn, "/api/v1/pleroma/scrobble", %{ +        conn +        |> put_req_header("content-type", "application/json") +        |> post("/api/v1/pleroma/scrobble", %{            "title" => "lain radio episode 1",            "artist" => "lain",            "album" => "lain radio",            "length" => "180000"          }) -      assert %{"title" => "lain radio episode 1"} = json_response(conn, 200) +      assert %{"title" => "lain radio episode 1"} = json_response_and_validate_schema(conn, 200)      end    end @@ -29,28 +31,28 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleControllerTest do        {:ok, _activity} =          CommonAPI.listen(user, %{ -          "title" => "lain radio episode 1", -          "artist" => "lain", -          "album" => "lain radio" +          title: "lain radio episode 1", +          artist: "lain", +          album: "lain radio"          })        {:ok, _activity} =          CommonAPI.listen(user, %{ -          "title" => "lain radio episode 2", -          "artist" => "lain", -          "album" => "lain radio" +          title: "lain radio episode 2", +          artist: "lain", +          album: "lain radio"          })        {:ok, _activity} =          CommonAPI.listen(user, %{ -          "title" => "lain radio episode 3", -          "artist" => "lain", -          "album" => "lain radio" +          title: "lain radio episode 3", +          artist: "lain", +          album: "lain radio"          })        conn = get(conn, "/api/v1/pleroma/accounts/#{user.id}/scrobbles") -      result = json_response(conn, 200) +      result = json_response_and_validate_schema(conn, 200)        assert length(result) == 3      end | 
