""" Tests for Ticket Pipeline. Tests the complete orchestration flow. """ import pytest from unittest.mock import Mock, patch, AsyncMock from src.agents.pipeline import ( TicketPipeline, PipelineResult, get_ticket_pipeline ) from src.agents.triage_agent import TriageResult, ExtractedEntities, Priority, Category from src.agents.specialist_agent import SpecialistResponse, EnrichedContext class TestTicketPipeline: """Tests for TicketPipeline class.""" @pytest.fixture def pipeline(self): """Create pipeline with mocked agents.""" patcher1 = patch('src.agents.pipeline.get_triage_agent') patcher2 = patch('src.agents.pipeline.get_specialist_agent') mock_triage = patcher1.start() mock_specialist = patcher2.start() mock_triage.return_value = Mock() mock_specialist.return_value = Mock() pipeline = TicketPipeline() yield pipeline patcher1.stop() patcher2.stop() def test_generate_ticket_id(self, pipeline): """Test ticket ID generation.""" ticket_id = pipeline._generate_ticket_id() assert ticket_id.startswith("TKT-") assert len(ticket_id) == 21 # TKT-YYYYMMDD-XXXXXXXX def test_build_email_response(self, pipeline): """Test email response formatting.""" tenant = Mock() tenant.name = "OESTEPAN" triage = TriageResult( success=True, ticket_id="TKT-001", tenant=tenant, entities=ExtractedEntities(priority=Priority.HIGH), sanitized_content="", recommended_tools=[], reasoning="" ) specialist = SpecialistResponse( success=True, ticket_id="TKT-001", diagnosis="Problema de memória", recommended_actions=["Reiniciar serviço", "Verificar logs"], response_to_client="O problema foi identificado como falta de memória.", context_used=EnrichedContext(), model_reasoning="", confidence_score=0.9 ) response = pipeline._build_email_response( ticket_id="TKT-001", triage=triage, specialist=specialist, original_subject="Problema servidor" ) assert "TKT-001" in response assert "OESTEPAN" in response assert "HIGH" in response assert "Reiniciar serviço" in response assert "Arthur" in response def test_build_email_with_escalation(self, pipeline): """Test email response with escalation notice.""" tenant = Mock() tenant.name = "ENSEG" triage = TriageResult( success=True, ticket_id="TKT-002", tenant=tenant, entities=ExtractedEntities(priority=Priority.CRITICAL), sanitized_content="", recommended_tools=[], reasoning="" ) specialist = SpecialistResponse( success=True, ticket_id="TKT-002", diagnosis="Problema complexo", recommended_actions=[], response_to_client="Estamos analisando o problema.", context_used=EnrichedContext(), model_reasoning="", confidence_score=0.3, requires_escalation=True, escalation_reason="Requer acesso ao datacenter" ) response = pipeline._build_email_response( ticket_id="TKT-002", triage=triage, specialist=specialist, original_subject="Emergência" ) assert "escalado" in response.lower() assert "datacenter" in response @pytest.mark.asyncio async def test_process_email_success(self, pipeline): """Test successful email processing.""" # Mock tenant tenant = Mock() tenant.id = "tenant-001" tenant.name = "OESTEPAN" # Mock triage result triage_result = TriageResult( success=True, ticket_id="TKT-001", tenant=tenant, entities=ExtractedEntities( hostname="srv-app01", priority=Priority.HIGH, category=Category.INFRASTRUCTURE ), sanitized_content="Conteúdo sanitizado", recommended_tools=["zabbix_get_status"], reasoning="Ticket urgente" ) pipeline._triage.process_ticket = AsyncMock(return_value=triage_result) # Mock specialist result specialist_result = SpecialistResponse( success=True, ticket_id="TKT-001", diagnosis="Servidor sobrecarregado", recommended_actions=["Reiniciar"], response_to_client="Identificamos sobrecarga no servidor.", context_used=EnrichedContext(), model_reasoning="Análise completa", confidence_score=0.85 ) pipeline._specialist.process = AsyncMock(return_value=specialist_result) # Mock audit log creation to avoid dependency issues pipeline._create_audit_log = Mock(return_value=Mock()) result = await pipeline.process_email( sender_email="joao@oestepan.com.br", subject="Servidor lento", body="O servidor srv-app01 está muito lento" ) assert result.success is True assert result.triage is not None assert result.specialist is not None assert result.email_response is not None @pytest.mark.asyncio async def test_process_email_triage_failure(self, pipeline): """Test email processing with triage failure.""" triage_result = TriageResult( success=False, ticket_id="TKT-001", tenant=None, entities=ExtractedEntities(), sanitized_content="", recommended_tools=[], reasoning="", error="Tenant não encontrado" ) pipeline._triage.process_ticket = AsyncMock(return_value=triage_result) result = await pipeline.process_email( sender_email="unknown@test.com", subject="Teste", body="Teste" ) assert result.success is False assert "Tenant" in result.error class TestPipelineSingleton: """Tests for singleton.""" def test_singleton(self): """Test singleton pattern.""" import src.agents.pipeline as module module._pipeline = None with patch('src.agents.pipeline.get_triage_agent'), \ patch('src.agents.pipeline.get_specialist_agent'): p1 = get_ticket_pipeline() p2 = get_ticket_pipeline() assert p1 is p2