Files
conference-room-booking-system/backend/tests/services/test_bookings_edge_cases.py
T
2025-09-22 11:54:03 -04:00

111 lines
3.8 KiB
Python

"""Edge case tests for backend.services.bookings update and delete operations."""
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from unittest.mock import AsyncMock
from unittest.mock import MagicMock
import pytest
from sqlalchemy.ext.asyncio import AsyncSession
from backend.src.backend.models import Booking
from backend.src.backend.services.bookings import delete_booking
from backend.src.backend.services.bookings import update_booking
from backend.src.backend.services.bookings import validate_room_exists
@pytest.mark.asyncio
@pytest.mark.parametrize("mock_logger", ["backend.services.bookings"], indirect=True)
async def test_update_booking_invalid_times(
async_session: AsyncSession, mock_logger: MagicMock
) -> None:
"""Test update_booking with invalid start/end times (start >= end).
Args:
async_session: The asynchronous database session.
mock_logger: The mocked logger instance.
"""
booking_id = 1
async_session.execute = AsyncMock()
async_session.commit = AsyncMock()
booking = Booking(
room_id=1,
start_time=datetime.now(timezone.utc),
end_time=datetime.now(timezone.utc) + timedelta(hours=1),
title="Invalid Time Test Booking",
)
booking.id = booking_id
async_session.scalar = AsyncMock(return_value=booking)
# new_start >= new_end
with pytest.raises(ValueError):
await update_booking(
async_session,
booking_id,
event_publisher=None,
**{
"start_time": datetime.now(timezone.utc) + timedelta(hours=2),
"end_time": datetime.now(timezone.utc) + timedelta(hours=1),
}
)
@pytest.mark.asyncio
@pytest.mark.parametrize("mock_logger", ["backend.services.bookings"], indirect=True)
async def test_update_booking_nonexistent_room(
async_session: AsyncSession, mock_logger: MagicMock
) -> None:
"""Test update_booking with nonexistent room.
Args:
async_session: The asynchronous database session.
mock_logger: The mocked logger instance.
"""
booking_id = 1
async_session.execute = AsyncMock()
async_session.commit = AsyncMock()
booking = Booking(
room_id=1,
start_time=datetime.now(timezone.utc),
end_time=datetime.now(timezone.utc) + timedelta(hours=1),
title="Nonexistent Room Test Booking",
)
booking.id = booking_id
async_session.scalar = AsyncMock(return_value=booking)
# Simulate get_room raising ValueError
orig_validate_room_exists = validate_room_exists
from typing import Any
async def fake_validate_room_exists(
session: AsyncSession, room_id: int, get_room: Any
):
raise ValueError("Room does not exist")
import backend.src.backend.services.bookings as bookings_mod
bookings_mod.validate_room_exists = fake_validate_room_exists
with pytest.raises(ValueError):
await update_booking(
async_session, booking_id, event_publisher=None, **{"room_id": 999}
)
bookings_mod.validate_room_exists = orig_validate_room_exists
@pytest.mark.asyncio
@pytest.mark.parametrize("mock_logger", ["backend.services.bookings"], indirect=True)
async def test_delete_booking_nonexistent(
async_session: AsyncSession, mock_logger: MagicMock
) -> None:
"""Test delete_booking for nonexistent booking (should raise ValueError).
Args:
async_session: The asynchronous database session.
mock_logger: The mocked logger instance.
"""
booking_id = 999
async_session.execute = AsyncMock(return_value=MagicMock(rowcount=0))
async_session.commit = AsyncMock()
async_session.scalar = AsyncMock(return_value=None)
with pytest.raises(ValueError):
await delete_booking(async_session, booking_id)