forked from potsda.mn/mobilizon
Make sure people can't join an event with limited participants
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
db5b02e397
commit
bf25d22786
|
@ -762,6 +762,17 @@ defmodule Mobilizon.Events do
|
||||||
|> Repo.aggregate(:count, :id)
|
|> Repo.aggregate(:count, :id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Counts participant participants.
|
||||||
|
"""
|
||||||
|
@spec count_participant_participants(integer | String.t()) :: integer
|
||||||
|
def count_participant_participants(event_id) do
|
||||||
|
event_id
|
||||||
|
|> count_participants_query()
|
||||||
|
|> filter_participant_role()
|
||||||
|
|> Repo.aggregate(:count, :id)
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Counts unapproved participants.
|
Counts unapproved participants.
|
||||||
"""
|
"""
|
||||||
|
@ -1457,6 +1468,11 @@ defmodule Mobilizon.Events do
|
||||||
from(p in query, where: p.role not in ^[:not_approved, :rejected])
|
from(p in query, where: p.role not in ^[:not_approved, :rejected])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec filter_participant_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||||
|
defp filter_participant_role(query) do
|
||||||
|
from(p in query, where: p.role == ^:participant)
|
||||||
|
end
|
||||||
|
|
||||||
@spec filter_unapproved_role(Ecto.Query.t()) :: Ecto.Query.t()
|
@spec filter_unapproved_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||||
defp filter_unapproved_role(query) do
|
defp filter_unapproved_role(query) do
|
||||||
from(p in query, where: p.role == ^:not_approved)
|
from(p in query, where: p.role == ^:not_approved)
|
||||||
|
|
|
@ -170,6 +170,9 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||||
|> Map.put(:actor, Person.proxify_pictures(actor)) do
|
|> Map.put(:actor, Person.proxify_pictures(actor)) do
|
||||||
{:ok, participant}
|
{:ok, participant}
|
||||||
else
|
else
|
||||||
|
{:maximum_attendee_capacity, _} ->
|
||||||
|
{:error, "The event has already reached it's maximum capacity"}
|
||||||
|
|
||||||
{:has_event, _} ->
|
{:has_event, _} ->
|
||||||
{:error, "Event with this ID #{inspect(event_id)} doesn't exist"}
|
{:error, "Event with this ID #{inspect(event_id)} doesn't exist"}
|
||||||
|
|
||||||
|
|
|
@ -411,8 +411,16 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||||
|
|
||||||
def join(object, actor, local \\ true)
|
def join(object, actor, local \\ true)
|
||||||
|
|
||||||
def join(%Event{} = event, %Actor{} = actor, local) do
|
def join(%Event{options: options} = event, %Actor{} = actor, local) do
|
||||||
with role <- Mobilizon.Events.get_default_participant_role(event),
|
# TODO Refactor me for federation
|
||||||
|
with maximum_attendee_capacity <-
|
||||||
|
Map.get(options, :maximum_attendee_capacity, 2_000_000) || false,
|
||||||
|
{:maximum_attendee_capacity, true} <-
|
||||||
|
{:maximum_attendee_capacity,
|
||||||
|
!maximum_attendee_capacity ||
|
||||||
|
Mobilizon.Events.count_participant_participants(event.id) <
|
||||||
|
maximum_attendee_capacity},
|
||||||
|
role <- Mobilizon.Events.get_default_participant_role(event),
|
||||||
{:ok, %Participant{} = participant} <-
|
{:ok, %Participant{} = participant} <-
|
||||||
Mobilizon.Events.create_participant(%{
|
Mobilizon.Events.create_participant(%{
|
||||||
role: role,
|
role: role,
|
||||||
|
|
|
@ -74,6 +74,76 @@ defmodule MobilizonWeb.Resolvers.ParticipantResolverTest do
|
||||||
assert hd(json_response(res, 200)["errors"])["message"] =~ "already a participant"
|
assert hd(json_response(res, 200)["errors"])["message"] =~ "already a participant"
|
||||||
end
|
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 it's maximum capacity"
|
||||||
|
end
|
||||||
|
|
||||||
test "actor_join_event/3 should check the actor is owned by the user", %{
|
test "actor_join_event/3 should check the actor is owned by the user", %{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
user: user
|
user: user
|
||||||
|
|
|
@ -124,7 +124,8 @@ defmodule Mobilizon.Factory do
|
||||||
url: Routes.page_url(Endpoint, :event, uuid),
|
url: Routes.page_url(Endpoint, :event, uuid),
|
||||||
picture: insert(:picture),
|
picture: insert(:picture),
|
||||||
uuid: uuid,
|
uuid: uuid,
|
||||||
join_options: :free
|
join_options: :free,
|
||||||
|
options: %{}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue