216 lines
6.8 KiB
Python
216 lines
6.8 KiB
Python
"""
|
|
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
|