test_handlers.py•15.5 kB
"""
Tests for handler classes and their search functionality.
"""
import pytest
from unittest.mock import Mock, patch, MagicMock
from elasticsearch_lib.handlers.simple import SimpleEntityHandler, ImpactHandler, UrgencyHandler, PriorityHandler
from elasticsearch_lib.handlers.model_based import ModelBasedEntityHandler, StatusHandler, CategoryHandler, SourceHandler
from elasticsearch_lib.handlers.hierarchical import HierarchicalEntityHandler, LocationHandler, DepartmentHandler
from elasticsearch_lib.handlers.complex import ComplexEntityHandler, UserGroupHandler, UserHandler, VendorHandler
from elasticsearch_lib.base.handler import SearchResult
from elasticsearch_lib.enums import EntityType
class TestBaseHandlerFunctionality:
    """Test cases for base handler functionality."""
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_handler_initialization(self, mock_client_manager):
        """Test handler initialization."""
        handler = ImpactHandler("test_tenant")
        
        assert handler.tenant_id == "test_tenant"
        assert hasattr(handler, 'entity')
        assert hasattr(handler, 'query_builder')
        assert hasattr(handler, 'client_manager')
    
    def test_get_index_name(self):
        """Test index name generation."""
        handler = ImpactHandler("test_tenant")
        index_name = handler.get_index_name()
        assert index_name == "test_tenant_impact"
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_process_search_response(self, mock_client_manager):
        """Test processing of search response."""
        handler = ImpactHandler("test_tenant")
        
        # Mock Elasticsearch response
        mock_response = {
            "hits": {
                "hits": [
                    {
                        "_source": {"name": "High", "dbid": "123"},
                        "_score": 5.5
                    },
                    {
                        "_source": {"name": "Medium", "dbid": "456"},
                        "_score": 3.2
                    }
                ]
            }
        }
        
        results = handler.process_search_response(mock_response)
        
        assert len(results) == 2
        assert isinstance(results[0], SearchResult)
        assert results[0].score == 5.5
        assert results[0].data["name"] == "High"
        assert results[1].score == 3.2
        assert results[1].data["name"] == "Medium"
class TestSimpleEntityHandlers:
    """Test cases for simple entity handlers."""
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_impact_handler(self, mock_client_manager):
        """Test ImpactHandler functionality."""
        handler = ImpactHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.IMPACT.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_urgency_handler(self, mock_client_manager):
        """Test UrgencyHandler functionality."""
        handler = UrgencyHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.URGENCY.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_priority_handler(self, mock_client_manager):
        """Test PriorityHandler functionality."""
        handler = PriorityHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.PRIORITY.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_simple_handler_search_by_name(self, mock_client_manager):
        """Test search by name functionality."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {"_source": {"name": "High Impact", "dbid": "123"}, "_score": 5.0}
                ]
            }
        }
        
        handler = ImpactHandler("test_tenant")
        results = handler.search_by_name("High", exact=False, limit=10)
        
        assert len(results) == 1
        assert results[0].data["name"] == "High Impact"
        mock_client.search.assert_called_once()
class TestModelBasedEntityHandlers:
    """Test cases for model-based entity handlers."""
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_status_handler(self, mock_client_manager):
        """Test StatusHandler functionality."""
        handler = StatusHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.STATUS.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_category_handler(self, mock_client_manager):
        """Test CategoryHandler functionality."""
        handler = CategoryHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.CATEGORY.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_source_handler(self, mock_client_manager):
        """Test SourceHandler functionality."""
        handler = SourceHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.SOURCE.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_model_based_search_with_model_filter(self, mock_client_manager):
        """Test search with model filtering."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {"_source": {"name": "Open", "model": "incident", "dbid": "123"}, "_score": 5.0}
                ]
            }
        }
        
        handler = StatusHandler("test_tenant")
        results = handler.search("Open", model="incident", limit=10)
        
        assert len(results) == 1
        assert results[0].data["name"] == "Open"
        mock_client.search.assert_called_once()
class TestHierarchicalEntityHandlers:
    """Test cases for hierarchical entity handlers."""
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_location_handler(self, mock_client_manager):
        """Test LocationHandler functionality."""
        handler = LocationHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.LOCATION.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_department_handler(self, mock_client_manager):
        """Test DepartmentHandler functionality."""
        handler = DepartmentHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.DEPARTMENT.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_hierarchical_search_by_hierarchy(self, mock_client_manager):
        """Test search by hierarchy functionality."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {"_source": {"name": "Building A", "hierarchy": "Campus > Building A", "dbid": "123"}, "_score": 5.0}
                ]
            }
        }
        
        handler = LocationHandler("test_tenant")
        results = handler.search_by_hierarchy("Building A", exact=False, limit=10)
        
        assert len(results) == 1
        assert results[0].data["name"] == "Building A"
        mock_client.search.assert_called_once()
class TestComplexEntityHandlers:
    """Test cases for complex entity handlers."""
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_user_group_handler(self, mock_client_manager):
        """Test UserGroupHandler functionality."""
        handler = UserGroupHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.USER_GROUP.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_user_handler(self, mock_client_manager):
        """Test UserHandler functionality."""
        handler = UserHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.USER.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_vendor_handler(self, mock_client_manager):
        """Test VendorHandler functionality."""
        handler = VendorHandler("test_tenant")
        assert handler.entity.get_entity_type() == EntityType.VENDOR.value
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_user_search_by_email(self, mock_client_manager):
        """Test user search by email functionality."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {
                        "_source": {
                            "user_name": "John Doe",
                            "user_email": "john.doe@example.com",
                            "user_userlogonname": "jdoe",
                            "user_contact": "123-456-7890",
                            "user_contact2": "098-765-4321",
                            "dbid": "123"
                        },
                        "_score": 5.0
                    }
                ]
            }
        }
        
        handler = UserHandler("test_tenant")
        results = handler.search_by_email("john.doe@example.com", exact=True, limit=10)
        
        assert len(results) == 1
        assert results[0].data["user_email"] == "john.doe@example.com"
        mock_client.search.assert_called_once()
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_user_search_by_logon_name(self, mock_client_manager):
        """Test user search by logon name functionality."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {
                        "_source": {
                            "user_name": "John Doe",
                            "user_email": "john.doe@example.com",
                            "user_userlogonname": "jdoe",
                            "dbid": "123"
                        },
                        "_score": 5.0
                    }
                ]
            }
        }
        
        handler = UserHandler("test_tenant")
        results = handler.search_by_logon_name("jdoe", exact=False, limit=10)
        
        assert len(results) == 1
        assert results[0].data["user_userlogonname"] == "jdoe"
        mock_client.search.assert_called_once()
class TestHandlerErrorHandling:
    """Test cases for handler error handling."""
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_search_with_elasticsearch_error(self, mock_client_manager):
        """Test handling of Elasticsearch errors."""
        # Mock client to raise an exception
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.side_effect = Exception("Elasticsearch connection failed")
        
        handler = ImpactHandler("test_tenant")
        results = handler.search_by_name("High", exact=False, limit=10)
        
        # Should return empty list on error
        assert results == []
    
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_search_with_invalid_limit(self, mock_client_manager):
        """Test handling of invalid limit values."""
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {"hits": {"hits": []}}
        
        handler = ImpactHandler("test_tenant")
        
        # Test with negative limit
        results = handler.search_by_name("High", exact=False, limit=-5)
        assert results == []
        
        # Test with very large limit
        results = handler.search_by_name("High", exact=False, limit=1000)
        # Should be clamped to maximum allowed
class TestHandlerIntegration:
    """Integration tests for handlers."""
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_multi_field_search(self, mock_client_manager):
        """Test multi-field search functionality."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {
                        "_source": {
                            "user_name": "John Doe",
                            "user_email": "john.doe@example.com",
                            "dbid": "123"
                        },
                        "_score": 5.0
                    }
                ]
            }
        }
        handler = UserHandler("test_tenant")
        results = handler.search_by_fields(
            user_name="John",
            user_email="john.doe@example.com",
            limit=10
        )
        assert len(results) == 1
        assert results[0].data["user_name"] == "John Doe"
        mock_client.search.assert_called_once()
    @patch('elasticsearch_lib.client.ElasticsearchClientManager')
    def test_search_result_data_mapping(self, mock_client_manager):
        """Test that search results are properly mapped."""
        # Mock the client and response
        mock_client = Mock()
        mock_client_manager.return_value.get_client.return_value = mock_client
        mock_client.search.return_value = {
            "hits": {
                "hits": [
                    {
                        "_source": {
                            "user_name": "Jane Smith",
                            "user_email": "jane.smith@example.com",
                            "user_userlogonname": "jsmith",
                            "user_contact": "555-1234",
                            "user_contact2": "555-5678",
                            "dbid": "456"
                        },
                        "_score": 7.5
                    }
                ]
            }
        }
        handler = UserHandler("test_tenant")
        results = handler.search("Jane", limit=10)
        assert len(results) == 1
        result = results[0]
        # Verify SearchResult structure
        assert isinstance(result, SearchResult)
        assert result.score == 7.5
        assert isinstance(result.data, dict)
        # Verify data mapping
        expected_data = {
            "name": "Jane Smith",
            "email": "jane.smith@example.com",
            "userLogonName": "jsmith",
            "contact": "555-1234",
            "contact2": "555-5678",
            "id": "456"
        }
        for key, expected_value in expected_data.items():
            assert result.data.get(key) == expected_value
if __name__ == "__main__":
    pytest.main([__file__])