From 86d754f4bb9ea85a75e17637f5be64775290b427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Thu, 26 Sep 2019 11:38:37 +0300 Subject: [PATCH 1/2] validate json translated field --- apps/establishment/serializers/back.py | 3 +- apps/establishment/serializers/common.py | 8 ++--- apps/establishment/tests.py | 1 - apps/utils/models.py | 16 +++++++--- apps/utils/serializers.py | 25 ++++++++++++++++ apps/utils/tests.py | 38 ++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 10 deletions(-) diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 7013fe6a..95491bec 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -8,6 +8,7 @@ from establishment.serializers import ( ContactPhonesSerializer, SocialNetworkRelatedSerializers, EstablishmentDetailSerializer ) from main.models import Currency +from utils.serializers import TJSONSerializer class EstablishmentListCreateSerializer(EstablishmentBaseSerializer): @@ -86,7 +87,7 @@ class SocialNetworkSerializers(serializers.ModelSerializer): class PlatesSerializers(PlateSerializer): """Social network serializers.""" - name = serializers.JSONField() + name = TJSONSerializer currency_id = serializers.PrimaryKeyRelatedField( source='currency', queryset=Currency.objects.all(), write_only=True diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 7b974887..d736ee99 100644 --- a/apps/establishment/serializers/common.py +++ b/apps/establishment/serializers/common.py @@ -12,7 +12,7 @@ from review import models as review_models from timetable.serialziers import ScheduleRUDSerializer from utils import exceptions as utils_exceptions from django.utils.translation import gettext_lazy as _ - +from utils.serializers import TJSONSerializer class ContactPhonesSerializer(serializers.ModelSerializer): """Contact phone serializer""" @@ -60,7 +60,7 @@ class PlateSerializer(serializers.ModelSerializer): class MenuSerializers(serializers.ModelSerializer): plates = PlateSerializer(read_only=True, many=True, source='plate_set') - category = serializers.JSONField() + category = TJSONSerializer() category_translated = serializers.CharField(read_only=True) class Meta: @@ -74,9 +74,9 @@ class MenuSerializers(serializers.ModelSerializer): ] -class MenuRUDSerializers(serializers.ModelSerializer): +class MenuRUDSerializers(serializers.ModelSerializer, ): plates = PlateSerializer(read_only=True, many=True, source='plate_set') - category = serializers.JSONField() + category = TJSONSerializer() class Meta: model = models.Menu diff --git a/apps/establishment/tests.py b/apps/establishment/tests.py index e4e3b02c..1f3151fd 100644 --- a/apps/establishment/tests.py +++ b/apps/establishment/tests.py @@ -5,7 +5,6 @@ from rest_framework import status from http.cookies import SimpleCookie from main.models import Currency from establishment.models import Establishment, EstablishmentType, Menu - # Create your tests here. diff --git a/apps/utils/models.py b/apps/utils/models.py index 632cf4a2..4e6df35e 100644 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -10,6 +10,8 @@ from django.utils.translation import ugettext_lazy as _, get_language from easy_thumbnails.fields import ThumbnailerImageField from utils.methods import image_path, svg_image_path from utils.validators import svg_image_validator +from django.db.models.fields import Field +from django.core import exceptions class ProjectBaseMixin(models.Model): @@ -26,6 +28,10 @@ class ProjectBaseMixin(models.Model): abstract = True +def valid(value): + print("Run") + + class TJSONField(JSONField): """Overrided JsonField.""" @@ -52,6 +58,7 @@ def translate_field(self, field_name): if isinstance(field, dict): return field.get(to_locale(get_language())) return None + return translate @@ -70,6 +77,7 @@ def index_field(self, field_name): for key, value in field.items(): setattr(obj, key, value) return obj + return index @@ -236,7 +244,8 @@ class LocaleManagerMixin(models.Manager): queryset = self.filter(**filters) # Prepare field for annotator - localized_fields = {f'{field}_{prefix}': KeyTextTransform(f'{locale}', field) for field in fields} + localized_fields = {f'{field}_{prefix}': KeyTextTransform(f'{locale}', field) for field in + fields} # Annotate them for _ in fields: @@ -245,7 +254,6 @@ class LocaleManagerMixin(models.Manager): class GMTokenGenerator(PasswordResetTokenGenerator): - CHANGE_EMAIL = 0 RESET_PASSWORD = 1 CHANGE_PASSWORD = 2 @@ -268,10 +276,10 @@ class GMTokenGenerator(PasswordResetTokenGenerator): """ fields = [str(timestamp), str(user.is_active), str(user.pk)] if self.purpose == self.CHANGE_EMAIL or \ - self.purpose == self.CONFIRM_EMAIL: + self.purpose == self.CONFIRM_EMAIL: fields.extend([str(user.email_confirmed), str(user.email)]) elif self.purpose == self.RESET_PASSWORD or \ - self.purpose == self.CHANGE_PASSWORD: + self.purpose == self.CHANGE_PASSWORD: fields.append(str(user.password)) return fields diff --git a/apps/utils/serializers.py b/apps/utils/serializers.py index 1f4c6f96..d30a046c 100644 --- a/apps/utils/serializers.py +++ b/apps/utils/serializers.py @@ -1,6 +1,8 @@ """Utils app serializer.""" from rest_framework import serializers from utils.models import PlatformMixin +from django.core import exceptions +from translation.models import Language class EmptySerializer(serializers.Serializer): @@ -21,3 +23,26 @@ class TranslatedField(serializers.CharField): **kwargs): super().__init__(allow_null=allow_null, required=required, read_only=read_only, **kwargs) + + +def validate_tjson(value): + + if not isinstance(value, dict): + raise exceptions.ValidationError( + 'invalid_json', + code='invalid_json', + params={'value': value}, + ) + + lang_count = Language.objects.filter(locale__in=value.keys()).count() + + if lang_count == 0: + raise exceptions.ValidationError( + 'invalid_translated_keys', + code='invalid_translated_keys', + params={'value': value}, + ) + + +class TJSONSerializer(serializers.JSONField): + validators = [validate_tjson] diff --git a/apps/utils/tests.py b/apps/utils/tests.py index 1c9fa71d..81fa02a3 100644 --- a/apps/utils/tests.py +++ b/apps/utils/tests.py @@ -8,6 +8,11 @@ from http.cookies import SimpleCookie from account.models import User from news.models import News, NewsType +from django.test import TestCase +from translation.models import Language +from django.core import exceptions + +from .serializers import validate_tjson class BaseTestCase(APITestCase): @@ -62,3 +67,36 @@ class TranslateFieldReview(BaseTestCase): self.assertIn("title_translated", news_data) self.assertEqual(news_data['title_translated'], "Test news item") + + +class ValidJSONTest(TestCase): + + def test_valid_json(self): + lang = Language.objects.create(title='English', locale='en-GB') + lang.save() + + data = 'str' + + with self.assertRaises(exceptions.ValidationError) as err: + validate_tjson(data) + + self.assertEqual(err.exception.code, 'invalid_json') + + data = { + "string": "value" + } + + with self.assertRaises(exceptions.ValidationError) as err: + validate_tjson(data) + + self.assertEqual(err.exception.code, 'invalid_translated_keys') + + data = { + "en-GB": "English" + } + + try: + validate_tjson(data) + self.assertTrue(True) + except exceptions.ValidationError: + self.assert_(False, "Test json translated FAILED") From 7c0e5057983f5b118723ac8ec810b3b9decb7c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=20=D0=93=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BA=D0=B8=D1=85?= Date: Thu, 26 Sep 2019 11:48:05 +0300 Subject: [PATCH 2/2] commit changes --- apps/utils/{!tests.py => tests.py} | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename apps/utils/{!tests.py => tests.py} (98%) diff --git a/apps/utils/!tests.py b/apps/utils/tests.py similarity index 98% rename from apps/utils/!tests.py rename to apps/utils/tests.py index 13058144..0ca77b6b 100644 --- a/apps/utils/!tests.py +++ b/apps/utils/tests.py @@ -8,11 +8,9 @@ from http.cookies import SimpleCookie from account.models import User from news.models import News, NewsType - from django.test import TestCase from translation.models import Language from django.core import exceptions - from .serializers import validate_tjson from establishment.models import Establishment, EstablishmentType, Employee @@ -126,6 +124,7 @@ class BaseAttributeTests(BaseTestCase): self.assertEqual(modify_user, employee.modified_by) self.assertEqual(self.user, employee.created_by) + class ValidJSONTest(TestCase): def test_valid_json(self):