Coverage for src/api/tests/test_models.py: 94%
98 statements
« prev ^ index » next coverage.py v7.11.1, created at 2025-11-08 10:41 +0000
« prev ^ index » next coverage.py v7.11.1, created at 2025-11-08 10:41 +0000
1import pytest
2from django.db import IntegrityError
3from django.utils import timezone
4from django.contrib.auth import get_user_model
5from src.api.models import ParkingLot, Spot, Booking, OperatorProfile
6from rest_framework.test import APITestCase
7from django.utils import timezone
8from datetime import timedelta
9from django.contrib.auth.models import User
10from django.conf import settings
12TEST_PASSWORD = settings.TEST_USER_PASSWORD
14TEST_PASSWORD = "pass"
16class BookingTests(APITestCase):
17 def setUp(self):
18 self.user = User.objects.create_user(username="test")
19 self.client.force_authenticate(user=self.user)
20 self.lot = ParkingLot.objects.create(name="River Mall", city="Kyiv", street="Dnipro")
21 self.spot = Spot.objects.create(number="P1", lot=self.lot)
22 self.start = timezone.now() + timedelta(hours=1)
23 self.end = timezone.now() + timedelta(hours=2)
26# ────────────────────────────────────────────────
27# ParkingLot model
28# ────────────────────────────────────────────────
30@pytest.mark.django_db
31def test_create_parking_lot_success():
32 lot = ParkingLot.objects.create(
33 name="SkyMall",
34 city="Kyiv",
35 street="Petrivka",
36 building="10A"
37 )
38 assert lot.id is not None
39 assert str(lot) == "SkyMall (Kyiv, Petrivka 10A)"
40 assert "Kyiv" in str(lot)
43@pytest.mark.django_db
44def test_parking_lot_str_without_building():
45 lot = ParkingLot.objects.create(
46 name="Center Lot",
47 city="Lviv",
48 street="Main Street"
49 )
50 result = str(lot)
51 assert "Center Lot" in result
52 assert "Main Street" in result
53 assert "None" not in result
56# ────────────────────────────────────────────────
57# Spot model
58# ────────────────────────────────────────────────
60@pytest.mark.django_db
61def test_spot_creation_and_str():
62 lot = ParkingLot.objects.create(name="Lot A", city="Kyiv", street="Main")
63 spot = Spot.objects.create(number="A1", lot=lot, is_ev=True, is_disabled=False)
64 assert spot.lot == lot
65 assert "#A1" in str(spot)
66 assert "Lot A" in str(spot)
69@pytest.mark.django_db
70def test_spot_unique_together_same_lot():
71 lot = ParkingLot.objects.create(name="Lot B", city="Kyiv", street="Main")
72 Spot.objects.create(number="X1", lot=lot)
73 with pytest.raises(IntegrityError):
74 Spot.objects.create(number="X1", lot=lot) # дубль у межах того ж лоту
77@pytest.mark.django_db
78def test_spot_number_can_repeat_in_different_lots():
79 lot1 = ParkingLot.objects.create(name="Lot1", city="Kyiv", street="Main")
80 lot2 = ParkingLot.objects.create(name="Lot2", city="Lviv", street="Market")
81 Spot.objects.create(number="S1", lot=lot1)
82 spot2 = Spot.objects.create(number="S1", lot=lot2)
83 assert spot2.lot != lot1
84 assert spot2.number == "S1"
87# ────────────────────────────────────────────────
88# Booking model
89# ────────────────────────────────────────────────
91@pytest.mark.django_db
92def test_booking_creation_defaults():
93 lot = ParkingLot.objects.create(name="LotX", city="Dnipro", street="River")
94 spot = Spot.objects.create(number="A5", lot=lot)
95 booking = Booking.objects.create(
96 spot=spot,
97 start_at=timezone.now(),
98 end_at=timezone.now() + timezone.timedelta(hours=2)
99 )
101 assert booking.status == "confirmed"
102 assert booking.cancellation_reason == ""
103 assert booking.payment_intent_id == ""
104 assert booking.user is None
107@pytest.mark.django_db
108def test_booking_with_user_relationship():
109 user = User.objects.create_user(username="testuser")
110 lot = ParkingLot.objects.create(name="LotY", city="Kyiv", street="Street")
111 spot = Spot.objects.create(number="Y1", lot=lot)
112 booking = Booking.objects.create(
113 user=user,
114 spot=spot,
115 start_at=timezone.now(),
116 end_at=timezone.now() + timezone.timedelta(hours=1)
117 )
119 assert booking.user.username == "testuser"
120 assert booking.spot == spot
121 assert booking.status == "confirmed"
124@pytest.mark.django_db
125def test_booking_has_index_fields():
126 """Перевіряємо, що індекс існує для (spot, start_at, end_at, status)."""
127 fields = [tuple(i.fields) for i in Booking._meta.indexes]
128 assert ("spot", "start_at", "end_at", "status") in fields
131# ────────────────────────────────────────────────
132# OperatorProfile model
133# ────────────────────────────────────────────────
135@pytest.mark.django_db
136def test_operator_profile_str_and_relation():
137 user = User.objects.create_user(username="operator1")
138 lot = ParkingLot.objects.create(name="Central", city="Kyiv", street="Main")
139 profile = OperatorProfile.objects.create(user=user, lot=lot)
141 assert profile.user == user
142 assert profile.lot == lot
143 assert "operator1" in str(profile)
144 assert "Central" in str(profile)
147@pytest.mark.django_db
148def test_operator_profile_without_lot():
149 user = User.objects.create_user(username="solo")
150 profile = OperatorProfile.objects.create(user=user, lot=None)
152 assert "N/A" in str(profile)
153 assert "solo" in str(profile)
155@pytest.mark.django_db
156def test_operator_profile_user_must_be_unique_fails():
157 user = User.objects.create_user(username="operator_gulliver")
158 lot = ParkingLot.objects.create(name="Central", city="Kyiv", street="Main")
160 OperatorProfile.objects.create(user=user, lot=lot)
161 with pytest.raises(IntegrityError):
162 OperatorProfile.objects.create(user=user, lot=None)