Add OpenAPI spec for ConversationController
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 5 May 2020 13:44:46 +0000 (17:44 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 5 May 2020 13:44:46 +0000 (17:44 +0400)
lib/pleroma/conversation/participation.ex
lib/pleroma/web/api_spec/operations/conversation_operation.ex [new file with mode: 0644]
lib/pleroma/web/api_spec/schemas/conversation.ex [new file with mode: 0644]
lib/pleroma/web/api_spec/schemas/status.ex
lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
test/web/mastodon_api/controllers/conversation_controller_test.exs

index 215265fc90a201c8c24539e9c0cc632bbea62699..51bb1bda94d43e85043d3c930896f4462565a2ca 100644 (file)
@@ -128,7 +128,7 @@ defmodule Pleroma.Conversation.Participation do
     |> Pleroma.Pagination.fetch_paginated(params)
   end
 
-  def restrict_recipients(query, user, %{"recipients" => user_ids}) do
+  def restrict_recipients(query, user, %{recipients: user_ids}) do
     user_binary_ids =
       [user.id | user_ids]
       |> Enum.uniq()
@@ -172,7 +172,7 @@ defmodule Pleroma.Conversation.Participation do
         | last_activity_id: activity_id
       }
     end)
-    |> Enum.filter(& &1.last_activity_id)
+    |> Enum.reject(&is_nil(&1.last_activity_id))
   end
 
   def get(_, _ \\ [])
diff --git a/lib/pleroma/web/api_spec/operations/conversation_operation.ex b/lib/pleroma/web/api_spec/operations/conversation_operation.ex
new file mode 100644 (file)
index 0000000..4754688
--- /dev/null
@@ -0,0 +1,61 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ApiSpec.ConversationOperation do
+  alias OpenApiSpex.Operation
+  alias OpenApiSpex.Schema
+  alias Pleroma.Web.ApiSpec.Schemas.Conversation
+  alias Pleroma.Web.ApiSpec.Schemas.FlakeID
+
+  import Pleroma.Web.ApiSpec.Helpers
+
+  def open_api_operation(action) do
+    operation = String.to_existing_atom("#{action}_operation")
+    apply(__MODULE__, operation, [])
+  end
+
+  def index_operation do
+    %Operation{
+      tags: ["Conversations"],
+      summary: "Show conversation",
+      security: [%{"oAuth" => ["read:statuses"]}],
+      operationId: "ConversationController.index",
+      parameters: [
+        Operation.parameter(
+          :recipients,
+          :query,
+          %Schema{type: :array, items: FlakeID},
+          "Only return conversations with the given recipients (a list of user ids)"
+        )
+        | pagination_params()
+      ],
+      responses: %{
+        200 =>
+          Operation.response("Array of Conversation", "application/json", %Schema{
+            type: :array,
+            items: Conversation,
+            example: [Conversation.schema().example]
+          })
+      }
+    }
+  end
+
+  def mark_as_read_operation do
+    %Operation{
+      tags: ["Conversations"],
+      summary: "Mark as read",
+      operationId: "ConversationController.mark_as_read",
+      parameters: [
+        Operation.parameter(:id, :path, :string, "Conversation ID",
+          example: "123",
+          required: true
+        )
+      ],
+      security: [%{"oAuth" => ["write:conversations"]}],
+      responses: %{
+        200 => Operation.response("Conversation", "application/json", Conversation)
+      }
+    }
+  end
+end
diff --git a/lib/pleroma/web/api_spec/schemas/conversation.ex b/lib/pleroma/web/api_spec/schemas/conversation.ex
new file mode 100644 (file)
index 0000000..d8ff5ba
--- /dev/null
@@ -0,0 +1,41 @@
+# 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.Schemas.Conversation do
+  alias OpenApiSpex.Schema
+  alias Pleroma.Web.ApiSpec.Schemas.Account
+  alias Pleroma.Web.ApiSpec.Schemas.Status
+
+  require OpenApiSpex
+
+  OpenApiSpex.schema(%{
+    title: "Conversation",
+    description: "Represents a conversation with \"direct message\" visibility.",
+    type: :object,
+    required: [:id, :accounts, :unread],
+    properties: %{
+      id: %Schema{type: :string},
+      accounts: %Schema{
+        type: :array,
+        items: Account,
+        description: "Participants in the conversation"
+      },
+      unread: %Schema{
+        type: :boolean,
+        description: "Is the conversation currently marked as unread?"
+      },
+      # last_status: Status
+      last_status: %Schema{
+        allOf: [Status],
+        description: "The last status in the conversation, to be used for optional display"
+      }
+    },
+    example: %{
+      "id" => "418450",
+      "unread" => true,
+      "accounts" => [Account.schema().example],
+      "last_status" => Status.schema().example
+    }
+  })
+end
index aef0588d43d29965fe31b376c28a8d6843053e89..42e9dae19fdae009d6e69d7a21652ec7b0cc8d6c 100644 (file)
@@ -86,7 +86,12 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
         properties: %{
           content: %Schema{type: :object, additionalProperties: %Schema{type: :string}},
           conversation_id: %Schema{type: :integer},
-          direct_conversation_id: %Schema{type: :string, nullable: true},
+          direct_conversation_id: %Schema{
+            type: :integer,
+            nullable: true,
+            description:
+              "The ID of the Mastodon direct message conversation the status is associated with (if any)"
+          },
           emoji_reactions: %Schema{
             type: :array,
             items: %Schema{
index c446415261978ef0a2dabbdd8d921ff6699ff696..f35ec3596589c902da4e5a79d06ad09291c9dbf6 100644 (file)
@@ -13,9 +13,12 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
 
   action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
 
+  plug(Pleroma.Web.ApiSpec.CastAndValidate)
   plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action == :index)
   plug(OAuthScopesPlug, %{scopes: ["write:conversations"]} when action != :index)
 
+  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ConversationOperation
+
   @doc "GET /api/v1/conversations"
   def index(%{assigns: %{user: user}} = conn, params) do
     participations = Participation.for_user_with_last_activity_id(user, params)
@@ -26,7 +29,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
   end
 
   @doc "POST /api/v1/conversations/:id/read"
-  def mark_as_read(%{assigns: %{user: user}} = conn, %{"id" => participation_id}) do
+  def mark_as_read(%{assigns: %{user: user}} = conn, %{id: participation_id}) do
     with %Participation{} = participation <-
            Repo.get_by(Participation, id: participation_id, user_id: user.id),
          {:ok, participation} <- Participation.mark_as_read(participation) do
index 801b0259b90a140c184b8d2006254a14f3ced4fd..04695572e3269cdb576eb7e95a93c6f6f01a0e27 100644 (file)
@@ -36,7 +36,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
 
     res_conn = get(conn, "/api/v1/conversations")
 
-    assert response = json_response(res_conn, 200)
+    assert response = json_response_and_validate_schema(res_conn, 200)
 
     assert [
              %{
@@ -91,18 +91,18 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
         "visibility" => "direct"
       })
 
-    [conversation1, conversation2] =
-      conn
-      |> get("/api/v1/conversations", %{"recipients" => [user_two.id]})
-      |> json_response(200)
+    assert [conversation1, conversation2] =
+             conn
+             |> get("/api/v1/conversations?recipients[]=#{user_two.id}")
+             |> json_response_and_validate_schema(200)
 
     assert conversation1["last_status"]["id"] == direct5.id
     assert conversation2["last_status"]["id"] == direct1.id
 
     [conversation1] =
       conn
-      |> get("/api/v1/conversations", %{"recipients" => [user_two.id, user_three.id]})
-      |> json_response(200)
+      |> get("/api/v1/conversations?recipients[]=#{user_two.id}&recipients[]=#{user_three.id}")
+      |> json_response_and_validate_schema(200)
 
     assert conversation1["last_status"]["id"] == direct3.id
   end
@@ -126,7 +126,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
     [%{"last_status" => res_last_status}] =
       conn
       |> get("/api/v1/conversations")
-      |> json_response(200)
+      |> json_response_and_validate_schema(200)
 
     assert res_last_status["id"] == direct_reply.id
   end
@@ -154,12 +154,12 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
     [%{"id" => direct_conversation_id, "unread" => true}] =
       user_two_conn
       |> get("/api/v1/conversations")
-      |> json_response(200)
+      |> json_response_and_validate_schema(200)
 
     %{"unread" => false} =
       user_two_conn
       |> post("/api/v1/conversations/#{direct_conversation_id}/read")
-      |> json_response(200)
+      |> json_response_and_validate_schema(200)
 
     assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
     assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
@@ -175,7 +175,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
     [%{"unread" => true}] =
       conn
       |> get("/api/v1/conversations")
-      |> json_response(200)
+      |> json_response_and_validate_schema(200)
 
     assert User.get_cached_by_id(user_one.id).unread_conversation_count == 1
     assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0