mirror of
https://framagit.org/framasoft/mobilizon.git
synced 2024-12-21 23:44:30 +00:00
Refactor Mobilizon.Federation.ActivityPub.Audience and add tests
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
221dd0609e
commit
78dc7613bc
9 changed files with 444 additions and 136 deletions
|
@ -426,7 +426,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
|||
"id" => "#{Endpoint.url()}/leave/event/#{participant.id}"
|
||||
},
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(participant),
|
||||
Audience.get_audience(participant),
|
||||
{:ok, activity} <- create_activity(Map.merge(leave_data, audience), local),
|
||||
:ok <- maybe_federate(activity) do
|
||||
{:ok, activity, participant}
|
||||
|
@ -803,7 +803,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
|||
Scheduler.trigger_notifications_for_participant(participant),
|
||||
participant_as_data <- Convertible.model_to_as(participant),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(participant),
|
||||
Audience.get_audience(participant),
|
||||
update_data <-
|
||||
make_accept_join_data(
|
||||
participant_as_data,
|
||||
|
@ -837,7 +837,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
|||
),
|
||||
member_as_data <- Convertible.model_to_as(member),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(member),
|
||||
Audience.get_audience(member),
|
||||
update_data <-
|
||||
make_accept_join_data(
|
||||
member_as_data,
|
||||
|
@ -899,7 +899,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
|||
participant_as_data <- Convertible.model_to_as(participant),
|
||||
audience <-
|
||||
participant
|
||||
|> Audience.calculate_to_and_cc_from_mentions()
|
||||
|> Audience.get_audience()
|
||||
|> Map.merge(additional),
|
||||
reject_data <- %{
|
||||
"type" => "Reject",
|
||||
|
@ -925,7 +925,7 @@ defmodule Mobilizon.Federation.ActivityPub do
|
|||
with {:ok, %Follower{} = follower} <- Actors.delete_follower(follower),
|
||||
follower_as_data <- Convertible.model_to_as(follower),
|
||||
audience <-
|
||||
follower.actor |> Audience.calculate_to_and_cc_from_mentions() |> Map.merge(additional),
|
||||
follower.actor |> Audience.get_audience() |> Map.merge(additional),
|
||||
reject_data <- %{
|
||||
"to" => [follower.actor.url],
|
||||
"type" => "Reject",
|
||||
|
|
|
@ -3,18 +3,95 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
Tools for calculating content audience
|
||||
"""
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.{Actors, Events, Share}
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Share
|
||||
alias Mobilizon.Storage.Repo
|
||||
|
||||
require Logger
|
||||
|
||||
@ap_public "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
@type audience :: %{required(String.t()) => list(String.t())}
|
||||
|
||||
@doc """
|
||||
Get audience for an entity
|
||||
"""
|
||||
@spec get_audience(Entity.t()) :: audience()
|
||||
def get_audience(%Event{} = event) do
|
||||
extract_actors_from_event(event)
|
||||
end
|
||||
|
||||
def get_audience(%Post{draft: true} = post) do
|
||||
get_audience(%Post{post | visibility: :private, draft: false})
|
||||
end
|
||||
|
||||
def get_audience(%Post{attributed_to: %Actor{} = group, visibility: visibility}) do
|
||||
{to, cc} = get_to_and_cc(group, [], visibility)
|
||||
%{"to" => to, "cc" => cc}
|
||||
end
|
||||
|
||||
def get_audience(%Discussion{actor: actor}) do
|
||||
%{"to" => maybe_add_group_members([], actor), "cc" => []}
|
||||
end
|
||||
|
||||
def get_audience(%Comment{discussion: %Discussion{} = discussion}) do
|
||||
get_audience(discussion)
|
||||
end
|
||||
|
||||
def get_audience(%Comment{
|
||||
mentions: mentions,
|
||||
actor: %Actor{} = actor,
|
||||
visibility: visibility,
|
||||
in_reply_to_comment: in_reply_to_comment,
|
||||
event: event,
|
||||
origin_comment: origin_comment,
|
||||
url: url
|
||||
}) do
|
||||
with {to, cc} <-
|
||||
extract_actors_from_mentions(mentions, actor, visibility),
|
||||
{to, cc} <- {Enum.uniq(to ++ add_in_reply_to(in_reply_to_comment)), cc},
|
||||
{to, cc} <- {Enum.uniq(to ++ add_event_author(event)), cc},
|
||||
{to, cc} <-
|
||||
{to,
|
||||
Enum.uniq(
|
||||
cc ++
|
||||
add_comments_authors([origin_comment]) ++
|
||||
add_shares_actors_followers(url)
|
||||
)} do
|
||||
%{"to" => to, "cc" => cc}
|
||||
end
|
||||
end
|
||||
|
||||
def get_audience(%Participant{} = participant) do
|
||||
event = Events.get_event_with_preload!(participant.event_id)
|
||||
|
||||
actor_participants_urls =
|
||||
event.id
|
||||
|> Mobilizon.Events.list_actors_participants_for_event()
|
||||
|> Enum.map(& &1.url)
|
||||
|
||||
%{
|
||||
"to" => [participant.actor.url, group_or_organizer_event(event).url],
|
||||
"cc" => actor_participants_urls
|
||||
}
|
||||
end
|
||||
|
||||
def get_audience(%Member{} = member) do
|
||||
%{"to" => [member.parent.url, member.parent.members_url], "cc" => []}
|
||||
end
|
||||
|
||||
def get_audience(%Actor{} = actor) do
|
||||
%{
|
||||
"to" => [@ap_public],
|
||||
"cc" =>
|
||||
maybe_add_group_members([actor.followers_url], actor) ++
|
||||
add_actors_that_had_our_content(actor.id)
|
||||
}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Determines the full audience based on mentions for an audience
|
||||
|
||||
|
@ -39,6 +116,8 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
to = [@ap_public | mentions]
|
||||
cc = [actor.followers_url]
|
||||
|
||||
cc = maybe_add_group_members(cc, actor)
|
||||
|
||||
{to, cc}
|
||||
end
|
||||
|
||||
|
@ -47,13 +126,18 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
to = [actor.followers_url | mentions]
|
||||
cc = [@ap_public]
|
||||
|
||||
to = maybe_add_group_members(to, actor)
|
||||
|
||||
{to, cc}
|
||||
end
|
||||
|
||||
@spec get_to_and_cc(Actor.t(), list(), String.t()) :: {list(), list()}
|
||||
def get_to_and_cc(%Actor{} = actor, mentions, :private) do
|
||||
{to, cc} = get_to_and_cc(actor, mentions, :direct)
|
||||
{[actor.followers_url | to], cc}
|
||||
|
||||
to = maybe_add_group_members(to, actor)
|
||||
|
||||
{to, cc}
|
||||
end
|
||||
|
||||
@spec get_to_and_cc(Actor.t(), list(), String.t()) :: {list(), list()}
|
||||
|
@ -65,125 +149,24 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
{mentions, []}
|
||||
end
|
||||
|
||||
@spec maybe_add_group_members(List.t(), Actor.t()) :: List.t()
|
||||
defp maybe_add_group_members(collection, %Actor{type: :Group, members_url: members_url}) do
|
||||
[members_url | collection]
|
||||
end
|
||||
|
||||
defp maybe_add_group_members(collection, %Actor{type: _}), do: collection
|
||||
|
||||
def get_addressed_actors(mentioned_users, _), do: mentioned_users
|
||||
|
||||
def calculate_to_and_cc_from_mentions(
|
||||
%Comment{discussion: %Discussion{actor_id: actor_id}} = _comment
|
||||
) do
|
||||
with %Actor{type: :Group, members_url: members_url} <- Actors.get_actor(actor_id) do
|
||||
%{"to" => [members_url], "cc" => []}
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Comment{} = comment) do
|
||||
with {to, cc} <-
|
||||
extract_actors_from_mentions(comment.mentions, comment.actor, comment.visibility),
|
||||
{to, cc} <- {Enum.uniq(to ++ add_in_reply_to(comment.in_reply_to_comment)), cc},
|
||||
{to, cc} <- {Enum.uniq(to ++ add_event_author(comment.event)), cc},
|
||||
{to, cc} <-
|
||||
{to,
|
||||
Enum.uniq(
|
||||
cc ++
|
||||
add_comments_authors([comment.origin_comment]) ++
|
||||
add_shares_actors_followers(comment.url)
|
||||
)} do
|
||||
%{"to" => to, "cc" => cc}
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Discussion{actor_id: actor_id}) do
|
||||
with %Actor{type: :Group, members_url: members_url} <- Actors.get_actor(actor_id) do
|
||||
%{"to" => [members_url], "cc" => []}
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(
|
||||
%Event{
|
||||
attributed_to: %Actor{members_url: members_url},
|
||||
visibility: visibility
|
||||
} = event
|
||||
) do
|
||||
%{"to" => to, "cc" => cc} = extract_actors_from_event(event)
|
||||
|
||||
case visibility do
|
||||
:public ->
|
||||
%{"to" => [@ap_public, members_url] ++ to, "cc" => [] ++ cc}
|
||||
|
||||
:unlisted ->
|
||||
%{"to" => [members_url] ++ to, "cc" => [@ap_public] ++ cc}
|
||||
|
||||
:private ->
|
||||
# Private is restricted to only the members
|
||||
%{"to" => [members_url], "cc" => []}
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Event{} = event) do
|
||||
extract_actors_from_event(event)
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Post{
|
||||
attributed_to: %Actor{members_url: members_url, followers_url: followers_url},
|
||||
visibility: visibility,
|
||||
draft: draft
|
||||
}) do
|
||||
cond do
|
||||
# If the post is draft we send it only to members
|
||||
draft == true ->
|
||||
%{"to" => [members_url], "cc" => []}
|
||||
|
||||
# If public everyone
|
||||
visibility == :public ->
|
||||
%{"to" => [@ap_public, members_url], "cc" => [followers_url]}
|
||||
|
||||
# Otherwise just followers
|
||||
visibility == :unlisted ->
|
||||
%{"to" => [followers_url, members_url], "cc" => [@ap_public]}
|
||||
|
||||
visibility == :private ->
|
||||
# Private is restricted to only the members
|
||||
%{"to" => [members_url], "cc" => []}
|
||||
|
||||
true ->
|
||||
%{"to" => [], "cc" => []}
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Participant{} = participant) do
|
||||
participant = Repo.preload(participant, [:actor, :event])
|
||||
|
||||
actor_participants_urls =
|
||||
participant.event.id
|
||||
|> Mobilizon.Events.list_actors_participants_for_event()
|
||||
|> Enum.map(& &1.url)
|
||||
|
||||
%{"to" => [participant.actor.url], "cc" => actor_participants_urls}
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Member{} = member) do
|
||||
member = Repo.preload(member, [:parent])
|
||||
|
||||
%{"to" => [member.parent.members_url], "cc" => []}
|
||||
end
|
||||
|
||||
def calculate_to_and_cc_from_mentions(%Actor{} = actor) do
|
||||
%{
|
||||
"to" => [@ap_public],
|
||||
"cc" => [actor.followers_url] ++ add_actors_that_had_our_content(actor.id)
|
||||
}
|
||||
end
|
||||
|
||||
defp add_in_reply_to(%Comment{actor: %Actor{url: url}} = _comment), do: [url]
|
||||
defp add_in_reply_to(%Event{organizer_actor: %Actor{url: url}} = _event), do: [url]
|
||||
defp add_in_reply_to(_), do: []
|
||||
|
||||
defp add_event_author(nil), do: []
|
||||
|
||||
defp add_event_author(%Event{} = event) do
|
||||
[Repo.preload(event, [:organizer_actor]).organizer_actor.url]
|
||||
end
|
||||
|
||||
defp add_comment_author(nil), do: nil
|
||||
defp add_event_author(_), do: []
|
||||
|
||||
defp add_comment_author(%Comment{} = comment) do
|
||||
case Repo.preload(comment, [:actor]) do
|
||||
|
@ -195,6 +178,8 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
end
|
||||
end
|
||||
|
||||
defp add_comment_author(_), do: nil
|
||||
|
||||
defp add_comments_authors(comments) do
|
||||
authors =
|
||||
comments
|
||||
|
@ -208,8 +193,6 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
defp add_shares_actors_followers(uri) do
|
||||
uri
|
||||
|> Share.get_actors_by_share_uri()
|
||||
|> Enum.map(&Actors.list_followers_actors_for_actor/1)
|
||||
|> List.flatten()
|
||||
|> Enum.map(& &1.url)
|
||||
|> Enum.uniq()
|
||||
end
|
||||
|
@ -217,8 +200,6 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
defp add_actors_that_had_our_content(actor_id) do
|
||||
actor_id
|
||||
|> Share.get_actors_by_owner_actor_id()
|
||||
|> Enum.map(&Actors.list_followers_actors_for_actor/1)
|
||||
|> List.flatten()
|
||||
|> Enum.map(& &1.url)
|
||||
|> Enum.uniq()
|
||||
end
|
||||
|
@ -241,7 +222,11 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
|
||||
defp extract_actors_from_event(%Event{} = event) do
|
||||
with {to, cc} <-
|
||||
extract_actors_from_mentions(event.mentions, event.organizer_actor, event.visibility),
|
||||
extract_actors_from_mentions(
|
||||
event.mentions,
|
||||
group_or_organizer_event(event),
|
||||
event.visibility
|
||||
),
|
||||
{to, cc} <-
|
||||
{to,
|
||||
Enum.uniq(
|
||||
|
@ -253,4 +238,8 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
|
|||
%{"to" => [], "cc" => []}
|
||||
end
|
||||
end
|
||||
|
||||
@spec group_or_organizer_event(Event.t()) :: Actor.t()
|
||||
defp group_or_organizer_event(%Event{attributed_to: %Actor{} = group}), do: group
|
||||
defp group_or_organizer_event(%Event{organizer_actor: %Actor{} = actor}), do: actor
|
||||
end
|
||||
|
|
|
@ -47,7 +47,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
|
|||
actor_as_data <- Convertible.model_to_as(new_actor),
|
||||
{:ok, true} <- Cachex.del(:activity_pub, "actor_#{new_actor.preferred_username}"),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(new_actor),
|
||||
Audience.get_audience(new_actor),
|
||||
additional <- Map.merge(additional, %{"actor" => old_actor.url}),
|
||||
update_data <- make_update_data(actor_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, new_actor, update_data}
|
||||
|
@ -142,7 +142,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Actors do
|
|||
"object" => group.url
|
||||
},
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(member) do
|
||||
Audience.get_audience(member) do
|
||||
approve_if_default_role_is_member(
|
||||
group,
|
||||
actor,
|
||||
|
|
|
@ -32,7 +32,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
|||
:ok <- maybe_publish_graphql_subscription(discussion_id),
|
||||
comment_as_data <- Convertible.model_to_as(comment),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(comment),
|
||||
Audience.get_audience(comment),
|
||||
create_data <-
|
||||
make_create_data(comment_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, comment, create_data}
|
||||
|
@ -47,7 +47,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
|||
{:ok, true} <- Cachex.del(:activity_pub, "comment_#{new_comment.uuid}"),
|
||||
comment_as_data <- Convertible.model_to_as(new_comment),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(new_comment),
|
||||
Audience.get_audience(new_comment),
|
||||
update_data <- make_update_data(comment_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, new_comment, update_data}
|
||||
else
|
||||
|
@ -79,7 +79,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
|||
force_deletion = Map.get(options, :force, false)
|
||||
|
||||
with audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(comment),
|
||||
Audience.get_audience(comment),
|
||||
{:ok, %Comment{} = updated_comment} <-
|
||||
Discussions.delete_comment(comment, force: force_deletion),
|
||||
{:ok, true} <- Cachex.del(:activity_pub, "comment_#{comment.uuid}"),
|
||||
|
|
|
@ -31,7 +31,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
|
|||
:ok <- maybe_publish_graphql_subscription(discussion),
|
||||
comment_as_data <- Convertible.model_to_as(last_comment),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(discussion),
|
||||
Audience.get_audience(discussion),
|
||||
create_data <-
|
||||
make_create_data(comment_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, discussion, create_data}
|
||||
|
@ -48,7 +48,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
|
|||
DiscussionActivity.insert_activity(discussion, subject: "discussion_created"),
|
||||
discussion_as_data <- Convertible.model_to_as(discussion),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(discussion),
|
||||
Audience.get_audience(discussion),
|
||||
create_data <-
|
||||
make_create_data(discussion_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, discussion, create_data}
|
||||
|
@ -68,7 +68,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Discussions do
|
|||
{:ok, true} <- Cachex.del(:activity_pub, "discussion_#{new_discussion.slug}"),
|
||||
discussion_as_data <- Convertible.model_to_as(new_discussion),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(new_discussion),
|
||||
Audience.get_audience(new_discussion),
|
||||
update_data <- make_update_data(discussion_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, new_discussion, update_data}
|
||||
else
|
||||
|
|
|
@ -29,7 +29,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
|||
EventActivity.insert_activity(event, subject: "event_created"),
|
||||
event_as_data <- Convertible.model_to_as(event),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(event),
|
||||
Audience.get_audience(event),
|
||||
create_data <-
|
||||
make_create_data(event_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, event, create_data}
|
||||
|
@ -46,7 +46,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
|||
{:ok, true} <- Cachex.del(:activity_pub, "event_#{new_event.uuid}"),
|
||||
event_as_data <- Convertible.model_to_as(new_event),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(new_event),
|
||||
Audience.get_audience(new_event),
|
||||
update_data <- make_update_data(event_as_data, Map.merge(audience, additional)) do
|
||||
{:ok, new_event, update_data}
|
||||
else
|
||||
|
@ -69,7 +69,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
|||
}
|
||||
|
||||
with audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(event),
|
||||
Audience.get_audience(event),
|
||||
{:ok, %Event{} = event} <- EventsManager.delete_event(event),
|
||||
{:ok, _} <-
|
||||
EventActivity.insert_activity(event, subject: "event_deleted"),
|
||||
|
@ -124,7 +124,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
|||
}),
|
||||
join_data <- Convertible.model_to_as(participant),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(participant) do
|
||||
Audience.get_audience(participant) do
|
||||
approve_if_default_role_is_participant(
|
||||
event,
|
||||
Map.merge(join_data, audience),
|
||||
|
|
|
@ -47,7 +47,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Posts do
|
|||
post_as_data <-
|
||||
Convertible.model_to_as(%{post | attributed_to: group, author: creator}),
|
||||
audience <-
|
||||
Audience.calculate_to_and_cc_from_mentions(post) do
|
||||
Audience.get_audience(post) do
|
||||
update_data = make_update_data(post_as_data, Map.merge(audience, additional))
|
||||
|
||||
{:ok, post, update_data}
|
||||
|
|
|
@ -41,7 +41,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Post do
|
|||
}
|
||||
} = post
|
||||
) do
|
||||
audience = Audience.calculate_to_and_cc_from_mentions(post)
|
||||
audience = Audience.get_audience(post)
|
||||
|
||||
%{
|
||||
"type" => "Article",
|
||||
|
|
319
test/federation/activity_pub/audience_test.exs
Normal file
319
test/federation/activity_pub/audience_test.exs
Normal file
|
@ -0,0 +1,319 @@
|
|||
defmodule Mobilizon.Federation.ActivityPub.AudienceTest do
|
||||
use Mobilizon.DataCase
|
||||
|
||||
import Mobilizon.Factory
|
||||
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Mention
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.Federation.ActivityPub.Audience
|
||||
alias Mobilizon.Posts.Post
|
||||
alias Mobilizon.Storage.Repo
|
||||
|
||||
@ap_public "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
describe "get audience for an event created from a profile" do
|
||||
test "when the event is public" do
|
||||
%Event{} = event = insert(:event)
|
||||
event = Repo.preload(event, [:comments])
|
||||
|
||||
assert %{"cc" => [event.organizer_actor.followers_url], "to" => [@ap_public]} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
|
||||
test "when the event is unlisted" do
|
||||
%Event{} = event = insert(:event, visibility: :unlisted)
|
||||
event = Repo.preload(event, [:comments])
|
||||
|
||||
assert %{"cc" => [@ap_public], "to" => [event.organizer_actor.followers_url]} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
|
||||
test "when the event is unlisted and mentions some actors" do
|
||||
%Actor{id: mentionned_actor_id, url: mentionned_actor_url} =
|
||||
insert(:actor, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Event{} = event = insert(:event, visibility: :unlisted)
|
||||
event = Repo.preload(event, [:comments])
|
||||
mentions = [%Mention{actor_id: mentionned_actor_id}]
|
||||
event = %Event{event | mentions: mentions}
|
||||
|
||||
assert %{
|
||||
"cc" => [@ap_public],
|
||||
"to" => [event.organizer_actor.followers_url, mentionned_actor_url]
|
||||
} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
|
||||
test "with interactions" do
|
||||
%Actor{} = interactor = insert(:actor)
|
||||
|
||||
%Event{} = event = insert(:event)
|
||||
|
||||
insert(:share, owner_actor: event.organizer_actor, actor: interactor, uri: event.url)
|
||||
|
||||
event = Repo.preload(event, [:comments])
|
||||
|
||||
assert %{
|
||||
"cc" => [event.organizer_actor.followers_url, interactor.url],
|
||||
"to" => [@ap_public]
|
||||
} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get audience for an event created from a group member" do
|
||||
test "when the event is public" do
|
||||
%Actor{} = actor = insert(:actor)
|
||||
|
||||
%Actor{
|
||||
followers_url: followers_url,
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Event{} = event = insert(:event, attributed_to: group, organizer_actor: actor)
|
||||
event = Repo.preload(event, [:comments])
|
||||
|
||||
assert %{
|
||||
"cc" => [members_url, followers_url],
|
||||
"to" => [@ap_public]
|
||||
} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
|
||||
test "when the event is unlisted" do
|
||||
%Actor{} = actor = insert(:actor)
|
||||
|
||||
%Actor{
|
||||
followers_url: followers_url,
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Event{} =
|
||||
event =
|
||||
insert(:event, visibility: :unlisted, attributed_to: group, organizer_actor: actor)
|
||||
|
||||
event = Repo.preload(event, [:comments])
|
||||
|
||||
assert %{
|
||||
"cc" => [@ap_public],
|
||||
"to" => [members_url, followers_url]
|
||||
} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
|
||||
test "when the event is unlisted and mentions some actors" do
|
||||
%Actor{id: mentionned_actor_id, url: mentionned_actor_url} =
|
||||
insert(:actor, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Actor{} = actor = insert(:actor)
|
||||
|
||||
%Actor{
|
||||
followers_url: followers_url,
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@a_group")
|
||||
|
||||
%Event{} =
|
||||
event =
|
||||
insert(:event, visibility: :unlisted, attributed_to: group, organizer_actor: actor)
|
||||
|
||||
event = Repo.preload(event, [:comments])
|
||||
mentions = [%Mention{actor_id: mentionned_actor_id}]
|
||||
event = %Event{event | mentions: mentions}
|
||||
|
||||
assert %{
|
||||
"cc" => [@ap_public],
|
||||
"to" => [members_url, followers_url, mentionned_actor_url]
|
||||
} ==
|
||||
Audience.get_audience(event)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get audience for a post" do
|
||||
test "when it's public" do
|
||||
%Actor{
|
||||
followers_url: followers_url,
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Post{} = post = insert(:post, attributed_to: group)
|
||||
|
||||
assert %{"to" => [@ap_public], "cc" => [members_url, followers_url]} ==
|
||||
Audience.get_audience(post)
|
||||
end
|
||||
|
||||
test "when it's unlisted" do
|
||||
%Actor{
|
||||
followers_url: followers_url,
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Post{} = post = insert(:post, attributed_to: group, visibility: :unlisted)
|
||||
|
||||
assert %{"to" => [members_url, followers_url], "cc" => [@ap_public]} ==
|
||||
Audience.get_audience(post)
|
||||
end
|
||||
|
||||
test "when it's private" do
|
||||
%Actor{
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Post{} = post = insert(:post, attributed_to: group, visibility: :private)
|
||||
|
||||
assert %{"to" => [members_url], "cc" => []} ==
|
||||
Audience.get_audience(post)
|
||||
end
|
||||
|
||||
test "when it's still a draft" do
|
||||
%Actor{
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Post{} = post = insert(:post, attributed_to: group, draft: true)
|
||||
|
||||
assert %{"to" => [members_url], "cc" => []} ==
|
||||
Audience.get_audience(post)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get audience for a discussion" do
|
||||
test "basic" do
|
||||
%Actor{
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Discussion{} = discussion = insert(:discussion, actor: group)
|
||||
|
||||
assert %{"to" => [members_url], "cc" => []} ==
|
||||
Audience.get_audience(discussion)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get audience for a comment" do
|
||||
test "basic" do
|
||||
%Actor{id: mentionned_actor_id, url: mentionned_actor_url} =
|
||||
insert(:actor, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Comment{} = comment = insert(:comment)
|
||||
mentions = [%Mention{actor_id: mentionned_actor_id}]
|
||||
comment = %Comment{comment | mentions: mentions}
|
||||
|
||||
assert %{
|
||||
"cc" => [comment.actor.followers_url],
|
||||
"to" => [@ap_public, mentionned_actor_url, comment.event.organizer_actor.url]
|
||||
} ==
|
||||
Audience.get_audience(comment)
|
||||
end
|
||||
|
||||
test "in reply to other comments" do
|
||||
%Actor{id: mentionned_actor_id, url: mentionned_actor_url} =
|
||||
insert(:actor, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Comment{} = original_comment = insert(:comment)
|
||||
|
||||
%Comment{} =
|
||||
reply_comment =
|
||||
insert(:comment, in_reply_to_comment: original_comment, origin_comment: original_comment)
|
||||
|
||||
%Comment{} =
|
||||
comment =
|
||||
insert(:comment, in_reply_to_comment: reply_comment, origin_comment: original_comment)
|
||||
|
||||
mentions = [%Mention{actor_id: mentionned_actor_id}]
|
||||
comment = %Comment{comment | mentions: mentions}
|
||||
|
||||
assert %{
|
||||
"cc" => [comment.actor.followers_url, original_comment.actor.url],
|
||||
"to" => [
|
||||
@ap_public,
|
||||
mentionned_actor_url,
|
||||
reply_comment.actor.url,
|
||||
comment.event.organizer_actor.url
|
||||
]
|
||||
} ==
|
||||
Audience.get_audience(comment)
|
||||
end
|
||||
|
||||
test "part of a discussion" do
|
||||
%Actor{
|
||||
members_url: members_url
|
||||
} = group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Discussion{} = discussion = insert(:discussion, actor: group)
|
||||
%Comment{} = comment = insert(:comment, discussion: discussion)
|
||||
|
||||
assert %{"to" => [members_url], "cc" => []} ==
|
||||
Audience.get_audience(comment)
|
||||
end
|
||||
end
|
||||
|
||||
describe "participant" do
|
||||
test "basic" do
|
||||
%Event{} = event = insert(:event)
|
||||
%Participant{} = participant2 = insert(:participant, event: event)
|
||||
%Participant{} = participant = insert(:participant, event: event)
|
||||
|
||||
assert %{
|
||||
"to" => [participant.actor.url, participant.event.organizer_actor.url],
|
||||
"cc" => [participant2.actor.url, participant.actor.url]
|
||||
} == Audience.get_audience(participant)
|
||||
end
|
||||
|
||||
test "to a group event" do
|
||||
%Actor{} =
|
||||
group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@someone")
|
||||
|
||||
%Event{} = event = insert(:event, attributed_to: group)
|
||||
%Participant{} = participant2 = insert(:participant, event: event)
|
||||
%Participant{} = participant = insert(:participant, event: event)
|
||||
|
||||
assert %{
|
||||
"to" => [participant.actor.url, participant.event.attributed_to.url],
|
||||
"cc" => [participant2.actor.url, participant.actor.url]
|
||||
} == Audience.get_audience(participant)
|
||||
end
|
||||
end
|
||||
|
||||
describe "member" do
|
||||
test "basic" do
|
||||
%Member{} = member = insert(:member)
|
||||
|
||||
assert %{"to" => [member.parent.url, member.parent.members_url], "cc" => []} ==
|
||||
Audience.get_audience(member)
|
||||
end
|
||||
end
|
||||
|
||||
describe "actor" do
|
||||
test "basic" do
|
||||
%Actor{followers_url: followers_url} = actor = insert(:actor)
|
||||
|
||||
assert %{"to" => [@ap_public], "cc" => [followers_url]} ==
|
||||
Audience.get_audience(actor)
|
||||
end
|
||||
|
||||
test "group" do
|
||||
%Actor{followers_url: followers_url, members_url: members_url, type: :Group} =
|
||||
group = insert(:group)
|
||||
|
||||
assert %{"to" => [@ap_public], "cc" => [members_url, followers_url]} ==
|
||||
Audience.get_audience(group)
|
||||
end
|
||||
|
||||
test "with interactions" do
|
||||
%Actor{followers_url: followers_url, members_url: members_url, type: :Group} =
|
||||
group = insert(:group)
|
||||
|
||||
%Actor{} = interactor = insert(:actor)
|
||||
|
||||
insert(:share, owner_actor: group, actor: interactor)
|
||||
|
||||
assert %{
|
||||
"to" => [@ap_public],
|
||||
"cc" => [members_url, followers_url, interactor.url]
|
||||
} ==
|
||||
Audience.get_audience(group)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue