fix(billing): unify quota counters, fix Stripe webhooks, tier/plan sync
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 3m16s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 3m16s
This commit is contained in:
@@ -115,26 +115,22 @@ def client(users_file: Path, monkeypatch):
|
||||
monkeypatch.setattr(RateLimitManager, "check_request", _check_request_allow)
|
||||
monkeypatch.setattr(RateLimitManager, "check_translation", _check_translation_allow)
|
||||
|
||||
from middleware.tier_quota import TierQuotaService
|
||||
def _check_usage_limits_allow(user):
|
||||
return {
|
||||
"can_translate": True,
|
||||
"docs_used": 0,
|
||||
"docs_limit": 5,
|
||||
"docs_remaining": 5,
|
||||
"pages_used": 0,
|
||||
"extra_credits": 0,
|
||||
"max_pages_per_doc": 50,
|
||||
"max_file_size_mb": 10,
|
||||
"allowed_providers": ["google", "deepl"],
|
||||
}
|
||||
|
||||
async def _check_quota_allow(self, user_id, tier):
|
||||
from middleware.tier_quota import QuotaResult
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
tomorrow = now.date() + timedelta(days=1)
|
||||
reset_at = datetime(
|
||||
tomorrow.year, tomorrow.month, tomorrow.day, tzinfo=timezone.utc
|
||||
)
|
||||
return QuotaResult(
|
||||
allowed=True, remaining=5, reset_at_utc=reset_at, current_usage=0, limit=5
|
||||
)
|
||||
|
||||
async def _increment_noop(self, user_id):
|
||||
pass
|
||||
|
||||
monkeypatch.setattr(TierQuotaService, "check_quota", _check_quota_allow)
|
||||
monkeypatch.setattr(TierQuotaService, "increment_on_success", _increment_noop)
|
||||
monkeypatch.setattr(
|
||||
"routes.translate_routes.check_usage_limits", _check_usage_limits_allow
|
||||
)
|
||||
|
||||
from main import app
|
||||
|
||||
@@ -477,24 +473,22 @@ class TestQuotaExceeded:
|
||||
|
||||
def test_returns_429_when_quota_exceeded(self, client, monkeypatch):
|
||||
"""Returns 429 with QUOTA_EXCEEDED when quota exceeded"""
|
||||
from middleware.tier_quota import TierQuotaService, QuotaResult
|
||||
from datetime import datetime, timezone, timedelta
|
||||
def _check_usage_limits_denied(user):
|
||||
return {
|
||||
"can_translate": False,
|
||||
"docs_used": 5,
|
||||
"docs_limit": 5,
|
||||
"docs_remaining": 0,
|
||||
"pages_used": 0,
|
||||
"extra_credits": 0,
|
||||
"max_pages_per_doc": 50,
|
||||
"max_file_size_mb": 10,
|
||||
"allowed_providers": ["google", "deepl"],
|
||||
}
|
||||
|
||||
async def _check_quota_denied(self, user_id, tier):
|
||||
now = datetime.now(timezone.utc)
|
||||
tomorrow = now.date() + timedelta(days=1)
|
||||
reset_at = datetime(
|
||||
tomorrow.year, tomorrow.month, tomorrow.day, tzinfo=timezone.utc
|
||||
)
|
||||
return QuotaResult(
|
||||
allowed=False,
|
||||
remaining=0,
|
||||
reset_at_utc=reset_at,
|
||||
current_usage=5,
|
||||
limit=5,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(TierQuotaService, "check_quota", _check_quota_denied)
|
||||
monkeypatch.setattr(
|
||||
"routes.translate_routes.check_usage_limits", _check_usage_limits_denied
|
||||
)
|
||||
|
||||
# Register and login
|
||||
client.post(REGISTER_URL, json=VALID_USER)
|
||||
@@ -530,24 +524,23 @@ class TestQuotaExceeded:
|
||||
|
||||
def test_includes_retry_after_header(self, client, monkeypatch):
|
||||
"""Includes Retry-After header on 429"""
|
||||
from middleware.tier_quota import TierQuotaService, QuotaResult
|
||||
from datetime import datetime, timezone, timedelta
|
||||
|
||||
async def _check_quota_denied(self, user_id, tier):
|
||||
now = datetime.now(timezone.utc)
|
||||
tomorrow = now.date() + timedelta(days=1)
|
||||
reset_at = datetime(
|
||||
tomorrow.year, tomorrow.month, tomorrow.day, tzinfo=timezone.utc
|
||||
)
|
||||
return QuotaResult(
|
||||
allowed=False,
|
||||
remaining=0,
|
||||
reset_at_utc=reset_at,
|
||||
current_usage=5,
|
||||
limit=5,
|
||||
)
|
||||
def _check_usage_limits_denied(user):
|
||||
return {
|
||||
"can_translate": False,
|
||||
"docs_used": 5,
|
||||
"docs_limit": 5,
|
||||
"docs_remaining": 0,
|
||||
"pages_used": 0,
|
||||
"extra_credits": 0,
|
||||
"max_pages_per_doc": 50,
|
||||
"max_file_size_mb": 10,
|
||||
"allowed_providers": ["google", "deepl"],
|
||||
}
|
||||
|
||||
monkeypatch.setattr(TierQuotaService, "check_quota", _check_quota_denied)
|
||||
monkeypatch.setattr(
|
||||
"routes.translate_routes.check_usage_limits", _check_usage_limits_denied
|
||||
)
|
||||
|
||||
client.post(REGISTER_URL, json=VALID_USER)
|
||||
response = client.post(
|
||||
|
||||
Reference in New Issue
Block a user