test_terminal_menu_fallbacks.py
1 """Regression tests for numbered fallbacks when TerminalMenu cannot initialize.""" 2 3 import subprocess 4 import sys 5 import types 6 7 from hermes_cli.config import load_config, save_config 8 9 10 class _BrokenTerminalMenu: 11 def __init__(self, *args, **kwargs): 12 raise subprocess.CalledProcessError(2, ["tput", "clear"]) 13 14 15 def test_prompt_model_selection_falls_back_on_terminalmenu_runtime_error(monkeypatch): 16 from hermes_cli.auth import _prompt_model_selection 17 18 monkeypatch.setitem( 19 sys.modules, 20 "simple_term_menu", 21 types.SimpleNamespace(TerminalMenu=_BrokenTerminalMenu), 22 ) 23 responses = iter(["2"]) 24 monkeypatch.setattr("builtins.input", lambda _prompt="": next(responses)) 25 26 selected = _prompt_model_selection(["model-a", "model-b"]) 27 28 assert selected == "model-b" 29 30 31 def test_prompt_reasoning_effort_falls_back_on_terminalmenu_runtime_error(monkeypatch): 32 from hermes_cli.main import _prompt_reasoning_effort_selection 33 34 monkeypatch.setitem( 35 sys.modules, 36 "simple_term_menu", 37 types.SimpleNamespace(TerminalMenu=_BrokenTerminalMenu), 38 ) 39 responses = iter(["3"]) 40 monkeypatch.setattr("builtins.input", lambda _prompt="": next(responses)) 41 42 selected = _prompt_reasoning_effort_selection(["low", "medium", "high"], current_effort="") 43 44 assert selected == "high" 45 46 47 def test_remove_custom_provider_falls_back_on_terminalmenu_runtime_error(tmp_path, monkeypatch): 48 from hermes_cli.main import _remove_custom_provider 49 50 monkeypatch.setenv("HERMES_HOME", str(tmp_path)) 51 monkeypatch.setitem( 52 sys.modules, 53 "simple_term_menu", 54 types.SimpleNamespace(TerminalMenu=_BrokenTerminalMenu), 55 ) 56 57 cfg = load_config() 58 cfg["custom_providers"] = [ 59 {"name": "Local A", "base_url": "http://localhost:8001/v1"}, 60 {"name": "Local B", "base_url": "http://localhost:8002/v1"}, 61 ] 62 save_config(cfg) 63 64 responses = iter(["1"]) 65 monkeypatch.setattr("builtins.input", lambda _prompt="": next(responses)) 66 67 _remove_custom_provider(cfg) 68 69 reloaded = load_config() 70 assert reloaded["custom_providers"] == [ 71 {"name": "Local B", "base_url": "http://localhost:8002/v1"}, 72 ] 73 74 75 def test_named_custom_provider_model_picker_falls_back_on_terminalmenu_runtime_error(tmp_path, monkeypatch): 76 from hermes_cli.main import _model_flow_named_custom 77 78 monkeypatch.setenv("HERMES_HOME", str(tmp_path)) 79 monkeypatch.setitem( 80 sys.modules, 81 "simple_term_menu", 82 types.SimpleNamespace(TerminalMenu=_BrokenTerminalMenu), 83 ) 84 monkeypatch.setattr("hermes_cli.models.fetch_api_models", lambda *args, **kwargs: ["model-a", "model-b"]) 85 monkeypatch.setattr("hermes_cli.auth.deactivate_provider", lambda: None) 86 87 cfg = load_config() 88 save_config(cfg) 89 90 responses = iter(["2"]) 91 monkeypatch.setattr("builtins.input", lambda _prompt="": next(responses)) 92 93 _model_flow_named_custom( 94 cfg, 95 { 96 "name": "Local", 97 "base_url": "http://localhost:8000/v1", 98 "api_key": "", 99 "model": "", 100 }, 101 ) 102 103 reloaded = load_config() 104 assert reloaded["model"]["provider"] == "custom" 105 assert reloaded["model"]["base_url"] == "http://localhost:8000/v1" 106 assert reloaded["model"]["default"] == "model-b"