Events with only one event creator participant can't be left

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2019-02-07 17:57:49 +01:00
parent d1d3beeb35
commit dfa25e0d21
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
3 changed files with 119 additions and 7 deletions

View file

@ -582,6 +582,28 @@ defmodule Mobilizon.Events do
) )
end end
@doc """
Returns the list of organizers participants for an event.
## Examples
iex> list_organizers_participants_for_event(id)
[%Participant{role: :creator}, ...]
"""
def list_organizers_participants_for_event(id, page \\ nil, limit \\ nil) do
Repo.all(
from(
p in Participant,
join: e in Event,
on: p.event_id == e.id,
where: e.id == ^id and p.role == ^:creator,
preload: [:actor]
)
|> paginate(page, limit)
)
end
@doc """ @doc """
Gets a single participant. Gets a single participant.

View file

@ -100,12 +100,19 @@ defmodule MobilizonWeb.Resolvers.Event do
with {:is_owned, true, _} <- User.owns_actor(user, actor_id), with {:is_owned, true, _} <- User.owns_actor(user, actor_id),
{:ok, %Participant{} = participant} <- {:ok, %Participant{} = participant} <-
Mobilizon.Events.get_participant(event_id, actor_id), Mobilizon.Events.get_participant(event_id, actor_id),
{:ok, _} <- Mobilizon.Events.delete_participant(participant) do {:only_organizer, false} <-
{:only_organizer,
Mobilizon.Events.list_organizers_participants_for_event(event_id) |> length == 1},
{:ok, _} <-
Mobilizon.Events.delete_participant(participant) do
{:ok, %{event: %{id: event_id}, actor: %{id: actor_id}}} {:ok, %{event: %{id: event_id}, actor: %{id: actor_id}}}
else else
{:is_owned, false} -> {:is_owned, false} ->
{:error, "Actor id is not owned by authenticated user"} {:error, "Actor id is not owned by authenticated user"}
{:only_organizer, true} ->
{:error, "You can't leave event because you're the only event creator participant"}
{:error, :participant_not_found} -> {:error, :participant_not_found} ->
{:error, "Participant not found"} {:error, "Participant not found"}
end end

View file

@ -46,7 +46,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil assert json_response(res, 200)["errors"] == nil
assert json_response(res, 200)["data"]["joinEvent"]["role"] == 1 assert json_response(res, 200)["data"]["joinEvent"]["role"] == "participant"
assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == event.id assert json_response(res, 200)["data"]["joinEvent"]["event"]["id"] == event.id
assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == actor.id assert json_response(res, 200)["data"]["joinEvent"]["actor"]["id"] == actor.id
@ -122,6 +122,63 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
conn: conn, conn: conn,
user: user, user: user,
actor: actor actor: actor
} do
event = insert(:event, %{organizer_actor: actor})
participant = insert(:participant, %{actor: actor, event: event})
participant2 = insert(:participant, %{event: event})
mutation = """
mutation {
leaveEvent(
actor_id: #{participant.actor.id},
event_id: #{event.id}
) {
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"]["leaveEvent"]["event"]["id"] == event.id
assert json_response(res, 200)["data"]["leaveEvent"]["actor"]["id"] == participant.actor.id
query = """
{
participants(uuid: "#{event.uuid}") {
role,
actor {
preferredUsername
}
}
}
"""
res =
conn
|> get("/api", AbsintheHelpers.query_skeleton(query, "participants"))
assert json_response(res, 200)["data"]["participants"] == [
%{
"actor" => %{"preferredUsername" => participant2.actor.preferred_username},
"role" => "creator"
}
]
end
test "actor_leave_event/3 should check if the participant is the only creator", %{
conn: conn,
actor: actor,
user: user
} do } do
participant = insert(:participant, %{actor: actor}) participant = insert(:participant, %{actor: actor})
@ -146,9 +203,35 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
|> auth_conn(user) |> auth_conn(user)
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation)) |> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
assert json_response(res, 200)["errors"] == nil assert hd(json_response(res, 200)["errors"])["message"] ==
assert json_response(res, 200)["data"]["leaveEvent"]["event"]["id"] == participant.event.id "You can't leave event because you're the only event creator participant"
assert json_response(res, 200)["data"]["leaveEvent"]["actor"]["id"] == participant.actor.id
# 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 end
test "actor_leave_event/3 should check the user is logged in", %{conn: conn, actor: actor} do test "actor_leave_event/3 should check the user is logged in", %{conn: conn, actor: actor} do
@ -258,7 +341,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
assert json_response(res, 200)["data"]["participants"] == [ assert json_response(res, 200)["data"]["participants"] == [
%{ %{
"actor" => %{"preferredUsername" => context.actor.preferred_username}, "actor" => %{"preferredUsername" => context.actor.preferred_username},
"role" => 4 "role" => "creator"
} }
] ]
@ -266,7 +349,7 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
actor2 = insert(:actor) actor2 = insert(:actor)
actor3 = insert(:actor) actor3 = insert(:actor)
# This one won't get listed (as not approved) # This one won't get listed (as not approved)
participant = insert(:participant, event: event, actor: actor2, role: :not_approved) insert(:participant, event: event, actor: actor2, role: :not_approved)
# This one will (as a participant) # This one will (as a participant)
participant2 = insert(:participant, event: event, actor: actor3, role: :participant) participant2 = insert(:participant, event: event, actor: actor3, role: :participant)