forked from AkkomaGang/akkoma
Oneric
7622aa27ca
Currently our own frontend doesn’t show backgrounds of other users, this
property is already publicly readable via REST API and likely was always
intended to be shown and federated.
Recently Sharkey added support for profile backgrounds and
immediately made them federate and be displayed to others.
We use the same AP field as Sharkey here which should make
it interoperable both ways out-of-the-box.
Ref.: 4e64397635
823 lines
27 KiB
Elixir
823 lines
27 KiB
Elixir
# Pleroma: A lightweight social networking server
|
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|
use Oban.Testing, repo: Pleroma.Repo
|
|
use Pleroma.DataCase, async: false
|
|
@moduletag :mocked
|
|
|
|
alias Pleroma.Activity
|
|
alias Pleroma.Notification
|
|
alias Pleroma.Object
|
|
alias Pleroma.Repo
|
|
alias Pleroma.Tests.ObanHelpers
|
|
alias Pleroma.User
|
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
|
alias Pleroma.Web.ActivityPub.Builder
|
|
alias Pleroma.Web.ActivityPub.SideEffects
|
|
alias Pleroma.Web.ActivityPub.Utils
|
|
alias Pleroma.Web.CommonAPI
|
|
|
|
import Mock
|
|
import Pleroma.Factory
|
|
|
|
describe "handle" do
|
|
test "it queues a fetch of instance information" do
|
|
author = insert(:user, local: false, ap_id: "https://wowee.example.com/users/1")
|
|
recipient = insert(:user, local: true)
|
|
|
|
{:ok, note_data, _meta} =
|
|
Builder.note(%Pleroma.Web.CommonAPI.ActivityDraft{
|
|
user: author,
|
|
to: [recipient.ap_id],
|
|
mentions: [recipient],
|
|
content_html: "hey",
|
|
extra: %{"id" => "https://wowee.example.com/notes/1"}
|
|
})
|
|
|
|
{:ok, create_activity_data, _meta} =
|
|
Builder.create(author, note_data["id"], [recipient.ap_id])
|
|
|
|
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
|
|
|
|
{:ok, _create_activity, _meta} =
|
|
SideEffects.handle(create_activity, local: false, object_data: note_data)
|
|
|
|
assert_enqueued(
|
|
worker: Pleroma.Workers.NodeInfoFetcherWorker,
|
|
args: %{"op" => "process", "source_url" => "https://wowee.example.com/users/1"}
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "handle_after_transaction" do
|
|
test "it streams out notifications and streams" do
|
|
author = insert(:user, local: true)
|
|
recipient = insert(:user, local: true)
|
|
|
|
{:ok, note_data, _meta} =
|
|
Builder.note(%Pleroma.Web.CommonAPI.ActivityDraft{
|
|
user: author,
|
|
to: [recipient.ap_id],
|
|
mentions: [recipient],
|
|
content_html: "hey",
|
|
extra: %{"id" => Utils.generate_object_id()}
|
|
})
|
|
|
|
{:ok, create_activity_data, _meta} =
|
|
Builder.create(author, note_data["id"], [recipient.ap_id])
|
|
|
|
{:ok, create_activity, _meta} = ActivityPub.persist(create_activity_data, local: false)
|
|
|
|
{:ok, _create_activity, meta} =
|
|
SideEffects.handle(create_activity, local: false, object_data: note_data)
|
|
|
|
assert [notification] = meta[:notifications]
|
|
|
|
with_mocks([
|
|
{
|
|
Pleroma.Web.Streamer,
|
|
[],
|
|
[
|
|
stream: fn _, _ -> nil end
|
|
]
|
|
},
|
|
{
|
|
Pleroma.Web.Push,
|
|
[],
|
|
[
|
|
send: fn _ -> nil end
|
|
]
|
|
}
|
|
]) do
|
|
SideEffects.handle_after_transaction(meta)
|
|
|
|
assert called(Pleroma.Web.Streamer.stream(["user", "user:notification"], notification))
|
|
assert called(Pleroma.Web.Push.send(notification))
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "blocking users" do
|
|
setup do
|
|
user = insert(:user)
|
|
blocked = insert(:user)
|
|
User.follow(blocked, user)
|
|
User.follow(user, blocked)
|
|
|
|
{:ok, block_data, []} = Builder.block(user, blocked)
|
|
{:ok, block, _meta} = ActivityPub.persist(block_data, local: true)
|
|
|
|
%{user: user, blocked: blocked, block: block}
|
|
end
|
|
|
|
test "it unfollows and blocks", %{user: user, blocked: blocked, block: block} do
|
|
assert User.following?(user, blocked)
|
|
assert User.following?(blocked, user)
|
|
|
|
{:ok, _, _} = SideEffects.handle(block)
|
|
|
|
refute User.following?(user, blocked)
|
|
refute User.following?(blocked, user)
|
|
assert User.blocks?(user, blocked)
|
|
end
|
|
|
|
test "it updates following relationship", %{user: user, blocked: blocked, block: block} do
|
|
{:ok, _, _} = SideEffects.handle(block)
|
|
|
|
refute Pleroma.FollowingRelationship.get(user, blocked)
|
|
assert User.get_follow_state(user, blocked) == nil
|
|
assert User.get_follow_state(blocked, user) == nil
|
|
assert User.get_follow_state(user, blocked, nil) == nil
|
|
assert User.get_follow_state(blocked, user, nil) == nil
|
|
end
|
|
|
|
test "it blocks but does not unfollow if the relevant setting is set", %{
|
|
user: user,
|
|
blocked: blocked,
|
|
block: block
|
|
} do
|
|
clear_config([:activitypub, :unfollow_blocked], false)
|
|
assert User.following?(user, blocked)
|
|
assert User.following?(blocked, user)
|
|
|
|
{:ok, _, _} = SideEffects.handle(block)
|
|
|
|
refute User.following?(user, blocked)
|
|
assert User.following?(blocked, user)
|
|
assert User.blocks?(user, blocked)
|
|
end
|
|
end
|
|
|
|
describe "update users" do
|
|
setup do
|
|
user = insert(:user, local: false)
|
|
|
|
{:ok, update_data, []} =
|
|
Builder.update(user, %{
|
|
"id" => user.ap_id,
|
|
"type" => "Person",
|
|
"name" => "new name!",
|
|
"icon" => %{"type" => "Image", "url" => "https://example.org/icon.png"},
|
|
"backgroundUrl" => %{"type" => "Image", "url" => "https://example.org/bg.jxl"}
|
|
})
|
|
|
|
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
|
|
|
%{user: user, update_data: update_data, update: update}
|
|
end
|
|
|
|
test "it updates the user", %{user: user, update: update} do
|
|
{:ok, _, _} = SideEffects.handle(update)
|
|
user = User.get_by_id(user.id)
|
|
|
|
assert user.name == "new name!"
|
|
assert [%{"href" => "https://example.org/icon.png"}] = user.avatar["url"]
|
|
assert [%{"href" => "https://example.org/bg.jxl"}] = user.background["url"]
|
|
end
|
|
|
|
test "it uses a given changeset to update", %{user: user, update: update} do
|
|
changeset = Ecto.Changeset.change(user, %{default_scope: "direct"})
|
|
|
|
assert user.default_scope == "public"
|
|
{:ok, _, _} = SideEffects.handle(update, user_update_changeset: changeset)
|
|
user = User.get_by_id(user.id)
|
|
assert user.default_scope == "direct"
|
|
end
|
|
end
|
|
|
|
describe "update notes" do
|
|
setup do
|
|
make_time = fn ->
|
|
Pleroma.Web.ActivityPub.Utils.make_date()
|
|
end
|
|
|
|
user = insert(:user)
|
|
note = insert(:note, user: user, data: %{"published" => make_time.()})
|
|
_note_activity = insert(:note_activity, note: note)
|
|
|
|
updated_note =
|
|
note.data
|
|
|> Map.put("summary", "edited summary")
|
|
|> Map.put("content", "edited content")
|
|
|> Map.put("updated", make_time.())
|
|
|
|
{:ok, update_data, []} = Builder.update(user, updated_note)
|
|
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
|
|
|
%{
|
|
user: user,
|
|
note: note,
|
|
object_id: note.id,
|
|
update_data: update_data,
|
|
update: update,
|
|
updated_note: updated_note
|
|
}
|
|
end
|
|
|
|
test "it updates the note", %{
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
updated_time = updated_note["updated"]
|
|
|
|
new_note = Pleroma.Object.get_by_id(object_id)
|
|
|
|
assert %{
|
|
"summary" => "edited summary",
|
|
"content" => "edited content",
|
|
"updated" => ^updated_time
|
|
} = new_note.data
|
|
end
|
|
|
|
test "it rejects updates with no updated attribute in object", %{
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
old_note = Pleroma.Object.get_by_id(object_id)
|
|
updated_note = Map.drop(updated_note, ["updated"])
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
new_note = Pleroma.Object.get_by_id(object_id)
|
|
assert old_note.data == new_note.data
|
|
end
|
|
|
|
test "it rejects updates with updated attribute older than what we have in the original object",
|
|
%{
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
old_note = Pleroma.Object.get_by_id(object_id)
|
|
{:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
|
|
|
|
updated_note =
|
|
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, -10)))
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
new_note = Pleroma.Object.get_by_id(object_id)
|
|
assert old_note.data == new_note.data
|
|
end
|
|
|
|
test "it rejects updates with updated attribute older than the last Update", %{
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
old_note = Pleroma.Object.get_by_id(object_id)
|
|
{:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
|
|
|
|
updated_note =
|
|
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, +10)))
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
|
|
old_note = Pleroma.Object.get_by_id(object_id)
|
|
{:ok, update_time, _} = DateTime.from_iso8601(old_note.data["updated"])
|
|
|
|
updated_note =
|
|
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(update_time, -5)))
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
|
|
new_note = Pleroma.Object.get_by_id(object_id)
|
|
assert old_note.data == new_note.data
|
|
end
|
|
|
|
test "it updates using object_data", %{
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
updated_note = Map.put(updated_note, "summary", "mew mew")
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
new_note = Pleroma.Object.get_by_id(object_id)
|
|
assert %{"summary" => "mew mew", "content" => "edited content"} = new_note.data
|
|
end
|
|
|
|
test "it records the original note in formerRepresentations", %{
|
|
note: note,
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
|
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
|
|
|
|
assert [Map.drop(note.data, ["id", "formerRepresentations"])] ==
|
|
new_note["formerRepresentations"]["orderedItems"]
|
|
|
|
assert new_note["formerRepresentations"]["totalItems"] == 1
|
|
end
|
|
|
|
test "it puts the original note at the front of formerRepresentations", %{
|
|
user: user,
|
|
note: note,
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
|
|
|
|
second_updated_note =
|
|
note.data
|
|
|> Map.put("summary", "edited summary 2")
|
|
|> Map.put("content", "edited content 2")
|
|
|> Map.put(
|
|
"updated",
|
|
first_edit["updated"]
|
|
|> DateTime.from_iso8601()
|
|
|> elem(1)
|
|
|> DateTime.add(10)
|
|
|> DateTime.to_iso8601()
|
|
)
|
|
|
|
{:ok, second_update_data, []} = Builder.update(user, second_updated_note)
|
|
{:ok, update, _meta} = ActivityPub.persist(second_update_data, local: true)
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: second_updated_note)
|
|
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
|
assert %{"summary" => "edited summary 2", "content" => "edited content 2"} = new_note
|
|
|
|
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
|
|
first_edit = Map.drop(first_edit, ["id", "formerRepresentations"])
|
|
|
|
assert [first_edit, original_version] ==
|
|
new_note["formerRepresentations"]["orderedItems"]
|
|
|
|
assert new_note["formerRepresentations"]["totalItems"] == 2
|
|
end
|
|
|
|
test "it does not prepend to formerRepresentations if no actual changes are made", %{
|
|
note: note,
|
|
object_id: object_id,
|
|
update: update,
|
|
updated_note: updated_note
|
|
} do
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
|
|
|
|
updated_note =
|
|
updated_note
|
|
|> Map.put(
|
|
"updated",
|
|
first_edit["updated"]
|
|
|> DateTime.from_iso8601()
|
|
|> elem(1)
|
|
|> DateTime.add(10)
|
|
|> DateTime.to_iso8601()
|
|
)
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
|
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
|
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
|
|
|
|
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
|
|
|
|
assert [original_version] ==
|
|
new_note["formerRepresentations"]["orderedItems"]
|
|
|
|
assert new_note["formerRepresentations"]["totalItems"] == 1
|
|
end
|
|
end
|
|
|
|
describe "update questions" do
|
|
setup do
|
|
user = insert(:user)
|
|
|
|
question =
|
|
insert(:question,
|
|
user: user,
|
|
data: %{"published" => Pleroma.Web.ActivityPub.Utils.make_date()}
|
|
)
|
|
|
|
%{user: user, data: question.data, id: question.id}
|
|
end
|
|
|
|
test "allows updating choice count without generating edit history", %{
|
|
user: user,
|
|
data: data,
|
|
id: id
|
|
} do
|
|
new_choices =
|
|
data["oneOf"]
|
|
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
|
|
|
updated_question =
|
|
data
|
|
|> Map.put("oneOf", new_choices)
|
|
|> Map.put("updated", Pleroma.Web.ActivityPub.Utils.make_date())
|
|
|
|
{:ok, update_data, []} = Builder.update(user, updated_question)
|
|
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
|
|
|
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
|
|
|
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
|
new_question["oneOf"]
|
|
|
|
refute Map.has_key?(new_question, "formerRepresentations")
|
|
end
|
|
|
|
test "allows updating choice count without updated field", %{
|
|
user: user,
|
|
data: data,
|
|
id: id
|
|
} do
|
|
new_choices =
|
|
data["oneOf"]
|
|
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
|
|
|
updated_question =
|
|
data
|
|
|> Map.put("oneOf", new_choices)
|
|
|
|
{:ok, update_data, []} = Builder.update(user, updated_question)
|
|
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
|
|
|
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
|
|
|
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
|
new_question["oneOf"]
|
|
|
|
refute Map.has_key?(new_question, "formerRepresentations")
|
|
end
|
|
|
|
test "allows updating choice count with updated field same as the creation date", %{
|
|
user: user,
|
|
data: data,
|
|
id: id
|
|
} do
|
|
new_choices =
|
|
data["oneOf"]
|
|
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
|
|
|
updated_question =
|
|
data
|
|
|> Map.put("oneOf", new_choices)
|
|
|> Map.put("updated", data["published"])
|
|
|
|
{:ok, update_data, []} = Builder.update(user, updated_question)
|
|
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
|
|
|
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
|
|
|
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
|
|
|
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
|
new_question["oneOf"]
|
|
|
|
refute Map.has_key?(new_question, "formerRepresentations")
|
|
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], nil] 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 "Question objects" do
|
|
setup do
|
|
user = insert(:user)
|
|
question = build(:question, user: user)
|
|
question_activity = build(:question_activity, question: question)
|
|
activity_data = Map.put(question_activity.data, "object", question.data["id"])
|
|
meta = [object_data: question.data, local: false]
|
|
|
|
{:ok, activity, meta} = ActivityPub.persist(activity_data, meta)
|
|
|
|
%{activity: activity, meta: meta}
|
|
end
|
|
|
|
test "enqueues the poll end", %{activity: activity, meta: meta} do
|
|
{:ok, activity, meta} = SideEffects.handle(activity, meta)
|
|
|
|
{:ok, time, _} = DateTime.from_iso8601(meta[:object_data]["closed"])
|
|
|
|
assert_enqueued(
|
|
worker: Pleroma.Workers.PollWorker,
|
|
args: %{op: "poll_end", activity_id: activity.id},
|
|
scheduled_at: time
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "delete users with confirmation pending" do
|
|
setup do
|
|
user = insert(:user, is_confirmed: false)
|
|
{:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
|
|
{:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
|
|
{:ok, delete: delete_user, user: user}
|
|
end
|
|
|
|
test "when activation is required", %{delete: delete, user: user} do
|
|
clear_config([:instance, :account_activation_required], true)
|
|
{:ok, _, _} = SideEffects.handle(delete)
|
|
ObanHelpers.perform_all()
|
|
|
|
refute User.get_cached_by_id(user.id)
|
|
end
|
|
end
|
|
|
|
describe "Undo objects" do
|
|
setup do
|
|
poster = insert(:user)
|
|
user = insert(:user)
|
|
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
|
{:ok, like} = CommonAPI.favorite(user, post.id)
|
|
{:ok, reaction} = CommonAPI.react_with_emoji(post.id, user, "👍")
|
|
{:ok, announce} = CommonAPI.repeat(post.id, user)
|
|
{:ok, block} = CommonAPI.block(user, poster)
|
|
|
|
{:ok, undo_data, _meta} = Builder.undo(user, like)
|
|
{:ok, like_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
|
|
|
{:ok, undo_data, _meta} = Builder.undo(user, reaction)
|
|
{:ok, reaction_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
|
|
|
{:ok, undo_data, _meta} = Builder.undo(user, announce)
|
|
{:ok, announce_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
|
|
|
{:ok, undo_data, _meta} = Builder.undo(user, block)
|
|
{:ok, block_undo, _meta} = ActivityPub.persist(undo_data, local: true)
|
|
|
|
%{
|
|
like_undo: like_undo,
|
|
post: post,
|
|
like: like,
|
|
reaction_undo: reaction_undo,
|
|
reaction: reaction,
|
|
announce_undo: announce_undo,
|
|
announce: announce,
|
|
block_undo: block_undo,
|
|
block: block,
|
|
poster: poster,
|
|
user: user
|
|
}
|
|
end
|
|
|
|
test "deletes the original block", %{
|
|
block_undo: block_undo,
|
|
block: block
|
|
} do
|
|
{:ok, _block_undo, _meta} = SideEffects.handle(block_undo)
|
|
|
|
refute Activity.get_by_id(block.id)
|
|
end
|
|
|
|
test "unblocks the blocked user", %{block_undo: block_undo, block: block} do
|
|
blocker = User.get_by_ap_id(block.data["actor"])
|
|
blocked = User.get_by_ap_id(block.data["object"])
|
|
|
|
{:ok, _block_undo, _} = SideEffects.handle(block_undo)
|
|
refute User.blocks?(blocker, blocked)
|
|
end
|
|
|
|
test "an announce undo removes the announce from the object", %{
|
|
announce_undo: announce_undo,
|
|
post: post
|
|
} do
|
|
{:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
|
|
|
|
object = Object.get_by_ap_id(post.data["object"])
|
|
|
|
assert object.data["announcement_count"] == 0
|
|
assert object.data["announcements"] == []
|
|
end
|
|
|
|
test "deletes the original announce", %{announce_undo: announce_undo, announce: announce} do
|
|
{:ok, _announce_undo, _} = SideEffects.handle(announce_undo)
|
|
refute Activity.get_by_id(announce.id)
|
|
end
|
|
|
|
test "a reaction undo removes the reaction from the object", %{
|
|
reaction_undo: reaction_undo,
|
|
post: post
|
|
} do
|
|
{:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
|
|
|
|
object = Object.get_by_ap_id(post.data["object"])
|
|
|
|
assert object.data["reaction_count"] == 0
|
|
assert object.data["reactions"] == []
|
|
end
|
|
|
|
test "deletes the original reaction", %{reaction_undo: reaction_undo, reaction: reaction} do
|
|
{:ok, _reaction_undo, _} = SideEffects.handle(reaction_undo)
|
|
refute Activity.get_by_id(reaction.id)
|
|
end
|
|
|
|
test "a like undo removes the like from the object", %{like_undo: like_undo, post: post} do
|
|
{:ok, _like_undo, _} = SideEffects.handle(like_undo)
|
|
|
|
object = Object.get_by_ap_id(post.data["object"])
|
|
|
|
assert object.data["like_count"] == 0
|
|
assert object.data["likes"] == []
|
|
end
|
|
|
|
test "deletes the original like", %{like_undo: like_undo, like: like} do
|
|
{:ok, _like_undo, _} = SideEffects.handle(like_undo)
|
|
refute Activity.get_by_id(like.id)
|
|
end
|
|
end
|
|
|
|
describe "like objects" do
|
|
setup do
|
|
poster = insert(:user)
|
|
user = insert(:user)
|
|
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
|
|
|
{:ok, like_data, _meta} = Builder.like(user, post.object)
|
|
{:ok, like, _meta} = ActivityPub.persist(like_data, local: true)
|
|
|
|
%{like: like, user: user, poster: poster}
|
|
end
|
|
|
|
test "add the like to the original object", %{like: like, user: user} do
|
|
{:ok, like, _} = SideEffects.handle(like)
|
|
object = Object.get_by_ap_id(like.data["object"])
|
|
assert object.data["like_count"] == 1
|
|
assert user.ap_id in object.data["likes"]
|
|
end
|
|
|
|
test "creates a notification", %{like: like, poster: poster} do
|
|
{:ok, like, _} = SideEffects.handle(like)
|
|
assert Repo.get_by(Notification, user_id: poster.id, activity_id: like.id)
|
|
end
|
|
end
|
|
|
|
describe "announce objects" do
|
|
setup do
|
|
poster = insert(:user)
|
|
user = insert(:user)
|
|
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
|
{:ok, private_post} = CommonAPI.post(poster, %{status: "hey", visibility: "private"})
|
|
|
|
{:ok, announce_data, _meta} = Builder.announce(user, post.object, public: true)
|
|
|
|
{:ok, private_announce_data, _meta} =
|
|
Builder.announce(user, private_post.object, public: false)
|
|
|
|
{:ok, relay_announce_data, _meta} =
|
|
Builder.announce(Pleroma.Web.ActivityPub.Relay.get_actor(), post.object, public: true)
|
|
|
|
{:ok, announce, _meta} = ActivityPub.persist(announce_data, local: true)
|
|
{:ok, private_announce, _meta} = ActivityPub.persist(private_announce_data, local: true)
|
|
{:ok, relay_announce, _meta} = ActivityPub.persist(relay_announce_data, local: true)
|
|
|
|
%{
|
|
announce: announce,
|
|
user: user,
|
|
poster: poster,
|
|
private_announce: private_announce,
|
|
relay_announce: relay_announce
|
|
}
|
|
end
|
|
|
|
test "adds the announce to the original object", %{announce: announce, user: user} do
|
|
{:ok, announce, _} = SideEffects.handle(announce)
|
|
object = Object.get_by_ap_id(announce.data["object"])
|
|
assert object.data["announcement_count"] == 1
|
|
assert user.ap_id in object.data["announcements"]
|
|
end
|
|
|
|
test "does not add the announce to the original object if the actor is a service actor", %{
|
|
relay_announce: announce
|
|
} do
|
|
{:ok, announce, _} = SideEffects.handle(announce)
|
|
object = Object.get_by_ap_id(announce.data["object"])
|
|
assert object.data["announcement_count"] == nil
|
|
end
|
|
|
|
test "creates a notification", %{announce: announce, poster: poster} do
|
|
{:ok, announce, _} = SideEffects.handle(announce)
|
|
assert Repo.get_by(Notification, user_id: poster.id, activity_id: announce.id)
|
|
end
|
|
|
|
test "it streams out the announce", %{announce: announce} do
|
|
with_mocks([
|
|
{
|
|
Pleroma.Web.Streamer,
|
|
[],
|
|
[
|
|
stream: fn _, _ -> nil end
|
|
]
|
|
},
|
|
{
|
|
Pleroma.Web.Push,
|
|
[],
|
|
[
|
|
send: fn _ -> nil end
|
|
]
|
|
}
|
|
]) do
|
|
{:ok, announce, _} = SideEffects.handle(announce)
|
|
|
|
assert called(Pleroma.Web.Streamer.stream(["user", "list"], announce))
|
|
|
|
assert called(Pleroma.Web.Push.send(:_))
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "removing a follower" do
|
|
setup do
|
|
user = insert(:user)
|
|
followed = insert(:user)
|
|
|
|
{:ok, _, _, follow_activity} = CommonAPI.follow(user, followed)
|
|
|
|
{:ok, reject_data, []} = Builder.reject(followed, follow_activity)
|
|
{:ok, reject, _meta} = ActivityPub.persist(reject_data, local: true)
|
|
|
|
%{user: user, followed: followed, reject: reject}
|
|
end
|
|
|
|
test "", %{user: user, followed: followed, reject: reject} do
|
|
assert User.following?(user, followed)
|
|
assert Pleroma.FollowingRelationship.get(user, followed)
|
|
|
|
{:ok, _, _} = SideEffects.handle(reject)
|
|
|
|
refute User.following?(user, followed)
|
|
refute Pleroma.FollowingRelationship.get(user, followed)
|
|
assert User.get_follow_state(user, followed) == nil
|
|
assert User.get_follow_state(user, followed, nil) == nil
|
|
end
|
|
end
|
|
|
|
describe "removing a follower from remote" do
|
|
setup do
|
|
user = insert(:user)
|
|
followed = insert(:user, local: false)
|
|
|
|
# Mock a local-to-remote follow
|
|
{:ok, follow_data, []} = Builder.follow(user, followed)
|
|
|
|
follow_data =
|
|
follow_data
|
|
|> Map.put("state", "accept")
|
|
|
|
{:ok, follow, _meta} = ActivityPub.persist(follow_data, local: true)
|
|
{:ok, _, _} = SideEffects.handle(follow)
|
|
|
|
# Mock a remote-to-local accept
|
|
{:ok, accept_data, _} = Builder.accept(followed, follow)
|
|
{:ok, accept, _} = ActivityPub.persist(accept_data, local: false)
|
|
{:ok, _, _} = SideEffects.handle(accept)
|
|
|
|
# Mock a remote-to-local reject
|
|
{:ok, reject_data, []} = Builder.reject(followed, follow)
|
|
{:ok, reject, _meta} = ActivityPub.persist(reject_data, local: false)
|
|
|
|
%{user: user, followed: followed, reject: reject}
|
|
end
|
|
|
|
test "", %{user: user, followed: followed, reject: reject} do
|
|
assert User.following?(user, followed)
|
|
assert Pleroma.FollowingRelationship.get(user, followed)
|
|
|
|
{:ok, _, _} = SideEffects.handle(reject)
|
|
|
|
refute User.following?(user, followed)
|
|
refute Pleroma.FollowingRelationship.get(user, followed)
|
|
|
|
assert Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, followed).data["state"] ==
|
|
"reject"
|
|
|
|
assert User.get_follow_state(user, followed) == nil
|
|
assert User.get_follow_state(user, followed, nil) == nil
|
|
end
|
|
end
|
|
end
|