Pleroma Conversations API: Add a way to set recipients.
authorlain <lain@soykaf.club>
Mon, 5 Aug 2019 13:09:19 +0000 (15:09 +0200)
committerlain <lain@soykaf.club>
Mon, 5 Aug 2019 13:09:19 +0000 (15:09 +0200)
lib/pleroma/conversation/participation.ex
lib/pleroma/web/mastodon_api/views/conversation_view.ex
lib/pleroma/web/pleroma_api/pleroma_api_controller.ex
lib/pleroma/web/router.ex
test/web/mastodon_api/conversation_view_test.exs [new file with mode: 0644]
test/web/pleroma_api/pleroma_api_controller_test.exs

index f1e1a69580e4c41b0ee8056fe52ab37a4ef3c64a..acdee55173617be544b9c3c16e60fad75d39af84 100644 (file)
@@ -99,4 +99,24 @@ defmodule Pleroma.Conversation.Participation do
   def get(id) do
     Repo.get(__MODULE__, id)
   end
+
+  def set_recipients(participation, user_ids) do
+    Repo.transaction(fn ->
+      query =
+        from(r in RecipientShip,
+          where: r.participation_id == ^participation.id
+        )
+
+      Repo.delete_all(query)
+
+      users =
+        from(u in User,
+          where: u.id in ^user_ids
+        )
+        |> Repo.all()
+
+      RecipientShip.create(users, participation)
+      :ok
+    end)
+  end
 end
index 38bdec737fb4bdf38462833b8ec9778b9a6486d8..5adaecdb03e41eb7afb31eb63661a0b3c44a6157 100644 (file)
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationView do
   alias Pleroma.Web.MastodonAPI.StatusView
 
   def render("participation.json", %{participation: participation, user: user}) do
-    participation = Repo.preload(participation, conversation: :users)
+    participation = Repo.preload(participation, conversation: :users, recipients: [])
 
     last_activity_id =
       with nil <- participation.last_activity_id do
@@ -37,11 +37,20 @@ defmodule Pleroma.Web.MastodonAPI.ConversationView do
         as: :user
       })
 
+    recipients =
+      AccountView.render("accounts.json", %{
+        users: participation.recipients,
+        as: :user
+      })
+
     %{
       id: participation.id |> to_string(),
       accounts: accounts,
       unread: !participation.read,
-      last_status: last_status
+      last_status: last_status,
+      pleroma: %{
+        recipients: recipients
+      }
     }
   end
 end
index b677892ed882efb9666aa18356b78b278916bf66..759d8aef0208ad5f7370573b54936eb61d5ced4f 100644 (file)
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
   alias Pleroma.Conversation.Participation
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.MastodonAPI.StatusView
+  alias Pleroma.Web.MastodonAPI.ConversationView
   alias Pleroma.Repo
 
   def conversation_statuses(
@@ -46,4 +47,20 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
       |> render("index.json", %{activities: activities, for: user, as: :activity})
     end
   end
+
+  def update_conversation(
+        %{assigns: %{user: user}} = conn,
+        %{"id" => participation_id, "recipients" => recipients}
+      ) do
+    participation =
+      participation_id
+      |> Participation.get()
+
+    with true <- user.id == participation.user_id,
+         {:ok, _} <- Participation.set_recipients(participation, recipients) do
+      conn
+      |> put_view(ConversationView)
+      |> render("participation.json", %{participation: participation, user: user})
+    end
+  end
 end
index 40298538a6d72cda96f3cc87ce956323c601f464..6cdef7e2f25ee6b44b32df3b4083fbdaf7d33e72 100644 (file)
@@ -263,6 +263,7 @@ defmodule Pleroma.Web.Router do
     scope [] do
       pipe_through(:oauth_write)
       get("/conversations/:id/statuses", PleromaAPIController, :conversation_statuses)
+      patch("/conversations/:id", PleromaAPIController, :update_conversation)
     end
   end
 
diff --git a/test/web/mastodon_api/conversation_view_test.exs b/test/web/mastodon_api/conversation_view_test.exs
new file mode 100644 (file)
index 0000000..2a4b41f
--- /dev/null
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do
+  use Pleroma.DataCase
+
+  alias Pleroma.Web.CommonAPI
+  alias Pleroma.Conversation.Participation
+  alias Pleroma.Web.MastodonAPI.ConversationView
+
+  import Pleroma.Factory
+
+  test "represents a Mastodon Conversation entity" do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    {:ok, activity} =
+      CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}", "visibility" => "direct"})
+
+    [participation] = Participation.for_user_with_last_activity_id(user)
+
+    assert participation
+
+    conversation =
+      ConversationView.render("participation.json", %{participation: participation, user: user})
+
+    assert conversation.id == participation.id |> to_string()
+    assert conversation.last_status.id == activity.id
+
+    assert [account] = conversation.accounts
+    assert account.id == other_user.id
+
+    assert recipients = conversation.pleroma.recipients
+    recipient_ids = recipients |> Enum.map(& &1.id)
+
+    assert user.id in recipient_ids
+    assert other_user.id in recipient_ids
+  end
+end
index 43104e36ea6696faedd235b61c4e654adef22b70..7989defe035b6ad8d97ef62d9b862588a22dcf64 100644 (file)
@@ -7,6 +7,7 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
 
   alias Pleroma.Conversation.Participation
   alias Pleroma.Web.CommonAPI
+  alias Pleroma.Repo
 
   import Pleroma.Factory
 
@@ -42,4 +43,34 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIControllerTest do
     id_two = activity_two.id
     assert [%{"id" => ^id_one}, %{"id" => ^id_two}] = result
   end
+
+  test "PATCH /api/v1/pleroma/conversations/:id", %{conn: conn} do
+    user = insert(:user)
+    other_user = insert(:user)
+
+    {:ok, _activity} = CommonAPI.post(user, %{"status" => "Hi", "visibility" => "direct"})
+
+    [participation] = Participation.for_user(user)
+
+    participation = Repo.preload(participation, :recipients)
+
+    assert [user] == participation.recipients
+    assert other_user not in participation.recipients
+
+    result =
+      conn
+      |> assign(:user, user)
+      |> patch("/api/v1/pleroma/conversations/#{participation.id}", %{
+        "recipients" => [user.id, other_user.id]
+      })
+      |> json_response(200)
+
+    assert result["id"] == participation.id |> to_string
+
+    assert recipients = result["pleroma"]["recipients"]
+    recipient_ids = Enum.map(recipients, & &1["id"])
+
+    assert user.id in recipient_ids
+    assert other_user.id in recipient_ids
+  end
 end