172 lines
5.9 KiB
Python
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"
|