# tests/conftest.py
import pytest
import os
import json
import psycopg2
from psycopg2.extras import RealDictCursor
from unittest.mock import Mock, patch
from fastapi.testclient import TestClient
import sys

# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# Test configuration
TEST_DB_HOST = "postgresql-genesis-u50607.vm.elestio.app"
TEST_DB_PORT = "25432"
TEST_DB_NAME = "postgres"
TEST_DB_USER = "postgres"
TEST_DB_PASSWORD = "etY0eog17tD-dDuj--IRH"
TEST_SCHEMA = "genesis_bridge_test"

TELNYX_API_KEY = "KEY019BE7A3A2D749FCA8681CFF8448A7F0_vTMM1n77CtQxLDT2ra3P1z"
ASSISTANT_ID = "assistant-696799a5-e994-4ac1-8f26-7b0923aee682"
API_KEY = "test-api-key-12345"


@pytest.fixture(scope="session")
def db_connection():
    """Create a database connection for the test session."""
    conn = psycopg2.connect(
        host=TEST_DB_HOST,
        port=TEST_DB_PORT,
        database=TEST_DB_NAME,
        user=TEST_DB_USER,
        password=TEST_DB_PASSWORD,
        cursor_factory=RealDictCursor
    )
    conn.autocommit = True
    
    # Create test schema
    with conn.cursor() as cur:
        cur.execute(f"DROP SCHEMA IF EXISTS {TEST_SCHEMA} CASCADE")
        cur.execute(f"CREATE SCHEMA {TEST_SCHEMA}")
        
        # Create tables needed for testing
        cur.execute(f"""
            CREATE TABLE {TEST_SCHEMA}.directives (
                id SERIAL PRIMARY KEY,
                directive_text TEXT NOT NULL,
                priority INTEGER DEFAULT 5,
                directive_type VARCHAR(50) DEFAULT 'task',
                status VARCHAR(50) DEFAULT 'pending',
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                processed_at TIMESTAMP,
                telnyx_call_id VARCHAR(255)
            )
        """)
        
        cur.execute(f"""
            CREATE TABLE {TEST_SCHEMA}.claude_status (
                id SERIAL PRIMARY KEY,
                current_task TEXT,
                status VARCHAR(50),
                last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                history JSONB DEFAULT '[]'::jsonb
            )
        """)
    
    yield conn
    
    # Cleanup
    with conn.cursor() as cur:
        cur.execute(f"DROP SCHEMA IF EXISTS {TEST_SCHEMA} CASCADE")
    conn.close()


@pytest.fixture
def db_cursor(db_connection):
    """Provide a fresh cursor for each test."""
    cursor = db_connection.cursor()
    yield cursor
    cursor.close()


@pytest.fixture
def clean_tables(db_connection):
    """Clean tables before each test."""
    with db_connection.cursor() as cur:
        cur.execute(f"TRUNCATE TABLE {TEST_SCHEMA}.directives RESTART IDENTITY CASCADE")
        cur.execute(f"TRUNCATE TABLE {TEST_SCHEMA}.claude_status RESTART IDENTITY CASCADE")
    yield


@pytest.fixture
def mock_telnyx_api():
    """Mock Telnyx API responses."""
    with patch('requests.patch') as mock_patch, \
         patch('requests.get') as mock_get, \
         patch('requests.post') as mock_post:
        
        # Successful assistant update
        mock_patch.return_value = Mock(
            status_code=200,
            json=lambda: {
                "data": {
                    "id": ASSISTANT_ID,
                    "tools": [
                        {
                            "name": "relay_directive_to_claude",
                            "type": "function"
                        },
                        {
                            "name": "check_claude_status",
                            "type": "function"
                        }
                    ]
                }
            }
        )
        
        # Successful assistant retrieval
        mock_get.return_value = Mock(
            status_code=200,
            json=lambda: {
                "data": {
                    "id": ASSISTANT_ID,
                    "name": "AIVA Assistant",
                    "tools": []
                }
            }
        )
        
        yield {
            'patch': mock_patch,
            'get': mock_get,
            'post': mock_post
        }


@pytest.fixture
def tool_definitions():
    """Load tool definitions."""
    return {
        "relay_directive_to_claude": {
            "type": "function",
            "function": {
                "name": "relay_directive_to_claude",
                "description": "Relays Kinan's spoken directives to Claude Code for processing. Use this when Kinan gives a command, asks a question, or requests status updates.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "directive_text": {
                            "type": "string",
                            "description": "The exact text of Kinan's spoken directive"
                        },
                        "priority": {
                            "type": "integer",
                            "description": "Priority level from 1 (lowest) to 10 (critical)",
                            "minimum": 1,
                            "maximum": 10,
                            "default": 5
                        },
                        "directive_type": {
                            "type": "string",
                            "description": "Category of the directive",
                            "enum": ["task", "query", "status_request", "urgent"],
                            "default": "task"
                        }
                    },
                    "required": ["directive_text"]
                }
            }
        },
        "check_claude_status": {
            "type": "function",
            "function": {
                "name": "check_claude_status",
                "description": "Checks what Claude Code is currently working on and retrieves recent activity history.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "include_history": {
                            "type": "boolean",
                            "description": "Whether to include recent task history",
                            "default": False
                        },
                        "history_limit": {
                            "type": "integer",
                            "description": "Number of historical items to return if include_history is true",
                            "default": 5,
                            "minimum": 1,
                            "maximum": 20
                        }
                    }
                }
            }
        }
    }


@pytest.fixture
def sample_webhook_payloads():
    """Sample Telnyx webhook payloads."""
    return {
        "relay_directive": {
            "data": {
                "event_type": "tool_invocation",
                "id": "uuid-relay-123",
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": "Create a new Python module for user authentication",
                        "priority": 8,
                        "directive_type": "task"
                    }
                },
                "call_control_id": "call-123",
                "call_session_id": "session-456"
            }
        },
        "check_status": {
            "data": {
                "event_type": "tool_invocation",
                "id": "uuid-status-456",
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {
                        "include_history": True,
                        "history_limit": 3
                    }
                },
                "call_control_id": "call-789",
                "call_session_id": "session-012"
            }
        },
        "invalid_tool": {
            "data": {
                "event_type": "tool_invocation",
                "id": "uuid-invalid",
                "payload": {
                    "tool_name": "nonexistent_tool",
                    "arguments": {}
                }
            }
        }
    }


@pytest.fixture
def fastapi_app(db_connection):
    """Create FastAPI app instance for testing."""
    from fastapi import FastAPI, HTTPException, Header, Request
    from fastapi.responses import JSONResponse
    import logging
    import json
    
    app = FastAPI(title="AIVA Command Bridge Test")
    
    # Configure logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    TEST_SCHEMA = "genesis_bridge_test"
    
    def get_db_cursor():
        return db_connection.cursor()
    
    def verify_api_key(x_api_key: str = Header(None)):
        if x_api_key != API_KEY:
            raise HTTPException(status_code=401, detail="Invalid API key")
        return x_api_key
    
    @app.post("/bridge/telnyx/relay_directive")
    async def relay_directive(request: Request, x_api_key: str = Header(None)):
        """Handle relay_directive_to_claude tool invocation."""
        verify_api_key(x_api_key)
        
        try:
            payload = await request.json()
            logger.info(f"Received relay directive: {payload}")
            
            # Extract tool arguments
            data = payload.get("data", {})
            tool_payload = data.get("payload", {})
            arguments = tool_payload.get("arguments", {})
            
            directive_text = arguments.get("directive_text")
            priority = arguments.get("priority", 5)
            directive_type = arguments.get("directive_type", "task")
            call_id = data.get("call_control_id", "unknown")
            
            if not directive_text:
                raise HTTPException(status_code=400, detail="directive_text is required")
            
            # Insert into database
            cursor = get_db_cursor()
            cursor.execute(f"""
                INSERT INTO {TEST_SCHEMA}.directives 
                (directive_text, priority, directive_type, status, telnyx_call_id)
                VALUES (%s, %s, %s, %s, %s)
                RETURNING id
            """, (directive_text, priority, directive_type, "pending", call_id))
            
            result = cursor.fetchone()
            directive_id = result["id"]
            cursor.close()
            
            return {
                "status": "success",
                "directive_id": directive_id,
                "message": f"Directive queued with priority {priority}"
            }
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"Error processing relay directive: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    @app.post("/bridge/telnyx/check_status")
    async def check_status(request: Request, x_api_key: str = Header(None)):
        """Handle check_claude_status tool invocation."""
        verify_api_key(x_api_key)
        
        try:
            payload = await request.json()
            logger.info(f"Received status check: {payload}")
            
            # Extract arguments
            data = payload.get("data", {})
            tool_payload = data.get("payload", {})
            arguments = tool_payload.get("arguments", {})
            
            include_history = arguments.get("include_history", False)
            history_limit = arguments.get("history_limit", 5)
            
            # Query database for current status
            cursor = get_db_cursor()
            
            # Get latest status
            cursor.execute(f"""
                SELECT current_task, status, last_updated 
                FROM {TEST_SCHEMA}.claude_status 
                ORDER BY last_updated DESC 
                LIMIT 1
            """)
            
            status_row = cursor.fetchone()
            
            response = {
                "current_task": status_row["current_task"] if status_row else "Idle",
                "status": status_row["status"] if status_row else "available",
                "last_updated": status_row["last_updated"].isoformat() if status_row else None
            }
            
            # Get history if requested
            if include_history:
                cursor.execute(f"""
                    SELECT current_task, status, last_updated
                    FROM {TEST_SCHEMA}.claude_status 
                    ORDER BY last_updated DESC 
                    LIMIT %s
                """, (history_limit,))
                
                history_rows = cursor.fetchall()
                response["history"] = [
                    {
                        "task": row["current_task"],
                        "status": row["status"],
                        "timestamp": row["last_updated"].isoformat()
                    }
                    for row in history_rows
                ]
            
            cursor.close()
            
            return {
                "status": "success",
                "claude_status": response
            }
            
        except Exception as e:
            logger.error(f"Error checking status: {e}")
            raise HTTPException(status_code=500, detail=str(e))
    
    return app


@pytest.fixture
def client(fastapi_app):
    """Create test client."""
    from fastapi.testclient import TestClient
    return TestClient(fastapi_app)


# tests/test_tool_definitions.py
import pytest
import json
from jsonschema import validate, ValidationError


class TestToolDefinitions:
    """Test suite for Telnyx Voice Assistant tool definitions."""
    
    def test_relay_directive_schema_validity(self, tool_definitions):
        """Test that relay_directive_to_claude follows Telnyx function schema."""
        tool = tool_definitions["relay_directive_to_claude"]
        
        # Check top-level structure
        assert tool["type"] == "function"
        assert "function" in tool
        
        func = tool["function"]
        assert "name" in func
        assert "description" in func
        assert "parameters" in func
        
        # Check parameters schema
        params = func["parameters"]
        assert params["type"] == "object"
        assert "properties" in params
        assert "required" in params
        
        # Check specific properties
        props = params["properties"]
        assert "directive_text" in props
        assert props["directive_text"]["type"] == "string"
        
        assert "priority" in props
        assert props["priority"]["type"] == "integer"
        assert props["priority"]["minimum"] == 1
        assert props["priority"]["maximum"] == 10
        
        assert "directive_type" in props
        assert props["directive_type"]["type"] == "string"
        assert "enum" in props["directive_type"]
        assert set(props["directive_type"]["enum"]) == {"task", "query", "status_request", "urgent"}
        
        # Check required fields
        assert "directive_text" in params["required"]
    
    def test_check_claude_status_schema_validity(self, tool_definitions):
        """Test that check_claude_status follows Telnyx function schema."""
        tool = tool_definitions["check_claude_status"]
        
        assert tool["type"] == "function"
        func = tool["function"]
        
        assert func["name"] == "check_claude_status"
        assert "description" in func
        
        params = func["parameters"]
        props = params["properties"]
        
        assert "include_history" in props
        assert props["include_history"]["type"] == "boolean"
        assert props["include_history"]["default"] == False
        
        assert "history_limit" in props
        assert props["history_limit"]["type"] == "integer"
        assert props["history_limit"]["default"] == 5
        assert props["history_limit"]["minimum"] == 1
        assert props["history_limit"]["maximum"] == 20
    
    def test_relay_directive_json_serialization(self, tool_definitions):
        """Test that tool definition can be serialized to JSON."""
        tool = tool_definitions["relay_directive_to_claude"]
        try:
            json_str = json.dumps(tool)
            parsed = json.loads(json_str)
            assert parsed["function"]["name"] == "relay_directive_to_claude"
        except (TypeError, ValueError) as e:
            pytest.fail(f"JSON serialization failed: {e}")
    
    def test_check_status_json_serialization(self, tool_definitions):
        """Test that check_claude_status can be serialized to JSON."""
        tool = tool_definitions["check_claude_status"]
        json_str = json.dumps(tool)
        assert "check_claude_status" in json_str
    
    def test_tool_names_follow_convention(self, tool_definitions):
        """Test that tool names use snake_case."""
        for name in tool_definitions.keys():
            assert "_" in name or name.islower()
            assert " " not in name
    
    def test_descriptions_not_empty(self, tool_definitions):
        """Test that all tools have non-empty descriptions."""
        for tool in tool_definitions.values():
            desc = tool["function"]["description"]
            assert desc and len(desc) > 10


# tests/test_telnyx_registration.py
import pytest
import json
import os
from unittest.mock import Mock, patch, mock_open
import requests
import sys

# Import the registration script (we'll create it inline for testing)
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


class TestTelnyxRegistration:
    """Test suite for Telnyx Voice Assistant tool registration."""
    
    @pytest.fixture
    def registration_config(self):
        """Configuration for Telnyx registration."""
        return {
            "api_key": "KEY019BE7A3A2D749FCA8681CFF8448A7F0_vTMM1n77CtQxLDT2ra3P1z",
            "assistant_id": "assistant-696799a5-e994-4ac1-8f26-7b0923aee682",
            "webhook_base_url": "https://api.genesis.example.com"
        }
    
    @pytest.fixture
    def tool_payloads(self):
        """Sample tool payloads for registration."""
        return [
            {
                "type": "function",
                "function": {
                    "name": "relay_directive_to_claude",
                    "description": "Relay directive",
                    "parameters": {"type": "object", "properties": {}}
                }
            },
            {
                "type": "function",
                "function": {
                    "name": "check_claude_status",
                    "description": "Check status",
                    "parameters": {"type": "object", "properties": {}}
                }
            }
        ]
    
    def test_registration_payload_structure(self, registration_config, tool_payloads):
        """Test that registration payload follows Telnyx API structure."""
        payload = {
            "tools": tool_payloads,
            "webhook_url": f"{registration_config['webhook_base_url']}/bridge/telnyx/webhook"
        }
        
        assert "tools" in payload
        assert isinstance(payload["tools"], list)
        assert len(payload["tools"]) == 2
        
        for tool in payload["tools"]:
            assert "type" in tool
            assert "function" in tool
            assert "name" in tool["function"]
    
    @patch('requests.patch')
    def test_successful_registration(self, mock_patch, registration_config, tool_payloads):
        """Test successful tool registration with Telnyx API."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            "data": {
                "id": registration_config['assistant_id'],
                "tools": tool_payloads
            }
        }
        mock_patch.return_value = mock_response
        
        # Simulate registration
        url = f"https://api.telnyx.com/v2/ai/assistants/{registration_config['assistant_id']}"
        headers = {
            "Authorization": f"Bearer {registration_config['api_key']}",
            "Content-Type": "application/json"
        }
        payload = {"tools": tool_payloads}
        
        response = requests.patch(url, headers=headers, json=payload)
        
        assert response.status_code == 200
        assert mock_patch.called
        call_args = mock_patch.call_args
        assert call_args[0][0] == url
        assert call_args[1]['headers']['Authorization'] == f"Bearer {registration_config['api_key']}"
    
    @patch('requests.patch')
    def test_registration_api_error(self, mock_patch, registration_config):
        """Test handling of Telnyx API errors."""
        mock_response = Mock()
        mock_response.status_code = 401
        mock_response.json.return_value = {"errors": [{"title": "Authentication failed"}]}
        mock_patch.return_value = mock_response
        
        url = f"https://api.telnyx.com/v2/ai/assistants/{registration_config['assistant_id']}"
        headers = {"Authorization": f"Bearer {registration_config['api_key']}"}
        
        response = requests.patch(url, headers=headers, json={})
        
        assert response.status_code == 401
        data = response.json()
        assert "errors" in data
    
    @patch('requests.patch')
    def test_registration_network_error(self, mock_patch, registration_config):
        """Test handling of network failures."""
        mock_patch.side_effect = requests.exceptions.ConnectionError("Network unreachable")
        
        url = f"https://api.telnyx.com/v2/ai/assistants/{registration_config['assistant_id']}"
        
        with pytest.raises(requests.exceptions.ConnectionError):
            requests.patch(url, headers={}, json={})
    
    def test_tool_definition_validation(self, tool_definitions):
        """Test that tool definitions match Telnyx schema requirements."""
        for tool_name, tool_def in tool_definitions.items():
            # Must have type and function
            assert "type" in tool_def
            assert tool_def["type"] == "function"
            assert "function" in tool_def
            
            func = tool_def["function"]
            # Required fields
            assert "name" in func
            assert "description" in func
            assert "parameters" in func
            
            # Parameters must be object type with properties
            params = func["parameters"]
            assert params.get("type") == "object"
            assert "properties" in params
    
    def test_webhook_url_construction(self, registration_config):
        """Test webhook URL formatting."""
        base = registration_config['webhook_base_url']
        webhook_url = f"{base}/bridge/telnyx/webhook"
        
        assert webhook_url.startswith("https://")
        assert "/bridge/telnyx/" in webhook_url


# tests/test_webhook_handlers.py
import pytest
import json
from datetime import datetime
from unittest.mock import Mock, patch


class TestRelayDirectiveWebhook:
    """Test suite for relay_directive webhook endpoint."""
    
    def test_successful_directive_relay(self, client, db_cursor, clean_tables, sample_webhook_payloads):
        """Test successful processing of relay directive."""
        payload = sample_webhook_payloads["relay_directive"]
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        data = response.json()
        assert data["status"] == "success"
        assert "directive_id" in data
        assert data["message"] == "Directive queued with priority 8"
        
        # Verify database insertion
        db_cursor.execute(f"SELECT * FROM {TEST_SCHEMA}.directives WHERE id = %s", (data["directive_id"],))
        row = db_cursor.fetchone()
        assert row is not None
        assert row["directive_text"] == "Create a new Python module for user authentication"
        assert row["priority"] == 8
        assert row["directive_type"] == "task"
        assert row["status"] == "pending"
        assert row["telnyx_call_id"] == "call-123"
    
    def test_missing_directive_text(self, client, clean_tables):
        """Test validation of missing required field."""
        payload = {
            "data": {
                "event_type": "tool_invocation",
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "priority": 5,
                        "directive_type": "task"
                        # missing directive_text
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 400
        assert "directive_text" in response.json()["detail"].lower()
    
    def test_invalid_priority_range(self, client, clean_tables):
        """Test validation of priority out of range."""
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": "Test",
                        "priority": 15  # Invalid: > 10
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        # Should either validate or accept and clamp
        assert response.status_code in [200, 400, 422]
    
    def test_invalid_directive_type(self, client, clean_tables):
        """Test validation of invalid directive type enum."""
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": "Test",
                        "directive_type": "invalid_type"
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code in [200, 400, 422]
    
    def test_unauthorized_access(self, client, sample_webhook_payloads):
        """Test API key validation."""
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=sample_webhook_payloads["relay_directive"],
            headers={"X-API-Key": "wrong-key"}
        )
        
        assert response.status_code == 401
    
    def test_missing_api_key(self, client, sample_webhook_payloads):
        """Test request without API key."""
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=sample_webhook_payloads["relay_directive"]
        )
        
        assert response.status_code == 401
    
    def test_malformed_json_payload(self, client):
        """Test handling of malformed JSON."""
        response = client.post(
            "/bridge/telnyx/relay_directive",
            data="not valid json",
            headers={
                "X-API-Key": API_KEY,
                "Content-Type": "application/json"
            }
        )
        
        assert response.status_code == 422
    
    def test_database_connection_failure(self, client, sample_webhook_payloads, monkeypatch):
        """Test handling of database connection failures."""
        def mock_connect(*args, **kwargs):
            raise psycopg2.OperationalError("Connection refused")
        
        monkeypatch.setattr("psycopg2.connect", mock_connect)
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=sample_webhook_payloads["relay_directive"],
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 500


class TestCheckStatusWebhook:
    """Test suite for check_claude_status webhook endpoint."""
    
    def test_successful_status_check_no_history(self, client, db_cursor, clean_tables):
        """Test status check without history."""
        # Insert a status record
        db_cursor.execute(f"""
            INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
            VALUES ('Refactoring authentication module', 'working')
        """)
        
        payload = {
            "data": {
                "event_type": "tool_invocation",
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {
                        "include_history": False
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        data = response.json()
        assert data["status"] == "success"
        assert "claude_status" in data
        assert data["claude_status"]["current_task"] == "Refactoring authentication module"
        assert data["claude_status"]["status"] == "working"
        assert "history" not in data["claude_status"]
    
    def test_status_check_with_history(self, client, db_cursor, clean_tables):
        """Test status check with history retrieval."""
        # Insert multiple status records
        for i in range(5):
            db_cursor.execute(f"""
                INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
                VALUES ('Task {i}', 'completed')
            """)
        
        payload = {
            "data": {
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {
                        "include_history": True,
                        "history_limit": 3
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        data = response.json()
        assert "history" in data["claude_status"]
        assert len(data["claude_status"]["history"]) == 3
    
    def test_empty_status_database(self, client, clean_tables):
        """Test status check when no status records exist."""
        payload = {
            "data": {
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {}
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        data = response.json()
        assert data["claude_status"]["current_task"] == "Idle"
        assert data["claude_status"]["status"] == "available"
    
    def test_history_limit_bounds(self, client, db_cursor, clean_tables):
        """Test that history_limit respects bounds."""
        # Insert records
        for i in range(25):
            db_cursor.execute(f"""
                INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
                VALUES ('Task {i}', 'completed')
            """)
        
        # Request more than max allowed (20)
        payload = {
            "data": {
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {
                        "include_history": True,
                        "history_limit": 25  # Should be clamped to 20
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        # Should either error or clamp the value
        assert response.status_code in [200, 422]
        
        if response.status_code == 200:
            data = response.json()
            if "history" in data["claude_status"]:
                assert len(data["claude_status"]["history"]) <= 20
    
    def test_unauthorized_status_check(self, client):
        """Test unauthorized access to status endpoint."""
        response = client.post(
            "/bridge/telnyx/check_status",
            json={},
            headers={"X-API-Key": "invalid"}
        )
        
        assert response.status_code == 401


# tests/test_integration.py
import pytest
import json
import time
from unittest.mock import Mock, patch


class TestIntegration:
    """End-to-end integration tests."""
    
    def test_full_directive_flow(self, client, db_cursor, clean_tables, sample_webhook_payloads):
        """Test complete flow from webhook to database storage."""
        payload = sample_webhook_payloads["relay_directive"]
        
        # Submit directive
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        directive_id = response.json()["directive_id"]
        
        # Verify in database
        db_cursor.execute(
            f"SELECT * FROM {TEST_SCHEMA}.directives WHERE id = %s",
            (directive_id,)
        )
        row = db_cursor.fetchone()
        
        assert row is not None
        assert row["directive_text"] == "Create a new Python module for user authentication"
        assert row["priority"] == 8
        assert row["directive_type"] == "task"
        assert row["telnyx_call_id"] == "call-123"
        assert row["status"] == "pending"
    
    def test_status_check_after_directive(self, client, db_cursor, clean_tables):
        """Test status check reflects recent activity."""
        # Insert a directive first
        db_cursor.execute(f"""
            INSERT INTO {TEST_SCHEMA}.directives (directive_text, status, created_at)
            VALUES ('Test directive', 'processing', NOW())
        """)
        
        # Update status
        db_cursor.execute(f"""
            INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
            VALUES ('Processing Test directive', 'working')
        """)
        
        # Check status via API
        payload = {
            "data": {
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {"include_history": False}
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        data = response.json()
        assert data["claude_status"]["current_task"] == "Processing Test directive"
        assert data["claude_status"]["status"] == "working"
    
    def test_concurrent_directive_submission(self, client, db_cursor, clean_tables):
        """Test handling of concurrent directive submissions."""
        import threading
        import queue
        
        results = queue.Queue()
        payloads = []
        
        for i in range(5):
            payload = {
                "data": {
                    "payload": {
                        "tool_name": "relay_directive_to_claude",
                        "arguments": {
                            "directive_text": f"Concurrent task {i}",
                            "priority": i + 1
                        }
                    },
                    "call_control_id": f"call-{i}"
                }
            }
            payloads.append(payload)
        
        def submit_directive(payload):
            try:
                response = client.post(
                    "/bridge/telnyx/relay_directive",
                    json=payload,
                    headers={"X-API-Key": API_KEY}
                )
                results.put(("success", response.status_code))
            except Exception as e:
                results.put(("error", str(e)))
        
        threads = []
        for payload in payloads:
            t = threading.Thread(target=submit_directive, args=(payload,))
            threads.append(t)
            t.start()
        
        for t in threads:
            t.join()
        
        # Check all succeeded
        success_count = 0
        while not results.empty():
            status, _ = results.get()
            if status == "success":
                success_count += 1
        
        assert success_count == 5
        
        # Verify all in database
        db_cursor.execute(f"SELECT COUNT(*) as count FROM {TEST_SCHEMA}.directives")
        count = db_cursor.fetchone()["count"]
        assert count == 5
    
    def test_error_recovery_and_logging(self, client, db_cursor, clean_tables, sample_webhook_payloads, caplog):
        """Test that errors are properly logged and recovered."""
        import logging
        
        with caplog.at_level(logging.ERROR):
            # Test with malformed payload that should trigger error handling
            bad_payload = {
                "data": {
                    "payload": {
                        "tool_name": "relay_directive_to_claude",
                        "arguments": {
                            # Missing required directive_text
                            "priority": 5
                        }
                    }
                }
            }
            
            response = client.post(
                "/bridge/telnyx/relay_directive",
                json=bad_payload,
                headers={"X-API-Key": API_KEY}
            )
            
            assert response.status_code == 400
    
    def test_telnyx_webhook_signature_validation(self, client):
        """Test webhook signature validation if implemented."""
        # This would test webhook security validation
        # For now, test that endpoint requires API key
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json={},
            headers={"X-API-Key": "wrong-key"}
        )
        assert response.status_code == 401


# tests/test_edge_cases.py
import pytest
import json


class TestEdgeCases:
    """Edge case and boundary condition tests."""
    
    def test_very_long_directive_text(self, client, db_cursor, clean_tables):
        """Test handling of very long directive text."""
        long_text = "A" * 10000
        
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": long_text,
                        "priority": 5
                    }
                },
                "call_control_id": "call-long"
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        # Should either accept or reject with proper error
        assert response.status_code in [200, 400, 413]
        
        if response.status_code == 200:
            # Verify stored correctly
            db_cursor.execute(
                f"SELECT directive_text FROM {TEST_SCHEMA}.directives WHERE telnyx_call_id = %s",
                ("call-long",)
            )
            row = db_cursor.fetchone()
            assert row["directive_text"] == long_text
    
    def test_special_characters_in_directive(self, client, db_cursor, clean_tables):
        """Test handling of special characters and Unicode."""
        special_text = "Test with emojis 🚀 and special chars <>&\"' and Unicode 中文"
        
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": special_text,
                        "priority": 5
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        
        # Verify proper storage
        db_cursor.execute(f"SELECT * FROM {TEST_SCHEMA}.directives ORDER BY id DESC LIMIT 1")
        row = db_cursor.fetchone()
        assert row["directive_text"] == special_text
    
    def test_priority_boundary_values(self, client, clean_tables):
        """Test boundary values for priority (1 and 10)."""
        for priority in [1, 10]:
            payload = {
                "data": {
                    "payload": {
                        "tool_name": "relay_directive_to_claude",
                        "arguments": {
                            "directive_text": f"Test priority {priority}",
                            "priority": priority
                        }
                    }
                }
            }
            
            response = client.post(
                "/bridge/telnyx/relay_directive",
                json=payload,
                headers={"X-API-Key": API_KEY}
            )
            
            assert response.status_code == 200, f"Priority {priority} should be valid"
    
    def test_priority_out_of_bounds(self, client, clean_tables):
        """Test invalid priority values (0, 11, negative)."""
        invalid_priorities = [0, 11, -1, 100]
        
        for priority in invalid_priorities:
            payload = {
                "data": {
                    "payload": {
                        "tool_name": "relay_directive_to_claude",
                        "arguments": {
                            "directive_text": "Test",
                            "priority": priority
                        }
                    }
                }
            }
            
            response = client.post(
                "/bridge/telnyx/relay_directive",
                json=payload,
                headers={"X-API-Key": API_KEY}
            )
            
            # Should reject invalid priorities
            assert response.status_code in [400, 422, 200], f"Priority {priority} handling"
    
    def test_history_limit_bounds(self, client, db_cursor, clean_tables):
        """Test boundary values for history_limit (1 and 20)."""
        # Insert some history
        for i in range(25):
            db_cursor.execute(f"""
                INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
                VALUES ('Task {i}', 'completed')
            """)
        
        for limit in [1, 20]:
            payload = {
                "data": {
                    "payload": {
                        "tool_name": "check_claude_status",
                        "arguments": {
                            "include_history": True,
                            "history_limit": limit
                        }
                    }
                }
            }
            
            response = client.post(
                "/bridge/telnyx/check_status",
                json=payload,
                headers={"X-API-Key": API_KEY}
            )
            
            assert response.status_code == 200
            data = response.json()
            if "history" in data["claude_status"]:
                assert len(data["claude_status"]["history"]) <= limit
    
    def test_empty_history_request(self, client, clean_tables):
        """Test history request when no history exists."""
        payload = {
            "data": {
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {
                        "include_history": True,
                        "history_limit": 5
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        data = response.json()
        assert "history" in data["claude_status"]
        assert len(data["claude_status"]["history"]) == 0
    
    def test_invalid_tool_name(self, client, sample_webhook_payloads):
        """Test handling of unknown tool names."""
        payload = sample_webhook_payloads["invalid_tool"]
        
        # Try both endpoints with wrong tool
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        # Should either process (if endpoint doesn't validate tool name) or reject
        assert response.status_code in [200, 400, 404]
    
    def test_missing_call_control_id(self, client, clean_tables):
        """Test handling of missing call control ID."""
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": "Test without call ID"
                    }
                }
                # Missing call_control_id
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        # Should handle gracefully (either require it or use default)
        assert response.status_code in [200, 400]
    
    def test_concurrent_status_checks(self, client, db_cursor, clean_tables):
        """Test concurrent status check requests."""
        # Insert status
        db_cursor.execute(f"""
            INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
            VALUES ('Stable task', 'working')
        """)
        
        import threading
        results = []
        
        def check_status():
            payload = {
                "data": {
                    "payload": {
                        "tool_name": "check_claude_status",
                        "arguments": {}
                    }
                }
            }
            
            response = client.post(
                "/bridge/telnyx/check_status",
                json=payload,
                headers={"X-API-Key": API_KEY}
            )
            results.append(response.status_code)
        
        threads = [threading.Thread(target=check_status) for _ in range(10)]
        for t in threads:
            t.start()
        for t in threads:
            t.join()
        
        assert all(r == 200 for r in results)
        assert len(results) == 10


# tests/test_registration_script.py
import pytest
import json
import os
import sys
from unittest.mock import Mock, patch, mock_open
from io import StringIO


class TestRegistrationScript:
    """Tests for the Telnyx registration script."""
    
    @pytest.fixture
    def script_env(self):
        """Environment variables for script."""
        return {
            "TELNYX_API_KEY": "KEY019BE7A3A2D749FCA8681CFF8448A7F0_vTMM1n77CtQxLDT2ra3P1z",
            "ASSISTANT_ID": "assistant-696799a5-e994-4ac1-8f26-7b0923aee682",
            "WEBHOOK_BASE_URL": "https://api.genesis.example.com"
        }
    
    def test_script_loads_tool_definitions(self, tool_definitions):
        """Test that script can load tool definition files."""
        # Simulate loading JSON files
        for tool_name in ["relay_directive_to_claude", "check_claude_status"]:
            assert tool_name in tool_definitions
            assert tool_definitions[tool_name]["type"] == "function"
    
    def test_script_constructs_correct_payload(self, script_env, tool_definitions):
        """Test payload construction for Telnyx API."""
        tools = [
            tool_definitions["relay_directive_to_claude"],
            tool_definitions["check_claude_status"]
        ]
        
        payload = {
            "tools": tools,
            "webhook_url": f"{script_env['WEBHOOK_BASE_URL']}/bridge/telnyx/webhook"
        }
        
        assert len(payload["tools"]) == 2
        assert "relay_directive_to_claude" in str(payload)
        assert "check_claude_status" in str(payload)
    
    @patch('requests.patch')
    def test_script_handles_api_success(self, mock_patch, script_env, tool_definitions):
        """Test script handles successful API response."""
        mock_response = Mock()
        mock_response.status_code = 200
        mock_response.json.return_value = {
            "data": {
                "id": script_env["ASSISTANT_ID"],
                "tools": [tool_definitions["relay_directive_to_claude"]]
            }
        }
        mock_patch.return_value = mock_response
        
        # Simulate script execution
        url = f"https://api.telnyx.com/v2/ai/assistants/{script_env['ASSISTANT_ID']}"
        headers = {
            "Authorization": f"Bearer {script_env['TELNYX_API_KEY']}",
            "Content-Type": "application/json"
        }
        
        import requests
        response = requests.patch(url, headers=headers, json={"tools": [tool_definitions["relay_directive_to_claude"]]})
        
        assert response.status_code == 200
        assert mock_patch.called
    
    @patch('requests.patch')
    def test_script_handles_api_error(self, mock_patch, script_env):
        """Test script handles API error response."""
        mock_response = Mock()
        mock_response.status_code = 422
        mock_response.json.return_value = {
            "errors": [{"title": "Invalid tool definition"}]
        }
        mock_patch.return_value = mock_response
        
        import requests
        url = f"https://api.telnyx.com/v2/ai/assistants/{script_env['ASSISTANT_ID']}"
        
        response = requests.patch(url, headers={}, json={})
        
        assert response.status_code == 422
        data = response.json()
        assert "errors" in data
    
    def test_script_validates_environment_variables(self):
        """Test that script validates required env vars."""
        required_vars = [
            "TELNYX_API_KEY",
            "ASSISTANT_ID",
            "WEBHOOK_BASE_URL"
        ]
        
        # Simulate validation
        env_vars = {
            "TELNYX_API_KEY": "valid-key",
            "ASSISTANT_ID": "valid-id",
            "WEBHOOK_BASE_URL": "https://valid.url"
        }
        
        for var in required_vars:
            assert var in env_vars
            assert env_vars[var] is not None
            assert len(env_vars[var]) > 0
    
    def test_tool_parameter_types(self, tool_definitions):
        """Test that tool parameters have correct types."""
        relay = tool_definitions["relay_directive_to_claude"]["function"]["parameters"]["properties"]
        
        assert relay["directive_text"]["type"] == "string"
        assert relay["priority"]["type"] == "integer"
        assert relay["directive_type"]["type"] == "string"
        
        check = tool_definitions["check_claude_status"]["function"]["parameters"]["properties"]
        assert check["include_history"]["type"] == "boolean"
        assert check["history_limit"]["type"] == "integer"


# tests/test_database_operations.py
import pytest
import psycopg2
from psycopg2.extras import RealDictCursor


class TestDatabaseOperations:
    """Test database schema and operations."""
    
    def test_directives_table_schema(self, db_cursor):
        """Test directives table has correct schema."""
        db_cursor.execute(f"""
            SELECT column_name, data_type, is_nullable 
            FROM information_schema.columns 
            WHERE table_schema = '{TEST_SCHEMA}' 
            AND table_name = 'directives'
        """)
        
        columns = {row["column_name"]: row for row in db_cursor.fetchall()}
        
        required_columns = [
            "id", "directive_text", "priority", "directive_type",
            "status", "created_at", "telnyx_call_id"
        ]
        
        for col in required_columns:
            assert col in columns, f"Missing column: {col}"
        
        # Check specific types
        assert columns["id"]["data_type"] == "integer"
        assert columns["directive_text"]["data_type"] == "text"
        assert columns["priority"]["data_type"] == "integer"
    
    def test_claude_status_table_schema(self, db_cursor):
        """Test claude_status table has correct schema."""
        db_cursor.execute(f"""
            SELECT column_name, data_type 
            FROM information_schema.columns 
            WHERE table_schema = '{TEST_SCHEMA}' 
            AND table_name = 'claude_status'
        """)
        
        columns = {row["column_name"]: row for row in db_cursor.fetchall()}
        
        assert "id" in columns
        assert "current_task" in columns
        assert "status" in columns
        assert "last_updated" in columns
        assert "history" in columns
    
    def test_directive_insert_and_retrieve(self, db_cursor, clean_tables):
        """Test CRUD operations on directives."""
        # Insert
        db_cursor.execute(f"""
            INSERT INTO {TEST_SCHEMA}.directives 
            (directive_text, priority, directive_type, status, telnyx_call_id)
            VALUES (%s, %s, %s, %s, %s)
            RETURNING id
        """, ("Test directive", 5, "task", "pending", "call-test"))
        
        directive_id = db_cursor.fetchone()["id"]
        
        # Retrieve
        db_cursor.execute(
            f"SELECT * FROM {TEST_SCHEMA}.directives WHERE id = %s",
            (directive_id,)
        )
        row = db_cursor.fetchone()
        
        assert row["directive_text"] == "Test directive"
        assert row["priority"] == 5
    
    def test_concurrent_database_access(self, db_connection, clean_tables):
        """Test concurrent database operations."""
        import threading
        import queue
        
        results = queue.Queue()
        
        def insert_directive(idx):
            try:
                cursor = db_connection.cursor()
                cursor.execute(f"""
                    INSERT INTO {TEST_SCHEMA}.directives 
                    (directive_text, priority, directive_type)
                    VALUES (%s, %s, %s)
                """, (f"Concurrent {idx}", idx, "task"))
                cursor.close()
                results.put(("success", idx))
            except Exception as e:
                results.put(("error", str(e)))
        
        threads = [threading.Thread(target=insert_directive, args=(i,)) for i in range(10)]
        for t in threads:
            t.start()
        for t in threads:
            t.join()
        
        errors = []
        successes = []
        while not results.empty():
            status, val = results.get()
            if status == "error":
                errors.append(val)
            else:
                successes.append(val)
        
        assert len(errors) == 0, f"Concurrent errors: {errors}"
        assert len(successes) == 10
        
        # Verify count
        cursor = db_connection.cursor()
        cursor.execute(f"SELECT COUNT(*) as count FROM {TEST_SCHEMA}.directives")
        count = cursor.fetchone()["count"]
        cursor.close()
        assert count == 10
    
    def test_database_connection_failure_handling(self):
        """Test handling of database connection failures."""
        with pytest.raises(Exception):
            # Attempt connection with invalid credentials
            conn = psycopg2.connect(
                host="invalid.host",
                port="5432",
                database="postgres",
                user="invalid",
                password="wrong"
            )
    
    def test_telnyx_api_timeout_handling(self, mock_telnyx_api):
        """Test handling of Telnyx API timeouts."""
        mock_telnyx_api['patch'].side_effect = requests.exceptions.Timeout("Request timed out")
        
        with pytest.raises(requests.exceptions.Timeout):
            requests.patch(
                "https://api.telnyx.com/v2/ai/assistants/test",
                headers={"Authorization": "Bearer key"},
                json={"tools": []},
                timeout=5
            )


# tests/test_performance.py
import pytest
import time


class TestPerformance:
    """Performance and load tests."""
    
    def test_directive_insertion_performance(self, client, clean_tables):
        """Test that directive insertion completes within acceptable time."""
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": "Performance test directive",
                        "priority": 5
                    }
                }
            }
        }
        
        start_time = time.time()
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        end_time = time.time()
        
        assert response.status_code == 200
        assert (end_time - start_time) < 1.0  # Should complete in less than 1 second
    
    def test_status_check_performance(self, client, db_cursor, clean_tables):
        """Test status check performance with large history."""
        # Insert many status records
        for i in range(1000):
            db_cursor.execute(f"""
                INSERT INTO {TEST_SCHEMA}.claude_status (current_task, status)
                VALUES ('Task {i}', 'completed')
            """)
        
        payload = {
            "data": {
                "payload": {
                    "tool_name": "check_claude_status",
                    "arguments": {
                        "include_history": True,
                        "history_limit": 20
                    }
                }
            }
        }
        
        start_time = time.time()
        response = client.post(
            "/bridge/telnyx/check_status",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        end_time = time.time()
        
        assert response.status_code == 200
        assert (end_time - start_time) < 2.0  # Should complete in less than 2 seconds even with 1000 records


# tests/test_security.py
import pytest
import json


class TestSecurity:
    """Security-focused tests."""
    
    def test_sql_injection_attempt_in_directive(self, client, db_cursor, clean_tables):
        """Test that SQL injection attempts are sanitized."""
        malicious_text = "'; DROP TABLE directives; --"
        
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": malicious_text,
                        "priority": 5
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        # Should either reject or safely store
        if response.status_code == 200:
            # Verify table still exists and text stored as-is (parameterized query)
            db_cursor.execute(f"SELECT COUNT(*) as count FROM {TEST_SCHEMA}.directives")
            count = db_cursor.fetchone()["count"]
            assert count >= 1
            
            db_cursor.execute(
                f"SELECT directive_text FROM {TEST_SCHEMA}.directives WHERE directive_text = %s",
                (malicious_text,)
            )
            row = db_cursor.fetchone()
            assert row is not None
    
    def test_xss_attempt_in_directive(self, client, db_cursor, clean_tables):
        """Test that XSS attempts are handled."""
        xss_text = "<script>alert('xss')</script>"
        
        payload = {
            "data": {
                "payload": {
                    "tool_name": "relay_directive_to_claude",
                    "arguments": {
                        "directive_text": xss_text
                    }
                }
            }
        }
        
        response = client.post(
            "/bridge/telnyx/relay_directive",
            json=payload,
            headers={"X-API-Key": API_KEY}
        )
        
        assert response.status_code == 200
        
        # Verify stored (should be stored as-is, escaping is presentation layer)
        db_cursor.execute(
            f"SELECT directive_text FROM {TEST_SCHEMA}.directives WHERE directive_text = %s",
            (xss_text,)
        )
        assert db_cursor.fetchone() is not None
    
    def test_api_key_leakage_in_error_messages(self, client, clean_tables):
        """Test that API keys don't leak in error messages."""
        # Force an error by sending bad data
        response = client.post(
            "/bridge/telnyx/relay_directive",
            data="bad data",
            headers={
                "X-API-Key": API_KEY,
                "Content-Type": "application/json"
            }
        )
        
        # Check response doesn't contain API key
        response_text = response.text
        assert API_KEY not in response_text
        assert "KEY019" not in response_text
    
    def test_https_enforcement(self):
        """Test that webhook URLs use HTTPS."""
        webhook_url = "https://api.genesis.example.com/bridge/telnyx/webhook"
        assert webhook_url.startswith("https://")
        
        # Should reject HTTP
        bad_url = "http://api.genesis.example.com/bridge/telnyx/webhook"
        assert not bad_url.startswith("https://")


# pytest.ini
"""
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -v --tb=short --strict-markers
markers =
    integration: marks tests as integration tests (may require external services)
    slow: marks tests as slow (deselect with '-m "not slow"')
    security: marks tests as security-focused
"""

# requirements-test.txt
"""
pytest>=7.0.0
pytest-cov>=4.0.0
pytest-asyncio>=0.21.0
httpx>=0.24.0
requests>=2.31.0
psycopg2-binary>=2.9.0
fastapi>=0.100.0
pydantic>=2.0.0
jsonschema>=4.19.0
"""