""" Tests for Triage Agent. Tests entity extraction and classification logic. """ import pytest from unittest.mock import Mock, patch, AsyncMock from src.agents.triage_agent import ( TriageAgent, TriageResult, ExtractedEntities, Priority, Category, get_triage_agent ) class TestExtractedEntities: """Tests for ExtractedEntities dataclass.""" def test_default_values(self): """Test default entity values.""" entities = ExtractedEntities() assert entities.problem_summary == "" assert entities.hostname is None assert entities.category == Category.OTHER assert entities.priority == Priority.MEDIUM assert entities.is_urgent is False def test_with_values(self): """Test entity with values.""" entities = ExtractedEntities( hostname="srv-app01", ip_address="192.168.1.10", category=Category.INFRASTRUCTURE, priority=Priority.HIGH, is_urgent=True ) assert entities.hostname == "srv-app01" assert entities.priority == Priority.HIGH assert entities.is_urgent is True class TestTriageAgent: """Tests for TriageAgent class.""" @pytest.fixture def agent(self): """Create a triage agent with mocked dependencies.""" # Patch at module level before creating agent patcher1 = patch('src.agents.triage_agent.get_ollama_client') patcher2 = patch('src.agents.triage_agent.get_financial_client') mock_ollama = patcher1.start() mock_financial = patcher2.start() mock_ollama.return_value = Mock() mock_financial.return_value = Mock() agent = TriageAgent() yield agent patcher1.stop() patcher2.stop() def test_fallback_hostname_extraction(self, agent): """Test regex fallback for hostname extraction.""" content = "O servidor srv-app01 está com problema de memória" entities = ExtractedEntities() result = agent._fallback_extraction(content, entities) assert result.hostname == "srv-app01" def test_fallback_ip_extraction(self, agent): """Test regex fallback for IP extraction.""" content = "O servidor 192.168.1.50 não está respondendo" entities = ExtractedEntities() result = agent._fallback_extraction(content, entities) assert result.ip_address == "192.168.1.50" def test_fallback_service_extraction(self, agent): """Test regex fallback for service extraction.""" content = "O serviço nginx está retornando erro 502" entities = ExtractedEntities() result = agent._fallback_extraction(content, entities) assert result.service_name.lower() == "nginx" def test_urgency_detection(self, agent): """Test urgency keyword detection.""" content = "URGENTE: Sistema caiu e precisa de atenção imediata" entities = ExtractedEntities(priority=Priority.MEDIUM) result = agent._fallback_extraction(content, entities) assert result.is_urgent is True assert result.priority == Priority.HIGH def test_production_detection(self, agent): """Test production keyword detection.""" content = "Servidor de produção com clientes afetados" entities = ExtractedEntities(priority=Priority.MEDIUM) result = agent._fallback_extraction(content, entities) assert result.affects_production is True assert result.priority == Priority.HIGH def test_recommend_tools_with_host(self, agent): """Test tool recommendation with hostname.""" entities = ExtractedEntities( hostname="srv-db01", category=Category.DATABASE ) tenant = Mock() tenant.id = "tenant-001" tools = agent._recommend_tools(entities, tenant) assert "zabbix_get_host_status" in tools assert "zabbix_get_problems" in tools assert "rag_search_manuals" in tools def test_build_reasoning(self, agent): """Test reasoning generation.""" entities = ExtractedEntities( hostname="srv-app01", category=Category.INFRASTRUCTURE, priority=Priority.HIGH, is_urgent=True, affects_production=True, problem_summary="Servidor não responde" ) tenant = Mock() tenant.name = "OESTEPAN" reasoning = agent._build_reasoning(entities, tenant) assert "OESTEPAN" in reasoning assert "infrastructure" in reasoning assert "high" in reasoning assert "URGÊNCIA" in reasoning assert "PRODUÇÃO" in reasoning @pytest.mark.asyncio async def test_process_ticket_without_tenant(self, agent): """Test ticket processing when tenant cannot be resolved.""" agent._financial.get_tenant_by_email = AsyncMock(return_value=None) result = await agent.process_ticket( ticket_id="TKT-001", sender_email="unknown@unknowndomain.com", subject="Problema", body="Teste" ) assert result.success is False assert "Tenant não identificado" in result.error class TestTriageAgentSingleton: """Tests for singleton.""" def test_singleton(self): """Test singleton returns same instance.""" import src.agents.triage_agent as module module._triage_agent = None with patch('src.agents.triage_agent.get_ollama_client'), \ patch('src.agents.triage_agent.get_financial_client'): agent1 = get_triage_agent() agent2 = get_triage_agent() assert agent1 is agent2