forked from AkkomaGang/akkoma
add tests for activity_pub/utils.ex
This commit is contained in:
parent
e72531bfac
commit
8cbad5500c
4 changed files with 371 additions and 172 deletions
|
@ -147,6 +147,7 @@ def get_cached_follow_state(user, target) do
|
||||||
Cachex.fetch!(:user_cache, key, fn _ -> {:commit, follow_state(user, target)} end)
|
Cachex.fetch!(:user_cache, key, fn _ -> {:commit, follow_state(user, target)} end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec set_follow_state_cache(String.t(), String.t(), String.t()) :: {:ok | :error, boolean()}
|
||||||
def set_follow_state_cache(user_ap_id, target_ap_id, state) do
|
def set_follow_state_cache(user_ap_id, target_ap_id, state) do
|
||||||
Cachex.put(
|
Cachex.put(
|
||||||
:user_cache,
|
:user_cache,
|
||||||
|
|
|
@ -435,6 +435,7 @@ def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ tru
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec block(User.t(), User.t(), String.t() | nil, boolean) :: {:ok, Activity.t() | nil}
|
||||||
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
def block(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||||
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
|
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
|
||||||
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
||||||
|
@ -463,10 +464,11 @@ def unblock(blocker, blocked, activity_id \\ nil, local \\ true) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec flag(map()) :: {:ok, Activity.t()} | any
|
||||||
def flag(
|
def flag(
|
||||||
%{
|
%{
|
||||||
actor: actor,
|
actor: actor,
|
||||||
context: context,
|
context: _context,
|
||||||
account: account,
|
account: account,
|
||||||
statuses: statuses,
|
statuses: statuses,
|
||||||
content: content
|
content: content
|
||||||
|
@ -478,14 +480,6 @@ def flag(
|
||||||
|
|
||||||
additional = params[:additional] || %{}
|
additional = params[:additional] || %{}
|
||||||
|
|
||||||
params = %{
|
|
||||||
actor: actor,
|
|
||||||
context: context,
|
|
||||||
account: account,
|
|
||||||
statuses: statuses,
|
|
||||||
content: content
|
|
||||||
}
|
|
||||||
|
|
||||||
additional =
|
additional =
|
||||||
if forward do
|
if forward do
|
||||||
Map.merge(additional, %{"to" => [], "cc" => [account.ap_id]})
|
Map.merge(additional, %{"to" => [], "cc" => [account.ap_id]})
|
||||||
|
|
|
@ -33,50 +33,40 @@ def normalize_params(params) do
|
||||||
Map.put(params, "actor", get_ap_id(params["actor"]))
|
Map.put(params, "actor", get_ap_id(params["actor"]))
|
||||||
end
|
end
|
||||||
|
|
||||||
def determine_explicit_mentions(%{"tag" => tag} = _object) when is_list(tag) do
|
@spec determine_explicit_mentions(map()) :: map()
|
||||||
tag
|
def determine_explicit_mentions(%{"tag" => tag} = _) when is_list(tag) do
|
||||||
|> Enum.filter(fn x -> is_map(x) end)
|
Enum.flat_map(tag, fn
|
||||||
|> Enum.filter(fn x -> x["type"] == "Mention" end)
|
%{"type" => "Mention", "href" => href} -> [href]
|
||||||
|> Enum.map(fn x -> x["href"] end)
|
_ -> []
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do
|
def determine_explicit_mentions(%{"tag" => tag} = object) when is_map(tag) do
|
||||||
Map.put(object, "tag", [tag])
|
object
|
||||||
|
|> Map.put("tag", [tag])
|
||||||
|> determine_explicit_mentions()
|
|> determine_explicit_mentions()
|
||||||
end
|
end
|
||||||
|
|
||||||
def determine_explicit_mentions(_), do: []
|
def determine_explicit_mentions(_), do: []
|
||||||
|
|
||||||
|
@spec recipient_in_collection(any(), any()) :: boolean()
|
||||||
defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll
|
defp recipient_in_collection(ap_id, coll) when is_binary(coll), do: ap_id == coll
|
||||||
defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll
|
defp recipient_in_collection(ap_id, coll) when is_list(coll), do: ap_id in coll
|
||||||
defp recipient_in_collection(_, _), do: false
|
defp recipient_in_collection(_, _), do: false
|
||||||
|
|
||||||
|
@spec recipient_in_message(User.t(), User.t(), map()) :: boolean()
|
||||||
def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params) do
|
def recipient_in_message(%User{ap_id: ap_id} = recipient, %User{} = actor, params) do
|
||||||
|
addresses = [params["to"], params["cc"], params["bto"], params["bcc"]]
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
recipient_in_collection(ap_id, params["to"]) ->
|
Enum.any?(addresses, &recipient_in_collection(ap_id, &1)) -> true
|
||||||
true
|
|
||||||
|
|
||||||
recipient_in_collection(ap_id, params["cc"]) ->
|
|
||||||
true
|
|
||||||
|
|
||||||
recipient_in_collection(ap_id, params["bto"]) ->
|
|
||||||
true
|
|
||||||
|
|
||||||
recipient_in_collection(ap_id, params["bcc"]) ->
|
|
||||||
true
|
|
||||||
|
|
||||||
# if the message is unaddressed at all, then assume it is directly addressed
|
# if the message is unaddressed at all, then assume it is directly addressed
|
||||||
# to the recipient
|
# to the recipient
|
||||||
!params["to"] && !params["cc"] && !params["bto"] && !params["bcc"] ->
|
Enum.all?(addresses, &is_nil(&1)) -> true
|
||||||
true
|
|
||||||
|
|
||||||
# if the message is sent from somebody the user is following, then assume it
|
# if the message is sent from somebody the user is following, then assume it
|
||||||
# is addressed to the recipient
|
# is addressed to the recipient
|
||||||
User.following?(recipient, actor) ->
|
User.following?(recipient, actor) -> true
|
||||||
true
|
true -> false
|
||||||
|
|
||||||
true ->
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -188,53 +178,58 @@ def maybe_federate(_), do: :ok
|
||||||
Adds an id and a published data if they aren't there,
|
Adds an id and a published data if they aren't there,
|
||||||
also adds it to an included object
|
also adds it to an included object
|
||||||
"""
|
"""
|
||||||
def lazy_put_activity_defaults(map, fake \\ false) do
|
@spec lazy_put_activity_defaults(map(), boolean) :: map()
|
||||||
map =
|
def lazy_put_activity_defaults(map, fake \\ false)
|
||||||
unless fake do
|
|
||||||
%{data: %{"id" => context}, id: context_id} = create_context(map["context"])
|
|
||||||
|
|
||||||
map
|
def lazy_put_activity_defaults(map, true) do
|
||||||
|> Map.put_new_lazy("id", &generate_activity_id/0)
|
map
|
||||||
|> Map.put_new_lazy("published", &make_date/0)
|
|> Map.put_new("id", "pleroma:fakeid")
|
||||||
|> Map.put_new("context", context)
|
|> Map.put_new_lazy("published", &make_date/0)
|
||||||
|> Map.put_new("context_id", context_id)
|
|> Map.put_new("context", "pleroma:fakecontext")
|
||||||
else
|
|> Map.put_new("context_id", -1)
|
||||||
map
|
|> lazy_put_object_defaults(true)
|
||||||
|> Map.put_new("id", "pleroma:fakeid")
|
end
|
||||||
|> Map.put_new_lazy("published", &make_date/0)
|
|
||||||
|> Map.put_new("context", "pleroma:fakecontext")
|
|
||||||
|> Map.put_new("context_id", -1)
|
|
||||||
end
|
|
||||||
|
|
||||||
if is_map(map["object"]) do
|
def lazy_put_activity_defaults(map, _fake) do
|
||||||
object = lazy_put_object_defaults(map["object"], map, fake)
|
%{data: %{"id" => context}, id: context_id} = create_context(map["context"])
|
||||||
%{map | "object" => object}
|
|
||||||
else
|
map
|
||||||
|
|> Map.put_new_lazy("id", &generate_activity_id/0)
|
||||||
|
|> Map.put_new_lazy("published", &make_date/0)
|
||||||
|
|> Map.put_new("context", context)
|
||||||
|
|> Map.put_new("context_id", context_id)
|
||||||
|
|> lazy_put_object_defaults(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds an id and published date if they aren't there.
|
||||||
|
#
|
||||||
|
@spec lazy_put_object_defaults(map(), boolean()) :: map()
|
||||||
|
defp lazy_put_object_defaults(%{"object" => map} = activity, true)
|
||||||
|
when is_map(map) do
|
||||||
|
object =
|
||||||
map
|
map
|
||||||
end
|
|> Map.put_new("id", "pleroma:fake_object_id")
|
||||||
|
|> Map.put_new_lazy("published", &make_date/0)
|
||||||
|
|> Map.put_new("context", activity["context"])
|
||||||
|
|> Map.put_new("context_id", activity["context_id"])
|
||||||
|
|> Map.put_new("fake", true)
|
||||||
|
|
||||||
|
%{activity | "object" => object}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
defp lazy_put_object_defaults(%{"object" => map} = activity, _)
|
||||||
Adds an id and published date if they aren't there.
|
when is_map(map) do
|
||||||
"""
|
object =
|
||||||
def lazy_put_object_defaults(map, activity \\ %{}, fake)
|
map
|
||||||
|
|> Map.put_new_lazy("id", &generate_object_id/0)
|
||||||
|
|> Map.put_new_lazy("published", &make_date/0)
|
||||||
|
|> Map.put_new("context", activity["context"])
|
||||||
|
|> Map.put_new("context_id", activity["context_id"])
|
||||||
|
|
||||||
def lazy_put_object_defaults(map, activity, true = _fake) do
|
%{activity | "object" => object}
|
||||||
map
|
|
||||||
|> Map.put_new_lazy("published", &make_date/0)
|
|
||||||
|> Map.put_new("id", "pleroma:fake_object_id")
|
|
||||||
|> Map.put_new("context", activity["context"])
|
|
||||||
|> Map.put_new("fake", true)
|
|
||||||
|> Map.put_new("context_id", activity["context_id"])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def lazy_put_object_defaults(map, activity, _fake) do
|
defp lazy_put_object_defaults(activity, _), do: activity
|
||||||
map
|
|
||||||
|> Map.put_new_lazy("id", &generate_object_id/0)
|
|
||||||
|> Map.put_new_lazy("published", &make_date/0)
|
|
||||||
|> Map.put_new("context", activity["context"])
|
|
||||||
|> Map.put_new("context_id", activity["context_id"])
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Inserts a full object if it is contained in an activity.
|
Inserts a full object if it is contained in an activity.
|
||||||
|
@ -356,23 +351,30 @@ defp fetch_likes(object) do
|
||||||
@doc """
|
@doc """
|
||||||
Updates a follow activity's state (for locked accounts).
|
Updates a follow activity's state (for locked accounts).
|
||||||
"""
|
"""
|
||||||
|
@spec update_follow_state_for_all(Activity.t(), String.t()) :: {:ok, Activity} | {:error, any()}
|
||||||
def update_follow_state_for_all(
|
def update_follow_state_for_all(
|
||||||
%Activity{data: %{"actor" => actor, "object" => object}} = activity,
|
%Activity{data: %{"actor" => actor, "object" => object}} = activity,
|
||||||
state
|
state
|
||||||
) do
|
) do
|
||||||
try do
|
query =
|
||||||
Ecto.Adapters.SQL.query!(
|
from(activity in Activity,
|
||||||
Repo,
|
where: fragment("data->>'type' = 'Follow'"),
|
||||||
"UPDATE activities SET data = jsonb_set(data, '{state}', $1) WHERE data->>'type' = 'Follow' AND data->>'actor' = $2 AND data->>'object' = $3 AND data->>'state' = 'pending'",
|
where: fragment("data->>'state' = 'pending'"),
|
||||||
[state, actor, object]
|
where: fragment("data->>'actor' = ?", ^actor),
|
||||||
|
where: fragment("data->>'object' = ?", ^object),
|
||||||
|
update: [
|
||||||
|
set: [
|
||||||
|
data: fragment("jsonb_set(data, '{state}', ?)", ^state)
|
||||||
|
]
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
User.set_follow_state_cache(actor, object, state)
|
with {_, _} <- Repo.update_all(query, []),
|
||||||
activity = Activity.get_by_id(activity.id)
|
{_, _} <- User.set_follow_state_cache(actor, object, state),
|
||||||
|
%Activity{} = activity <- Activity.get_by_id(activity.id) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
rescue
|
else
|
||||||
e ->
|
e -> {:error, e}
|
||||||
{:error, e}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -380,9 +382,7 @@ def update_follow_state(
|
||||||
%Activity{data: %{"actor" => actor, "object" => object}} = activity,
|
%Activity{data: %{"actor" => actor, "object" => object}} = activity,
|
||||||
state
|
state
|
||||||
) do
|
) do
|
||||||
with new_data <-
|
with new_data <- Map.put(activity.data, "state", state),
|
||||||
activity.data
|
|
||||||
|> Map.put("state", state),
|
|
||||||
changeset <- Changeset.change(activity, data: new_data),
|
changeset <- Changeset.change(activity, data: new_data),
|
||||||
{:ok, activity} <- Repo.update(changeset),
|
{:ok, activity} <- Repo.update(changeset),
|
||||||
_ <- User.set_follow_state_cache(actor, object, state) do
|
_ <- User.set_follow_state_cache(actor, object, state) do
|
||||||
|
@ -411,27 +411,17 @@ def make_follow_data(
|
||||||
|
|
||||||
def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do
|
def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do
|
||||||
query =
|
query =
|
||||||
from(
|
follower_id
|
||||||
activity in Activity,
|
|> Activity.Queries.by_actor()
|
||||||
where:
|
|> Activity.Queries.by_type("Follow")
|
||||||
fragment(
|
|> Activity.Queries.by_object_id(followed_id)
|
||||||
"? ->> 'type' = 'Follow'",
|
|> Activity.Queries.limit(1)
|
||||||
activity.data
|
|
||||||
),
|
|
||||||
where: activity.actor == ^follower_id,
|
|
||||||
# this is to use the index
|
|
||||||
where:
|
|
||||||
fragment(
|
|
||||||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?",
|
|
||||||
activity.data,
|
|
||||||
activity.data,
|
|
||||||
^followed_id
|
|
||||||
),
|
|
||||||
order_by: [fragment("? desc nulls last", activity.id)],
|
|
||||||
limit: 1
|
|
||||||
)
|
|
||||||
|
|
||||||
Repo.one(query)
|
from(
|
||||||
|
activity in query,
|
||||||
|
order_by: [fragment("? desc nulls last", activity.id)]
|
||||||
|
)
|
||||||
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
#### Announce-related helpers
|
#### Announce-related helpers
|
||||||
|
@ -439,23 +429,14 @@ def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do
|
||||||
@doc """
|
@doc """
|
||||||
Retruns an existing announce activity if the notice has already been announced
|
Retruns an existing announce activity if the notice has already been announced
|
||||||
"""
|
"""
|
||||||
|
@spec get_existing_announce(String.t(), map()) :: Activity.t() | nil
|
||||||
def get_existing_announce(actor, %{data: %{"id" => id}}) do
|
def get_existing_announce(actor, %{data: %{"id" => id}}) do
|
||||||
query =
|
actor
|
||||||
from(
|
|> Activity.Queries.by_actor()
|
||||||
activity in Activity,
|
|> Activity.Queries.by_type("Announce")
|
||||||
where: activity.actor == ^actor,
|
|> Activity.Queries.by_object_id(id)
|
||||||
# this is to use the index
|
|> Activity.Queries.limit(1)
|
||||||
where:
|
|> Repo.one()
|
||||||
fragment(
|
|
||||||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?",
|
|
||||||
activity.data,
|
|
||||||
activity.data,
|
|
||||||
^id
|
|
||||||
),
|
|
||||||
where: fragment("(?)->>'type' = 'Announce'", activity.data)
|
|
||||||
)
|
|
||||||
|
|
||||||
Repo.one(query)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -531,31 +512,35 @@ def make_unlike_data(
|
||||||
|> maybe_put("id", activity_id)
|
|> maybe_put("id", activity_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec add_announce_to_object(Activity.t(), Object.t()) ::
|
||||||
|
{:ok, Object.t()} | {:error, Ecto.Changeset.t()}
|
||||||
def add_announce_to_object(
|
def add_announce_to_object(
|
||||||
%Activity{
|
%Activity{data: %{"actor" => actor, "cc" => [Pleroma.Constants.as_public()]}},
|
||||||
data: %{"actor" => actor, "cc" => [Pleroma.Constants.as_public()]}
|
|
||||||
},
|
|
||||||
object
|
object
|
||||||
) do
|
) do
|
||||||
announcements =
|
announcements = fetch_announcements(object)
|
||||||
if is_list(object.data["announcements"]), do: object.data["announcements"], else: []
|
|
||||||
|
|
||||||
with announcements <- [actor | announcements] |> Enum.uniq() do
|
with announcements <- Enum.uniq([actor | announcements]) do
|
||||||
update_element_in_object("announcement", announcements, object)
|
update_element_in_object("announcement", announcements, object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_announce_to_object(_, object), do: {:ok, object}
|
def add_announce_to_object(_, object), do: {:ok, object}
|
||||||
|
|
||||||
|
@spec remove_announce_from_object(Activity.t(), Object.t()) ::
|
||||||
|
{:ok, Object.t()} | {:error, Ecto.Changeset.t()}
|
||||||
def remove_announce_from_object(%Activity{data: %{"actor" => actor}}, object) do
|
def remove_announce_from_object(%Activity{data: %{"actor" => actor}}, object) do
|
||||||
announcements =
|
with announcements <- List.delete(fetch_announcements(object), actor) do
|
||||||
if is_list(object.data["announcements"]), do: object.data["announcements"], else: []
|
|
||||||
|
|
||||||
with announcements <- announcements |> List.delete(actor) do
|
|
||||||
update_element_in_object("announcement", announcements, object)
|
update_element_in_object("announcement", announcements, object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp fetch_announcements(%{data: %{"announcements" => announcements}} = _)
|
||||||
|
when is_list(announcements),
|
||||||
|
do: announcements
|
||||||
|
|
||||||
|
defp fetch_announcements(_), do: []
|
||||||
|
|
||||||
#### Unfollow-related helpers
|
#### Unfollow-related helpers
|
||||||
|
|
||||||
def make_unfollow_data(follower, followed, follow_activity, activity_id) do
|
def make_unfollow_data(follower, followed, follow_activity, activity_id) do
|
||||||
|
@ -569,29 +554,20 @@ def make_unfollow_data(follower, followed, follow_activity, activity_id) do
|
||||||
end
|
end
|
||||||
|
|
||||||
#### Block-related helpers
|
#### Block-related helpers
|
||||||
|
@spec fetch_latest_block(User.t(), User.t()) :: Activity.t() | nil
|
||||||
def fetch_latest_block(%User{ap_id: blocker_id}, %User{ap_id: blocked_id}) do
|
def fetch_latest_block(%User{ap_id: blocker_id}, %User{ap_id: blocked_id}) do
|
||||||
query =
|
query =
|
||||||
from(
|
blocker_id
|
||||||
activity in Activity,
|
|> Activity.Queries.by_actor()
|
||||||
where:
|
|> Activity.Queries.by_type("Block")
|
||||||
fragment(
|
|> Activity.Queries.by_object_id(blocked_id)
|
||||||
"? ->> 'type' = 'Block'",
|
|> Activity.Queries.limit(1)
|
||||||
activity.data
|
|
||||||
),
|
|
||||||
where: activity.actor == ^blocker_id,
|
|
||||||
# this is to use the index
|
|
||||||
where:
|
|
||||||
fragment(
|
|
||||||
"coalesce((?)->'object'->>'id', (?)->>'object') = ?",
|
|
||||||
activity.data,
|
|
||||||
activity.data,
|
|
||||||
^blocked_id
|
|
||||||
),
|
|
||||||
order_by: [fragment("? desc nulls last", activity.id)],
|
|
||||||
limit: 1
|
|
||||||
)
|
|
||||||
|
|
||||||
Repo.one(query)
|
from(
|
||||||
|
activity in query,
|
||||||
|
order_by: [fragment("? desc nulls last", activity.id)]
|
||||||
|
)
|
||||||
|
|> Repo.one()
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_block_data(blocker, blocked, activity_id) do
|
def make_block_data(blocker, blocked, activity_id) do
|
||||||
|
@ -631,28 +607,32 @@ def make_create_data(params, additional) do
|
||||||
end
|
end
|
||||||
|
|
||||||
#### Flag-related helpers
|
#### Flag-related helpers
|
||||||
|
@spec make_flag_data(map(), map()) :: map()
|
||||||
def make_flag_data(params, additional) do
|
def make_flag_data(%{actor: actor, context: context, content: content} = params, additional) do
|
||||||
status_ap_ids =
|
|
||||||
Enum.map(params.statuses || [], fn
|
|
||||||
%Activity{} = act -> act.data["id"]
|
|
||||||
act when is_map(act) -> act["id"]
|
|
||||||
act when is_binary(act) -> act
|
|
||||||
end)
|
|
||||||
|
|
||||||
object = [params.account.ap_id] ++ status_ap_ids
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
"type" => "Flag",
|
"type" => "Flag",
|
||||||
"actor" => params.actor.ap_id,
|
"actor" => actor.ap_id,
|
||||||
"content" => params.content,
|
"content" => content,
|
||||||
"object" => object,
|
"object" => build_flag_object(params),
|
||||||
"context" => params.context,
|
"context" => context,
|
||||||
"state" => "open"
|
"state" => "open"
|
||||||
}
|
}
|
||||||
|> Map.merge(additional)
|
|> Map.merge(additional)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def make_flag_data(_, _), do: %{}
|
||||||
|
|
||||||
|
defp build_flag_object(%{account: account, statuses: statuses} = _) do
|
||||||
|
[account.ap_id] ++
|
||||||
|
Enum.map(statuses || [], fn
|
||||||
|
%Activity{} = act -> act.data["id"]
|
||||||
|
act when is_map(act) -> act["id"]
|
||||||
|
act when is_binary(act) -> act
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_flag_object(_), do: []
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Fetches the OrderedCollection/OrderedCollectionPage from `from`, limiting the amount of pages fetched after
|
Fetches the OrderedCollection/OrderedCollectionPage from `from`, limiting the amount of pages fetched after
|
||||||
the first one to `pages_left` pages.
|
the first one to `pages_left` pages.
|
||||||
|
|
|
@ -87,6 +87,18 @@ test "works with an object that has only IR tags" do
|
||||||
|
|
||||||
assert Utils.determine_explicit_mentions(object) == []
|
assert Utils.determine_explicit_mentions(object) == []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "works with an object has tags as map" do
|
||||||
|
object = %{
|
||||||
|
"tag" => %{
|
||||||
|
"type" => "Mention",
|
||||||
|
"href" => "https://example.com/~alyssa",
|
||||||
|
"name" => "Alyssa P. Hacker"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert Utils.determine_explicit_mentions(object) == ["https://example.com/~alyssa"]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "make_unlike_data/3" do
|
describe "make_unlike_data/3" do
|
||||||
|
@ -300,8 +312,8 @@ test "updates the state of all Follow activities with the same actor and object"
|
||||||
{:ok, follow_activity_two} =
|
{:ok, follow_activity_two} =
|
||||||
Utils.update_follow_state_for_all(follow_activity_two, "accept")
|
Utils.update_follow_state_for_all(follow_activity_two, "accept")
|
||||||
|
|
||||||
assert Repo.get(Activity, follow_activity.id).data["state"] == "accept"
|
assert refresh_record(follow_activity).data["state"] == "accept"
|
||||||
assert Repo.get(Activity, follow_activity_two.id).data["state"] == "accept"
|
assert refresh_record(follow_activity_two).data["state"] == "accept"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -323,8 +335,8 @@ test "updates the state of the given follow activity" do
|
||||||
|
|
||||||
{:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject")
|
{:ok, follow_activity_two} = Utils.update_follow_state(follow_activity_two, "reject")
|
||||||
|
|
||||||
assert Repo.get(Activity, follow_activity.id).data["state"] == "pending"
|
assert refresh_record(follow_activity).data["state"] == "pending"
|
||||||
assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject"
|
assert refresh_record(follow_activity_two).data["state"] == "reject"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -401,4 +413,216 @@ test "fetches existing like" do
|
||||||
assert ^like_activity = Utils.get_existing_like(user.ap_id, object)
|
assert ^like_activity = Utils.get_existing_like(user.ap_id, object)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "get_get_existing_announce/2" do
|
||||||
|
test "returns nil if announce not found" do
|
||||||
|
actor = insert(:user)
|
||||||
|
refute Utils.get_existing_announce(actor.ap_id, %{data: %{"id" => "test"}})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "fetches existing announce" do
|
||||||
|
note_activity = insert(:note_activity)
|
||||||
|
assert object = Object.normalize(note_activity)
|
||||||
|
actor = insert(:user)
|
||||||
|
|
||||||
|
{:ok, announce, _object} = ActivityPub.announce(actor, object)
|
||||||
|
assert Utils.get_existing_announce(actor.ap_id, object) == announce
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "fetch_latest_block/2" do
|
||||||
|
test "fetches last block activities" do
|
||||||
|
user1 = insert(:user)
|
||||||
|
user2 = insert(:user)
|
||||||
|
|
||||||
|
assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
|
||||||
|
assert {:ok, %Activity{} = _} = ActivityPub.block(user1, user2)
|
||||||
|
assert {:ok, %Activity{} = activity} = ActivityPub.block(user1, user2)
|
||||||
|
|
||||||
|
assert Utils.fetch_latest_block(user1, user2) == activity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "recipient_in_message/3" do
|
||||||
|
test "returns true when recipient in `to`" do
|
||||||
|
recipient = insert(:user)
|
||||||
|
actor = insert(:user)
|
||||||
|
assert Utils.recipient_in_message(recipient, actor, %{"to" => recipient.ap_id})
|
||||||
|
|
||||||
|
assert Utils.recipient_in_message(
|
||||||
|
recipient,
|
||||||
|
actor,
|
||||||
|
%{"to" => [recipient.ap_id], "cc" => ""}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns true when recipient in `cc`" do
|
||||||
|
recipient = insert(:user)
|
||||||
|
actor = insert(:user)
|
||||||
|
assert Utils.recipient_in_message(recipient, actor, %{"cc" => recipient.ap_id})
|
||||||
|
|
||||||
|
assert Utils.recipient_in_message(
|
||||||
|
recipient,
|
||||||
|
actor,
|
||||||
|
%{"cc" => [recipient.ap_id], "to" => ""}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns true when recipient in `bto`" do
|
||||||
|
recipient = insert(:user)
|
||||||
|
actor = insert(:user)
|
||||||
|
assert Utils.recipient_in_message(recipient, actor, %{"bto" => recipient.ap_id})
|
||||||
|
|
||||||
|
assert Utils.recipient_in_message(
|
||||||
|
recipient,
|
||||||
|
actor,
|
||||||
|
%{"bcc" => "", "bto" => [recipient.ap_id]}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns true when recipient in `bcc`" do
|
||||||
|
recipient = insert(:user)
|
||||||
|
actor = insert(:user)
|
||||||
|
assert Utils.recipient_in_message(recipient, actor, %{"bcc" => recipient.ap_id})
|
||||||
|
|
||||||
|
assert Utils.recipient_in_message(
|
||||||
|
recipient,
|
||||||
|
actor,
|
||||||
|
%{"bto" => "", "bcc" => [recipient.ap_id]}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns true when message without addresses fields" do
|
||||||
|
recipient = insert(:user)
|
||||||
|
actor = insert(:user)
|
||||||
|
assert Utils.recipient_in_message(recipient, actor, %{"bccc" => recipient.ap_id})
|
||||||
|
|
||||||
|
assert Utils.recipient_in_message(
|
||||||
|
recipient,
|
||||||
|
actor,
|
||||||
|
%{"btod" => "", "bccc" => [recipient.ap_id]}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns false" do
|
||||||
|
recipient = insert(:user)
|
||||||
|
actor = insert(:user)
|
||||||
|
refute Utils.recipient_in_message(recipient, actor, %{"to" => "ap_id"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "lazy_put_activity_defaults/2" do
|
||||||
|
test "returns map with id and published data" do
|
||||||
|
note_activity = insert(:note_activity)
|
||||||
|
object = Object.normalize(note_activity)
|
||||||
|
res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
|
||||||
|
assert res["context"] == object.data["id"]
|
||||||
|
assert res["context_id"] == object.id
|
||||||
|
assert res["id"]
|
||||||
|
assert res["published"]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns map with fake id and published data" do
|
||||||
|
assert %{
|
||||||
|
"context" => "pleroma:fakecontext",
|
||||||
|
"context_id" => -1,
|
||||||
|
"id" => "pleroma:fakeid",
|
||||||
|
"published" => _
|
||||||
|
} = Utils.lazy_put_activity_defaults(%{}, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns activity data with object" do
|
||||||
|
note_activity = insert(:note_activity)
|
||||||
|
object = Object.normalize(note_activity)
|
||||||
|
|
||||||
|
res =
|
||||||
|
Utils.lazy_put_activity_defaults(%{
|
||||||
|
"context" => object.data["id"],
|
||||||
|
"object" => %{}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert res["context"] == object.data["id"]
|
||||||
|
assert res["context_id"] == object.id
|
||||||
|
assert res["id"]
|
||||||
|
assert res["published"]
|
||||||
|
assert res["object"]["id"]
|
||||||
|
assert res["object"]["published"]
|
||||||
|
assert res["object"]["context"] == object.data["id"]
|
||||||
|
assert res["object"]["context_id"] == object.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "make_flag_data" do
|
||||||
|
test "returns empty map when params is invalid" do
|
||||||
|
assert Utils.make_flag_data(%{}, %{}) == %{}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns map with Flag object" do
|
||||||
|
reporter = insert(:user)
|
||||||
|
target_account = insert(:user)
|
||||||
|
{:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"})
|
||||||
|
context = Utils.generate_context_id()
|
||||||
|
content = "foobar"
|
||||||
|
|
||||||
|
target_ap_id = target_account.ap_id
|
||||||
|
activity_ap_id = activity.data["id"]
|
||||||
|
|
||||||
|
res =
|
||||||
|
Utils.make_flag_data(
|
||||||
|
%{
|
||||||
|
actor: reporter,
|
||||||
|
context: context,
|
||||||
|
account: target_account,
|
||||||
|
statuses: [%{"id" => activity.data["id"]}],
|
||||||
|
content: content
|
||||||
|
},
|
||||||
|
%{}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert %{
|
||||||
|
"type" => "Flag",
|
||||||
|
"content" => ^content,
|
||||||
|
"context" => ^context,
|
||||||
|
"object" => [^target_ap_id, ^activity_ap_id],
|
||||||
|
"state" => "open"
|
||||||
|
} = res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "add_announce_to_object/2" do
|
||||||
|
test "adds actor to announcement" do
|
||||||
|
user = insert(:user)
|
||||||
|
object = insert(:note)
|
||||||
|
|
||||||
|
activity =
|
||||||
|
insert(:note_activity,
|
||||||
|
data: %{
|
||||||
|
"actor" => user.ap_id,
|
||||||
|
"cc" => [Pleroma.Constants.as_public()]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert {:ok, updated_object} = Utils.add_announce_to_object(activity, object)
|
||||||
|
assert updated_object.data["announcements"] == [user.ap_id]
|
||||||
|
assert updated_object.data["announcement_count"] == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "remove_announce_from_object/2" do
|
||||||
|
test "removes actor from announcements" do
|
||||||
|
user = insert(:user)
|
||||||
|
user2 = insert(:user)
|
||||||
|
|
||||||
|
object =
|
||||||
|
insert(:note,
|
||||||
|
data: %{"announcements" => [user.ap_id, user2.ap_id], "announcement_count" => 2}
|
||||||
|
)
|
||||||
|
|
||||||
|
activity = insert(:note_activity, data: %{"actor" => user.ap_id})
|
||||||
|
|
||||||
|
assert {:ok, updated_object} = Utils.remove_announce_from_object(activity, object)
|
||||||
|
assert updated_object.data["announcements"] == [user2.ap_id]
|
||||||
|
assert updated_object.data["announcement_count"] == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue