feat(V2): IBKR client base + auth header + tickle keep-alive
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
import pytest
|
||||
from cerbero_mcp.exchanges.ibkr.client import IBKRClient
|
||||
from pytest_httpx import HTTPXMock
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_signer():
|
||||
s = MagicMock()
|
||||
s.consumer_key = "CK"
|
||||
s.access_token = "AT"
|
||||
s.get_live_session_token = AsyncMock(return_value="LSTBASE64==")
|
||||
s.sign_with_lst = MagicMock(return_value="SIG==")
|
||||
s.make_oauth_params = MagicMock(return_value={
|
||||
"oauth_consumer_key": "CK", "oauth_token": "AT",
|
||||
"oauth_nonce": "n", "oauth_timestamp": "1",
|
||||
"oauth_signature_method": "HMAC-SHA256", "oauth_version": "1.0",
|
||||
})
|
||||
return s
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(fake_signer):
|
||||
return IBKRClient(
|
||||
signer=fake_signer,
|
||||
account_id="DU1234",
|
||||
paper=True,
|
||||
base_url="https://api.ibkr.com/v1/api",
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_health_no_network(client):
|
||||
info = await client.health()
|
||||
assert info["status"] == "ok"
|
||||
assert info["paper"] is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_account_summary(httpx_mock: HTTPXMock, client):
|
||||
httpx_mock.add_response(
|
||||
url=re.compile(r".*/portfolio/DU1234/summary"),
|
||||
json={"netliquidation": {"amount": 10000, "currency": "USD"}, "totalcashvalue": {"amount": 8000}},
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
url=re.compile(r".*/tickle"),
|
||||
json={"session": "abc"},
|
||||
)
|
||||
data = await client.get_account()
|
||||
assert "netliquidation" in data
|
||||
Reference in New Issue
Block a user