* 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
68 lines
2.1 KiB
Python
68 lines
2.1 KiB
Python
"""Tests for the /plan CLI slash command."""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from agent.skill_commands import scan_skill_commands
|
|
from cli import HermesCLI
|
|
|
|
|
|
def _make_cli():
|
|
cli_obj = HermesCLI.__new__(HermesCLI)
|
|
cli_obj.config = {}
|
|
cli_obj.console = MagicMock()
|
|
cli_obj.agent = None
|
|
cli_obj.conversation_history = []
|
|
cli_obj.session_id = "sess-123"
|
|
cli_obj._pending_input = MagicMock()
|
|
return cli_obj
|
|
|
|
|
|
def _make_plan_skill(skills_dir):
|
|
skill_dir = skills_dir / "plan"
|
|
skill_dir.mkdir(parents=True, exist_ok=True)
|
|
(skill_dir / "SKILL.md").write_text(
|
|
"""---
|
|
name: plan
|
|
description: Plan mode skill.
|
|
---
|
|
|
|
# Plan
|
|
|
|
Use the current conversation context when no explicit instruction is provided.
|
|
Save plans under the active workspace's .hermes/plans directory.
|
|
"""
|
|
)
|
|
|
|
|
|
class TestCLIPlanCommand:
|
|
def test_plan_command_queues_plan_skill_message(self, tmp_path, monkeypatch):
|
|
cli_obj = _make_cli()
|
|
|
|
with patch("tools.skills_tool.SKILLS_DIR", tmp_path):
|
|
_make_plan_skill(tmp_path)
|
|
scan_skill_commands()
|
|
result = cli_obj.process_command("/plan Add OAuth login")
|
|
|
|
assert result is True
|
|
cli_obj._pending_input.put.assert_called_once()
|
|
queued = cli_obj._pending_input.put.call_args[0][0]
|
|
assert "Plan mode skill" in queued
|
|
assert "Add OAuth login" in queued
|
|
assert ".hermes/plans" in queued
|
|
assert str(tmp_path / "plans") not in queued
|
|
assert "active workspace/backend cwd" in queued
|
|
assert "Runtime note:" in queued
|
|
|
|
def test_plan_without_args_uses_skill_context_guidance(self, tmp_path, monkeypatch):
|
|
cli_obj = _make_cli()
|
|
|
|
with patch("tools.skills_tool.SKILLS_DIR", tmp_path):
|
|
_make_plan_skill(tmp_path)
|
|
scan_skill_commands()
|
|
cli_obj.process_command("/plan")
|
|
|
|
queued = cli_obj._pending_input.put.call_args[0][0]
|
|
assert "current conversation context" in queued
|
|
assert ".hermes/plans/" in queued
|
|
assert "conversation-plan.md" in queued
|