test_client.py•4.48 kB
"""Tests for ALA API client."""
from unittest.mock import AsyncMock, patch
import httpx
import pytest
from ala_mcp.client import ALAClient
@pytest.mark.asyncio
async def test_client_initialization():
"""Test client initialization with default values."""
client = ALAClient()
assert client.base_url == "https://biocache-ws.ala.org.au/ws"
assert client.timeout == 30
assert client.api_key is None
@pytest.mark.asyncio
async def test_client_initialization_custom():
"""Test client initialization with custom values."""
client = ALAClient(base_url="https://custom.example.com", timeout=60, api_key="test-key")
assert client.base_url == "https://custom.example.com"
assert client.timeout == 60
assert client.api_key == "test-key"
@pytest.mark.asyncio
async def test_successful_get_request(mock_httpx_response, sample_api_response):
"""Test successful GET request."""
mock_httpx_response.json.return_value = sample_api_response
with patch("httpx.AsyncClient") as mock_client_class:
mock_client = AsyncMock()
mock_client.request.return_value = mock_httpx_response
mock_client_class.return_value.__aenter__.return_value = mock_client
client = ALAClient()
result = await client.request(method="GET", endpoint="/occurrences", params={"limit": 10})
assert result["status_code"] == 200
assert result["data"] == sample_api_response
assert "url" in result
assert "headers" in result
@pytest.mark.asyncio
async def test_request_with_api_key(mock_httpx_response):
"""Test request with API key authentication."""
with patch("httpx.AsyncClient") as mock_client_class:
mock_client = AsyncMock()
mock_client.request.return_value = mock_httpx_response
mock_client_class.return_value.__aenter__.return_value = mock_client
client = ALAClient(api_key="test-api-key")
await client.request(method="GET", endpoint="/occurrences")
# Verify Authorization header was added
call_kwargs = mock_client.request.call_args[1]
assert "Authorization" in call_kwargs["headers"]
assert call_kwargs["headers"]["Authorization"] == "Bearer test-api-key"
@pytest.mark.asyncio
async def test_request_timeout():
"""Test request timeout handling."""
with patch("httpx.AsyncClient") as mock_client_class:
mock_client = AsyncMock()
mock_client.request.side_effect = httpx.TimeoutException("Request timeout")
mock_client_class.return_value.__aenter__.return_value = mock_client
client = ALAClient()
with pytest.raises(httpx.TimeoutException):
await client.request(method="GET", endpoint="/occurrences")
@pytest.mark.asyncio
async def test_request_http_error():
"""Test HTTP error handling."""
with patch("httpx.AsyncClient") as mock_client_class:
mock_client = AsyncMock()
mock_client.request.side_effect = httpx.HTTPError("HTTP error")
mock_client_class.return_value.__aenter__.return_value = mock_client
client = ALAClient()
with pytest.raises(httpx.HTTPError):
await client.request(method="GET", endpoint="/occurrences")
@pytest.mark.asyncio
async def test_post_request_with_data(mock_httpx_response):
"""Test POST request with JSON data."""
with patch("httpx.AsyncClient") as mock_client_class:
mock_client = AsyncMock()
mock_client.request.return_value = mock_httpx_response
mock_client_class.return_value.__aenter__.return_value = mock_client
client = ALAClient()
data = {"key": "value", "nested": {"data": "test"}}
await client.request(method="POST", endpoint="/data", data=data)
call_kwargs = mock_client.request.call_args[1]
assert call_kwargs["json"] == data
@pytest.mark.asyncio
async def test_non_json_response(mock_httpx_response):
"""Test handling of non-JSON response."""
mock_httpx_response.json.side_effect = Exception("Not JSON")
mock_httpx_response.text = "Plain text response"
with patch("httpx.AsyncClient") as mock_client_class:
mock_client = AsyncMock()
mock_client.request.return_value = mock_httpx_response
mock_client_class.return_value.__aenter__.return_value = mock_client
client = ALAClient()
result = await client.request(method="GET", endpoint="/occurrences")
assert result["data"] == "Plain text response"