Files
MathApp/payment/tests_bazaar_pack.py
Zareian fe658c697a bazaar: a pack bought through Bazaar now gives its credits; verify reports the real order status
Bazaar orders are only created through POST /api/payment/orders, which
took no planId, so a pack order had plan_id=None: Bazaar verified the
purchase, the order became paid, and grant_pack never ran. The endpoint
now takes planId (rejected when unknown) and snapshots the plan title.
The verify response also returned the pre-payment status ('pending')
because apply_order_payment_result updates its own copy of the order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 13:04:41 +03:30

69 lines
3.4 KiB
Python
Raw 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.
"""
خریدِ بسته‌ی سوال از راهِ کافه‌بازار (بازبینیِ ۲۰۲۶-۱۰-۰۲).
سفارشِ بازار فقط از `POST /api/payment/orders` (کلیدِ داخلی) ساخته می‌شود. آن endpoint
`planId` نمی‌گرفت، پس سفارشِ بسته بی‌`plan_id` ساخته می‌شد و بعد از تأییدِ بازار «paid» می‌شد
بی‌آن‌که `grant_pack` چیزی بدهد: پول گرفته می‌شد و اعتباری نمی‌آمد. پاسخِ تأیید هم وضعیتِ
پیش از پرداخت («pending») را برمی‌گرداند. بازار با `bazaar.verify_purchase`ِ ساختگی آزموده
می‌شود؛ خریدِ واقعیِ بازار هنوز هیچ‌جا آزموده نشده.
"""
from unittest.mock import patch
from django.core.cache import cache
from django.test import TestCase, override_settings
from rest_framework.test import APIClient
from accounts.authentication import issue_access_token
from accounts.models import User
from subscription.models import Plan
from subscription.services import credit_balance
from .bazaar import BazaarPurchaseResult
from .models import Order
@override_settings(INTERNAL_SERVICE_KEY='internal-test-key')
class BazaarPackTests(TestCase):
def setUp(self):
cache.clear()
self.user = User.objects.create(phone='09120007101', is_guest=False)
self.client = APIClient()
self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {issue_access_token(self.user.id)}')
self.pack = Plan.objects.get(kind='pack', question_credits=20)
def tearDown(self):
cache.clear()
def create_bazaar_order(self, **extra):
response = APIClient().post('/api/payment/orders', {
'userId': str(self.user.id), 'amount': self.pack.price, 'provider': 'bazaar',
'bazaarProductSku': 'pack20', **extra,
}, format='json', HTTP_X_INTERNAL_KEY='internal-test-key')
self.assertEqual(response.status_code, 200, response.content)
return response.json()['orderId']
def verify(self, order_id, valid=True):
with patch('payment.bazaar.verify_purchase',
return_value=BazaarPurchaseResult(is_valid=valid, purchase_state=0 if valid else None)):
return self.client.post('/api/payment/bazaar/verify', {
'orderId': order_id, 'productSku': 'pack20', 'purchaseToken': 'token-1'}, format='json')
def test_a_pack_bought_through_bazaar_gives_its_credits(self):
order_id = self.create_bazaar_order(planId=str(self.pack.id))
order = Order.objects.get(pk=order_id)
self.assertEqual((order.plan_id, order.plan_title, order.list_price), (self.pack.id, self.pack.title, self.pack.price))
self.verify(order_id)
self.assertEqual(credit_balance(self.user.id), 20)
def test_verify_reports_the_status_the_order_actually_has(self):
order_id = self.create_bazaar_order(planId=str(self.pack.id))
response = self.verify(order_id)
self.assertEqual(Order.objects.get(pk=order_id).status, 'paid')
self.assertEqual(response.json()['status'], 'paid')
def test_unknown_plan_is_rejected(self):
response = APIClient().post('/api/payment/orders', {
'userId': str(self.user.id), 'amount': 1, 'provider': 'bazaar', 'planId': '999999',
}, format='json', HTTP_X_INTERNAL_KEY='internal-test-key')
self.assertEqual(response.status_code, 400)