Replace `user.following` with Pleroma.FollowingRelationship

This commit is contained in:
Egor Kislitsyn 2019-10-11 02:35:32 +07:00
parent 2c7ff32e5b
commit 059005ff82
No known key found for this signature in database
GPG Key ID: 1B49CB15B71E7805
28 changed files with 275 additions and 235 deletions

View File

@ -52,9 +52,9 @@ defmodule Mix.Tasks.Pleroma.Database do
def run(["update_users_following_followers_counts"]) do def run(["update_users_following_followers_counts"]) do
start_pleroma() start_pleroma()
users = Repo.all(User) User
Enum.each(users, &User.remove_duplicated_following/1) |> Repo.all()
Enum.each(users, &User.update_follower_count/1) |> Enum.each(&User.update_follower_count/1)
end end
def run(["prune_objects" | args]) do def run(["prune_objects" | args]) do

View File

@ -36,8 +36,9 @@ defmodule Mix.Tasks.Pleroma.Relay do
def run(["list"]) do def run(["list"]) do
start_pleroma() start_pleroma()
with %User{following: following} = _user <- Relay.get_actor() do with %User{} = user <- Relay.get_actor() do
following user
|> User.following()
|> Enum.map(fn entry -> URI.parse(entry).host end) |> Enum.map(fn entry -> URI.parse(entry).host end)
|> Enum.uniq() |> Enum.uniq()
|> Enum.each(&shell_info(&1)) |> Enum.each(&shell_info(&1))

View File

@ -162,7 +162,7 @@ defmodule Mix.Tasks.Pleroma.User do
user = User.get_cached_by_id(user.id) user = User.get_cached_by_id(user.id)
if Enum.empty?(user.following) do if Enum.empty?(User.get_friends(user)) do
shell_info("Successfully unsubscribed all followers from #{user.nickname}") shell_info("Successfully unsubscribed all followers from #{user.nickname}")
end end
else else

View File

@ -97,7 +97,7 @@ defmodule Pleroma.BBS.Handler do
|> Map.put("user", user) |> Map.put("user", user)
activities = activities =
[user.ap_id | user.following] [user.ap_id | Pleroma.User.following(user)]
|> ActivityPub.fetch_activities(params) |> ActivityPub.fetch_activities(params)
Enum.each(activities, fn activity -> Enum.each(activities, fn activity ->

View File

@ -0,0 +1,110 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.FollowingRelationship do
use Ecto.Schema
import Ecto.Changeset
import Ecto.Query
alias FlakeId.Ecto.CompatType
alias Pleroma.Repo
alias Pleroma.User
schema "following_relationships" do
field(:state, :string, default: "accept")
belongs_to(:follower, User, type: CompatType)
belongs_to(:following, User, type: CompatType)
timestamps()
end
def changeset(%__MODULE__{} = following_relationship, attrs) do
following_relationship
|> cast(attrs, [:state])
|> put_assoc(:follower, attrs.follower)
|> put_assoc(:following, attrs.following)
|> validate_required([:state, :follower, :following])
end
def get(%User{} = follower, %User{} = following) do
__MODULE__
|> where(follower_id: ^follower.id, following_id: ^following.id)
|> Repo.one()
end
def update(follower, following, "reject"), do: unfollow(follower, following)
def update(%User{} = follower, %User{} = following, state) do
case get(follower, following) do
nil ->
follow(follower, following, state)
following_relationship ->
following_relationship
|> cast(%{state: state}, [:state])
|> validate_required([:state])
|> Repo.update()
end
end
def follow(%User{} = follower, %User{} = following, state \\ "accept") do
%__MODULE__{}
|> changeset(%{follower: follower, following: following, state: state})
|> Repo.insert(on_conflict: :nothing)
end
def unfollow(%User{} = follower, %User{} = following) do
case get(follower, following) do
nil -> {:ok, nil}
%__MODULE__{} = following_relationship -> Repo.delete(following_relationship)
end
end
def follower_count(%User{} = user) do
%{followers: user, deactivated: false}
|> User.Query.build()
|> Repo.aggregate(:count, :id)
end
def following_count(%User{id: nil}), do: 0
def following_count(%User{} = user) do
%{friends: user, deactivated: false}
|> User.Query.build()
|> Repo.aggregate(:count, :id)
end
def get_follow_requests(%User{id: id}) do
__MODULE__
|> join(:inner, [r], f in assoc(r, :follower))
|> where([r], r.state == "pending")
|> where([r], r.following_id == ^id)
|> select([r, f], f)
|> Repo.all()
end
def following?(%User{id: follower_id}, %User{id: followed_id}) do
__MODULE__
|> where(follower_id: ^follower_id, following_id: ^followed_id, state: "accept")
|> Repo.exists?()
end
def following(%User{} = user) do
following =
__MODULE__
|> join(:inner, [r], u in User, on: r.following_id == u.id)
|> where([r], r.follower_id == ^user.id)
|> where([r], r.state == "accept")
|> select([r, u], u.follower_address)
|> Repo.all()
if user.nickname in [nil, "internal.fetch"] do
following
else
[user.follower_address | following]
end
end
end

View File

@ -13,6 +13,7 @@ defmodule Pleroma.User do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Conversation.Participation alias Pleroma.Conversation.Participation
alias Pleroma.Delivery alias Pleroma.Delivery
alias Pleroma.FollowingRelationship
alias Pleroma.Keys alias Pleroma.Keys
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
@ -52,7 +53,6 @@ defmodule Pleroma.User do
field(:password, :string, virtual: true) field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true) field(:password_confirmation, :string, virtual: true)
field(:keys, :string) field(:keys, :string)
field(:following, {:array, :string}, default: [])
field(:ap_id, :string) field(:ap_id, :string)
field(:avatar, :map) field(:avatar, :map)
field(:local, :boolean, default: true) field(:local, :boolean, default: true)
@ -162,13 +162,7 @@ defmodule Pleroma.User do
) )
end end
def following_count(%User{following: []}), do: 0 defdelegate following_count(user), to: FollowingRelationship
def following_count(%User{} = user) do
user
|> get_friends_query()
|> Repo.aggregate(:count, :id)
end
defp truncate_if_exists(params, key, max_length) do defp truncate_if_exists(params, key, max_length) do
if Map.has_key?(params, key) and is_binary(params[key]) do if Map.has_key?(params, key) and is_binary(params[key]) do
@ -216,7 +210,7 @@ defmodule Pleroma.User do
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100) name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
struct struct
|> cast(params, [:bio, :name, :avatar, :following]) |> cast(params, [:bio, :name, :avatar])
|> unique_constraint(:nickname) |> unique_constraint(:nickname)
|> validate_format(:nickname, local_nickname_regex()) |> validate_format(:nickname, local_nickname_regex())
|> validate_length(:bio, max: bio_limit) |> validate_length(:bio, max: bio_limit)
@ -324,7 +318,6 @@ defmodule Pleroma.User do
followers = ap_followers(%User{nickname: get_field(changeset, :nickname)}) followers = ap_followers(%User{nickname: get_field(changeset, :nickname)})
changeset changeset
|> put_change(:following, [followers])
|> put_change(:follower_address, followers) |> put_change(:follower_address, followers)
end end
@ -378,8 +371,11 @@ defmodule Pleroma.User do
def needs_update?(_), do: true def needs_update?(_), do: true
@spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t()} | {:error, String.t()} @spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t()} | {:error, String.t()}
def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{locked: true}}) do def maybe_direct_follow(
{:ok, follower} %User{} = follower,
%User{local: true, info: %{locked: true}} = followed
) do
follow(follower, followed, "pending")
end end
def maybe_direct_follow(%User{} = follower, %User{local: true} = followed) do def maybe_direct_follow(%User{} = follower, %User{local: true} = followed) do
@ -397,37 +393,22 @@ defmodule Pleroma.User do
@doc "A mass follow for local users. Respects blocks in both directions but does not create activities." @doc "A mass follow for local users. Respects blocks in both directions but does not create activities."
@spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()} @spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()}
def follow_all(follower, followeds) do def follow_all(follower, followeds) do
followed_addresses = followeds =
followeds Enum.reject(followeds, fn followed ->
|> Enum.reject(fn followed -> blocks?(follower, followed) || blocks?(followed, follower) end) blocks?(follower, followed) || blocks?(followed, follower)
|> Enum.map(fn %{follower_address: fa} -> fa end) end)
q = Enum.each(followeds, &follow(follower, &1, "accept"))
from(u in User,
where: u.id == ^follower.id,
update: [
set: [
following:
fragment(
"array(select distinct unnest (array_cat(?, ?)))",
u.following,
^followed_addresses
)
]
],
select: u
)
{1, [follower]} = Repo.update_all(q, [])
Enum.each(followeds, &update_follower_count/1) Enum.each(followeds, &update_follower_count/1)
set_cache(follower) set_cache(follower)
end end
def follow(%User{} = follower, %User{info: info} = followed) do defdelegate following(user), to: FollowingRelationship
def follow(%User{} = follower, %User{info: info} = followed, state \\ "accept") do
deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked]) deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked])
ap_followers = followed.follower_address
cond do cond do
info.deactivated -> info.deactivated ->
@ -441,14 +422,7 @@ defmodule Pleroma.User do
Websub.subscribe(follower, followed) Websub.subscribe(follower, followed)
end end
q = FollowingRelationship.follow(follower, followed, state)
from(u in User,
where: u.id == ^follower.id,
update: [push: [following: ^ap_followers]],
select: u
)
{1, [follower]} = Repo.update_all(q, [])
follower = maybe_update_following_count(follower) follower = maybe_update_following_count(follower)
@ -459,17 +433,8 @@ defmodule Pleroma.User do
end end
def unfollow(%User{} = follower, %User{} = followed) do def unfollow(%User{} = follower, %User{} = followed) do
ap_followers = followed.follower_address
if following?(follower, followed) and follower.ap_id != followed.ap_id do if following?(follower, followed) and follower.ap_id != followed.ap_id do
q = FollowingRelationship.unfollow(follower, followed)
from(u in User,
where: u.id == ^follower.id,
update: [pull: [following: ^ap_followers]],
select: u
)
{1, [follower]} = Repo.update_all(q, [])
follower = maybe_update_following_count(follower) follower = maybe_update_following_count(follower)
@ -483,10 +448,7 @@ defmodule Pleroma.User do
end end
end end
@spec following?(User.t(), User.t()) :: boolean defdelegate following?(follower, followed), to: FollowingRelationship
def following?(%User{} = follower, %User{} = followed) do
Enum.member?(follower.following, followed.follower_address)
end
def locked?(%User{} = user) do def locked?(%User{} = user) do
user.info.locked || false user.info.locked || false
@ -707,16 +669,7 @@ defmodule Pleroma.User do
|> Repo.all() |> Repo.all()
end end
@spec get_follow_requests(User.t()) :: {:ok, [User.t()]} defdelegate get_follow_requests(user), to: FollowingRelationship
def get_follow_requests(%User{} = user) do
user
|> Activity.follow_requests_for_actor()
|> join(:inner, [a], u in User, on: a.actor == u.ap_id)
|> where([a, u], not fragment("? @> ?", u.following, ^[user.follower_address]))
|> group_by([a, u], u.id)
|> select([a, u], u)
|> Repo.all()
end
def increase_note_count(%User{} = user) do def increase_note_count(%User{} = user) do
User User
@ -899,18 +852,6 @@ defmodule Pleroma.User do
def increment_unread_conversation_count(_, _), do: :noop def increment_unread_conversation_count(_, _), do: :noop
def remove_duplicated_following(%User{following: following} = user) do
uniq_following = Enum.uniq(following)
if length(following) == length(uniq_following) do
{:ok, user}
else
user
|> update_changeset(%{following: uniq_following})
|> update_and_set_cache()
end
end
@spec get_users_from_set([String.t()], boolean()) :: [User.t()] @spec get_users_from_set([String.t()], boolean()) :: [User.t()]
def get_users_from_set(ap_ids, local_only \\ true) do def get_users_from_set(ap_ids, local_only \\ true) do
criteria = %{ap_id: ap_ids, deactivated: false} criteria = %{ap_id: ap_ids, deactivated: false}

View File

@ -28,6 +28,8 @@ defmodule Pleroma.User.Query do
""" """
import Ecto.Query import Ecto.Query
import Pleroma.Web.AdminAPI.Search, only: [not_empty_string: 1] import Pleroma.Web.AdminAPI.Search, only: [not_empty_string: 1]
alias Pleroma.FollowingRelationship
alias Pleroma.User alias Pleroma.User
@type criteria :: @type criteria ::
@ -130,18 +132,40 @@ defmodule Pleroma.User.Query do
|> where([u], not is_nil(u.nickname)) |> where([u], not is_nil(u.nickname))
end end
defp compose_query({:followers, %User{id: id, follower_address: follower_address}}, query) do defp compose_query({:followers, %User{id: id}}, query) do
where(query, [u], fragment("? <@ ?", ^[follower_address], u.following)) query
|> where([u], u.id != ^id) |> where([u], u.id != ^id)
|> join(:inner, [u], r in FollowingRelationship,
as: :relationships,
on: r.following_id == ^id and r.follower_id == u.id
)
|> where([relationships: r], r.state == "accept")
end end
defp compose_query({:friends, %User{id: id, following: following}}, query) do defp compose_query({:friends, %User{id: id}}, query) do
where(query, [u], u.follower_address in ^following) query
|> where([u], u.id != ^id) |> where([u], u.id != ^id)
|> join(:inner, [u], r in FollowingRelationship,
as: :relationships,
on: r.following_id == u.id and r.follower_id == ^id
)
|> where([relationships: r], r.state == "accept")
end end
defp compose_query({:recipients_from_activity, to}, query) do defp compose_query({:recipients_from_activity, to}, query) do
where(query, [u], u.ap_id in ^to or fragment("? && ?", u.following, ^to)) query
|> join(:left, [u], r in FollowingRelationship,
as: :relationships,
on: r.follower_id == u.id
)
|> join(:left, [relationships: r], f in User,
as: :following,
on: f.id == r.following_id
)
|> where(
[u, following: f, relationships: r],
u.ap_id in ^to or (f.follower_address in ^to and r.state == "accept")
)
end end
defp compose_query({:order_by, key}, query) do defp compose_query({:order_by, key}, query) do

View File

@ -501,7 +501,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
public = [Pleroma.Constants.as_public()] public = [Pleroma.Constants.as_public()]
recipients = recipients =
if opts["user"], do: [opts["user"].ap_id | opts["user"].following] ++ public, else: public if opts["user"],
do: [opts["user"].ap_id | User.following(opts["user"])] ++ public,
else: public
from(activity in Activity) from(activity in Activity)
|> maybe_preload_objects(opts) |> maybe_preload_objects(opts)
@ -652,7 +654,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp user_activities_recipients(%{"reading_user" => reading_user}) do defp user_activities_recipients(%{"reading_user" => reading_user}) do
if reading_user do if reading_user do
[Pleroma.Constants.as_public()] ++ [reading_user.ap_id | reading_user.following] [Pleroma.Constants.as_public()] ++ [reading_user.ap_id | User.following(reading_user)]
else else
[Pleroma.Constants.as_public()] [Pleroma.Constants.as_public()]
end end

View File

@ -319,12 +319,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
when page? in [true, "true"] do when page? in [true, "true"] do
activities = activities =
if params["max_id"] do if params["max_id"] do
ActivityPub.fetch_activities([user.ap_id | user.following], %{ ActivityPub.fetch_activities([user.ap_id | User.following(user)], %{
"max_id" => params["max_id"], "max_id" => params["max_id"],
"limit" => 10 "limit" => 10
}) })
else else
ActivityPub.fetch_activities([user.ap_id | user.following], %{"limit" => 10}) ActivityPub.fetch_activities([user.ap_id | User.following(user)], %{"limit" => 10})
end end
conn conn

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
A module to handle coding from internal to wire ActivityPub and back. A module to handle coding from internal to wire ActivityPub and back.
""" """
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.FollowingRelationship
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Object.Containment alias Pleroma.Object.Containment
alias Pleroma.Repo alias Pleroma.Repo
@ -474,7 +475,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{_, false} <- {:user_locked, User.locked?(followed)}, {_, false} <- {:user_locked, User.locked?(followed)},
{_, {:ok, follower}} <- {:follow, User.follow(follower, followed)}, {_, {:ok, follower}} <- {:follow, User.follow(follower, followed)},
{_, {:ok, _}} <- {_, {:ok, _}} <-
{:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")} do {:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")},
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do
ActivityPub.accept(%{ ActivityPub.accept(%{
to: [follower.ap_id], to: [follower.ap_id],
actor: followed, actor: followed,
@ -484,6 +486,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
else else
{:user_blocked, true} -> {:user_blocked, true} ->
{:ok, _} = Utils.update_follow_state_for_all(activity, "reject") {:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
{:ok, _relationship} = FollowingRelationship.update(follower, followed, "reject")
ActivityPub.reject(%{ ActivityPub.reject(%{
to: [follower.ap_id], to: [follower.ap_id],
@ -494,6 +497,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:follow, {:error, _}} -> {:follow, {:error, _}} ->
{:ok, _} = Utils.update_follow_state_for_all(activity, "reject") {:ok, _} = Utils.update_follow_state_for_all(activity, "reject")
{:ok, _relationship} = FollowingRelationship.update(follower, followed, "reject")
ActivityPub.reject(%{ ActivityPub.reject(%{
to: [follower.ap_id], to: [follower.ap_id],
@ -522,7 +526,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, follow_activity} <- get_follow_activity(follow_object, followed), {:ok, follow_activity} <- get_follow_activity(follow_object, followed),
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]), %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
{:ok, _follower} = User.follow(follower, followed) do {:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do
ActivityPub.accept(%{ ActivityPub.accept(%{
to: follow_activity.data["to"], to: follow_activity.data["to"],
type: "Accept", type: "Accept",
@ -544,6 +548,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
{:ok, follow_activity} <- get_follow_activity(follow_object, followed), {:ok, follow_activity} <- get_follow_activity(follow_object, followed),
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"),
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]), %User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, "reject"),
{:ok, activity} <- {:ok, activity} <-
ActivityPub.reject(%{ ActivityPub.reject(%{
to: follow_activity.data["to"], to: follow_activity.data["to"],
@ -552,8 +557,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
object: follow_activity.data["id"], object: follow_activity.data["id"],
local: false local: false
}) do }) do
User.unfollow(follower, followed)
{:ok, activity} {:ok, activity}
else else
_e -> :error _e -> :error
@ -1050,46 +1053,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def perform(:user_upgrade, user) do def perform(:user_upgrade, user) do
# we pass a fake user so that the followers collection is stripped away # we pass a fake user so that the followers collection is stripped away
old_follower_address = User.ap_followers(%User{nickname: user.nickname}) old_follower_address = User.ap_followers(%User{nickname: user.nickname})
q =
from(
u in User,
where: ^old_follower_address in u.following,
update: [
set: [
following:
fragment(
"array_replace(?,?,?)",
u.following,
^old_follower_address,
^user.follower_address
)
]
]
)
Repo.update_all(q, [])
maybe_retire_websub(user.ap_id) maybe_retire_websub(user.ap_id)
q = from(
from( a in Activity,
a in Activity, where: ^old_follower_address in a.recipients,
where: ^old_follower_address in a.recipients, update: [
update: [ set: [
set: [ recipients:
recipients: fragment(
fragment( "array_replace(?,?,?)",
"array_replace(?,?,?)", a.recipients,
a.recipients, ^old_follower_address,
^old_follower_address, ^user.follower_address
^user.follower_address )
)
]
] ]
) ]
)
Repo.update_all(q, []) |> Repo.update_all([])
end end
def upgrade_user_from_ap_id(ap_id) do def upgrade_user_from_ap_id(ap_id) do

View File

@ -58,7 +58,7 @@ defmodule Pleroma.Web.ActivityPub.Visibility do
end end
def visible_for_user?(activity, user) do def visible_for_user?(activity, user) do
x = [user.ap_id | user.following] x = [user.ap_id | User.following(user)]
y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || []) y = [activity.actor] ++ activity.data["to"] ++ (activity.data["cc"] || [])
visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y)) visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y))
end end

View File

@ -6,6 +6,7 @@ defmodule Pleroma.Web.CommonAPI do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.ActivityExpiration alias Pleroma.ActivityExpiration
alias Pleroma.Conversation.Participation alias Pleroma.Conversation.Participation
alias Pleroma.FollowingRelationship
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.ThreadMute alias Pleroma.ThreadMute
alias Pleroma.User alias Pleroma.User
@ -40,6 +41,7 @@ defmodule Pleroma.Web.CommonAPI do
with {:ok, follower} <- User.follow(follower, followed), with {:ok, follower} <- User.follow(follower, followed),
%Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept"),
{:ok, _activity} <- {:ok, _activity} <-
ActivityPub.accept(%{ ActivityPub.accept(%{
to: [follower.ap_id], to: [follower.ap_id],
@ -54,6 +56,7 @@ defmodule Pleroma.Web.CommonAPI do
def reject_follow_request(follower, followed) do def reject_follow_request(follower, followed) do
with %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), with %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed),
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"), {:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "reject"),
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, "reject"),
{:ok, _activity} <- {:ok, _activity} <-
ActivityPub.reject(%{ ActivityPub.reject(%{
to: [follower.ap_id], to: [follower.ap_id],

View File

@ -10,6 +10,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
alias Pleroma.Pagination alias Pleroma.Pagination
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct]) plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
@ -28,7 +29,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put("muting_user", user) |> Map.put("muting_user", user)
|> Map.put("user", user) |> Map.put("user", user)
recipients = [user.ap_id | user.following] recipients = [user.ap_id | User.following(user)]
activities = activities =
recipients recipients
@ -128,9 +129,12 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
# we must filter the following list for the user to avoid leaking statuses the user # we must filter the following list for the user to avoid leaking statuses the user
# does not actually have permission to see (for more info, peruse security issue #270). # does not actually have permission to see (for more info, peruse security issue #270).
user_following = User.following(user)
activities = activities =
following following
|> Enum.filter(fn x -> x in user.following end) |> Enum.filter(fn x -> x in user_following end)
|> ActivityPub.fetch_activities_bounded(following, params) |> ActivityPub.fetch_activities_bounded(following, params)
|> Enum.reverse() |> Enum.reverse()

View File

@ -132,7 +132,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
recipients = recipients =
if for_user do if for_user do
[Pleroma.Constants.as_public()] ++ [for_user.ap_id | for_user.following] [Pleroma.Constants.as_public()] ++ [for_user.ap_id | User.following(for_user)]
else else
[Pleroma.Constants.as_public()] [Pleroma.Constants.as_public()]
end end

View File

@ -16,7 +16,7 @@ defmodule Pleroma.Repo.Migrations.CreateFollowingRelationships do
execute(update_thread_visibility(), restore_thread_visibility()) execute(update_thread_visibility(), restore_thread_visibility())
end end
# The only difference with the original verion: `actor_user` replaced with `actor_user_following` # The only difference between the original version: `actor_user` replaced with `actor_user_following`
def update_thread_visibility do def update_thread_visibility do
""" """
CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar) RETURNS boolean AS $$ CREATE OR REPLACE FUNCTION thread_visibility(actor varchar, activity_id varchar) RETURNS boolean AS $$

View File

@ -39,8 +39,7 @@ defmodule Pleroma.Factory do
user user
| ap_id: User.ap_id(user), | ap_id: User.ap_id(user),
follower_address: User.ap_followers(user), follower_address: User.ap_followers(user),
following_address: User.ap_following(user), following_address: User.ap_following(user)
following: [User.ap_id(user)]
} }
end end

View File

@ -72,25 +72,25 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
describe "running update_users_following_followers_counts" do describe "running update_users_following_followers_counts" do
test "following and followers count are updated" do test "following and followers count are updated" do
[user, user2] = insert_pair(:user) [user, user2] = insert_pair(:user)
{:ok, %User{following: following, info: info} = user} = User.follow(user, user2) {:ok, %User{info: info} = user} = User.follow(user, user2)
following = User.following(user)
assert length(following) == 2 assert length(following) == 2
assert info.follower_count == 0 assert info.follower_count == 0
{:ok, user} = {:ok, user} =
user user
|> Ecto.Changeset.change(%{following: following ++ following})
|> User.change_info(&Ecto.Changeset.change(&1, %{follower_count: 3})) |> User.change_info(&Ecto.Changeset.change(&1, %{follower_count: 3}))
|> Repo.update() |> Repo.update()
assert length(user.following) == 4
assert user.info.follower_count == 3 assert user.info.follower_count == 3
assert :ok == Mix.Tasks.Pleroma.Database.run(["update_users_following_followers_counts"]) assert :ok == Mix.Tasks.Pleroma.Database.run(["update_users_following_followers_counts"])
user = User.get_by_id(user.id) user = User.get_by_id(user.id)
assert length(user.following) == 2 assert length(User.following(user)) == 2
assert user.info.follower_count == 0 assert user.info.follower_count == 0
end end
end end

View File

@ -51,7 +51,7 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
target_user = User.get_cached_by_ap_id(target_instance) target_user = User.get_cached_by_ap_id(target_instance)
follow_activity = Utils.fetch_latest_follow(local_user, target_user) follow_activity = Utils.fetch_latest_follow(local_user, target_user)
User.follow(local_user, target_user) User.follow(local_user, target_user)
assert "#{target_instance}/followers" in refresh_record(local_user).following assert "#{target_instance}/followers" in User.following(local_user)
Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance]) Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance])
cancelled_activity = Activity.get_by_ap_id(follow_activity.data["id"]) cancelled_activity = Activity.get_by_ap_id(follow_activity.data["id"])
@ -68,7 +68,7 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
assert undo_activity.data["type"] == "Undo" assert undo_activity.data["type"] == "Undo"
assert undo_activity.data["actor"] == local_user.ap_id assert undo_activity.data["actor"] == local_user.ap_id
assert undo_activity.data["object"] == cancelled_activity.data assert undo_activity.data["object"] == cancelled_activity.data
refute "#{target_instance}/followers" in refresh_record(local_user).following refute "#{target_instance}/followers" in User.following(local_user)
end end
end end
@ -78,20 +78,18 @@ defmodule Mix.Tasks.Pleroma.RelayTest do
refute_receive {:mix_shell, :info, _} refute_receive {:mix_shell, :info, _}
Pleroma.Web.ActivityPub.Relay.get_actor() relay_user = Relay.get_actor()
|> Ecto.Changeset.change(
following: [ ["http://mastodon.example.org/users/admin", "https://mstdn.io/users/mayuutann"]
"http://test-app.com/user/test1", |> Enum.each(fn ap_id ->
"http://test-app.com/user/test1", {:ok, user} = User.get_or_fetch_by_ap_id(ap_id)
"http://test-app-42.com/user/test1" User.follow(relay_user, user)
] end)
)
|> Pleroma.User.update_and_set_cache()
:ok = Mix.Tasks.Pleroma.Relay.run(["list"]) :ok = Mix.Tasks.Pleroma.Relay.run(["list"])
assert_receive {:mix_shell, :info, ["test-app.com"]} assert_receive {:mix_shell, :info, ["mstdn.io"]}
assert_receive {:mix_shell, :info, ["test-app-42.com"]} assert_receive {:mix_shell, :info, ["mastodon.example.org"]}
end end
end end
end end

View File

@ -139,7 +139,8 @@ defmodule Mix.Tasks.Pleroma.UserTest do
describe "running unsubscribe" do describe "running unsubscribe" do
test "user is unsubscribed" do test "user is unsubscribed" do
followed = insert(:user) followed = insert(:user)
user = insert(:user, %{following: [User.ap_followers(followed)]}) user = insert(:user)
User.follow(user, followed, "accept")
Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname]) Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname])
@ -154,7 +155,7 @@ defmodule Mix.Tasks.Pleroma.UserTest do
assert message =~ "Successfully unsubscribed" assert message =~ "Successfully unsubscribed"
user = User.get_cached_by_nickname(user.nickname) user = User.get_cached_by_nickname(user.nickname)
assert Enum.empty?(user.following) assert Enum.empty?(User.get_friends(user))
assert user.info.deactivated assert user.info.deactivated
end end

View File

@ -88,10 +88,9 @@ defmodule Pleroma.UserTest do
CommonAPI.follow(pending_follower, locked) CommonAPI.follow(pending_follower, locked)
CommonAPI.follow(pending_follower, locked) CommonAPI.follow(pending_follower, locked)
CommonAPI.follow(accepted_follower, locked) CommonAPI.follow(accepted_follower, locked)
User.follow(accepted_follower, locked) Pleroma.FollowingRelationship.update(accepted_follower, locked, "accept")
assert [activity] = User.get_follow_requests(locked) assert [^pending_follower] = User.get_follow_requests(locked)
assert activity
end end
test "clears follow requests when requester is blocked" do test "clears follow requests when requester is blocked" do
@ -136,10 +135,10 @@ defmodule Pleroma.UserTest do
followed_two = insert(:user) followed_two = insert(:user)
{:ok, user} = User.follow_all(user, [followed_zero, followed_one]) {:ok, user} = User.follow_all(user, [followed_zero, followed_one])
assert length(user.following) == 3 assert length(User.following(user)) == 3
{:ok, user} = User.follow_all(user, [followed_one, followed_two]) {:ok, user} = User.follow_all(user, [followed_one, followed_two])
assert length(user.following) == 4 assert length(User.following(user)) == 4
end end
test "follow takes a user and another user" do test "follow takes a user and another user" do
@ -153,7 +152,7 @@ defmodule Pleroma.UserTest do
followed = User.get_cached_by_ap_id(followed.ap_id) followed = User.get_cached_by_ap_id(followed.ap_id)
assert followed.info.follower_count == 1 assert followed.info.follower_count == 1
assert User.ap_followers(followed) in user.following assert User.ap_followers(followed) in User.following(user)
end end
test "can't follow a deactivated users" do test "can't follow a deactivated users" do
@ -198,7 +197,7 @@ defmodule Pleroma.UserTest do
# assert followed.local == false # assert followed.local == false
# {:ok, user} = User.follow(user, followed) # {:ok, user} = User.follow(user, followed)
# assert User.ap_followers(followed) in user.following # assert User.ap_followers(followed) in User.following(user)
# query = from w in WebsubClientSubscription, # query = from w in WebsubClientSubscription,
# where: w.topic == ^followed.info["topic"] # where: w.topic == ^followed.info["topic"]
@ -235,26 +234,29 @@ defmodule Pleroma.UserTest do
nickname: "fuser2", nickname: "fuser2",
ap_id: "http://localhost:4001/users/fuser2", ap_id: "http://localhost:4001/users/fuser2",
follower_address: "http://localhost:4001/users/fuser2/followers", follower_address: "http://localhost:4001/users/fuser2/followers",
following_address: "http://localhost:4001/users/fuser2/following", following_address: "http://localhost:4001/users/fuser2/following"
following: [User.ap_followers(followed)]
}) })
{:ok, user} = User.follow(user, followed, "accept")
{:ok, user, _activity} = User.unfollow(user, followed) {:ok, user, _activity} = User.unfollow(user, followed)
user = User.get_cached_by_id(user.id) user = User.get_cached_by_id(user.id)
assert user.following == [] assert User.following(user) == [user.follower_address]
end end
test "unfollow takes a user and another user" do test "unfollow takes a user and another user" do
followed = insert(:user) followed = insert(:user)
user = insert(:user, %{following: [User.ap_followers(followed)]}) user = insert(:user)
{:ok, user} = User.follow(user, followed, "accept")
assert User.following(user) == [user.follower_address, followed.follower_address]
{:ok, user, _activity} = User.unfollow(user, followed) {:ok, user, _activity} = User.unfollow(user, followed)
user = User.get_cached_by_id(user.id) assert User.following(user) == [user.follower_address]
assert user.following == []
end end
test "unfollow doesn't unfollow yourself" do test "unfollow doesn't unfollow yourself" do
@ -262,14 +264,14 @@ defmodule Pleroma.UserTest do
{:error, _} = User.unfollow(user, user) {:error, _} = User.unfollow(user, user)
user = User.get_cached_by_id(user.id) assert User.following(user) == [user.follower_address]
assert user.following == [user.ap_id]
end end
end end
test "test if a user is following another user" do test "test if a user is following another user" do
followed = insert(:user) followed = insert(:user)
user = insert(:user, %{following: [User.ap_followers(followed)]}) user = insert(:user)
User.follow(user, followed, "accept")
assert User.following?(user, followed) assert User.following?(user, followed)
refute User.following?(followed, user) refute User.following?(followed, user)
@ -352,7 +354,7 @@ defmodule Pleroma.UserTest do
refute changeset.valid? refute changeset.valid?
end end
test "it sets the password_hash, ap_id and following fields" do test "it sets the password_hash and ap_id" do
changeset = User.register_changeset(%User{}, @full_user_data) changeset = User.register_changeset(%User{}, @full_user_data)
assert changeset.valid? assert changeset.valid?
@ -360,10 +362,6 @@ defmodule Pleroma.UserTest do
assert is_binary(changeset.changes[:password_hash]) assert is_binary(changeset.changes[:password_hash])
assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname}) assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
assert changeset.changes[:following] == [
User.ap_followers(%User{nickname: @full_user_data.nickname})
]
assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers" assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
end end
@ -671,37 +669,6 @@ defmodule Pleroma.UserTest do
end end
end end
describe "remove duplicates from following list" do
test "it removes duplicates" do
user = insert(:user)
follower = insert(:user)
{:ok, %User{following: following} = follower} = User.follow(follower, user)
assert length(following) == 2
{:ok, follower} =
follower
|> User.update_changeset(%{following: following ++ following})
|> Repo.update()
assert length(follower.following) == 4
{:ok, follower} = User.remove_duplicated_following(follower)
assert length(follower.following) == 2
end
test "it does nothing when following is uniq" do
user = insert(:user)
follower = insert(:user)
{:ok, follower} = User.follow(follower, user)
assert length(follower.following) == 2
{:ok, follower} = User.remove_duplicated_following(follower)
assert length(follower.following) == 2
end
end
describe "follow_import" do describe "follow_import" do
test "it imports user followings from list" do test "it imports user followings from list" do
[user1, user2, user3] = insert_list(3, :user) [user1, user2, user3] = insert_list(3, :user)
@ -1010,7 +977,9 @@ defmodule Pleroma.UserTest do
assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark) assert [activity] == ActivityPub.fetch_public_activities(%{}) |> Repo.preload(:bookmark)
assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] == assert [%{activity | thread_muted?: CommonAPI.thread_muted?(user2, activity)}] ==
ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2}) ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
"user" => user2
})
{:ok, _user} = User.deactivate(user) {:ok, _user} = User.deactivate(user)
@ -1018,7 +987,9 @@ defmodule Pleroma.UserTest do
assert [] == Pleroma.Notification.for_user(user2) assert [] == Pleroma.Notification.for_user(user2)
assert [] == assert [] ==
ActivityPub.fetch_activities([user2.ap_id | user2.following], %{"user" => user2}) ActivityPub.fetch_activities([user2.ap_id | User.following(user2)], %{
"user" => user2
})
end end
end end

View File

@ -606,7 +606,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, announce, _object} = CommonAPI.repeat(activity_three.id, booster) {:ok, announce, _object} = CommonAPI.repeat(activity_three.id, booster)
[announce_activity] = ActivityPub.fetch_activities([user.ap_id | user.following]) [announce_activity] = ActivityPub.fetch_activities([user.ap_id | User.following(user)])
assert announce_activity.id == announce.id assert announce_activity.id == announce.id
end end
@ -1132,7 +1132,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
}) })
activities = activities =
ActivityPub.fetch_activities([user1.ap_id | user1.following]) ActivityPub.fetch_activities([user1.ap_id | User.following(user1)])
|> Enum.map(fn a -> a.id end) |> Enum.map(fn a -> a.id end)
private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"]) private_activity_1 = Activity.get_by_ap_id_with_object(private_activity_1.data["id"])
@ -1142,7 +1142,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert length(activities) == 3 assert length(activities) == 3
activities = activities =
ActivityPub.fetch_activities([user1.ap_id | user1.following], %{"user" => user1}) ActivityPub.fetch_activities([user1.ap_id | User.following(user1)], %{"user" => user1})
|> Enum.map(fn a -> a.id end) |> Enum.map(fn a -> a.id end)
assert [public_activity.id, private_activity_1.id] == activities assert [public_activity.id, private_activity_1.id] == activities

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Relay
@ -50,14 +51,14 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do
service_actor = Relay.get_actor() service_actor = Relay.get_actor()
ActivityPub.follow(service_actor, user) ActivityPub.follow(service_actor, user)
Pleroma.User.follow(service_actor, user) Pleroma.User.follow(service_actor, user)
assert "#{user.ap_id}/followers" in refresh_record(service_actor).following assert "#{user.ap_id}/followers" in User.following(service_actor)
assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id) assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id)
assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay" assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay"
assert user.ap_id in activity.recipients assert user.ap_id in activity.recipients
assert activity.data["type"] == "Undo" assert activity.data["type"] == "Undo"
assert activity.data["actor"] == service_actor.ap_id assert activity.data["actor"] == service_actor.ap_id
assert activity.data["to"] == [user.ap_id] assert activity.data["to"] == [user.ap_id]
refute "#{user.ap_id}/followers" in refresh_record(service_actor).following refute "#{user.ap_id}/followers" in User.following(service_actor)
end end
end end

View File

@ -1312,7 +1312,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"}) follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
}) })
user_two = insert(:user, %{following: [user.follower_address]}) user_two = insert(:user)
Pleroma.FollowingRelationship.follow(user_two, user, "accept")
{:ok, activity} = CommonAPI.post(user, %{"status" => "test"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "test"})
{:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"}) {:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"})
@ -1359,8 +1360,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
refute user.follower_address in unrelated_activity.recipients refute user.follower_address in unrelated_activity.recipients
user_two = User.get_cached_by_id(user_two.id) user_two = User.get_cached_by_id(user_two.id)
assert user.follower_address in user_two.following assert User.following?(user_two, user)
refute "..." in user_two.following refute "..." in User.following(user_two)
end end
end end

View File

@ -212,7 +212,8 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do
test "returns true if user following to author" do test "returns true if user following to author" do
author = insert(:user) author = insert(:user)
user = insert(:user, following: [author.ap_id]) user = insert(:user)
Pleroma.User.follow(user, author)
activity = activity =
insert(:note_activity, insert(:note_activity,

View File

@ -457,7 +457,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
conn = conn =
build_conn() build_conn()
|> assign(:user, follower) |> assign(:user, User.get_cached_by_id(follower.id))
|> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true") |> post("/api/v1/accounts/#{followed.id}/follow?reblogs=true")
assert %{"showing_reblogs" => true} = json_response(conn, 200) assert %{"showing_reblogs" => true} = json_response(conn, 200)

View File

@ -16,9 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
other_user = insert(:user) other_user = insert(:user)
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
{:ok, other_user} = User.follow(other_user, user, "pending")
user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false
@ -36,6 +34,7 @@ defmodule Pleroma.Web.MastodonAPI.FollowRequestControllerTest do
other_user = insert(:user) other_user = insert(:user)
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
{:ok, other_user} = User.follow(other_user, user, "pending")
user = User.get_cached_by_id(user.id) user = User.get_cached_by_id(user.id)
other_user = User.get_cached_by_id(other_user.id) other_user = User.get_cached_by_id(other_user.id)

View File

@ -169,7 +169,8 @@ defmodule Pleroma.Web.StreamerTest do
test "it doesn't send to user if recipients invalid and thread containment is enabled" do test "it doesn't send to user if recipients invalid and thread containment is enabled" do
Pleroma.Config.put([:instance, :skip_thread_containment], false) Pleroma.Config.put([:instance, :skip_thread_containment], false)
author = insert(:user) author = insert(:user)
user = insert(:user, following: [author.ap_id]) user = insert(:user)
User.follow(user, author, "accept")
activity = activity =
insert(:note_activity, insert(:note_activity,
@ -191,7 +192,8 @@ defmodule Pleroma.Web.StreamerTest do
test "it sends message if recipients invalid and thread containment is disabled" do test "it sends message if recipients invalid and thread containment is disabled" do
Pleroma.Config.put([:instance, :skip_thread_containment], true) Pleroma.Config.put([:instance, :skip_thread_containment], true)
author = insert(:user) author = insert(:user)
user = insert(:user, following: [author.ap_id]) user = insert(:user)
User.follow(user, author, "accept")
activity = activity =
insert(:note_activity, insert(:note_activity,
@ -213,7 +215,8 @@ defmodule Pleroma.Web.StreamerTest do
test "it sends message if recipients invalid and thread containment is enabled but user's thread containment is disabled" do test "it sends message if recipients invalid and thread containment is enabled but user's thread containment is disabled" do
Pleroma.Config.put([:instance, :skip_thread_containment], false) Pleroma.Config.put([:instance, :skip_thread_containment], false)
author = insert(:user) author = insert(:user)
user = insert(:user, following: [author.ap_id], info: %{skip_thread_containment: true}) user = insert(:user, info: %{skip_thread_containment: true})
User.follow(user, author, "accept")
activity = activity =
insert(:note_activity, insert(:note_activity,

View File

@ -366,7 +366,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|> response(200) |> response(200)
assert response =~ "Account followed!" assert response =~ "Account followed!"
assert user2.follower_address in refresh_record(user).following assert user2.follower_address in User.following(user)
end end
test "returns error when user is deactivated", %{conn: conn} do test "returns error when user is deactivated", %{conn: conn} do
@ -438,7 +438,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|> response(200) |> response(200)
assert response =~ "Account followed!" assert response =~ "Account followed!"
assert user2.follower_address in refresh_record(user).following assert user2.follower_address in User.following(user)
end end
test "returns error when followee not found", %{conn: conn} do test "returns error when followee not found", %{conn: conn} do