""" 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"