Add OpenAPI spec for ReportController
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 28 Apr 2020 12:50:37 +0000 (16:50 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 28 Apr 2020 12:50:37 +0000 (16:50 +0400)
lib/pleroma/web/api_spec/operations/report_operation.ex [new file with mode: 0644]
lib/pleroma/web/common_api/common_api.ex
lib/pleroma/web/common_api/utils.ex
lib/pleroma/web/mastodon_api/controllers/report_controller.ex
test/web/admin_api/admin_api_controller_test.exs
test/web/admin_api/views/report_view_test.exs
test/web/common_api/common_api_test.exs
test/web/mastodon_api/controllers/report_controller_test.exs

diff --git a/lib/pleroma/web/api_spec/operations/report_operation.ex b/lib/pleroma/web/api_spec/operations/report_operation.ex
new file mode 100644 (file)
index 0000000..da4d507
--- /dev/null
@@ -0,0 +1,78 @@
+# 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.ReportOperation do
+  alias OpenApiSpex.Operation
+  alias OpenApiSpex.Schema
+  alias Pleroma.Web.ApiSpec.Helpers
+  alias Pleroma.Web.ApiSpec.Schemas.ApiError
+
+  def open_api_operation(action) do
+    operation = String.to_existing_atom("#{action}_operation")
+    apply(__MODULE__, operation, [])
+  end
+
+  def create_operation do
+    %Operation{
+      tags: ["reports"],
+      summary: "File a report",
+      description: "Report problematic users to your moderators",
+      operationId: "ReportController.create",
+      security: [%{"oAuth" => ["follow", "write:reports"]}],
+      requestBody: Helpers.request_body("Parameters", create_request(), required: true),
+      responses: %{
+        200 => Operation.response("Report", "application/json", create_response()),
+        400 => Operation.response("Report", "application/json", ApiError)
+      }
+    }
+  end
+
+  defp create_request do
+    %Schema{
+      title: "ReportCreateRequest",
+      description: "POST body for creating a report",
+      type: :object,
+      properties: %{
+        account_id: %Schema{type: :string, description: "ID of the account to report"},
+        status_ids: %Schema{
+          type: :array,
+          items: %Schema{type: :string},
+          description: "Array of Statuses to attach to the report, for context"
+        },
+        comment: %Schema{
+          type: :string,
+          description: "Reason for the report"
+        },
+        forward: %Schema{
+          type: :boolean,
+          default: false,
+          description:
+            "If the account is remote, should the report be forwarded to the remote admin?"
+        }
+      },
+      required: [:account_id],
+      example: %{
+        "account_id" => "123",
+        "status_ids" => ["1337"],
+        "comment" => "bad status!",
+        "forward" => "false"
+      }
+    }
+  end
+
+  defp create_response do
+    %Schema{
+      title: "ReportResponse",
+      type: :object,
+      properties: %{
+        id: %Schema{type: :string, description: "Report ID"},
+        action_taken: %Schema{type: :boolean, description: "Is action taken?"}
+      },
+      example: %{
+        "id" => "123",
+        "action_taken" => false
+      }
+    }
+  end
+end
index d1efe0c36e0d1a19eb9377d700639c2434ef8bb0..53ce7d425735aa4caf4d7637fadfbbee471f8b6d 100644 (file)
@@ -380,9 +380,9 @@ defmodule Pleroma.Web.CommonAPI do
     ThreadMute.exists?(user.id, activity.data["context"])
   end
 
-  def report(user, %{"account_id" => account_id} = data) do
-    with {:ok, account} <- get_reported_account(account_id),
-         {:ok, {content_html, _, _}} <- make_report_content_html(data["comment"]),
+  def report(user, data) do
+    with {:ok, account} <- get_reported_account(data.account_id),
+         {:ok, {content_html, _, _}} <- make_report_content_html(data[:comment]),
          {:ok, statuses} <- get_report_statuses(account, data) do
       ActivityPub.flag(%{
         context: Utils.generate_context_id(),
@@ -390,13 +390,11 @@ defmodule Pleroma.Web.CommonAPI do
         account: account,
         statuses: statuses,
         content: content_html,
-        forward: data["forward"] || false
+        forward: Map.get(data, :forward, false)
       })
     end
   end
 
-  def report(_user, _params), do: {:error, dgettext("errors", "Valid `account_id` required")}
-
   defp get_reported_account(account_id) do
     case User.get_cached_by_id(account_id) do
       %User{} = account -> {:ok, account}
index 945e63e22a7c24be8fcc4142bd2050d4600d69e6..6540fa5d18ecb770dbde1f2d24e49dde5474f3ea 100644 (file)
@@ -504,7 +504,8 @@ defmodule Pleroma.Web.CommonAPI.Utils do
     end
   end
 
-  def get_report_statuses(%User{ap_id: actor}, %{"status_ids" => status_ids}) do
+  def get_report_statuses(%User{ap_id: actor}, %{status_ids: status_ids})
+      when is_list(status_ids) do
     {:ok, Activity.all_by_actor_and_id(actor, status_ids)}
   end
 
index f5782be130f7845a533c7391bf4afe67a8e5b8bb..85bd521068c0723a77957368a9ed95c3c05e335a 100644 (file)
@@ -9,12 +9,14 @@ defmodule Pleroma.Web.MastodonAPI.ReportController do
 
   action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
 
+  plug(OpenApiSpex.Plug.CastAndValidate, render_error: Pleroma.Web.ApiSpec.RenderError)
   plug(OAuthScopesPlug, %{scopes: ["write:reports"]} when action == :create)
-
   plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
 
+  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ReportOperation
+
   @doc "POST /api/v1/reports"
-  def create(%{assigns: %{user: user}} = conn, params) do
+  def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
     with {:ok, activity} <- Pleroma.Web.CommonAPI.report(user, params) do
       render(conn, "show.json", activity: activity)
     end
index f80dbf8dd9058d750c81a8eb1a79362130111c68..1862a95896eb3e918b2ab19d89cb600b088df833 100644 (file)
@@ -1347,9 +1347,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
 
       {:ok, %{id: report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       response =
@@ -1374,16 +1374,16 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
 
       {:ok, %{id: report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       {:ok, %{id: second_report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel very offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel very offended",
+          status_ids: [activity.id]
         })
 
       %{
@@ -1523,9 +1523,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
 
       {:ok, %{id: report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       response =
@@ -1547,15 +1547,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
 
       {:ok, %{id: first_report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       {:ok, %{id: second_report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I don't like this user"
+          account_id: target_user.id,
+          comment: "I don't like this user"
         })
 
       CommonAPI.update_report_state(second_report_id, "closed")
@@ -3431,9 +3431,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
 
       {:ok, %{id: report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       post(conn, "/api/pleroma/admin/reports/#{report_id}/notes", %{
index 5db6629f2298f0a629dfdd341b82fa2e20cd2c9d..8cfa1dcfa03476f3f33b75688bfe4690a766d926 100644 (file)
@@ -15,7 +15,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
     user = insert(:user)
     other_user = insert(:user)
 
-    {:ok, activity} = CommonAPI.report(user, %{"account_id" => other_user.id})
+    {:ok, activity} = CommonAPI.report(user, %{account_id: other_user.id})
 
     expected = %{
       content: nil,
@@ -48,7 +48,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
     {:ok, activity} = CommonAPI.post(other_user, %{"status" => "toot"})
 
     {:ok, report_activity} =
-      CommonAPI.report(user, %{"account_id" => other_user.id, "status_ids" => [activity.id]})
+      CommonAPI.report(user, %{account_id: other_user.id, status_ids: [activity.id]})
 
     other_user = Pleroma.User.get_by_id(other_user.id)
 
@@ -81,7 +81,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
     user = insert(:user)
     other_user = insert(:user)
 
-    {:ok, activity} = CommonAPI.report(user, %{"account_id" => other_user.id})
+    {:ok, activity} = CommonAPI.report(user, %{account_id: other_user.id})
     {:ok, activity} = CommonAPI.update_report_state(activity.id, "closed")
 
     assert %{state: "closed"} =
@@ -94,8 +94,8 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
 
     {:ok, activity} =
       CommonAPI.report(user, %{
-        "account_id" => other_user.id,
-        "comment" => "posts are too good for this instance"
+        account_id: other_user.id,
+        comment: "posts are too good for this instance"
       })
 
     assert %{content: "posts are too good for this instance"} =
@@ -108,8 +108,8 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
 
     {:ok, activity} =
       CommonAPI.report(user, %{
-        "account_id" => other_user.id,
-        "comment" => ""
+        account_id: other_user.id,
+        comment: ""
       })
 
     data = Map.put(activity.data, "content", "<script> alert('hecked :D:D:D:D:D:D:D') </script>")
@@ -125,8 +125,8 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
 
     {:ok, activity} =
       CommonAPI.report(user, %{
-        "account_id" => other_user.id,
-        "comment" => ""
+        account_id: other_user.id,
+        comment: ""
       })
 
     Pleroma.User.delete(other_user)
index 1758662b0c69b3caccd8289a33e4a916f8413dde..c6ccc02c4a4e58daf18cc2685413530d4c52da13 100644 (file)
@@ -485,9 +485,9 @@ defmodule Pleroma.Web.CommonAPITest do
       comment = "foobar"
 
       report_data = %{
-        "account_id" => target_user.id,
-        "comment" => comment,
-        "status_ids" => [activity.id]
+        account_id: target_user.id,
+        comment: comment,
+        status_ids: [activity.id]
       }
 
       note_obj = %{
@@ -517,9 +517,9 @@ defmodule Pleroma.Web.CommonAPITest do
 
       {:ok, %Activity{id: report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       {:ok, report} = CommonAPI.update_report_state(report_id, "resolved")
@@ -538,9 +538,9 @@ defmodule Pleroma.Web.CommonAPITest do
 
       {:ok, %Activity{id: report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       assert CommonAPI.update_report_state(report_id, "test") == {:error, "Unsupported state"}
@@ -552,16 +552,16 @@ defmodule Pleroma.Web.CommonAPITest do
 
       {:ok, %Activity{id: first_report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel offended",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel offended",
+          status_ids: [activity.id]
         })
 
       {:ok, %Activity{id: second_report_id}} =
         CommonAPI.report(reporter, %{
-          "account_id" => target_user.id,
-          "comment" => "I feel very offended!",
-          "status_ids" => [activity.id]
+          account_id: target_user.id,
+          comment: "I feel very offended!",
+          status_ids: [activity.id]
         })
 
       {:ok, report_ids} =
index 34ec8119eb30b91a03ecc2935768504977f7fcbe..21b03723714462e3c53da2e1ff4e188193b4b9b5 100644 (file)
@@ -22,8 +22,9 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
   test "submit a basic report", %{conn: conn, target_user: target_user} do
     assert %{"action_taken" => false, "id" => _} =
              conn
+             |> put_req_header("content-type", "application/json")
              |> post("/api/v1/reports", %{"account_id" => target_user.id})
-             |> json_response(200)
+             |> json_response_and_validate_schema(200)
   end
 
   test "submit a report with statuses and comment", %{
@@ -33,23 +34,25 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
   } do
     assert %{"action_taken" => false, "id" => _} =
              conn
+             |> put_req_header("content-type", "application/json")
              |> post("/api/v1/reports", %{
                "account_id" => target_user.id,
                "status_ids" => [activity.id],
                "comment" => "bad status!",
                "forward" => "false"
              })
-             |> json_response(200)
+             |> json_response_and_validate_schema(200)
   end
 
   test "account_id is required", %{
     conn: conn,
     activity: activity
   } do
-    assert %{"error" => "Valid `account_id` required"} =
+    assert %{"error" => "Missing field: account_id."} =
              conn
+             |> put_req_header("content-type", "application/json")
              |> post("/api/v1/reports", %{"status_ids" => [activity.id]})
-             |> json_response(400)
+             |> json_response_and_validate_schema(400)
   end
 
   test "comment must be up to the size specified in the config", %{
@@ -63,17 +66,21 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
 
     assert ^error =
              conn
+             |> put_req_header("content-type", "application/json")
              |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment})
-             |> json_response(400)
+             |> json_response_and_validate_schema(400)
   end
 
   test "returns error when account is not exist", %{
     conn: conn,
     activity: activity
   } do
-    conn = post(conn, "/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"})
+    conn =
+      conn
+      |> put_req_header("content-type", "application/json")
+      |> post("/api/v1/reports", %{"status_ids" => [activity.id], "account_id" => "foo"})
 
-    assert json_response(conn, 400) == %{"error" => "Account not found"}
+    assert json_response_and_validate_schema(conn, 400) == %{"error" => "Account not found"}
   end
 
   test "doesn't fail if an admin has no email", %{conn: conn, target_user: target_user} do
@@ -81,7 +88,8 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
 
     assert %{"action_taken" => false, "id" => _} =
              conn
+             |> put_req_header("content-type", "application/json")
              |> post("/api/v1/reports", %{"account_id" => target_user.id})
-             |> json_response(200)
+             |> json_response_and_validate_schema(200)
   end
 end