let the subscription card come from the server
کارتِ اشتراک زیرِ هر پلن فهرستِ امکانات و یک برچسب («محبوبترین»، «بهترین ارزش») نشان میدهد، و هر دو در کدِ فرانت هاردکد بودند — یعنی عوض کردنِ یک بندِ متنی به دیپلویِ تازهی اپ نیاز داشت. Plan حالا features و badge دارد. `popular` سرِ جایش ماند: بولین است و متنِ برچسب را نمیدهد، پس این جایگزینش نیست، کنارش است. هیچکدام اجباری نیستند و پلنهای موجود بدونشان همچنان سرو میشوند. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
23
subscription/migrations/0004_plan_badge_plan_features.py
Normal file
23
subscription/migrations/0004_plan_badge_plan_features.py
Normal file
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.2.17 on 2026-09-13 22:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('subscription', '0003_subscription_version'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='plan',
|
||||
name='badge',
|
||||
field=models.CharField(blank=True, max_length=30),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='plan',
|
||||
name='features',
|
||||
field=models.JSONField(blank=True, default=list),
|
||||
),
|
||||
]
|
||||
@@ -19,6 +19,14 @@ class Plan(models.Model):
|
||||
# از رویِ متنِ title (مثلاً کلمهی «سالانه») حدس بزنه.
|
||||
duration_days = models.PositiveIntegerField(default=30)
|
||||
|
||||
# کارتِ اشتراک زیرِ هر پلن فهرستِ امکانات نشان میدهد («درسهای نامحدود»،
|
||||
# «دستیار هوشمند»…). تا امروز این فهرست در کدِ فرانت هاردکد بود، یعنی
|
||||
# عوض کردنِ یک بند به دیپلویِ تازهی اپ نیاز داشت.
|
||||
features = models.JSONField(default=list, blank=True)
|
||||
# برچسبِ بالای کارت: «محبوبترین»، «بهترین ارزش». `popular` فقط بولین است
|
||||
# و یک متن نمیدهد؛ این جایگزینش نیست، کنارش است.
|
||||
badge = models.CharField(max_length=30, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ class PlanSerializer(serializers.Serializer):
|
||||
popular = serializers.BooleanField()
|
||||
discountPercent = serializers.IntegerField(required=False)
|
||||
durationDays = serializers.IntegerField(required=False)
|
||||
features = serializers.ListField(child=serializers.CharField())
|
||||
badge = serializers.CharField(allow_blank=True)
|
||||
|
||||
|
||||
class PlansListResponseSerializer(serializers.Serializer):
|
||||
|
||||
@@ -516,3 +516,28 @@ class PurchaseGuestThrottleBypassTests(TestCase):
|
||||
|
||||
self.assertFalse(Subscription.objects.filter(user_id=guest2.id).exists())
|
||||
self.assertEqual(Order.objects.filter(user_id=guest2.id).count(), 0)
|
||||
|
||||
|
||||
class PlanCardContractTests(TestCase):
|
||||
"""
|
||||
کارتِ اشتراک در فرانت فهرستِ امکانات و یک برچسب نشان میدهد؛ تا امروز هر
|
||||
دو در کدِ اپ هاردکد بودند، یعنی عوض کردنِ یک بند به دیپلویِ تازه نیاز داشت.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
from django.core.cache import cache
|
||||
cache.clear()
|
||||
|
||||
def test_plans_carry_their_feature_list_and_badge(self):
|
||||
Plan.objects.create(title='طلایی', price=49000, popular=True,
|
||||
badge='محبوبترین',
|
||||
features=['درسهای نامحدود', 'بدون تبلیغ'])
|
||||
row = self.client.get('/api/subscription/plans').json()['plans'][0]
|
||||
self.assertEqual(row['badge'], 'محبوبترین')
|
||||
self.assertEqual(row['features'], ['درسهای نامحدود', 'بدون تبلیغ'])
|
||||
|
||||
def test_a_plan_without_them_still_serializes(self):
|
||||
Plan.objects.create(title='رایگان', price=0)
|
||||
row = self.client.get('/api/subscription/plans').json()['plans'][0]
|
||||
self.assertEqual(row['features'], [])
|
||||
self.assertEqual(row['badge'], '')
|
||||
|
||||
@@ -61,6 +61,8 @@ class PlansListView(APIView):
|
||||
'popular': p.popular,
|
||||
'discountPercent': p.discount_percent,
|
||||
'durationDays': p.duration_days,
|
||||
'features': p.features or [],
|
||||
'badge': p.badge,
|
||||
}
|
||||
for p in Plan.objects.all()
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user