Skip to main content
Glama

Supabase MCP Server

Apache 2.0
797
  • Apple
  • Linux
test_tool_manager.py7.4 kB
from unittest.mock import MagicMock, mock_open, patch from supabase_mcp.tools.manager import ToolManager, ToolName class TestToolManager: """Tests for the ToolManager class.""" def test_singleton_pattern(self): """Test that ToolManager follows the singleton pattern.""" # Get two instances manager1 = ToolManager.get_instance() manager2 = ToolManager.get_instance() # They should be the same object assert manager1 is manager2 # Reset the singleton for other tests # pylint: disable=protected-access # We need to reset the singleton for test isolation ToolManager._instance = None # type: ignore @patch("supabase_mcp.tools.manager.Path") @patch("supabase_mcp.tools.manager.yaml.safe_load") def test_load_descriptions(self, mock_yaml_load: MagicMock, mock_path: MagicMock): """Test that descriptions are loaded correctly from YAML files.""" # Setup mock directory structure mock_file_path = MagicMock() mock_dir = MagicMock() # Mock the Path(__file__) call mock_path.return_value = mock_file_path mock_file_path.parent = mock_dir mock_dir.__truediv__.return_value = mock_dir # For the / operator # Mock directory existence check mock_dir.exists.return_value = True # Mock the glob to return some YAML files mock_file1 = MagicMock() mock_file1.name = "database_tools.yaml" mock_file2 = MagicMock() mock_file2.name = "api_tools.yaml" mock_dir.glob.return_value = [mock_file1, mock_file2] # Mock the file open and YAML load mock_yaml_data = {"get_schemas": "Description for get_schemas", "get_tables": "Description for get_tables"} mock_yaml_load.return_value = mock_yaml_data # Create a new instance to trigger _load_descriptions with patch("builtins.open", mock_open(read_data="dummy yaml content")): # We need to create the manager to trigger _load_descriptions ToolManager() # Verify the descriptions were loaded assert mock_dir.glob.call_count > 0 assert mock_dir.glob.call_args[0][0] == "*.yaml" assert mock_yaml_load.call_count >= 1 # Reset the singleton for other tests # pylint: disable=protected-access ToolManager._instance = None # type: ignore def test_get_description_valid_tool(self): """Test getting a description for a valid tool.""" # Setup manager = ToolManager.get_instance() # Force the descriptions to have a known value for testing # pylint: disable=protected-access # We need to set the descriptions directly for testing manager.descriptions = { ToolName.GET_SCHEMAS.value: "Description for get_schemas", ToolName.GET_TABLES.value: "Description for get_tables", } # Test description = manager.get_description(ToolName.GET_SCHEMAS.value) # Verify assert description == "Description for get_schemas" # Reset the singleton for other tests # pylint: disable=protected-access ToolManager._instance = None # type: ignore def test_get_description_invalid_tool(self): """Test getting a description for an invalid tool.""" # Setup manager = ToolManager.get_instance() # Force the descriptions to have a known value for testing # pylint: disable=protected-access # We need to set the descriptions directly for testing manager.descriptions = { ToolName.GET_SCHEMAS.value: "Description for get_schemas", ToolName.GET_TABLES.value: "Description for get_tables", } # Test and verify description = manager.get_description("nonexistent_tool") assert description == "" # The method returns an empty string for unknown tools # Reset the singleton for other tests # pylint: disable=protected-access ToolManager._instance = None # type: ignore def test_all_tool_names_have_descriptions(self): """Test that all tools defined in ToolName enum have descriptions.""" # Setup - get a fresh instance # Reset the singleton first to ensure we get a clean instance # pylint: disable=protected-access ToolManager._instance = None # type: ignore # Get a fresh instance that will load the real YAML files manager = ToolManager.get_instance() # Print the loaded descriptions for debugging print(f"\nLoaded descriptions: {manager.descriptions}") # Verify that we have at least some descriptions loaded assert len(manager.descriptions) > 0, "No descriptions were loaded" # Check that descriptions are not empty empty_descriptions: list[str] = [] for tool_name, description in manager.descriptions.items(): if not description or len(description.strip()) == 0: empty_descriptions.append(tool_name) # Fail if we found any empty descriptions assert len(empty_descriptions) == 0, f"Found empty descriptions for tools: {empty_descriptions}" # Check that at least some of the tool names have descriptions found_descriptions = 0 missing_descriptions: list[str] = [] for tool_name in ToolName: description = manager.get_description(tool_name.value) if description: found_descriptions += 1 else: missing_descriptions.append(tool_name.value) # Print missing descriptions for debugging if missing_descriptions: print(f"\nMissing descriptions for: {missing_descriptions}") # We should have at least some descriptions assert found_descriptions > 0, "No tool has a description" # Reset the singleton for other tests # pylint: disable=protected-access ToolManager._instance = None # type: ignore @patch.object(ToolManager, "_load_descriptions") def test_initialization_loads_descriptions(self, mock_load_descriptions: MagicMock): """Test that descriptions are loaded during initialization.""" # Create a new instance # We need to create the manager to trigger __init__ ToolManager() # Verify _load_descriptions was called assert mock_load_descriptions.call_count > 0 # Reset the singleton for other tests # pylint: disable=protected-access ToolManager._instance = None # type: ignore def test_tool_enum_completeness(self): """Test that the ToolName enum contains all expected tools.""" # Get all tool values from the enum tool_values = [tool.value for tool in ToolName] # Verify the total number of tools # Update this number when new tools are added expected_tool_count = 12 assert len(tool_values) == expected_tool_count, f"Expected {expected_tool_count} tools, got {len(tool_values)}" # Verify specific tools are included assert "retrieve_logs" in tool_values, "retrieve_logs tool is missing from ToolName enum" # Reset the singleton for other tests # pylint: disable=protected-access ToolManager._instance = None # type: ignore

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alexander-zuev/supabase-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server