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

121 lines
3.7 KiB
Python
Raw Normal View History

2025-08-24 16:37:21 -04:00
"""Unit tests for the backend.routers.users module."""
2025-09-26 06:24:01 -04:00
from typing import Any
2025-08-24 16:37:21 -04:00
import pytest
2025-09-26 06:24:01 -04:00
import sqlalchemy.exc
2025-08-27 15:51:05 -04:00
from httpx import AsyncClient
2025-08-24 16:37:21 -04:00
from sqlalchemy.exc import SQLAlchemyError
2025-09-26 06:24:01 -04:00
from backend.dependencies.users import get_users_service
from backend.main import app
2025-08-26 17:20:16 -04:00
from backend.models import UserList
2025-09-26 06:24:01 -04:00
from tests.types import UserData
# Useful constants for users router tests
USERS_SUCCESS_STATUS = 200
USERS_DB_ERROR_STATUS = 500
USERS_NOT_FOUND_STATUS = 404
USERS_DB_ERROR_DETAIL = "Database error"
USERS_NOT_FOUND_DETAIL = "User not found"
USERS_UNEXPECTED_ERROR_DETAIL = "An unexpected error occurred"
2025-08-24 16:37:21 -04:00
@pytest.mark.asyncio
2025-10-01 15:23:35 -04:00
@pytest.mark.parametrize("has_users", [True, False], ids=["users_exist", "users_empty"])
2025-09-26 06:24:01 -04:00
async def test_read_users_parametrized(
client: AsyncClient,
sample_users: UserList,
sample_users_data: list[UserData],
has_users: bool,
2025-08-24 16:37:21 -04:00
) -> None:
2025-09-26 06:24:01 -04:00
"""Test GET /users/ for success and empty list cases.
2025-08-26 15:47:08 -04:00
Args:
client: The FastAPI test client for making HTTP requests.
2025-09-26 06:24:01 -04:00
sample_users: The list of sample User objects.
sample_users_data: The expected response data for users.
has_users: Whether to return users or an empty list.
2025-09-30 09:01:42 -04:00
Asserts:
- Response status code is USERS_SUCCESS_STATUS.
- Response JSON matches expected user data or empty list.
2025-08-24 16:37:21 -04:00
"""
2025-09-26 06:24:01 -04:00
async def mock_get_users(*args: Any, **kwargs: Any) -> UserList:
return sample_users if has_users else []
2025-08-24 16:37:21 -04:00
2025-09-26 06:24:01 -04:00
app.dependency_overrides[get_users_service] = lambda: mock_get_users
response = await client.get("/users/")
assert response.status_code == USERS_SUCCESS_STATUS
expected = sample_users_data if has_users else []
assert response.json() == expected
2025-08-24 16:37:21 -04:00
@pytest.mark.asyncio
async def test_read_users_database_error(
2025-09-26 06:24:01 -04:00
client: AsyncClient,
2025-08-24 16:37:21 -04:00
) -> None:
2025-09-26 06:24:01 -04:00
"""Test GET /users/ for database error.
2025-08-26 15:47:08 -04:00
Args:
client: The FastAPI test client for making HTTP requests.
2025-09-30 09:01:42 -04:00
Asserts:
- Response status code is USERS_DB_ERROR_STATUS.
- Response JSON contains 'detail'.
2025-08-24 16:37:21 -04:00
"""
2025-09-26 06:24:01 -04:00
async def mock_get_users(*args: Any, **kwargs: Any) -> None:
raise SQLAlchemyError()
2025-08-24 16:37:21 -04:00
2025-09-26 06:24:01 -04:00
app.dependency_overrides[get_users_service] = lambda: mock_get_users
response = await client.get("/users/")
assert response.status_code == USERS_DB_ERROR_STATUS
assert "detail" in response.json()
# Parametrized error path tests for GET /users/
2025-08-24 16:37:21 -04:00
@pytest.mark.asyncio
@pytest.mark.parametrize(
2025-09-26 06:24:01 -04:00
"exception_to_raise,expected_status,expected_detail",
2025-08-24 16:37:21 -04:00
[
2025-09-26 06:24:01 -04:00
(
sqlalchemy.exc.NoResultFound(),
USERS_NOT_FOUND_STATUS,
USERS_NOT_FOUND_DETAIL,
),
(Exception("fail"), USERS_DB_ERROR_STATUS, USERS_UNEXPECTED_ERROR_DETAIL),
2025-08-24 16:37:21 -04:00
],
2025-10-01 15:23:35 -04:00
ids=["no_result_found", "unexpected_error"],
2025-08-24 16:37:21 -04:00
)
2025-09-26 06:24:01 -04:00
async def test_read_users_error_paths(
client: AsyncClient,
exception_to_raise: Exception,
expected_status: int,
expected_detail: str,
2025-08-24 16:37:21 -04:00
) -> None:
2025-09-26 06:24:01 -04:00
"""Test GET /users/ for error paths: NoResultFound (404) and generic exception (500).
2025-08-26 15:47:08 -04:00
Args:
client: The FastAPI test client for making HTTP requests.
2025-09-26 06:24:01 -04:00
exception_to_raise: The exception to raise in the service dependency.
expected_status: The expected HTTP status code.
expected_detail: The expected error detail message.
2025-09-30 09:01:42 -04:00
Asserts:
- Response status code matches expected_status.
- Response JSON 'detail' matches expected_detail.
2025-08-24 16:37:21 -04:00
"""
2025-09-26 06:24:01 -04:00
async def mock_get_users(*args: Any, **kwargs: Any) -> None:
raise exception_to_raise
2025-08-24 16:37:21 -04:00
2025-09-26 06:24:01 -04:00
app.dependency_overrides[get_users_service] = lambda: mock_get_users
response = await client.get("/users/")
assert response.status_code == expected_status
assert response.json()["detail"] == expected_detail