Files
hermes-agent/tests/tools/test_secrets_tool.py

98 lines
3.8 KiB
Python
Raw Normal View History

import json
import os
from tools.env_passthrough import clear_env_passthrough, get_all_passthrough
from tools.secrets_tool import secrets_tool, set_secrets_request_callback
def setup_function(_fn):
clear_env_passthrough()
set_secrets_request_callback(None)
def test_list_returns_names_only(monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-secret")
monkeypatch.setenv("PATH", "/usr/bin")
result = json.loads(secrets_tool({"action": "list"}))
assert "OPENAI_API_KEY" in result["secrets"]
assert "PATH" not in result["secrets"]
assert "sk-test-secret" not in json.dumps(result)
def test_check_splits_configured_and_missing(monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-secret")
result = json.loads(secrets_tool({"action": "check", "keys": ["OPENAI_API_KEY", "MISSING_API_KEY"]}))
assert result["configured"] == ["OPENAI_API_KEY"]
assert result["missing"] == ["MISSING_API_KEY"]
assert result["rejected"] == []
def test_check_rejects_non_secret_like_vars(monkeypatch):
monkeypatch.setenv("PATH", "/usr/bin")
monkeypatch.setenv("HOME", "/tmp")
monkeypatch.setenv("SSH_AUTH_SOCK", "/tmp/agent.sock")
monkeypatch.setenv("SESSION_COOKIE_NAME", "sid")
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-secret")
result = json.loads(secrets_tool({"action": "check", "keys": ["PATH", "HOME", "SSH_AUTH_SOCK", "SESSION_COOKIE_NAME", "OPENAI_API_KEY"]}))
assert result["configured"] == ["OPENAI_API_KEY"]
assert sorted(result["rejected"]) == ["HOME", "PATH", "SESSION_COOKIE_NAME", "SSH_AUTH_SOCK"]
def test_request_uses_secure_callback():
calls = []
def fake_callback(var_name, prompt, metadata=None):
calls.append((var_name, prompt, metadata))
return {"success": True, "skipped": False, "message": "stored"}
set_secrets_request_callback(fake_callback)
result = json.loads(secrets_tool({
"action": "request",
"key": "TENOR_API_KEY",
"description": "Tenor API key",
"instructions": "Find it in Tenor dashboard",
"prompt": "Enter Tenor API key",
}))
assert result["success"] is True
assert result["stored"] is True
assert calls[0][0] == "TENOR_API_KEY"
assert calls[0][1] == "Enter Tenor API key"
assert calls[0][2]["description"] == "Tenor API key"
assert calls[0][2]["instructions"] == "Find it in Tenor dashboard"
def test_request_without_callback_returns_hint():
result = json.loads(secrets_tool({"action": "request", "key": "TENOR_API_KEY"}))
assert result["success"] is False
assert "local cli" in result["hint"].lower()
def test_delete_clears_env(monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-secret")
result = json.loads(secrets_tool({"action": "delete", "key": "OPENAI_API_KEY"}))
assert result["success"] is True
assert "OPENAI_API_KEY" not in os.environ
def test_delete_removes_key_from_env_file(tmp_path, monkeypatch):
hermes_home = tmp_path / ".hermes"
hermes_home.mkdir()
env_path = hermes_home / ".env"
env_path.write_text("OPENAI_API_KEY=sk-test-secret\nKEEP_ME=value\n", encoding="utf-8")
monkeypatch.setenv("HERMES_HOME", str(hermes_home))
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-secret")
result = json.loads(secrets_tool({"action": "delete", "key": "OPENAI_API_KEY"}))
assert result["success"] is True
content = env_path.read_text(encoding="utf-8")
assert "OPENAI_API_KEY=" not in content
assert "KEEP_ME=value" in content
def test_inject_registers_existing_keys(monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "sk-test-secret")
result = json.loads(secrets_tool({"action": "inject", "keys": ["OPENAI_API_KEY", "MISSING_API_KEY"]}))
assert result["injected"] == ["OPENAI_API_KEY"]
assert result["missing"] == ["MISSING_API_KEY"]
assert "OPENAI_API_KEY" in get_all_passthrough()