Skip to main content
Glama

Supabase MCP Server

by deploya-labs
test_sdk_client_integration.py17.4 kB
import os import time import uuid from datetime import datetime import pytest import pytest_asyncio from supabase_mcp.exceptions import PythonSDKError from supabase_mcp.sdk_client.python_client import SupabaseSDKClient # Unique identifier for test users to avoid conflicts TEST_ID = f"test-{int(time.time())}-{uuid.uuid4().hex[:6]}" # Create unique test emails def get_test_email(prefix="user"): """Generate a unique test email""" return f"a.zuev+{prefix}-{TEST_ID}@outlook.com" @pytest_asyncio.fixture async def sdk_client(): """ Create a SupabaseSDKClient instance for integration testing. Uses environment variables directly. """ # Reset the singleton to ensure we get a fresh instance SupabaseSDKClient._instance = None # Get Supabase credentials from environment variables project_ref = os.environ.get("SUPABASE_PROJECT_REF") service_role_key = os.environ.get("SUPABASE_SERVICE_ROLE_KEY") if not project_ref or not service_role_key: pytest.skip("SUPABASE_PROJECT_REF or SUPABASE_SERVICE_ROLE_KEY environment variables not set") client = await SupabaseSDKClient.create(project_ref, service_role_key) yield client # Cleanup after tests SupabaseSDKClient._instance = None @pytest.mark.asyncio class TestSDKClientIntegration: """ Integration tests for the SupabaseSDKClient. These tests make actual API calls to the Supabase Auth service. """ async def test_list_users(self, sdk_client): """Test listing users with pagination""" # Create test parameters list_params = {"page": 1, "per_page": 10} # List users result = await sdk_client.call_auth_admin_method("list_users", list_params) # Verify response format assert result is not None assert hasattr(result, "__iter__") # Should be iterable (list of users) assert len(result) >= 0 # Should have users or be empty # Check that the first user has expected attributes if there are any users if len(result) > 0: first_user = result[0] assert hasattr(first_user, "id") assert hasattr(first_user, "email") assert hasattr(first_user, "user_metadata") # Test with invalid parameters (negative page number) invalid_params = {"page": -1, "per_page": 10} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("list_users", invalid_params) # The actual error message contains "Bad Pagination Parameters" instead of "Invalid parameters" assert "Bad Pagination Parameters" in str(excinfo.value) async def test_get_user_by_id(self, sdk_client): """Test retrieving a user by ID""" # First create a user to get test_email = get_test_email("get") create_params = { "email": test_email, "password": f"Password123!{TEST_ID}", "email_confirm": True, "user_metadata": {"name": "Test User", "test_id": TEST_ID}, } # Create the user create_result = await sdk_client.call_auth_admin_method("create_user", create_params) assert create_result is not None assert hasattr(create_result, "user") user_id = create_result.user.id try: # Get the user by ID get_params = {"uid": user_id} get_result = await sdk_client.call_auth_admin_method("get_user_by_id", get_params) # Verify user data assert get_result is not None assert hasattr(get_result, "user") assert get_result.user.id == user_id assert get_result.user.email == test_email assert get_result.user.user_metadata["test_id"] == TEST_ID # Test with invalid parameters (non-existent user ID) invalid_params = {"uid": "non-existent-user-id"} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("get_user_by_id", invalid_params) # The actual error message contains "user_id must be an UUID" instead of "user not found" assert "user_id must be an UUID" in str(excinfo.value) finally: # Clean up - delete the test user delete_params = {"id": user_id} await sdk_client.call_auth_admin_method("delete_user", delete_params) async def test_create_user(self, sdk_client): """Test creating a new user""" # Create a new test user test_email = get_test_email("create") create_params = { "email": test_email, "password": f"Password123!{TEST_ID}", "email_confirm": True, "user_metadata": {"name": "Test User", "test_id": TEST_ID}, } # Create the user create_result = await sdk_client.call_auth_admin_method("create_user", create_params) assert create_result is not None assert hasattr(create_result, "user") assert hasattr(create_result.user, "id") user_id = create_result.user.id try: # Verify user was created get_params = {"uid": user_id} get_result = await sdk_client.call_auth_admin_method("get_user_by_id", get_params) assert get_result is not None assert hasattr(get_result, "user") assert get_result.user.email == test_email # Test with invalid parameters (missing required fields) invalid_params = {"user_metadata": {"name": "Invalid User"}} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("create_user", invalid_params) assert "Invalid parameters" in str(excinfo.value) finally: # Clean up - delete the test user delete_params = {"id": user_id} await sdk_client.call_auth_admin_method("delete_user", delete_params) async def test_update_user_by_id(self, sdk_client): """Test updating a user's attributes""" # Create a new test user test_email = get_test_email("update") create_params = { "email": test_email, "password": f"Password123!{TEST_ID}", "email_confirm": True, "user_metadata": {"name": "Before Update", "test_id": TEST_ID}, } # Create the user create_result = await sdk_client.call_auth_admin_method("create_user", create_params) assert hasattr(create_result, "user") user_id = create_result.user.id try: # Update the user update_params = { "uid": user_id, "user_metadata": { "name": "After Update", "test_id": TEST_ID, "updated_at": datetime.now().isoformat(), }, } update_result = await sdk_client.call_auth_admin_method("update_user_by_id", update_params) # Verify user was updated assert update_result is not None assert hasattr(update_result, "user") assert update_result.user.id == user_id assert update_result.user.user_metadata["name"] == "After Update" assert "updated_at" in update_result.user.user_metadata # Test with invalid parameters (non-existent user ID) invalid_params = {"uid": "non-existent-user-id", "user_metadata": {"name": "Invalid Update"}} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("update_user_by_id", invalid_params) # The actual error message contains "user_id must be an uuid" instead of "user not found" assert "user_id must be an uuid" in str(excinfo.value).lower() finally: # Clean up - delete the test user delete_params = {"id": user_id} await sdk_client.call_auth_admin_method("delete_user", delete_params) async def test_delete_user(self, sdk_client): """Test deleting a user""" # Create a new test user test_email = get_test_email("delete") create_params = { "email": test_email, "password": f"Password123!{TEST_ID}", "email_confirm": True, "user_metadata": {"name": "Delete Test User", "test_id": TEST_ID}, } # Create the user create_result = await sdk_client.call_auth_admin_method("create_user", create_params) assert hasattr(create_result, "user") user_id = create_result.user.id # Delete the user delete_params = {"id": user_id} # The delete_user method returns None on success, so we just check that it doesn't raise an exception await sdk_client.call_auth_admin_method("delete_user", delete_params) # No need to assert on the result, as the API returns None on success # We'll verify deletion by trying to get the user and expecting an error # Verify user no longer exists get_params = {"uid": user_id} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("get_user_by_id", get_params) assert "user not found" in str(excinfo.value).lower() or "not found" in str(excinfo.value).lower() # Test with invalid parameters (non-UUID format user ID) invalid_params = {"id": "non-existent-user-id"} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("delete_user", invalid_params) # The API validates UUID format before checking if user exists assert "user_id must be an uuid" in str(excinfo.value).lower() async def test_invite_user_by_email(self, sdk_client): """Test inviting a user by email""" # Create invite parameters test_email = get_test_email("invite") invite_params = { "email": test_email, "options": {"data": {"name": "Invited User", "test_id": TEST_ID, "invited_at": datetime.now().isoformat()}}, } # Invite the user try: result = await sdk_client.call_auth_admin_method("invite_user_by_email", invite_params) # Verify response assert result is not None assert hasattr(result, "user") assert result.user.email == test_email assert hasattr(result.user, "invited_at") # Clean up - delete the invited user if hasattr(result.user, "id"): delete_params = {"id": result.user.id} await sdk_client.call_auth_admin_method("delete_user", delete_params) # Test with invalid parameters (missing email) invalid_params = {"options": {"data": {"name": "Invalid Invite"}}} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("invite_user_by_email", invalid_params) assert "Invalid parameters" in str(excinfo.value) except PythonSDKError as e: # Some Supabase instances may have email sending disabled, # so we'll check if the error is related to that if "sending emails is not configured" in str(e).lower(): pytest.skip("Email sending is not configured in this Supabase instance") else: raise async def test_generate_link(self, sdk_client): """Test generating authentication links""" # Test different link types link_types = ["signup", "magiclink", "recovery"] created_user_ids = [] for link_type in link_types: test_email = get_test_email(f"link-{link_type}") # For magiclink and recovery, we need to create the user first if link_type in ["magiclink", "recovery"]: # Create a user first create_params = { "email": test_email, "password": f"Password123!{TEST_ID}", "email_confirm": True, "user_metadata": {"name": f"{link_type.capitalize()} User", "test_id": TEST_ID}, } try: create_result = await sdk_client.call_auth_admin_method("create_user", create_params) if hasattr(create_result, "user") and hasattr(create_result.user, "id"): created_user_ids.append(create_result.user.id) except PythonSDKError as e: pytest.skip(f"Failed to create user for {link_type} test: {str(e)}") continue # Different parameters based on link type if link_type == "signup": link_params = { "type": link_type, "email": test_email, "password": f"Password123!{TEST_ID}", "options": { "data": {"name": f"{link_type.capitalize()} User", "test_id": TEST_ID}, "redirect_to": "https://example.com/welcome", }, } else: link_params = { "type": link_type, "email": test_email, "options": { "data": {"name": f"{link_type.capitalize()} User", "test_id": TEST_ID}, "redirect_to": "https://example.com/welcome", }, } try: # Generate link result = await sdk_client.call_auth_admin_method("generate_link", link_params) # Verify response assert result is not None assert hasattr(result, "properties") assert hasattr(result.properties, "action_link") # If a user was created during link generation (for signup), store ID for cleanup if hasattr(result, "user") and hasattr(result.user, "id"): created_user_ids.append(result.user.id) except PythonSDKError as e: # Some Supabase instances may have email sending disabled if "sending emails is not configured" in str(e).lower(): pytest.skip(f"Email sending is not configured for {link_type} links") else: raise # Test with invalid parameters (invalid link type) invalid_params = {"type": "invalid_type", "email": get_test_email("invalid")} with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method("generate_link", invalid_params) assert "Invalid parameters" in str(excinfo.value) or "invalid type" in str(excinfo.value).lower() # Clean up any created users for user_id in created_user_ids: try: delete_params = {"id": user_id} await sdk_client.call_auth_admin_method("delete_user", delete_params) except Exception: pass async def test_delete_factor(self, sdk_client): """Test deleting an MFA factor""" # Create a test user test_email = get_test_email("factor") create_params = { "email": test_email, "password": f"Password123!{TEST_ID}", "email_confirm": True, "user_metadata": {"name": "Factor Test User", "test_id": TEST_ID}, } # Create the user create_result = await sdk_client.call_auth_admin_method("create_user", create_params) assert hasattr(create_result, "user") user_id = create_result.user.id try: # Attempt to delete a factor (this will likely fail as the method is not implemented) delete_factor_params = {"user_id": user_id, "id": "non-existent-factor-id"} try: await sdk_client.call_auth_admin_method("delete_factor", delete_factor_params) # If it succeeds (unlikely), we should assert something assert False, "delete_factor should not succeed as it's not implemented" except PythonSDKError as e: # We expect this to fail with a specific error message assert "not implemented" in str(e).lower() or "method not found" in str(e).lower() finally: # Clean up - delete the test user delete_params = {"id": user_id} await sdk_client.call_auth_admin_method("delete_user", delete_params) async def test_empty_parameters(self, sdk_client): """Test validation errors with empty parameters for various methods""" # Test methods with empty parameters methods = ["get_user_by_id", "create_user", "update_user_by_id", "delete_user", "generate_link"] for method in methods: empty_params = {} # Should raise PythonSDKError containing validation error details with pytest.raises(PythonSDKError) as excinfo: await sdk_client.call_auth_admin_method(method, empty_params) # Verify error message contains validation info assert "Invalid parameters" in str(excinfo.value)

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/deploya-labs/mcp-supabase'

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