mobilizon/test/graphql/resolvers/participant_test.exs

1387 lines
42 KiB
Elixir

defmodule Mobilizon.GraphQL.Resolvers.ParticipantTest do
use Mobilizon.Web.ConnCase
use Bamboo.Test
use Mobilizon.Tests.Helpers
alias Mobilizon.Config
alias Mobilizon.Events
alias Mobilizon.Events.{Event, EventParticipantStats, Participant}
alias Mobilizon.GraphQL.AbsintheHelpers
alias Mobilizon.Storage.Page
alias Mobilizon.Web.Email
import Mobilizon.Factory
@event %{
description: "some body",
title: "some title",
begins_on:
DateTime.utc_now()
|> DateTime.truncate(:second),
uuid: "b5126423-f1af-43e4-a923-002a03003ba4",
url: "some url",
category: "meeting",
options: %{}
}
setup %{conn: conn} do
user = insert(:user)
actor = insert(:actor, user: user, preferred_username: "test")
{:ok, conn: conn, actor: actor, user: user}
end
describe "Participant Resolver" do
test "actor_join_event/3 should create a participant", %{conn: conn, user: user, actor: actor} do
event = insert(:event)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "PARTICIPANT"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "already a participant"
end
test "actor_join_event/3 doesn't work if the event already has too much participants", %{
conn: conn,
actor: actor
} do
event = insert(:event, options: %{maximum_attendee_capacity: 2})
insert(:participant, event: event, actor: actor, role: :creator)
insert(:participant, event: event, role: :participant)
insert(:participant, event: event, role: :not_approved)
insert(:participant, event: event, role: :rejected)
user_participant = insert(:user)
actor_participant = insert(:actor, user: user_participant)
mutation = """
mutation {
joinEvent(
actor_id: #{actor_participant.id},
event_id: #{event.id}
) {
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_participant)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "PARTICIPANT"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] ==
to_string(actor_participant.id)
user_participant_2 = insert(:user)
actor_participant_2 = insert(:actor, user: user_participant_2)
mutation = """
mutation {
joinEvent(
actor_id: #{actor_participant_2.id},
event_id: #{event.id}
) {
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_participant_2)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"The event has already reached its maximum capacity"
end
test "actor_join_event/3 should check the actor is owned by the user", %{
conn: conn,
user: user
} do
event = insert(:event)
mutation = """
mutation {
joinEvent(
actor_id: 1042,
event_id: #{event.id}
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "actor_join_event/3 should check the event exists", %{
conn: conn,
user: user,
actor: actor
} do
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: 1042
) {
role
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Event with this ID \"1042\" doesn't exist"
end
@person_participations """
query PersonParticipations($actorId: ID!, $eventId: ID) {
person(id: $actorId) {
participations(eventId: $eventId) {
total,
elements {
event {
uuid,
title
},
role
}
}
}
}
"""
test "actor_leave_event/3 should delete a participant from an event", %{
conn: conn,
user: user,
actor: actor
} do
event =
insert(:event, %{organizer_actor: actor, participant_stats: %{creator: 1, participant: 1}})
insert(:participant, %{actor: actor, event: event, role: :creator})
user2 = insert(:user)
actor2 = insert(:actor, user: user2)
participant2 = insert(:participant, %{event: event, actor: actor2, role: :participant})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant2.actor.id},
event_id: #{event.id}
) {
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user2)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["leaveEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["leaveEvent"]["actor"]["id"] ==
to_string(participant2.actor.id)
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: @person_participations,
variables: %{actorId: actor.id, eventId: event.id}
)
assert res["data"]["person"]["participations"]["elements"] == [
%{
"event" => %{
"uuid" => event.uuid,
"title" => event.title
},
"role" => "CREATOR"
}
]
res =
conn
|> auth_conn(user2)
|> AbsintheHelpers.graphql_query(
query: @person_participations,
variables: %{actorId: actor2.id, eventId: event.id}
)
assert res["data"]["person"]["participations"]["elements"] == []
end
test "actor_leave_event/3 should check if the participant is the only creator", %{
conn: conn,
actor: actor,
user: user
} do
participant = insert(:participant, %{actor: actor})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"You can't leave event because you're the only event creator participant"
# If we have a second participant but not an event creator
insert(:participant, %{event: participant.event, role: :participant})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"You can't leave event because you're the only event creator participant"
end
test "actor_leave_event/3 should check the user is logged in", %{conn: conn, actor: actor} do
participant = insert(:participant, %{actor: actor})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "logged-in"
end
test "actor_leave_event/3 should check the actor is owned by the user", %{
conn: conn,
user: user
} do
participant = insert(:participant)
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{participant.event.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "not owned"
end
test "actor_leave_event/3 should check the participant exists", %{
conn: conn,
user: user,
actor: actor
} do
event = insert(:event)
participant = insert(:participant, %{actor: actor})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{event.id}
) {
actor {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] =~ "Participant not found"
end
test "list_participants_for_event/3 returns participants for an event", %{
conn: conn,
actor: actor,
user: user
} do
event =
@event
|> Map.put(:organizer_actor_id, actor.id)
{:ok, event} = Events.create_event(event)
query = """
{
event(uuid: "#{event.uuid}") {
participants(roles: "participant,moderator,administrator,creator", actor_id: "#{
actor.id
}") {
elements {
role,
actor {
preferredUsername
}
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["event"]["participants"]["elements"] == [
%{
"actor" => %{
"preferredUsername" => actor.preferred_username
},
"role" => "CREATOR"
}
]
# Adding two participants
actor2 = insert(:actor)
actor3 = insert(:actor)
# This one won't get listed (as not approved)
insert(:participant, event: event, actor: actor2, role: :not_approved)
# This one will (as a participant)
participant2 = insert(:participant, event: event, actor: actor3, role: :participant)
query = """
query EventParticipants($uuid: UUID!, $actorId: ID, $roles: String, $page: Int, $limit: Int) {
event(uuid: $uuid) {
participants(page: $page, limit: $limit, roles: $roles, actorId: $actorId) {
total,
elements {
role,
actor {
preferredUsername
}
}
}
}
}
"""
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: query,
variables: %{
uuid: event.uuid,
actorId: actor.id,
roles: "participant,moderator,administrator,creator",
page: 1,
limit: 2
}
)
assert is_nil(res["errors"])
sorted_participants =
res["data"]["event"]["participants"]["elements"]
|> Enum.filter(&(&1["role"] == "CREATOR"))
assert sorted_participants == [
%{
"actor" => %{
"preferredUsername" => actor.preferred_username
},
"role" => "CREATOR"
}
]
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: query,
variables: %{
uuid: event.uuid,
actorId: actor.id,
roles: "participant,moderator,administrator,creator",
page: 1,
limit: 2
}
)
assert is_nil(res["errors"])
sorted_participants =
res["data"]["event"]["participants"]["elements"]
|> Enum.filter(&(&1["role"] == "PARTICIPANT"))
assert sorted_participants == [
%{
"actor" => %{
"preferredUsername" => participant2.actor.preferred_username
},
"role" => "PARTICIPANT"
}
]
end
test "stats_participants_for_event/3 give the number of (un)approved participants", %{
conn: conn,
actor: actor,
user: user
} do
event =
@event
|> Map.put(:organizer_actor_id, actor.id)
{:ok, event} = Events.create_event(event)
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
participantStats {
going,
notApproved,
rejected
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
assert json_response(res, 200)["data"]["event"]["participantStats"]["going"] == 1
assert json_response(res, 200)["data"]["event"]["participantStats"]["notApproved"] == 0
assert json_response(res, 200)["data"]["event"]["participantStats"]["rejected"] == 0
moderator = insert(:actor)
Events.create_participant(%{
role: :moderator,
event_id: event.id,
actor_id: moderator.id
})
not_approved = insert(:actor)
Events.create_participant(%{
role: :not_approved,
event_id: event.id,
actor_id: not_approved.id
})
rejected = insert(:actor)
Events.create_participant(%{
role: :rejected,
event_id: event.id,
actor_id: rejected.id
})
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
participantStats {
going,
notApproved,
rejected
}
}
}
"""
res =
conn
|> auth_conn(user)
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert json_response(res, 200)["data"]["event"]["uuid"] == to_string(event.uuid)
assert json_response(res, 200)["data"]["event"]["participantStats"]["going"] == 2
assert json_response(res, 200)["data"]["event"]["participantStats"]["notApproved"] == 1
assert json_response(res, 200)["data"]["event"]["participantStats"]["rejected"] == 1
query = """
{
event(uuid: "#{event.uuid}") {
uuid,
participantStats {
going,
notApproved,
rejected
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "event"))
assert is_nil(json_response(res, 200)["errors"])
assert json_response(res, 200)["data"]["event"]["going"] == nil
end
end
describe "Participation role status update" do
test "update_participation/3", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted, organizer_actor: actor_creator)
insert(:participant, event: event, actor: actor_creator, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation(
id: "#{participation_id}",
role: PARTICIPANT,
moderator_actor_id: #{actor_creator.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["updateParticipation"]["role"] == "PARTICIPANT"
assert json_response(res, 200)["data"]["updateParticipation"]["event"]["id"] ==
to_string(event.id)
assert json_response(res, 200)["data"]["updateParticipation"]["actor"]["id"] ==
to_string(actor.id)
participation = Events.get_participant(participation_id)
assert_delivered_email(Email.Participation.participation_updated(user, participation))
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Participant already has role participant"
end
test "accept_participation/3 with bad parameters", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted)
insert(:participant, event: event, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation (
id: "#{participation_id}",
role: PARTICIPANT,
moderator_actor_id: #{actor_creator.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Provided moderator actor ID doesn't have permission on this event"
end
end
describe "reject participation" do
test "reject_participation/3", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted, organizer_actor: actor_creator)
insert(:participant, event: event, actor: actor_creator, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation(
id: "#{participation_id}",
role: REJECTED,
moderator_actor_id: #{actor_creator.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["updateParticipation"]["id"] == participation_id
assert json_response(res, 200)["data"]["updateParticipation"]["event"]["id"] ==
to_string(event.id)
assert json_response(res, 200)["data"]["updateParticipation"]["actor"]["id"] ==
to_string(actor.id)
participation = Events.get_participant(participation_id)
assert_delivered_email(Email.Participation.participation_updated(user, participation))
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Participant already has role rejected"
end
test "reject_participation/3 with bad parameters", %{conn: conn, actor: actor, user: user} do
user_creator = insert(:user)
actor_creator = insert(:actor, user: user_creator)
event = insert(:event, join_options: :restricted)
insert(:participant, event: event, role: :creator)
mutation = """
mutation {
joinEvent(
actor_id: #{actor.id},
event_id: #{event.id}
) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == "NOT_APPROVED"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == to_string(actor.id)
participation_id = json_response(res, 200)["data"]["joinEvent"]["id"]
mutation = """
mutation {
updateParticipation (
id: "#{participation_id}",
role: REJECTED,
moderator_actor_id: #{actor_creator.id}
) {
id,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user_creator)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert hd(json_response(res, 200)["errors"])["message"] ==
"Provided moderator actor ID doesn't have permission on this event"
end
end
describe "Participate with anonymous user" do
@email "test@test.tld"
@mutation """
mutation JoinEvent($actorId: ID!, $eventId: ID!, $email: String) {
joinEvent(
actorId: $actorId,
eventId: $eventId,
email: $email
) {
role,
actor {
id
},
event {
id
}
}
}
"""
@confirmation_mutation """
mutation ConfirmParticipation($confirmationToken: String!) {
confirmParticipation(confirmationToken: $confirmationToken) {
role,
actor {
id
},
event {
id
}
}
}
"""
@cancel_participation_mutation """
mutation LeaveEvent($actorId: ID!, $eventId: ID!, $token: String) {
leaveEvent(
actorId: $actorId,
eventId: $eventId,
token: $token
) {
id
}
}
"""
clear_config([:anonymous, :participation])
setup %{conn: conn, actor: actor, user: user} do
Mobilizon.Config.clear_config_cache()
anonymous_actor_id = Config.anonymous_actor_id()
{:ok, conn: conn, actor: actor, user: user, anonymous_actor_id: anonymous_actor_id}
end
test "I can't participate if anonymous participation is enabled on the server but disabled for this event",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: false})
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], false)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id}
)
assert hd(res["errors"])["message"] == "Anonymous participation is not enabled"
end
test "I can't participate if anonymous participation is enabled on the server and enabled for the event but the event is remote",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: true}, local: false)
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], false)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id}
)
assert hd(res["errors"])["message"] == "Anonymous participation is not enabled"
end
test "I can't participate without being logged in when using anonymous user and providing no email when required",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: true})
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], false)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id}
)
assert hd(res["errors"])["message"] == "A valid email is required by your instance"
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: "bad_email"}
)
assert hd(res["errors"])["message"] == "A valid email is required by your instance"
end
test "I can participate without being logged in when using anonymous user when providing email",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: true})
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], false)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert res["errors"] == nil
assert res["data"]["joinEvent"]["role"] == "PARTICIPANT"
assert res["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert res["data"]["joinEvent"]["actor"]["id"] == to_string(actor_id)
%Participant{} =
participant = event.id |> Events.list_participants_for_event() |> Map.get(:elements) |> hd
assert participant.metadata.email == @email
# When confirmation_required is false, participant has already the participant role
assert participant.role == :participant
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert hd(res["errors"])["message"] == "You are already a participant of this event"
end
test "Participating without being logged in when using anonymous user and providing email sends a confirmation email",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: true})
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], true)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert res["errors"] == nil
# Not approved until email confirmation
assert res["data"]["joinEvent"]["role"] == "NOT_CONFIRMED"
assert res["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert res["data"]["joinEvent"]["actor"]["id"] == to_string(actor_id)
assert %Participant{
metadata: %{confirmation_token: confirmation_token},
role: :not_confirmed
} =
participant =
event.id |> Events.list_participants_for_event([]) |> Map.get(:elements) |> hd()
# hack to avoid preloading event in participant
participant = Map.put(participant, :event, event)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert hd(res["errors"])["message"] == "You are already a participant of this event"
assert_delivered_email(
Email.Participation.anonymous_participation_confirmation(@email, participant)
)
conn
|> AbsintheHelpers.graphql_query(
query: @confirmation_mutation,
variables: %{confirmationToken: confirmation_token}
)
assert %Participant{role: :participant} =
event.id |> Events.list_participants_for_event() |> Map.get(:elements) |> hd()
end
test "I can participate anonymously and and confirm my participation with bad token",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: true})
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], true)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert res["errors"] == nil
assert res["data"]["joinEvent"]["role"] == "NOT_CONFIRMED"
assert res["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert res["data"]["joinEvent"]["actor"]["id"] == to_string(actor_id)
%Participant{} =
participant =
event.id |> Events.list_participants_for_event([]) |> Map.get(:elements) |> hd
assert participant.metadata.email == @email
# When confirmation_required is false, participant has already the participant role
assert participant.role == :not_confirmed
res =
conn
|> AbsintheHelpers.graphql_query(
query: @confirmation_mutation,
variables: %{confirmationToken: "bad token"}
)
assert hd(res["errors"])["message"] == "This token is invalid"
assert %Participant{role: :not_confirmed} =
event.id |> Events.list_participants_for_event([]) |> Map.get(:elements) |> hd()
end
test "I can participate anonymously but change my mind and cancel my participation",
%{conn: conn, anonymous_actor_id: actor_id} do
event = insert(:event, options: %{anonymous_participation: true})
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], true)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert res["errors"] == nil
assert res["data"]["joinEvent"]["role"] == "NOT_CONFIRMED"
assert res["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert res["data"]["joinEvent"]["actor"]["id"] == to_string(actor_id)
{:ok, %Event{participant_stats: %{not_confirmed: 1}}} = Events.get_event(event.id)
%Participant{} =
participant =
event.id |> Events.list_participants_for_event([]) |> Map.get(:elements) |> hd
assert participant.metadata.email == @email
# When confirmation_required is false, participant has already the participant role
assert participant.role == :not_confirmed
res =
conn
|> AbsintheHelpers.graphql_query(
query: @cancel_participation_mutation,
variables: %{
actorId: actor_id,
eventId: event.id,
token: "bad token"
}
)
assert hd(res["errors"])["message"] == "Participant not found"
assert %Participant{
id: participant_id,
role: :not_confirmed,
metadata: %{cancellation_token: cancellation_token}
} = event.id |> Events.list_participants_for_event([]) |> Map.get(:elements) |> hd()
res =
conn
|> AbsintheHelpers.graphql_query(
query: @cancel_participation_mutation,
variables: %{
actorId: actor_id,
eventId: event.id,
token: cancellation_token
}
)
assert res["data"]["leaveEvent"]["id"] == participant_id
{:ok, %Event{participant_stats: %{not_confirmed: 0}}} = Events.get_event(event.id)
assert Events.list_participants_for_event(event.id, []) == %Page{elements: [], total: 0}
end
test "I can participate anonymously, confirm my participation and then be confirmed by the organizer",
%{conn: conn, anonymous_actor_id: actor_id, actor: event_creator_actor, user: user} do
event =
insert(:event,
options: %{anonymous_participation: true},
join_options: :restricted,
organizer_actor: event_creator_actor,
participant_stats: %{creator: 1}
)
insert(:participant, event: event, actor: event_creator_actor, role: :creator)
Config.put([:anonymous, :participation, :allowed], true)
Config.put([:anonymous, :participation, :validation, :email, :enabled], true)
Config.put([:anonymous, :participation, :validation, :email, :confirmation_required], true)
assert {:ok,
%Event{
participant_stats: %EventParticipantStats{
not_confirmed: 0,
not_approved: 0,
creator: 1,
participant: 0
}
}} = Events.get_event(event.id)
res =
conn
|> AbsintheHelpers.graphql_query(
query: @mutation,
variables: %{actorId: actor_id, eventId: event.id, email: @email}
)
assert res["errors"] == nil
assert res["data"]["joinEvent"]["role"] == "NOT_CONFIRMED"
assert res["data"]["joinEvent"]["event"]["id"] == to_string(event.id)
assert res["data"]["joinEvent"]["actor"]["id"] == to_string(actor_id)
assert {:ok,
%Event{
participant_stats: %EventParticipantStats{
not_confirmed: 1,
not_approved: 0,
creator: 1,
participant: 0
}
}} = Events.get_event(event.id)
assert %Participant{
role: :not_confirmed,
metadata: %{confirmation_token: confirmation_token, email: @email}
} =
event.id
|> Events.list_participants_for_event([:not_confirmed])
|> Map.get(:elements)
|> hd
conn
|> AbsintheHelpers.graphql_query(
query: @confirmation_mutation,
variables: %{confirmationToken: confirmation_token}
)
assert {:ok,
%Event{
participant_stats: %EventParticipantStats{
not_confirmed: 0,
not_approved: 1,
creator: 1,
participant: 0
}
}} = Events.get_event(event.id)
assert %Participant{role: :not_approved, id: participant_id} =
event.id
|> Events.list_participants_for_event([:not_approved])
|> Map.get(:elements)
|> hd
update_participation_mutation = """
mutation UpdateParticipation($participantId: ID!, $role: ParticipantRoleEnum!, $moderatorActorId: ID!) {
updateParticipation(id: $participantId, role: $role, moderatorActorId: $moderatorActorId) {
id,
role,
actor {
id
},
event {
id
}
}
}
"""
res =
conn
|> auth_conn(user)
|> AbsintheHelpers.graphql_query(
query: update_participation_mutation,
variables: %{
participantId: participant_id,
role: "PARTICIPANT",
moderatorActorId: event_creator_actor.id
}
)
assert res["errors"] == nil
assert %Participant{role: :participant} =
event.id
|> Events.list_participants_for_event([:participant])
|> Map.get(:elements)
|> hd
assert {:ok,
%Event{
participant_stats: %EventParticipantStats{
not_confirmed: 0,
not_approved: 0,
creator: 1,
participant: 1
}
}} = Events.get_event(event.id)
participant = Events.get_participant(participant_id)
assert_delivered_email(Email.Participation.participation_updated(@email, participant))
end
end
end