/ tests / hermes_cli / test_auth_provider_gate.py
test_auth_provider_gate.py
 1  """Tests for is_provider_explicitly_configured()."""
 2  
 3  import json
 4  import os
 5  import pytest
 6  
 7  
 8  def _write_config(tmp_path, config: dict) -> None:
 9      hermes_home = tmp_path / "hermes"
10      hermes_home.mkdir(parents=True, exist_ok=True)
11      import yaml
12      (hermes_home / "config.yaml").write_text(yaml.dump(config))
13  
14  
15  def _write_auth_store(tmp_path, payload: dict) -> None:
16      hermes_home = tmp_path / "hermes"
17      hermes_home.mkdir(parents=True, exist_ok=True)
18      (hermes_home / "auth.json").write_text(json.dumps(payload, indent=2))
19  
20  
21  @pytest.fixture(autouse=True)
22  def _clean_anthropic_env(monkeypatch):
23      """Strip Anthropic env vars so CI secrets don't leak into tests."""
24      for key in ("ANTHROPIC_API_KEY", "ANTHROPIC_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN"):
25          monkeypatch.delenv(key, raising=False)
26  
27  
28  def test_returns_false_when_no_config(tmp_path, monkeypatch):
29      monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
30      (tmp_path / "hermes").mkdir(parents=True, exist_ok=True)
31  
32      from hermes_cli.auth import is_provider_explicitly_configured
33      assert is_provider_explicitly_configured("anthropic") is False
34  
35  
36  def test_returns_true_when_active_provider_matches(tmp_path, monkeypatch):
37      monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
38      _write_auth_store(tmp_path, {
39          "version": 1,
40          "providers": {},
41          "active_provider": "anthropic",
42      })
43  
44      from hermes_cli.auth import is_provider_explicitly_configured
45      assert is_provider_explicitly_configured("anthropic") is True
46  
47  
48  def test_returns_true_when_config_provider_matches(tmp_path, monkeypatch):
49      monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
50      _write_config(tmp_path, {"model": {"provider": "anthropic", "default": "claude-sonnet-4-6"}})
51  
52      from hermes_cli.auth import is_provider_explicitly_configured
53      assert is_provider_explicitly_configured("anthropic") is True
54  
55  
56  def test_returns_false_when_config_provider_is_different(tmp_path, monkeypatch):
57      monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
58      _write_config(tmp_path, {"model": {"provider": "kimi-coding", "default": "kimi-k2"}})
59      _write_auth_store(tmp_path, {
60          "version": 1,
61          "providers": {},
62          "active_provider": None,
63      })
64  
65      from hermes_cli.auth import is_provider_explicitly_configured
66      assert is_provider_explicitly_configured("anthropic") is False
67  
68  
69  def test_returns_true_when_anthropic_env_var_set(tmp_path, monkeypatch):
70      monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
71      monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-ant-api03-realkey")
72      (tmp_path / "hermes").mkdir(parents=True, exist_ok=True)
73  
74      from hermes_cli.auth import is_provider_explicitly_configured
75      assert is_provider_explicitly_configured("anthropic") is True
76  
77  
78  def test_claude_code_oauth_token_does_not_count_as_explicit(tmp_path, monkeypatch):
79      """CLAUDE_CODE_OAUTH_TOKEN is set by Claude Code, not the user — must not gate."""
80      monkeypatch.setenv("HERMES_HOME", str(tmp_path / "hermes"))
81      monkeypatch.setenv("CLAUDE_CODE_OAUTH_TOKEN", "sk-ant-oat01-auto-token")
82      (tmp_path / "hermes").mkdir(parents=True, exist_ok=True)
83  
84      from hermes_cli.auth import is_provider_explicitly_configured
85      assert is_provider_explicitly_configured("anthropic") is False