122 lines
3.6 KiB
Python
122 lines
3.6 KiB
Python
from datetime import timedelta
|
|
|
|
import pytest
|
|
from django.urls import reverse
|
|
from django.utils import timezone
|
|
from rest_framework.test import APIClient
|
|
|
|
from apps.accounts.models import User, UserRole
|
|
from apps.bookings.models import Booking, BookingStatus
|
|
from apps.notifications.models import Notification, NotificationEvent, NotificationStatus
|
|
from apps.salons.models import Salon, Service, StaffProfile
|
|
|
|
|
|
@pytest.fixture
|
|
def booking_payload():
|
|
owner = User.objects.create_user(
|
|
email="owner@example.com",
|
|
password="pass",
|
|
role=UserRole.MANAGER,
|
|
phone_number="+966500000001",
|
|
)
|
|
customer = User.objects.create_user(
|
|
email="customer@example.com",
|
|
password="pass",
|
|
phone_number="+966500000002",
|
|
)
|
|
staff_user = User.objects.create_user(
|
|
email="staff@example.com",
|
|
password="pass",
|
|
role=UserRole.STAFF,
|
|
phone_number="+966500000003",
|
|
)
|
|
|
|
salon = Salon.objects.create(
|
|
owner=owner,
|
|
name="Main Salon",
|
|
description="",
|
|
address="123 King Rd",
|
|
city="Riyadh",
|
|
phone_number="0512345678",
|
|
)
|
|
service = Service.objects.create(
|
|
salon=salon,
|
|
name="Haircut",
|
|
description="",
|
|
duration_minutes=60,
|
|
price_amount=120,
|
|
currency="SAR",
|
|
)
|
|
staff = StaffProfile.objects.create(user=staff_user, salon=salon)
|
|
|
|
start_time = timezone.now() + timedelta(days=1)
|
|
end_time = start_time + timedelta(minutes=60)
|
|
|
|
return {
|
|
"customer": customer,
|
|
"staff_user": staff_user,
|
|
"service": service,
|
|
"staff": staff,
|
|
"payload": {
|
|
"service": service.id,
|
|
"staff": staff.id,
|
|
"start_time": start_time.isoformat(),
|
|
"end_time": end_time.isoformat(),
|
|
"notes": "",
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_booking_create_sends_notifications(booking_payload):
|
|
client = APIClient()
|
|
client.force_authenticate(user=booking_payload["customer"])
|
|
|
|
response = client.post(
|
|
reverse("booking-list"),
|
|
booking_payload["payload"],
|
|
content_type="application/json",
|
|
)
|
|
assert response.status_code == 201
|
|
|
|
notifications = Notification.objects.filter(event=NotificationEvent.BOOKING_CREATED)
|
|
assert notifications.count() == 2
|
|
assert all(notification.status == NotificationStatus.SENT for notification in notifications)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_booking_status_change_sends_notifications_once(booking_payload):
|
|
client = APIClient()
|
|
client.force_authenticate(user=booking_payload["customer"])
|
|
|
|
response = client.post(
|
|
reverse("booking-list"),
|
|
booking_payload["payload"],
|
|
content_type="application/json",
|
|
)
|
|
assert response.status_code == 201
|
|
|
|
booking_id = Booking.objects.get(customer=booking_payload["customer"]).id
|
|
update_payload = {"status": BookingStatus.CONFIRMED}
|
|
|
|
client.force_authenticate(user=booking_payload["staff_user"])
|
|
response_update = client.patch(
|
|
reverse("booking-detail", args=[booking_id]),
|
|
update_payload,
|
|
content_type="application/json",
|
|
)
|
|
assert response_update.status_code == 200
|
|
|
|
notifications = Notification.objects.filter(event=NotificationEvent.BOOKING_CONFIRMED)
|
|
assert notifications.count() == 2
|
|
|
|
response_repeat = client.patch(
|
|
reverse("booking-detail", args=[booking_id]),
|
|
update_payload,
|
|
content_type="application/json",
|
|
)
|
|
assert response_repeat.status_code == 200
|
|
|
|
notifications_repeat = Notification.objects.filter(event=NotificationEvent.BOOKING_CONFIRMED)
|
|
assert notifications_repeat.count() == 2
|