FollowingRelationship storage & performance optimizations (state turned `ecto_enum`-driven integer, reorganized indices etc.).
This commit is contained in:
parent
4e81b4b190
commit
be9d18461a
|
@ -11,3 +11,9 @@
|
||||||
notification_mute: 4,
|
notification_mute: 4,
|
||||||
inverse_subscription: 5
|
inverse_subscription: 5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
defenum(FollowingRelationshipStateEnum,
|
||||||
|
follow_pending: 1,
|
||||||
|
follow_accept: 2,
|
||||||
|
follow_reject: 3
|
||||||
|
)
|
||||||
|
|
|
@ -13,7 +13,7 @@ defmodule Pleroma.FollowingRelationship do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
schema "following_relationships" do
|
schema "following_relationships" do
|
||||||
field(:state, :string, default: "accept")
|
field(:state, FollowingRelationshipStateEnum, default: :follow_pending)
|
||||||
|
|
||||||
belongs_to(:follower, User, type: CompatType)
|
belongs_to(:follower, User, type: CompatType)
|
||||||
belongs_to(:following, User, type: CompatType)
|
belongs_to(:following, User, type: CompatType)
|
||||||
|
@ -27,6 +27,19 @@ def changeset(%__MODULE__{} = following_relationship, attrs) do
|
||||||
|> put_assoc(:follower, attrs.follower)
|
|> put_assoc(:follower, attrs.follower)
|
||||||
|> put_assoc(:following, attrs.following)
|
|> put_assoc(:following, attrs.following)
|
||||||
|> validate_required([:state, :follower, :following])
|
|> validate_required([:state, :follower, :following])
|
||||||
|
|> unique_constraint(:follower_id,
|
||||||
|
name: :following_relationships_follower_id_following_id_index
|
||||||
|
)
|
||||||
|
|> validate_not_self_relationship()
|
||||||
|
end
|
||||||
|
|
||||||
|
def state_to_enum(state) when is_binary(state) do
|
||||||
|
case state do
|
||||||
|
"pending" -> :follow_pending
|
||||||
|
"accept" -> :follow_accept
|
||||||
|
"reject" -> :follow_reject
|
||||||
|
_ -> raise "State is not convertible to FollowingRelationshipStateEnum: #{state}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(%User{} = follower, %User{} = following) do
|
def get(%User{} = follower, %User{} = following) do
|
||||||
|
@ -35,7 +48,7 @@ def get(%User{} = follower, %User{} = following) do
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(follower, following, "reject"), do: unfollow(follower, following)
|
def update(follower, following, :follow_reject), do: unfollow(follower, following)
|
||||||
|
|
||||||
def update(%User{} = follower, %User{} = following, state) do
|
def update(%User{} = follower, %User{} = following, state) do
|
||||||
case get(follower, following) do
|
case get(follower, following) do
|
||||||
|
@ -50,7 +63,7 @@ def update(%User{} = follower, %User{} = following, state) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow(%User{} = follower, %User{} = following, state \\ "accept") do
|
def follow(%User{} = follower, %User{} = following, state \\ :follow_accept) do
|
||||||
%__MODULE__{}
|
%__MODULE__{}
|
||||||
|> changeset(%{follower: follower, following: following, state: state})
|
|> changeset(%{follower: follower, following: following, state: state})
|
||||||
|> Repo.insert(on_conflict: :nothing)
|
|> Repo.insert(on_conflict: :nothing)
|
||||||
|
@ -80,7 +93,7 @@ def following_count(%User{} = user) do
|
||||||
def get_follow_requests(%User{id: id}) do
|
def get_follow_requests(%User{id: id}) do
|
||||||
__MODULE__
|
__MODULE__
|
||||||
|> join(:inner, [r], f in assoc(r, :follower))
|
|> join(:inner, [r], f in assoc(r, :follower))
|
||||||
|> where([r], r.state == "pending")
|
|> where([r], r.state == ^:follow_pending)
|
||||||
|> where([r], r.following_id == ^id)
|
|> where([r], r.following_id == ^id)
|
||||||
|> select([r, f], f)
|
|> select([r, f], f)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
@ -88,7 +101,7 @@ def get_follow_requests(%User{id: id}) do
|
||||||
|
|
||||||
def following?(%User{id: follower_id}, %User{id: followed_id}) do
|
def following?(%User{id: follower_id}, %User{id: followed_id}) do
|
||||||
__MODULE__
|
__MODULE__
|
||||||
|> where(follower_id: ^follower_id, following_id: ^followed_id, state: "accept")
|
|> where(follower_id: ^follower_id, following_id: ^followed_id, state: ^:follow_accept)
|
||||||
|> Repo.exists?()
|
|> Repo.exists?()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -97,7 +110,7 @@ def following(%User{} = user) do
|
||||||
__MODULE__
|
__MODULE__
|
||||||
|> join(:inner, [r], u in User, on: r.following_id == u.id)
|
|> join(:inner, [r], u in User, on: r.following_id == u.id)
|
||||||
|> where([r], r.follower_id == ^user.id)
|
|> where([r], r.follower_id == ^user.id)
|
||||||
|> where([r], r.state == "accept")
|
|> where([r], r.state == ^:follow_accept)
|
||||||
|> select([r, u], u.follower_address)
|
|> select([r, u], u.follower_address)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
|
||||||
|
@ -157,4 +170,22 @@ def find(following_relationships, follower, following) do
|
||||||
fr -> fr.follower_id == follower.id and fr.following_id == following.id
|
fr -> fr.follower_id == follower.id and fr.following_id == following.id
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp validate_not_self_relationship(%Ecto.Changeset{} = changeset) do
|
||||||
|
changeset
|
||||||
|
|> validate_change(:following_id, fn _, following_id ->
|
||||||
|
if following_id == get_field(changeset, :follower_id) do
|
||||||
|
[target_id: "can't be equal to follower_id"]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> validate_change(:follower_id, fn _, follower_id ->
|
||||||
|
if follower_id == get_field(changeset, :following_id) do
|
||||||
|
[source_id: "can't be equal to following_id"]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -697,7 +697,7 @@ 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, locked: true} = followed) do
|
def maybe_direct_follow(%User{} = follower, %User{local: true, locked: true} = followed) do
|
||||||
follow(follower, followed, "pending")
|
follow(follower, followed, :follow_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
|
||||||
|
@ -717,14 +717,14 @@ def maybe_direct_follow(%User{} = follower, %User{} = followed) do
|
||||||
def follow_all(follower, followeds) do
|
def follow_all(follower, followeds) do
|
||||||
followeds
|
followeds
|
||||||
|> Enum.reject(fn followed -> blocks?(follower, followed) || blocks?(followed, follower) end)
|
|> Enum.reject(fn followed -> blocks?(follower, followed) || blocks?(followed, follower) end)
|
||||||
|> Enum.each(&follow(follower, &1, "accept"))
|
|> Enum.each(&follow(follower, &1, :follow_accept))
|
||||||
|
|
||||||
set_cache(follower)
|
set_cache(follower)
|
||||||
end
|
end
|
||||||
|
|
||||||
defdelegate following(user), to: FollowingRelationship
|
defdelegate following(user), to: FollowingRelationship
|
||||||
|
|
||||||
def follow(%User{} = follower, %User{} = followed, state \\ "accept") do
|
def follow(%User{} = follower, %User{} = followed, state \\ :follow_accept) do
|
||||||
deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked])
|
deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked])
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
|
@ -751,7 +751,7 @@ def unfollow(%User{ap_id: ap_id}, %User{ap_id: ap_id}) do
|
||||||
|
|
||||||
def unfollow(%User{} = follower, %User{} = followed) do
|
def unfollow(%User{} = follower, %User{} = followed) do
|
||||||
case get_follow_state(follower, followed) do
|
case get_follow_state(follower, followed) do
|
||||||
state when state in ["accept", "pending"] ->
|
state when state in [:follow_pending, :follow_accept] ->
|
||||||
FollowingRelationship.unfollow(follower, followed)
|
FollowingRelationship.unfollow(follower, followed)
|
||||||
{:ok, followed} = update_follower_count(followed)
|
{:ok, followed} = update_follower_count(followed)
|
||||||
|
|
||||||
|
@ -769,6 +769,7 @@ def unfollow(%User{} = follower, %User{} = followed) do
|
||||||
|
|
||||||
defdelegate following?(follower, followed), to: FollowingRelationship
|
defdelegate following?(follower, followed), to: FollowingRelationship
|
||||||
|
|
||||||
|
@doc "Returns follow state as FollowingRelationshipStateEnum value"
|
||||||
def get_follow_state(%User{} = follower, %User{} = following) do
|
def get_follow_state(%User{} = follower, %User{} = following) do
|
||||||
following_relationship = FollowingRelationship.get(follower, following)
|
following_relationship = FollowingRelationship.get(follower, following)
|
||||||
get_follow_state(follower, following, following_relationship)
|
get_follow_state(follower, following, following_relationship)
|
||||||
|
@ -782,8 +783,11 @@ def get_follow_state(
|
||||||
case {following_relationship, following.local} do
|
case {following_relationship, following.local} do
|
||||||
{nil, false} ->
|
{nil, false} ->
|
||||||
case Utils.fetch_latest_follow(follower, following) do
|
case Utils.fetch_latest_follow(follower, following) do
|
||||||
%{data: %{"state" => state}} when state in ["pending", "accept"] -> state
|
%Activity{data: %{"state" => state}} when state in ["pending", "accept"] ->
|
||||||
_ -> nil
|
FollowingRelationship.state_to_enum(state)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
{%{state: state}, _} ->
|
{%{state: state}, _} ->
|
||||||
|
@ -1282,7 +1286,7 @@ def blocks?(nil, _), do: false
|
||||||
|
|
||||||
def blocks?(%User{} = user, %User{} = target) do
|
def blocks?(%User{} = user, %User{} = target) do
|
||||||
blocks_user?(user, target) ||
|
blocks_user?(user, target) ||
|
||||||
(!User.following?(user, target) && blocks_domain?(user, target))
|
(blocks_domain?(user, target) and not User.following?(user, target))
|
||||||
end
|
end
|
||||||
|
|
||||||
def blocks_user?(%User{} = user, %User{} = target) do
|
def blocks_user?(%User{} = user, %User{} = target) do
|
||||||
|
|
|
@ -148,7 +148,7 @@ defp compose_query({:followers, %User{id: id}}, query) do
|
||||||
as: :relationships,
|
as: :relationships,
|
||||||
on: r.following_id == ^id and r.follower_id == u.id
|
on: r.following_id == ^id and r.follower_id == u.id
|
||||||
)
|
)
|
||||||
|> where([relationships: r], r.state == "accept")
|
|> where([relationships: r], r.state == ^:follow_accept)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:friends, %User{id: id}}, query) do
|
defp compose_query({:friends, %User{id: id}}, query) do
|
||||||
|
@ -158,7 +158,7 @@ defp compose_query({:friends, %User{id: id}}, query) do
|
||||||
as: :relationships,
|
as: :relationships,
|
||||||
on: r.following_id == u.id and r.follower_id == ^id
|
on: r.following_id == u.id and r.follower_id == ^id
|
||||||
)
|
)
|
||||||
|> where([relationships: r], r.state == "accept")
|
|> where([relationships: r], r.state == ^:follow_accept)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:recipients_from_activity, to}, query) do
|
defp compose_query({:recipients_from_activity, to}, query) do
|
||||||
|
@ -173,7 +173,7 @@ defp compose_query({:recipients_from_activity, to}, query) do
|
||||||
)
|
)
|
||||||
|> where(
|
|> where(
|
||||||
[u, following: f, relationships: r],
|
[u, following: f, relationships: r],
|
||||||
u.ap_id in ^to or (f.follower_address in ^to and r.state == "accept")
|
u.ap_id in ^to or (f.follower_address in ^to and r.state == ^:follow_accept)
|
||||||
)
|
)
|
||||||
|> distinct(true)
|
|> distinct(true)
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,7 +33,7 @@ def subdomains_regex(domains) when is_list(domains) do
|
||||||
|
|
||||||
@spec subdomain_match?([Regex.t()], String.t()) :: boolean()
|
@spec subdomain_match?([Regex.t()], String.t()) :: boolean()
|
||||||
def subdomain_match?(domains, host) do
|
def subdomain_match?(domains, host) do
|
||||||
Enum.any?(domains, fn domain -> Regex.match?(domain, host) end)
|
!!Enum.find(domains, fn domain -> Regex.match?(domain, host) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@callback describe() :: {:ok | :error, Map.t()}
|
@callback describe() :: {:ok | :error, Map.t()}
|
||||||
|
|
|
@ -490,7 +490,8 @@ def handle_incoming(
|
||||||
{_, {: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")},
|
{:follow_state_update, Utils.update_follow_state_for_all(activity, "accept")},
|
||||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do
|
{:ok, _relationship} <-
|
||||||
|
FollowingRelationship.update(follower, followed, :follow_accept) do
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
actor: followed,
|
actor: followed,
|
||||||
|
@ -500,7 +501,7 @@ def handle_incoming(
|
||||||
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")
|
{:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
|
||||||
|
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
|
@ -511,7 +512,7 @@ def handle_incoming(
|
||||||
|
|
||||||
{: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")
|
{:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_reject)
|
||||||
|
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
|
@ -521,7 +522,7 @@ def handle_incoming(
|
||||||
})
|
})
|
||||||
|
|
||||||
{:user_locked, true} ->
|
{:user_locked, true} ->
|
||||||
{:ok, _relationship} = FollowingRelationship.update(follower, followed, "pending")
|
{:ok, _relationship} = FollowingRelationship.update(follower, followed, :follow_pending)
|
||||||
:noop
|
:noop
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -541,7 +542,7 @@ def handle_incoming(
|
||||||
{: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, _relationship} <- FollowingRelationship.update(follower, followed, "accept") do
|
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: follow_activity.data["to"],
|
to: follow_activity.data["to"],
|
||||||
type: "Accept",
|
type: "Accept",
|
||||||
|
@ -564,7 +565,7 @@ def handle_incoming(
|
||||||
{: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, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject),
|
||||||
{:ok, activity} <-
|
{:ok, activity} <-
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: follow_activity.data["to"],
|
to: follow_activity.data["to"],
|
||||||
|
|
|
@ -42,7 +42,7 @@ def accept_follow_request(follower, followed) 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, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept),
|
||||||
{:ok, _activity} <-
|
{:ok, _activity} <-
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
|
@ -57,7 +57,7 @@ def accept_follow_request(follower, followed) 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, _relationship} <- FollowingRelationship.update(follower, followed, :follow_reject),
|
||||||
{:ok, _activity} <-
|
{:ok, _activity} <-
|
||||||
ActivityPub.reject(%{
|
ActivityPub.reject(%{
|
||||||
to: [follower.ap_id],
|
to: [follower.ap_id],
|
||||||
|
|
|
@ -71,7 +71,7 @@ def render(
|
||||||
followed_by =
|
followed_by =
|
||||||
if following_relationships do
|
if following_relationships do
|
||||||
case FollowingRelationship.find(following_relationships, target, reading_user) do
|
case FollowingRelationship.find(following_relationships, target, reading_user) do
|
||||||
%{state: "accept"} -> true
|
%{state: :follow_accept} -> true
|
||||||
_ -> false
|
_ -> false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -81,7 +81,7 @@ def render(
|
||||||
# NOTE: adjust UserRelationship.view_relationships_option/2 on new relation-related flags
|
# NOTE: adjust UserRelationship.view_relationships_option/2 on new relation-related flags
|
||||||
%{
|
%{
|
||||||
id: to_string(target.id),
|
id: to_string(target.id),
|
||||||
following: follow_state == "accept",
|
following: follow_state == :follow_accept,
|
||||||
followed_by: followed_by,
|
followed_by: followed_by,
|
||||||
blocking:
|
blocking:
|
||||||
UserRelationship.exists?(
|
UserRelationship.exists?(
|
||||||
|
@ -123,7 +123,7 @@ def render(
|
||||||
reading_user,
|
reading_user,
|
||||||
&User.subscribed_to?(&2, &1)
|
&User.subscribed_to?(&2, &1)
|
||||||
),
|
),
|
||||||
requested: follow_state == "pending",
|
requested: follow_state == :follow_pending,
|
||||||
domain_blocking: User.blocks_domain?(reading_user, target),
|
domain_blocking: User.blocks_domain?(reading_user, target),
|
||||||
showing_reblogs:
|
showing_reblogs:
|
||||||
not UserRelationship.exists?(
|
not UserRelationship.exists?(
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.ChangeFollowingRelationshipsStateToInteger do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
@alter_apps_scopes "ALTER TABLE following_relationships ALTER COLUMN state"
|
||||||
|
|
||||||
|
def up do
|
||||||
|
execute("""
|
||||||
|
#{@alter_apps_scopes} TYPE integer USING
|
||||||
|
CASE
|
||||||
|
WHEN state = 'pending' THEN 1
|
||||||
|
WHEN state = 'accept' THEN 2
|
||||||
|
WHEN state = 'reject' THEN 3
|
||||||
|
ELSE 0
|
||||||
|
END;
|
||||||
|
""")
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
execute("""
|
||||||
|
#{@alter_apps_scopes} TYPE varchar(255) USING
|
||||||
|
CASE
|
||||||
|
WHEN state = 1 THEN 'pending'
|
||||||
|
WHEN state = 2 THEN 'accept'
|
||||||
|
WHEN state = 3 THEN 'reject'
|
||||||
|
ELSE ''
|
||||||
|
END;
|
||||||
|
""")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.AddFollowingRelationshipsFollowingIdIndex do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
# [:follower_index] index is useless because of [:follower_id, :following_id] index
|
||||||
|
# [:following_id] index makes sense because of user's followers-targeted queries
|
||||||
|
def change do
|
||||||
|
drop_if_exists(index(:following_relationships, [:follower_id]))
|
||||||
|
|
||||||
|
create_if_not_exists(drop_if_exists(index(:following_relationships, [:following_id])))
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,28 +15,28 @@ defmodule Pleroma.FollowingRelationshipTest do
|
||||||
test "returns following addresses without internal.fetch" do
|
test "returns following addresses without internal.fetch" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
fetch_actor = InternalFetchActor.get_actor()
|
fetch_actor = InternalFetchActor.get_actor()
|
||||||
FollowingRelationship.follow(fetch_actor, user, "accept")
|
FollowingRelationship.follow(fetch_actor, user, :follow_accept)
|
||||||
assert FollowingRelationship.following(fetch_actor) == [user.follower_address]
|
assert FollowingRelationship.following(fetch_actor) == [user.follower_address]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns following addresses without relay" do
|
test "returns following addresses without relay" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
relay_actor = Relay.get_actor()
|
relay_actor = Relay.get_actor()
|
||||||
FollowingRelationship.follow(relay_actor, user, "accept")
|
FollowingRelationship.follow(relay_actor, user, :follow_accept)
|
||||||
assert FollowingRelationship.following(relay_actor) == [user.follower_address]
|
assert FollowingRelationship.following(relay_actor) == [user.follower_address]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns following addresses without remote user" do
|
test "returns following addresses without remote user" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
actor = insert(:user, local: false)
|
actor = insert(:user, local: false)
|
||||||
FollowingRelationship.follow(actor, user, "accept")
|
FollowingRelationship.follow(actor, user, :follow_accept)
|
||||||
assert FollowingRelationship.following(actor) == [user.follower_address]
|
assert FollowingRelationship.following(actor) == [user.follower_address]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "returns following addresses with local user" do
|
test "returns following addresses with local user" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
actor = insert(:user, local: true)
|
actor = insert(:user, local: true)
|
||||||
FollowingRelationship.follow(actor, user, "accept")
|
FollowingRelationship.follow(actor, user, :follow_accept)
|
||||||
|
|
||||||
assert FollowingRelationship.following(actor) == [
|
assert FollowingRelationship.following(actor) == [
|
||||||
actor.follower_address,
|
actor.follower_address,
|
||||||
|
|
|
@ -140,7 +140,7 @@ test "no user to toggle" do
|
||||||
test "user is unsubscribed" do
|
test "user is unsubscribed" do
|
||||||
followed = insert(:user)
|
followed = insert(:user)
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
User.follow(user, followed, "accept")
|
User.follow(user, followed, :follow_accept)
|
||||||
|
|
||||||
Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname])
|
Mix.Tasks.Pleroma.User.run(["unsubscribe", user.nickname])
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,8 @@ test "doesn't return already accepted or duplicate follow requests" 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)
|
||||||
Pleroma.FollowingRelationship.update(accepted_follower, locked, "accept")
|
|
||||||
|
Pleroma.FollowingRelationship.update(accepted_follower, locked, :follow_accept)
|
||||||
|
|
||||||
assert [^pending_follower] = User.get_follow_requests(locked)
|
assert [^pending_follower] = User.get_follow_requests(locked)
|
||||||
end
|
end
|
||||||
|
@ -319,7 +320,7 @@ test "unfollow with syncronizes external user" do
|
||||||
following_address: "http://localhost:4001/users/fuser2/following"
|
following_address: "http://localhost:4001/users/fuser2/following"
|
||||||
})
|
})
|
||||||
|
|
||||||
{:ok, user} = User.follow(user, followed, "accept")
|
{:ok, user} = User.follow(user, followed, :follow_accept)
|
||||||
|
|
||||||
{:ok, user, _activity} = User.unfollow(user, followed)
|
{:ok, user, _activity} = User.unfollow(user, followed)
|
||||||
|
|
||||||
|
@ -332,7 +333,7 @@ test "unfollow takes a user and another user" do
|
||||||
followed = insert(:user)
|
followed = insert(:user)
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
{:ok, user} = User.follow(user, followed, "accept")
|
{:ok, user} = User.follow(user, followed, :follow_accept)
|
||||||
|
|
||||||
assert User.following(user) == [user.follower_address, followed.follower_address]
|
assert User.following(user) == [user.follower_address, followed.follower_address]
|
||||||
|
|
||||||
|
@ -353,7 +354,7 @@ test "unfollow doesn't unfollow yourself" do
|
||||||
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)
|
user = insert(:user)
|
||||||
User.follow(user, followed, "accept")
|
User.follow(user, followed, :follow_accept)
|
||||||
|
|
||||||
assert User.following?(user, followed)
|
assert User.following?(user, followed)
|
||||||
refute User.following?(followed, user)
|
refute User.following?(followed, user)
|
||||||
|
|
|
@ -1622,7 +1622,7 @@ test "it upgrades a user to activitypub" do
|
||||||
})
|
})
|
||||||
|
|
||||||
user_two = insert(:user)
|
user_two = insert(:user)
|
||||||
Pleroma.FollowingRelationship.follow(user_two, user, "accept")
|
Pleroma.FollowingRelationship.follow(user_two, user, :follow_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"})
|
||||||
|
|
|
@ -562,7 +562,7 @@ test "cancels a pending follow for a local user" do
|
||||||
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
|
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
|
||||||
CommonAPI.follow(follower, followed)
|
CommonAPI.follow(follower, followed)
|
||||||
|
|
||||||
assert User.get_follow_state(follower, followed) == "pending"
|
assert User.get_follow_state(follower, followed) == :follow_pending
|
||||||
assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
|
assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
|
||||||
assert User.get_follow_state(follower, followed) == nil
|
assert User.get_follow_state(follower, followed) == nil
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ test "cancels a pending follow for a remote user" do
|
||||||
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
|
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
|
||||||
CommonAPI.follow(follower, followed)
|
CommonAPI.follow(follower, followed)
|
||||||
|
|
||||||
assert User.get_follow_state(follower, followed) == "pending"
|
assert User.get_follow_state(follower, followed) == :follow_pending
|
||||||
assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
|
assert {:ok, follower} = CommonAPI.unfollow(follower, followed)
|
||||||
assert User.get_follow_state(follower, followed) == nil
|
assert User.get_follow_state(follower, followed) == nil
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ test "/api/v1/follow_requests works", %{user: user, conn: conn} 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")
|
{:ok, other_user} = User.follow(other_user, user, :follow_pending)
|
||||||
|
|
||||||
assert User.following?(other_user, user) == false
|
assert User.following?(other_user, user) == false
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ test "/api/v1/follow_requests/:id/authorize works", %{user: user, conn: conn} 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")
|
{:ok, other_user} = User.follow(other_user, user, :follow_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)
|
||||||
|
|
|
@ -197,7 +197,7 @@ test "it doesn't send to user if recipients invalid and thread containment is en
|
||||||
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)
|
user = insert(:user)
|
||||||
User.follow(user, author, "accept")
|
User.follow(user, author, :follow_accept)
|
||||||
|
|
||||||
activity =
|
activity =
|
||||||
insert(:note_activity,
|
insert(:note_activity,
|
||||||
|
@ -220,7 +220,7 @@ test "it sends message if recipients invalid and thread containment is disabled"
|
||||||
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)
|
user = insert(:user)
|
||||||
User.follow(user, author, "accept")
|
User.follow(user, author, :follow_accept)
|
||||||
|
|
||||||
activity =
|
activity =
|
||||||
insert(:note_activity,
|
insert(:note_activity,
|
||||||
|
@ -243,7 +243,7 @@ test "it sends message if recipients invalid and thread containment is enabled b
|
||||||
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, skip_thread_containment: true)
|
user = insert(:user, skip_thread_containment: true)
|
||||||
User.follow(user, author, "accept")
|
User.follow(user, author, :follow_accept)
|
||||||
|
|
||||||
activity =
|
activity =
|
||||||
insert(:note_activity,
|
insert(:note_activity,
|
||||||
|
|
Loading…
Reference in New Issue