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