""" Tests for call flow models and serialization. """ import pytest from models.call_flow import ActionType, CallFlow, CallFlowCreate, CallFlowStep, CallFlowSummary class TestCallFlowStep: """Test CallFlowStep model.""" def test_basic_dtmf_step(self): step = CallFlowStep( id="press_1", description="Press 1 for English", action=ActionType.DTMF, action_value="1", expect="for english|para espaƱol", next_step="main_menu", ) assert step.id == "press_1" assert step.action == ActionType.DTMF assert step.action_value == "1" assert step.timeout == 30 # default def test_hold_step(self): step = CallFlowStep( id="hold_queue", description="On hold waiting for agent", action=ActionType.HOLD, timeout=7200, next_step="agent_connected", notes="Average hold: 25-45 min. Plays Vivaldi. Kill me.", ) assert step.action == ActionType.HOLD assert step.timeout == 7200 assert "Vivaldi" in step.notes def test_transfer_step(self): step = CallFlowStep( id="connected", description="Agent picked up!", action=ActionType.TRANSFER, action_value="sip_phone", ) assert step.action == ActionType.TRANSFER class TestCallFlow: """Test CallFlow model.""" @pytest.fixture def sample_flow(self): return CallFlow( id="test-bank", name="Test Bank - Main Line", phone_number="+18005551234", description="Test bank IVR", steps=[ CallFlowStep( id="greeting", description="Language selection", action=ActionType.DTMF, action_value="1", expect="for english", next_step="main_menu", ), CallFlowStep( id="main_menu", description="Main menu", action=ActionType.LISTEN, next_step="agent_request", fallback_step="agent_request", ), CallFlowStep( id="agent_request", description="Request agent", action=ActionType.DTMF, action_value="0", next_step="hold_queue", ), CallFlowStep( id="hold_queue", description="Hold queue", action=ActionType.HOLD, timeout=3600, next_step="agent_connected", ), CallFlowStep( id="agent_connected", description="Agent connected", action=ActionType.TRANSFER, action_value="sip_phone", ), ], tags=["bank", "personal"], avg_hold_time=2100, success_rate=0.92, ) def test_step_count(self, sample_flow): assert len(sample_flow.steps) == 5 def test_get_step(self, sample_flow): step = sample_flow.get_step("hold_queue") assert step is not None assert step.action == ActionType.HOLD assert step.timeout == 3600 def test_get_step_not_found(self, sample_flow): assert sample_flow.get_step("nonexistent") is None def test_first_step(self, sample_flow): first = sample_flow.first_step() assert first is not None assert first.id == "greeting" def test_steps_by_id(self, sample_flow): steps = sample_flow.steps_by_id() assert len(steps) == 5 assert "greeting" in steps assert "agent_connected" in steps assert steps["agent_connected"].action == ActionType.TRANSFER def test_serialization_roundtrip(self, sample_flow): """Test JSON serialization and deserialization.""" json_str = sample_flow.model_dump_json() restored = CallFlow.model_validate_json(json_str) assert restored.id == sample_flow.id assert len(restored.steps) == len(sample_flow.steps) assert restored.steps[0].id == "greeting" assert restored.avg_hold_time == 2100 class TestCallFlowCreate: """Test call flow creation model.""" def test_minimal_create(self): create = CallFlowCreate( name="My Bank", phone_number="+18005551234", steps=[ CallFlowStep( id="start", description="Start", action=ActionType.HOLD, next_step="end", ), ], ) assert create.name == "My Bank" assert len(create.steps) == 1 assert create.tags == [] assert create.notes is None class TestCallFlowSummary: """Test lightweight summary model.""" def test_summary(self): summary = CallFlowSummary( id="chase-bank-main", name="Chase Bank - Main", phone_number="+18005551234", step_count=6, avg_hold_time=2100, success_rate=0.92, times_used=15, tags=["bank"], ) assert summary.step_count == 6 assert summary.success_rate == 0.92