minions-ai-agents/tests/test_models.py

172 lines
5.9 KiB
Python

"""
Tests for Pydantic Models (TenantContext, AuditLog).
Validates schema correctness and edge cases.
"""
import pytest
from datetime import datetime
from src.models.tenant import TenantContext, TenantStatus
from src.models.audit import AuditLog, ResolutionStatus, TicketContext
class TestTenantContext:
"""Tests for TenantContext model."""
def test_create_valid_tenant(self):
"""Test creating a valid tenant context."""
tenant = TenantContext(
id="tenant_test",
name="Test Company",
email_domains=["test.com.br", "test.net"],
status=TenantStatus.ACTIVE
)
assert tenant.id == "tenant_test"
assert tenant.name == "Test Company"
assert len(tenant.email_domains) == 2
assert tenant.status == TenantStatus.ACTIVE
assert tenant.rate_limit_per_hour == 10 # default
def test_tenant_with_all_fields(self):
"""Test tenant with all optional fields populated."""
tenant = TenantContext(
id="tenant_full",
name="Full Company",
email_domains=["full.com.br"],
status=TenantStatus.ACTIVE,
zabbix_host_group="FULL-Infrastructure",
qdrant_collection="full_knowledge",
rate_limit_per_hour=50,
created_at=datetime(2025, 1, 1, 10, 0, 0)
)
assert tenant.zabbix_host_group == "FULL-Infrastructure"
assert tenant.qdrant_collection == "full_knowledge"
assert tenant.rate_limit_per_hour == 50
def test_tenant_status_enum(self):
"""Test different tenant status values."""
active = TenantContext(
id="t1", name="Active", email_domains=["a.com"],
status=TenantStatus.ACTIVE
)
inactive = TenantContext(
id="t2", name="Inactive", email_domains=["i.com"],
status=TenantStatus.INACTIVE
)
suspended = TenantContext(
id="t3", name="Suspended", email_domains=["s.com"],
status=TenantStatus.SUSPENDED
)
assert active.status == TenantStatus.ACTIVE
assert inactive.status == TenantStatus.INACTIVE
assert suspended.status == TenantStatus.SUSPENDED
def test_tenant_serialization(self):
"""Test JSON serialization of tenant."""
tenant = TenantContext(
id="tenant_json",
name="JSON Test",
email_domains=["json.com"]
)
json_data = tenant.model_dump_json()
assert "tenant_json" in json_data
assert "JSON Test" in json_data
class TestAuditLog:
"""Tests for AuditLog model."""
def test_create_minimal_audit_log(self):
"""Test creating audit log with required fields only."""
log = AuditLog(
ticket_id="TKT-001",
tenant_id="tenant_test",
sender_email="user@test.com",
subject="Test Subject",
original_message="Test message content"
)
assert log.ticket_id == "TKT-001"
assert log.tenant_id == "tenant_test"
assert log.resolution_status == ResolutionStatus.PENDING
assert log.tools_called == []
assert log.created_at is not None
def test_create_full_audit_log(self):
"""Test creating audit log with all fields."""
context = TicketContext(
zabbix_data={"host": "srv-app01", "status": "down"},
rag_context=["Manual de troubleshooting"],
historical_tickets=[{"id": "TKT-000", "status": "resolved"}],
extracted_entities={"technology": "Windows Server", "problem": "Offline"}
)
log = AuditLog(
ticket_id="TKT-002",
tenant_id="tenant_full",
sender_email="admin@full.com",
subject="Server Down",
original_message="O servidor está offline desde às 10h",
context_collected=context,
triage_model_output="Classificado como: Infraestrutura",
specialist_model_reasoning="Análise indica falha de rede...",
response_sent="Prezado, identificamos o problema...",
tools_called=["zabbix_get_host", "rag_search"],
resolution_status=ResolutionStatus.RESOLVED,
processing_time_ms=2500
)
assert log.context_collected.zabbix_data["status"] == "down"
assert "zabbix_get_host" in log.tools_called
assert log.processing_time_ms == 2500
def test_resolution_status_transitions(self):
"""Test different resolution statuses."""
statuses = [
ResolutionStatus.PENDING,
ResolutionStatus.IN_PROGRESS,
ResolutionStatus.RESOLVED,
ResolutionStatus.ESCALATED,
ResolutionStatus.REOPENED,
ResolutionStatus.FAILED
]
for status in statuses:
log = AuditLog(
ticket_id=f"TKT-{status.value}",
tenant_id="tenant_test",
sender_email="test@test.com",
subject="Status Test",
original_message="Test",
resolution_status=status
)
assert log.resolution_status == status
class TestTicketContext:
"""Tests for TicketContext model."""
def test_empty_context(self):
"""Test creating empty ticket context."""
context = TicketContext()
assert context.zabbix_data is None
assert context.rag_context is None
assert context.historical_tickets is None
def test_partial_context(self):
"""Test creating context with some fields."""
context = TicketContext(
zabbix_data={"host": "srv-01"},
extracted_entities={"technology": "Linux"}
)
assert context.zabbix_data["host"] == "srv-01"
assert context.rag_context is None
assert context.extracted_entities["technology"] == "Linux"