-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add application section recurring reservation mass cancel endpoint
- Loading branch information
1 parent
8f4d410
commit 8cee54c
Showing
9 changed files
with
460 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
217 changes: 217 additions & 0 deletions
217
tests/test_graphql_api/test_recurring_reservation/test_cancel_series.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
import datetime | ||
|
||
import pytest | ||
from freezegun import freeze_time | ||
|
||
from tests.factories import ( | ||
AllocatedTimeSlotFactory, | ||
ApplicationRoundFactory, | ||
ReservationCancelReasonFactory, | ||
UserFactory, | ||
) | ||
from tilavarauspalvelu.enums import ReservationStateChoice, ReservationTypeChoice | ||
from utils.date_utils import local_date, local_datetime | ||
|
||
from .helpers import CANCEL_SECTION_SERIES_MUTATION, create_reservation_series | ||
|
||
# Applied to all tests | ||
pytestmark = [ | ||
pytest.mark.django_db, | ||
] | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__cancel_whole_remaining(graphql): | ||
reason = ReservationCancelReasonFactory.create() | ||
user = UserFactory.create() | ||
|
||
reservation_series = create_reservation_series( | ||
user=user, | ||
reservations__type=ReservationTypeChoice.SEASONAL, | ||
reservations__price=0, | ||
reservation_unit__cancellation_rule__can_be_cancelled_time_before=datetime.timedelta(), | ||
) | ||
|
||
application_round = ApplicationRoundFactory.create_in_status_results_sent() | ||
allocation = AllocatedTimeSlotFactory.create( | ||
reservation_unit_option__application_section__application__user=user, | ||
reservation_unit_option__application_section__application__application_round=application_round, | ||
) | ||
section = allocation.reservation_unit_option.application_section | ||
|
||
reservation_series.allocated_time_slot = allocation | ||
reservation_series.save() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.force_login(user) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.has_errors is False, response.errors | ||
|
||
assert response.first_query_object == {"cancelled": 5, "future": 5} | ||
assert reservation_series.reservations.count() == 9 | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__not_seasonal_type(graphql): | ||
reason = ReservationCancelReasonFactory.create() | ||
user = UserFactory.create() | ||
|
||
reservation_series = create_reservation_series( | ||
user=user, | ||
reservations__type=ReservationTypeChoice.NORMAL, | ||
reservations__price=0, | ||
reservation_unit__cancellation_rule__can_be_cancelled_time_before=datetime.timedelta(), | ||
) | ||
|
||
application_round = ApplicationRoundFactory.create_in_status_results_sent() | ||
allocation = AllocatedTimeSlotFactory.create( | ||
reservation_unit_option__application_section__application__user=user, | ||
reservation_unit_option__application_section__application__application_round=application_round, | ||
) | ||
section = allocation.reservation_unit_option.application_section | ||
|
||
reservation_series.allocated_time_slot = allocation | ||
reservation_series.save() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.force_login(user) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.has_errors is False, response.errors | ||
|
||
assert response.first_query_object == {"cancelled": 0, "future": 5} | ||
assert reservation_series.reservations.count() == 9 | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__paid(graphql): | ||
reason = ReservationCancelReasonFactory.create() | ||
user = UserFactory.create() | ||
|
||
reservation_series = create_reservation_series( | ||
user=user, | ||
reservations__type=ReservationTypeChoice.SEASONAL, | ||
reservations__price=10, | ||
reservation_unit__cancellation_rule__can_be_cancelled_time_before=datetime.timedelta(), | ||
) | ||
|
||
application_round = ApplicationRoundFactory.create_in_status_results_sent() | ||
allocation = AllocatedTimeSlotFactory.create( | ||
reservation_unit_option__application_section__application__user=user, | ||
reservation_unit_option__application_section__application__application_round=application_round, | ||
) | ||
section = allocation.reservation_unit_option.application_section | ||
|
||
reservation_series.allocated_time_slot = allocation | ||
reservation_series.save() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.force_login(user) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.has_errors is False, response.errors | ||
|
||
assert response.first_query_object == {"cancelled": 0, "future": 5} | ||
assert reservation_series.reservations.count() == 9 | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__not_confirmed_state(graphql): | ||
reason = ReservationCancelReasonFactory.create() | ||
user = UserFactory.create() | ||
|
||
reservation_series = create_reservation_series( | ||
user=user, | ||
reservations__type=ReservationTypeChoice.SEASONAL, | ||
reservations__state=ReservationTypeChoice.BEHALF, | ||
reservations__price=0, | ||
reservation_unit__cancellation_rule__can_be_cancelled_time_before=datetime.timedelta(), | ||
) | ||
|
||
application_round = ApplicationRoundFactory.create_in_status_results_sent() | ||
allocation = AllocatedTimeSlotFactory.create( | ||
reservation_unit_option__application_section__application__user=user, | ||
reservation_unit_option__application_section__application__application_round=application_round, | ||
) | ||
section = allocation.reservation_unit_option.application_section | ||
|
||
reservation_series.allocated_time_slot = allocation | ||
reservation_series.save() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.force_login(user) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.has_errors is False, response.errors | ||
|
||
assert response.first_query_object == {"cancelled": 0, "future": 5} | ||
assert reservation_series.reservations.count() == 9 | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__cancellation_rule(graphql): | ||
reason = ReservationCancelReasonFactory.create() | ||
user = UserFactory.create() | ||
|
||
reservation_series = create_reservation_series( | ||
user=user, | ||
reservations__type=ReservationTypeChoice.SEASONAL, | ||
reservations__price=0, | ||
reservation_unit__cancellation_rule__can_be_cancelled_time_before=datetime.timedelta(days=1), | ||
) | ||
|
||
application_round = ApplicationRoundFactory.create_in_status_results_sent() | ||
allocation = AllocatedTimeSlotFactory.create( | ||
reservation_unit_option__application_section__application__user=user, | ||
reservation_unit_option__application_section__application__application_round=application_round, | ||
) | ||
section = allocation.reservation_unit_option.application_section | ||
|
||
reservation_series.allocated_time_slot = allocation | ||
reservation_series.save() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.force_login(user) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.has_errors is False, response.errors | ||
|
||
# First future reservation is not cancelled since it's too soon according to the cancellation rule. | ||
assert response.first_query_object == {"cancelled": 4, "future": 5} | ||
assert reservation_series.reservations.count() == 9 | ||
|
||
future_reservations = reservation_series.reservations.filter(begin__date__gte=local_date()).iterator() | ||
|
||
reservation_1 = next(future_reservations) | ||
assert reservation_1.begin.date() == datetime.date(2024, 1, 1) | ||
assert reservation_1.state == ReservationStateChoice.CONFIRMED | ||
|
||
reservation_2 = next(future_reservations) | ||
assert reservation_2.begin.date() == datetime.date(2024, 1, 8) | ||
assert reservation_2.state == ReservationStateChoice.CANCELLED |
92 changes: 92 additions & 0 deletions
92
tests/test_graphql_api/test_recurring_reservation/test_cancel_series_permissions.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import datetime | ||
|
||
import pytest | ||
from freezegun import freeze_time | ||
|
||
from tests.factories import ( | ||
AllocatedTimeSlotFactory, | ||
ApplicationRoundFactory, | ||
ReservationCancelReasonFactory, | ||
UserFactory, | ||
) | ||
from tilavarauspalvelu.enums import ReservationTypeChoice, UserRoleChoice | ||
from tilavarauspalvelu.models import ApplicationSection, ReservationCancelReason, User | ||
from utils.date_utils import local_datetime | ||
|
||
from .helpers import CANCEL_SECTION_SERIES_MUTATION, create_reservation_series | ||
|
||
# Applied to all tests | ||
pytestmark = [ | ||
pytest.mark.django_db, | ||
] | ||
|
||
|
||
def create_data_for_cancellation() -> tuple[ReservationCancelReason, ApplicationSection, User]: | ||
reason = ReservationCancelReasonFactory.create() | ||
user = UserFactory.create() | ||
|
||
reservation_series = create_reservation_series( | ||
user=user, | ||
reservations__type=ReservationTypeChoice.SEASONAL, | ||
reservations__price=0, | ||
reservation_unit__cancellation_rule__can_be_cancelled_time_before=datetime.timedelta(), | ||
) | ||
|
||
application_round = ApplicationRoundFactory.create_in_status_results_sent() | ||
allocation = AllocatedTimeSlotFactory.create( | ||
reservation_unit_option__application_section__application__user=user, | ||
reservation_unit_option__application_section__application__application_round=application_round, | ||
) | ||
section = allocation.reservation_unit_option.application_section | ||
|
||
reservation_series.allocated_time_slot = allocation | ||
reservation_series.save() | ||
return reason, section, user | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__applicant(graphql): | ||
reason, section, user = create_data_for_cancellation() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.force_login(user) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.has_errors is False, response.errors | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__superuser(graphql): | ||
reason, section, _ = create_data_for_cancellation() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.login_with_superuser() | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.error_message() == "No permission to update." | ||
|
||
|
||
@freeze_time(local_datetime(year=2024, month=1, day=1)) | ||
def test_recurring_reservations__cancel_section_series__general_admin(graphql): | ||
reason, section, _ = create_data_for_cancellation() | ||
|
||
data = { | ||
"pk": section.pk, | ||
"cancelReason": reason.pk, | ||
"cancelDetails": "Cancellation details", | ||
} | ||
|
||
graphql.login_user_with_role(UserRoleChoice.ADMIN) | ||
response = graphql(CANCEL_SECTION_SERIES_MUTATION, input_data=data) | ||
|
||
assert response.error_message() == "No permission to update." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.