Files
Aether/tests/services/test_provider_keys_query_service.py
AAEE86 08b89b7ef8 refactor(provider-keys): 拆分 keys 端点逻辑并补充配额刷新测试
将 admin keys 接口的创建、更新、查询、删除、导出与配额刷新逻辑迁移到 provider_keys 服务层

新增 auth_type 归一化、重复校验、响应构建与 quota_refresh(codex/kiro/antigravity)模块,并补充对应单元测试
2026-02-28 14:12:08 +08:00

156 lines
5.1 KiB
Python

from __future__ import annotations
from types import SimpleNamespace
from typing import Any, cast
import pytest
from src.core.exceptions import NotFoundException
from src.services.provider_keys import key_query_service as query_service_module
from src.services.provider_keys.key_query_service import (
get_keys_grouped_by_format,
list_provider_keys_responses,
)
class _FakeQuery:
def __init__(
self,
*,
first_result: Any = None,
all_result: list[Any] | None = None,
) -> None:
self._first_result = first_result
self._all_result = all_result or []
def join(self, *args: Any, **kwargs: Any) -> _FakeQuery:
return self
def filter(self, *args: Any, **kwargs: Any) -> _FakeQuery:
return self
def order_by(self, *args: Any, **kwargs: Any) -> _FakeQuery:
return self
def offset(self, *args: Any, **kwargs: Any) -> _FakeQuery:
return self
def limit(self, *args: Any, **kwargs: Any) -> _FakeQuery:
return self
def first(self) -> Any:
return self._first_result
def all(self) -> list[Any]:
return self._all_result
class _FakeGroupedDB:
def __init__(
self,
*,
key_provider_rows: list[tuple[Any, Any]],
endpoint_rows: list[tuple[str, str, str]],
) -> None:
self._key_provider_rows = key_provider_rows
self._endpoint_rows = endpoint_rows
def query(self, *models: Any) -> _FakeQuery:
if len(models) == 2:
return _FakeQuery(all_result=self._key_provider_rows)
if len(models) == 3:
return _FakeQuery(all_result=self._endpoint_rows)
raise AssertionError(f"unexpected query models: {models}")
class _FakeListDB:
def __init__(self, *, provider: Any, keys: list[SimpleNamespace]) -> None:
self._provider = provider
self._keys = keys
def query(self, model: Any) -> _FakeQuery:
model_name = getattr(model, "__name__", "")
if model_name == "Provider":
return _FakeQuery(first_result=self._provider)
if model_name == "ProviderAPIKey":
return _FakeQuery(all_result=self._keys)
raise AssertionError(f"unexpected query model: {model}")
def test_get_keys_grouped_by_format_builds_expected_shape(
monkeypatch: pytest.MonkeyPatch,
) -> None:
provider = SimpleNamespace(id="p1", is_active=True, name="Provider-1")
key = SimpleNamespace(
id="k1",
name="Key-1",
api_formats=["openai:chat", "openai:cli"],
auth_type="api_key",
api_key="enc-key",
internal_priority=3,
global_priority_by_format={"openai:chat": 8},
rate_multipliers={"openai:chat": 1.1},
is_active=True,
capabilities={"cache_1h": True, "ctx_1m": False},
success_count=8,
request_count=10,
total_response_time_ms=800,
health_by_format={"openai:chat": {"health_score": 0.7}},
circuit_breaker_by_format={"openai:chat": {"open": True}},
)
db = _FakeGroupedDB(
key_provider_rows=[(key, provider)],
endpoint_rows=[
("p1", "openai:chat", "https://chat.example"),
("p1", "openai:cli", "https://cli.example"),
],
)
monkeypatch.setattr(
query_service_module.crypto_service, "decrypt", lambda _v: "sk-1234567890abcd"
)
monkeypatch.setattr(
query_service_module,
"get_capability",
lambda name: SimpleNamespace(short_name="缓存1h") if name == "cache_1h" else None,
)
result = get_keys_grouped_by_format(cast(Any, db))
assert set(result.keys()) == {"openai:chat", "openai:cli"}
chat_item = result["openai:chat"][0]
assert chat_item["id"] == "k1"
assert chat_item["provider_name"] == "Provider-1"
assert chat_item["endpoint_base_url"] == "https://chat.example"
assert chat_item["format_priority"] == 8
assert chat_item["circuit_breaker_open"] is True
assert chat_item["health_score"] == 0.7
assert chat_item["capabilities"] == ["缓存1h"]
assert chat_item["api_key_masked"].startswith("sk-12345")
assert chat_item["api_key_masked"].endswith("abcd")
cli_item = result["openai:cli"][0]
assert cli_item["endpoint_base_url"] == "https://cli.example"
assert cli_item["format_priority"] is None
assert cli_item["circuit_breaker_open"] is False
assert cli_item["health_score"] == 1.0
def test_list_provider_keys_responses_provider_not_found_raises() -> None:
db = _FakeListDB(provider=None, keys=[])
with pytest.raises(NotFoundException, match="Provider p1 不存在"):
list_provider_keys_responses(cast(Any, db), provider_id="p1", skip=0, limit=10)
def test_list_provider_keys_responses_uses_response_builder(
monkeypatch: pytest.MonkeyPatch,
) -> None:
provider = SimpleNamespace(id="p1")
keys = [SimpleNamespace(id="k1"), SimpleNamespace(id="k2")]
db = _FakeListDB(provider=provider, keys=keys)
monkeypatch.setattr(query_service_module, "build_key_response", lambda key: {"id": key.id})
result = list_provider_keys_responses(cast(Any, db), provider_id="p1", skip=0, limit=10)
assert result == [{"id": "k1"}, {"id": "k2"}]