Files
azionelab/backend/bookings/tests.py

120 lines
4.2 KiB
Python

from datetime import timedelta
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.db import IntegrityError
from django.test import TestCase
from django.utils import timezone
from bookings.models import Reservation, ReservationToken
from checkins.models import CheckIn
from shows.models import Performance, Show, Venue
class DomainModelTests(TestCase):
def setUp(self):
self.show = Show.objects.create(
title="Open Stage",
slug="open-stage",
is_published=True,
)
self.venue = Venue.objects.create(
name="AzioneLab Theatre",
slug="azionelab-theatre",
address="Via Example 1",
city="Rome",
)
self.performance = Performance.objects.create(
show=self.show,
venue=self.venue,
starts_at=timezone.now() + timedelta(days=7),
room_capacity=10,
manually_occupied_seats=2,
additional_seats=3,
)
def create_reservation(self, **overrides):
data = {
"performance": self.performance,
"name": "Maria Rossi",
"email": "maria@example.com",
"party_size": 2,
}
data.update(overrides)
return Reservation.objects.create(**data)
def test_available_seats_count_only_confirmed_reservations(self):
self.create_reservation(party_size=4)
self.create_reservation(
party_size=3,
status=Reservation.Status.CONFIRMED,
confirmed_at=timezone.now(),
)
self.assertEqual(self.performance.configured_capacity, 11)
self.assertEqual(self.performance.confirmed_seats(), 3)
self.assertEqual(self.performance.available_seats(), 8)
def test_reservation_lifecycle_pending_to_confirmed_with_token(self):
reservation = self.create_reservation()
token, raw_token = ReservationToken.create_token(
reservation=reservation,
purpose=ReservationToken.Purpose.CONFIRMATION,
expires_at=timezone.now() + timedelta(hours=2),
)
reservation.confirm_with_token(raw_token)
reservation.refresh_from_db()
token.refresh_from_db()
self.assertEqual(reservation.status, Reservation.Status.CONFIRMED)
self.assertIsNotNone(reservation.confirmed_at)
self.assertIsNotNone(token.used_at)
def test_only_pending_reservations_can_be_confirmed(self):
reservation = self.create_reservation(status=Reservation.Status.CANCELLED)
token, raw_token = ReservationToken.create_token(
reservation=reservation,
purpose=ReservationToken.Purpose.CONFIRMATION,
expires_at=timezone.now() + timedelta(hours=2),
)
with self.assertRaises(ValidationError):
reservation.confirm_with_token(raw_token)
token.refresh_from_db()
self.assertIsNone(token.used_at)
def test_capacity_configuration_rejects_impossible_manual_occupancy(self):
performance = Performance(
show=self.show,
venue=self.venue,
starts_at=timezone.now() + timedelta(days=8),
room_capacity=5,
additional_seats=1,
manually_occupied_seats=7,
)
with self.assertRaises(ValidationError):
performance.full_clean()
def test_check_in_requires_confirmed_reservation(self):
reservation = self.create_reservation()
user = get_user_model().objects.create_user(username="staff", password="test")
check_in = CheckIn(reservation=reservation, checked_in_by=user)
with self.assertRaises(ValidationError):
check_in.full_clean()
def test_reservation_cannot_be_checked_in_twice(self):
reservation = self.create_reservation(
status=Reservation.Status.CONFIRMED,
confirmed_at=timezone.now(),
)
user = get_user_model().objects.create_user(username="staff", password="test")
CheckIn.objects.create(reservation=reservation, checked_in_by=user)
with self.assertRaises((IntegrityError, ValidationError)):
CheckIn.objects.create(reservation=reservation, checked_in_by=user)