Really-amin's picture
Upload 317 files
eebf5c4 verified
"""
Unit tests for async API client
Test async HTTP operations, retry logic, and error handling
"""
import pytest
import aiohttp
from unittest.mock import AsyncMock, patch, MagicMock
import asyncio
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from utils.async_api_client import AsyncAPIClient, safe_api_call, parallel_api_calls
@pytest.mark.asyncio
class TestAsyncAPIClient:
"""Test AsyncAPIClient class"""
async def test_client_initialization(self):
"""Test client initialization with context manager"""
async with AsyncAPIClient() as client:
assert client._session is not None
assert isinstance(client._session, aiohttp.ClientSession)
async def test_successful_get_request(self):
"""Test successful GET request"""
mock_response_data = {"status": "success", "data": "test"}
async with AsyncAPIClient() as client:
with patch.object(
client._session,
'get',
return_value=AsyncMock(
json=AsyncMock(return_value=mock_response_data),
raise_for_status=MagicMock(),
__aenter__=AsyncMock(),
__aexit__=AsyncMock()
)
):
result = await client.get("https://api.example.com/data")
# Note: This test structure needs adjustment based on actual mock implementation
async def test_retry_on_timeout(self):
"""Test retry logic on timeout"""
async with AsyncAPIClient(max_retries=3, retry_delay=0.1) as client:
# Mock timeout errors
client._session.get = AsyncMock(side_effect=asyncio.TimeoutError())
result = await client.get("https://api.example.com/data")
# Should return None after max retries
assert result is None
# Should have tried max_retries times
assert client._session.get.call_count == 3
async def test_retry_on_server_error(self):
"""Test retry on 5xx server errors"""
# This test would mock server errors and verify retry behavior
pass
async def test_no_retry_on_client_error(self):
"""Test that client errors (4xx) don't trigger retries"""
# Mock 404 error and verify only one attempt
pass
async def test_parallel_requests(self):
"""Test parallel request execution"""
urls = [
"https://api.example.com/endpoint1",
"https://api.example.com/endpoint2",
"https://api.example.com/endpoint3"
]
async with AsyncAPIClient() as client:
# Mock successful responses
mock_data = [{"id": i} for i in range(len(urls))]
# Test parallel execution
# Results should be returned in order
pass
@pytest.mark.asyncio
class TestConvenienceFunctions:
"""Test convenience functions"""
async def test_safe_api_call(self):
"""Test safe_api_call convenience function"""
# Test successful call
with patch('utils.async_api_client.AsyncAPIClient') as MockClient:
mock_instance = MockClient.return_value.__aenter__.return_value
mock_instance.get = AsyncMock(return_value={"success": True})
result = await safe_api_call("https://api.example.com/test")
# Verify result
async def test_parallel_api_calls(self):
"""Test parallel_api_calls convenience function"""
urls = ["https://api.example.com/1", "https://api.example.com/2"]
with patch('utils.async_api_client.AsyncAPIClient') as MockClient:
mock_instance = MockClient.return_value.__aenter__.return_value
mock_instance.gather_requests = AsyncMock(
return_value=[{"id": 1}, {"id": 2}]
)
results = await parallel_api_calls(urls)
# Verify results
if __name__ == '__main__':
pytest.main([__file__, '-v'])