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:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user