Supabase MCP Server
by alexander-zuev
Verified
import httpx
import pytest
from supabase_mcp.exceptions import APIClientError, APIConnectionError
from supabase_mcp.services.api.api_client import ManagementAPIClient
@pytest.mark.asyncio(loop_scope="module")
@pytest.mark.integration
class TestAPIClient:
"""Integration tests for the API client."""
async def test_execute_get_request(self, api_client_integration: ManagementAPIClient):
"""Test executing a GET request to the API."""
# Make a simple GET request to a public endpoint
# Since /v1/health returns 404, we'll test the error handling instead
path = "/v1/health"
# Execute the request and expect a 404 error
with pytest.raises(APIClientError) as exc_info:
await api_client_integration.execute_request(
method="GET",
path=path,
)
# Verify the error details
assert exc_info.value.status_code == 404
assert "Cannot GET /v1/health" in str(exc_info.value)
# @pytest.mark.asyncio(loop_scope="function")
async def test_request_preparation(self, api_client_integration: ManagementAPIClient):
"""Test that requests are properly prepared with headers and parameters."""
# Prepare a request with parameters
method = "GET"
path = "/v1/health"
request_params = {"param1": "value1", "param2": "value2"}
# Prepare the request
request = api_client_integration.prepare_request(
method=method,
path=path,
request_params=request_params,
)
# Verify the request
assert request.method == method
assert path in str(request.url)
assert "param1=value1" in str(request.url)
assert "param2=value2" in str(request.url)
assert "Content-Type" in request.headers
assert request.headers["Content-Type"] == "application/json"
# @pytest.mark.asyncio(loop_scope="function")
async def test_error_handling(self, api_client_integration: ManagementAPIClient):
"""Test handling of API errors."""
# Make a request to a non-existent endpoint
path = "/v1/nonexistent-endpoint"
# Execute the request and expect an APIClientError (not APIResponseError)
with pytest.raises(APIClientError) as exc_info:
await api_client_integration.execute_request(
method="GET",
path=path,
)
# Verify the error details
assert exc_info.value.status_code == 404
assert "Cannot GET /v1/nonexistent-endpoint" in str(exc_info.value)
# @pytest.mark.asyncio(loop_scope="function")
async def test_request_with_body(self, api_client_integration: ManagementAPIClient):
"""Test executing a request with a body."""
# This test would normally make a POST request with a body
# Since we don't want to create real resources, we'll use a mock
# or a safe endpoint that accepts POST but doesn't modify anything
# For now, we'll just test the request preparation
method = "POST"
path = "/v1/health/check" # This is a hypothetical endpoint
request_body = {"test": "data", "nested": {"value": 123}}
# Prepare the request
request = api_client_integration.prepare_request(
method=method,
path=path,
request_body=request_body,
)
# Verify the request
assert request.method == method
assert path in str(request.url)
assert request.content # Should have content for the body
assert "Content-Type" in request.headers
assert request.headers["Content-Type"] == "application/json"
# @pytest.mark.asyncio(loop_scope="function")
async def test_response_parsing(self, api_client_integration: ManagementAPIClient):
"""Test parsing API responses."""
# Make a request to a public endpoint that returns JSON
path = "/v1/projects"
# Execute the request
response = await api_client_integration.execute_request(
method="GET",
path=path,
)
# Verify the response is parsed correctly
assert isinstance(response, list)
# The response is a list of projects, not a dict with a "projects" key
assert len(response) > 0
assert "id" in response[0]
# @pytest.mark.asyncio(loop_scope="function")
async def test_request_retry_mechanism(self, monkeypatch, api_client_integration: ManagementAPIClient):
"""Test that the tenacity retry mechanism works correctly for API requests."""
# Create a simple mock that always raises a network error
async def mock_send(*args, **kwargs):
raise httpx.NetworkError("Simulated network failure", request=None)
# Replace the client's send method with our mock
monkeypatch.setattr(api_client_integration.client, "send", mock_send)
# Execute a request - this should trigger retries and eventually fail
with pytest.raises(APIConnectionError) as exc_info:
await api_client_integration.execute_request(
method="GET",
path="/v1/projects",
)
# Verify the error message indicates retries were attempted
assert "Network error after 3 retry attempts" in str(exc_info.value)
# @pytest.mark.asyncio(loop_scope="function")
async def test_request_without_access_token(
self, monkeypatch: pytest.MonkeyPatch, api_client_integration: ManagementAPIClient
):
"""Test that an exception is raised when attempting to send a request without an access token."""
# Temporarily set the access token to None
monkeypatch.setattr(api_client_integration.settings, "supabase_access_token", None)
# Attempt to execute a request - should raise an exception
with pytest.raises(APIClientError):
await api_client_integration.execute_request(
method="GET",
path="/v1/projects",
)