114 lines
4.3 KiB
Python
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")
|