brief-rags-bench/tests/test_auth.py

114 lines
4.3 KiB
Python

"""Tests for authentication endpoints and service."""
import pytest
from unittest.mock import AsyncMock, patch
from app.services.auth_service import AuthService
from app.models.auth import LoginRequest, UserResponse
class TestAuthEndpoints:
"""Tests for /api/v1/auth endpoints."""
def test_login_success(self, unauthenticated_client, mock_db_client, test_user_response):
"""Test successful login with valid 8-digit login."""
# Mock DB client response
mock_db_client.login_user = AsyncMock(return_value=test_user_response)
# Override dependency
from app.main import app
from app.dependencies import get_db_client
app.dependency_overrides[get_db_client] = lambda: mock_db_client
try:
response = unauthenticated_client.post("/api/v1/auth/login?login=12345678")
assert response.status_code == 200
data = response.json()
assert "access_token" in data
assert data["token_type"] == "bearer"
assert "user" in data
assert data["user"]["login"] == "12345678"
# Verify DB client was called
mock_db_client.login_user.assert_called_once()
finally:
app.dependency_overrides.clear()
def test_login_invalid_format(self, unauthenticated_client):
"""Test login with invalid format (not 8 digits)."""
# Test with 7 digits
response = unauthenticated_client.post("/api/v1/auth/login?login=1234567")
assert response.status_code == 400
assert "must be 8 digits" in response.json()["detail"].lower()
# Test with 9 digits
response = unauthenticated_client.post("/api/v1/auth/login?login=123456789")
assert response.status_code == 400
# Test with letters
response = unauthenticated_client.post("/api/v1/auth/login?login=abcd1234")
assert response.status_code == 400
def test_login_db_api_error(self, unauthenticated_client, mock_db_client):
"""Test login when DB API fails."""
# Mock DB client to raise exception
mock_db_client.login_user = AsyncMock(side_effect=Exception("DB API unavailable"))
from app.main import app
from app.dependencies import get_db_client
app.dependency_overrides[get_db_client] = lambda: mock_db_client
try:
response = unauthenticated_client.post("/api/v1/auth/login?login=12345678")
assert response.status_code == 500
assert "failed" in response.json()["detail"].lower()
finally:
app.dependency_overrides.clear()
class TestAuthService:
"""Tests for AuthService."""
@pytest.mark.asyncio
async def test_login_success(self, mock_db_client, test_user_response):
"""Test successful login via AuthService."""
mock_db_client.login_user = AsyncMock(return_value=test_user_response)
auth_service = AuthService(mock_db_client)
result = await auth_service.login("12345678", "192.168.1.1")
assert result.access_token is not None
assert result.token_type == "bearer"
assert result.user.login == "12345678"
assert result.user.user_id == "test-user-123"
# Verify DB client was called with correct params
call_args = mock_db_client.login_user.call_args[0][0]
assert call_args.login == "12345678"
assert call_args.client_ip == "192.168.1.1"
@pytest.mark.asyncio
async def test_login_invalid_format(self, mock_db_client):
"""Test login with invalid format raises ValueError."""
auth_service = AuthService(mock_db_client)
with pytest.raises(ValueError, match="8 digits"):
await auth_service.login("1234567", "192.168.1.1")
with pytest.raises(ValueError, match="8 digits"):
await auth_service.login("abcd1234", "192.168.1.1")
# Verify DB client was never called
mock_db_client.login_user.assert_not_called()
@pytest.mark.asyncio
async def test_login_db_api_failure(self, mock_db_client):
"""Test login when DB API fails."""
mock_db_client.login_user = AsyncMock(side_effect=Exception("DB error"))
auth_service = AuthService(mock_db_client)
with pytest.raises(Exception, match="DB error"):
await auth_service.login("12345678", "192.168.1.1")