diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 7013fe6a..96795711 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -7,7 +7,11 @@ from establishment.serializers import ( EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer, ContactPhonesSerializer, SocialNetworkRelatedSerializers, EstablishmentDetailSerializer ) + +from utils.decorators import with_base_attributes + from main.models import Currency +from utils.serializers import TJSONSerializer class EstablishmentListCreateSerializer(EstablishmentBaseSerializer): @@ -86,7 +90,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 @@ -123,7 +127,10 @@ class ContactEmailBackSerializers(PlateSerializer): ] +# TODO: test decorator +@with_base_attributes class EmployeeBackSerializers(serializers.ModelSerializer): + """Social network serializers.""" class Meta: model = models.Employee @@ -131,4 +138,5 @@ class EmployeeBackSerializers(serializers.ModelSerializer): 'id', 'user', 'name' - ] \ No newline at end of file + ] + diff --git a/apps/establishment/serializers/common.py b/apps/establishment/serializers/common.py index 1f001886..c637acd8 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 @@ -300,20 +300,22 @@ class EstablishmentFavoritesCreateSerializer(serializers.ModelSerializer): def validate(self, attrs): """Override validate method""" # Check establishment object - establishment_id = self.context.get('request').parser_context.get('kwargs').get('pk') - establishment_qs = models.Establishment.objects.filter(id=establishment_id) + establishment_slug = self.context.get('request').parser_context.get('kwargs').get('slug') + establishment_qs = models.Establishment.objects.filter(slug=establishment_slug) - # Check establishment obj by pk from lookup_kwarg + # Check establishment obj by slug from lookup_kwarg if not establishment_qs.exists(): raise serializers.ValidationError({'detail': _('Object not found.')}) + else: + establishment = establishment_qs.first() # Check existence in favorites if self.get_user().favorites.by_content_type(app_label='establishment', model='establishment')\ - .by_object_id(object_id=establishment_id).exists(): + .by_object_id(object_id=establishment.id).exists(): raise utils_exceptions.FavoritesError() - attrs['establishment'] = establishment_qs.first() + attrs['establishment'] = establishment return attrs def create(self, validated_data, *args, **kwargs): diff --git a/apps/establishment/tests.py b/apps/establishment/tests.py index e4e3b02c..16d224b8 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. @@ -27,7 +26,7 @@ class BaseTestCase(APITestCase): self.establishment_type = EstablishmentType.objects.create(name="Test establishment type") -class EstablishmentTests(BaseTestCase): +class EstablishmentBTests(BaseTestCase): def test_establishment_CRUD(self): params = {'page': 1, 'page_size': 1,} response = self.client.get('/api/back/establishments/', params, format='json') @@ -93,7 +92,8 @@ class ChildTestCase(BaseTestCase): self.establishment = Establishment.objects.create( name="Test establishment", establishment_type_id=self.establishment_type.id, - is_publish=True + is_publish=True, + slug="test" ) @@ -263,3 +263,89 @@ class EstablishmentShedulerTests(ChildTestCase): response = self.client.delete(f'/api/back/establishments/{self.establishment.id}/schedule/1/') self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + +# Web tests +class EstablishmentWebTests(BaseTestCase): + + def test_establishment_Read(self): + params = {'page': 1, 'page_size': 1,} + response = self.client.get('/api/web/establishments/', params, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class EstablishmentWebTagTests(BaseTestCase): + + def test_tag_Read(self): + response = self.client.get('/api/web/establishments/tags/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class EstablishmentWebSlugTests(ChildTestCase): + + def test_slug_Read(self): + response = self.client.get(f'/api/web/establishments/slug/{self.establishment.slug}/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class EstablishmentWebSimilarTests(ChildTestCase): + + def test_similar_Read(self): + response = self.client.get(f'/api/web/establishments/slug/{self.establishment.slug}/similar/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class EstablishmentWebCommentsTests(ChildTestCase): + + def test_comments_CRUD(self): + + response = self.client.get(f'/api/web/establishments/slug/{self.establishment.slug}/comments/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + data = { + 'text': 'test', + 'user': self.user.id, + 'mark': 4 + } + + response = self.client.post(f'/api/web/establishments/slug/{self.establishment.slug}/comments/create/', + data=data) + + comment = response.json() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.get(f'/api/web/establishments/slug/{self.establishment.slug}/comments/{comment["id"]}/', + format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + update_data = { + 'text': 'Test new establishment' + } + + response = self.client.patch(f'/api/web/establishments/slug/{self.establishment.slug}/comments/{comment["id"]}/', + data=update_data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.delete( + f'/api/web/establishments/slug/{self.establishment.slug}/comments/{comment["id"]}/', + format='json') + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + +class EstablishmentWebFavoriteTests(ChildTestCase): + + def test_favorite_CR(self): + data = { + "user": self.user.id, + "object_id": self.establishment.id + } + + response = self.client.post(f'/api/web/establishments/slug/{self.establishment.slug}/favorites/', + data=data) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.delete( + f'/api/web/establishments/slug/{self.establishment.slug}/favorites/', + format='json') + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/apps/establishment/urls/common.py b/apps/establishment/urls/common.py index c1161e92..1e9225d6 100644 --- a/apps/establishment/urls/common.py +++ b/apps/establishment/urls/common.py @@ -10,13 +10,13 @@ urlpatterns = [ path('tags/', views.EstablishmentTagListView.as_view(), name='tags'), path('recent-reviews/', views.EstablishmentRecentReviewListView.as_view(), name='recent-reviews'), - path('/', views.EstablishmentRetrieveView.as_view(), name='detail'), - path('/similar/', views.EstablishmentSimilarListView.as_view(), name='similar'), - path('/comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'), - path('/comments/create/', views.EstablishmentCommentCreateView.as_view(), + path('slug//', views.EstablishmentRetrieveView.as_view(), name='detail'), + path('slug//similar/', views.EstablishmentSimilarListView.as_view(), name='similar'), + path('slug//comments/', views.EstablishmentCommentListView.as_view(), name='list-comments'), + path('slug//comments/create/', views.EstablishmentCommentCreateView.as_view(), name='create-comment'), - path('/comments//', views.EstablishmentCommentRUDView.as_view(), + path('slug//comments//', views.EstablishmentCommentRUDView.as_view(), name='rud-comment'), - path('/favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(), + path('slug//favorites/', views.EstablishmentFavoritesCreateDestroyView.as_view(), name='add-to-favorites') ] diff --git a/apps/location/tests.py b/apps/location/tests.py index 7ce503c2..f68ba56b 100644 --- a/apps/location/tests.py +++ b/apps/location/tests.py @@ -1,3 +1,193 @@ -from django.test import TestCase +import json -# Create your tests here. +from rest_framework.test import APITestCase +from account.models import User +from rest_framework import status +from http.cookies import SimpleCookie + +from location.models import City, Region, Country + + +class BaseTestCase(APITestCase): + + def setUp(self): + self.username = 'sedragurda' + self.password = 'sedragurdaredips19' + self.email = 'sedragurda@desoz.com' + self.newsletter = True + self.user = User.objects.create_user( + username=self.username, email=self.email, password=self.password) + + # get tokens + + tokkens = User.create_jwt_tokens(self.user) + self.client.cookies = SimpleCookie( + {'access_token': tokkens.get('access_token'), + 'refresh_token': tokkens.get('refresh_token')}) + + +class CountryTests(BaseTestCase): + + def test_country_CRUD(self): + response = self.client.get('/api/back/location/countries/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + data = { + 'name': 'Test country', + 'code': 'test' + } + + response = self.client.post('/api/back/location/countries/', data=data, format='json') + response_data = response.json() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.get(f'/api/back/location/countries/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + update_data = { + 'name': json.dumps({"en-GB": "Test new country"}) + } + + response = self.client.patch(f'/api/back/location/countries/{response_data["id"]}/', data=update_data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.delete(f'/api/back/location/countries/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + +class RegionTests(BaseTestCase): + + def setUp(self): + super().setUp() + self.country = Country.objects.create( + name=json.dumps({"en-GB": "Test country"}), + code="test" + ) + + def test_region_CRUD(self): + response = self.client.get('/api/back/location/regions/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + data = { + 'name': 'Test country', + 'code': 'test', + 'country_id': self.country.id + } + + response = self.client.post('/api/back/location/regions/', data=data, format='json') + response_data = response.json() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.get(f'/api/back/location/regions/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + update_data = { + 'name': json.dumps({"en-GB": "Test new country"}) + } + + response = self.client.patch(f'/api/back/location/regions/{response_data["id"]}/', data=update_data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.delete(f'/api/back/location/regions/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + +class CityTests(BaseTestCase): + + def setUp(self): + super().setUp() + + self.country = Country.objects.create( + name=json.dumps({"en-GB": "Test country"}), + code="test" + ) + + self.region = Region.objects.create( + name="Test region", + code="812", + country=self.country + ) + + def test_city_CRUD(self): + response = self.client.get('/api/back/location/cities/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + data = { + 'name': 'Test country', + 'code': 'test', + 'country_id': self.country.id, + 'region_id': self.region.id + } + + response = self.client.post('/api/back/location/cities/', data=data, format='json') + response_data = response.json() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.get(f'/api/back/location/cities/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + update_data = { + 'name': json.dumps({"en-GB": "Test new country"}) + } + + response = self.client.patch(f'/api/back/location/cities/{response_data["id"]}/', data=update_data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.delete(f'/api/back/location/cities/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + +class AddressTests(BaseTestCase): + + def setUp(self): + super().setUp() + + self.country = Country.objects.create( + name=json.dumps({"en-GB": "Test country"}), + code="test" + ) + + self.region = Region.objects.create( + name="Test region", + code="812", + country=self.country + ) + + self.city = City.objects.create( + name="Test region", + code="812", + region=self.region, + country=self.country + ) + + def test_address_CRUD(self): + response = self.client.get('/api/back/location/addresses/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + data = { + 'city_id': self.city.id, + 'number': '+79999999', + "coordinates": { + "latitude": 37.0625, + "longitude": -95.677068 + }, + "geo_lon": -95.677068, + "geo_lat": 37.0625 + } + + response = self.client.post('/api/back/location/addresses/', data=data, format='json') + response_data = response.json() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self.client.get(f'/api/back/location/addresses/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + + update_data = { + 'number': '+79999991' + } + + response = self.client.patch(f'/api/back/location/addresses/{response_data["id"]}/', data=update_data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.delete(f'/api/back/location/addresses/{response_data["id"]}/', format='json') + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) diff --git a/apps/main/serializers.py b/apps/main/serializers.py index 10d75f2b..c981f0ee 100644 --- a/apps/main/serializers.py +++ b/apps/main/serializers.py @@ -136,8 +136,8 @@ class CarouselListSerializer(serializers.ModelSerializer): """Serializer for retrieving list of carousel items.""" model_name = serializers.CharField() name = serializers.CharField() - toque_number = serializers.CharField() - public_mark = serializers.CharField() + toque_number = serializers.IntegerField() + public_mark = serializers.IntegerField() image = serializers.URLField(source='image_url') awards = AwardBaseSerializer(many=True) vintage_year = serializers.IntegerField() diff --git a/apps/news/tests.py b/apps/news/tests.py index 9ac8742c..7d6724d7 100644 --- a/apps/news/tests.py +++ b/apps/news/tests.py @@ -35,11 +35,18 @@ class NewsTestCase(BaseTestCase): response = self.client.get("/api/web/news/") self.assertEqual(response.status_code, status.HTTP_200_OK) - def test_news_detail(self): - response = self.client.get(f"/api/web/news/{self.test_news.slug}/") + def test_news_web_detail(self): + response = self.client.get(f"/api/web/news/slug/{self.test_news.slug}/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_news_back_detail(self): + response = self.client.get(f"/api/back/news/{self.test_news.id}/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_news_list_back(self): + response = self.client.get("/api/back/news/") self.assertEqual(response.status_code, status.HTTP_200_OK) def test_news_type_list(self): response = self.client.get("/api/web/news/types/") self.assertEqual(response.status_code, status.HTTP_200_OK) - diff --git a/apps/news/urls/web.py b/apps/news/urls/web.py index 10513910..80fcf072 100644 --- a/apps/news/urls/web.py +++ b/apps/news/urls/web.py @@ -7,5 +7,5 @@ app_name = 'news' urlpatterns = [ path('', views.NewsListView.as_view(), name='list'), path('types/', views.NewsTypeListView.as_view(), name='type'), - path('/', views.NewsDetailView.as_view(), name='rud'), + path('slug//', views.NewsDetailView.as_view(), name='rud'), ] diff --git a/apps/notification/tests.py b/apps/notification/tests.py new file mode 100644 index 00000000..d78c7fca --- /dev/null +++ b/apps/notification/tests.py @@ -0,0 +1,116 @@ +from http.cookies import SimpleCookie + +from django.test import TestCase +from rest_framework.test import APITestCase +from rest_framework import status + +from account.models import User +from notification.models import Subscriber + + +class BaseTestCase(APITestCase): + + def setUp(self): + self.username = 'sedragurda' + self.password = 'sedragurdaredips19' + self.email = 'sedragurda@desoz.com' + self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password) + # get tokkens + tokkens = User.create_jwt_tokens(self.user) + self.client.cookies = SimpleCookie({'access_token': tokkens.get('access_token'), + 'refresh_token': tokkens.get('refresh_token')}) + + +class NotificationAnonSubscribeTestCase(APITestCase): + + def test_subscribe(self): + + test_data = { + "email": "test@email.com", + "state": 1 + } + + response = self.client.post("/api/web/notifications/subscribe/", data=test_data, format="json") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["email"], test_data["email"]) + self.assertEqual(response.json()["state"], test_data["state"]) + + +class NotificationSubscribeTestCase(BaseTestCase): + + def setUp(self): + super().setUp() + + self.test_data = { + "email": self.email, + "state": 1 + } + + def test_subscribe(self): + + response = self.client.post("/api/web/notifications/subscribe/", data=self.test_data, format="json") + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["email"], self.email) + self.assertEqual(response.json()["state"], self.test_data["state"]) + + def test_subscribe_info_auth_user(self): + + Subscriber.objects.create(user=self.user, email=self.email, state=1) + + response = self.client.get("/api/web/notifications/subscribe-info/", data=self.test_data, format="json") + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class NotificationSubscribeInfoTestCase(APITestCase): + + def test_subscribe_info(self): + + self.username = 'sedragurda' + self.password = 'sedragurdaredips19' + self.email = 'sedragurda@desoz.com' + self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password) + + test_subscriber = Subscriber.objects.create(user=self.user, email=self.email, state=1) + + response = self.client.get(f"/api/web/notifications/subscribe-info/{test_subscriber.update_code}/") + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class NotificationUnsubscribeAuthUserTestCase(BaseTestCase): + + def test_unsubscribe_auth_user(self): + + Subscriber.objects.create(user=self.user, email=self.email, state=1) + + self.test_data = { + "email": self.email, + "state": 1 + } + + response = self.client.patch("/api/web/notifications/unsubscribe/", data=self.test_data, format="json") + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + +class NotificationUnsubscribeTestCase(APITestCase): + + def test_unsubscribe(self): + self.username = 'sedragurda' + self.password = 'sedragurdaredips19' + self.email = 'sedragurda@desoz.com' + self.user = User.objects.create_user(username=self.username, email=self.email, password=self.password) + + self.test_data = { + "email": self.email, + "state": 1 + } + + test_subscriber = Subscriber.objects.create(user=self.user, email=self.email, state=1) + + response = self.client.patch(f"/api/web/notifications/unsubscribe/{test_subscriber.update_code}/", + data=self.test_data, format="json") + + self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/apps/search_indexes/documents/establishment.py b/apps/search_indexes/documents/establishment.py index 10f95d6c..16321723 100644 --- a/apps/search_indexes/documents/establishment.py +++ b/apps/search_indexes/documents/establishment.py @@ -84,6 +84,8 @@ class EstablishmentDocument(Document): 'name', 'toque_number', 'price_level', + 'preview_image_url', + 'slug', ) def get_queryset(self): diff --git a/apps/search_indexes/serializers.py b/apps/search_indexes/serializers.py index e6950bdd..480f509d 100644 --- a/apps/search_indexes/serializers.py +++ b/apps/search_indexes/serializers.py @@ -63,6 +63,8 @@ class EstablishmentDocumentSerializer(DocumentSerializer): 'collections', 'establishment_type', 'establishment_subtypes', + 'preview_image_url', + 'slug', ) @staticmethod diff --git a/apps/utils/decorators.py b/apps/utils/decorators.py new file mode 100644 index 00000000..c48a26c7 --- /dev/null +++ b/apps/utils/decorators.py @@ -0,0 +1,21 @@ + +def with_base_attributes(cls): + + def validate(self, data): + user = None + request = self.context.get("request") + + if request and hasattr(request, "user"): + user = request.user + + if user is not None: + data.update({'modified_by': user}) + + if not self.instance: + data.update({'created_by': user}) + + return data + + setattr(cls, "validate", validate) + + return cls 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..0ca77b6b 100644 --- a/apps/utils/tests.py +++ b/apps/utils/tests.py @@ -8,6 +8,13 @@ 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 + class BaseTestCase(APITestCase): @@ -28,6 +35,12 @@ class BaseTestCase(APITestCase): 'locale': "en" }) + +class TranslateFieldTests(BaseTestCase): + + def setUp(self): + super().setUp() + self.news_type = NewsType.objects.create(name="Test news type") self.news_item = News.objects.create( @@ -45,15 +58,9 @@ class BaseTestCase(APITestCase): news_type=self.news_type ) - -class TranslateFieldModel(BaseTestCase): - def test_model_field(self): self.assertIsNotNone(getattr(self.news_item, "title_translated", None)) - -class TranslateFieldReview(BaseTestCase): - def test_read_locale(self): response = self.client.get(f"/api/web/news/{self.news_item.id}/", format='json') self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -62,3 +69,90 @@ class TranslateFieldReview(BaseTestCase): self.assertIn("title_translated", news_data) self.assertEqual(news_data['title_translated'], "Test news item") + + +class BaseAttributeTests(BaseTestCase): + + def setUp(self): + super().setUp() + + self.establishment_type = EstablishmentType.objects.create(name="Test establishment type") + self.establishment = Establishment.objects.create( + name="Test establishment", + establishment_type_id=self.establishment_type.id, + is_publish=True + ) + + def test_base_attr_api(self): + data = { + 'user': self.user.id, + 'name': 'Test name' + } + + response = self.client.post('/api/back/establishments/employees/', data=data) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response_data = response.json() + self.assertIn("id", response_data) + + employee = Employee.objects.get(id=response_data['id']) + + self.assertEqual(self.user, employee.created_by) + self.assertEqual(self.user, employee.modified_by) + + modify_user = User.objects.create_user( + username='sedragurda2', + password='sedragurdaredips192', + email='sedragurda2@desoz.com', + ) + + modify_tokkens = User.create_jwt_tokens(modify_user) + self.client.cookies = SimpleCookie( + {'access_token': modify_tokkens.get('access_token'), + 'refresh_token': modify_tokkens.get('refresh_token'), + 'locale': "en" + }) + + update_data = { + 'name': 'Test new name' + } + + response = self.client.patch('/api/back/establishments/employees/1/', data=update_data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + employee.refresh_from_db() + self.assertEqual(modify_user, employee.modified_by) + self.assertEqual(self.user, employee.created_by) + + +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") \ No newline at end of file