Skip to main content
Glama
test_client.py12.4 kB
"""Tests for DeBank API client.""" import pytest from unittest.mock import AsyncMock, patch, MagicMock import httpx class TestDeBankClientInitialization: """Test DeBank client initialization.""" def test_client_initialization_with_key(self, debank_api_key): """Test that client initializes correctly with API key.""" from mcp_server_debank.client import DeBankClient client = DeBankClient(access_key=debank_api_key) assert client.access_key == debank_api_key def test_client_initialization_from_env(self, mock_env): """Test that client reads API key from environment.""" from mcp_server_debank.client import DeBankClient client = DeBankClient() assert client.access_key is not None def test_client_initialization_no_key(self, monkeypatch): """Test that client raises error without API key.""" from mcp_server_debank.client import DeBankClient monkeypatch.delenv("DEBANK_ACCESS_KEY", raising=False) with pytest.raises(ValueError, match="API key"): DeBankClient() def test_client_base_url_set(self, debank_api_key): """Test that base URL is properly set.""" from mcp_server_debank.client import DeBankClient client = DeBankClient(access_key=debank_api_key) assert "debank.com" in client.base_url or "cloud.debank" in client.base_url class TestDeBankClientGetRequest: """Test GET request functionality.""" @pytest.mark.asyncio async def test_get_request_success(self, debank_api_key, mock_response_chains): """Test successful GET request.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = mock_response_chains mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) result = await client.get("/v1/chain/list") assert result == mock_response_chains mock_get.assert_called_once() @pytest.mark.asyncio async def test_get_request_with_params(self, debank_api_key): """Test GET request with query parameters.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = {"data": []} mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) params = {"chain_id": "eth", "limit": 20} await client.get("/v1/user/tokens", params=params) # Verify params were passed call_kwargs = mock_get.call_args[1] assert "params" in call_kwargs assert call_kwargs["params"]["chain_id"] == "eth" @pytest.mark.asyncio async def test_get_request_with_headers(self, debank_api_key): """Test that authorization header is included.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = {} mock_response.raise_for_status = MagicMock() mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) await client.get("/v1/chain/list") # Verify authorization header call_kwargs = mock_get.call_args[1] assert "headers" in call_kwargs assert debank_api_key in str(call_kwargs["headers"]) class TestDeBankClientPostRequest: """Test POST request functionality.""" @pytest.mark.asyncio async def test_post_request_success(self, debank_api_key, sample_transaction, mock_response_simulate_tx): """Test successful POST request.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.post") as mock_post: mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = mock_response_simulate_tx mock_response.raise_for_status = MagicMock() mock_post.return_value = mock_response client = DeBankClient(access_key=debank_api_key) result = await client.post("/v1/tx/simulate", json=sample_transaction) assert result == mock_response_simulate_tx mock_post.assert_called_once() @pytest.mark.asyncio async def test_post_request_with_json_body(self, debank_api_key, sample_transaction): """Test POST request with JSON body.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.post") as mock_post: mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = {} mock_response.raise_for_status = MagicMock() mock_post.return_value = mock_response client = DeBankClient(access_key=debank_api_key) await client.post("/v1/tx/simulate", json=sample_transaction) # Verify JSON body was passed call_kwargs = mock_post.call_args[1] assert "json" in call_kwargs assert call_kwargs["json"] == sample_transaction class TestDeBankClientErrorHandling: """Test error handling for various HTTP status codes.""" @pytest.mark.asyncio async def test_401_unauthorized(self, debank_api_key): """Test handling of 401 Unauthorized error.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 401 mock_response.raise_for_status.side_effect = httpx.HTTPStatusError( "Unauthorized", request=MagicMock(), response=mock_response ) mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) with pytest.raises(Exception, match="401|Unauthorized|API key"): await client.get("/v1/chain/list") @pytest.mark.asyncio async def test_403_forbidden(self, debank_api_key): """Test handling of 403 Forbidden error.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 403 mock_response.raise_for_status.side_effect = httpx.HTTPStatusError( "Forbidden", request=MagicMock(), response=mock_response ) mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) with pytest.raises(Exception, match="403|Forbidden|permission"): await client.get("/v1/chain/list") @pytest.mark.asyncio async def test_429_rate_limit(self, debank_api_key): """Test handling of 429 Rate Limit error.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 429 mock_response.raise_for_status.side_effect = httpx.HTTPStatusError( "Too Many Requests", request=MagicMock(), response=mock_response ) mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) with pytest.raises(Exception, match="429|rate limit|Too Many"): await client.get("/v1/chain/list") @pytest.mark.asyncio async def test_500_server_error(self, debank_api_key): """Test handling of 500 Server Error.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 500 mock_response.raise_for_status.side_effect = httpx.HTTPStatusError( "Internal Server Error", request=MagicMock(), response=mock_response ) mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key) with pytest.raises(Exception, match="500|server error|Internal"): await client.get("/v1/chain/list") @pytest.mark.asyncio async def test_network_error(self, debank_api_key): """Test handling of network errors.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_get.side_effect = httpx.NetworkError("Connection failed") client = DeBankClient(access_key=debank_api_key) with pytest.raises(Exception, match="network|connection"): await client.get("/v1/chain/list") @pytest.mark.asyncio async def test_timeout_error(self, debank_api_key): """Test handling of timeout errors.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_get.side_effect = httpx.TimeoutException("Request timeout") client = DeBankClient(access_key=debank_api_key) with pytest.raises(Exception, match="timeout"): await client.get("/v1/chain/list") class TestDeBankClientRetryLogic: """Test retry logic for transient failures.""" @pytest.mark.asyncio async def test_retry_on_network_error(self, debank_api_key): """Test that client retries on network errors.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: # Fail twice, then succeed mock_get.side_effect = [ httpx.NetworkError("Connection failed"), httpx.NetworkError("Connection failed"), MagicMock(status_code=200, json=lambda: {"data": []}) ] client = DeBankClient(access_key=debank_api_key, max_retries=3) # Should eventually succeed result = await client.get("/v1/chain/list") assert result == {"data": []} assert mock_get.call_count == 3 @pytest.mark.asyncio async def test_no_retry_on_client_error(self, debank_api_key): """Test that client doesn't retry on 4xx errors.""" from mcp_server_debank.client import DeBankClient with patch("httpx.AsyncClient.get") as mock_get: mock_response = MagicMock() mock_response.status_code = 400 mock_response.raise_for_status.side_effect = httpx.HTTPStatusError( "Bad Request", request=MagicMock(), response=mock_response ) mock_get.return_value = mock_response client = DeBankClient(access_key=debank_api_key, max_retries=3) with pytest.raises(Exception): await client.get("/v1/chain/list") # Should only call once (no retries for 4xx) assert mock_get.call_count == 1 class TestDeBankClientContextManager: """Test client context manager functionality.""" @pytest.mark.asyncio async def test_context_manager_usage(self, debank_api_key): """Test that client works as async context manager.""" from mcp_server_debank.client import DeBankClient async with DeBankClient(access_key=debank_api_key) as client: assert client is not None assert client.access_key == debank_api_key @pytest.mark.asyncio async def test_context_manager_cleanup(self, debank_api_key): """Test that client properly closes connections.""" from mcp_server_debank.client import DeBankClient client = DeBankClient(access_key=debank_api_key) async with client: pass # Do nothing # Verify client is closed (implementation dependent) # This test verifies the pattern works

Latest Blog Posts

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/caiovicentino/debank-mcp-server'

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