@@ -89,7 +89,6 @@ PATH_PREFETCH_MAP = { 'business_account__parent_company__user__payment_plan__plan', queryset=NeuronModel.objects.only('slug'), ), - 'payment_plan__plan__features', ), }, } @@ -1,6 +1,7 @@ from abc import abstractmethod from typing import Any +from cacheops import invalidate_all from django.test import TestCase from ninja.testing import TestClient from rest_framework_simplejwt.tokens import RefreshToken @@ -19,6 +20,10 @@ class BaseAPITest(TestCase): @abstractmethod def test_unauthorized_status_code(self) -> None: ... + def setUp(self): + invalidate_all() + super().setUp() + class BaseAuthorizedAPITest(BaseAPITest): TEST_USER_EMAIL = 'test@test.test' @@ -5,14 +5,14 @@ from datetime import date, timedelta from decimal import Decimal from dateutil.relativedelta import relativedelta -from django.db.models import CharField, F, Func, Sum, Value +from django.db.models import CharField, F, Func, Sum, Value, Prefetch from django.db.models.functions import Round, TruncDay, TruncMonth, TruncYear from django.utils.translation import gettext as _ from ninja import Query, Router from ninja.errors import HttpError from authentication.security import AsyncAuthBearer, SyncAuthBearer -from payments.models import Invoice, Payment, PaymentPlan +from payments.models import Invoice, Payment, PaymentPlan, PaymentPlanFeature from payments.schema import UserBalance from payments.schemas import ( ExpensesParamsSchema, @@ -115,16 +115,25 @@ async def list_payment_plans(request): if request.auth.account_type not in {'regular', 'business_host'}: raise HttpError(401, 'Unauthorized') is_corporate = request.auth.account_type == 'business_host' - plans = PaymentPlan.objects.filter( price__gt=0, is_corporate=is_corporate, is_visible=True - ).prefetch_related('features__model', 'features__model__category') - + ).prefetch_related( + Prefetch( + 'features', + queryset=PaymentPlanFeature.objects.filter( + model__model_settings__is_active=True + ).select_related( + 'model__category', + 'model__model_settings', + ), + to_attr='active_features', + ) + ) result = [] GROUPED_FEATURES_ORDER = ['Чат-боты', 'Изображения', 'Видео', 'Аудио'] async for plan in plans: raw_grouped = defaultdict(list) - for feature in [f async for f in plan.features.filter(model__model_settings__is_active=True)]: + for feature in plan.active_features: raw_grouped[feature.model.category.title].append( { 'name': feature.model.title, @@ -132,7 +141,9 @@ async def list_payment_plans(request): 'measurement_unit': feature.measurement_unit, } ) - grouped = dict(sorted(raw_grouped.items(), key=lambda items: GROUPED_FEATURES_ORDER.index(items[0]))) + grouped = dict( + sorted(raw_grouped.items(), key=lambda items: GROUPED_FEATURES_ORDER.index(items[0])) + ) result.append( PaymentPlanSchema( uid=plan.uid, @@ -5,7 +5,7 @@ from django.utils.translation import gettext as _ from authentication.models import BusinessUserHost, BusinessAccount from core.tests import BaseAuthorizedAPITest -from ml_model.models import ModelCategory, NeuronModel +from ml_model.models import ModelCategory, NeuronModel, ModelSettings from payments.models import PaymentPlan, PaymentPlanFeature @@ -35,9 +35,20 @@ class PlansAPITest(BaseAuthorizedAPITest): title=_('Audio'), ) - cls.model1 = NeuronModel.objects.create(title='Model 1', slug='model-1', category=cls.category_chat_bots) - cls.model2 = NeuronModel.objects.create(title='Model 2', slug='model-2', category=cls.category_chat_bots) - cls.model3 = NeuronModel.objects.create(title='Model 3', slug='model-3', category=cls.category_images) + cls.model1 = NeuronModel.objects.create( + title='Model 1', slug='model-1', category=cls.category_chat_bots + ) + cls.model2 = NeuronModel.objects.create( + title='Model 2', slug='model-2', category=cls.category_chat_bots + ) + cls.model3 = NeuronModel.objects.create( + title='Model 3', slug='model-3', category=cls.category_images + ) + for model, is_active in {cls.model1: True, cls.model2: False, cls.model3: True}.items(): + ModelSettings.objects.update_or_create( + model=model, + defaults={'is_active': is_active}, + ) cls.regular_plan1 = PaymentPlan.objects.create( title='Regular Plan 1', @@ -127,6 +138,7 @@ class PlansAPITest(BaseAuthorizedAPITest): 'points', 'grouped_features', 'accessed_models', + 'individual' ], ) @@ -183,7 +195,7 @@ class PlansAPITest(BaseAuthorizedAPITest): self.assertIn(_('Images'), category_names) category1_group = [g for g in grouped_features if g['name'] == _('Chat-bots')][0] - self.assertEqual(len(category1_group['features']), 2) + self.assertEqual(len(category1_group['features']), 1) category2_group = [g for g in grouped_features if g['name'] == _('Images')][0] self.assertEqual(len(category2_group['features']), 1) @@ -198,7 +210,7 @@ class PlansAPITest(BaseAuthorizedAPITest): all_features.extend(group['features']) feature_names = {f['name'] for f in all_features} - self.assertSetEqual({'Model 1', 'Model 2', 'Model 3'}, feature_names) + self.assertSetEqual({'Model 1', 'Model 3'}, feature_names) feature1 = [f for f in all_features if f['name'] == 'Model 1'][0] self.assertEqual(feature1['quantity'], 10)