# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
alias Pleroma.Web.ActivityPub.SideEffects
alias Pleroma.Web.CommonAPI
- import ExUnit.CaptureLog
import Mock
import Pleroma.Factory
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,
end
end
- describe "delete objects" do
- setup do
- user = insert(:user)
- other_user = insert(:user)
-
- {:ok, op} = CommonAPI.post(other_user, %{status: "big oof"})
- {:ok, post} = CommonAPI.post(user, %{status: "hey", in_reply_to_id: op})
- {:ok, favorite} = CommonAPI.favorite(user, post.id)
- object = Object.normalize(post)
- {:ok, delete_data, _meta} = Builder.delete(user, object.data["id"])
- {:ok, delete_user_data, _meta} = Builder.delete(user, user.ap_id)
- {:ok, delete, _meta} = ActivityPub.persist(delete_data, local: true)
- {:ok, delete_user, _meta} = ActivityPub.persist(delete_user_data, local: true)
-
- %{
- user: user,
- delete: delete,
- post: post,
- object: object,
- delete_user: delete_user,
- op: op,
- favorite: favorite
- }
- end
-
- test "it handles object deletions", %{
- delete: delete,
- post: post,
- object: object,
- user: user,
- op: op,
- favorite: favorite
- } do
- with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
- stream_out: fn _ -> nil end,
- stream_out_participations: fn _, _ -> nil end do
- {:ok, delete, _} = SideEffects.handle(delete)
- user = User.get_cached_by_ap_id(object.data["actor"])
-
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
- end
-
- object = Object.get_by_id(object.id)
- assert object.data["type"] == "Tombstone"
- refute Activity.get_by_id(post.id)
- refute Activity.get_by_id(favorite.id)
-
- user = User.get_by_id(user.id)
- assert user.note_count == 0
-
- object = Object.normalize(op.data["object"], false)
-
- assert object.data["repliesCount"] == 0
- end
-
- test "it handles object deletions when the object itself has been pruned", %{
- delete: delete,
- post: post,
- object: object,
- user: user,
- op: op
- } do
- with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough],
- stream_out: fn _ -> nil end,
- stream_out_participations: fn _, _ -> nil end do
- {:ok, delete, _} = SideEffects.handle(delete)
- user = User.get_cached_by_ap_id(object.data["actor"])
-
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(delete))
- assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out_participations(object, user))
- end
-
- object = Object.get_by_id(object.id)
- assert object.data["type"] == "Tombstone"
- refute Activity.get_by_id(post.id)
-
- user = User.get_by_id(user.id)
- assert user.note_count == 0
-
- object = Object.normalize(op.data["object"], false)
-
- assert object.data["repliesCount"] == 0
- end
-
- test "it handles user deletions", %{delete_user: delete, user: user} do
- {:ok, _delete, _} = SideEffects.handle(delete)
- ObanHelpers.perform_all()
-
- assert User.get_cached_by_ap_id(user.ap_id).deactivated
- end
-
- test "it logs issues with objects deletion", %{
- delete: delete,
- object: object
- } do
- {:ok, object} =
- object
- |> Object.change(%{data: Map.delete(object.data, "actor")})
- |> Repo.update()
-
- Object.invalid_object_cache(object)
-
- assert capture_log(fn ->
- {:error, :no_object_actor} = SideEffects.handle(delete)
- end) =~ "object doesn't have an actor"
- end
- end
-
describe "EmojiReact objects" do
setup do
poster = insert(:user)
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)
+
+ assert_enqueued(
+ worker: Pleroma.Workers.PollWorker,
+ args: %{op: "poll_end", activity_id: activity.id},
+ scheduled_at: NaiveDateTime.from_iso8601!(meta[:object_data]["closed"])
+ )
+ end
+ end
+
describe "delete users with confirmation pending" do
setup do
- user = insert(:user, confirmation_pending: true)
+ 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 not required", %{delete: delete, user: user} do
- clear_config([:instance, :account_activation_required], false)
- {:ok, _, _} = SideEffects.handle(delete)
- ObanHelpers.perform_all()
-
- assert User.get_cached_by_id(user.id).deactivated
- end
-
test "when activation is required", %{delete: delete, user: user} do
clear_config([:instance, :account_activation_required], true)
{:ok, _, _} = SideEffects.handle(delete)
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