Files
MathApp/ai_tutor/tests_quota.py
Zareian 947f946909 Question packs removed at the root; all subscriptions 4 assistant questions a day; Bazaar is subscription-only
- subscription.0017/0018, payment.0013: pack plans deleted, QuestionCredit/HeartsPass models and Plan.kind /
  question_credits / hearts_days / Order.question_credits / hearts_days dropped. The only paid pack order was the
  company owner's test account (user 26).
- Assistant: no credit spending; quota is the daily cap only (free 2, every plan 4, gift subscription 4).
- Bazaar: verify_purchase is subscription-only (no inapp guess), start/purchase responses lose productType,
  verify refuses an order without a subscription. A paid order with no subscription now logs ERROR.
- Removed POST /api/payment/orders (internal; no caller). Its permission tests stay.
- Pack-based tests rewritten on subscriptions (refund, security, Bazaar token); pack-only test files deleted.
- docs: profit table for 4/day on both payment routes plus free users; handbook, operations, CLAUDE.md current.
949 tests green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 20:33:38 +03:30

54 lines
2.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
سقفِ روزانه‌ی دستیار: رایگان در برابرِ اشتراکی (۲۰۲۶-۱۰-۰۱). تا آن روز همه ۱۵ سوال
داشتند، یعنی گران‌ترین بخشِ اپ برای کاربرِ بی‌اشتراک هم کامل باز بود.
"""
from datetime import timedelta
from django.core.cache import cache
from django.test import TestCase, override_settings
from django.utils import timezone
from rest_framework.test import APIClient
from accounts.authentication import issue_access_token
from accounts.models import User
from subscription.models import Plan, Subscription
from subscription.services import ai_daily_quota
@override_settings(AI_DAILY_QUOTA_FREE=2)
class DailyQuotaTests(TestCase):
def setUp(self):
cache.clear()
self.user = User.objects.create(phone='09120006001')
self.client = APIClient()
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {issue_access_token(self.user.id)}')
def ask(self):
return self.client.post('/api/ai/ask', {'userQuestion': '۲ + ۲ چند میشه؟'}, format='json')
def test_free_user_gets_the_free_quota_and_a_hint_to_subscribe(self):
self.assertEqual([self.ask().status_code for _ in range(2)], [200, 200])
blocked = self.ask()
self.assertEqual(blocked.status_code, 429)
self.assertIn('اشتراک', blocked.json()['detail']) # بسته از subscription.0016 فروخته نمی‌شود
def test_remaining_quota_follows_the_users_own_limit(self):
self.assertEqual(self.ask().json()['remainingQuota'], 1)
def test_subscriber_gets_the_plans_quota(self):
plan = Plan.objects.create(title='ماهانه', price=99000, duration_days=30, ai_daily_quota=4)
Subscription.objects.create(user_id=self.user.id, plan=plan, status='active',
expires_at=timezone.now() + timedelta(days=30))
self.assertEqual(ai_daily_quota(self.user.id), 4)
self.assertEqual([self.ask().status_code for _ in range(5)], [200, 200, 200, 200, 429])
def test_expired_subscription_falls_back_to_free(self):
plan = Plan.objects.create(title='ماهانه', price=99000, duration_days=30, ai_daily_quota=40)
Subscription.objects.create(user_id=self.user.id, plan=plan, status='active',
expires_at=timezone.now() - timedelta(days=1))
self.assertEqual(ai_daily_quota(self.user.id), 2)
def test_gifted_subscription_without_plan_gets_the_default(self):
Subscription.objects.create(user_id=self.user.id, plan=None, status='active', expires_at=None)
self.assertEqual(ai_daily_quota(self.user.id), 4) # DEFAULT_SUBSCRIBER_AI_QUOTA، مثلِ پلن‌های فروشی