Refactor tests for improved consistency and readability

- Updated test cases in `test_auth_endpoints.py` to ensure consistent formatting and style.
- Enhanced `test_socket_endpoints.py` with consistent parameter formatting and improved readability.
- Cleaned up `conftest.py` by ensuring consistent parameter formatting in fixtures.
- Added comprehensive tests for API token dependencies in `test_api_token_dependencies.py`.
- Refactored `test_auth_service.py` to maintain consistent parameter formatting.
- Cleaned up `test_oauth_service.py` by removing unnecessary imports.
- Improved `test_socket_service.py` with consistent formatting and readability.
- Enhanced `test_cookies.py` by ensuring consistent formatting and readability.
- Introduced new tests for token utilities in `test_token_utils.py` to validate token generation and expiration logic.
This commit is contained in:
JSC
2025-07-27 15:11:47 +02:00
parent 42deab2409
commit 3dc21337f9
16 changed files with 991 additions and 159 deletions

View File

@@ -9,7 +9,6 @@ from app.models.plan import Plan
from app.models.user import User
from app.schemas.auth import UserLoginRequest, UserRegisterRequest
from app.services.auth import AuthService
from app.utils.auth import PasswordUtils
class TestAuthService:
@@ -49,11 +48,11 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_register_duplicate_email(
self, auth_service: AuthService, test_user: User
self, auth_service: AuthService, test_user: User,
) -> None:
"""Test registration with duplicate email."""
request = UserRegisterRequest(
email=test_user.email, password="password123", name="Another User"
email=test_user.email, password="password123", name="Another User",
)
with pytest.raises(HTTPException) as exc_info:
@@ -90,7 +89,7 @@ class TestAuthService:
async def test_login_invalid_email(self, auth_service: AuthService) -> None:
"""Test login with invalid email."""
request = UserLoginRequest(
email="nonexistent@example.com", password="password123"
email="nonexistent@example.com", password="password123",
)
with pytest.raises(HTTPException) as exc_info:
@@ -101,7 +100,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_login_invalid_password(
self, auth_service: AuthService, test_user: User
self, auth_service: AuthService, test_user: User,
) -> None:
"""Test login with invalid password."""
request = UserLoginRequest(email=test_user.email, password="wrongpassword")
@@ -114,7 +113,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_login_inactive_user(
self, auth_service: AuthService, test_user: User, test_session: AsyncSession
self, auth_service: AuthService, test_user: User, test_session: AsyncSession,
) -> None:
"""Test login with inactive user."""
# Store the email before deactivating
@@ -134,7 +133,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_login_user_without_password(
self, auth_service: AuthService, test_user: User, test_session: AsyncSession
self, auth_service: AuthService, test_user: User, test_session: AsyncSession,
) -> None:
"""Test login with user that has no password hash."""
# Store the email before removing password
@@ -154,7 +153,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_get_current_user_success(
self, auth_service: AuthService, test_user: User
self, auth_service: AuthService, test_user: User,
) -> None:
"""Test getting current user successfully."""
user = await auth_service.get_current_user(test_user.id)
@@ -175,7 +174,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_get_current_user_inactive(
self, auth_service: AuthService, test_user: User, test_session: AsyncSession
self, auth_service: AuthService, test_user: User, test_session: AsyncSession,
) -> None:
"""Test getting current user when user is inactive."""
# Store the user ID before deactivating
@@ -193,7 +192,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_create_access_token(
self, auth_service: AuthService, test_user: User
self, auth_service: AuthService, test_user: User,
) -> None:
"""Test access token creation."""
token_response = auth_service._create_access_token(test_user)
@@ -212,7 +211,7 @@ class TestAuthService:
@pytest.mark.asyncio
async def test_create_user_response(
self, auth_service: AuthService, test_user: User, test_session: AsyncSession
self, auth_service: AuthService, test_user: User, test_session: AsyncSession,
) -> None:
"""Test user response creation."""
# Ensure plan relationship is loaded

View File

@@ -1,16 +1,14 @@
"""Tests for OAuth service."""
from typing import Any
from unittest.mock import AsyncMock, Mock, patch
from unittest.mock import Mock, patch
import pytest
from httpx import AsyncClient
from app.services.oauth import (
GitHubOAuthProvider,
GoogleOAuthProvider,
OAuthService,
OAuthUserInfo,
)

View File

@@ -1,7 +1,8 @@
"""Tests for socket service."""
from unittest.mock import AsyncMock, patch
import pytest
from unittest.mock import AsyncMock, MagicMock, patch, call
import socketio
from app.services.socket import SocketManager
@@ -24,7 +25,7 @@ class TestSocketManager:
def test_init_creates_socket_server(self):
"""Test that socket manager initializes with proper configuration."""
manager = SocketManager()
assert manager.sio is not None
assert isinstance(manager.user_rooms, dict)
assert isinstance(manager.socket_users, dict)
@@ -37,12 +38,12 @@ class TestSocketManager:
user_id = "123"
room_id = "user_123"
socket_manager.user_rooms[user_id] = room_id
event = "test_event"
data = {"message": "hello"}
result = await socket_manager.send_to_user(user_id, event, data)
assert result is True
mock_sio.emit.assert_called_once_with(event, data, room=room_id)
@@ -52,9 +53,9 @@ class TestSocketManager:
user_id = "999"
event = "test_event"
data = {"message": "hello"}
result = await socket_manager.send_to_user(user_id, event, data)
assert result is False
mock_sio.emit.assert_not_called()
@@ -63,9 +64,9 @@ class TestSocketManager:
"""Test broadcasting message to all users."""
event = "broadcast_event"
data = {"message": "announcement"}
await socket_manager.broadcast_to_all(event, data)
mock_sio.emit.assert_called_once_with(event, data)
def test_get_connected_users(self, socket_manager):
@@ -74,9 +75,9 @@ class TestSocketManager:
socket_manager.user_rooms["1"] = "user_1"
socket_manager.user_rooms["2"] = "user_2"
socket_manager.user_rooms["3"] = "user_3"
connected_users = socket_manager.get_connected_users()
assert len(connected_users) == 3
assert "1" in connected_users
assert "2" in connected_users
@@ -87,139 +88,139 @@ class TestSocketManager:
# Add some users
socket_manager.user_rooms["1"] = "user_1"
socket_manager.user_rooms["2"] = "user_2"
room_info = socket_manager.get_room_info()
assert room_info["total_users"] == 2
assert room_info["connected_users"] == ["1", "2"]
@pytest.mark.asyncio
@patch('app.services.socket.extract_access_token_from_cookies')
@patch('app.services.socket.JWTUtils.decode_access_token')
@patch("app.services.socket.extract_access_token_from_cookies")
@patch("app.services.socket.JWTUtils.decode_access_token")
async def test_connect_handler_success(self, mock_decode, mock_extract_token, socket_manager, mock_sio):
"""Test successful connection with valid token."""
# Setup mocks
mock_extract_token.return_value = "valid_token"
mock_decode.return_value = {"sub": "123"}
# Mock environment
environ = {"HTTP_COOKIE": "access_token=valid_token"}
# Access the connect handler directly
handlers = {}
original_event = socket_manager.sio.event
def mock_event(func):
handlers[func.__name__] = func
return func
socket_manager.sio.event = mock_event
socket_manager._setup_handlers()
# Call the connect handler
await handlers['connect']("test_sid", environ)
await handlers["connect"]("test_sid", environ)
# Verify token extraction and validation
mock_extract_token.assert_called_once_with("access_token=valid_token")
mock_decode.assert_called_once_with("valid_token")
# Verify user tracking
assert socket_manager.socket_users["test_sid"] == "123"
assert socket_manager.user_rooms["123"] == "user_123"
@pytest.mark.asyncio
@patch('app.services.socket.extract_access_token_from_cookies')
@patch("app.services.socket.extract_access_token_from_cookies")
async def test_connect_handler_no_token(self, mock_extract_token, socket_manager, mock_sio):
"""Test connection with no access token."""
# Setup mocks
mock_extract_token.return_value = None
# Mock environment
environ = {"HTTP_COOKIE": ""}
# Access the connect handler directly
handlers = {}
original_event = socket_manager.sio.event
def mock_event(func):
handlers[func.__name__] = func
return func
socket_manager.sio.event = mock_event
socket_manager._setup_handlers()
# Call the connect handler
await handlers['connect']("test_sid", environ)
await handlers["connect"]("test_sid", environ)
# Verify disconnection
mock_sio.disconnect.assert_called_once_with("test_sid")
# Verify no user tracking
assert "test_sid" not in socket_manager.socket_users
assert len(socket_manager.user_rooms) == 0
@pytest.mark.asyncio
@patch('app.services.socket.extract_access_token_from_cookies')
@patch('app.services.socket.JWTUtils.decode_access_token')
@patch("app.services.socket.extract_access_token_from_cookies")
@patch("app.services.socket.JWTUtils.decode_access_token")
async def test_connect_handler_invalid_token(self, mock_decode, mock_extract_token, socket_manager, mock_sio):
"""Test connection with invalid token."""
# Setup mocks
mock_extract_token.return_value = "invalid_token"
mock_decode.side_effect = Exception("Invalid token")
# Mock environment
environ = {"HTTP_COOKIE": "access_token=invalid_token"}
# Access the connect handler directly
handlers = {}
original_event = socket_manager.sio.event
def mock_event(func):
handlers[func.__name__] = func
return func
socket_manager.sio.event = mock_event
socket_manager._setup_handlers()
# Call the connect handler
await handlers['connect']("test_sid", environ)
await handlers["connect"]("test_sid", environ)
# Verify disconnection
mock_sio.disconnect.assert_called_once_with("test_sid")
# Verify no user tracking
assert "test_sid" not in socket_manager.socket_users
assert len(socket_manager.user_rooms) == 0
@pytest.mark.asyncio
@patch('app.services.socket.extract_access_token_from_cookies')
@patch('app.services.socket.JWTUtils.decode_access_token')
@patch("app.services.socket.extract_access_token_from_cookies")
@patch("app.services.socket.JWTUtils.decode_access_token")
async def test_connect_handler_missing_user_id(self, mock_decode, mock_extract_token, socket_manager, mock_sio):
"""Test connection with token missing user ID."""
# Setup mocks
mock_extract_token.return_value = "token_without_user_id"
mock_decode.return_value = {"other_field": "value"} # Missing 'sub'
# Mock environment
environ = {"HTTP_COOKIE": "access_token=token_without_user_id"}
# Access the connect handler directly
handlers = {}
original_event = socket_manager.sio.event
def mock_event(func):
handlers[func.__name__] = func
return func
socket_manager.sio.event = mock_event
socket_manager._setup_handlers()
# Call the connect handler
await handlers['connect']("test_sid", environ)
await handlers["connect"]("test_sid", environ)
# Verify disconnection
mock_sio.disconnect.assert_called_once_with("test_sid")
# Verify no user tracking
assert "test_sid" not in socket_manager.socket_users
assert len(socket_manager.user_rooms) == 0
@@ -230,21 +231,21 @@ class TestSocketManager:
# Setup initial state
socket_manager.socket_users["test_sid"] = "123"
socket_manager.user_rooms["123"] = "user_123"
# Access the disconnect handler directly
handlers = {}
original_event = socket_manager.sio.event
def mock_event(func):
handlers[func.__name__] = func
return func
socket_manager.sio.event = mock_event
socket_manager._setup_handlers()
# Call the disconnect handler
await handlers['disconnect']("test_sid")
await handlers["disconnect"]("test_sid")
# Verify cleanup
assert "test_sid" not in socket_manager.socket_users
assert "123" not in socket_manager.user_rooms
@@ -255,17 +256,17 @@ class TestSocketManager:
# Access the disconnect handler directly
handlers = {}
original_event = socket_manager.sio.event
def mock_event(func):
handlers[func.__name__] = func
return func
socket_manager.sio.event = mock_event
socket_manager._setup_handlers()
# Call the disconnect handler with unknown socket
await handlers['disconnect']("unknown_sid")
await handlers["disconnect"]("unknown_sid")
# Should not raise any errors and state should remain clean
assert len(socket_manager.socket_users) == 0
assert len(socket_manager.user_rooms) == 0
assert len(socket_manager.user_rooms) == 0