mirror of
https://github.com/xlorepdarkhelm/numinar-coding-project.git
synced 2026-09-06 23:58:26 -04:00
208 lines
7.8 KiB
Python
208 lines
7.8 KiB
Python
"""Unit tests for the backend.routers.invitees module."""
|
|
|
|
from typing import Any
|
|
from unittest.mock import ANY
|
|
from unittest.mock import AsyncMock
|
|
from unittest.mock import MagicMock
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
|
|
from backend.models import Invitee
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.routers.invitees"], indirect=True)
|
|
async def test_get_invitees_for_booking_success(
|
|
client: AsyncClient,
|
|
sample_invitee: Invitee,
|
|
mock_logger: MagicMock,
|
|
) -> None:
|
|
"""Test successful retrieval of all invitees for a booking.
|
|
|
|
Via GET /invitees/booking/{booking_id}. Verifies that the endpoint returns the
|
|
expected list of users with a 200 status.
|
|
|
|
Args:
|
|
client: The FastAPI test client for making HTTP requests.
|
|
sample_invitee: The mocked invitee to return.
|
|
mock_logger: The mocked logger instance.
|
|
"""
|
|
invitee_data: dict[str, Any] = {
|
|
"user_email": sample_invitee.user_email,
|
|
}
|
|
|
|
with patch(
|
|
"backend.routers.invitees._try_create_invitee", new=AsyncMock()
|
|
) as mock_create_invitee, patch(
|
|
"backend.routers.invitees._fetch_user_data", new=AsyncMock()
|
|
) as mock_fetch_user_data:
|
|
mock_create_invitee.return_value = sample_invitee
|
|
mock_fetch_user_data.return_value = sample_invitee.user
|
|
response = await client.post(
|
|
f"/invitees/booking/{sample_invitee.booking_id}", json=invitee_data
|
|
)
|
|
if response.status_code != 201:
|
|
print("TEST FAILURE RESPONSE:", response.json())
|
|
assert response.status_code == 201
|
|
result = response.json()
|
|
assert result["booking_id"] == sample_invitee.booking_id
|
|
assert result["user_email"] == sample_invitee.user_email
|
|
assert result["user"] == {
|
|
"email": sample_invitee.user.email,
|
|
"name": sample_invitee.user.name,
|
|
}
|
|
mock_create_invitee.assert_called_once_with(ANY, sample_invitee.booking_id, ANY)
|
|
mock_fetch_user_data.assert_called_once_with(ANY, sample_invitee.user_email)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.routers.invitees"], indirect=True)
|
|
async def test_get_invitees_for_booking_empty(
|
|
client: AsyncClient, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test retrieval of invitees when none exist for a booking.
|
|
|
|
Via GET /invitees/booking/{booking_id}. Verifies that the endpoint returns an
|
|
empty list with a 200 status.
|
|
|
|
Args:
|
|
client: The FastAPI test client for making HTTP requests.
|
|
mock_logger: The mocked logger instance.
|
|
"""
|
|
booking_id = 1
|
|
with patch(
|
|
"backend.routers.invitees.get_invitees_for_booking",
|
|
new=AsyncMock(return_value=[]),
|
|
) as mock_get_invitees:
|
|
response = await client.get(f"/invitees/booking/{booking_id}")
|
|
assert response.status_code == 200
|
|
assert response.json() == []
|
|
mock_get_invitees.assert_called_once_with(ANY, booking_id)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.routers.invitees"], indirect=True)
|
|
async def test_add_invitee_success(
|
|
client: AsyncClient,
|
|
sample_invitee: Invitee,
|
|
mock_logger: MagicMock,
|
|
) -> None:
|
|
"""Test successful addition of an invitee to a booking.
|
|
|
|
Via POST /invitees/booking/{booking_id}. Verifies that the endpoint returns the
|
|
created invitee with a 201 status.
|
|
|
|
Args:
|
|
client (AsyncClient): The FastAPI test client for making HTTP requests.
|
|
sample_invitee (Invitee): The mocked invitee object.
|
|
mock_logger (MagicMock): The mocked logger instance.
|
|
"""
|
|
with patch(
|
|
"backend.routers.invitees._try_create_invitee", new=AsyncMock()
|
|
) as mock_create_invitee, patch(
|
|
"backend.routers.invitees._fetch_user_data", new=AsyncMock()
|
|
) as mock_fetch_user_data:
|
|
mock_create_invitee.return_value = sample_invitee
|
|
mock_fetch_user_data.return_value = sample_invitee.user
|
|
response = await client.post(
|
|
f"/invitees/booking/{sample_invitee.booking_id}",
|
|
json={"user_email": sample_invitee.user_email},
|
|
)
|
|
if response.status_code != 201:
|
|
print("TEST FAILURE RESPONSE:", response.json())
|
|
assert response.status_code == 201
|
|
result = response.json()
|
|
assert result["booking_id"] == sample_invitee.booking_id
|
|
assert result["user_email"] == sample_invitee.user_email
|
|
assert result["user"] == {
|
|
"email": sample_invitee.user.email,
|
|
"name": sample_invitee.user.name,
|
|
}
|
|
mock_create_invitee.assert_called_once_with(ANY, sample_invitee.booking_id, ANY)
|
|
mock_fetch_user_data.assert_called_once_with(ANY, sample_invitee.user_email)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.routers.invitees"], indirect=True)
|
|
async def test_add_invitee_database_error(
|
|
client: AsyncClient, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test handling of database errors in POST /invitees/booking/{booking_id}.
|
|
|
|
Verifies that the endpoint returns a 400 status on database failure.
|
|
|
|
Args:
|
|
client: The FastAPI test client for making HTTP requests.
|
|
mock_logger: The mocked logger instance.
|
|
"""
|
|
booking_id = 1
|
|
invitee_data: dict[str, Any] = {
|
|
"booking_id": booking_id,
|
|
"user_email": "user1@example.com",
|
|
}
|
|
with patch(
|
|
"backend.routers.invitees._try_create_invitee", new=AsyncMock()
|
|
) as mock_create_invitee:
|
|
mock_create_invitee.side_effect = SQLAlchemyError()
|
|
response = await client.post(
|
|
f"/invitees/booking/{booking_id}", json=invitee_data
|
|
)
|
|
assert response.status_code == 400
|
|
assert "detail" in response.json()
|
|
mock_create_invitee.assert_called_once_with(ANY, booking_id, ANY)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.routers.invitees"], indirect=True)
|
|
async def test_remove_invitee_success(
|
|
client: AsyncClient, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test successful removal of an invitee from a booking.
|
|
|
|
Via DELETE /invitees/booking/{booking_id}/user/{user_email}. Verifies that the
|
|
endpoint returns a 204 status on successful deletion.
|
|
|
|
Args:
|
|
client: The FastAPI test client for making HTTP requests.
|
|
mock_logger: The mocked logger instance.
|
|
"""
|
|
booking_id = 1
|
|
user_email = "user1@example.com"
|
|
with patch(
|
|
"backend.routers.invitees.remove_invitee_from_booking",
|
|
new=AsyncMock(return_value=None),
|
|
) as mock_remove_invitee:
|
|
response = await client.delete(f"/invitees/booking/{booking_id}/{user_email}")
|
|
assert response.status_code == 204
|
|
assert response.text == ""
|
|
mock_remove_invitee.assert_called_once_with(ANY, booking_id, user_email)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize("mock_logger", ["backend.routers.invitees"], indirect=True)
|
|
async def test_remove_invitee_database_error(
|
|
client: AsyncClient, mock_logger: MagicMock
|
|
) -> None:
|
|
"""Test handling of database errors for delete.
|
|
|
|
Via DELETE /invitees/booking/{booking_id}/user/{user_email}. Verifies that the
|
|
endpoint returns a 500 status on database failure.
|
|
|
|
Args:
|
|
client: The FastAPI test client for making HTTP requests.
|
|
mock_logger: The mocked logger instance.
|
|
"""
|
|
booking_id = 1
|
|
user_email = "user1@example.com"
|
|
with patch(
|
|
"backend.routers.invitees.remove_invitee_from_booking",
|
|
new=AsyncMock(side_effect=SQLAlchemyError()),
|
|
) as mock_remove_invitee:
|
|
response = await client.delete(f"/invitees/booking/{booking_id}/{user_email}")
|
|
assert response.status_code == 500
|
|
assert "detail" in response.json()
|
|
mock_remove_invitee.assert_called_once_with(ANY, booking_id, user_email)
|