mirror of
http://88.130.71.182:3000/BlitTech/badoHair_be.git
synced 2026-06-12 23:23:22 +00:00
78 lines
3.0 KiB
Python
78 lines
3.0 KiB
Python
"""
|
|
Tests that booking status updates succeed even when the email service fails.
|
|
This covers the fix: email send is wrapped in try/except so SMTP failure
|
|
does not block the booking status change.
|
|
"""
|
|
from unittest.mock import AsyncMock, patch
|
|
from tests.conftest import SAMPLE_BOOKING, BOOKING_ID, ADMIN_ID
|
|
|
|
|
|
async def test_confirm_booking_succeeds_when_email_fails(admin_client, mock_db):
|
|
"""Admin confirming a booking must succeed even if the email service raises."""
|
|
mock_db.fetchrow = AsyncMock(side_effect=[
|
|
SAMPLE_BOOKING, # UPDATE bookings RETURNING *
|
|
{"email": "client@test.com"}, # SELECT email FROM profiles
|
|
{"date": "2026-06-01", "start_time": "10:00:00"}, # SELECT from time_slots
|
|
SAMPLE_BOOKING, # get_booking at the end
|
|
])
|
|
mock_db.execute = AsyncMock(return_value="INSERT 1")
|
|
|
|
with patch("app.services.email_service.send_booking_confirmed",
|
|
new_callable=AsyncMock, side_effect=Exception("SMTP unavailable")):
|
|
r = await admin_client.patch(
|
|
f"/api/v1/admin/bookings/{BOOKING_ID}",
|
|
json={"status": "confirmed"},
|
|
)
|
|
|
|
# Must succeed despite the email failure
|
|
assert r.status_code == 200
|
|
assert r.json()["success"] is True
|
|
|
|
|
|
async def test_cancel_booking_succeeds_when_email_fails(admin_client, mock_db):
|
|
"""Same resilience for cancellation emails."""
|
|
pending = {**SAMPLE_BOOKING, "status": "pending"}
|
|
mock_db.fetchrow = AsyncMock(side_effect=[
|
|
pending,
|
|
{"email": "client@test.com"},
|
|
{"date": "2026-06-01", "start_time": "10:00:00"},
|
|
pending,
|
|
])
|
|
mock_db.execute = AsyncMock(return_value="INSERT 1")
|
|
|
|
with patch("app.services.email_service.send_booking_cancelled",
|
|
new_callable=AsyncMock, side_effect=Exception("SMTP unavailable")):
|
|
r = await admin_client.patch(
|
|
f"/api/v1/admin/bookings/{BOOKING_ID}",
|
|
json={"status": "cancelled"},
|
|
)
|
|
|
|
assert r.status_code == 200
|
|
assert r.json()["success"] is True
|
|
|
|
|
|
async def test_confirm_booking_with_no_email_address(admin_client, mock_db):
|
|
"""Booking with no guest_email and no user_id must still update successfully."""
|
|
no_email_booking = {**SAMPLE_BOOKING, "guest_email": None, "user_id": None}
|
|
mock_db.fetchrow = AsyncMock(side_effect=[
|
|
no_email_booking, # UPDATE RETURNING *
|
|
no_email_booking, # get_booking at the end
|
|
])
|
|
mock_db.execute = AsyncMock(return_value="INSERT 1")
|
|
|
|
r = await admin_client.patch(
|
|
f"/api/v1/admin/bookings/{BOOKING_ID}",
|
|
json={"status": "confirmed"},
|
|
)
|
|
assert r.status_code == 200
|
|
|
|
|
|
async def test_confirm_booking_not_found(admin_client, mock_db):
|
|
mock_db.fetchrow = AsyncMock(return_value=None)
|
|
r = await admin_client.patch(
|
|
f"/api/v1/admin/bookings/00000000-0000-0000-0000-000000000000",
|
|
json={"status": "confirmed"},
|
|
)
|
|
assert r.status_code == 404
|
|
assert r.json()["error"]["code"] == "BOOKING_NOT_FOUND"
|