Files
hermes-agent/tests/hermes_cli/test_memory_setup.py
ethernet 5e4a2a3d24 refactor(pm): remove legacy dependency and launch managers
Competing installers and checkout-local venv assumptions bypassed PM
selection, install consent, and generation lifetimes. Route consumers
through PM and installation-bound launchers. Refresh source launchers
before obsolete Python entries can be collected.

Remove Node, browser, and CUA acquisition engines, obsolete venv-holder
handling, detached sync, and unused PM APIs. Keep historical updater
exports inert and preserve external tool ownership and native integration.

Share product freshness and prepared inputs across builders. Align plugin
admission, Docker provisioning, setup instructions, and behavioral tests.

Verified targeted Python and JavaScript tests, desktop and web typechecks,
scoped lint, real product builds, and the Docker frontend smoke test.
The missed post-setup test cleanup is included and verified.

Native Windows/macOS execution, full Rust compilation, and the complete
repository suite remain unverified. Historical compatibility requirements
were preserved and extended, not fully rescanned.
2026-09-12 14:57:38 -04:00

124 lines
4.4 KiB
Python

from types import SimpleNamespace
from unittest.mock import MagicMock
import hermes_cli.memory_setup as memory_setup
from hermes_cli.memory_setup import _CANCELLED, _curses_select
def test_cmd_setup_generic_choice_cancel_writes_nothing(tmp_path, monkeypatch):
class ChoiceProvider:
def __init__(self):
self.save_config = MagicMock()
def get_config_schema(self):
return [{
"key": "mode",
"description": "Mode",
"default": "one",
"choices": ["one", "two"],
}]
provider = ChoiceProvider()
selections = iter([0, _CANCELLED])
save_config = MagicMock()
install_dependencies = MagicMock()
monkeypatch.setattr(memory_setup, "_get_available_providers", lambda: [("fake", "local", provider)])
monkeypatch.setattr(memory_setup, "_curses_select", lambda *args, **kwargs: next(selections))
monkeypatch.setattr(memory_setup, "_install_dependencies", install_dependencies)
monkeypatch.setattr(memory_setup, "get_hermes_home", lambda: tmp_path)
monkeypatch.setattr("hermes_cli.config.load_config", lambda: {"memory": {}})
monkeypatch.setattr("hermes_cli.config.save_config", save_config)
memory_setup.cmd_setup(SimpleNamespace())
install_dependencies.assert_called_once_with("fake")
save_config.assert_not_called()
provider.save_config.assert_not_called()
assert not (tmp_path / ".env").exists()
# _write_env_vars's CR/LF-stripping, denylist, and plain-value-roundtrip
# behavior is covered by tests/hermes_cli/test_memory_setup_env_denylist.py,
# which exercises the current save_env_value-routed signature
# (env_writes, hermes_home=None) \u2014 these three tests pinned the prior direct
# Path.write_text(env_path, env_writes) signature/implementation and were
# removed along with it (#60587).
# ---------------------------------------------------------------------------
# provider extras — mode-aware expansion (#70636)
# ---------------------------------------------------------------------------
def test_install_dependencies_prepares_declared_extra_even_if_importable(tmp_path, monkeypatch):
"""PM, not ambient importability, decides whether constraints are current."""
import hermes_yaml as _yaml
plugin_dir = tmp_path / "mem0"
plugin_dir.mkdir()
(plugin_dir / "plugin.yaml").write_text(
_yaml.safe_dump({"extra": "mem0"}), encoding="utf-8"
)
monkeypatch.setattr(
"plugins.memory.find_provider_dir", lambda name: plugin_dir
)
synced = []
import pm
monkeypatch.setattr(pm, "available", lambda extra: True)
monkeypatch.setattr(
pm, "sync_venv",
lambda extras=None, explicit=False: synced.append((list(extras or []), explicit)),
)
memory_setup._install_dependencies("mem0")
assert synced == [(["mem0"], True)]
def test_cmd_status_memory_tool_gate_disabled(capsys, monkeypatch):
"""When both memory stores are disabled, Memory status reports memory tool as disabled."""
_cfg = {"memory": {"memory_enabled": False, "user_profile_enabled": False}}
monkeypatch.setattr("hermes_cli.config.load_config", lambda: _cfg)
# check_memory_requirements() reads the readonly loader, not load_config.
monkeypatch.setattr(
"hermes_cli.config.load_config_readonly", lambda: _cfg, raising=False
)
monkeypatch.setattr(memory_setup, "_get_available_providers", lambda: [])
memory_setup.cmd_status(SimpleNamespace())
captured = capsys.readouterr().out
assert "Memory tool: disabled ✗" in captured
assert "Memory injection: disabled ✗" in captured
assert "User profile: disabled ✗" in captured
def test_cmd_status_memory_tool_gate_enabled(capsys, monkeypatch):
"""When at least one memory store is enabled, Memory status reports memory tool as enabled."""
_cfg = {"memory": {"memory_enabled": True, "user_profile_enabled": False}}
monkeypatch.setattr("hermes_cli.config.load_config", lambda: _cfg)
monkeypatch.setattr(
"hermes_cli.config.load_config_readonly", lambda: _cfg, raising=False
)
monkeypatch.setattr(memory_setup, "_get_available_providers", lambda: [])
memory_setup.cmd_status(SimpleNamespace())
captured = capsys.readouterr().out
assert "Memory tool: enabled ✓" in captured
assert "Memory injection: enabled ✓" in captured
assert "User profile: disabled ✗" in captured