more tests and update for docs and changelog
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 26 Jan 2021 14:43:49 +0000 (17:43 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Mon, 1 Feb 2021 11:11:12 +0000 (14:11 +0300)
CHANGELOG.md
docs/development/API/differences_in_mastoapi_responses.md
lib/pleroma/web/api_spec/operations/timeline_operation.ex
test/pleroma/web/mastodon_api/controllers/timeline_controller_test.exs

index 0d1039be8b7869b1992f79e2edd27942457315e6..70d2ac0a8e690488e06a46ae2d2b4af2437734c0 100644 (file)
@@ -49,7 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Admin API: An endpoint to manage frontends.
 - Streaming API: Add follow relationships updates.
 - WebPush: Introduce `pleroma:chat_mention` and `pleroma:emoji_reaction` notification types.
-- Mastodon API: Added `only_media` & `only_remote` parameters to the home timeline.
+- Mastodon API: Home, public, hashtag & list timelines accept `only_media`, `only_remote` & `local` parameters for filtration.
 </details>
 
 ### Fixed
index cb34324abef76202f5c0f28eadfc55de2fe8e006..e9ab896b7d2824ed97a745db1da9deb84335d486 100644 (file)
@@ -16,9 +16,11 @@ Adding the parameter `reply_visibility` to the public and home timelines queries
 
 Adding the parameter `instance=lain.com` to the public timeline will show only statuses originating from `lain.com` (or any remote instance).
 
-Adding the parameter `only_media=true` to the home timeline will show only statuses with media attachments.
+Home, public, hashtag & list timelines can filter statuses by accepting these parameters:
 
-Adding the parameter `only_remote=true` to the home timeline will show only remote statuses.
+- `only_media`: show only statuses with media attached
+- `local`: show only local statuses
+- `only_remote`: show only remote statuses
 
 ## Statuses
 
index e5bf18d4d199d6b6f4bdf4f79275e2664b6bd30f..52008e27cae2c4c27595522249553923e5dcc028 100644 (file)
@@ -63,6 +63,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
         local_param(),
         instance_param(),
         only_media_param(),
+        only_remote_param(),
         with_muted_param(),
         exclude_visibilities_param(),
         reply_visibility_param() | pagination_params()
@@ -109,6 +110,7 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
         ),
         local_param(),
         only_media_param(),
+        only_remote_param(),
         with_muted_param(),
         exclude_visibilities_param() | pagination_params()
       ],
index 75a008f4c7e554a6e62bbc61cb9b119a948d351c..066762748c20b6580a201d1395f9a17a5ee877aa 100644 (file)
@@ -91,110 +91,146 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
              ] = result
     end
 
-    test "local/remote filtering", %{conn: conn, user: user} do
+    test "filtering", %{conn: conn, user: user} do
       local_user = insert(:user)
       {:ok, user, local_user} = User.follow(user, local_user)
       {:ok, local_activity} = CommonAPI.post(local_user, %{status: "Status"})
+      with_media = create_with_media_activity(local_user)
 
       remote_user = insert(:user, local: false)
       {:ok, _user, remote_user} = User.follow(user, remote_user)
       remote_activity = create_remote_activity(remote_user)
 
-      resp1 =
+      without_filter_ids =
         conn
         |> get("/api/v1/timelines/home")
         |> json_response_and_validate_schema(200)
-
-      without_filter_ids = Enum.map(resp1, & &1["id"])
+        |> Enum.map(& &1["id"])
 
       assert local_activity.id in without_filter_ids
       assert remote_activity.id in without_filter_ids
+      assert with_media.id in without_filter_ids
 
-      resp2 =
+      only_local_ids =
         conn
         |> get("/api/v1/timelines/home?local=true")
         |> json_response_and_validate_schema(200)
-
-      only_local_ids = Enum.map(resp2, & &1["id"])
+        |> Enum.map(& &1["id"])
 
       assert local_activity.id in only_local_ids
       refute remote_activity.id in only_local_ids
+      assert with_media.id in only_local_ids
 
-      resp3 =
+      only_local_media_ids =
         conn
-        |> get("/api/v1/timelines/home?only_remote=true")
+        |> get("/api/v1/timelines/home?local=true&only_media=true")
         |> json_response_and_validate_schema(200)
+        |> Enum.map(& &1["id"])
 
-      only_remote_ids = Enum.map(resp3, & &1["id"])
+      refute local_activity.id in only_local_media_ids
+      refute remote_activity.id in only_local_media_ids
+      assert with_media.id in only_local_media_ids
+
+      only_remote_ids =
+        conn
+        |> get("/api/v1/timelines/home?only_remote=true")
+        |> json_response_and_validate_schema(200)
+        |> Enum.map(& &1["id"])
 
       refute local_activity.id in only_remote_ids
       assert remote_activity.id in only_remote_ids
+      refute with_media.id in only_remote_ids
 
-      resp4 =
-        conn
-        |> get("/api/v1/timelines/home?only_remote=true&local=true")
-        |> json_response_and_validate_schema(200)
+      assert conn
+             |> get("/api/v1/timelines/home?only_remote=true&only_media=true")
+             |> json_response_and_validate_schema(200) == []
 
-      assert resp4 == []
+      assert conn
+             |> get("/api/v1/timelines/home?only_remote=true&local=true")
+             |> json_response_and_validate_schema(200) == []
     end
+  end
+
+  describe "public" do
+    @tag capture_log: true
+    test "the public timeline", %{conn: conn} do
+      user = insert(:user)
 
-    test "only_media flag", %{conn: conn, user: user} do
-      other = insert(:user)
-      {:ok, _, other} = User.follow(user, other)
+      {:ok, activity} = CommonAPI.post(user, %{status: "test"})
+      with_media = create_with_media_activity(user)
 
-      {:ok, without_media} = CommonAPI.post(other, %{status: "some status"})
+      remote = insert(:note_activity, local: false)
 
-      with_media = create_with_media_activity(other)
+      assert conn
+             |> get("/api/v1/timelines/public?local=False")
+             |> json_response_and_validate_schema(:ok)
+             |> length == 3
 
-      resp1 =
+      local_ids =
         conn
-        |> get("/api/v1/timelines/home")
-        |> json_response_and_validate_schema(200)
-
-      without_filter_ids = Enum.map(resp1, & &1["id"])
+        |> get("/api/v1/timelines/public?local=True")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
 
-      assert without_media.id in without_filter_ids
-      assert with_media.id in without_filter_ids
+      assert activity.id in local_ids
+      assert with_media.id in local_ids
+      refute remote.id in local_ids
 
-      resp2 =
+      local_ids =
         conn
-        |> get("/api/v1/timelines/home?only_media=true")
-        |> json_response_and_validate_schema(200)
+        |> get("/api/v1/timelines/public?local=True")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
 
-      only_media_ids = Enum.map(resp2, & &1["id"])
+      assert activity.id in local_ids
+      assert with_media.id in local_ids
+      refute remote.id in local_ids
 
-      refute without_media.id in only_media_ids
-      assert with_media.id in only_media_ids
-    end
-  end
-
-  describe "public" do
-    @tag capture_log: true
-    test "the public timeline", %{conn: conn} do
-      user = insert(:user)
+      local_ids =
+        conn
+        |> get("/api/v1/timelines/public?local=True&only_media=true")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
 
-      {:ok, activity} = CommonAPI.post(user, %{status: "test"})
+      refute activity.id in local_ids
+      assert with_media.id in local_ids
+      refute remote.id in local_ids
 
-      _activity = insert(:note_activity, local: false)
+      local_ids =
+        conn
+        |> get("/api/v1/timelines/public?local=1")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
 
-      conn = get(conn, "/api/v1/timelines/public?local=False")
+      assert activity.id in local_ids
+      assert with_media.id in local_ids
+      refute remote.id in local_ids
 
-      assert length(json_response_and_validate_schema(conn, :ok)) == 2
+      remote_id = remote.id
 
-      conn = get(build_conn(), "/api/v1/timelines/public?local=True")
+      assert [%{"id" => ^remote_id}] =
+               conn
+               |> get("/api/v1/timelines/public?only_remote=true")
+               |> json_response_and_validate_schema(:ok)
 
-      assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok)
+      with_media_id = with_media.id
 
-      conn = get(build_conn(), "/api/v1/timelines/public?local=1")
+      assert [%{"id" => ^with_media_id}] =
+               conn
+               |> get("/api/v1/timelines/public?only_media=true")
+               |> json_response_and_validate_schema(:ok)
 
-      assert [%{"content" => "test"}] = json_response_and_validate_schema(conn, :ok)
+      assert conn
+             |> get("/api/v1/timelines/public?only_remote=true&only_media=true")
+             |> json_response_and_validate_schema(:ok) == []
 
       # does not contain repeats
       {:ok, _} = CommonAPI.repeat(activity.id, user)
 
-      conn = get(build_conn(), "/api/v1/timelines/public?local=true")
-
-      assert [_] = json_response_and_validate_schema(conn, :ok)
+      assert [_, _] =
+               conn
+               |> get("/api/v1/timelines/public?local=true")
+               |> json_response_and_validate_schema(:ok)
     end
 
     test "the public timeline includes only public statuses for an authenticated user" do
@@ -621,7 +657,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
              ] = result
     end
 
-    test "filering with params", %{user: user, conn: conn} do
+    test "filering", %{user: user, conn: conn} do
       {:ok, list} = Pleroma.List.create("name", user)
 
       local_user = insert(:user)
@@ -633,43 +669,55 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
       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"])
+      all_ids =
+        conn
+        |> get("/api/v1/timelines/list/#{list.id}")
+        |> json_response_and_validate_schema(200)
+        |> Enum.map(& &1["id"])
 
       assert local_activity.id in all_ids
       assert with_media.id in all_ids
       assert remote_activity.id in all_ids
 
-      resp2 =
+      only_local_ids =
         conn
         |> get("/api/v1/timelines/list/#{list.id}?local=true")
         |> json_response_and_validate_schema(200)
-
-      only_local_ids = Enum.map(resp2, & &1["id"])
+        |> Enum.map(& &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 =
+      only_local_media_ids =
         conn
-        |> get("/api/v1/timelines/list/#{list.id}?only_remote=true")
+        |> get("/api/v1/timelines/list/#{list.id}?local=true&only_media=true")
         |> json_response_and_validate_schema(200)
+        |> Enum.map(& &1["id"])
+
+      refute local_activity.id in only_local_media_ids
+      assert with_media.id in only_local_media_ids
+      refute remote_activity.id in only_local_media_ids
 
-      only_remote_ids = Enum.map(resp3, & &1["id"])
+      only_remote_ids =
+        conn
+        |> get("/api/v1/timelines/list/#{list.id}?only_remote=true")
+        |> json_response_and_validate_schema(200)
+        |> Enum.map(& &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 =
+      assert conn
+             |> get("/api/v1/timelines/list/#{list.id}?only_remote=true&only_media=true")
+             |> json_response_and_validate_schema(200) == []
+
+      only_media_ids =
         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"])
+        |> Enum.map(& &1["id"])
 
       refute local_activity.id in only_media_ids
       assert with_media.id in only_media_ids
@@ -691,19 +739,85 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
       following = insert(:user)
 
       {:ok, activity} = CommonAPI.post(following, %{status: "test #2hu"})
+      with_media = create_with_media_activity(following)
 
-      nconn = get(conn, "/api/v1/timelines/tag/2hu")
+      remote = insert(:user, local: false)
+      remote_activity = create_remote_activity(remote)
 
-      assert [%{"id" => id}] = json_response_and_validate_schema(nconn, :ok)
+      all_ids =
+        conn
+        |> get("/api/v1/timelines/tag/2hu")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
 
-      assert id == to_string(activity.id)
+      assert activity.id in all_ids
+      assert with_media.id in all_ids
+      assert remote_activity.id in all_ids
 
       # works for different capitalization too
-      nconn = get(conn, "/api/v1/timelines/tag/2HU")
+      all_ids =
+        conn
+        |> get("/api/v1/timelines/tag/2HU")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
 
-      assert [%{"id" => id}] = json_response_and_validate_schema(nconn, :ok)
+      assert activity.id in all_ids
+      assert with_media.id in all_ids
+      assert remote_activity.id in all_ids
+
+      local_ids =
+        conn
+        |> get("/api/v1/timelines/tag/2hu?local=true")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
+
+      assert activity.id in local_ids
+      assert with_media.id in local_ids
+      refute remote_activity.id in local_ids
+
+      remote_ids =
+        conn
+        |> get("/api/v1/timelines/tag/2hu?only_remote=true")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
+
+      refute activity.id in remote_ids
+      refute with_media.id in remote_ids
+      assert remote_activity.id in remote_ids
+
+      media_ids =
+        conn
+        |> get("/api/v1/timelines/tag/2hu?only_media=true")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
+
+      refute activity.id in media_ids
+      assert with_media.id in media_ids
+      refute remote_activity.id in media_ids
+
+      media_local_ids =
+        conn
+        |> get("/api/v1/timelines/tag/2hu?only_media=true&local=true")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
+
+      refute activity.id in media_local_ids
+      assert with_media.id in media_local_ids
+      refute remote_activity.id in media_local_ids
 
-      assert id == to_string(activity.id)
+      ids =
+        conn
+        |> get("/api/v1/timelines/tag/2hu?only_media=true&local=true&only_remote=true")
+        |> json_response_and_validate_schema(:ok)
+        |> Enum.map(& &1["id"])
+
+      refute activity.id in ids
+      refute with_media.id in ids
+      refute remote_activity.id in ids
+
+      assert conn
+             |> get("/api/v1/timelines/tag/2hu?only_media=true&only_remote=true")
+             |> json_response_and_validate_schema(:ok) == []
     end
 
     test "multi-hashtag timeline", %{conn: conn} do