from decimal import Decimal import pytest from grid_trading.domain.models import Instrument from grid_trading.market.tencent import ( QuoteFetchError, TencentQuoteProvider, infer_tencent_symbol, parse_tencent_response, ) def test_infer_tencent_symbol_from_a_share_code(): assert infer_tencent_symbol("000001") == "sz000001" assert infer_tencent_symbol("600000") == "sh600000" assert infer_tencent_symbol("510300") == "sh510300" assert infer_tencent_symbol("sz000001") == "sz000001" def test_parse_tencent_response_extracts_realtime_fields(): raw = ( 'v_sz000001="51~平安银行~000001~10.60~10.47~10.44~0~0~0~' '10.60~0~10.59~0~10.58~0~10.57~0~10.56~0~10.61~0~10.62~0~' '10.63~0~10.64~0~10.65~0~~20260708161430~0.13~1.24~10.63~10.34";' ).encode("gbk") [quote] = parse_tencent_response(raw) assert quote.symbol == "sz000001" assert quote.code == "000001" assert quote.name == "平安银行" assert quote.price == Decimal("10.60") assert quote.previous_close == Decimal("10.47") assert quote.open_price == Decimal("10.44") assert quote.change == Decimal("0.13") assert quote.change_percent == Decimal("1.24") assert quote.high == Decimal("10.63") assert quote.low == Decimal("10.34") assert quote.quote_time == "20260708161430" assert quote.source == "tencent" def test_parse_tencent_response_rejects_missing_price(): raw = 'v_sz000001="51~平安银行~000001~~~";'.encode("gbk") with pytest.raises(QuoteFetchError, match="price"): parse_tencent_response(raw) def test_provider_builds_batch_query_and_maps_by_code(): calls: list[str] = [] raw = ( 'v_sz000001="51~平安银行~000001~10.60~10.47~10.44~0~0~0~' '0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~0~~20260708161430~0.13~1.24~10.63~10.34";' ).encode("gbk") def fake_fetch(url: str, timeout: float) -> bytes: calls.append(url) return raw provider = TencentQuoteProvider(fetcher=fake_fetch) quotes = provider.fetch_quotes([Instrument(id=1, code="000001", name="平安银行")]) assert "q=sz000001" in calls[0] assert quotes["000001"].price == Decimal("10.60")