geo/backend/tests/test_services/test_adapter_key_source.py

111 lines
4.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from unittest.mock import MagicMock
import pytest
from app.services.ai_engine.base import AIEngineAdapter, EngineType
from app.services.api_key_manager import APIKeyManager, KeySource
class MockAdapter(AIEngineAdapter):
def __init__(self, api_key: str | None = None, **kwargs):
super().__init__(api_key=api_key, **kwargs)
async def query(self, query: str, brand_name: str, competitor_names: list[str] | None = None):
pass
def get_engine_type(self) -> EngineType:
return EngineType.CHATGPT
def _get_env_key(self) -> str | None:
return os.getenv("OPENAI_API_KEY", "")
class TestAdapterKeySource:
def test_adapter_accepts_key_manager_parameter(self):
key_manager = MagicMock(spec=APIKeyManager)
adapter = MockAdapter(key_manager=key_manager, user_id="user123")
assert adapter._key_manager is key_manager
assert adapter._user_id == "user123"
def test_adapter_accepts_api_key_parameter(self):
adapter = MockAdapter(api_key="direct-key-123")
assert adapter.api_key == "direct-key-123"
def test_resolve_key_from_direct_api_key(self):
adapter = MockAdapter(api_key="direct-key-123")
assert adapter.api_key == "direct-key-123"
def test_resolve_key_from_key_manager_user_key(self):
key_manager = MagicMock(spec=APIKeyManager)
key_manager.get_key.return_value = "manager-key-456"
adapter = MockAdapter(key_manager=key_manager, user_id="user123")
key_manager.get_key.assert_called_once_with("chatgpt", user_id="user123")
assert adapter.api_key == "manager-key-456"
def test_resolve_key_fallback_to_env_when_no_manager(self, monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "env-key-789")
adapter = MockAdapter()
assert adapter.api_key == "env-key-789"
def test_direct_api_key_priority_over_key_manager(self):
key_manager = MagicMock(spec=APIKeyManager)
key_manager.get_key.return_value = "manager-key-456"
adapter = MockAdapter(api_key="direct-key-123", key_manager=key_manager, user_id="user123")
key_manager.get_key.assert_not_called()
assert adapter.api_key == "direct-key-123"
def test_user_key_priority_over_system_key(self):
key_manager = MagicMock(spec=APIKeyManager)
key_manager.get_key.return_value = "user-key-from-manager"
adapter = MockAdapter(key_manager=key_manager, user_id="user123")
assert adapter.api_key == "user-key-from-manager"
def test_no_key_available_returns_empty(self, monkeypatch):
key_manager = MagicMock(spec=APIKeyManager)
key_manager.get_key.return_value = None
# 清除环境变量确保不会从环境变量获取key
monkeypatch.delenv("OPENAI_API_KEY", raising=False)
adapter = MockAdapter(key_manager=key_manager, user_id="user123")
assert adapter.api_key == ""
def test_adapter_with_all_parameters(self):
key_manager = MagicMock(spec=APIKeyManager)
key_manager.get_key.return_value = "full-key"
adapter = MockAdapter(
api_key=None,
rate_limiter=MagicMock(),
proxy="http://proxy:8080",
key_manager=key_manager,
user_id="test-user"
)
assert adapter._key_manager is key_manager
assert adapter._user_id == "test-user"
assert adapter.proxy == "http://proxy:8080"
class TestBatchQueryServiceKeyIntegration:
def test_build_adapters_with_key_manager(self):
from app.services.ai_engine.batch_query import BatchQueryService
key_manager = MagicMock(spec=APIKeyManager)
key_manager.get_key.return_value = "batch-test-key"
adapters = {
"chatgpt": MockAdapter(key_manager=key_manager, user_id="batch-user")
}
service = BatchQueryService(adapters)
service.set_user_context(user_id="batch-user", brand_id="brand-123")
assert service._user_id == "batch-user"
assert service._brand_id == "brand-123"