Files
crypto_trader/tests/unit/data/providers/test_coingecko_provider.py

114 lines
3.7 KiB
Python
Raw Normal View History

"""Unit tests for CoinGecko pricing provider."""
import pytest
from unittest.mock import Mock, patch, MagicMock
from decimal import Decimal
import httpx
from src.data.providers.coingecko_provider import CoinGeckoProvider
@pytest.fixture
def provider():
"""Create a CoinGecko provider instance."""
return CoinGeckoProvider()
@pytest.fixture
def mock_response():
"""Create a mock HTTP response."""
response = Mock()
response.status_code = 200
response.json = Mock(return_value={
'bitcoin': {
'usd': 50000.0,
'usd_24h_change': 2.5,
'usd_24h_vol': 1000000.0,
}
})
return response
class TestCoinGeckoProvider:
"""Tests for CoinGeckoProvider."""
def test_init(self, provider):
"""Test provider initialization."""
assert provider.name == "CoinGecko"
assert not provider.supports_websocket
assert not provider._connected
@patch('src.data.providers.coingecko_provider.httpx.Client')
def test_connect_success(self, mock_client_class, provider, mock_response):
"""Test successful connection."""
mock_client = Mock()
mock_client.get = Mock(return_value=mock_response)
mock_client_class.return_value = mock_client
result = provider.connect()
assert result is True
assert provider._connected is True
@patch('src.data.providers.coingecko_provider.httpx.Client')
def test_connect_failure(self, mock_client_class, provider):
"""Test connection failure."""
mock_client = Mock()
mock_client.get = Mock(side_effect=Exception("Connection failed"))
mock_client_class.return_value = mock_client
result = provider.connect()
assert result is False
assert not provider._connected
def test_parse_symbol(self, provider):
"""Test symbol parsing."""
coin_id, currency = provider._parse_symbol('BTC/USD')
assert coin_id == 'bitcoin'
assert currency == 'usd'
coin_id, currency = provider._parse_symbol('ETH/USDT')
assert coin_id == 'ethereum'
assert currency == 'usd' # USDT maps to USD
@patch('src.data.providers.coingecko_provider.httpx.Client')
def test_get_ticker(self, mock_client_class, provider, mock_response):
"""Test getting ticker data."""
mock_client = Mock()
mock_client.get = Mock(return_value=mock_response)
mock_client_class.return_value = mock_client
provider.connect()
ticker = provider.get_ticker('BTC/USD')
assert ticker['symbol'] == 'BTC/USD'
assert isinstance(ticker['last'], Decimal)
assert ticker['last'] > 0
assert 'timestamp' in ticker
@patch('src.data.providers.coingecko_provider.httpx.Client')
def test_get_ohlcv(self, mock_client_class, provider):
"""Test getting OHLCV data."""
mock_response = Mock()
mock_response.status_code = 200
mock_response.json = Mock(return_value=[
[1609459200000, 50000, 51000, 49000, 50000],
])
mock_client = Mock()
mock_client.get = Mock(return_value=mock_response)
mock_client_class.return_value = mock_client
provider.connect()
ohlcv = provider.get_ohlcv('BTC/USD', '1h', limit=10)
assert len(ohlcv) > 0
# CoinGecko returns 5 elements, we add volume as 0
assert len(ohlcv[0]) == 6
def test_normalize_symbol(self, provider):
"""Test symbol normalization."""
normalized = provider.normalize_symbol('btc-usdt')
assert normalized == 'BTC/USDT'