From eebd66fa275c4ab45816ca97939fa9ade24048f6 Mon Sep 17 00:00:00 2001 From: littlewolf Date: Tue, 24 Sep 2019 13:35:05 +0300 Subject: [PATCH 1/6] Add tests to created_by and modified_by --- apps/utils/tests.py | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/apps/utils/tests.py b/apps/utils/tests.py index 1c9fa71d..786ed940 100644 --- a/apps/utils/tests.py +++ b/apps/utils/tests.py @@ -8,6 +8,8 @@ from http.cookies import SimpleCookie from account.models import User from news.models import News, NewsType +from establishment.models import Establishment, EstablishmentType, Employee + class BaseTestCase(APITestCase): @@ -28,6 +30,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 +53,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 +64,32 @@ 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) From 82d29d2795f9564f79dced9f713ca44f3efdc440 Mon Sep 17 00:00:00 2001 From: littlewolf Date: Tue, 24 Sep 2019 15:17:08 +0300 Subject: [PATCH 2/6] Add signal --- apps/utils/models.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/utils/models.py b/apps/utils/models.py index 632cf4a2..929b5e5b 100644 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -11,6 +11,9 @@ 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.signals import pre_save +from django.dispatch import receiver + class ProjectBaseMixin(models.Model): """Base mixin model.""" @@ -123,6 +126,23 @@ class BaseAttributes(ProjectBaseMixin): null=True, related_name='%(class)s_records_modified' ) + @receiver(pre_save) + def _pre_save(sender, instance, **kwargs): + if not issubclass(sender, BaseAttributes): + return + + # debug + from establishment.models import Employee + if not isinstance(instance, Employee): + return + + user = False + + instance.modified_by = user + + if instance._state.adding: + instance.created_by = user + class Meta: """Meta class.""" From a55695b12060210fc3da6b40098cea16578b7c86 Mon Sep 17 00:00:00 2001 From: littlewolf Date: Tue, 24 Sep 2019 20:12:09 +0300 Subject: [PATCH 3/6] Switch to decorator Add update test --- apps/establishment/serializers/back.py | 9 ++++++- apps/utils/decorators.py | 35 ++++++++++++++++++++++++++ apps/utils/models.py | 20 --------------- apps/utils/tests.py | 23 +++++++++++++++++ 4 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 apps/utils/decorators.py diff --git a/apps/establishment/serializers/back.py b/apps/establishment/serializers/back.py index 7199eb54..b4269c5f 100644 --- a/apps/establishment/serializers/back.py +++ b/apps/establishment/serializers/back.py @@ -7,6 +7,9 @@ from establishment.serializers import ( EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer, ContactPhonesSerializer, SocialNetworkRelatedSerializers, EstablishmentDetailSerializer ) + +from utils.decorators import with_base_attributes + from main.models import Currency @@ -121,7 +124,10 @@ class ContactEmailBackSerializers(PlateSerializer): ] +# TODO: test decorator +@with_base_attributes class EmployeeBackSerializers(serializers.ModelSerializer): + """Social network serializers.""" class Meta: model = models.Employee @@ -129,4 +135,5 @@ class EmployeeBackSerializers(serializers.ModelSerializer): 'id', 'user', 'name' - ] \ No newline at end of file + ] + diff --git a/apps/utils/decorators.py b/apps/utils/decorators.py new file mode 100644 index 00000000..12233021 --- /dev/null +++ b/apps/utils/decorators.py @@ -0,0 +1,35 @@ +from functools import wraps + +def with_base_attributes(cls): + + def create(self, validated_data): + user = None + request = self.context.get("request") + + if request and hasattr(request, "user"): + user = request.user + + if user is not None: + validated_data['created_by'] = user + validated_data['modified_by'] = user + + obj = self.Meta.model.objects.create(**validated_data) + return obj + + def update(self, validated_data): + user = None + request = self.context.get("request") + + if request and hasattr(request, "user"): + user = request.user + + if user is not None: + validated_data['modified_by'] = user + + obj = self.Meta.model.objects.create(**validated_data) + return obj + + setattr(cls, "create", create) + setattr(cls, "update", update) + + return cls diff --git a/apps/utils/models.py b/apps/utils/models.py index 929b5e5b..632cf4a2 100644 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -11,9 +11,6 @@ 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.signals import pre_save -from django.dispatch import receiver - class ProjectBaseMixin(models.Model): """Base mixin model.""" @@ -126,23 +123,6 @@ class BaseAttributes(ProjectBaseMixin): null=True, related_name='%(class)s_records_modified' ) - @receiver(pre_save) - def _pre_save(sender, instance, **kwargs): - if not issubclass(sender, BaseAttributes): - return - - # debug - from establishment.models import Employee - if not isinstance(instance, Employee): - return - - user = False - - instance.modified_by = user - - if instance._state.adding: - instance.created_by = user - class Meta: """Meta class.""" diff --git a/apps/utils/tests.py b/apps/utils/tests.py index 786ed940..dafe0fee 100644 --- a/apps/utils/tests.py +++ b/apps/utils/tests.py @@ -91,5 +91,28 @@ class BaseAttributeTests(BaseTestCase): 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='sedragurda', + password='sedragurdaredips19', + email='sedragurda@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) + + self.assertEqual(modify_user, employee.modified_by) From d006184b14f905c2d9ec8f772b9927db6ddaa298 Mon Sep 17 00:00:00 2001 From: littlewolf Date: Tue, 24 Sep 2019 20:22:27 +0300 Subject: [PATCH 4/6] Fix update --- apps/utils/decorators.py | 9 +++++---- apps/utils/tests.py | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/utils/decorators.py b/apps/utils/decorators.py index 12233021..e22fc3dc 100644 --- a/apps/utils/decorators.py +++ b/apps/utils/decorators.py @@ -1,4 +1,3 @@ -from functools import wraps def with_base_attributes(cls): @@ -16,7 +15,7 @@ def with_base_attributes(cls): obj = self.Meta.model.objects.create(**validated_data) return obj - def update(self, validated_data): + def update(self, instance, validated_data): user = None request = self.context.get("request") @@ -26,8 +25,10 @@ def with_base_attributes(cls): if user is not None: validated_data['modified_by'] = user - obj = self.Meta.model.objects.create(**validated_data) - return obj + obj = self.Meta.model + obj.objects.filter(pk=instance.id).update(**validated_data) + + return instance setattr(cls, "create", create) setattr(cls, "update", update) diff --git a/apps/utils/tests.py b/apps/utils/tests.py index dafe0fee..8645a020 100644 --- a/apps/utils/tests.py +++ b/apps/utils/tests.py @@ -96,9 +96,9 @@ class BaseAttributeTests(BaseTestCase): self.assertEqual(self.user, employee.modified_by) modify_user = User.objects.create_user( - username='sedragurda', - password='sedragurdaredips19', - email='sedragurda@desoz.com', + username='sedragurda2', + password='sedragurdaredips192', + email='sedragurda2@desoz.com', ) modify_tokkens = User.create_jwt_tokens(modify_user) @@ -115,4 +115,5 @@ class BaseAttributeTests(BaseTestCase): 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) From 6bbbd1d6fe2414b8c5cabf9b84519c9da4722566 Mon Sep 17 00:00:00 2001 From: littlewolf Date: Wed, 25 Sep 2019 11:11:12 +0300 Subject: [PATCH 5/6] Switch decorator to validate --- apps/utils/decorators.py | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/apps/utils/decorators.py b/apps/utils/decorators.py index e22fc3dc..c48a26c7 100644 --- a/apps/utils/decorators.py +++ b/apps/utils/decorators.py @@ -1,7 +1,7 @@ def with_base_attributes(cls): - def create(self, validated_data): + def validate(self, data): user = None request = self.context.get("request") @@ -9,28 +9,13 @@ def with_base_attributes(cls): user = request.user if user is not None: - validated_data['created_by'] = user - validated_data['modified_by'] = user + data.update({'modified_by': user}) - obj = self.Meta.model.objects.create(**validated_data) - return obj + if not self.instance: + data.update({'created_by': user}) - def update(self, instance, validated_data): - user = None - request = self.context.get("request") + return data - if request and hasattr(request, "user"): - user = request.user - - if user is not None: - validated_data['modified_by'] = user - - obj = self.Meta.model - obj.objects.filter(pk=instance.id).update(**validated_data) - - return instance - - setattr(cls, "create", create) - setattr(cls, "update", update) + setattr(cls, "validate", validate) return cls From 617beb652f38659f7eebc4dc828a161bbbab5d9d Mon Sep 17 00:00:00 2001 From: littlewolf Date: Wed, 25 Sep 2019 11:12:17 +0300 Subject: [PATCH 6/6] Add test to modified item --- apps/utils/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/utils/tests.py b/apps/utils/tests.py index 8645a020..e9ad3c23 100644 --- a/apps/utils/tests.py +++ b/apps/utils/tests.py @@ -117,3 +117,4 @@ class BaseAttributeTests(BaseTestCase): employee.refresh_from_db() self.assertEqual(modify_user, employee.modified_by) + self.assertEqual(self.user, employee.created_by)