* refactor: re-architect tests to mirror the codebase
* Update tests.yml
* fix: add missing tool_error imports after registry refactor
* fix(tests): replace patch.dict with monkeypatch to prevent env var leaks under xdist
patch.dict(os.environ) can leak TERMINAL_ENV across xdist workers,
causing test_code_execution tests to hit the Modal remote path.
* fix(tests): fix update_check and telegram xdist failures
- test_update_check: replace patch("hermes_cli.banner.os.getenv") with
monkeypatch.setenv("HERMES_HOME") — banner.py no longer imports os
directly, it uses get_hermes_home() from hermes_constants.
- test_telegram_conflict/approval_buttons: provide real exception classes
for telegram.error mock (NetworkError, TimedOut, BadRequest) so the
except clause in connect() doesn't fail with "catching classes that do
not inherit from BaseException" when xdist pollutes sys.modules.
* fix(tests): accept unavailable_models kwarg in _prompt_model_selection mock
66 lines
2.2 KiB
Python
66 lines
2.2 KiB
Python
"""Regression tests for loading feedback on slow slash commands."""
|
|
|
|
from unittest.mock import patch
|
|
|
|
from cli import HermesCLI
|
|
|
|
|
|
class TestCLILoadingIndicator:
|
|
def _make_cli(self):
|
|
cli_obj = HermesCLI.__new__(HermesCLI)
|
|
cli_obj._app = None
|
|
cli_obj._last_invalidate = 0.0
|
|
cli_obj._command_running = False
|
|
cli_obj._command_status = ""
|
|
return cli_obj
|
|
|
|
def test_skills_command_sets_busy_state_and_prints_status(self, capsys):
|
|
cli_obj = self._make_cli()
|
|
seen = {}
|
|
|
|
def fake_handle(cmd: str):
|
|
seen["cmd"] = cmd
|
|
seen["running"] = cli_obj._command_running
|
|
seen["status"] = cli_obj._command_status
|
|
print("skills done")
|
|
|
|
with patch.object(cli_obj, "_handle_skills_command", side_effect=fake_handle), \
|
|
patch.object(cli_obj, "_invalidate") as invalidate_mock:
|
|
assert cli_obj.process_command("/skills search kubernetes")
|
|
|
|
output = capsys.readouterr().out
|
|
assert "⏳ Searching skills..." in output
|
|
assert "skills done" in output
|
|
assert seen == {
|
|
"cmd": "/skills search kubernetes",
|
|
"running": True,
|
|
"status": "Searching skills...",
|
|
}
|
|
assert cli_obj._command_running is False
|
|
assert cli_obj._command_status == ""
|
|
assert invalidate_mock.call_count == 2
|
|
|
|
def test_reload_mcp_sets_busy_state_and_prints_status(self, capsys):
|
|
cli_obj = self._make_cli()
|
|
seen = {}
|
|
|
|
def fake_reload():
|
|
seen["running"] = cli_obj._command_running
|
|
seen["status"] = cli_obj._command_status
|
|
print("reload done")
|
|
|
|
with patch.object(cli_obj, "_reload_mcp", side_effect=fake_reload), \
|
|
patch.object(cli_obj, "_invalidate") as invalidate_mock:
|
|
assert cli_obj.process_command("/reload-mcp")
|
|
|
|
output = capsys.readouterr().out
|
|
assert "⏳ Reloading MCP servers..." in output
|
|
assert "reload done" in output
|
|
assert seen == {
|
|
"running": True,
|
|
"status": "Reloading MCP servers...",
|
|
}
|
|
assert cli_obj._command_running is False
|
|
assert cli_obj._command_status == ""
|
|
assert invalidate_mock.call_count == 2
|