- Add AGENTS.md with coding guidelines for AI agents - Add comprehensive unit tests for Binance adapter (mocked) - Add integration tests for Binance testnet connectivity - Fix pydantic-settings v2 compatibility for nested settings - Fix MarginType enum to handle lowercase API responses - Update Python requirement to 3.12+ (pandas-ta dependency) - Update ruff config to new lint section format - Update PLAN.md to reflect completed milestones 1.1-1.3 32 tests passing with 81% coverage
81 lines
2.6 KiB
Python
81 lines
2.6 KiB
Python
import os
|
|
from collections.abc import AsyncIterator
|
|
from decimal import Decimal
|
|
|
|
import pytest
|
|
from dotenv import load_dotenv
|
|
|
|
from tradefinder.adapters.binance_usdm import BinanceUSDMAdapter
|
|
from tradefinder.core.config import (
|
|
Settings,
|
|
TradingMode,
|
|
get_settings,
|
|
reset_settings,
|
|
)
|
|
|
|
# Load .env file before checking for keys
|
|
load_dotenv()
|
|
|
|
BINANCE_TESTNET_KEYS = bool(
|
|
os.getenv("BINANCE_TESTNET_API_KEY") and os.getenv("BINANCE_TESTNET_SECRET")
|
|
)
|
|
|
|
pytestmark = pytest.mark.skipif(
|
|
not BINANCE_TESTNET_KEYS,
|
|
reason="BINANCE_TESTNET_API_KEY and BINANCE_TESTNET_SECRET are required",
|
|
)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def settings() -> Settings:
|
|
reset_settings() # Clear any cached settings first
|
|
settings = get_settings()
|
|
if settings.trading_mode != TradingMode.TESTNET:
|
|
pytest.skip("Integration tests require testnet trading mode")
|
|
return settings
|
|
|
|
|
|
@pytest.fixture
|
|
async def adapter(settings: Settings) -> AsyncIterator[BinanceUSDMAdapter]:
|
|
adapter = BinanceUSDMAdapter(settings)
|
|
await adapter.connect()
|
|
try:
|
|
yield adapter
|
|
finally:
|
|
await adapter.disconnect()
|
|
|
|
|
|
@pytest.mark.integration
|
|
class TestBinanceIntegration:
|
|
async def test_connect_and_disconnect(self, settings: Settings) -> None:
|
|
adapter = BinanceUSDMAdapter(settings)
|
|
await adapter.connect()
|
|
assert adapter._client is not None
|
|
await adapter.disconnect()
|
|
assert adapter._client is None
|
|
|
|
async def test_get_usdt_balance(self, adapter: BinanceUSDMAdapter) -> None:
|
|
balance = await adapter.get_balance("USDT")
|
|
assert balance.asset == "USDT"
|
|
assert balance.wallet_balance >= Decimal("0")
|
|
assert balance.available_balance >= Decimal("0")
|
|
|
|
async def test_get_all_positions(self, adapter: BinanceUSDMAdapter) -> None:
|
|
positions = await adapter.get_positions()
|
|
assert isinstance(positions, list)
|
|
for position in positions:
|
|
assert position.symbol
|
|
|
|
async def test_get_symbol_info(self, adapter: BinanceUSDMAdapter) -> None:
|
|
symbol_info = await adapter.get_symbol_info("BTCUSDT")
|
|
assert symbol_info.symbol == "BTCUSDT"
|
|
assert symbol_info.tick_size > Decimal("0")
|
|
|
|
async def test_get_mark_price(self, adapter: BinanceUSDMAdapter) -> None:
|
|
mark_price = await adapter.get_mark_price("BTCUSDT")
|
|
assert mark_price > Decimal("0")
|
|
|
|
async def test_configure_hedge_mode(self, adapter: BinanceUSDMAdapter) -> None:
|
|
await adapter.configure_hedge_mode(True)
|
|
await adapter.configure_hedge_mode(False)
|