mirror of
https://github.com/xlorepdarkhelm/numinar-coding-project.git
synced 2026-09-05 18:58:25 -04:00
205 lines
7.2 KiB
Python
205 lines
7.2 KiB
Python
"""Unit tests for the backend.services.invitees module."""
|
|
|
|
from unittest.mock import AsyncMock
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
from sqlalchemy import delete
|
|
from sqlalchemy import select
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from backend.models import Invitee
|
|
from backend.services.invitees import UserList
|
|
from backend.services.invitees import add_invitee_to_booking
|
|
from backend.services.invitees import get_invitees_for_booking
|
|
from backend.services.invitees import remove_invitee_from_booking
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
async def test_get_invitees_for_booking_success(
|
|
async_session: AsyncSession, sample_invitees: UserList, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test successful retrieval of all invitees for a booking.
|
|
|
|
Verifies that get_invitees_for_booking returns the expected list of users and constructs
|
|
the correct SQLAlchemy query.
|
|
"""
|
|
booking_id = 1
|
|
mock_scalars_result = AsyncMock()
|
|
mock_scalars_result.all = MagicMock(return_value=sample_invitees)
|
|
mock_scalars = AsyncMock(return_value=mock_scalars_result)
|
|
async_session.scalars = mock_scalars
|
|
|
|
result: UserList = await get_invitees_for_booking(async_session, booking_id)
|
|
|
|
assert isinstance(result, list)
|
|
assert len(result) == 2
|
|
assert result == sample_invitees
|
|
async_session.scalars.assert_called_once()
|
|
assert async_session.scalars.call_args.args[0].compare(
|
|
select(Invitee.user).where(Invitee.booking_id == booking_id)
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
async def test_get_invitees_for_booking_empty(
|
|
async_session: AsyncSession, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test retrieval of invitees when none exist for the booking.
|
|
|
|
Verifies that get_invitees_for_booking returns an empty list when no invitees are found.
|
|
"""
|
|
booking_id = 1
|
|
mock_scalars_result = AsyncMock()
|
|
mock_scalars_result.all = MagicMock(return_value=[])
|
|
mock_scalars = AsyncMock(return_value=mock_scalars_result)
|
|
async_session.scalars = mock_scalars
|
|
|
|
result: UserList = await get_invitees_for_booking(async_session, booking_id)
|
|
|
|
assert isinstance(result, list)
|
|
assert len(result) == 0
|
|
async_session.scalars.assert_called_once()
|
|
assert async_session.scalars.call_args.args[0].compare(
|
|
select(Invitee.user).where(Invitee.booking_id == booking_id)
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
async def test_get_invitees_for_booking_database_error(
|
|
async_session: AsyncSession, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test handling of database errors in get_invitees_for_booking.
|
|
|
|
Verifies that get_invitees_for_booking raises an exception on database failure.
|
|
"""
|
|
booking_id = 1
|
|
async_session.scalars = AsyncMock(side_effect=SQLAlchemyError("Database error"))
|
|
|
|
with pytest.raises(SQLAlchemyError):
|
|
await get_invitees_for_booking(async_session, booking_id)
|
|
async_session.scalars.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
@pytest.mark.parametrize(
|
|
"booking_id, user_email",
|
|
[
|
|
(1, "user1@example.com"),
|
|
(2, "user2@example.com"),
|
|
],
|
|
ids=["invitee1", "invitee2"],
|
|
)
|
|
async def test_add_invitee_to_booking_success(
|
|
async_session: AsyncSession,
|
|
booking_id: int,
|
|
user_email: str,
|
|
mock_logger: MagicMock,
|
|
) -> None:
|
|
"""Test successful addition of an invitee to a booking.
|
|
|
|
Verifies that add_invitee_to_booking adds the invitee, commits the session,
|
|
and returns the invitee.
|
|
"""
|
|
invitee = Invitee(booking_id=booking_id, user_email=user_email)
|
|
async_session.add = MagicMock()
|
|
async_session.commit = AsyncMock()
|
|
|
|
result: Invitee = await add_invitee_to_booking(
|
|
async_session, booking_id, user_email
|
|
)
|
|
|
|
assert result == invitee
|
|
assert result.booking_id == booking_id
|
|
assert result.user_email == user_email
|
|
async_session.add.assert_called_once_with(invitee)
|
|
async_session.commit.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
async def test_add_invitee_to_booking_database_error(
|
|
async_session: AsyncSession, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test handling of database errors in add_invitee_to_booking.
|
|
|
|
Verifies that add_invitee_to_booking rolls back the session on database failure.
|
|
"""
|
|
booking_id = 1
|
|
user_email = "user1@example.com"
|
|
invitee = Invitee(booking_id=booking_id, user_email=user_email)
|
|
async_session.add = MagicMock()
|
|
async_session.commit = AsyncMock(side_effect=SQLAlchemyError("Database error"))
|
|
async_session.rollback = AsyncMock()
|
|
|
|
with pytest.raises(SQLAlchemyError):
|
|
await add_invitee_to_booking(async_session, booking_id, user_email)
|
|
async_session.add.assert_called_once_with(invitee)
|
|
async_session.commit.assert_called_once()
|
|
async_session.rollback.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
@pytest.mark.parametrize(
|
|
"booking_id, user_email",
|
|
[
|
|
(1, "user1@example.com"),
|
|
(2, "user2@example.com"),
|
|
],
|
|
ids=["invitee1", "invitee2"],
|
|
)
|
|
async def test_remove_invitee_from_booking_success(
|
|
async_session: AsyncSession,
|
|
booking_id: int,
|
|
user_email: str,
|
|
mock_logger: MagicMock,
|
|
) -> None:
|
|
"""Test successful removal of an invitee from a booking.
|
|
|
|
Verifies that remove_invitee_from_booking deletes the invitee and commits the session.
|
|
"""
|
|
mock_execute_result = MagicMock(rowcount=1)
|
|
async_session.execute = AsyncMock(return_value=mock_execute_result)
|
|
async_session.commit = AsyncMock()
|
|
|
|
await remove_invitee_from_booking(async_session, booking_id, user_email)
|
|
|
|
async_session.execute.assert_called_once()
|
|
assert async_session.execute.call_args.args[0].compare(
|
|
delete(Invitee).where(
|
|
Invitee.booking_id == booking_id, Invitee.user_email == user_email
|
|
)
|
|
)
|
|
async_session.commit.assert_called_once()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.services.invitees"], indirect=True)
|
|
async def test_remove_invitee_from_booking_database_error(
|
|
async_session: AsyncSession, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test handling of database errors in remove_invitee_from_booking.
|
|
|
|
Verifies that remove_invitee_from_booking rolls back the session on database failure.
|
|
"""
|
|
booking_id = 1
|
|
user_email = "user1@example.com"
|
|
async_session.execute = AsyncMock(side_effect=SQLAlchemyError("Database error"))
|
|
async_session.rollback = AsyncMock()
|
|
|
|
with pytest.raises(SQLAlchemyError):
|
|
await remove_invitee_from_booking(async_session, booking_id, user_email)
|
|
async_session.execute.assert_called_once()
|
|
assert async_session.execute.call_args.args[0].compare(
|
|
delete(Invitee).where(
|
|
Invitee.booking_id == booking_id, Invitee.user_email == user_email
|
|
)
|
|
)
|
|
async_session.rollback.assert_called_once()
|