support for with_relationships parameter
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 29 Jan 2021 05:41:21 +0000 (08:41 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Fri, 29 Jan 2021 05:41:21 +0000 (08:41 +0300)
in /api/v1/mutes and /api/v1/accounts/:id endpoints

CHANGELOG.md
docs/development/API/differences_in_mastoapi_responses.md
lib/pleroma/web/api_spec/operations/account_operation.ex
lib/pleroma/web/mastodon_api/controllers/account_controller.ex
test/pleroma/web/mastodon_api/controllers/account_controller_test.exs

index c4f3867a26d3d8797b0c4e5bcb8cd79ab8de6735..b2b7e5671718ac9d3c492cd69220a3cd341f4d5d 100644 (file)
@@ -48,7 +48,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Mastodon API: User and conversation mutes can now auto-expire if `expires_in` parameter was given while adding the mute.
 - Admin API: An endpoint to manage frontends.
 - Streaming API: Add follow relationships updates.
-- WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types
+- WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types.
+- Mastodon API: `/api/v1/accounts/:id` & `/api/v1/mutes` endpoints accept `with_relationships` parameter and return filled `pleroma.relationship` field.
 </details>
 
 ### Fixed
index 84430408b4c3e9fca74f05e476e02eb5622c248e..b532d14eddb99347787e1b4bffec7abbffc44c9d 100644 (file)
@@ -54,6 +54,13 @@ The `id` parameter can also be the `nickname` of the user. This only works in th
 - `/api/v1/accounts/:id`
 - `/api/v1/accounts/:id/statuses`
 
+Endpoints which accept `with_relationships` parameter:
+
+- `/api/v1/accounts/:id`
+- `/api/v1/accounts/:id/followers`
+- `/api/v1/accounts/:id/following`
+- `/api/v1/mutes`
+
 Has these additional fields under the `pleroma` object:
 
 - `ap_id`: nullable URL string, ActivityPub id of the user
index 80acee2f7a21fb689ad62a538105adffac8c438f..d7e01f55b36e10ba30b6001aa51b78472e1ff841 100644 (file)
@@ -99,7 +99,10 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
       summary: "Account",
       operationId: "AccountController.show",
       description: "View information about a profile.",
-      parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
+      parameters: [
+        %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
+        with_relationships_param()
+      ],
       responses: %{
         200 => Operation.response("Account", "application/json", Account),
         401 => Operation.response("Error", "application/json", ApiError),
@@ -347,7 +350,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
       operationId: "AccountController.mutes",
       description: "Accounts the user has muted.",
       security: [%{"oAuth" => ["follow", "read:mutes"]}],
-      parameters: pagination_params(),
+      parameters: [with_relationships_param() | pagination_params()],
       responses: %{
         200 => Operation.response("Accounts", "application/json", array_of_accounts())
       }
index d277aeca50dd91cd6e0d39cb4f80f264eb17ba3f..7a1e990449502c9e501574c9583602049454e43e 100644 (file)
@@ -269,10 +269,14 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
   def relationships(%{assigns: %{user: _user}} = conn, _), do: json(conn, [])
 
   @doc "GET /api/v1/accounts/:id"
-  def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id}) do
+  def show(%{assigns: %{user: for_user}} = conn, %{id: nickname_or_id} = params) do
     with %User{} = user <- User.get_cached_by_nickname_or_id(nickname_or_id, for: for_user),
          :visible <- User.visible_for(user, for_user) do
-      render(conn, "show.json", user: user, for: for_user)
+      render(conn, "show.json",
+        user: user,
+        for: for_user,
+        embed_relationships: embed_relationships?(params)
+      )
     else
       error -> user_visibility_error(conn, error)
     end
@@ -454,7 +458,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
 
     conn
     |> add_link_headers(users)
-    |> render("index.json", users: users, for: user, as: :user)
+    |> render("index.json",
+      users: users,
+      for: user,
+      as: :user,
+      embed_relationships: embed_relationships?(params)
+    )
   end
 
   @doc "GET /api/v1/blocks"
index 1276597a4e911a6d6d55fc8960dfa9b50dac3161..e5020fecaefd06887a16d20fae221cb057fa97ac 100644 (file)
@@ -29,6 +29,45 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
                |> json_response_and_validate_schema(404)
     end
 
+    test "relationship field" do
+      %{conn: conn, user: user} = oauth_access(["read"])
+
+      other_user = insert(:user)
+
+      response =
+        conn
+        |> get("/api/v1/accounts/#{other_user.id}")
+        |> json_response_and_validate_schema(200)
+
+      assert response["id"] == other_user.id
+      assert response["pleroma"]["relationship"] == %{}
+
+      assert %{"pleroma" => %{"relationship" => %{"following" => false, "followed_by" => false}}} =
+               conn
+               |> get("/api/v1/accounts/#{other_user.id}?with_relationships=true")
+               |> json_response_and_validate_schema(200)
+
+      {:ok, _, %{id: other_id}} = User.follow(user, other_user)
+
+      assert %{
+               "id" => ^other_id,
+               "pleroma" => %{"relationship" => %{"following" => true, "followed_by" => false}}
+             } =
+               conn
+               |> get("/api/v1/accounts/#{other_id}?with_relationships=true")
+               |> json_response_and_validate_schema(200)
+
+      {:ok, _, _} = User.follow(other_user, user)
+
+      assert %{
+               "id" => ^other_id,
+               "pleroma" => %{"relationship" => %{"following" => true, "followed_by" => true}}
+             } =
+               conn
+               |> get("/api/v1/accounts/#{other_id}?with_relationships=true")
+               |> json_response_and_validate_schema(200)
+    end
+
     test "works by nickname" do
       user = insert(:user)
 
@@ -590,6 +629,45 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
       assert [%{"id" => ^user_id}] = json_response_and_validate_schema(conn, 200)
     end
 
+    test "following with relationship", %{conn: conn, user: user} do
+      other_user = insert(:user)
+      {:ok, %{id: id}, _} = User.follow(other_user, user)
+
+      assert [
+               %{
+                 "id" => ^id,
+                 "pleroma" => %{
+                   "relationship" => %{
+                     "id" => ^id,
+                     "following" => false,
+                     "followed_by" => true
+                   }
+                 }
+               }
+             ] =
+               conn
+               |> get("/api/v1/accounts/#{user.id}/followers?with_relationships=true")
+               |> json_response_and_validate_schema(200)
+
+      {:ok, _, _} = User.follow(user, other_user)
+
+      assert [
+               %{
+                 "id" => ^id,
+                 "pleroma" => %{
+                   "relationship" => %{
+                     "id" => ^id,
+                     "following" => true,
+                     "followed_by" => true
+                   }
+                 }
+               }
+             ] =
+               conn
+               |> get("/api/v1/accounts/#{user.id}/followers?with_relationships=true")
+               |> json_response_and_validate_schema(200)
+    end
+
     test "getting followers, hide_followers", %{user: user, conn: conn} do
       other_user = insert(:user, hide_followers: true)
       {:ok, _user, _other_user} = User.follow(user, other_user)
@@ -660,6 +738,24 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
       assert id == to_string(other_user.id)
     end
 
+    test "following with relationship", %{conn: conn, user: user} do
+      other_user = insert(:user)
+      {:ok, user, other_user} = User.follow(user, other_user)
+
+      conn = get(conn, "/api/v1/accounts/#{user.id}/following?with_relationships=true")
+
+      id = other_user.id
+
+      assert [
+               %{
+                 "id" => ^id,
+                 "pleroma" => %{
+                   "relationship" => %{"id" => ^id, "following" => true, "followed_by" => false}
+                 }
+               }
+             ] = json_response_and_validate_schema(conn, 200)
+    end
+
     test "getting following, hide_follows, other user requesting" do
       user = insert(:user, hide_follows: true)
       other_user = insert(:user)
@@ -1565,7 +1661,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     result =
       conn
-      |> assign(:user, user)
       |> get("/api/v1/mutes")
       |> json_response_and_validate_schema(200)
 
@@ -1573,7 +1668,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     result =
       conn
-      |> assign(:user, user)
       |> get("/api/v1/mutes?limit=1")
       |> json_response_and_validate_schema(200)
 
@@ -1581,7 +1675,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     result =
       conn
-      |> assign(:user, user)
       |> get("/api/v1/mutes?since_id=#{id1}")
       |> json_response_and_validate_schema(200)
 
@@ -1589,7 +1682,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     result =
       conn
-      |> assign(:user, user)
       |> get("/api/v1/mutes?since_id=#{id1}&max_id=#{id3}")
       |> json_response_and_validate_schema(200)
 
@@ -1597,13 +1689,45 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
 
     result =
       conn
-      |> assign(:user, user)
       |> get("/api/v1/mutes?since_id=#{id1}&limit=1")
       |> json_response_and_validate_schema(200)
 
     assert [%{"id" => ^id2}] = result
   end
 
+  test "list of mutes with with_relationships parameter" do
+    %{user: user, conn: conn} = oauth_access(["read:mutes"])
+    %{id: id1} = other_user1 = insert(:user)
+    %{id: id2} = other_user2 = insert(:user)
+    %{id: id3} = other_user3 = insert(:user)
+
+    {:ok, _, _} = User.follow(other_user1, user)
+    {:ok, _, _} = User.follow(other_user2, user)
+    {:ok, _, _} = User.follow(other_user3, user)
+
+    {:ok, _} = User.mute(user, other_user1)
+    {:ok, _} = User.mute(user, other_user2)
+    {:ok, _} = User.mute(user, other_user3)
+
+    assert [
+             %{
+               "id" => ^id1,
+               "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
+             },
+             %{
+               "id" => ^id2,
+               "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
+             },
+             %{
+               "id" => ^id3,
+               "pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
+             }
+           ] =
+             conn
+             |> get("/api/v1/mutes?with_relationships=true")
+             |> json_response_and_validate_schema(200)
+  end
+
   test "getting a list of blocks" do
     %{user: user, conn: conn} = oauth_access(["read:blocks"])
     %{id: id1} = other_user1 = insert(:user)