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 test "reply to a remote comment" do %Actor{} = remote_actor = insert(:actor, domain: "somewhere.else", url: "https://somewhere.else/@someone") %Actor{} = remote_group = insert(:group, domain: "somewhere.else", url: "https://somewhere.else/@somegroup") %Event{} = event = insert(:event, local: false, organizer_actor: remote_actor, attributed_to: remote_group) %Comment{} = comment = insert(:comment, event: event) assert %{ "cc" => [comment.actor.followers_url, comment.event.attributed_to.followers_url], "to" => [ @ap_public, comment.event.organizer_actor.url, comment.event.attributed_to.members_url ] } == 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] } == 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" => [group.followers_url, group.members_url, participant2.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