test(graphql): add tests for sending private event announcements
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
5bc0593ed6
commit
681f8dcd04
|
@ -117,6 +117,14 @@ defmodule Mobilizon.Conversations do
|
||||||
|> Page.build_page(page, limit)
|
|> Page.build_page(page, limit)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_all_conversations_for_event(event_id) do
|
||||||
|
ConversationParticipant
|
||||||
|
|> join(:inner, [cp], c in Conversation, on: cp.conversation_id == c.id)
|
||||||
|
|> join(:left, [_cp, c], e in Event, on: c.event_id == e.id)
|
||||||
|
|> where([_cp, c], c.event_id == ^event_id)
|
||||||
|
|> Repo.all()
|
||||||
|
end
|
||||||
|
|
||||||
@spec list_conversation_participants_for_actor(
|
@spec list_conversation_participants_for_actor(
|
||||||
integer | String.t(),
|
integer | String.t(),
|
||||||
integer | nil,
|
integer | nil,
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|
defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|
||||||
use Mobilizon.Web.ConnCase
|
use Mobilizon.Web.ConnCase
|
||||||
use Mobilizon.Tests.Helpers
|
use Mobilizon.Tests.Helpers
|
||||||
|
use Oban.Testing, repo: Mobilizon.Storage.Repo
|
||||||
|
|
||||||
alias Mobilizon.Config
|
alias Mobilizon.Actors.Actor
|
||||||
alias Mobilizon.Events
|
alias Mobilizon.{Config, Conversations, Events}
|
||||||
alias Mobilizon.Events.{Event, EventParticipantStats, Participant}
|
alias Mobilizon.Events.{Event, EventParticipantStats, Participant}
|
||||||
alias Mobilizon.GraphQL.AbsintheHelpers
|
alias Mobilizon.GraphQL.AbsintheHelpers
|
||||||
|
alias Mobilizon.Service.Workers.LegacyNotifierBuilder
|
||||||
alias Mobilizon.Storage.Page
|
alias Mobilizon.Storage.Page
|
||||||
|
|
||||||
import Mobilizon.Factory
|
import Mobilizon.Factory
|
||||||
|
@ -1381,4 +1383,356 @@ defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
|
||||||
assert_email_sent(to: @email)
|
assert_email_sent(to: @email)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Send private messages to participants" do
|
||||||
|
@send_event_private_message_mutation """
|
||||||
|
mutation SendEventPrivateMessageMutation(
|
||||||
|
$text: String!
|
||||||
|
$actorId: ID!
|
||||||
|
$eventId: ID!
|
||||||
|
$roles: [ParticipantRoleEnum]
|
||||||
|
$language: String
|
||||||
|
) {
|
||||||
|
sendEventPrivateMessage(
|
||||||
|
text: $text
|
||||||
|
actorId: $actorId
|
||||||
|
eventId: $eventId
|
||||||
|
roles: $roles
|
||||||
|
language: $language
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
conversationParticipantId
|
||||||
|
actor {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
lastComment {
|
||||||
|
id
|
||||||
|
text
|
||||||
|
}
|
||||||
|
originComment {
|
||||||
|
id
|
||||||
|
text
|
||||||
|
}
|
||||||
|
participants {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
event {
|
||||||
|
id
|
||||||
|
uuid
|
||||||
|
title
|
||||||
|
organizerActor {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
attributedTo {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unread
|
||||||
|
insertedAt
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
setup %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
actor = insert(:actor, user: user, preferred_username: "test")
|
||||||
|
|
||||||
|
{:ok, conn: conn, actor: actor, user: user}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "Without being logged-in", %{conn: conn} do
|
||||||
|
%Actor{id: actor_id} = insert(:actor)
|
||||||
|
%Event{id: event_id} = insert(:event)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{actorId: actor_id, eventId: event_id, text: "Hello dear participants"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert hd(res["errors"])["message"] == "You need to be logged in"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "With actor not allowed", %{conn: conn, actor: actor, user: user} do
|
||||||
|
%Event{id: event_id} = insert(:event)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{actorId: actor.id, eventId: event_id, text: "Hello dear participants"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert hd(res["errors"])["message"] == "You don't have permission to do this"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "With actor as event organizer", %{conn: conn, actor: actor, user: user} do
|
||||||
|
%Event{id: event_id, title: event_title, uuid: event_uuid} =
|
||||||
|
event = insert(:event, organizer_actor: actor)
|
||||||
|
|
||||||
|
%Participant{actor_id: participant_actor_id} = insert(:participant, event: event)
|
||||||
|
%Participant{actor_id: participant_actor_id_2} = insert(:participant, event: event)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{actorId: actor.id, eventId: event_id, text: "Hello dear participants"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert res["errors"] == nil
|
||||||
|
|
||||||
|
assert res["data"]["sendEventPrivateMessage"]["lastComment"]["id"] ==
|
||||||
|
res["data"]["sendEventPrivateMessage"]["originComment"]["id"]
|
||||||
|
|
||||||
|
assert res["data"]["sendEventPrivateMessage"]["lastComment"]["text"] ==
|
||||||
|
"Hello dear participants"
|
||||||
|
|
||||||
|
participants_ids =
|
||||||
|
Enum.map(res["data"]["sendEventPrivateMessage"]["participants"], fn participant ->
|
||||||
|
String.to_integer(participant["id"])
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert length(participants_ids) == 3
|
||||||
|
|
||||||
|
assert MapSet.new(participants_ids) ==
|
||||||
|
MapSet.new([actor.id, participant_actor_id, participant_actor_id_2])
|
||||||
|
|
||||||
|
assert res["data"]["sendEventPrivateMessage"]["actor"]["id"] == to_string(actor.id)
|
||||||
|
conversation_id = res["data"]["sendEventPrivateMessage"]["id"]
|
||||||
|
|
||||||
|
all_conversation_participants_ids = Conversations.find_all_conversations_for_event(event_id)
|
||||||
|
|
||||||
|
notified_conversation_participant_ids =
|
||||||
|
all_conversation_participants_ids
|
||||||
|
|> Enum.filter(&(&1.actor_id != actor.id))
|
||||||
|
|> Enum.map(&[&1.id, &1.actor_id])
|
||||||
|
|
||||||
|
Enum.each(notified_conversation_participant_ids, fn [pa_id, participant_actor_id] ->
|
||||||
|
assert_enqueued(
|
||||||
|
worker: LegacyNotifierBuilder,
|
||||||
|
args: %{
|
||||||
|
"author_id" => actor.id,
|
||||||
|
"object_id" => to_string(conversation_id),
|
||||||
|
"object_type" => "conversation",
|
||||||
|
"op" => "legacy_notify",
|
||||||
|
"subject" => "conversation_created",
|
||||||
|
"subject_params" => %{
|
||||||
|
"conversation_id" => String.to_integer(conversation_id),
|
||||||
|
"conversation_participant_id" => pa_id,
|
||||||
|
"conversation_text" => "Hello dear participants",
|
||||||
|
"conversation_event_id" => event_id,
|
||||||
|
"conversation_event_title" => event_title,
|
||||||
|
"conversation_event_uuid" => event_uuid
|
||||||
|
},
|
||||||
|
"type" => "conversation",
|
||||||
|
"participant" => %{
|
||||||
|
"actor_id" => participant_actor_id,
|
||||||
|
"id" => pa_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
ignored_conversation_participant_id =
|
||||||
|
all_conversation_participants_ids
|
||||||
|
|> Enum.filter(&(&1.actor_id == actor.id))
|
||||||
|
|> Enum.map(& &1.id)
|
||||||
|
|
||||||
|
refute_enqueued(
|
||||||
|
worker: LegacyNotifierBuilder,
|
||||||
|
args: %{
|
||||||
|
"author_id" => actor.id,
|
||||||
|
"object_id" => to_string(conversation_id),
|
||||||
|
"object_type" => "conversation",
|
||||||
|
"op" => "legacy_notify",
|
||||||
|
"subject" => "conversation_created",
|
||||||
|
"subject_params" => %{
|
||||||
|
"conversation_id" => String.to_integer(conversation_id),
|
||||||
|
"conversation_participant_id" => ignored_conversation_participant_id,
|
||||||
|
"conversation_text" => "Hello dear participants",
|
||||||
|
"conversation_event_id" => event_id,
|
||||||
|
"conversation_event_title" => event_title,
|
||||||
|
"conversation_event_uuid" => event_uuid
|
||||||
|
},
|
||||||
|
"type" => "conversation",
|
||||||
|
"participant" => %{
|
||||||
|
"actor_id" => actor.id,
|
||||||
|
"id" => ignored_conversation_participant_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "With actor as event organizer with customized roles", %{
|
||||||
|
conn: conn,
|
||||||
|
actor: actor,
|
||||||
|
user: user
|
||||||
|
} do
|
||||||
|
%Event{id: event_id, title: event_title, uuid: event_uuid} =
|
||||||
|
event = insert(:event, organizer_actor: actor)
|
||||||
|
|
||||||
|
%Participant{actor_id: _participant_actor_id} = insert(:participant, event: event)
|
||||||
|
|
||||||
|
%Participant{actor_id: participant_actor_id_2} =
|
||||||
|
insert(:participant, event: event, role: :not_approved)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{
|
||||||
|
actorId: actor.id,
|
||||||
|
eventId: event_id,
|
||||||
|
text: "Hello dear participants",
|
||||||
|
roles: ["NOT_APPROVED"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert res["errors"] == nil
|
||||||
|
|
||||||
|
assert res["data"]["sendEventPrivateMessage"]["lastComment"]["id"] ==
|
||||||
|
res["data"]["sendEventPrivateMessage"]["originComment"]["id"]
|
||||||
|
|
||||||
|
assert res["data"]["sendEventPrivateMessage"]["lastComment"]["text"] ==
|
||||||
|
"Hello dear participants"
|
||||||
|
|
||||||
|
participants_ids =
|
||||||
|
Enum.map(res["data"]["sendEventPrivateMessage"]["participants"], fn participant ->
|
||||||
|
String.to_integer(participant["id"])
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert length(participants_ids) == 2
|
||||||
|
|
||||||
|
assert MapSet.new(participants_ids) ==
|
||||||
|
MapSet.new([actor.id, participant_actor_id_2])
|
||||||
|
|
||||||
|
conversation_id = res["data"]["sendEventPrivateMessage"]["id"]
|
||||||
|
|
||||||
|
all_conversation_participants_ids = Conversations.find_all_conversations_for_event(event_id)
|
||||||
|
|
||||||
|
notified_conversation_participant_ids =
|
||||||
|
all_conversation_participants_ids
|
||||||
|
|> Enum.filter(&(&1.actor_id == participant_actor_id_2))
|
||||||
|
|> Enum.map(&[&1.id, &1.actor_id])
|
||||||
|
|
||||||
|
Enum.each(notified_conversation_participant_ids, fn [pa_id, participant_actor_id] ->
|
||||||
|
assert_enqueued(
|
||||||
|
worker: LegacyNotifierBuilder,
|
||||||
|
args: %{
|
||||||
|
"author_id" => actor.id,
|
||||||
|
"object_id" => to_string(conversation_id),
|
||||||
|
"object_type" => "conversation",
|
||||||
|
"op" => "legacy_notify",
|
||||||
|
"subject" => "conversation_created",
|
||||||
|
"subject_params" => %{
|
||||||
|
"conversation_id" => String.to_integer(conversation_id),
|
||||||
|
"conversation_participant_id" => pa_id,
|
||||||
|
"conversation_text" => "Hello dear participants",
|
||||||
|
"conversation_event_id" => event_id,
|
||||||
|
"conversation_event_title" => event_title,
|
||||||
|
"conversation_event_uuid" => event_uuid
|
||||||
|
},
|
||||||
|
"type" => "conversation",
|
||||||
|
"participant" => %{
|
||||||
|
"actor_id" => participant_actor_id,
|
||||||
|
"id" => pa_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
ignored_conversation_participant_id =
|
||||||
|
all_conversation_participants_ids
|
||||||
|
|> Enum.filter(&(&1.actor_id != participant_actor_id_2))
|
||||||
|
|> Enum.map(&[&1.id, &1.actor_id])
|
||||||
|
|
||||||
|
Enum.each(ignored_conversation_participant_id, fn [pa_id, participant_actor_id] ->
|
||||||
|
refute_enqueued(
|
||||||
|
worker: LegacyNotifierBuilder,
|
||||||
|
args: %{
|
||||||
|
"author_id" => participant_actor_id,
|
||||||
|
"object_id" => to_string(conversation_id),
|
||||||
|
"object_type" => "conversation",
|
||||||
|
"op" => "legacy_notify",
|
||||||
|
"subject" => "conversation_created",
|
||||||
|
"subject_params" => %{
|
||||||
|
"conversation_id" => String.to_integer(conversation_id),
|
||||||
|
"conversation_participant_id" => pa_id,
|
||||||
|
"conversation_text" => "Hello dear participants",
|
||||||
|
"conversation_event_id" => event_id,
|
||||||
|
"conversation_event_title" => event_title,
|
||||||
|
"conversation_event_uuid" => event_uuid
|
||||||
|
},
|
||||||
|
"type" => "conversation",
|
||||||
|
"participant" => %{
|
||||||
|
"actor_id" => participant_actor_id,
|
||||||
|
"id" => pa_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "With actor as member of group event organizer", %{conn: conn, actor: actor, user: user} do
|
||||||
|
%Actor{id: group_id} = group = insert(:group)
|
||||||
|
insert(:member, parent: group, actor: actor, role: :moderator)
|
||||||
|
%Event{id: event_id} = event = insert(:event, organizer_actor: actor, attributed_to: group)
|
||||||
|
%Participant{actor_id: participant_actor_id} = insert(:participant, event: event)
|
||||||
|
%Participant{actor_id: participant_actor_id_2} = insert(:participant, event: event)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{actorId: group_id, eventId: event_id, text: "Hello dear participants"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert res["errors"] == nil
|
||||||
|
|
||||||
|
participants_ids =
|
||||||
|
Enum.map(res["data"]["sendEventPrivateMessage"]["participants"], fn participant ->
|
||||||
|
String.to_integer(participant["id"])
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert MapSet.new(participants_ids) ==
|
||||||
|
MapSet.new([group_id, participant_actor_id, participant_actor_id_2])
|
||||||
|
|
||||||
|
assert res["data"]["sendEventPrivateMessage"]["actor"]["id"] == to_string(group_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "With event not found", %{conn: conn, actor: actor, user: user} do
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{actorId: actor.id, eventId: "5019438457", text: "Hello dear participants"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert hd(res["errors"])["message"] ==
|
||||||
|
"Event not found"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "With no participants matching the audience", %{conn: conn, actor: actor, user: user} do
|
||||||
|
%Event{id: event_id} = insert(:event, organizer_actor: actor)
|
||||||
|
|
||||||
|
res =
|
||||||
|
conn
|
||||||
|
|> auth_conn(user)
|
||||||
|
|> AbsintheHelpers.graphql_query(
|
||||||
|
query: @send_event_private_message_mutation,
|
||||||
|
variables: %{actorId: actor.id, eventId: event_id, text: "Hello dear participants"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert hd(res["errors"])["message"] ==
|
||||||
|
"There are no participants matching the audience you've selected."
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue