mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat(wallet): 钱包系统替代配额系统,新增支付与退款机制
- 新增钱包余额管理、充值、扣费、退款完整流程 - 新增支付网关抽象层(支持手动/支付宝/微信) - 用量计费从配额系统迁移到钱包余额扣费 - 新增管理员钱包管理与支付订单管理页面 - 新增用户钱包中心页面 - 移除独立 Key 锁定机制,统一由钱包余额控制 - 新增相关 API 路由、序列化器与数据库迁移 - 新增钱包、支付、退款相关测试
This commit is contained in:
79
tests/unit/test_api_key_auth_plugin.py
Normal file
79
tests/unit/test_api_key_auth_plugin.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from src.plugins.auth.api_key import ApiKeyAuthPlugin
|
||||
|
||||
|
||||
def _build_request() -> SimpleNamespace:
|
||||
return SimpleNamespace(
|
||||
headers={"x-api-key": "test-key"},
|
||||
client=SimpleNamespace(host="127.0.0.1"),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_key_auth_plugin_uses_standalone_wallet_for_billing() -> None:
|
||||
plugin = ApiKeyAuthPlugin()
|
||||
request = _build_request()
|
||||
db = MagicMock()
|
||||
|
||||
user = SimpleNamespace(id="user-1", username="alice", is_admin=False)
|
||||
api_key = SimpleNamespace(id="key-1", name="standalone-key", is_standalone=True)
|
||||
wallet = SimpleNamespace(id="wallet-key")
|
||||
|
||||
with (
|
||||
patch(
|
||||
"src.plugins.auth.api_key.AuthService.authenticate_api_key",
|
||||
return_value=(user, api_key),
|
||||
),
|
||||
patch(
|
||||
"src.plugins.auth.api_key.UsageService.check_request_balance",
|
||||
return_value=(True, "OK"),
|
||||
),
|
||||
patch("src.plugins.auth.api_key.WalletService.get_wallet", return_value=wallet) as get_wallet,
|
||||
patch(
|
||||
"src.plugins.auth.api_key.WalletService.serialize_wallet_summary",
|
||||
return_value={"id": "wallet-key"},
|
||||
),
|
||||
):
|
||||
context = await plugin.authenticate(request, db)
|
||||
|
||||
assert context is not None
|
||||
assert context.billing_info["billing"]["id"] == "wallet-key"
|
||||
get_wallet.assert_called_once_with(db, api_key_id="key-1")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_api_key_auth_plugin_uses_user_wallet_for_normal_key_billing() -> None:
|
||||
plugin = ApiKeyAuthPlugin()
|
||||
request = _build_request()
|
||||
db = MagicMock()
|
||||
|
||||
user = SimpleNamespace(id="user-2", username="bob", is_admin=False)
|
||||
api_key = SimpleNamespace(id="key-2", name="normal-key", is_standalone=False)
|
||||
wallet = SimpleNamespace(id="wallet-user")
|
||||
|
||||
with (
|
||||
patch(
|
||||
"src.plugins.auth.api_key.AuthService.authenticate_api_key",
|
||||
return_value=(user, api_key),
|
||||
),
|
||||
patch(
|
||||
"src.plugins.auth.api_key.UsageService.check_request_balance",
|
||||
return_value=(True, "OK"),
|
||||
),
|
||||
patch("src.plugins.auth.api_key.WalletService.get_wallet", return_value=wallet) as get_wallet,
|
||||
patch(
|
||||
"src.plugins.auth.api_key.WalletService.serialize_wallet_summary",
|
||||
return_value={"id": "wallet-user"},
|
||||
),
|
||||
):
|
||||
context = await plugin.authenticate(request, db)
|
||||
|
||||
assert context is not None
|
||||
assert context.billing_info["billing"]["id"] == "wallet-user"
|
||||
get_wallet.assert_called_once_with(db, user_id="user-2")
|
||||
Reference in New Issue
Block a user