1+ import pytest
2+ from unittest .mock import patch , MagicMock
3+ from fastapi import HTTPException , status
4+ from sqlalchemy .exc import IntegrityError
5+ from passlib .context import CryptContext
6+ from openai_api_client .dependencies .auth import create_access_token
7+ from openai_api_client .dependencies .database import get_db
8+ from openai_api_client .models .user import User
9+ from openai_api_client .schemas .user import UserCreate , User , UserLogin , Token
10+ from openai_api_client .services .user import user_service
11+
12+ # Load environment variables
13+ from openai_api_client .config import settings
14+
15+ # Initialize password hashing context
16+ pwd_context = CryptContext (schemes = ["bcrypt" ], deprecated = "auto" )
17+
18+ # Mock the database session for unit testing
19+ @pytest .fixture
20+ def mock_db ():
21+ with patch ("openai_api_client.services.user.get_db" ) as mock_get_db :
22+ mock_session = MagicMock (spec = Session )
23+ mock_get_db .return_value = mock_session
24+ yield mock_session
25+
26+ # Test cases for user registration
27+ class TestUserService_CreateUser :
28+ def test_create_user_success (self , mock_db ):
29+ """Test successful user creation with valid data."""
30+ request = UserCreate (username = "testuser" , email = "test@example.com" , password = "testpassword" )
31+ mock_db .add .return_value = None
32+ mock_db .commit .return_value = None
33+ mock_db .refresh .return_value = None
34+ service = user_service (db = mock_db )
35+ user = service .create_user (request )
36+ assert user .username == "testuser"
37+ assert user .email == "test@example.com"
38+ assert user .api_key is None
39+ mock_db .add .assert_called_once_with (User (username = "testuser" , email = "test@example.com" , password = pwd_context .hash ("testpassword" )))
40+ mock_db .commit .assert_called_once ()
41+ mock_db .refresh .assert_called_once_with (User (username = "testuser" , email = "test@example.com" , password = pwd_context .hash ("testpassword" )))
42+
43+ def test_create_user_username_exists (self , mock_db ):
44+ """Test handling of duplicate username."""
45+ request = UserCreate (username = "testuser" , email = "test@example.com" , password = "testpassword" )
46+ mock_db .add .side_effect = IntegrityError (None , None , "users_username_key" )
47+ mock_db .rollback .return_value = None
48+ service = user_service (db = mock_db )
49+ with pytest .raises (HTTPException ) as exc :
50+ service .create_user (request )
51+ assert exc .value .status_code == status .HTTP_400_BAD_REQUEST
52+ assert "Username already exists" in str (exc .value .detail )
53+
54+ def test_create_user_email_exists (self , mock_db ):
55+ """Test handling of duplicate email."""
56+ request = UserCreate (username = "testuser" , email = "test@example.com" , password = "testpassword" )
57+ mock_db .add .side_effect = IntegrityError (None , None , "users_email_key" )
58+ mock_db .rollback .return_value = None
59+ service = user_service (db = mock_db )
60+ with pytest .raises (HTTPException ) as exc :
61+ service .create_user (request )
62+ assert exc .value .status_code == status .HTTP_400_BAD_REQUEST
63+ assert "Email already exists" in str (exc .value .detail )
64+
65+ def test_create_user_general_error (self , mock_db ):
66+ """Test handling of general error during user creation."""
67+ request = UserCreate (username = "testuser" , email = "test@example.com" , password = "testpassword" )
68+ mock_db .add .side_effect = Exception ("General error" )
69+ mock_db .rollback .return_value = None
70+ service = user_service (db = mock_db )
71+ with pytest .raises (HTTPException ) as exc :
72+ service .create_user (request )
73+ assert exc .value .status_code == status .HTTP_500_INTERNAL_SERVER_ERROR
74+ assert "Error creating user" in str (exc .value .detail )
75+
76+ # Test cases for user authentication
77+ class TestUserService_AuthenticateUser :
78+ def test_authenticate_user_success (self , mock_db ):
79+ """Test successful user authentication with valid credentials."""
80+ request = UserLogin (email = "test@example.com" , password = "testpassword" )
81+ mock_db .query .return_value .filter .return_value .first .return_value = User (id = 1 , username = "testuser" , email = "test@example.com" , password = pwd_context .hash ("testpassword" ))
82+ service = user_service (db = mock_db )
83+ user = service .authenticate_user (request )
84+ assert user .id == 1
85+ assert user .username == "testuser"
86+ assert user .email == "test@example.com"
87+ mock_db .query .assert_called_once_with (User )
88+ mock_db .query (User ).filter .assert_called_once_with (User .email == "test@example.com" )
89+ mock_db .query (User ).filter (User .email == "test@example.com" ).first .assert_called_once ()
90+
91+ def test_authenticate_user_invalid_credentials (self , mock_db ):
92+ """Test handling of invalid email or password."""
93+ request = UserLogin (email = "test@example.com" , password = "testpassword" )
94+ mock_db .query .return_value .filter .return_value .first .return_value = None
95+ service = user_service (db = mock_db )
96+ with pytest .raises (HTTPException ) as exc :
97+ service .authenticate_user (request )
98+ assert exc .value .status_code == status .HTTP_401_UNAUTHORIZED
99+ assert "Invalid credentials" in str (exc .value .detail )
100+
101+ def test_authenticate_user_incorrect_password (self , mock_db ):
102+ """Test handling of incorrect password."""
103+ request = UserLogin (email = "test@example.com" , password = "wrongpassword" )
104+ mock_db .query .return_value .filter .return_value .first .return_value = User (id = 1 , username = "testuser" , email = "test@example.com" , password = pwd_context .hash ("testpassword" ))
105+ service = user_service (db = mock_db )
106+ with pytest .raises (HTTPException ) as exc :
107+ service .authenticate_user (request )
108+ assert exc .value .status_code == status .HTTP_401_UNAUTHORIZED
109+ assert "Incorrect password" in str (exc .value .detail )
110+
111+ # Test cases for retrieving user by ID
112+ class TestUserService_GetUserById :
113+ def test_get_user_by_id_success (self , mock_db ):
114+ """Test successful retrieval of a user by ID."""
115+ user_id = 1
116+ mock_db .query .return_value .filter .return_value .first .return_value = User (id = user_id , username = "testuser" , email = "test@example.com" , password = pwd_context .hash ("testpassword" ))
117+ service = user_service (db = mock_db )
118+ user = service .get_user_by_id (user_id )
119+ assert user .id == user_id
120+ assert user .username == "testuser"
121+ assert user .email == "test@example.com"
122+ mock_db .query .assert_called_once_with (User )
123+ mock_db .query (User ).filter .assert_called_once_with (User .id == user_id )
124+ mock_db .query (User ).filter (User .id == user_id ).first .assert_called_once ()
125+
126+ def test_get_user_by_id_not_found (self , mock_db ):
127+ """Test handling of user not found."""
128+ user_id = 1
129+ mock_db .query .return_value .filter .return_value .first .return_value = None
130+ service = user_service (db = mock_db )
131+ with pytest .raises (HTTPException ) as exc :
132+ service .get_user_by_id (user_id )
133+ assert exc .value .status_code == status .HTTP_404_NOT_FOUND
134+ assert "User not found" in str (exc .value .detail )
135+
136+ # Test cases for generating JWT access token
137+ class TestCreateAccessToken :
138+ def test_create_access_token (self ):
139+ """Test generating a JWT access token with valid user data."""
140+ user_id = 1
141+ data = {"sub" : user_id }
142+ token = create_access_token (data )
143+ # Verify the token structure and content
144+ assert isinstance (token , str )
145+ # (Add specific assertions based on your JWT token structure)
146+
147+ # Test cases for verifying JWT access token
148+ class TestVerifyAccessToken :
149+ # (Add test cases for `verify_access_token` function, similar to the above test cases)
150+
151+ # Test cases for retrieving the current user
152+ class TestGetCurrentUser :
153+ # (Add test cases for `get_current_user` function, similar to the above test cases)
0 commit comments