Add OpenAPI spec for InstanceController
authorEgor Kislitsyn <egor@kislitsyn.com>
Tue, 5 May 2020 13:24:16 +0000 (17:24 +0400)
committerEgor Kislitsyn <egor@kislitsyn.com>
Tue, 5 May 2020 13:24:16 +0000 (17:24 +0400)
lib/pleroma/stats.ex
lib/pleroma/web/api_spec/operations/instance_operation.ex [new file with mode: 0644]
lib/pleroma/web/mastodon_api/controllers/instance_controller.ex
test/web/mastodon_api/controllers/instance_controller_test.exs

index 8d2809bbbe546bce9399f069d72f11027da5ba45..6b3a8a41f738801e8ffc0817d066cd3212d0ef74 100644 (file)
@@ -91,7 +91,7 @@ defmodule Pleroma.Stats do
       peers: peers,
       stats: %{
         domain_count: domain_count,
-        status_count: status_count,
+        status_count: status_count || 0,
         user_count: user_count
       }
     }
diff --git a/lib/pleroma/web/api_spec/operations/instance_operation.ex b/lib/pleroma/web/api_spec/operations/instance_operation.ex
new file mode 100644 (file)
index 0000000..36a1a90
--- /dev/null
@@ -0,0 +1,169 @@
+# 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.InstanceOperation do
+  alias OpenApiSpex.Operation
+  alias OpenApiSpex.Schema
+
+  def open_api_operation(action) do
+    operation = String.to_existing_atom("#{action}_operation")
+    apply(__MODULE__, operation, [])
+  end
+
+  def show_operation do
+    %Operation{
+      tags: ["Instance"],
+      summary: "Fetch instance",
+      description: "Information about the server",
+      operationId: "InstanceController.show",
+      responses: %{
+        200 => Operation.response("Instance", "application/json", instance())
+      }
+    }
+  end
+
+  def peers_operation do
+    %Operation{
+      tags: ["Instance"],
+      summary: "List of connected domains",
+      operationId: "InstanceController.peers",
+      responses: %{
+        200 => Operation.response("Array of domains", "application/json", array_of_domains())
+      }
+    }
+  end
+
+  defp instance do
+    %Schema{
+      type: :object,
+      properties: %{
+        uri: %Schema{type: :string, description: "The domain name of the instance"},
+        title: %Schema{type: :string, description: "The title of the website"},
+        description: %Schema{
+          type: :string,
+          description: "Admin-defined description of the Mastodon site"
+        },
+        version: %Schema{
+          type: :string,
+          description: "The version of Mastodon installed on the instance"
+        },
+        email: %Schema{
+          type: :string,
+          description: "An email that may be contacted for any inquiries",
+          format: :email
+        },
+        urls: %Schema{
+          type: :object,
+          description: "URLs of interest for clients apps",
+          properties: %{
+            streaming_api: %Schema{
+              type: :string,
+              description: "Websockets address for push streaming"
+            }
+          }
+        },
+        stats: %Schema{
+          type: :object,
+          description: "Statistics about how much information the instance contains",
+          properties: %{
+            user_count: %Schema{
+              type: :integer,
+              description: "Users registered on this instance"
+            },
+            status_count: %Schema{
+              type: :integer,
+              description: "Statuses authored by users on instance"
+            },
+            domain_count: %Schema{
+              type: :integer,
+              description: "Domains federated with this instance"
+            }
+          }
+        },
+        thumbnail: %Schema{
+          type: :string,
+          description: "Banner image for the website",
+          nullable: true
+        },
+        languages: %Schema{
+          type: :array,
+          items: %Schema{type: :string},
+          description: "Primary langauges of the website and its staff"
+        },
+        registrations: %Schema{type: :boolean, description: "Whether registrations are enabled"},
+        # Extra (not present in Mastodon):
+        max_toot_chars: %Schema{
+          type: :integer,
+          description: ": Posts character limit (CW/Subject included in the counter)"
+        },
+        poll_limits: %Schema{
+          type: :object,
+          description: "A map with poll limits for local polls",
+          properties: %{
+            max_options: %Schema{
+              type: :integer,
+              description: "Maximum number of options."
+            },
+            max_option_chars: %Schema{
+              type: :integer,
+              description: "Maximum number of characters per option."
+            },
+            min_expiration: %Schema{
+              type: :integer,
+              description: "Minimum expiration time (in seconds)."
+            },
+            max_expiration: %Schema{
+              type: :integer,
+              description: "Maximum expiration time (in seconds)."
+            }
+          }
+        },
+        upload_limit: %Schema{
+          type: :integer,
+          description: "File size limit of uploads (except for avatar, background, banner)"
+        },
+        avatar_upload_limit: %Schema{type: :integer, description: "The title of the website"},
+        background_upload_limit: %Schema{type: :integer, description: "The title of the website"},
+        banner_upload_limit: %Schema{type: :integer, description: "The title of the website"}
+      },
+      example: %{
+        "avatar_upload_limit" => 2_000_000,
+        "background_upload_limit" => 4_000_000,
+        "banner_upload_limit" => 4_000_000,
+        "description" => "A Pleroma instance, an alternative fediverse server",
+        "email" => "lain@lain.com",
+        "languages" => ["en"],
+        "max_toot_chars" => 5000,
+        "poll_limits" => %{
+          "max_expiration" => 31_536_000,
+          "max_option_chars" => 200,
+          "max_options" => 20,
+          "min_expiration" => 0
+        },
+        "registrations" => false,
+        "stats" => %{
+          "domain_count" => 2996,
+          "status_count" => 15_802,
+          "user_count" => 5
+        },
+        "thumbnail" => "https://lain.com/instance/thumbnail.jpeg",
+        "title" => "lain.com",
+        "upload_limit" => 16_000_000,
+        "uri" => "https://lain.com",
+        "urls" => %{
+          "streaming_api" => "wss://lain.com"
+        },
+        "version" => "2.7.2 (compatible; Pleroma 2.0.50-536-g25eec6d7-develop)"
+      }
+    }
+  end
+
+  defp array_of_domains do
+    %Schema{
+      type: :array,
+      items: %Schema{type: :string},
+      example: ["pleroma.site", "lain.com", "bikeshed.party"]
+    }
+  end
+end
index 237f8567758e1c19de872b84ac94d38135f6e084..d8859731d97e52c880295a10bf0aa8e5b27edf35 100644 (file)
@@ -5,12 +5,16 @@
 defmodule Pleroma.Web.MastodonAPI.InstanceController do
   use Pleroma.Web, :controller
 
+  plug(OpenApiSpex.Plug.CastAndValidate)
+
   plug(
     :skip_plug,
     [Pleroma.Plugs.OAuthScopesPlug, Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug]
     when action in [:show, :peers]
   )
 
+  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.InstanceOperation
+
   @doc "GET /api/v1/instance"
   def show(conn, _params) do
     render(conn, "show.json")
index 2c7fd9fd000bbe2e427a2520ad8c6e3096367738..90840d5ab6116412a0edc350d416eb393dbedd27 100644 (file)
@@ -10,7 +10,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
 
   test "get instance information", %{conn: conn} do
     conn = get(conn, "/api/v1/instance")
-    assert result = json_response(conn, 200)
+    assert result = json_response_and_validate_schema(conn, 200)
 
     email = Pleroma.Config.get([:instance, :email])
     # Note: not checking for "max_toot_chars" since it's optional
@@ -56,7 +56,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
 
     conn = get(conn, "/api/v1/instance")
 
-    assert result = json_response(conn, 200)
+    assert result = json_response_and_validate_schema(conn, 200)
 
     stats = result["stats"]
 
@@ -74,7 +74,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceControllerTest do
 
     conn = get(conn, "/api/v1/instance/peers")
 
-    assert result = json_response(conn, 200)
+    assert result = json_response_and_validate_schema(conn, 200)
 
     assert ["peer1.com", "peer2.com"] == Enum.sort(result)
   end