Files
orion/tests/unit/services/test_auth_service.py
2025-09-21 13:00:10 +02:00

215 lines
7.8 KiB
Python

# tests/test_auth_service.py
import pytest
from fastapi import HTTPException
from app.services.auth_service import AuthService
from models.api.auth import UserLogin, UserRegister
from models.database.user import User
@pytest.mark.unit
@pytest.mark.auth
class TestAuthService:
"""Test suite for AuthService following the application's testing patterns"""
def setup_method(self):
"""Setup method following the same pattern as admin service tests"""
self.service = AuthService()
def test_register_user_success(self, db):
"""Test successful user registration"""
user_data = UserRegister(
email="newuser@example.com", username="newuser123", password="securepass123"
)
user = self.service.register_user(db, user_data)
assert user is not None
assert user.email == "newuser@example.com"
assert user.username == "newuser123"
assert user.role == "user"
assert user.is_active is True
assert user.hashed_password != "securepass123" # Should be hashed
def test_register_user_email_already_exists(self, db, test_user):
"""Test registration fails when email already exists"""
user_data = UserRegister(
email=test_user.email, # Use existing email
username="differentuser",
password="securepass123",
)
with pytest.raises(HTTPException) as exc_info:
self.service.register_user(db, user_data)
assert exc_info.value.status_code == 400
assert "Email already registered" in str(exc_info.value.detail)
def test_register_user_username_already_exists(self, db, test_user):
"""Test registration fails when username already exists"""
user_data = UserRegister(
email="different@example.com",
username=test_user.username, # Use existing username
password="securepass123",
)
with pytest.raises(HTTPException) as exc_info:
self.service.register_user(db, user_data)
assert exc_info.value.status_code == 400
assert "Username already taken" in str(exc_info.value.detail)
def test_login_user_success(self, db, test_user):
"""Test successful user login"""
user_credentials = UserLogin(
username=test_user.username, password="testpass123"
)
result = self.service.login_user(db, user_credentials)
assert "token_data" in result
assert "user" in result
assert result["user"].id == test_user.id
assert result["user"].username == test_user.username
assert "access_token" in result["token_data"]
assert "token_type" in result["token_data"]
assert "expires_in" in result["token_data"]
def test_login_user_wrong_username(self, db):
"""Test login fails with wrong username"""
user_credentials = UserLogin(username="nonexistentuser", password="testpass123")
with pytest.raises(HTTPException) as exc_info:
self.service.login_user(db, user_credentials)
assert exc_info.value.status_code == 401
assert "Incorrect username or password" in str(exc_info.value.detail)
def test_login_user_wrong_password(self, db, test_user):
"""Test login fails with wrong password"""
user_credentials = UserLogin(
username=test_user.username, password="wrongpassword"
)
with pytest.raises(HTTPException) as exc_info:
self.service.login_user(db, user_credentials)
assert exc_info.value.status_code == 401
assert "Incorrect username or password" in str(exc_info.value.detail)
def test_login_user_inactive_user(self, db, test_user):
"""Test login fails for inactive user"""
# Deactivate user
test_user.is_active = False
db.commit()
user_credentials = UserLogin(
username=test_user.username, password="testpass123"
)
with pytest.raises(HTTPException) as exc_info:
self.service.login_user(db, user_credentials)
assert exc_info.value.status_code == 401
assert "Incorrect username or password" in str(exc_info.value.detail)
def test_get_user_by_email(self, db, test_user):
"""Test getting user by email"""
user = self.service.get_user_by_email(db, test_user.email)
assert user is not None
assert user.id == test_user.id
assert user.email == test_user.email
def test_get_user_by_email_not_found(self, db):
"""Test getting user by email when user doesn't exist"""
user = self.service.get_user_by_email(db, "nonexistent@example.com")
assert user is None
def test_get_user_by_username(self, db, test_user):
"""Test getting user by username"""
user = self.service.get_user_by_username(db, test_user.username)
assert user is not None
assert user.id == test_user.id
assert user.username == test_user.username
def test_get_user_by_username_not_found(self, db):
"""Test getting user by username when user doesn't exist"""
user = self.service.get_user_by_username(db, "nonexistentuser")
assert user is None
def test_email_exists_true(self, db, test_user):
"""Test email_exists returns True when email exists"""
exists = self.service.email_exists(db, test_user.email)
assert exists is True
def test_email_exists_false(self, db):
"""Test email_exists returns False when email doesn't exist"""
exists = self.service.email_exists(db, "nonexistent@example.com")
assert exists is False
def test_username_exists_true(self, db, test_user):
"""Test username_exists returns True when username exists"""
exists = self.service.username_exists(db, test_user.username)
assert exists is True
def test_username_exists_false(self, db):
"""Test username_exists returns False when username doesn't exist"""
exists = self.service.username_exists(db, "nonexistentuser")
assert exists is False
def test_authenticate_user_success(self, db, test_user):
"""Test successful user authentication"""
user = self.service.authenticate_user(db, test_user.username, "testpass123")
assert user is not None
assert user.id == test_user.id
assert user.username == test_user.username
def test_authenticate_user_wrong_password(self, db, test_user):
"""Test authentication fails with wrong password"""
user = self.service.authenticate_user(db, test_user.username, "wrongpassword")
assert user is None
def test_authenticate_user_nonexistent(self, db):
"""Test authentication fails with nonexistent user"""
user = self.service.authenticate_user(db, "nonexistentuser", "password")
assert user is None
def test_create_access_token(self, test_user):
"""Test creating access token for user"""
token_data = self.service.create_access_token(test_user)
assert "access_token" in token_data
assert "token_type" in token_data
assert "expires_in" in token_data
assert token_data["token_type"] == "bearer"
assert isinstance(token_data["expires_in"], int)
assert token_data["expires_in"] > 0
def test_hash_password(self):
"""Test password hashing"""
password = "testpassword123"
hashed = self.service.hash_password(password)
assert hashed != password
assert len(hashed) > len(password)
assert hashed.startswith("$") # bcrypt hash format
def test_hash_password_different_results(self):
"""Test that hashing same password produces different hashes (salt)"""
password = "testpassword123"
hash1 = self.service.hash_password(password)
hash2 = self.service.hash_password(password)
assert hash1 != hash2 # Should be different due to salt