""" Unit tests for Binance raw → domain event parsing. """ import pytest from app.providers.binance import BinanceProvider from app.domain.events import EventType @pytest.fixture def provider(): return BinanceProvider() # ── Trade parsing ────────────────────────────────────────────────────── BINANCE_TRADE_RAW = { "e": "trade", "E": 1672515782136, "s": "BTCUSDT", "t": 123456789, "p": "42500.50", "q": "0.015", "T": 1672515782135, "m": True, } def test_parse_trade_basic(provider): event = provider._parse(BINANCE_TRADE_RAW) assert event is not None assert event.event_type == EventType.TRADE assert event.symbol == "BTCUSDT" assert event.price == 42500.50 assert event.size == 0.015 assert event.side == "sell" # m=True → seller is maker → trade is sell assert event.trade_id == "123456789" assert event.provider == "binance" def test_parse_trade_ts_exchange(provider): event = provider._parse(BINANCE_TRADE_RAW) assert event.ts_exchange is not None # 1672515782135 ms → 2022-12-31 or 2023-01-01 (depending on TZ) assert event.ts_exchange.year >= 2022 def test_parse_trade_buy_side(provider): raw = {**BINANCE_TRADE_RAW, "m": False} event = provider._parse(raw) assert event.side == "buy" # ── BookTicker (Quote) parsing ───────────────────────────────────────── BINANCE_BOOKTICKER_RAW = { "u": 400900217, "s": "ETHUSDT", "b": "2150.25000000", "B": "31.21000000", "a": "2150.50000000", "A": "40.66000000", } def test_parse_bookticker(provider): event = provider._parse(BINANCE_BOOKTICKER_RAW) assert event is not None assert event.event_type == EventType.QUOTE assert event.symbol == "ETHUSDT" assert event.bid == 2150.25 assert event.ask == 2150.50 assert event.bid_size == 31.21 assert event.ask_size == 40.66 assert event.provider == "binance" # ── Edge cases ───────────────────────────────────────────────────────── def test_parse_unknown_event(provider): raw = {"e": "aggTrade", "s": "BTCUSDT", "p": "100"} event = provider._parse(raw) assert event is None def test_parse_subscription_confirmation(provider): raw = {"result": None, "id": 1} # This is handled in stream(), not _parse(), so _parse should return None event = provider._parse(raw) assert event is None def test_parse_empty_values(provider): raw = {"e": "trade", "s": "", "p": "0", "q": "0", "T": None, "m": True, "t": ""} event = provider._parse(raw) assert event is not None assert event.price == 0.0 assert event.symbol == ""