"""Unit tests for src/my_deepagent/secrets.py.""" from __future__ import annotations import pytest import my_deepagent.keys as keys_module from my_deepagent.config import load_config from my_deepagent.errors import MyDeepAgentError from my_deepagent.secrets import resolve_openrouter_api_key class _FakeKeyring: def __init__(self) -> None: self.store: dict[tuple[str, str], str] = {} def get_password(self, service: str, username: str) -> str | None: return self.store.get((service, username)) def set_password(self, service: str, username: str, value: str) -> None: self.store[(service, username)] = value def delete_password(self, service: str, username: str) -> None: self.store.pop((service, username), None) @pytest.fixture def fake_keyring(monkeypatch: pytest.MonkeyPatch) -> _FakeKeyring: fake = _FakeKeyring() monkeypatch.setattr(keys_module.keyring, "get_password", fake.get_password) monkeypatch.setattr(keys_module.keyring, "set_password", fake.set_password) monkeypatch.setattr(keys_module.keyring, "delete_password", fake.delete_password) return fake def test_resolves_from_config(fake_keyring: _FakeKeyring) -> None: config = load_config(openrouter_api_key="sk-config-key") result = resolve_openrouter_api_key(config) assert result == "sk-config-key" def test_resolves_from_mydeepagent_env( monkeypatch: pytest.MonkeyPatch, fake_keyring: _FakeKeyring ) -> None: monkeypatch.delenv("MYDEEPAGENT_OPENROUTER_API_KEY", raising=False) monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) monkeypatch.setenv("MYDEEPAGENT_OPENROUTER_API_KEY", "sk-env-mydeepagent") config = load_config(openrouter_api_key=None) assert resolve_openrouter_api_key(config) == "sk-env-mydeepagent" def test_resolves_from_openrouter_env_fallback( monkeypatch: pytest.MonkeyPatch, fake_keyring: _FakeKeyring ) -> None: monkeypatch.delenv("MYDEEPAGENT_OPENROUTER_API_KEY", raising=False) monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) monkeypatch.setenv("OPENROUTER_API_KEY", "sk-env-fallback") config = load_config(openrouter_api_key=None) assert resolve_openrouter_api_key(config) == "sk-env-fallback" def test_resolves_from_keyring(monkeypatch: pytest.MonkeyPatch, fake_keyring: _FakeKeyring) -> None: monkeypatch.delenv("MYDEEPAGENT_OPENROUTER_API_KEY", raising=False) monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) keys_module.set_api_key("openrouter", "sk-keyring-key") config = load_config(openrouter_api_key=None) assert resolve_openrouter_api_key(config) == "sk-keyring-key" def test_raises_backend_auth_failed_when_all_missing( monkeypatch: pytest.MonkeyPatch, fake_keyring: _FakeKeyring ) -> None: monkeypatch.delenv("MYDEEPAGENT_OPENROUTER_API_KEY", raising=False) monkeypatch.delenv("OPENROUTER_API_KEY", raising=False) config = load_config(openrouter_api_key=None) with pytest.raises(MyDeepAgentError) as exc_info: resolve_openrouter_api_key(config) assert exc_info.value.code == "backend_auth_failed" def test_config_takes_priority_over_env( monkeypatch: pytest.MonkeyPatch, fake_keyring: _FakeKeyring ) -> None: monkeypatch.setenv("MYDEEPAGENT_OPENROUTER_API_KEY", "sk-env-should-lose") config = load_config(openrouter_api_key="sk-config-wins") assert resolve_openrouter_api_key(config) == "sk-config-wins"