Merge branch 'feature/emojireactvalidator' into 'develop'

Move EmojiReacts to the Pipeline.

See merge request pleroma/pleroma!2473
This commit is contained in:
lain 2020-05-08 10:41:41 +00:00
commit fbcc53760e
19 changed files with 276 additions and 169 deletions

View file

@ -356,31 +356,6 @@ def update(%{to: to, cc: cc, actor: actor, object: object} = params) do
end end
end end
@spec react_with_emoji(User.t(), Object.t(), String.t(), keyword()) ::
{:ok, Activity.t(), Object.t()} | {:error, any()}
def react_with_emoji(user, object, emoji, options \\ []) do
with {:ok, result} <-
Repo.transaction(fn -> do_react_with_emoji(user, object, emoji, options) end) do
result
end
end
defp do_react_with_emoji(user, object, emoji, options) do
with local <- Keyword.get(options, :local, true),
activity_id <- Keyword.get(options, :activity_id, nil),
true <- Pleroma.Emoji.is_unicode_emoji?(emoji),
reaction_data <- make_emoji_reaction_data(user, object, emoji, activity_id),
{:ok, activity} <- insert(reaction_data, local),
{:ok, object} <- add_emoji_reaction_to_object(activity, object),
_ <- notify_and_stream(activity),
:ok <- maybe_federate(activity) do
{:ok, activity, object}
else
false -> {:error, false}
{:error, error} -> Repo.rollback(error)
end
end
@spec announce(User.t(), Object.t(), String.t() | nil, boolean(), boolean()) :: @spec announce(User.t(), Object.t(), String.t() | nil, boolean(), boolean()) ::
{:ok, Activity.t(), Object.t()} | {:error, any()} {:ok, Activity.t(), Object.t()} | {:error, any()}
def announce( def announce(

View file

@ -10,6 +10,18 @@ defmodule Pleroma.Web.ActivityPub.Builder do
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
@spec emoji_react(User.t(), Object.t(), String.t()) :: {:ok, map(), keyword()}
def emoji_react(actor, object, emoji) do
with {:ok, data, meta} <- object_action(actor, object) do
data =
data
|> Map.put("content", emoji)
|> Map.put("type", "EmojiReact")
{:ok, data, meta}
end
end
@spec undo(User.t(), Activity.t()) :: {:ok, map(), keyword()} @spec undo(User.t(), Activity.t()) :: {:ok, map(), keyword()}
def undo(actor, object) do def undo(actor, object) do
{:ok, {:ok,
@ -52,6 +64,17 @@ def delete(actor, object_id) do
@spec like(User.t(), Object.t()) :: {:ok, map(), keyword()} @spec like(User.t(), Object.t()) :: {:ok, map(), keyword()}
def like(actor, object) do def like(actor, object) do
with {:ok, data, meta} <- object_action(actor, object) do
data =
data
|> Map.put("type", "Like")
{:ok, data, meta}
end
end
@spec object_action(User.t(), Object.t()) :: {:ok, map(), keyword()}
defp object_action(actor, object) do
object_actor = User.get_cached_by_ap_id(object.data["actor"]) object_actor = User.get_cached_by_ap_id(object.data["actor"])
# Address the actor of the object, and our actor's follower collection if the post is public. # Address the actor of the object, and our actor's follower collection if the post is public.
@ -73,7 +96,6 @@ def like(actor, object) do
%{ %{
"id" => Utils.generate_activity_id(), "id" => Utils.generate_activity_id(),
"actor" => actor.ap_id, "actor" => actor.ap_id,
"type" => "Like",
"object" => object.data["id"], "object" => object.data["id"],
"to" => to, "to" => to,
"cc" => cc, "cc" => cc,

View file

@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidator do
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator alias Pleroma.Web.ActivityPub.ObjectValidators.DeleteValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator alias Pleroma.Web.ActivityPub.ObjectValidators.LikeValidator
alias Pleroma.Web.ActivityPub.ObjectValidators.Types alias Pleroma.Web.ActivityPub.ObjectValidators.Types
alias Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator alias Pleroma.Web.ActivityPub.ObjectValidators.UndoValidator
@ -47,6 +48,16 @@ def validate(%{"type" => "Like"} = object, meta) do
end end
end end
def validate(%{"type" => "EmojiReact"} = object, meta) do
with {:ok, object} <-
object
|> EmojiReactValidator.cast_and_validate()
|> Ecto.Changeset.apply_action(:insert) do
object = stringify_keys(object |> Map.from_struct())
{:ok, object, meta}
end
end
def stringify_keys(%{__struct__: _} = object) do def stringify_keys(%{__struct__: _} = object) do
object object
|> Map.from_struct() |> Map.from_struct()

View file

@ -0,0 +1,81 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ObjectValidators.EmojiReactValidator do
use Ecto.Schema
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.ObjectValidators.Types
import Ecto.Changeset
import Pleroma.Web.ActivityPub.ObjectValidators.CommonValidations
@primary_key false
embedded_schema do
field(:id, Types.ObjectID, primary_key: true)
field(:type, :string)
field(:object, Types.ObjectID)
field(:actor, Types.ObjectID)
field(:context, :string)
field(:content, :string)
field(:to, {:array, :string}, default: [])
field(:cc, {:array, :string}, default: [])
end
def cast_and_validate(data) do
data
|> cast_data()
|> validate_data()
end
def cast_data(data) do
%__MODULE__{}
|> changeset(data)
end
def changeset(struct, data) do
struct
|> cast(data, __schema__(:fields))
|> fix_after_cast()
end
def fix_after_cast(cng) do
cng
|> fix_context()
end
def fix_context(cng) do
object = get_field(cng, :object)
with nil <- get_field(cng, :context),
%Object{data: %{"context" => context}} <- Object.get_cached_by_ap_id(object) do
cng
|> put_change(:context, context)
else
_ ->
cng
end
end
def validate_emoji(cng) do
content = get_field(cng, :content)
if Pleroma.Emoji.is_unicode_emoji?(content) do
cng
else
cng
|> add_error(:content, "must be a single character emoji")
end
end
def validate_data(data_cng) do
data_cng
|> validate_inclusion(:type, ["EmojiReact"])
|> validate_required([:id, :type, :object, :actor, :context, :to, :cc, :content])
|> validate_actor_presence()
|> validate_object_presence()
|> validate_emoji()
end
end

View file

@ -34,6 +34,18 @@ def handle(%{data: %{"type" => "Undo", "object" => undone_object}} = object, met
end end
end end
# Tasks this handles:
# - Add reaction to object
# - Set up notification
def handle(%{data: %{"type" => "EmojiReact"}} = object, meta) do
reacted_object = Object.get_by_ap_id(object.data["object"])
Utils.add_emoji_reaction_to_object(object, reacted_object)
Notification.create_notifications(object)
{:ok, object, meta}
end
# Tasks this handles: # Tasks this handles:
# - Delete and unpins the create activity # - Delete and unpins the create activity
# - Replace object with Tombstone # - Replace object with Tombstone

View file

@ -656,7 +656,7 @@ def handle_incoming(
|> handle_incoming(options) |> handle_incoming(options)
end end
def handle_incoming(%{"type" => "Like"} = data, _options) do def handle_incoming(%{"type" => type} = data, _options) when type in ["Like", "EmojiReact"] do
with :ok <- ObjectValidator.fetch_actor_and_object(data), with :ok <- ObjectValidator.fetch_actor_and_object(data),
{:ok, activity, _meta} <- {:ok, activity, _meta} <-
Pipeline.common_pipeline(data, local: false) do Pipeline.common_pipeline(data, local: false) do
@ -666,27 +666,6 @@ def handle_incoming(%{"type" => "Like"} = data, _options) do
end end
end end
def handle_incoming(
%{
"type" => "EmojiReact",
"object" => object_id,
"actor" => _actor,
"id" => id,
"content" => emoji
} = data,
_options
) do
with actor <- Containment.get_actor(data),
{:ok, %User{} = actor} <- User.get_or_fetch_by_ap_id(actor),
{:ok, object} <- get_obj_helper(object_id),
{:ok, activity, _object} <-
ActivityPub.react_with_emoji(actor, object, emoji, activity_id: id, local: false) do
{:ok, activity}
else
_e -> :error
end
end
def handle_incoming( def handle_incoming(
%{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data, %{"type" => "Announce", "object" => object_id, "actor" => _actor, "id" => id} = data,
_options _options

View file

@ -191,8 +191,10 @@ def unfavorite(id, user) do
def react_with_emoji(id, user, emoji) do def react_with_emoji(id, user, emoji) do
with %Activity{} = activity <- Activity.get_by_id(id), with %Activity{} = activity <- Activity.get_by_id(id),
object <- Object.normalize(activity) do object <- Object.normalize(activity),
ActivityPub.react_with_emoji(user, object, emoji) {:ok, emoji_react, _} <- Builder.emoji_react(user, object, emoji),
{:ok, activity, _} <- Pipeline.common_pipeline(emoji_react, local: true) do
{:ok, activity}
else else
_ -> _ ->
{:error, dgettext("errors", "Could not add reaction emoji")} {:error, dgettext("errors", "Could not add reaction emoji")}

View file

@ -86,7 +86,7 @@ def emoji_reactions_by(%{assigns: %{user: user}} = conn, %{"id" => activity_id}
end end
def react_with_emoji(%{assigns: %{user: user}} = conn, %{"id" => activity_id, "emoji" => emoji}) do def react_with_emoji(%{assigns: %{user: user}} = conn, %{"id" => activity_id, "emoji" => emoji}) do
with {:ok, _activity, _object} <- CommonAPI.react_with_emoji(activity_id, user, emoji), with {:ok, _activity} <- CommonAPI.react_with_emoji(activity_id, user, emoji),
activity <- Activity.get_by_id(activity_id) do activity <- Activity.get_by_id(activity_id) do
conn conn
|> put_view(StatusView) |> put_view(StatusView)

View file

@ -24,7 +24,7 @@ test "creates a notification for an emoji reaction" do
other_user = insert(:user) other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "yeah"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "yeah"})
{:ok, activity, _object} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, activity} = CommonAPI.react_with_emoji(activity.id, other_user, "")
{:ok, [notification]} = Notification.create_notifications(activity) {:ok, [notification]} = Notification.create_notifications(activity)

View file

@ -16,7 +16,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.ActivityPub.Utils
alias Pleroma.Web.AdminAPI.AccountView alias Pleroma.Web.AdminAPI.AccountView
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Federator
import ExUnit.CaptureLog import ExUnit.CaptureLog
import Mock import Mock
@ -874,71 +873,6 @@ test "returns reblogs for users for whom reblogs have not been muted" do
end end
end end
describe "react to an object" do
test_with_mock "sends an activity to federation", Federator, [:passthrough], [] do
Config.put([:instance, :federating], true)
user = insert(:user)
reactor = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
assert object = Object.normalize(activity)
{:ok, reaction_activity, _object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
assert called(Federator.publish(reaction_activity))
end
test "adds an emoji reaction activity to the db" do
user = insert(:user)
reactor = insert(:user)
third_user = insert(:user)
fourth_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "YASSSS queen slay"})
assert object = Object.normalize(activity)
{:ok, reaction_activity, object} = ActivityPub.react_with_emoji(reactor, object, "🔥")
assert reaction_activity
assert reaction_activity.data["actor"] == reactor.ap_id
assert reaction_activity.data["type"] == "EmojiReact"
assert reaction_activity.data["content"] == "🔥"
assert reaction_activity.data["object"] == object.data["id"]
assert reaction_activity.data["to"] == [User.ap_followers(reactor), activity.data["actor"]]
assert reaction_activity.data["context"] == object.data["context"]
assert object.data["reaction_count"] == 1
assert object.data["reactions"] == [["🔥", [reactor.ap_id]]]
{:ok, _reaction_activity, object} = ActivityPub.react_with_emoji(third_user, object, "")
assert object.data["reaction_count"] == 2
assert object.data["reactions"] == [["🔥", [reactor.ap_id]], ["", [third_user.ap_id]]]
{:ok, _reaction_activity, object} = ActivityPub.react_with_emoji(fourth_user, object, "🔥")
assert object.data["reaction_count"] == 3
assert object.data["reactions"] == [
["🔥", [fourth_user.ap_id, reactor.ap_id]],
["", [third_user.ap_id]]
]
end
test "reverts emoji reaction on error" do
[user, reactor] = insert_list(2, :user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "Status"})
object = Object.normalize(activity)
with_mock(Utils, [:passthrough], maybe_federate: fn _ -> {:error, :reverted} end) do
assert {:error, :reverted} = ActivityPub.react_with_emoji(reactor, object, "😀")
end
object = Object.get_by_ap_id(object.data["id"])
refute object.data["reaction_count"]
refute object.data["reactions"]
end
end
describe "announcing an object" do describe "announcing an object" do
test "adds an announce activity to the db" do test "adds an announce activity to the db" do
note_activity = insert(:note_activity) note_activity = insert(:note_activity)

View file

@ -10,6 +10,46 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidatorTest do
import Pleroma.Factory import Pleroma.Factory
describe "EmojiReacts" do
setup do
user = insert(:user)
{:ok, post_activity} = CommonAPI.post(user, %{"status" => "uguu"})
object = Pleroma.Object.get_by_ap_id(post_activity.data["object"])
{:ok, valid_emoji_react, []} = Builder.emoji_react(user, object, "👌")
%{user: user, post_activity: post_activity, valid_emoji_react: valid_emoji_react}
end
test "it validates a valid EmojiReact", %{valid_emoji_react: valid_emoji_react} do
assert {:ok, _, _} = ObjectValidator.validate(valid_emoji_react, [])
end
test "it is not valid without a 'content' field", %{valid_emoji_react: valid_emoji_react} do
without_content =
valid_emoji_react
|> Map.delete("content")
{:error, cng} = ObjectValidator.validate(without_content, [])
refute cng.valid?
assert {:content, {"can't be blank", [validation: :required]}} in cng.errors
end
test "it is not valid with a non-emoji content field", %{valid_emoji_react: valid_emoji_react} do
without_emoji_content =
valid_emoji_react
|> Map.put("content", "x")
{:error, cng} = ObjectValidator.validate(without_emoji_content, [])
refute cng.valid?
assert {:content, {"must be a single character emoji", []}} in cng.errors
end
end
describe "Undos" do describe "Undos" do
setup do setup do
user = insert(:user) user = insert(:user)

View file

@ -72,13 +72,40 @@ test "it handles user deletions", %{delete_user: delete, user: user} do
end end
end end
describe "EmojiReact objects" do
setup do
poster = insert(:user)
user = insert(:user)
{:ok, post} = CommonAPI.post(poster, %{"status" => "hey"})
{:ok, emoji_react_data, []} = Builder.emoji_react(user, post.object, "👌")
{:ok, emoji_react, _meta} = ActivityPub.persist(emoji_react_data, local: true)
%{emoji_react: emoji_react, user: user, poster: poster}
end
test "adds the reaction to the object", %{emoji_react: emoji_react, user: user} do
{:ok, emoji_react, _} = SideEffects.handle(emoji_react)
object = Object.get_by_ap_id(emoji_react.data["object"])
assert object.data["reaction_count"] == 1
assert ["👌", [user.ap_id]] in object.data["reactions"]
end
test "creates a notification", %{emoji_react: emoji_react, poster: poster} do
{:ok, emoji_react, _} = SideEffects.handle(emoji_react)
assert Repo.get_by(Notification, user_id: poster.id, activity_id: emoji_react.id)
end
end
describe "Undo objects" do describe "Undo objects" do
setup do setup do
poster = insert(:user) poster = insert(:user)
user = insert(:user) user = insert(:user)
{:ok, post} = CommonAPI.post(poster, %{"status" => "hey"}) {:ok, post} = CommonAPI.post(poster, %{"status" => "hey"})
{:ok, like} = CommonAPI.favorite(user, post.id) {:ok, like} = CommonAPI.favorite(user, post.id)
{:ok, reaction, _} = CommonAPI.react_with_emoji(post.id, user, "👍") {:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
{:ok, announce, _} = CommonAPI.repeat(post.id, user) {:ok, announce, _} = CommonAPI.repeat(post.id, user)
{:ok, block} = ActivityPub.block(user, poster) {:ok, block} = ActivityPub.block(user, poster)
User.block(user, poster) User.block(user, poster)

View file

@ -0,0 +1,61 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
use Pleroma.DataCase
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.CommonAPI
import Pleroma.Factory
test "it works for incoming emoji reactions" do
user = insert(:user)
other_user = insert(:user, local: false)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
data =
File.read!("test/fixtures/emoji-reaction.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
|> Map.put("actor", other_user.ap_id)
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["actor"] == other_user.ap_id
assert data["type"] == "EmojiReact"
assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2"
assert data["object"] == activity.data["object"]
assert data["content"] == "👌"
object = Object.get_by_ap_id(data["object"])
assert object.data["reaction_count"] == 1
assert match?([["👌", _]], object.data["reactions"])
end
test "it reject invalid emoji reactions" do
user = insert(:user)
other_user = insert(:user, local: false)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
data =
File.read!("test/fixtures/emoji-reaction-too-long.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
|> Map.put("actor", other_user.ap_id)
assert {:error, _} = Transmogrifier.handle_incoming(data)
data =
File.read!("test/fixtures/emoji-reaction-no-emoji.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
|> Map.put("actor", other_user.ap_id)
assert {:error, _} = Transmogrifier.handle_incoming(data)
end
end

View file

@ -17,7 +17,7 @@ test "it works for incoming emoji reaction undos" do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
{:ok, reaction_activity, _object} = CommonAPI.react_with_emoji(activity.id, user, "👌") {:ok, reaction_activity} = CommonAPI.react_with_emoji(activity.id, user, "👌")
data = data =
File.read!("test/fixtures/mastodon-undo-like.json") File.read!("test/fixtures/mastodon-undo-like.json")

View file

@ -325,43 +325,6 @@ test "it cleans up incoming notices which are not really DMs" do
assert object_data["cc"] == to assert object_data["cc"] == to
end end
test "it works for incoming emoji reactions" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
data =
File.read!("test/fixtures/emoji-reaction.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
assert data["actor"] == "http://mastodon.example.org/users/admin"
assert data["type"] == "EmojiReact"
assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2"
assert data["object"] == activity.data["object"]
assert data["content"] == "👌"
end
test "it reject invalid emoji reactions" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hello"})
data =
File.read!("test/fixtures/emoji-reaction-too-long.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
assert :error = Transmogrifier.handle_incoming(data)
data =
File.read!("test/fixtures/emoji-reaction-no-emoji.json")
|> Poison.decode!()
|> Map.put("object", activity.data["object"])
assert :error = Transmogrifier.handle_incoming(data)
end
test "it works for incoming announces" do test "it works for incoming announces" do
data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!() data = File.read!("test/fixtures/mastodon-announce.json") |> Poison.decode!()
@ -518,7 +481,7 @@ test "it strips internal likes" do
test "it strips internal reactions" do test "it strips internal reactions" do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "📢") {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "📢")
%{object: object} = Activity.get_by_id_with_object(activity.id) %{object: object} = Activity.get_by_id_with_object(activity.id)
assert Map.has_key?(object.data, "reactions") assert Map.has_key?(object.data, "reactions")

View file

@ -358,7 +358,7 @@ test "reacting to a status with an emoji" do
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
{:ok, reaction, _} = CommonAPI.react_with_emoji(activity.id, user, "👍") {:ok, reaction} = CommonAPI.react_with_emoji(activity.id, user, "👍")
assert reaction.data["actor"] == user.ap_id assert reaction.data["actor"] == user.ap_id
assert reaction.data["content"] == "👍" assert reaction.data["content"] == "👍"
@ -373,7 +373,7 @@ test "unreacting to a status with an emoji" do
other_user = insert(:user) other_user = insert(:user)
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"}) {:ok, activity} = CommonAPI.post(other_user, %{"status" => "cofe"})
{:ok, reaction, _} = CommonAPI.react_with_emoji(activity.id, user, "👍") {:ok, reaction} = CommonAPI.react_with_emoji(activity.id, user, "👍")
{:ok, unreaction} = CommonAPI.unreact_with_emoji(activity.id, user, "👍") {:ok, unreaction} = CommonAPI.unreact_with_emoji(activity.id, user, "👍")

View file

@ -156,7 +156,7 @@ test "EmojiReact notification" do
other_user = insert(:user) other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
{:ok, _activity, _} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, _activity} = CommonAPI.react_with_emoji(activity.id, other_user, "")
activity = Repo.get(Activity, activity.id) activity = Repo.get(Activity, activity.id)

View file

@ -32,9 +32,9 @@ test "has an emoji reaction list" do
third_user = insert(:user) third_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "dae cofe??"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "dae cofe??"})
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, user, "") {:ok, _} = CommonAPI.react_with_emoji(activity.id, user, "")
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵") {:ok, _} = CommonAPI.react_with_emoji(activity.id, third_user, "🍵")
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "")
activity = Repo.get(Activity, activity.id) activity = Repo.get(Activity, activity.id)
status = StatusView.render("show.json", activity: activity) status = StatusView.render("show.json", activity: activity)

View file

@ -43,7 +43,7 @@ test "DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
other_user = insert(:user) other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe"})
{:ok, _reaction, _object} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, _reaction_activity} = CommonAPI.react_with_emoji(activity.id, other_user, "")
ObanHelpers.perform_all() ObanHelpers.perform_all()
@ -77,8 +77,8 @@ test "GET /api/v1/pleroma/statuses/:id/reactions", %{conn: conn} do
assert result == [] assert result == []
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅") {:ok, _} = CommonAPI.react_with_emoji(activity.id, doomed_user, "🎅")
User.perform(:delete, doomed_user) User.perform(:delete, doomed_user)
@ -115,8 +115,8 @@ test "GET /api/v1/pleroma/statuses/:id/reactions/:emoji", %{conn: conn} do
assert result == [] assert result == []
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "🎅")
{:ok, _, _} = CommonAPI.react_with_emoji(activity.id, other_user, "") {:ok, _} = CommonAPI.react_with_emoji(activity.id, other_user, "")
result = result =
conn conn