Source code for rest_framework_tricks.tests.test_nested_proxy_field

"""
Test NestedProxyField.
"""

from __future__ import absolute_import

from decimal import Decimal

import unittest

from nine.versions import DJANGO_GTE_1_10

import pytest

from rest_framework import status

import factories

from .base import BaseRestFrameworkTestCase

if DJANGO_GTE_1_10:
    from django.urls import reverse
else:
    from django.core.urlresolvers import reverse

__title__ = 'rest_framework_tricks.tests.test_nested_proxy_field'
__author__ = 'Artur Barseghyan <artur.barseghyan@gmail.com>'
__copyright__ = '2017-2019 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = (
    'TestNestedProxyFieldCreateAction',
    'TestNestedProxyFieldUpdateAction',
)


@pytest.mark.django_db
class TestNestedProxyFieldActionBase(BaseRestFrameworkTestCase):
    """Test NestedProxyField - update action."""

    pytestmark = pytest.mark.django_db

    def get_status_code(self):
        """Get status code.

        :return: Status code expected as result of the action.
        :rtype: str
        """
        raise NotImplementedError

    def get_client_action(self):
        """Get client action.

        :return: Client action.
        :rtype: callable
        """
        raise NotImplementedError

    def _nested_proxy_field_hyperlinked_model_serializer(self, url=None):
        """Test NestedProxyField and HyperlinkedModelSerializer."""
        data = {
            'title': self.faker.sentence(nb_words=3, variable_nb_words=True),
            'description': self.faker.text(),
            'summary': self.faker.text(),
            'publishing_information': {
                'publication_date': self.faker.date(),
                'isbn': self.faker.isbn10(),
                'pages': self.faker.pyint()
            },
            'stock_information': {
                'stock_count': self.faker.pyint(),
                'price': self.faker.pyint(),
                'state': 'published'
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())
        for __key in ('title', 'summary', 'description'):
            self.assertEqual(response.data.get(__key), data.get(__key))

        for __key in ('publication_date', 'isbn', 'pages'):
            self.assertEqual(
                response.data['publishing_information'].get(__key),
                data['publishing_information'].get(__key)
            )

        for __key in ('stock_count', 'state'):
            self.assertEqual(
                response.data['stock_information'].get(__key),
                data['stock_information'].get(__key)
            )
        self.assertEqual(
            Decimal(response.data['stock_information'].get('price')),
            Decimal(data['stock_information'].get('price'))
        )

    def _nested_proxy_field_model_serializer(self, url=None):
        """Test NestedProxyField and ModelSerializer."""
        data = {
            'name': self.faker.text(max_nb_chars=30),
            'info': self.faker.text(),
            'website': self.faker.url(),
            'address_information': {
                'address': self.faker.address(),
                'city': self.faker.city(),
                'state_province': self.faker.state(),
                'country': self.faker.country()
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())
        for __key in ('name', 'info', 'website'):
            self.assertEqual(response.data.get(__key), data.get(__key))

        for __key in ('address', 'city', 'state_province', 'country'):
            self.assertEqual(
                response.data['address_information'].get(__key),
                data['address_information'].get(__key)
            )

    def _nested_proxy_field_model_serializer_missing_all_nested_fields(
            self, url=None
    ):
        """Test NestedProxyField and ModelSerializer.

        All nested fields are missing.

        Note, that the `address_information` which contains the `address`,
        `city`, `state_province` and `country` fields is completely missing
        in the payload.
        """
        data = {
            'name': self.faker.text(max_nb_chars=30),
            'info': self.faker.text(),
            'website': self.faker.url(),
            # 'address_information': {
            #     'address': self.faker.address(),
            #     'city': self.faker.city(),
            #     'state_province': self.faker.state(),
            #     'country': self.faker.country()
            # }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())
        for __key in ('name', 'info', 'website'):
            self.assertEqual(response.data.get(__key), data.get(__key))

    def _nested_proxy_field_model_serializer_depth(self, url=None):
        """Test NestedProxyField and ModelSerializer with more depth."""
        data = {
            'salutation': self.faker.text(max_nb_chars=10),
            'name': self.faker.name(),
            'birth_date': self.faker.date(),
            'biography': self.faker.text(),
            'contact_information': {
                'personal_contact_information': {
                    'email': self.faker.email(),
                    'phone_number': self.faker.phone_number(),
                    'website': self.faker.url(),
                },
                'business_contact_information': {
                    'company': self.faker.company(),
                    'company_email': self.faker.email(),
                    'company_phone_number': self.faker.phone_number(),
                    'company_website': self.faker.url()
                }
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())
        for __key in ('salutation', 'name', 'biography'):
            self.assertEqual(response.data.get(__key), data.get(__key))

        for __key in ('email', 'phone_number', 'website'):
            self.assertEqual(
                response.data['contact_information']
                             ['personal_contact_information'].get(__key),
                data['contact_information']
                    ['personal_contact_information'].get(__key)
            )

        for __key in ('company',
                      'company_email',
                      'company_phone_number',
                      'company_website'):
            self.assertEqual(
                response.data['contact_information']
                             ['business_contact_information'].get(__key),
                data['contact_information']
                    ['business_contact_information'].get(__key)
            )

    def _nested_proxy_field_model_serializer_more_depth(self, url=None):
        """Test NestedProxyField and ModelSerializer with more depth."""
        data = {
            'information': {
                'data': {
                    'personal_information': {
                        'salutation': self.faker.text(max_nb_chars=10),
                        'first_name': self.faker.first_name(),
                        'last_name': self.faker.last_name(),
                        'birth_date': self.faker.date(),
                        'biography': self.faker.text(),
                    },
                    'contact_information': {
                        'personal_contact_information': {
                            'email': self.faker.email(),
                            'phone_number': self.faker.phone_number(),
                            'website': self.faker.url(),
                        },
                        'business_contact_information': {
                            'company': self.faker.company(),
                            'company_email': self.faker.email(),
                            'company_phone_number': self.faker.phone_number(),
                            'company_website': self.faker.url()
                        }
                    },
                    'bank_information': {
                        'bank_name': self.faker.company(),
                        'bank_account_name': self.faker.name(),
                        'bank_account_number': self.faker.pystr(),
                    },
                }
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())

        for __key in ('salutation', 'first_name', 'last_name', 'biography'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['personal_information'].get(__key),
                data['information']
                    ['data']
                    ['personal_information'].get(__key)
            )

        for __key in ('email', 'phone_number', 'website'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['contact_information']
                             ['personal_contact_information'].get(__key),
                data['information']
                    ['data']
                    ['contact_information']
                    ['personal_contact_information'].get(__key)
            )

        for __key in ('company',
                      'company_email',
                      'company_phone_number',
                      'company_website'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['contact_information']
                             ['business_contact_information'].get(__key),
                data['information']
                    ['data']
                    ['contact_information']
                    ['business_contact_information'].get(__key)
            )

        for __key in ('bank_name', 'bank_account_name', 'bank_account_number'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['bank_information'].get(__key),
                data['information']
                    ['data']
                    ['bank_information'].get(__key)
            )

    def _nested_proxy_field_model_serializer_missing_fields(self, url=None):
        """Test NestedProxyField and ModelSerializer with missing fields.

        Several non-required fields are missing (in this case, it's the
        ``info`` field).
        """
        data = {
            'name': self.faker.text(max_nb_chars=30),
            'website': self.faker.url(),
            'address_information': {
                'address': self.faker.address(),
                'city': self.faker.city(),
                'state_province': self.faker.state(),
                'country': self.faker.country()
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())
        for __key in ('name', 'website'):
            self.assertEqual(response.data.get(__key), data.get(__key))

        for __key in ('address', 'city', 'state_province', 'country'):
            self.assertEqual(
                response.data['address_information'].get(__key),
                data['address_information'].get(__key)
            )

    def _nested_proxy_field_model_serializer_depth_missing_fields(self,
                                                                  url=None):
        """Test NestedProxyField and ModelSerializer with more depth.

        Several non-required fields are missing (in this case they are
        ``birth_date``, ``biography``, ``website`` and ``company_website``).
        """
        data = {
            'information': {
                'data': {
                    'personal_information': {
                        'salutation': self.faker.text(max_nb_chars=10),
                        'first_name': self.faker.first_name(),
                        'last_name': self.faker.last_name(),
                    },
                    'contact_information': {
                        'personal_contact_information': {
                            'email': self.faker.email(),
                            'phone_number': self.faker.phone_number(),
                        },
                        'business_contact_information': {
                            'company': self.faker.company(),
                            'company_email': self.faker.email(),
                            'company_phone_number': self.faker.phone_number(),
                        }
                    },
                    'bank_information': {
                        'bank_name': self.faker.company(),
                        'bank_account_name': self.faker.name(),
                        'bank_account_number': self.faker.pystr(),
                    },
                }
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())

        for __key in ('salutation', 'first_name', 'last_name'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['personal_information'].get(__key),
                data['information']
                    ['data']
                    ['personal_information'].get(__key)
            )

        for __key in ('email', 'phone_number'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['contact_information']
                             ['personal_contact_information'].get(__key),
                data['information']
                    ['data']
                    ['contact_information']
                    ['personal_contact_information'].get(__key)
            )

        for __key in ('company', 'company_email', 'company_phone_number'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['contact_information']
                             ['business_contact_information'].get(__key),
                data['information']
                    ['data']
                    ['contact_information']
                    ['business_contact_information'].get(__key)
            )

        for __key in ('bank_name', 'bank_account_name', 'bank_account_number'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['bank_information'].get(__key),
                data['information']
                    ['data']
                    ['bank_information'].get(__key)
            )

    def _nested_proxy_field_model_serializer_depth_more_missing_fields(
            self, url=None
    ):
        """Test NestedProxyField and ModelSerializer with more depth.

        All non-required fields are missing (in this case they are
        ``birth_date``, ``biography``, ``website`` and ``company_website``).
        """
        data = {
            'information': {
                'data': {
                    'personal_information': {
                        'salutation': self.faker.text(max_nb_chars=10),
                        'first_name': self.faker.first_name(),
                        'last_name': self.faker.last_name(),
                    },
                    'contact_information': {
                        'personal_contact_information': {
                            'email': self.faker.email(),
                        },
                    },
                }
            }
        }

        response = self.get_client_action()(url, data, format='json')

        self.assertEqual(response.status_code, self.get_status_code())

        for __key in ('salutation', 'first_name', 'last_name'):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['personal_information'].get(__key),
                data['information']
                    ['data']
                    ['personal_information'].get(__key)
            )

        for __key in ('email',):
            self.assertEqual(
                response.data['information']
                             ['data']
                             ['contact_information']
                             ['personal_contact_information'].get(__key),
                data['information']
                    ['data']
                    ['contact_information']
                    ['personal_contact_information'].get(__key)
            )


[docs]class TestNestedProxyFieldCreateAction(TestNestedProxyFieldActionBase): """Test NestedProxyField - create action."""
[docs] def get_status_code(self): """Get status code. :return: Status code expected as result of the action. :rtype: str """ return status.HTTP_201_CREATED
[docs] def get_client_action(self): """Get client action. :return: Client action. :rtype: callable """ return self.client.post
[docs] @classmethod def setUpClass(cls): """Set up.""" super(TestNestedProxyFieldCreateAction, cls).setUpClass() cls.book_listing_url = reverse('book-list', kwargs={}) cls.publisher_listing_url = reverse('publisher-list', kwargs={}) cls.author_listing_url = reverse('author-list', kwargs={}) cls.profile_listing_url = reverse('profile-list', kwargs={}) cls.proxy_author_listing_url = reverse('authorproxy-list', kwargs={})
[docs] def test_nested_proxy_field_hyperlinked_model_serializer(self): """Test NestedProxyField and HyperlinkedModelSerializer.""" self._nested_proxy_field_hyperlinked_model_serializer( self.book_listing_url )
[docs] def test_nested_proxy_field_model_serializer_depth(self): """Test NestedProxyField and ModelSerializer with more depth.""" self._nested_proxy_field_model_serializer_depth( self.author_listing_url )
[docs] def test_another_nested_proxy_field_model_serializer_depth(self): """Test NestedProxyField and ModelSerializer with more depth.""" self._nested_proxy_field_model_serializer_depth( self.proxy_author_listing_url )
[docs] def test_another_nested_proxy_field_model_serializer_more_depth(self): """Test NestedProxyField and ModelSerializer with more depth.""" self._nested_proxy_field_model_serializer_more_depth( self.profile_listing_url )
[docs] def test_nested_proxy_field_model_serializer_missing_fields(self): """Test NestedProxyField and ModelSerializer with missing fields.""" self._nested_proxy_field_model_serializer_missing_fields( self.publisher_listing_url )
[docs] def test_nested_proxy_field_model_serializer_depth_missing_fields(self): """Test NestedProxyField and ModelSerializer with more depth. Several non-required fields are missing. """ self._nested_proxy_field_model_serializer_depth_missing_fields( self.profile_listing_url )
[docs] def test_nested_proxy_field_model_serializer_depth_more_missing_fields( self ): """Test NestedProxyField and ModelSerializer with more depth. All of the non-required fields are missing. """ self._nested_proxy_field_model_serializer_depth_more_missing_fields( self.profile_listing_url )
[docs] def test_nested_proxy_field_model_serializer(self): """Test NestedProxyField and ModelSerializer.""" self._nested_proxy_field_model_serializer( self.publisher_listing_url )
[docs] def test_nested_proxy_field_model_serializer_missing_all_nested_fields( self ): """Test NestedProxyField and ModelSerializer.""" self._nested_proxy_field_model_serializer_missing_all_nested_fields( self.publisher_listing_url )
[docs]@pytest.mark.django_db class TestNestedProxyFieldUpdateAction(TestNestedProxyFieldActionBase): """Test NestedProxyField - update action.""" pytestmark = pytest.mark.django_db
[docs] def get_status_code(self): """Get status code. :return: Status code expected as result of the action. :rtype: str """ return status.HTTP_200_OK
[docs] def get_client_action(self): """Get client action. :return: Client action. :rtype: callable """ return self.client.put
[docs] @classmethod def setUpClass(cls): """Set up.""" super(TestNestedProxyFieldUpdateAction, cls).setUpClass() cls.books = factories.BookFactory.create_batch(10) cls.profiles = factories.ProfileFactory.create_batch(10) cls.book_detail_url = reverse( 'book-detail', kwargs={'pk': cls.books[0].pk} ) cls.publisher_detail_url = reverse( 'publisher-detail', kwargs={'pk': cls.books[0].publisher.pk} ) cls.author_detail_url = reverse( 'author-detail', kwargs={'pk': cls.books[0].authors.first().pk} ) cls.profile_detail_url = reverse( 'profile-detail', kwargs={'pk': cls.profiles[0].pk} ) cls.proxy_author_detail_url = reverse( 'authorproxy-detail', kwargs={'pk': cls.books[0].authors.first().pk} )
[docs] def test_nested_proxy_field_hyperlinked_model_serializer(self): """Test NestedProxyField and HyperlinkedModelSerializer.""" self._nested_proxy_field_hyperlinked_model_serializer( self.book_detail_url )
[docs] def test_nested_proxy_field_model_serializer(self): """Test NestedProxyField and ModelSerializer.""" self._nested_proxy_field_model_serializer( self.publisher_detail_url )
[docs] def test_nested_proxy_field_model_serializer_missing_all_nested_fields( self ): """Test NestedProxyField and ModelSerializer.""" self._nested_proxy_field_model_serializer_missing_all_nested_fields( self.publisher_detail_url )
[docs] def test_nested_proxy_field_model_serializer_depth(self): """Test NestedProxyField and ModelSerializer with more depth.""" self._nested_proxy_field_model_serializer_depth( self.author_detail_url )
[docs] def test_another_nested_proxy_field_model_serializer_depth(self): """Test NestedProxyField and ModelSerializer with more depth.""" self._nested_proxy_field_model_serializer_depth( self.proxy_author_detail_url )
[docs] def test_another_nested_proxy_field_model_serializer_more_depth(self): """Test NestedProxyField and ModelSerializer with more depth.""" self._nested_proxy_field_model_serializer_more_depth( self.profile_detail_url )
[docs] def test_nested_proxy_field_model_serializer_missing_fields(self): """Test NestedProxyField and ModelSerializer with missing fields.""" self._nested_proxy_field_model_serializer_missing_fields( self.publisher_detail_url )
[docs] def test_nested_proxy_field_model_serializer_depth_missing_fields(self): """Test NestedProxyField and ModelSerializer with more depth. Several non-required fields are missing. """ self._nested_proxy_field_model_serializer_depth_missing_fields( self.profile_detail_url )
[docs] def test_nested_proxy_field_model_serializer_depth_more_missing_fields( self ): """Test NestedProxyField and ModelSerializer with more depth. All of the non-required fields are missing. """ self._nested_proxy_field_model_serializer_depth_more_missing_fields( self.profile_detail_url )
if __name__ == '__main__': unittest.main()