Conversation pagination
authorSteven Fuchs <steven.fuchs@dockyard.com>
Sat, 30 May 2020 10:02:37 +0000 (10:02 +0000)
committerlain <lain@soykaf.club>
Sat, 30 May 2020 10:02:37 +0000 (10:02 +0000)
lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex
test/web/mastodon_api/controllers/conversation_controller_test.exs

index f35ec3596589c902da4e5a79d06ad09291c9dbf6..69f0e384600ae80b9698638da7c4767d141cb6b2 100644 (file)
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
 
   @doc "GET /api/v1/conversations"
   def index(%{assigns: %{user: user}} = conn, params) do
+    params = stringify_pagination_params(params)
     participations = Participation.for_user_with_last_activity_id(user, params)
 
     conn
@@ -36,4 +37,20 @@ defmodule Pleroma.Web.MastodonAPI.ConversationController do
       render(conn, "participation.json", participation: participation, for: user)
     end
   end
+
+  defp stringify_pagination_params(params) do
+    atom_keys =
+      Pleroma.Pagination.page_keys()
+      |> Enum.map(&String.to_atom(&1))
+
+    str_keys =
+      params
+      |> Map.take(atom_keys)
+      |> Enum.map(fn {key, value} -> {to_string(key), value} end)
+      |> Enum.into(%{})
+
+    params
+    |> Map.delete(atom_keys)
+    |> Map.merge(str_keys)
+  end
 end
index 693ba51e57a6dc09109c4ac419014307a2150a6c..3e21e6bf178ddab076fbb7f2ebbb40cefbb81be1 100644 (file)
@@ -12,84 +12,88 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
 
   setup do: oauth_access(["read:statuses"])
 
-  test "returns a list of conversations", %{user: user_one, conn: conn} do
-    user_two = insert(:user)
-    user_three = insert(:user)
-
-    {:ok, user_two} = User.follow(user_two, user_one)
-
-    assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
-
-    {:ok, direct} =
-      CommonAPI.post(user_one, %{
-        status: "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
-        visibility: "direct"
-      })
-
-    assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
-
-    {:ok, _follower_only} =
-      CommonAPI.post(user_one, %{
-        status: "Hi @#{user_two.nickname}!",
-        visibility: "private"
-      })
-
-    res_conn = get(conn, "/api/v1/conversations")
-
-    assert response = json_response_and_validate_schema(res_conn, 200)
-
-    assert [
-             %{
-               "id" => res_id,
-               "accounts" => res_accounts,
-               "last_status" => res_last_status,
-               "unread" => unread
-             }
-           ] = response
-
-    account_ids = Enum.map(res_accounts, & &1["id"])
-    assert length(res_accounts) == 2
-    assert user_two.id in account_ids
-    assert user_three.id in account_ids
-    assert is_binary(res_id)
-    assert unread == false
-    assert res_last_status["id"] == direct.id
-    assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
+  describe "returns a list of conversations" do
+    setup(%{user: user_one, conn: conn}) do
+      user_two = insert(:user)
+      user_three = insert(:user)
+
+      {:ok, user_two} = User.follow(user_two, user_one)
+
+      {:ok, %{user: user_one, user_two: user_two, user_three: user_three, conn: conn}}
+    end
+
+    test "returns correct conversations", %{
+      user: user_one,
+      user_two: user_two,
+      user_three: user_three,
+      conn: conn
+    } do
+      assert User.get_cached_by_id(user_two.id).unread_conversation_count == 0
+      {:ok, direct} = create_direct_message(user_one, [user_two, user_three])
+
+      assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
+
+      {:ok, _follower_only} =
+        CommonAPI.post(user_one, %{
+          status: "Hi @#{user_two.nickname}!",
+          visibility: "private"
+        })
+
+      res_conn = get(conn, "/api/v1/conversations")
+
+      assert response = json_response_and_validate_schema(res_conn, 200)
+
+      assert [
+               %{
+                 "id" => res_id,
+                 "accounts" => res_accounts,
+                 "last_status" => res_last_status,
+                 "unread" => unread
+               }
+             ] = response
+
+      account_ids = Enum.map(res_accounts, & &1["id"])
+      assert length(res_accounts) == 2
+      assert user_two.id in account_ids
+      assert user_three.id in account_ids
+      assert is_binary(res_id)
+      assert unread == false
+      assert res_last_status["id"] == direct.id
+      assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
+    end
+
+    test "observes limit params", %{
+      user: user_one,
+      user_two: user_two,
+      user_three: user_three,
+      conn: conn
+    } do
+      {:ok, _} = create_direct_message(user_one, [user_two, user_three])
+      {:ok, _} = create_direct_message(user_two, [user_one, user_three])
+      {:ok, _} = create_direct_message(user_three, [user_two, user_one])
+
+      res_conn = get(conn, "/api/v1/conversations?limit=1")
+
+      assert response = json_response_and_validate_schema(res_conn, 200)
+
+      assert Enum.count(response) == 1
+
+      res_conn = get(conn, "/api/v1/conversations?limit=2")
+
+      assert response = json_response_and_validate_schema(res_conn, 200)
+
+      assert Enum.count(response) == 2
+    end
   end
 
   test "filters conversations by recipients", %{user: user_one, conn: conn} do
     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"
-      })
+    {:ok, direct1} = create_direct_message(user_one, [user_two])
+    {:ok, _direct2} = create_direct_message(user_one, [user_three])
+    {:ok, direct3} = create_direct_message(user_one, [user_two, user_three])
+    {:ok, _direct4} = create_direct_message(user_two, [user_three])
+    {:ok, direct5} = create_direct_message(user_two, [user_one])
 
     assert [conversation1, conversation2] =
              conn
@@ -109,12 +113,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
 
   test "updates the last_status on reply", %{user: user_one, conn: conn} do
     user_two = insert(:user)
-
-    {:ok, direct} =
-      CommonAPI.post(user_one, %{
-        status: "Hi @#{user_two.nickname}",
-        visibility: "direct"
-      })
+    {:ok, direct} = create_direct_message(user_one, [user_two])
 
     {:ok, direct_reply} =
       CommonAPI.post(user_two, %{
@@ -133,12 +132,7 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
 
   test "the user marks a conversation as read", %{user: user_one, conn: conn} do
     user_two = insert(:user)
-
-    {:ok, direct} =
-      CommonAPI.post(user_one, %{
-        status: "Hi @#{user_two.nickname}",
-        visibility: "direct"
-      })
+    {:ok, direct} = create_direct_message(user_one, [user_two])
 
     assert User.get_cached_by_id(user_one.id).unread_conversation_count == 0
     assert User.get_cached_by_id(user_two.id).unread_conversation_count == 1
@@ -194,15 +188,22 @@ defmodule Pleroma.Web.MastodonAPI.ConversationControllerTest do
 
   test "(vanilla) Mastodon frontend behaviour", %{user: user_one, conn: conn} do
     user_two = insert(:user)
-
-    {:ok, direct} =
-      CommonAPI.post(user_one, %{
-        status: "Hi @#{user_two.nickname}!",
-        visibility: "direct"
-      })
+    {:ok, direct} = create_direct_message(user_one, [user_two])
 
     res_conn = get(conn, "/api/v1/statuses/#{direct.id}/context")
 
     assert %{"ancestors" => [], "descendants" => []} == json_response(res_conn, 200)
   end
+
+  defp create_direct_message(sender, recips) do
+    hellos =
+      recips
+      |> Enum.map(fn s -> "@#{s.nickname}" end)
+      |> Enum.join(", ")
+
+    CommonAPI.post(sender, %{
+      status: "Hi #{hellos}!",
+      visibility: "direct"
+    })
+  end
 end