list timeline filtration by params
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 26 Jan 2021 13:55:44 +0000 (16:55 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Mon, 1 Feb 2021 11:11:12 +0000 (14:11 +0300)
lib/pleroma/web/api_spec/operations/timeline_operation.ex
lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex
test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs
test/support/factory.ex

index 7b2fe48a5a4d11a98b513a397f1c151870261f37..e5bf18d4d199d6b6f4bdf4f79275e2664b6bd30f 100644 (file)
@@ -25,7 +25,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
       security: [%{"oAuth" => ["read:statuses"]}],
       parameters: [
         local_param(),
-        remote_param(),
+        only_remote_param(),
         only_media_param(),
         with_muted_param(),
         exclude_visibilities_param(),
@@ -134,6 +134,9 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
           required: true
         ),
         with_muted_param(),
+        local_param(),
+        only_remote_param(),
+        only_media_param(),
         exclude_visibilities_param() | pagination_params()
       ],
       operationId: "TimelineController.list",
@@ -201,7 +204,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
     )
   end
 
-  defp remote_param do
+  defp only_remote_param do
     Operation.parameter(
       :only_remote,
       :query,
index b63945912a513a7ae5543bfabfd44604d3df33a9..cef299aa49a1579719b3f017aade8edfced9076a 100644 (file)
@@ -192,6 +192,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
         |> Map.put(:blocking_user, user)
         |> Map.put(:user, user)
         |> Map.put(:muting_user, user)
+        |> Map.put(:local_only, params[:local])
 
       # we must filter the following list for the user to avoid leaking statuses the user
       # does not actually have permission to see (for more info, peruse security issue #270).
index d8cc3c9b92140a0987beb680ac3ecb44c0ea1472..75a008f4c7e554a6e62bbc61cb9b119a948d351c 100644 (file)
@@ -92,42 +92,13 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
     end
 
     test "local/remote filtering", %{conn: conn, user: user} do
-      local = insert(:user)
-      remote = insert(:user, local: false)
-
-      {:ok, user, local} = User.follow(user, local)
-      {:ok, _user, remote} = User.follow(user, remote)
-
-      object1 =
-        insert(:note, %{
-          data: %{
-            "to" => ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(local)]
-          },
-          user: local
-        })
-
-      activity1 =
-        insert(:note_activity, %{
-          note: object1,
-          recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(local)],
-          user: local
-        })
+      local_user = insert(:user)
+      {:ok, user, local_user} = User.follow(user, local_user)
+      {:ok, local_activity} = CommonAPI.post(local_user, %{status: "Status"})
 
-      object2 =
-        insert(:note, %{
-          data: %{
-            "to" => ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(remote)]
-          },
-          user: remote
-        })
-
-      activity2 =
-        insert(:note_activity, %{
-          note: object2,
-          recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(remote)],
-          user: remote,
-          local: false
-        })
+      remote_user = insert(:user, local: false)
+      {:ok, _user, remote_user} = User.follow(user, remote_user)
+      remote_activity = create_remote_activity(remote_user)
 
       resp1 =
         conn
@@ -136,8 +107,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
 
       without_filter_ids = Enum.map(resp1, & &1["id"])
 
-      assert activity1.id in without_filter_ids
-      assert activity2.id in without_filter_ids
+      assert local_activity.id in without_filter_ids
+      assert remote_activity.id in without_filter_ids
 
       resp2 =
         conn
@@ -146,8 +117,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
 
       only_local_ids = Enum.map(resp2, & &1["id"])
 
-      assert activity1.id in only_local_ids
-      refute activity2.id in only_local_ids
+      assert local_activity.id in only_local_ids
+      refute remote_activity.id in only_local_ids
 
       resp3 =
         conn
@@ -156,8 +127,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
 
       only_remote_ids = Enum.map(resp3, & &1["id"])
 
-      refute activity1.id in only_remote_ids
-      assert activity2.id in only_remote_ids
+      refute local_activity.id in only_remote_ids
+      assert remote_activity.id in only_remote_ids
 
       resp4 =
         conn
@@ -171,40 +142,9 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
       other = insert(:user)
       {:ok, _, other} = User.follow(user, other)
 
-      without_media =
-        insert(:note_activity,
-          user: other,
-          recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(other)]
-        )
-
-      obj =
-        insert(:note, %{
-          data: %{
-            "attachment" => [
-              %{
-                "mediaType" => "image/jpeg",
-                "name" => "an_image.jpg",
-                "type" => "Document",
-                "url" => [
-                  %{
-                    "href" =>
-                      "http://localhost:4001/media/8270697e-104f-4a54-a7c1-514bb6713f2c/some_image.jpg",
-                    "mediaType" => "image/jpeg",
-                    "type" => "Link"
-                  }
-                ]
-              }
-            ]
-          },
-          user: other
-        })
+      {:ok, without_media} = CommonAPI.post(other, %{status: "some status"})
 
-      with_media =
-        insert(:note_activity, %{
-          note: obj,
-          recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(other)],
-          user: other
-        })
+      with_media = create_with_media_activity(other)
 
       resp1 =
         conn
@@ -680,6 +620,67 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
                }
              ] = result
     end
+
+    test "filering with params", %{user: user, conn: conn} do
+      {:ok, list} = Pleroma.List.create("name", user)
+
+      local_user = insert(:user)
+      {:ok, local_activity} = CommonAPI.post(local_user, %{status: "Marisa is stupid."})
+      with_media = create_with_media_activity(local_user)
+      {:ok, list} = Pleroma.List.follow(list, local_user)
+
+      remote_user = insert(:user, local: false)
+      remote_activity = create_remote_activity(remote_user)
+      {:ok, list} = Pleroma.List.follow(list, remote_user)
+
+      resp1 =
+        conn |> get("/api/v1/timelines/list/#{list.id}") |> json_response_and_validate_schema(200)
+
+      all_ids = Enum.map(resp1, & &1["id"])
+
+      assert local_activity.id in all_ids
+      assert with_media.id in all_ids
+      assert remote_activity.id in all_ids
+
+      resp2 =
+        conn
+        |> get("/api/v1/timelines/list/#{list.id}?local=true")
+        |> json_response_and_validate_schema(200)
+
+      only_local_ids = Enum.map(resp2, & &1["id"])
+
+      assert local_activity.id in only_local_ids
+      assert with_media.id in only_local_ids
+      refute remote_activity.id in only_local_ids
+
+      resp3 =
+        conn
+        |> get("/api/v1/timelines/list/#{list.id}?only_remote=true")
+        |> json_response_and_validate_schema(200)
+
+      only_remote_ids = Enum.map(resp3, & &1["id"])
+
+      refute local_activity.id in only_remote_ids
+      refute with_media.id in only_remote_ids
+      assert remote_activity.id in only_remote_ids
+
+      resp4 =
+        conn
+        |> get("/api/v1/timelines/list/#{list.id}?only_media=true")
+        |> json_response_and_validate_schema(200)
+
+      only_media_ids = Enum.map(resp4, & &1["id"])
+
+      refute local_activity.id in only_media_ids
+      assert with_media.id in only_media_ids
+      refute remote_activity.id in only_media_ids
+
+      assert conn
+             |> get(
+               "/api/v1/timelines/list/#{list.id}?only_media=true&local=true&only_remote=true"
+             )
+             |> json_response_and_validate_schema(200) == []
+    end
   end
 
   describe "hashtag" do
@@ -862,4 +863,37 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
       ensure_authenticated_access(base_uri)
     end
   end
+
+  defp create_remote_activity(user) do
+    obj =
+      insert(:note, %{
+        data: %{
+          "to" => [
+            "https://www.w3.org/ns/activitystreams#Public",
+            User.ap_followers(user)
+          ]
+        },
+        user: user
+      })
+
+    insert(:note_activity, %{
+      note: obj,
+      recipients: [
+        "https://www.w3.org/ns/activitystreams#Public",
+        User.ap_followers(user)
+      ],
+      user: user,
+      local: false
+    })
+  end
+
+  defp create_with_media_activity(user) do
+    obj = insert(:attachment_note, user: user)
+
+    insert(:note_activity, %{
+      note: obj,
+      recipients: ["https://www.w3.org/ns/activitystreams#Public", User.ap_followers(user)],
+      user: user
+    })
+  end
 end
index bf9592064ed7c63eda4d16e508c36f074f0b7e23..436e19409c5ab0f4701bea5aa4dd1f4e32ca4ecb 100644 (file)
@@ -104,6 +104,37 @@ defmodule Pleroma.Factory do
     }
   end
 
+  def attachment_note_factory(attrs \\ %{}) do
+    user = attrs[:user] || insert(:user)
+    {length, attrs} = Map.pop(attrs, :length, 1)
+
+    data = %{
+      "attachment" =>
+        Stream.repeatedly(fn -> attachment_data(user.ap_id, attrs[:href]) end)
+        |> Enum.take(length)
+    }
+
+    build(:note, Map.put(attrs, :data, data))
+  end
+
+  defp attachment_data(ap_id, href) do
+    href = href || sequence(:href, &"#{Pleroma.Web.Endpoint.url()}/media/#{&1}.jpg")
+
+    %{
+      "url" => [
+        %{
+          "href" => href,
+          "type" => "Link",
+          "mediaType" => "image/jpeg"
+        }
+      ],
+      "name" => "some name",
+      "type" => "Document",
+      "actor" => ap_id,
+      "mediaType" => "image/jpeg"
+    }
+  end
+
   def audio_factory(attrs \\ %{}) do
     text = sequence(:text, &"lain radio episode #{&1}")