Spaces:
Sleeping
Sleeping
| """ | |
| Simplified integration tests for authentication flows | |
| Focus on core functionality without complex session management | |
| """ | |
| import unittest | |
| from unittest.mock import Mock, patch, MagicMock | |
| from datetime import datetime | |
| from bson import ObjectId | |
| import json | |
| # Import the Flask app and models | |
| from app import app | |
| from models import User, ChatSession | |
| class TestSimpleAuthenticationFlows(unittest.TestCase): | |
| """Simplified integration tests for authentication flows""" | |
| def setUp(self): | |
| """Set up test client""" | |
| self.app = app | |
| self.app.config['TESTING'] = True | |
| self.app.config['WTF_CSRF_ENABLED'] = False | |
| self.app.config['SECRET_KEY'] = 'test-secret-key' | |
| self.client = self.app.test_client() | |
| self.test_user_data = { | |
| '_id': ObjectId(), | |
| 'email': 'test@example.com', | |
| 'password_hash': 'hashed_password', | |
| 'created_at': datetime.utcnow(), | |
| 'is_active': True | |
| } | |
| self.test_user = User(self.test_user_data) | |
| def test_registration_form_display(self): | |
| """Test that registration form is displayed correctly""" | |
| response = self.client.get('/register') | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Create Account', response.data) | |
| self.assertIn(b'email', response.data) | |
| self.assertIn(b'password', response.data) | |
| def test_login_form_display(self): | |
| """Test that login form is displayed correctly""" | |
| response = self.client.get('/login') | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Login to Chatty', response.data) | |
| self.assertIn(b'email', response.data) | |
| self.assertIn(b'password', response.data) | |
| def test_registration_with_valid_data(self): | |
| """Test registration with valid data""" | |
| with patch('models.get_users_collection') as mock_users_collection, \ | |
| patch('models.User.find_by_email') as mock_find_by_email, \ | |
| patch('models.User.validate_email_format', return_value=True), \ | |
| patch('models.User.validate_password_strength', return_value=True): | |
| # Setup mocks | |
| mock_collection = Mock() | |
| mock_users_collection.return_value = mock_collection | |
| mock_find_by_email.return_value = None # User doesn't exist | |
| mock_collection.insert_one.return_value = Mock(inserted_id=self.test_user_data['_id']) | |
| mock_collection.find_one.return_value = self.test_user_data | |
| registration_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123', | |
| 'confirm_password': 'password123' | |
| } | |
| response = self.client.post('/register', data=registration_data, follow_redirects=False) | |
| # Should redirect to login page | |
| self.assertEqual(response.status_code, 302) | |
| self.assertIn('/login', response.location) | |
| def test_registration_with_mismatched_passwords(self): | |
| """Test registration with mismatched passwords""" | |
| registration_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123', | |
| 'confirm_password': 'different_password' | |
| } | |
| response = self.client.post('/register', data=registration_data) | |
| # Should stay on registration page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Passwords do not match', response.data) | |
| def test_login_with_valid_credentials(self): | |
| """Test login with valid credentials""" | |
| with patch('models.User.find_by_email') as mock_find_by_email, \ | |
| patch.object(User, 'check_password', return_value=True): | |
| mock_find_by_email.return_value = self.test_user | |
| login_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123' | |
| } | |
| response = self.client.post('/login', data=login_data, follow_redirects=False) | |
| # Should redirect to chat interface | |
| self.assertEqual(response.status_code, 302) | |
| self.assertIn('/chat', response.location) | |
| def test_login_with_invalid_credentials(self): | |
| """Test login with invalid credentials""" | |
| with patch('models.User.find_by_email') as mock_find_by_email: | |
| mock_find_by_email.return_value = None # User doesn't exist | |
| login_data = { | |
| 'email': 'nonexistent@example.com', | |
| 'password': 'password123' | |
| } | |
| response = self.client.post('/login', data=login_data) | |
| # Should stay on login page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Invalid email or password', response.data) | |
| def test_unauthenticated_access_to_chat_redirects(self): | |
| """Test that unauthenticated users are redirected from chat page""" | |
| response = self.client.get('/chat', follow_redirects=False) | |
| # Should redirect to login | |
| self.assertEqual(response.status_code, 302) | |
| self.assertIn('/login', response.location) | |
| def test_unauthenticated_api_chat_request(self): | |
| """Test that unauthenticated API requests are rejected""" | |
| chat_data = { | |
| 'message': 'Hello, this should fail' | |
| } | |
| response = self.client.post( | |
| '/api/chat', | |
| data=json.dumps(chat_data), | |
| content_type='application/json' | |
| ) | |
| # Should return 401 or redirect | |
| self.assertIn(response.status_code, [401, 302]) | |
| def test_unauthenticated_history_request(self): | |
| """Test that unauthenticated history requests are rejected""" | |
| response = self.client.get('/api/user-history') | |
| # Should return 401 or redirect | |
| self.assertIn(response.status_code, [401, 302]) | |
| def test_root_route_redirects_to_login_when_unauthenticated(self): | |
| """Test that root route redirects to login for unauthenticated users""" | |
| response = self.client.get('/', follow_redirects=False) | |
| self.assertEqual(response.status_code, 302) | |
| self.assertIn('/login', response.location) | |
| def test_database_error_handling_in_login(self): | |
| """Test graceful handling of database errors during login""" | |
| with patch('models.User.find_by_email') as mock_find_by_email: | |
| mock_find_by_email.side_effect = Exception("Database connection failed") | |
| login_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123' | |
| } | |
| response = self.client.post('/login', data=login_data) | |
| # Should handle error gracefully | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'We're experiencing technical difficulties', response.data) | |
| def test_database_error_handling_in_registration(self): | |
| """Test graceful handling of database errors during registration""" | |
| with patch('models.User.create_user') as mock_create_user: | |
| mock_create_user.side_effect = Exception("Database connection failed") | |
| registration_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123', | |
| 'confirm_password': 'password123' | |
| } | |
| response = self.client.post('/register', data=registration_data) | |
| # Should handle error gracefully | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'We're experiencing technical difficulties', response.data) | |
| def test_weak_password_validation(self): | |
| """Test that weak passwords are rejected""" | |
| registration_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'weak', # Too short | |
| 'confirm_password': 'weak' | |
| } | |
| response = self.client.post('/register', data=registration_data) | |
| # Should stay on registration page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Password must be at least 8 characters long', response.data) | |
| def test_invalid_email_format_validation(self): | |
| """Test that invalid email formats are rejected""" | |
| registration_data = { | |
| 'email': 'invalid_email', # Invalid format | |
| 'password': 'password123', | |
| 'confirm_password': 'password123' | |
| } | |
| response = self.client.post('/register', data=registration_data) | |
| # Should stay on registration page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Please enter a valid email address', response.data) | |
| def test_existing_email_registration_attempt(self): | |
| """Test registration attempt with existing email""" | |
| with patch('models.User.find_by_email') as mock_find_by_email, \ | |
| patch('models.User.validate_email_format', return_value=True), \ | |
| patch('models.User.validate_password_strength', return_value=True): | |
| # User already exists | |
| mock_find_by_email.return_value = self.test_user | |
| registration_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123', | |
| 'confirm_password': 'password123' | |
| } | |
| response = self.client.post('/register', data=registration_data) | |
| # Should stay on registration page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Email already registered', response.data) | |
| def test_login_with_wrong_password(self): | |
| """Test login with correct email but wrong password""" | |
| with patch('models.User.find_by_email') as mock_find_by_email, \ | |
| patch.object(User, 'check_password', return_value=False): | |
| mock_find_by_email.return_value = self.test_user | |
| login_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'wrongpassword' | |
| } | |
| response = self.client.post('/login', data=login_data) | |
| # Should stay on login page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'Invalid email or password', response.data) | |
| def test_login_with_inactive_user(self): | |
| """Test login attempt with inactive user account""" | |
| # Create inactive user | |
| inactive_user_data = self.test_user_data.copy() | |
| inactive_user_data['is_active'] = False | |
| inactive_user = User(inactive_user_data) | |
| with patch('models.User.find_by_email') as mock_find_by_email: | |
| mock_find_by_email.return_value = inactive_user | |
| login_data = { | |
| 'email': 'test@example.com', | |
| 'password': 'password123' | |
| } | |
| response = self.client.post('/login', data=login_data) | |
| # Should stay on login page with error | |
| self.assertEqual(response.status_code, 200) | |
| self.assertIn(b'disabled', response.data) | |
| if __name__ == '__main__': | |
| unittest.main(verbosity=2) |