mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 09:50:21 +08:00
refactor: Antigravity/Codex 服务重构为插件化适配器架构
- 将 Antigravity 和 Codex 从独立模块迁移至 src/services/provider/adapters/ 插件体系 - 新增 provider_types 和 oauth_token 模块,移除 maintenance_scheduler 中的 OAuth 定时刷新 - 增强 admin API:扩展 keys 和 provider_query 端点,新增 dashboard 路由 - 大幅增强 ProviderDetailDrawer 组件,新增 AntigravityQuotaDialog - 改进 handler 基类(chat/cli)和错误分类器 - 优化 fetch_scheduler 和 upstream_fetcher - 前端 UI 组件清理和优化 - 更新测试以匹配新模块结构
This commit is contained in:
69
tests/services/test_upstream_fetcher_antigravity_models.py
Normal file
69
tests/services/test_upstream_fetcher_antigravity_models.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from src.services.model.upstream_fetcher import UpstreamModelsFetchContext, fetch_models_for_key
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_models_for_key_antigravity_parses_quota() -> None:
|
||||
mock_resp = {
|
||||
"models": {
|
||||
"claude-sonnet-4": {
|
||||
"displayName": "Claude Sonnet 4",
|
||||
"quotaInfo": {"remainingFraction": 0.75, "resetTime": "2024-01-15T12:00:00Z"},
|
||||
},
|
||||
"gemini-2.5-pro": {
|
||||
"displayName": "Gemini 2.5 Pro",
|
||||
"quotaInfo": {"remainingFraction": 0.0},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
ctx = UpstreamModelsFetchContext(
|
||||
provider_type="antigravity",
|
||||
api_key_value="tok",
|
||||
format_to_endpoint={},
|
||||
proxy_config=None,
|
||||
auth_config={"project_id": "project-1"},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"src.services.provider.adapters.antigravity.client.fetch_available_models",
|
||||
AsyncMock(return_value=mock_resp),
|
||||
):
|
||||
models, errors, ok, meta = await fetch_models_for_key(ctx, timeout_seconds=1.0)
|
||||
|
||||
assert ok is True
|
||||
assert errors == []
|
||||
|
||||
ids = {m.get("id") for m in models}
|
||||
assert "claude-sonnet-4" in ids
|
||||
assert "gemini-2.5-pro" in ids
|
||||
|
||||
assert isinstance(meta, dict)
|
||||
quota = meta["antigravity"]["quota_by_model"]
|
||||
assert quota["claude-sonnet-4"]["remaining_fraction"] == 0.75
|
||||
assert quota["claude-sonnet-4"]["used_percent"] == 25.0
|
||||
assert quota["claude-sonnet-4"]["reset_time"] == "2024-01-15T12:00:00Z"
|
||||
assert quota["gemini-2.5-pro"]["used_percent"] == 100.0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_fetch_models_for_key_antigravity_requires_project_id() -> None:
|
||||
ctx = UpstreamModelsFetchContext(
|
||||
provider_type="antigravity",
|
||||
api_key_value="tok",
|
||||
format_to_endpoint={},
|
||||
proxy_config=None,
|
||||
auth_config={},
|
||||
)
|
||||
|
||||
models, errors, ok, meta = await fetch_models_for_key(ctx, timeout_seconds=1.0)
|
||||
|
||||
assert ok is False
|
||||
assert models == []
|
||||
assert meta is None
|
||||
assert any("project_id" in e for e in errors)
|
||||
Reference in New Issue
Block a user