feat: add balance API endpoint
This commit is contained in:
@@ -120,6 +120,77 @@ class ApiKeyAuthenticationTests(TestCase):
|
||||
self.assertEqual(response.data["error"]["code"], "unauthorized")
|
||||
|
||||
|
||||
class BalanceApiTests(TestCase):
|
||||
url = "/api/v1/balance"
|
||||
|
||||
def setUp(self):
|
||||
suffix = uuid.uuid4().hex[:8]
|
||||
self.user = get_user_model().objects.create_user(
|
||||
username=f"balance-user-{suffix}",
|
||||
email=f"balance-user-{suffix}@example.com",
|
||||
password="password",
|
||||
)
|
||||
self.api_key, self.raw_key = ApiKey.create_for_user(self.user, name="balance")
|
||||
self.client = APIClient()
|
||||
|
||||
def auth_header(self, raw_key: str | None = None) -> dict:
|
||||
return {"HTTP_AUTHORIZATION": f"Bearer {raw_key or self.raw_key}"}
|
||||
|
||||
def test_balance_returns_wallet_balance_matching_ledger_sum(self):
|
||||
UserWallet.objects.create(user=self.user, points_balance=100)
|
||||
PointsLedger.objects.create(
|
||||
user=self.user,
|
||||
change_type=PointsLedger.ChangeType.RECHARGE,
|
||||
points_delta=120,
|
||||
balance_after=120,
|
||||
ref_order_id=1,
|
||||
)
|
||||
call = CallRecord.objects.create(
|
||||
user=self.user,
|
||||
api_key=self.api_key,
|
||||
operation_type=CallRecord.OperationType.TITLE,
|
||||
alias="title-standard",
|
||||
model_used="gpt-5.5",
|
||||
points_cost=20,
|
||||
status=CallRecord.Status.SUCCESS,
|
||||
)
|
||||
PointsLedger.objects.create(
|
||||
user=self.user,
|
||||
change_type=PointsLedger.ChangeType.CONSUME,
|
||||
points_delta=-20,
|
||||
balance_after=100,
|
||||
ref_call=call,
|
||||
)
|
||||
|
||||
response = self.client.get(self.url, **self.auth_header())
|
||||
|
||||
ledger_sum = sum(
|
||||
PointsLedger.objects.filter(user=self.user).values_list(
|
||||
"points_delta",
|
||||
flat=True,
|
||||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data["user"], self.user.username)
|
||||
self.assertEqual(response.data["points_balance"], 100)
|
||||
self.assertEqual(response.data["points_balance"], ledger_sum)
|
||||
|
||||
def test_balance_returns_zero_without_creating_missing_wallet(self):
|
||||
response = self.client.get(self.url, **self.auth_header())
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.data["points_balance"], 0)
|
||||
self.assertFalse(UserWallet.objects.filter(user=self.user).exists())
|
||||
|
||||
def test_balance_does_not_accept_web_session_without_api_key(self):
|
||||
self.client.force_login(self.user)
|
||||
|
||||
response = self.client.get(self.url)
|
||||
|
||||
self.assertEqual(response.status_code, 401)
|
||||
self.assertEqual(response.data["error"]["code"], "unauthorized")
|
||||
|
||||
|
||||
class FakeGenerationProvider:
|
||||
def __init__(self, *, capabilities=None):
|
||||
self._capabilities = set(capabilities or {"text", "image", "vision"})
|
||||
|
||||
Reference in New Issue
Block a user