Local changes: Updated model training, removed debug instrumentation, and configuration improvements
This commit is contained in:
2
tests/unit/exchanges/__init__.py
Normal file
2
tests/unit/exchanges/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
"""Unit tests for exchange adapters."""
|
||||
|
||||
24
tests/unit/exchanges/test_base.py
Normal file
24
tests/unit/exchanges/test_base.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""Tests for base exchange adapter."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock
|
||||
from src.exchanges.base import BaseExchange
|
||||
|
||||
|
||||
class TestBaseExchange:
|
||||
"""Tests for BaseExchange abstract class."""
|
||||
|
||||
def test_base_exchange_init(self):
|
||||
"""Test base exchange initialization."""
|
||||
# Can't instantiate abstract class, test through concrete implementation
|
||||
from src.exchanges.coinbase import CoinbaseExchange
|
||||
|
||||
exchange = CoinbaseExchange(
|
||||
name="test",
|
||||
api_key="test_key",
|
||||
secret_key="test_secret"
|
||||
)
|
||||
assert exchange.name == "test"
|
||||
assert exchange.api_key == "test_key"
|
||||
assert not exchange.is_connected
|
||||
|
||||
56
tests/unit/exchanges/test_coinbase.py
Normal file
56
tests/unit/exchanges/test_coinbase.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Tests for Coinbase exchange adapter."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from src.exchanges.coinbase import CoinbaseExchange
|
||||
|
||||
|
||||
class TestCoinbaseExchange:
|
||||
"""Tests for CoinbaseExchange."""
|
||||
|
||||
@pytest.fixture
|
||||
def exchange(self):
|
||||
"""Create Coinbase exchange instance."""
|
||||
return CoinbaseExchange(
|
||||
name="test_coinbase",
|
||||
api_key="test_key",
|
||||
secret_key="test_secret",
|
||||
permissions="read_only"
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_connect(self, exchange):
|
||||
"""Test connection to Coinbase."""
|
||||
with patch.object(exchange.exchange, 'load_markets', new_callable=AsyncMock):
|
||||
await exchange.connect()
|
||||
assert exchange.is_connected
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_balance(self, exchange):
|
||||
"""Test fetching balance."""
|
||||
mock_balance = {'USD': {'free': 1000.0, 'used': 0.0, 'total': 1000.0}}
|
||||
exchange.exchange.fetch_balance = AsyncMock(return_value=mock_balance)
|
||||
exchange.is_connected = True
|
||||
|
||||
balance = await exchange.fetch_balance()
|
||||
assert balance == mock_balance
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_place_order_readonly(self, exchange):
|
||||
"""Test placing order with read-only permissions."""
|
||||
exchange.permissions = "read_only"
|
||||
exchange.is_connected = True
|
||||
|
||||
with pytest.raises(PermissionError):
|
||||
await exchange.place_order("BTC/USD", "buy", "market", 0.01)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_ohlcv(self, exchange):
|
||||
"""Test fetching OHLCV data."""
|
||||
mock_ohlcv = [[1609459200000, 29000, 29500, 28800, 29300, 1000]]
|
||||
exchange.exchange.fetch_ohlcv = AsyncMock(return_value=mock_ohlcv)
|
||||
exchange.is_connected = True
|
||||
|
||||
ohlcv = await exchange.fetch_ohlcv("BTC/USD", "1h")
|
||||
assert ohlcv == mock_ohlcv
|
||||
|
||||
40
tests/unit/exchanges/test_factory.py
Normal file
40
tests/unit/exchanges/test_factory.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""Tests for exchange factory."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import patch, Mock
|
||||
from src.exchanges.factory import ExchangeFactory
|
||||
from src.exchanges.coinbase import CoinbaseExchange
|
||||
|
||||
|
||||
class TestExchangeFactory:
|
||||
"""Tests for ExchangeFactory."""
|
||||
|
||||
def test_register_exchange(self):
|
||||
"""Test exchange registration."""
|
||||
ExchangeFactory.register_exchange("test_exchange", CoinbaseExchange)
|
||||
assert "test_exchange" in ExchangeFactory.list_available()
|
||||
|
||||
def test_get_exchange(self):
|
||||
"""Test getting exchange instance."""
|
||||
with patch('src.exchanges.factory.get_key_manager') as mock_km:
|
||||
mock_km.return_value.get_exchange_keys.return_value = {
|
||||
'api_key': 'test_key',
|
||||
'secret_key': 'test_secret',
|
||||
'permissions': 'read_only'
|
||||
}
|
||||
|
||||
exchange = ExchangeFactory.get_exchange("coinbase")
|
||||
assert exchange is not None
|
||||
assert isinstance(exchange, CoinbaseExchange)
|
||||
|
||||
def test_get_nonexistent_exchange(self):
|
||||
"""Test getting non-existent exchange."""
|
||||
with pytest.raises(ValueError, match="not registered"):
|
||||
ExchangeFactory.get_exchange("nonexistent")
|
||||
|
||||
def test_list_available(self):
|
||||
"""Test listing available exchanges."""
|
||||
exchanges = ExchangeFactory.list_available()
|
||||
assert isinstance(exchanges, list)
|
||||
assert "coinbase" in exchanges
|
||||
|
||||
44
tests/unit/exchanges/test_websocket.py
Normal file
44
tests/unit/exchanges/test_websocket.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""Tests for WebSocket functionality."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, patch
|
||||
from src.exchanges.coinbase import CoinbaseAdapter
|
||||
|
||||
|
||||
def test_subscribe_ticker():
|
||||
"""Test ticker subscription."""
|
||||
adapter = CoinbaseAdapter("test_key", "test_secret", sandbox=True)
|
||||
callback = Mock()
|
||||
|
||||
adapter.subscribe_ticker("BTC/USD", callback)
|
||||
|
||||
assert f'ticker_BTC/USD' in adapter._ws_callbacks
|
||||
assert adapter._ws_callbacks[f'ticker_BTC/USD'] == callback
|
||||
|
||||
|
||||
def test_subscribe_orderbook():
|
||||
"""Test orderbook subscription."""
|
||||
adapter = CoinbaseAdapter("test_key", "test_secret", sandbox=True)
|
||||
callback = Mock()
|
||||
|
||||
adapter.subscribe_orderbook("BTC/USD", callback)
|
||||
|
||||
assert f'orderbook_BTC/USD' in adapter._ws_callbacks
|
||||
|
||||
|
||||
def test_subscribe_trades():
|
||||
"""Test trades subscription."""
|
||||
adapter = CoinbaseAdapter("test_key", "test_secret", sandbox=True)
|
||||
callback = Mock()
|
||||
|
||||
adapter.subscribe_trades("BTC/USD", callback)
|
||||
|
||||
assert f'trades_BTC/USD' in adapter._ws_callbacks
|
||||
|
||||
|
||||
def test_normalize_symbol():
|
||||
"""Test symbol normalization."""
|
||||
adapter = CoinbaseAdapter("test_key", "test_secret", sandbox=True)
|
||||
|
||||
assert adapter.normalize_symbol("BTC/USD") == "BTC-USD"
|
||||
assert adapter.normalize_symbol("ETH/USDT") == "ETH-USDT"
|
||||
Reference in New Issue
Block a user