aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreugenijm <eugenijm@protonmail.com>2019-11-07 03:00:21 +0300
committereugenijm <eugenijm@protonmail.com>2019-11-07 08:26:24 +0300
commit7888803ffed428438ed107d35a856647a46b347d (patch)
tree31a82ba5fcdbde2e3f045b295764916e7c90ae5d
parent9f9c3c4fbe4a2f95227bc4b32ea8961c4f699ecf (diff)
downloadpleroma-7888803ffed428438ed107d35a856647a46b347d.tar.gz
Mastodon API: Add the `recipients` parameter to `GET /api/v1/conversations`
-rw-r--r--CHANGELOG.md1
-rw-r--r--docs/API/differences_in_mastoapi_responses.md6
-rw-r--r--lib/pleroma/conversation/participation.ex28
-rw-r--r--test/web/mastodon_api/controllers/conversation_controller_test.exs53
4 files changed, 88 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9fd46b650..b33d61819 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -57,6 +57,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Admin API: Add `GET /api/pleroma/admin/relay` endpoint - lists all followed relays
- Pleroma API: `POST /api/v1/pleroma/conversations/read` to mark all conversations as read
- Mastodon API: Add `/api/v1/markers` for managing timeline read markers
+- Mastodon API: Add the `recipients` parameter to `GET /api/v1/conversations`
</details>
### Fixed
diff --git a/docs/API/differences_in_mastoapi_responses.md b/docs/API/differences_in_mastoapi_responses.md
index aca0f5e0e..7fbe17130 100644
--- a/docs/API/differences_in_mastoapi_responses.md
+++ b/docs/API/differences_in_mastoapi_responses.md
@@ -72,6 +72,12 @@ Has an additional field under the `pleroma` object:
- `recipients`: The list of the recipients of this Conversation. These will be addressed when replying to this conversation.
+## GET `/api/v1/conversations`
+
+Accepts additional parameters:
+
+- `recipients`: Only return conversations with the given recipients (a list of user ids). Usage example: `GET /api/v1/conversations?recipients[]=1&recipients[]=2`
+
## Account Search
Behavior has changed:
diff --git a/lib/pleroma/conversation/participation.ex b/lib/pleroma/conversation/participation.ex
index 176b82a20..aafe57280 100644
--- a/lib/pleroma/conversation/participation.ex
+++ b/lib/pleroma/conversation/participation.ex
@@ -122,9 +122,37 @@ defmodule Pleroma.Conversation.Participation do
order_by: [desc: p.updated_at],
preload: [conversation: [:users]]
)
+ |> restrict_recipients(user, params)
|> Pleroma.Pagination.fetch_paginated(params)
end
+ def restrict_recipients(query, user, %{"recipients" => user_ids}) do
+ user_ids =
+ [user.id | user_ids]
+ |> Enum.uniq()
+ |> Enum.reduce([], fn user_id, acc ->
+ case FlakeId.Ecto.CompatType.dump(user_id) do
+ {:ok, user_id} -> [user_id | acc]
+ _ -> acc
+ end
+ end)
+
+ conversation_subquery =
+ __MODULE__
+ |> group_by([p], p.conversation_id)
+ |> having(
+ [p],
+ count(p.user_id) == ^length(user_ids) and
+ fragment("array_agg(?) @> ?", p.user_id, ^user_ids)
+ )
+ |> select([p], %{id: p.conversation_id})
+
+ query
+ |> join(:inner, [p], c in subquery(conversation_subquery), on: p.conversation_id == c.id)
+ end
+
+ def restrict_recipients(query, _, _), do: query
+
def for_user_and_conversation(user, conversation) do
from(p in __MODULE__,
where: p.user_id == ^user.id,
diff --git a/test/web/mastodon_api/controllers/conversation_controller_test.exs b/test/web/mastodon_api/controllers/conversation_controller_test.exs
index 542af4944..2a1223b18 100644
--- a/test/web/mastodon_api/controllers/conversation_controller_test.exs
+++ b/test/web/mastodon_api/controllers/conversation_controller_test.exs
@@ -59,6 +59,59 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
end
+ test "filters conversations by recipients", %{conn: conn} do
+ user_one = insert(:user)
+ user_two = insert(:user)
+ user_three = insert(:user)
+
+ {:ok, direct1} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi @#{user_two.nickname}!",
+ "visibility" => "direct"
+ })
+
+ {:ok, _direct2} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi @#{user_three.nickname}!",
+ "visibility" => "direct"
+ })
+
+ {:ok, direct3} =
+ CommonAPI.post(user_one, %{
+ "status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
+ "visibility" => "direct"
+ })
+
+ {:ok, _direct4} =
+ CommonAPI.post(user_two, %{
+ "status" => "Hi @#{user_three.nickname}!",
+ "visibility" => "direct"
+ })
+
+ {:ok, direct5} =
+ CommonAPI.post(user_two, %{
+ "status" => "Hi @#{user_one.nickname}!",
+ "visibility" => "direct"
+ })
+
+ [conversation1, conversation2] =
+ conn
+ |> assign(:user, user_one)
+ |> get("/api/v1/conversations", %{"recipients" => [user_two.id]})
+ |> json_response(200)
+
+ assert conversation1["last_status"]["id"] == direct5.id
+ assert conversation2["last_status"]["id"] == direct1.id
+
+ [conversation1] =
+ conn
+ |> assign(:user, user_one)
+ |> get("/api/v1/conversations", %{"recipients" => [user_two.id, user_three.id]})
+ |> json_response(200)
+
+ assert conversation1["last_status"]["id"] == direct3.id
+ end
+
test "updates the last_status on reply", %{conn: conn} do
user_one = insert(:user)
user_two = insert(:user)