"""Pytest configuration and shared fixtures for MCP SQL tests."""
import pytest
from unittest.mock import Mock, AsyncMock
from typing import Any, Optional
class MockCredentials:
"""Mock credentials object."""
def __init__(
self,
user: Optional[str] = "test_user",
password: Optional[str] = "test_pass",
server: Optional[str] = "test_server",
database: Optional[str] = "test_db",
driver: Optional[str] = "ODBC Driver 17 for SQL Server",
port: Optional[int] = 1433
):
self.user = user
self.password = password
self.server = server
self.database = database
self.driver = driver
self.port = port
def is_valid(self) -> bool:
"""Check if credentials are valid."""
return bool(self.user and self.password and self.server)
class MockContext:
"""Mock FastMCP Context."""
def __init__(self):
self.meta = {}
@pytest.fixture
def mock_context():
"""Create a mock FastMCP context."""
return MockContext()
@pytest.fixture
def mock_credentials():
"""Create mock credentials."""
return MockCredentials()
@pytest.fixture
def mock_invalid_credentials():
"""Create invalid mock credentials (missing required fields)."""
return MockCredentials(user=None, password=None, server=None)
@pytest.fixture
def mock_connection_manager():
"""Create a mock ConnectionManager."""
mock = Mock()
mock.get_configured_server_names = Mock(return_value=["server1", "server2", "server3"])
return mock
@pytest.fixture
def mock_credentials_manager(mock_credentials):
"""Create a mock CredentialsManager."""
mock = Mock()
mock.get_from_context = Mock(return_value=mock_credentials)
return mock
@pytest.fixture
def mock_credentials_manager_invalid(mock_invalid_credentials):
"""Create a mock CredentialsManager that returns invalid credentials."""
mock = Mock()
mock.get_from_context = Mock(return_value=mock_invalid_credentials)
return mock
@pytest.fixture
def mock_database_inspector():
"""Create a mock DatabaseInspector."""
mock = Mock()
# Mock get_databases
mock.get_databases = Mock(return_value=["db1", "db2", "db3"])
# Mock get_tables
mock.get_tables = Mock(return_value=["table1", "table2", "table3"])
# Mock describe_table
mock.describe_table = Mock(return_value={
"table_name": "test_table",
"columns": [
{"name": "id", "type": "int", "nullable": False},
{"name": "name", "type": "varchar", "nullable": True},
{"name": "created_at", "type": "datetime", "nullable": True}
],
"primary_key": ["id"],
"indexes": ["idx_name"],
"row_count": 100
})
return mock
@pytest.fixture
def mock_query_executor():
"""Create a mock QueryExecutor."""
mock = Mock()
# Mock execute_select_query
mock.execute_select_query = Mock(return_value={
"columns": ["id", "name", "created_at"],
"rows": [
[1, "Test 1", "2025-01-01"],
[2, "Test 2", "2025-01-02"]
],
"row_count": 2,
"execution_time": 0.05
})
# Mock query_columns
mock.query_columns = Mock(return_value=[
{"id": 1, "name": "Test 1"},
{"id": 2, "name": "Test 2"}
])
# Mock explore_table
mock.explore_table = Mock(return_value=[
{"id": 1, "name": "Test 1", "created_at": "2025-01-01"},
{"id": 2, "name": "Test 2", "created_at": "2025-01-02"},
{"id": 3, "name": "Test 3", "created_at": "2025-01-03"}
])
return mock
@pytest.fixture
def tool_dependencies(
mock_connection_manager,
mock_credentials_manager,
mock_database_inspector,
mock_query_executor
):
"""Bundle all tool dependencies together."""
return {
"connection_manager": mock_connection_manager,
"credentials_manager": mock_credentials_manager,
"inspector": mock_database_inspector,
"executor": mock_query_executor
}
@pytest.fixture
def tool_dependencies_invalid(
mock_connection_manager,
mock_credentials_manager_invalid,
mock_database_inspector,
mock_query_executor
):
"""Bundle all tool dependencies with invalid credentials."""
return {
"connection_manager": mock_connection_manager,
"credentials_manager": mock_credentials_manager_invalid,
"inspector": mock_database_inspector,
"executor": mock_query_executor
}