"""Unit tests for API endpoints without external dependencies.""" import json import pytest from unittest.mock import patch, MagicMock from app import create_app, db from chat_agent.models.chat_session import ChatSession from chat_agent.models.language_context import LanguageContext @pytest.fixture def app(): """Create test application.""" app = create_app('testing') with app.app_context(): db.create_all() yield app db.drop_all() @pytest.fixture def client(app): """Create test client.""" return app.test_client() @pytest.fixture def auth_headers(): """Create authentication headers for testing.""" return { 'X-User-ID': 'test-user-123', 'Content-Type': 'application/json' } class TestAPIEndpoints: """Test API endpoints functionality.""" def test_supported_languages_endpoint(self, client): """Test the supported languages endpoint.""" response = client.get('/api/v1/chat/languages') assert response.status_code == 200 data = json.loads(response.data) assert 'languages' in data assert 'default_language' in data assert 'total_count' in data assert data['default_language'] == 'python' assert data['total_count'] > 0 # Check that Python is in the supported languages language_codes = [lang['code'] for lang in data['languages']] assert 'python' in language_codes assert 'javascript' in language_codes @patch('chat_agent.api.chat_routes.get_services') def test_create_session_success(self, mock_get_services, client, auth_headers): """Test successful session creation.""" # Mock the services mock_session_manager = MagicMock() mock_chat_history_manager = MagicMock() mock_language_context_manager = MagicMock() # Create a mock session mock_session = MagicMock() mock_session.id = 'test-session-id' mock_session.user_id = 'test-user-123' mock_session.language = 'python' mock_session.created_at.isoformat.return_value = '2023-01-01T00:00:00' mock_session.message_count = 0 mock_session.session_metadata = {'test': True} mock_session_manager.create_session.return_value = mock_session mock_get_services.return_value = (mock_session_manager, mock_chat_history_manager, mock_language_context_manager) data = { 'language': 'python', 'metadata': {'test': True} } response = client.post( '/api/v1/chat/sessions', data=json.dumps(data), headers=auth_headers ) assert response.status_code == 201 response_data = json.loads(response.data) assert response_data['session_id'] == 'test-session-id' assert response_data['user_id'] == 'test-user-123' assert response_data['language'] == 'python' assert response_data['message_count'] == 0 # Verify the service was called correctly mock_session_manager.create_session.assert_called_once_with( user_id='test-user-123', language='python', session_metadata={'test': True} ) mock_language_context_manager.create_context.assert_called_once_with('test-session-id', 'python') def test_create_session_invalid_language(self, client, auth_headers): """Test session creation with invalid language.""" data = { 'language': 'invalid-language' } response = client.post( '/api/v1/chat/sessions', data=json.dumps(data), headers=auth_headers ) assert response.status_code == 400 response_data = json.loads(response.data) assert 'Unsupported language' in response_data['error'] def test_create_session_missing_auth(self, client): """Test session creation without authentication.""" data = { 'language': 'python' } response = client.post( '/api/v1/chat/sessions', data=json.dumps(data), headers={'Content-Type': 'application/json'} ) assert response.status_code == 401 response_data = json.loads(response.data) assert 'Authentication required' in response_data['error'] def test_create_session_missing_language(self, client, auth_headers): """Test session creation without required language field.""" data = { 'metadata': {'test': True} } response = client.post( '/api/v1/chat/sessions', data=json.dumps(data), headers=auth_headers ) assert response.status_code == 400 response_data = json.loads(response.data) assert 'Missing required fields' in response_data['error'] def test_invalid_json_request(self, client, auth_headers): """Test handling of invalid JSON requests.""" response = client.post( '/api/v1/chat/sessions', data='invalid json', headers=auth_headers ) assert response.status_code == 400 response_data = json.loads(response.data) assert 'Request must be JSON' in response_data['error'] def test_empty_request_body(self, client, auth_headers): """Test handling of empty request body.""" response = client.post( '/api/v1/chat/sessions', data='{}', headers=auth_headers ) assert response.status_code == 400 response_data = json.loads(response.data) assert 'Missing required fields' in response_data['error'] def test_non_existent_endpoint(self, client, auth_headers): """Test handling of non-existent endpoints.""" response = client.get( '/api/v1/chat/non-existent', headers=auth_headers ) assert response.status_code == 404 response_data = json.loads(response.data) assert 'Not found' in response_data['error'] @patch('chat_agent.api.chat_routes.get_services') def test_get_session_success(self, mock_get_services, client, auth_headers): """Test successful session retrieval.""" # Mock the services mock_session_manager = MagicMock() mock_chat_history_manager = MagicMock() mock_language_context_manager = MagicMock() # Create a mock session mock_session = MagicMock() mock_session.id = 'test-session-id' mock_session.user_id = 'test-user-123' mock_session.language = 'python' mock_session.created_at.isoformat.return_value = '2023-01-01T00:00:00' mock_session.last_active.isoformat.return_value = '2023-01-01T01:00:00' mock_session.message_count = 5 mock_session.is_active = True mock_session.session_metadata = {'test': True} mock_session_manager.get_session.return_value = mock_session mock_get_services.return_value = (mock_session_manager, mock_chat_history_manager, mock_language_context_manager) response = client.get( '/api/v1/chat/sessions/test-session-id', headers=auth_headers ) assert response.status_code == 200 response_data = json.loads(response.data) assert response_data['session_id'] == 'test-session-id' assert response_data['user_id'] == 'test-user-123' assert response_data['language'] == 'python' assert response_data['message_count'] == 5 assert response_data['is_active'] is True # Verify the service was called correctly mock_session_manager.get_session.assert_called_once_with('test-session-id') @patch('chat_agent.api.chat_routes.get_services') def test_get_session_wrong_user(self, mock_get_services, client): """Test getting session with wrong user.""" # Mock the services mock_session_manager = MagicMock() mock_chat_history_manager = MagicMock() mock_language_context_manager = MagicMock() # Create a mock session with different user mock_session = MagicMock() mock_session.user_id = 'different-user' mock_session_manager.get_session.return_value = mock_session mock_get_services.return_value = (mock_session_manager, mock_chat_history_manager, mock_language_context_manager) headers = { 'X-User-ID': 'test-user-123', 'Content-Type': 'application/json' } response = client.get( '/api/v1/chat/sessions/test-session-id', headers=headers ) assert response.status_code == 403 response_data = json.loads(response.data) assert 'Access denied' in response_data['error'] if __name__ == '__main__': pytest.main([__file__, '-v'])