Skip to content

Commit ff75000

Browse files
test: add coverage for CLI utility functions (#7422)
Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com>
1 parent 86ec79d commit ff75000

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

cli/tests/test_controllers_utils.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
import pytest
88
from openbb_cli.controllers.utils import (
9+
check_file_type_saved,
910
check_non_negative,
1011
check_positive,
1112
get_flair_and_username,
1213
get_user_agent,
1314
parse_and_split_input,
15+
parse_unknown_args_to_dict,
1416
print_goodbye,
1517
remove_file,
18+
validate_register_key,
1619
welcome_message,
1720
)
1821

@@ -138,3 +141,100 @@ def test_get_user_agent():
138141
"""Test getting the user agent."""
139142
result = get_user_agent()
140143
assert result.startswith("Mozilla/5.0")
144+
145+
146+
# --- Tests for parse_unknown_args_to_dict ---
147+
148+
149+
@pytest.mark.parametrize(
150+
"args, expected",
151+
[
152+
(["--key", "value"], {"key": "value"}),
153+
(["--a", "1", "--b", "hello"], {"a": 1, "b": "hello"}),
154+
(["--flag"], {}),
155+
(None, {}),
156+
([], {}),
157+
],
158+
)
159+
def test_parse_unknown_args_to_dict_basic(args, expected, mock_session):
160+
"""Test basic key-value parsing and edge cases."""
161+
result = parse_unknown_args_to_dict(args)
162+
assert result == expected
163+
164+
165+
@pytest.mark.parametrize(
166+
"args, expected",
167+
[
168+
(["--num", "42"], {"num": 42}),
169+
(["--pi", "3.14"], {"pi": 3.14}),
170+
(["--items", "[1, 2, 3]"], {"items": [1, 2, 3]}),
171+
(["--mapping", "{'a': 1}"], {"mapping": {"a": 1}}),
172+
(["--bool", "True"], {"bool": True}),
173+
(["--plain", "not-a-literal"], {"plain": "not-a-literal"}),
174+
],
175+
)
176+
def test_parse_unknown_args_to_dict_literal_eval(args, expected, mock_session):
177+
"""Test that ast.literal_eval correctly parses typed values."""
178+
result = parse_unknown_args_to_dict(args)
179+
assert result == expected
180+
181+
182+
def test_parse_unknown_args_to_dict_missing_value(mock_session):
183+
"""Test that a trailing --flag with no value prints a warning."""
184+
result = parse_unknown_args_to_dict(["--orphan"])
185+
assert result == {}
186+
mock_session.console.print.assert_called_once()
187+
188+
189+
# --- Tests for validate_register_key ---
190+
191+
192+
@pytest.mark.parametrize(
193+
"key, should_raise",
194+
[
195+
("my_api_key", False),
196+
("secret_123", False),
197+
("OBB_KEY", True),
198+
("my_OBB_key", True),
199+
("OBB", True),
200+
],
201+
)
202+
def test_validate_register_key(key, should_raise):
203+
"""Test that keys containing 'OBB' are rejected."""
204+
if should_raise:
205+
with pytest.raises(argparse.ArgumentTypeError, match="OBB"):
206+
validate_register_key(key)
207+
else:
208+
assert validate_register_key(key) == key
209+
210+
211+
# --- Tests for check_file_type_saved ---
212+
213+
214+
def test_check_file_type_saved_valid(mock_session):
215+
"""Test valid filenames are accepted."""
216+
checker = check_file_type_saved(valid_types=[".csv", ".json"])
217+
assert checker("report.csv") == "report.csv"
218+
assert checker("data.json") == "data.json"
219+
assert checker("a.csv,b.json") == "a.csv,b.json"
220+
221+
222+
def test_check_file_type_saved_invalid(mock_session):
223+
"""Test invalid filenames are rejected with a warning."""
224+
checker = check_file_type_saved(valid_types=[".csv"])
225+
result = checker("report.xlsx")
226+
assert result == ""
227+
mock_session.console.print.assert_called()
228+
229+
230+
def test_check_file_type_saved_empty(mock_session):
231+
"""Test empty input returns empty string."""
232+
checker = check_file_type_saved(valid_types=[".csv"])
233+
assert checker("") == ""
234+
assert checker() == ""
235+
236+
237+
def test_check_file_type_saved_no_valid_types(mock_session):
238+
"""Test that None valid_types returns empty string."""
239+
checker = check_file_type_saved(valid_types=None)
240+
assert checker("anything.csv") == ""

0 commit comments

Comments
 (0)