Files
conference-room-booking-system/backend/tests/routers/test_users.py
T

145 lines
4.9 KiB
Python
Raw Normal View History

2025-08-24 16:37:21 -04:00
"""Unit tests for the backend.routers.users module."""
from unittest.mock import ANY
from unittest.mock import AsyncMock
from unittest.mock import MagicMock
from unittest.mock import patch
import pytest
from fastapi.testclient import TestClient
from sqlalchemy.exc import NoResultFound
from sqlalchemy.exc import SQLAlchemyError
from backend.models import User
from backend.services.users import UserList
@pytest.mark.asyncio
2025-08-25 21:38:31 -04:00
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
2025-08-24 16:37:21 -04:00
async def test_read_users_success(
2025-08-25 21:38:31 -04:00
client: TestClient, sample_users: UserList, mock_logger: MagicMock
2025-08-24 16:37:21 -04:00
) -> None:
"""Test successful retrieval of all users via GET /users/.
Verifies that the endpoint returns the expected list of users with a 200 status.
"""
with patch("backend.routers.users.get_users", new=AsyncMock()) as mock_get_users:
mock_get_users.return_value = sample_users
response = client.get("/users/")
assert response.status_code == 200
assert response.json() == [
{"email": "user1@example.com", "name": "User One"},
{"email": "user2@example.com", "name": "User Two"},
]
mock_get_users.assert_called_once()
@pytest.mark.asyncio
2025-08-25 21:38:31 -04:00
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
async def test_read_users_empty(client: TestClient, mock_logger: MagicMock) -> None:
2025-08-24 16:37:21 -04:00
"""Test retrieval of users when none exist via GET /users/.
Verifies that the endpoint returns an empty list with a 200 status.
"""
with patch("backend.routers.users.get_users", new=AsyncMock()) as mock_get_users:
mock_get_users.return_value = []
response = client.get("/users/")
assert response.status_code == 200
assert response.json() == []
mock_get_users.assert_called_once()
@pytest.mark.asyncio
2025-08-25 21:38:31 -04:00
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
2025-08-24 16:37:21 -04:00
async def test_read_users_database_error(
2025-08-25 21:38:31 -04:00
client: TestClient, mock_logger: MagicMock
2025-08-24 16:37:21 -04:00
) -> None:
"""Test handling of database errors in GET /users/.
Verifies that the endpoint returns a 500 status on database failure.
"""
with patch("backend.routers.users.get_users", new=AsyncMock()) as mock_get_users:
2025-08-24 21:20:24 -04:00
mock_get_users.side_effect = SQLAlchemyError()
2025-08-24 16:37:21 -04:00
response = client.get("/users/")
assert response.status_code == 500
2025-08-24 21:20:24 -04:00
assert "detail" in response.json()
2025-08-24 16:37:21 -04:00
mock_get_users.assert_called_once()
@pytest.mark.asyncio
2025-08-25 21:38:31 -04:00
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
2025-08-24 16:37:21 -04:00
@pytest.mark.parametrize(
"email, expected_name",
[
("user1@example.com", "User One"),
("user2@example.com", "User Two"),
],
ids=["user1", "user2"],
)
async def test_read_user_success(
2025-08-25 21:38:31 -04:00
client: TestClient, email: str, expected_name: str, mock_logger: MagicMock
2025-08-24 16:37:21 -04:00
) -> None:
"""Test successful retrieval of a user by email via GET /users/{email}.
Verifies that the endpoint returns the correct user with a 200 status.
"""
user = User(email=email, name=expected_name)
with patch("backend.routers.users.get_user", new=AsyncMock()) as mock_get_user:
mock_get_user.return_value = user
response = client.get(f"/users/{email}")
assert response.status_code == 200
assert response.json() == {"email": email, "name": expected_name}
mock_get_user.assert_called_once_with(ANY, email)
@pytest.mark.asyncio
2025-08-25 21:38:31 -04:00
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
2025-08-24 16:37:21 -04:00
@pytest.mark.parametrize(
"email",
["nonexistent@example.com", "invalid@domain.com"],
ids=["nonexistent_email", "invalid_email"],
)
async def test_read_user_not_found(
2025-08-25 21:38:31 -04:00
client: TestClient, email: str, mock_logger: MagicMock
2025-08-24 16:37:21 -04:00
) -> None:
"""Test handling of non-existent user in GET /users/{email}.
Verifies that the endpoint returns a 404 status when the user is not found.
"""
with patch("backend.routers.users.get_user", new=AsyncMock()) as mock_get_user:
2025-08-24 21:20:24 -04:00
mock_get_user.side_effect = NoResultFound()
2025-08-24 16:37:21 -04:00
response = client.get(f"/users/{email}")
assert response.status_code == 404
2025-08-24 21:20:24 -04:00
assert "detail" in response.json()
2025-08-24 16:37:21 -04:00
mock_get_user.assert_called_once_with(ANY, email)
@pytest.mark.asyncio
2025-08-25 21:38:31 -04:00
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
2025-08-24 16:37:21 -04:00
async def test_read_user_database_error(
2025-08-25 21:38:31 -04:00
client: TestClient, mock_logger: MagicMock
2025-08-24 16:37:21 -04:00
) -> None:
"""Test handling of database errors in GET /users/{email}.
Verifies that the endpoint returns a 500 status on database failure.
"""
email = "user1@example.com"
with patch("backend.routers.users.get_user", new=AsyncMock()) as mock_get_user:
2025-08-24 21:20:24 -04:00
mock_get_user.side_effect = SQLAlchemyError()
2025-08-24 16:37:21 -04:00
response = client.get(f"/users/{email}")
assert response.status_code == 500
2025-08-24 21:20:24 -04:00
assert "detail" in response.json()
2025-08-24 16:37:21 -04:00
mock_get_user.assert_called_once_with(ANY, email)