commit: 4f7c11b2814f22fd7f28832462569a78faf223b5
parent 6d0cc8fa2af293280f1816410794d2afdbc2294b
Author: Haelwenn <contact+git.pleroma.social@hacktivis.me>
Date: Mon, 27 Mar 2023 10:05:47 +0000
Merge branch 'tusooa/3073-react-legacy' into 'develop'
Fix emoji reactions for legacy 2-tuple formats
Closes #3073
See merge request pleroma/pleroma!3861
Diffstat:
8 files changed, 147 insertions(+), 14 deletions(-)
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
@@ -425,4 +425,30 @@ defmodule Pleroma.Object do
end
def object_data_hashtags(_), do: []
+
+ def get_emoji_reactions(object) do
+ reactions = object.data["reactions"]
+
+ if is_list(reactions) or is_map(reactions) do
+ reactions
+ |> Enum.map(fn
+ [_emoji, users, _maybe_url] = item when is_list(users) ->
+ item
+
+ [emoji, users] when is_list(users) ->
+ [emoji, users, nil]
+
+ # This case is here to process the Map situation, which will happen
+ # only with the legacy two-value format.
+ {emoji, users} when is_list(users) ->
+ [emoji, users, nil]
+
+ _ ->
+ nil
+ end)
+ |> Enum.reject(&is_nil/1)
+ else
+ []
+ end
+ end
end
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
@@ -408,11 +408,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end
def get_cached_emoji_reactions(object) do
- if is_list(object.data["reactions"]) do
- object.data["reactions"]
- else
- []
- end
+ Object.get_emoji_reactions(object)
end
@spec add_like_to_object(Activity.t(), Object.t()) ::
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -334,8 +334,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end
emoji_reactions =
- object.data
- |> Map.get("reactions", [])
+ object
+ |> Object.get_emoji_reactions()
|> EmojiReactionController.filter_allowed_users(
opts[:for],
Map.get(opts, :with_muted, false)
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex
@@ -28,8 +28,8 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
def index(%{assigns: %{user: user}} = conn, %{id: activity_id} = params) do
with true <- Pleroma.Config.get([:instance, :show_reactions]),
%Activity{} = activity <- Activity.get_by_id_with_object(activity_id),
- %Object{data: %{"reactions" => reactions}} when is_list(reactions) <-
- Object.normalize(activity, fetch: false) do
+ %Object{} = object <- Object.normalize(activity, fetch: false),
+ reactions <- Object.get_emoji_reactions(object) do
reactions =
reactions
|> filter(params)
@@ -60,9 +60,6 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionController do
reactions
|> Stream.map(fn
[emoji, users, url] when is_list(users) -> filter_emoji.(emoji, users, url)
- {emoji, users, url} when is_list(users) -> filter_emoji.(emoji, users, url)
- {emoji, users} when is_list(users) -> filter_emoji.(emoji, users, nil)
- _ -> nil
end)
|> Stream.reject(&is_nil/1)
end
diff --git a/test/pleroma/object_test.exs b/test/pleroma/object_test.exs
@@ -444,4 +444,42 @@ defmodule Pleroma.ObjectTest do
Enum.sort_by(object.hashtags, & &1.name)
end
end
+
+ describe "get_emoji_reactions/1" do
+ test "3-tuple current format" do
+ object = %Object{
+ data: %{
+ "reactions" => [
+ ["x", ["https://some/user"], "https://some/emoji"]
+ ]
+ }
+ }
+
+ assert Object.get_emoji_reactions(object) == object.data["reactions"]
+ end
+
+ test "2-tuple legacy format" do
+ object = %Object{
+ data: %{
+ "reactions" => [
+ ["x", ["https://some/user"]]
+ ]
+ }
+ }
+
+ assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
+ end
+
+ test "Map format" do
+ object = %Object{
+ data: %{
+ "reactions" => %{
+ "x" => ["https://some/user"]
+ }
+ }
+ }
+
+ assert Object.get_emoji_reactions(object) == [["x", ["https://some/user"], nil]]
+ end
+ end
end
diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs
@@ -587,15 +587,38 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
end
describe "get_cached_emoji_reactions/1" do
- test "returns the data or an emtpy list" do
+ test "returns the normalized data or an emtpy list" do
object = insert(:note)
assert Utils.get_cached_emoji_reactions(object) == []
object = insert(:note, data: %{"reactions" => [["x", ["lain"]]]})
- assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"]]]
+ assert Utils.get_cached_emoji_reactions(object) == [["x", ["lain"], nil]]
object = insert(:note, data: %{"reactions" => %{}})
assert Utils.get_cached_emoji_reactions(object) == []
end
end
+
+ describe "add_emoji_reaction_to_object/1" do
+ test "works with legacy 2-tuple format" do
+ user = insert(:user)
+ other_user = insert(:user)
+ third_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [["😿", [other_user.ap_id]]]
+ }
+ )
+
+ _activity = insert(:note_activity, user: user, note: note)
+
+ Utils.add_emoji_reaction_to_object(
+ %Activity{data: %{"content" => "😿", "actor" => third_user.ap_id}},
+ note
+ )
+ end
+ end
end
diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -74,6 +74,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
]
end
+ test "works with legacy-formatted reactions" do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [["😿", [other_user.ap_id]]]
+ }
+ )
+
+ activity = insert(:note_activity, user: user, note: note)
+
+ status = StatusView.render("show.json", activity: activity, for: user)
+
+ assert status[:pleroma][:emoji_reactions] == [
+ %{name: "😿", count: 1, me: false, url: nil, account_ids: [other_user.id]}
+ ]
+ end
+
test "works correctly with badly formatted emojis" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "yo"})
diff --git a/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/emoji_reaction_controller_test.exs
@@ -245,6 +245,38 @@ defmodule Pleroma.Web.PleromaAPI.EmojiReactionControllerTest do
result
end
+ test "GET /api/v1/pleroma/statuses/:id/reactions with legacy format", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ note =
+ insert(:note,
+ user: user,
+ data: %{
+ "reactions" => [["😿", [other_user.ap_id]]]
+ }
+ )
+
+ activity = insert(:note_activity, user: user, note: note)
+
+ result =
+ conn
+ |> get("/api/v1/pleroma/statuses/#{activity.id}/reactions")
+ |> json_response_and_validate_schema(200)
+
+ other_user_id = other_user.id
+
+ assert [
+ %{
+ "name" => "😿",
+ "count" => 1,
+ "me" => false,
+ "url" => nil,
+ "accounts" => [%{"id" => ^other_user_id}]
+ }
+ ] = result
+ end
+
test "GET /api/v1/pleroma/statuses/:id/reactions?with_muted=true", %{conn: conn} do
user = insert(:user)
user2 = insert(:user)