"""Tests for UserService""" import pytest from sqlalchemy.ext.asyncio import AsyncSession from litestar.exceptions import PermissionDeniedException from sqlalchemy.exc import IntegrityError from chitai.services import UserService from chitai.database import models as m @pytest.mark.asyncio class TestUserServiceAuthentication: """Test authentication functionality.""" async def test_authenticate_success( self, session: AsyncSession, user_service: UserService ) -> None: """Test successful user authentication.""" # Create a user with a known password password = "password123" user = m.User(email=f"test@example.com", password=password) session.add(user) await session.commit() # Authenticate user authenticated_user = await user_service.authenticate( "test@example.com", password ) assert authenticated_user is not None assert authenticated_user.email == "test@example.com" assert authenticated_user.id == user.id async def test_authenticate_user_not_found( self, session: AsyncSession, user_service: UserService ) -> None: """Test authentication with non-existent user.""" with pytest.raises(PermissionDeniedException) as exc_info: await user_service.authenticate("nonexistent@example.com", "password") assert "User not found or password invalid" in str(exc_info.value) async def test_authenticate_wrong_password( self, session: AsyncSession, user_service: UserService ) -> None: """Test authentication with wrong password.""" # Create user password = "password123" user = m.User(email=f"test@example.com", password=password) session.add(user) await session.commit() # Attempt authentication with pytest.raises(PermissionDeniedException) as exc_info: await user_service.authenticate("test@example.com", "WrongPassword") assert "User not found or password invalid" in str(exc_info.value) @pytest.mark.asyncio class TestUserServiceCRUD: """Test basic CRUD operations.""" async def test_create_user_with_password_hashing( self, session: AsyncSession, user_service: UserService ) -> None: user_data = {"email": "newuser@example.com", "password": "password123"} user = await user_service.create(data=user_data) assert user.email == "newuser@example.com" assert user.password is not None assert user.password != "password123" # Password should be hashed assert user.password.verify("password123") async def test_get_user_by_email( self, session: AsyncSession, user_service: UserService ) -> None: """Test getting user by email.""" user = m.User(email=f"test@example.com", password="password123") session.add(user) await session.commit() found_user = await user_service.get_one_or_none(email="test@example.com") assert found_user is not None assert found_user.id == user.id assert found_user.email == user.email async def test_create_user_with_duplicate_email( self, session: AsyncSession, user_service: UserService ) -> None: """Test creating a new user with a duplicate email.""" # Create first user user = m.User(email=f"test@example.com", password="password123") session.add(user) await session.commit() # Create second user user = m.User(email=f"test@example.com", password="password12345") with pytest.raises(IntegrityError) as exc_info: session.add(user) await session.commit() assert "violates unique constraint" in str(exc_info.value)