Skip to content

Commit

Permalink
Add validation for Seasonal Reservation cancellation endpoint
Browse files Browse the repository at this point in the history
refs. TILA-3669
  • Loading branch information
ranta authored and matti-lamppu committed Nov 21, 2024
1 parent edfcd61 commit 9acf72b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
37 changes: 34 additions & 3 deletions tests/test_graphql_api/test_reservation/test_cancel.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from tests.factories import PaymentOrderFactory, ReservationFactory
from tests.helpers import patch_method
from tilavarauspalvelu.enums import OrderStatus, PaymentType, ReservationStateChoice
from tilavarauspalvelu.enums import OrderStatus, PaymentType, ReservationStateChoice, ReservationTypeChoice
from tilavarauspalvelu.models import ReservationCancelReason
from tilavarauspalvelu.utils.verkkokauppa.verkkokauppa_api_client import VerkkokauppaAPIClient
from utils.date_utils import local_datetime
Expand All @@ -20,8 +20,9 @@
]


def test_reservation__cancel__success(graphql):
reservation = ReservationFactory.create_for_cancellation()
@pytest.mark.parametrize("reservation_type", [ReservationTypeChoice.NORMAL, ReservationTypeChoice.SEASONAL])
def test_reservation__cancel__success(graphql, reservation_type):
reservation = ReservationFactory.create_for_cancellation(type=reservation_type)

graphql.login_with_superuser()
data = get_cancel_data(reservation)
Expand Down Expand Up @@ -50,6 +51,36 @@ def test_reservation__cancel__adds_cancel_details(graphql):
assert reservation.cancel_details == "foo"


@pytest.mark.parametrize(
"reservation_type",
[
ReservationTypeChoice.BLOCKED,
ReservationTypeChoice.STAFF,
ReservationTypeChoice.BEHALF,
],
)
def test_reservation__cancel__fails_type_wrong(graphql, reservation_type):
reservation = ReservationFactory.create_for_cancellation(type=reservation_type)

graphql.login_with_superuser()
data = get_cancel_data(reservation)
response = graphql(CANCEL_MUTATION, input_data=data)

assert response.error_message() == "Mutation was unsuccessful."
assert response.field_error_messages() == ["Only reservations with type ['NORMAL', 'SEASONAL'] can be cancelled."]


def test_reservation__cancel__fails_when_type_is_seasonal_and_reservation_is_paid(graphql):
reservation = ReservationFactory.create_for_cancellation(type=ReservationTypeChoice.SEASONAL, price=10)

graphql.login_with_superuser()
data = get_cancel_data(reservation)
response = graphql(CANCEL_MUTATION, input_data=data)

assert response.error_message() == "Mutation was unsuccessful."
assert response.field_error_messages() == ["Paid seasonal reservations cannot be cancelled."]


def test_reservation__cancel__fails_if_state_is_not_confirmed(graphql):
reservation = ReservationFactory.create_for_cancellation(state=ReservationStateChoice.CREATED)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from rest_framework.exceptions import ValidationError

from tilavarauspalvelu.api.graphql.extensions import error_codes
from tilavarauspalvelu.enums import OrderStatus, ReservationStateChoice
from tilavarauspalvelu.enums import OrderStatus, ReservationStateChoice, ReservationTypeChoice
from tilavarauspalvelu.integrations.email.main import EmailService
from tilavarauspalvelu.models import Reservation
from tilavarauspalvelu.tasks import refund_paid_reservation_task
Expand Down Expand Up @@ -46,6 +46,14 @@ def validate(self, data: dict[str, Any]) -> dict[str, Any]:
msg = "Only reservations with state 'CONFIRMED' can be cancelled."
raise ValidationError(msg, code=error_codes.RESERVATION_CANCELLATION_NOT_ALLOWED)

if self.instance.type not in ReservationTypeChoice.types_that_can_be_cancelled:
msg = f"Only reservations with type {ReservationTypeChoice.types_that_can_be_cancelled} can be cancelled."
raise ValidationError(msg, code=error_codes.RESERVATION_CANCELLATION_NOT_ALLOWED)

if self.instance.type == ReservationTypeChoice.SEASONAL.value and self.instance.price > 0:
msg = "Paid seasonal reservations cannot be cancelled."
raise ValidationError(msg, code=error_codes.RESERVATION_CANCELLATION_NOT_ALLOWED)

now = local_datetime()
if self.instance.begin < now:
msg = "Reservation cannot be cancelled after it has begun."
Expand Down
7 changes: 7 additions & 0 deletions tilavarauspalvelu/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,13 @@ def should_not_anonymize(cls) -> list[str]:
ReservationTypeChoice.STAFF.value,
]

@classproperty
def types_that_can_be_cancelled(cls) -> list[str]:
return [ # type: ignore[return-type]
ReservationTypeChoice.NORMAL.value,
ReservationTypeChoice.SEASONAL.value,
]


class ReservationTypeStaffChoice(models.TextChoices):
# These are the same as the ones above, but for the staff create endpoint
Expand Down

0 comments on commit 9acf72b

Please sign in to comment.