Skip to content

Commit

Permalink
test:fix: use CharlesSchwab
Browse files Browse the repository at this point in the history
  • Loading branch information
Romazes committed Dec 30, 2024
1 parent 1ea9c94 commit 4976716
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 22 deletions.
46 changes: 26 additions & 20 deletions tests/commands/test_live.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@
from unittest import mock

import pytest
import responses
from click.testing import CliRunner

from lean.commands import lean
from lean.constants import DEFAULT_ENGINE_IMAGE
from lean.container import container
from lean.models.docker import DockerImage
from lean.models.json_module import JsonModule
from tests.test_helpers import create_fake_lean_cli_directory, reset_state_installed_modules
from tests.test_helpers import create_fake_lean_cli_directory, reset_state_installed_modules, \
setup_mock_api_client_and_responses
from tests.conftest import initialize_container
from click.testing import Result

Expand Down Expand Up @@ -428,10 +430,8 @@ def test_live_sets_dependent_configurations_from_modules_json_based_on_environme
"tt-order-routing-port": "abc",
"tt-log-fix-messages": "no"
},
"TDAmeritrade": {
"tdameritrade-account-number": "123",
"tdameritrade-api-key": "abc",
"tdameritrade-access-token": "abc",
"CharlesSchwab": {
"charles-schwab-account-number": "123"
},
"Bybit": {
"bybit-api-key": "abc",
Expand All @@ -441,10 +441,6 @@ def test_live_sets_dependent_configurations_from_modules_json_based_on_environme
}
}

brokerage_required_options_not_persistently_save_in_lean_config = {
"TDAmeritrade": ["tdameritrade-access-token"]
}

data_feed_required_options = {
"Interactive Brokers": brokerage_required_options["Interactive Brokers"],
"Tradier": brokerage_required_options["Tradier"],
Expand All @@ -456,7 +452,7 @@ def test_live_sets_dependent_configurations_from_modules_json_based_on_environme
"Samco": brokerage_required_options["Samco"],
"Terminal Link": terminal_link_required_options,
"Kraken": brokerage_required_options["Kraken"],
"TDAmeritrade": brokerage_required_options["TDAmeritrade"],
"CharlesSchwab": brokerage_required_options["CharlesSchwab"],
"Bybit": brokerage_required_options["Bybit"],
}

Expand Down Expand Up @@ -589,13 +585,16 @@ def test_live_non_interactive_aborts_when_missing_data_feed_options(data_feed: s
container.lean_runner.run_lean.assert_not_called()


@responses.activate
@pytest.mark.parametrize("brokerage,data_feed",
itertools.product(brokerage_required_options.keys(), data_feed_required_options.keys()))
def test_live_non_interactive_do_not_store_non_persistent_properties_in_lean_config(brokerage: str, data_feed: str) -> None:
if ((brokerage == "Interactive Brokers" or data_feed == "Interactive Brokers") and sys.platform == "darwin"):
pytest.skip("MacOS does not support IB tests")

create_fake_lean_cli_directory()
container.api_client = setup_mock_api_client_and_responses()

lean_runner = container.lean_runner

options = []
Expand Down Expand Up @@ -630,18 +629,17 @@ def test_live_non_interactive_do_not_store_non_persistent_properties_in_lean_con
{})

config = container.lean_config_manager.get_lean_config()
if brokerage in brokerage_required_options_not_persistently_save_in_lean_config:
for key in brokerage_required_options_not_persistently_save_in_lean_config[brokerage]:
assert key not in config


@responses.activate
@pytest.mark.parametrize("brokerage,data_feed",
itertools.product(brokerage_required_options.keys(), data_feed_required_options.keys()))
def test_live_non_interactive_calls_run_lean_when_all_options_given(brokerage: str, data_feed: str) -> None:
if ((brokerage == "Interactive Brokers" or data_feed == "Interactive Brokers") and sys.platform == "darwin"):
pytest.skip("MacOS does not support IB tests")

create_fake_lean_cli_directory()
container.api_client = setup_mock_api_client_and_responses()
lean_runner = container.lean_runner

options = []
Expand Down Expand Up @@ -675,13 +673,15 @@ def test_live_non_interactive_calls_run_lean_when_all_options_given(brokerage: s
{},
{})

@responses.activate
@pytest.mark.parametrize("brokerage,data_feed1,data_feed2",[(brokerage, *data_feeds) for brokerage, data_feeds in
itertools.product(brokerage_required_options.keys(), itertools.combinations(data_feed_required_options.keys(), 2))])
def test_live_non_interactive_calls_run_lean_when_all_options_given_with_multiple_data_feeds(brokerage: str, data_feed1: str, data_feed2: str) -> None:
if ((brokerage == "Interactive Brokers" or data_feed1 == "Interactive Brokers" or data_feed2 == "Interactive Brokers") and sys.platform == "darwin"):
pytest.skip("MacOS does not support IB tests")

create_fake_lean_cli_directory()
container.api_client = setup_mock_api_client_and_responses()
lean_runner = container.lean_runner

options = []
Expand Down Expand Up @@ -833,12 +833,14 @@ def test_live_non_interactive_falls_back_to_lean_config_for_data_feed_settings(d
{})


@responses.activate
@pytest.mark.parametrize("data_feed1,data_feed2", itertools.combinations(data_feed_required_options.keys(), 2))
def test_live_non_interactive_falls_back_to_lean_config_for_multiple_data_feed_settings(data_feed1: str, data_feed2: str) -> None:
if ((data_feed1 == "Interactive Brokers" or data_feed2 == "Interactive Brokers") and sys.platform == "darwin"):
pytest.skip("MacOS does not support IB tests")

create_fake_lean_cli_directory()
mock_api_client = setup_mock_api_client_and_responses()

required_options = list(data_feed_required_options[data_feed1].items()) + list(data_feed_required_options[data_feed2].items())
if len(required_options) > 8:
Expand All @@ -848,7 +850,7 @@ def test_live_non_interactive_falls_back_to_lean_config_for_multiple_data_feed_s
for current_options in itertools.combinations(required_options, length):
lean_runner = mock.Mock()
# refresh so we assert we are called once
initialize_container(None, lean_runner)
initialize_container(None, lean_runner,api_client_to_use=mock_api_client)

options = []

Expand Down Expand Up @@ -983,6 +985,7 @@ def test_live_passes_custom_python_venv_to_lean_runner_when_given_as_option(pyth
assert "python-venv" not in args[0]


@responses.activate
@pytest.mark.parametrize("brokerage,cash", [("Paper Trading", ""),
("Paper Trading", "USD:100"),
("Paper Trading", "USD:100,EUR:200"),
Expand All @@ -1009,14 +1012,15 @@ def test_live_passes_custom_python_venv_to_lean_runner_when_given_as_option(pyth
("Tradier", "USD:100"),
("Zerodha", ""),
("Zerodha", "USD:100"),
("TDAmeritrade", ""),
("TDAmeritrade", "USD:100")])
("CharlesSchwab", ""),
("CharlesSchwab", "USD:100")])
def test_live_passes_live_cash_balance_to_lean_runner_when_given_as_option(brokerage: str, cash: str) -> None:
if (brokerage == "Interactive Brokers" and sys.platform == "darwin"):
pytest.skip("MacOS does not support IB tests")

create_fake_lean_cli_directory()
lean_runner= container.lean_runner
container.api_client = setup_mock_api_client_and_responses()
lean_runner = container.lean_runner

options = []
required_options = brokerage_required_options[brokerage].items()
Expand Down Expand Up @@ -1051,6 +1055,7 @@ def test_live_passes_live_cash_balance_to_lean_runner_when_given_as_option(broke
assert args[0]["live-cash-balance"] == cash_list


@responses.activate
@pytest.mark.parametrize("brokerage,holdings", [("Paper Trading", ""),
("Paper Trading", "A:A 2T:1:145.1"),
("Paper Trading", "A:A 2T:1:145.1,AA:AA 2T:2:20.35"),
Expand All @@ -1076,14 +1081,15 @@ def test_live_passes_live_cash_balance_to_lean_runner_when_given_as_option(broke
("Tradier", "A:A 2T:1:145.1"),
("Zerodha", ""),
("Zerodha", "A:A 2T:1:145.1"),
("TDAmeritrade", ""),
("TDAmeritrade", "A:A 2T:1:145.1")])
("CharlesSchwab", ""),
("CharlesSchwab", "A:A 2T:1:145.1")])
def test_live_passes_live_holdings_to_lean_runner_when_given_as_option(brokerage: str, holdings: str) -> None:
if (brokerage == "Interactive Brokers" and sys.platform == "darwin"):
pytest.skip("MacOS does not support IB tests")

create_fake_lean_cli_directory()
lean_runner= container.lean_runner
container.api_client = setup_mock_api_client_and_responses()
lean_runner = container.lean_runner

options = []
required_options = brokerage_required_options[brokerage].items()
Expand Down
37 changes: 35 additions & 2 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
# limitations under the License.

import json
import responses
from datetime import datetime
from pathlib import Path
from typing import List
from unittest import mock

from lean.constants import DEFAULT_LEAN_DOTNET_FRAMEWORK
from lean.components.util.http_client import HTTPClient
from lean.components.api.api_client import APIClient
from lean.constants import DEFAULT_LEAN_DOTNET_FRAMEWORK, API_BASE_URL
from lean.models.cli import (cli_brokerages, cli_data_downloaders, cli_data_queue_handlers,
cli_addon_modules, cli_history_provider)

Expand Down Expand Up @@ -85,7 +89,9 @@ def _get_lean_config_file_content() -> str:
"data-folder": "data",
// organization-id documentation
"organization-id": "abc"
"organization-id": "abc",
"project-id": 123
}
"""

Expand All @@ -105,6 +111,33 @@ def create_fake_lean_cli_directory() -> None:
_write_fake_directory(files)


def setup_mock_api_client_and_responses() -> APIClient:
"""
Sets up a mock API client and configures a mock response for API calls.
- Creates a mock `APIClient` with test credentials.
- Adds a mock POST response to the `live/auth0/read` endpoint with sample authorization data.
Returns:
APIClient: A mock API client for testing.
"""
api_client = APIClient(mock.Mock(), HTTPClient(mock.Mock()), user_id="123", api_token="abc")
responses.add(
responses.POST,
f"{API_BASE_URL}live/auth0/read",
json={
"authorization": {
"accounts": [
{"id": "123", "name": "123 | Margin | USD"}
]
},
"success": "true"
},
status=200
)
return api_client


def create_fake_lean_cli_project(name: str, language: str) -> None:
"""Creates a directory structure similar to the one created by `lean init` with a given project info"""
(Path.cwd() / "data").mkdir()
Expand Down

0 comments on commit 4976716

Please sign in to comment.