Files
conference-room-booking-system/backend/tests/routers/test_users.py
Cliff Hill ed813c382c More fixes.
Signed-off-by: Cliff Hill <xlorep@darkhelm.org>
2025-08-26 17:20:16 -04:00

173 lines
5.9 KiB
Python

"""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.models import UserList
@pytest.mark.asyncio
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
async def test_read_users_success(
client: TestClient, sample_users: UserList, mock_logger: MagicMock
) -> None:
"""Test successful retrieval of all users via GET /users/.
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_users: The mocked list of users to return.
mock_logger: The mocked logger instance.
"""
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
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
async def test_read_users_empty(client: TestClient, mock_logger: MagicMock) -> None:
"""Test retrieval of users when none exist via GET /users/.
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.
"""
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
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
async def test_read_users_database_error(
client: TestClient, mock_logger: MagicMock
) -> None:
"""Test handling of database errors in GET /users/.
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.
"""
with patch("backend.routers.users.get_users", new=AsyncMock()) as mock_get_users:
mock_get_users.side_effect = SQLAlchemyError()
response = client.get("/users/")
assert response.status_code == 500
assert "detail" in response.json()
mock_get_users.assert_called_once()
@pytest.mark.asyncio
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
@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(
client: TestClient, email: str, expected_name: str, mock_logger: MagicMock
) -> 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.
Args:
client: The FastAPI test client for making HTTP requests.
email: The email of the user to retrieve.
expected_name: The expected name of the user.
mock_logger: The mocked logger instance.
"""
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
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
@pytest.mark.parametrize(
"email",
["nonexistent@example.com", "invalid@domain.com"],
ids=["nonexistent_email", "invalid_email"],
)
async def test_read_user_not_found(
client: TestClient, email: str, mock_logger: MagicMock
) -> 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.
Args:
client: The FastAPI test client for making HTTP requests.
email: The email of the user to retrieve.
mock_logger: The mocked logger instance.
"""
with patch("backend.routers.users.get_user", new=AsyncMock()) as mock_get_user:
mock_get_user.side_effect = NoResultFound()
response = client.get(f"/users/{email}")
assert response.status_code == 404
assert "detail" in response.json()
mock_get_user.assert_called_once_with(ANY, email)
@pytest.mark.asyncio
@pytest.mark.parametrize("mock_logger", ["backend.routers.users"], indirect=True)
async def test_read_user_database_error(
client: TestClient, mock_logger: MagicMock
) -> None:
"""Test handling of database errors in GET /users/{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.
"""
email = "user1@example.com"
with patch("backend.routers.users.get_user", new=AsyncMock()) as mock_get_user:
mock_get_user.side_effect = SQLAlchemyError()
response = client.get(f"/users/{email}")
assert response.status_code == 500
assert "detail" in response.json()
mock_get_user.assert_called_once_with(ANY, email)