Files
OpenBB/cli/tests/test_controllers_settings_controller.py
Danglewood 9a30186174 [V5] CLI 2.0 - Pluggable Backends, Non-TTY Default, HTTP Dispatcher, Spec Files + Codegen (#7433)
* stash some changes

* add more robust testing

* mypy

* point PR at V5

* introduce spec file

* codespell

* test fix

* fix workflow environment setup

* fix workflow environment setup

* fix workflow environment setup

* add pyyaml to dependencies

* split lint jobs

* fix workflow environment setup

* fix workflow environment setup

* workflow env setup

* workflow env setup

* clean up code comments

* add auth hook entrypoints

* codespell

* add codegen feature

* codespell

* move _unpack into dispatchers for consistency with codegen packages

* surface nested models in the response

* fix missing coverage in CI

* socrata updates

* test fix

* detect plotly output

* add --include and --exclude flags from generate-extension command

* cap test matrix at python 3.14

* no useless comments

* platform controller command description split

* merge URL overloads from path params

* exclude none and unset from model dump

---------

Co-authored-by: deeleeramone <>
Co-authored-by: Copilot <copilot@github.com>
2026-06-01 19:14:38 +03:00

165 lines
5.1 KiB
Python

"""Test the SettingsController class."""
from unittest.mock import MagicMock, patch
import pytest
from openbb_cli.controllers.settings_controller import SettingsController
@pytest.fixture
def mock_session():
"""Create a mock session fixture."""
with patch("openbb_cli.controllers.settings_controller.session") as mock:
mock.settings.USE_INTERACTIVE_DF = False
mock.settings.ALLOWED_NUMBER_OF_ROWS = 20
mock.settings.TIMEZONE = "UTC"
mock.style.available_styles = ["dark"]
mock.settings.set_item = MagicMock()
yield mock
def test_call_interactive(mock_session):
"""Test toggling interactive mode."""
controller = SettingsController()
controller.call_interactive(None)
mock_session.settings.set_item.assert_called_once_with("USE_INTERACTIVE_DF", True)
@pytest.mark.parametrize(
"input_rows, expected",
[
(10, 10),
(15, 15),
],
)
def test_call_n_rows(input_rows, expected, mock_session):
"""Test setting number of rows."""
controller = SettingsController()
args = ["--value", str(input_rows)]
controller.call_n_rows(args)
mock_session.settings.set_item.assert_called_with(
"ALLOWED_NUMBER_OF_ROWS", expected
)
def test_call_n_rows_no_args_provided(mock_session):
"""Test n_rows with no arguments shows current value."""
controller = SettingsController()
controller.call_n_rows([])
mock_session.console.print.assert_called_with("[info]Current value:[/info] 20")
@pytest.mark.parametrize(
"timezone, valid",
[
("UTC", True),
("Mars/Phobos", False),
],
)
def test_call_timezone(timezone, valid, mock_session):
"""Test setting timezone."""
controller = SettingsController()
args = ["--value", timezone]
controller.call_timezone(args)
if valid:
mock_session.settings.set_item.assert_called_with("TIMEZONE", timezone)
else:
mock_session.settings.set_item.assert_not_called()
def test_call_console_style(mock_session):
"""Test setting console style."""
controller = SettingsController()
args = ["--value", "dark"]
controller.call_console_style(args)
mock_session.console.print.assert_called()
def test_call_console_style_no_args(mock_session):
"""Test console style with no args shows current value."""
mock_session.settings.RICH_STYLE = "default"
controller = SettingsController()
controller.call_console_style([])
mock_session.console.print.assert_called_with("[info]Current value:[/info] default")
def test_call_flair(mock_session):
"""Test setting flair."""
controller = SettingsController()
args = ["--value", "rocket"]
controller.call_flair(args)
def test_call_flair_no_args(mock_session):
"""Test flair with no args shows current value."""
mock_session.settings.FLAIR = "bug"
controller = SettingsController()
controller.call_flair([])
mock_session.console.print.assert_called_with("[info]Current value:[/info] bug")
def test_call_obbject_display(mock_session):
"""Test setting obbject display count."""
controller = SettingsController()
args = ["--value", "5"]
controller.call_obbject_display(args)
mock_session.settings.set_item.assert_called_once_with(
"N_TO_DISPLAY_OBBJECT_REGISTRY", 5
)
def test_call_obbject_display_no_args(mock_session):
"""Test obbject display with no args shows current value."""
mock_session.settings.N_TO_DISPLAY_OBBJECT_REGISTRY = 10
controller = SettingsController()
controller.call_obbject_display([])
mock_session.console.print.assert_called_with("[info]Current value:[/info] 10")
@pytest.mark.parametrize(
"args, expected",
[
(["--value", "50"], 50),
(["--value", "100"], 100),
([], 20),
],
)
def test_call_n_rows_v2(args, expected, mock_session):
"""Test n_rows with parametrized args."""
mock_session.settings.ALLOWED_NUMBER_OF_ROWS = 20
controller = SettingsController()
controller.call_n_rows(args)
if args:
mock_session.settings.set_item.assert_called_with(
"ALLOWED_NUMBER_OF_ROWS", expected
)
else:
mock_session.console.print.assert_called_with("[info]Current value:[/info] 20")
def test_print_help_walks_feature_flags_and_preferences(mock_session):
"""``print_help`` formats both groups (feature flags + preferences) into a menu."""
controller = SettingsController()
controller.print_help()
mock_session.console.print.assert_called_once()
call_kwargs = mock_session.console.print.call_args[1]
assert call_kwargs.get("menu") == "Settings"
text = call_kwargs.get("text", "")
assert "Feature Flags" in text
assert "Preferences" in text
def test_generate_command_invalid_action_raises(mock_session):
"""Action type other than 'toggle'/'set' raises ValueError."""
controller = SettingsController()
field = {
"command": "x",
"field_name": "x",
"description": "d",
"annotation": str,
}
with pytest.raises(ValueError, match="not allowed"):
controller._generate_command("x", field, "bogus")