Merge branch 'develop' into feature/digest-email
authorRoman Chvanikov <chvanikoff@pm.me>
Sun, 30 Jun 2019 18:23:35 +0000 (21:23 +0300)
committerRoman Chvanikov <chvanikoff@pm.me>
Sun, 30 Jun 2019 18:23:35 +0000 (21:23 +0300)
16 files changed:
CHANGELOG.md
docs/config.md
docs/installation/migrating_from_source_otp_en.md
lib/pleroma/config.ex
lib/pleroma/upload/filter/anonymize_filename.ex
lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex [new file with mode: 0644]
lib/pleroma/web/admin_api/views/account_view.ex
lib/pleroma/web/admin_api/views/report_view.ex
lib/pleroma/web/common_api/common_api.ex
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
test/upload/filter/anonymize_filename_test.exs [new file with mode: 0644]
test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs [new file with mode: 0644]
test/web/admin_api/admin_api_controller_test.exs
test/web/admin_api/views/report_view_test.exs
test/web/common_api/common_api_test.exs
test/web/mastodon_api/mastodon_api_controller_test.exs

index 8913f7e9dfd6a5cf66e8b3875870968cd3a6b734..bd7ca14e44b10fe6779f7af6b5851b520b7a2085 100644 (file)
@@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file.
 
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 
+## [Unreleased]
+### Added
+- MRF: Support for priming the mediaproxy cache (`Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`)
+- Mastodon API: Support for the [`tagged` filter](https://github.com/tootsuite/mastodon/pull/9755) in [`GET /api/v1/accounts/:id/statuses`](https://docs.joinmastodon.org/api/rest/accounts/#get-api-v1-accounts-id-statuses)
+
+### Fixed
+- Not being able to pin unlisted posts
+
+### Changed
+- Configuration: Filter.AnonymizeFilename added ability to retain file extension with custom text
+
 ## [1.0.0] - 2019-06-29
 ### Security
 - Mastodon API: Fix display names not being sanitized
index 4f713f5b0db677e64808a593cc65b3571005544c..15af7f1b22fb1cec864ba8e287882c0557ecc5e8 100644 (file)
@@ -36,7 +36,7 @@ No specific configuration.
 This filter replaces the filename (not the path) of an upload. For complete obfuscation, add
 `Pleroma.Upload.Filter.Dedupe` before AnonymizeFilename.
 
-* `text`: Text to replace filenames in links. If empty, `{random}.extension` will be used.
+* `text`: Text to replace filenames in links. If empty, `{random}.extension` will be used. You can get the original filename extension by using `{extension}`, for example `custom-file-name.{extension}`.
 
 ## Pleroma.Emails.Mailer
 * `adapter`: one of the mail adapters listed in [Swoosh readme](https://github.com/swoosh/swoosh#adapters), or `Swoosh.Adapters.Local` for in-memory mailbox.
@@ -98,6 +98,7 @@ config :pleroma, Pleroma.Emails.Mailer,
   * `Pleroma.Web.ActivityPub.MRF.RejectNonPublic`: Drops posts with non-public visibility settings (See ``:mrf_rejectnonpublic`` section)
   * `Pleroma.Web.ActivityPub.MRF.EnsureRePrepended`: Rewrites posts to ensure that replies to posts with subjects do not have an identical subject and instead begin with re:.
   * `Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy`: Rejects posts from likely spambots by rejecting posts from new users that contain links.
+  * `Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy`: Crawls attachments using their MediaProxy URLs so that the MediaProxy cache is primed.
 * `public`: Makes the client API in authentificated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network.
 * `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send.
 * `managed_config`: Whenether the config for pleroma-fe is configured in this config or in ``static/config.json``
@@ -279,7 +280,7 @@ config :pleroma, :mrf_subchain,
 
 ## Pleroma.Web.Endpoint
 `Phoenix` endpoint configuration, all configuration options can be viewed [here](https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#module-dynamic-configuration), only common options are listed here
-* `http` - a list containing http protocol configuration, all configuration options can be viewed [here](https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html#module-options), only common options are listed here
+* `http` - a list containing http protocol configuration, all configuration options can be viewed [here](https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html#module-options), only common options are listed here. For deployment using docker, you need to set this to `[ip: {0,0,0,0}, port: 4000]` to make pleroma accessible from other containers (such as your nginx server).
   - `ip` - a tuple consisting of 4 integers
   - `port`
 * `url` - a list containing the configuration for generating urls, accepts
index 0b41d0c0edd2e74cb7458d3d93519e671e682456..b779be8cc1b8b1423b3721f8fe9fed2ee5e812ba 100644 (file)
@@ -49,7 +49,7 @@ mkdir -p /var/lib/pleroma/static
 chown -R pleroma /var/lib/pleroma
 
 # If you use the local uploader with default settings your uploads should be located in `~pleroma/uploads`
-mv ~pleroma/uploads /var/lib/pleroma/uploads
+mv ~pleroma/uploads/* /var/lib/pleroma/uploads
 
 # If you have created the custom public files directory with default settings it should be located in `~pleroma/instance/static`
 mv ~pleroma/instance/static /var/lib/pleroma/static
@@ -122,13 +122,15 @@ su pleroma -s $SHELL -lc "./bin/pleroma stop"
 ## Setting up a system service
 OTP releases have different service files than from-source installs so they need to be copied over again.
 
+**Warning:** The service files assume pleroma user's home directory is `/opt/pleroma`, please make sure all paths fit your installation.
+
 Debian/Ubuntu:
 ```sh
 # Copy the service into a proper directory
 cp ~pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
 
 # Reload service files
-systemctl reload-daemon
+systemctl daemon-reload
 
 # Reenable pleroma to start on boot
 systemctl reenable pleroma
index 71a47b9fb99615db9e837d9edb08216e47811fe6..fcc0397101368e26d3eb22c5734160eaa017a205 100644 (file)
@@ -38,7 +38,7 @@ defmodule Pleroma.Config do
 
   def put([parent_key | keys], value) do
     parent =
-      Application.get_env(:pleroma, parent_key)
+      Application.get_env(:pleroma, parent_key, [])
       |> put_in(keys, value)
 
     Application.put_env(:pleroma, parent_key, parent)
index 5ca53a79ba46ac7609a24e2e00ffc74c47bcec0d..a8516811ce666bb53d4d2c556892d0c6ca626cc0 100644 (file)
@@ -10,10 +10,19 @@ defmodule Pleroma.Upload.Filter.AnonymizeFilename do
   """
   @behaviour Pleroma.Upload.Filter
 
-  def filter(upload) do
-    extension = List.last(String.split(upload.name, "."))
-    name = Pleroma.Config.get([__MODULE__, :text], random(extension))
-    {:ok, %Pleroma.Upload{upload | name: name}}
+  alias Pleroma.Config
+  alias Pleroma.Upload
+
+  def filter(%Upload{name: name} = upload) do
+    extension = List.last(String.split(name, "."))
+    name = predefined_name(extension) || random(extension)
+    {:ok, %Upload{upload | name: name}}
+  end
+
+  @spec predefined_name(String.t()) :: String.t() | nil
+  defp predefined_name(extension) do
+    with name when not is_nil(name) <- Config.get([__MODULE__, :text]),
+         do: String.replace(name, "{extension}", extension)
   end
 
   defp random(extension) do
diff --git a/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex b/lib/pleroma/web/activity_pub/mrf/mediaproxy_warming_policy.ex
new file mode 100644 (file)
index 0000000..01d21a2
--- /dev/null
@@ -0,0 +1,56 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy do
+  @moduledoc "Preloads any attachments in the MediaProxy cache by prefetching them"
+  @behaviour Pleroma.Web.ActivityPub.MRF
+
+  alias Pleroma.HTTP
+  alias Pleroma.Web.MediaProxy
+
+  require Logger
+
+  @hackney_options [
+    pool: :media,
+    recv_timeout: 10_000
+  ]
+
+  def perform(:prefetch, url) do
+    Logger.info("Prefetching #{inspect(url)}")
+
+    url
+    |> MediaProxy.url()
+    |> HTTP.get([], adapter: @hackney_options)
+  end
+
+  def perform(:preload, %{"object" => %{"attachment" => attachments}} = _message) do
+    Enum.each(attachments, fn
+      %{"url" => url} when is_list(url) ->
+        url
+        |> Enum.each(fn
+          %{"href" => href} ->
+            PleromaJobQueue.enqueue(:background, __MODULE__, [:prefetch, href])
+
+          x ->
+            Logger.debug("Unhandled attachment URL object #{inspect(x)}")
+        end)
+
+      x ->
+        Logger.debug("Unhandled attachment #{inspect(x)}")
+    end)
+  end
+
+  @impl true
+  def filter(
+        %{"type" => "Create", "object" => %{"attachment" => attachments} = _object} = message
+      )
+      when is_list(attachments) and length(attachments) > 0 do
+    PleromaJobQueue.enqueue(:background, __MODULE__, [:preload, message])
+
+    {:ok, message}
+  end
+
+  @impl true
+  def filter(message), do: {:ok, message}
+end
index 28bb667d84d3a4ad39ecdc479a160dd5fe34e681..7e1b9c431bfbdd36c2ea6b631e8822f84e47b812 100644 (file)
@@ -5,8 +5,11 @@
 defmodule Pleroma.Web.AdminAPI.AccountView do
   use Pleroma.Web, :view
 
+  alias Pleroma.HTML
+  alias Pleroma.User
   alias Pleroma.User.Info
   alias Pleroma.Web.AdminAPI.AccountView
+  alias Pleroma.Web.MediaProxy
 
   def render("index.json", %{users: users, count: count, page_size: page_size}) do
     %{
@@ -17,9 +20,14 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
   end
 
   def render("show.json", %{user: user}) do
+    avatar = User.avatar_url(user) |> MediaProxy.url()
+    display_name = HTML.strip_tags(user.name || user.nickname)
+
     %{
       "id" => user.id,
+      "avatar" => avatar,
       "nickname" => user.nickname,
+      "display_name" => display_name,
       "deactivated" => user.info.deactivated,
       "local" => user.local,
       "roles" => Info.roles(user.info),
index e7db3a8fff827ad7f6199d4edf2788c2af3761df..73ccdc582ae97b6da8434c9343629925295966cb 100644 (file)
@@ -8,7 +8,6 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
   alias Pleroma.HTML
   alias Pleroma.User
   alias Pleroma.Web.CommonAPI.Utils
-  alias Pleroma.Web.MastodonAPI.AccountView
   alias Pleroma.Web.MastodonAPI.StatusView
 
   def render("index.json", %{reports: reports}) do
@@ -38,12 +37,17 @@ defmodule Pleroma.Web.AdminAPI.ReportView do
 
     %{
       id: report.id,
-      account: AccountView.render("account.json", %{user: account}),
-      actor: AccountView.render("account.json", %{user: user}),
+      account: merge_account_views(account),
+      actor: merge_account_views(user),
       content: content,
       created_at: created_at,
       statuses: StatusView.render("index.json", %{activities: statuses, as: :activity}),
       state: report.data["state"]
     }
   end
+
+  defp merge_account_views(user) do
+    Pleroma.Web.MastodonAPI.AccountView.render("account.json", %{user: user})
+    |> Map.merge(Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user}))
+  end
 end
index f8df1e2eafd64f782e01d905f22bdc09ef27956b..f71c67a3d8383ac75bfb2cf3bce7c26e45501b85 100644 (file)
@@ -11,6 +11,7 @@ defmodule Pleroma.Web.CommonAPI do
   alias Pleroma.User
   alias Pleroma.Web.ActivityPub.ActivityPub
   alias Pleroma.Web.ActivityPub.Utils
+  alias Pleroma.Web.ActivityPub.Visibility
 
   import Pleroma.Web.CommonAPI.Utils
 
@@ -284,12 +285,11 @@ defmodule Pleroma.Web.CommonAPI do
            },
            object: %Object{
              data: %{
-               "to" => object_to,
                "type" => "Note"
              }
            }
          } = activity <- get_by_id_or_ap_id(id_or_ap_id),
-         true <- Enum.member?(object_to, "https://www.w3.org/ns/activitystreams#Public"),
+         true <- Visibility.is_public?(activity),
          %{valid?: true} = info_changeset <-
            User.Info.add_pinnned_activity(user.info, activity),
          changeset <-
index 7cdba4cc03c2ed6a7c054568729e588074e25e44..ceb88511b0e5e0d03d8dfc922f4ce9651c3f5607 100644 (file)
@@ -356,6 +356,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 
   def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do
     with %User{} = user <- User.get_cached_by_id(params["id"]) do
+      params =
+        params
+        |> Map.put("tag", params["tagged"])
+
       activities = ActivityPub.fetch_user_activities(user, reading_user, params)
 
       conn
diff --git a/test/upload/filter/anonymize_filename_test.exs b/test/upload/filter/anonymize_filename_test.exs
new file mode 100644 (file)
index 0000000..02241cf
--- /dev/null
@@ -0,0 +1,40 @@
+defmodule Pleroma.Upload.Filter.AnonymizeFilenameTest do
+  use Pleroma.DataCase
+
+  alias Pleroma.Config
+  alias Pleroma.Upload
+
+  setup do
+    custom_filename = Config.get([Upload.Filter.AnonymizeFilename, :text])
+
+    on_exit(fn ->
+      Config.put([Upload.Filter.AnonymizeFilename, :text], custom_filename)
+    end)
+
+    upload_file = %Upload{
+      name: "an… image.jpg",
+      content_type: "image/jpg",
+      path: Path.absname("test/fixtures/image_tmp.jpg")
+    }
+
+    %{upload_file: upload_file}
+  end
+
+  test "it replaces filename on pre-defined text", %{upload_file: upload_file} do
+    Config.put([Upload.Filter.AnonymizeFilename, :text], "custom-file.png")
+    {:ok, %Upload{name: name}} = Upload.Filter.AnonymizeFilename.filter(upload_file)
+    assert name == "custom-file.png"
+  end
+
+  test "it replaces filename on pre-defined text expression", %{upload_file: upload_file} do
+    Config.put([Upload.Filter.AnonymizeFilename, :text], "custom-file.{extension}")
+    {:ok, %Upload{name: name}} = Upload.Filter.AnonymizeFilename.filter(upload_file)
+    assert name == "custom-file.jpg"
+  end
+
+  test "it replaces filename on random text", %{upload_file: upload_file} do
+    {:ok, %Upload{name: name}} = Upload.Filter.AnonymizeFilename.filter(upload_file)
+    assert <<_::bytes-size(14)>> <> ".jpg" = name
+    refute name == "an… image.jpg"
+  end
+end
diff --git a/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs b/test/web/activity_pub/mrf/mediaproxy_warming_policy_test.exs
new file mode 100644 (file)
index 0000000..372e789
--- /dev/null
@@ -0,0 +1,45 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
+  use Pleroma.DataCase
+
+  alias Pleroma.HTTP
+  alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
+
+  import Mock
+
+  @message %{
+    "type" => "Create",
+    "object" => %{
+      "type" => "Note",
+      "content" => "content",
+      "attachment" => [
+        %{"url" => [%{"href" => "http://example.com/image.jpg"}]}
+      ]
+    }
+  }
+
+  test "it prefetches media proxy URIs" do
+    with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
+      MediaProxyWarmingPolicy.filter(@message)
+      assert called(HTTP.get(:_, :_, :_))
+    end
+  end
+
+  test "it does nothing when no attachments are present" do
+    object =
+      @message["object"]
+      |> Map.delete("attachment")
+
+    message =
+      @message
+      |> Map.put("object", object)
+
+    with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
+      MediaProxyWarmingPolicy.filter(message)
+      refute called(HTTP.get(:_, :_, :_))
+    end
+  end
+end
index 4278ac59dc4d906814bfadc14e237ac3c44febd6..4ea33a6cc483cfbdf540c73019dfc1a3746e50c8 100644 (file)
@@ -6,9 +6,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
   use Pleroma.Web.ConnCase
 
   alias Pleroma.Activity
+  alias Pleroma.HTML
   alias Pleroma.User
   alias Pleroma.UserInviteToken
   alias Pleroma.Web.CommonAPI
+  alias Pleroma.Web.MediaProxy
   import Pleroma.Factory
 
   describe "/api/pleroma/admin/users" do
@@ -58,7 +60,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
         "local" => true,
         "nickname" => user.nickname,
         "roles" => %{"admin" => false, "moderator" => false},
-        "tags" => []
+        "tags" => [],
+        "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+        "display_name" => HTML.strip_tags(user.name || user.nickname)
       }
 
       assert expected == json_response(conn, 200)
@@ -445,7 +449,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => admin.nickname,
             "roles" => %{"admin" => true, "moderator" => false},
             "local" => true,
-            "tags" => []
+            "tags" => [],
+            "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(admin.name || admin.nickname)
           },
           %{
             "deactivated" => user.info.deactivated,
@@ -453,7 +459,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => user.nickname,
             "roles" => %{"admin" => false, "moderator" => false},
             "local" => false,
-            "tags" => ["foo", "bar"]
+            "tags" => ["foo", "bar"],
+            "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(user.name || user.nickname)
           }
         ]
         |> Enum.sort_by(& &1["nickname"])
@@ -492,7 +500,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -514,7 +524,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -536,7 +548,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -558,7 +572,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -580,7 +596,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -602,7 +620,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -619,7 +639,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user2.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user2.name || user2.nickname)
                  }
                ]
              }
@@ -646,7 +668,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => true,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -671,7 +695,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => user.nickname,
             "roles" => %{"admin" => false, "moderator" => false},
             "local" => true,
-            "tags" => []
+            "tags" => [],
+            "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(user.name || user.nickname)
           },
           %{
             "deactivated" => admin.info.deactivated,
@@ -679,7 +705,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => admin.nickname,
             "roles" => %{"admin" => true, "moderator" => false},
             "local" => true,
-            "tags" => []
+            "tags" => [],
+            "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(admin.name || admin.nickname)
           },
           %{
             "deactivated" => false,
@@ -687,7 +715,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "local" => true,
             "nickname" => old_admin.nickname,
             "roles" => %{"admin" => true, "moderator" => false},
-            "tags" => []
+            "tags" => [],
+            "avatar" => User.avatar_url(old_admin) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(old_admin.name || old_admin.nickname)
           }
         ]
         |> Enum.sort_by(& &1["nickname"])
@@ -714,7 +744,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => admin.nickname,
             "roles" => %{"admin" => true, "moderator" => false},
             "local" => admin.local,
-            "tags" => []
+            "tags" => [],
+            "avatar" => User.avatar_url(admin) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(admin.name || admin.nickname)
           },
           %{
             "deactivated" => false,
@@ -722,7 +754,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => second_admin.nickname,
             "roles" => %{"admin" => true, "moderator" => false},
             "local" => second_admin.local,
-            "tags" => []
+            "tags" => [],
+            "avatar" => User.avatar_url(second_admin) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(second_admin.name || second_admin.nickname)
           }
         ]
         |> Enum.sort_by(& &1["nickname"])
@@ -751,7 +785,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => moderator.nickname,
                    "roles" => %{"admin" => false, "moderator" => true},
                    "local" => moderator.local,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(moderator) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(moderator.name || moderator.nickname)
                  }
                ]
              }
@@ -773,7 +809,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => user1.nickname,
             "roles" => %{"admin" => false, "moderator" => false},
             "local" => user1.local,
-            "tags" => ["first"]
+            "tags" => ["first"],
+            "avatar" => User.avatar_url(user1) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(user1.name || user1.nickname)
           },
           %{
             "deactivated" => false,
@@ -781,7 +819,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
             "nickname" => user2.nickname,
             "roles" => %{"admin" => false, "moderator" => false},
             "local" => user2.local,
-            "tags" => ["second"]
+            "tags" => ["second"],
+            "avatar" => User.avatar_url(user2) |> MediaProxy.url(),
+            "display_name" => HTML.strip_tags(user2.name || user2.nickname)
           }
         ]
         |> Enum.sort_by(& &1["nickname"])
@@ -815,7 +855,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                    "nickname" => user.nickname,
                    "roles" => %{"admin" => false, "moderator" => false},
                    "local" => user.local,
-                   "tags" => []
+                   "tags" => [],
+                   "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+                   "display_name" => HTML.strip_tags(user.name || user.nickname)
                  }
                ]
              }
@@ -838,7 +880,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
                "nickname" => user.nickname,
                "roles" => %{"admin" => false, "moderator" => false},
                "local" => true,
-               "tags" => []
+               "tags" => [],
+               "avatar" => User.avatar_url(user) |> MediaProxy.url(),
+               "display_name" => HTML.strip_tags(user.name || user.nickname)
              }
   end
 
index f35f36cac3a9391acc0a9890e27dc3fdd7c10d47..75d8bb4b5a9daf68b1b711297ee822a4427dcd0f 100644 (file)
@@ -18,8 +18,16 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
 
     expected = %{
       content: nil,
-      actor: AccountView.render("account.json", %{user: user}),
-      account: AccountView.render("account.json", %{user: other_user}),
+      actor:
+        Map.merge(
+          AccountView.render("account.json", %{user: user}),
+          Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
+        ),
+      account:
+        Map.merge(
+          AccountView.render("account.json", %{user: other_user}),
+          Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
+        ),
       statuses: [],
       state: "open",
       id: activity.id
@@ -42,8 +50,16 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
 
     expected = %{
       content: nil,
-      actor: AccountView.render("account.json", %{user: user}),
-      account: AccountView.render("account.json", %{user: other_user}),
+      actor:
+        Map.merge(
+          AccountView.render("account.json", %{user: user}),
+          Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: user})
+        ),
+      account:
+        Map.merge(
+          AccountView.render("account.json", %{user: other_user}),
+          Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
+        ),
       statuses: [StatusView.render("status.json", %{activity: activity})],
       state: "open",
       id: report_activity.id
index e96106f1114777ca284f80921e9319b22d92a319..6f57bbe1f7b0d568e0852007de286dacad50391b 100644 (file)
@@ -188,6 +188,11 @@ defmodule Pleroma.Web.CommonAPITest do
       assert %User{info: %{pinned_activities: [^id]}} = user
     end
 
+    test "unlisted statuses can be pinned", %{user: user} do
+      {:ok, activity} = CommonAPI.post(user, %{"status" => "HI!!!", "visibility" => "unlisted"})
+      assert {:ok, ^activity} = CommonAPI.pin(activity.id, user)
+    end
+
     test "only self-authored can be pinned", %{activity: activity} do
       user = insert(:user)
 
index 03f57dbfaa8004de9394e79be2cae7ce583c9486..b7487c68cc2052a65740c0890d9bd50373b5b65f 100644 (file)
@@ -1408,6 +1408,19 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
       assert [%{"id" => id}] = json_response(conn, 200)
       assert id == to_string(post.id)
     end
+
+    test "filters user's statuses by a hashtag", %{conn: conn} do
+      user = insert(:user)
+      {:ok, post} = CommonAPI.post(user, %{"status" => "#hashtag"})
+      {:ok, _post} = CommonAPI.post(user, %{"status" => "hashtag"})
+
+      conn =
+        conn
+        |> get("/api/v1/accounts/#{user.id}/statuses", %{"tagged" => "hashtag"})
+
+      assert [%{"id" => id}] = json_response(conn, 200)
+      assert id == to_string(post.id)
+    end
   end
 
   describe "user relationships" do