Skip to content

Commit

Permalink
Merge pull request #8 from jourdanrodrigues/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
jourdanrodrigues authored Oct 24, 2016
2 parents d3ea675 + 23216df commit d956ddc
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 18 deletions.
76 changes: 67 additions & 9 deletions assets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,28 @@
from django.utils.translation import ugettext as _
from rest_framework.exceptions import ValidationError
from rest_framework.test import APITestCase
from rest_framework.viewsets import GenericViewSet

from assets.utils import is_cpf_valid


class MultiSerializerViewSet(GenericViewSet):
serializers = {'default': None}

def get_serializer_class(self):
assert self.serializers.get('default') is not None, (
"'%s' should include a `serializers` attribute as a dictionary"
" with a `default` key containing the serializer."
% self.__class__.__name__
)

return self.serializers.get(self.action, self.serializers.get('default'))


class CustomAPITestCase(APITestCase):
request_kwargs = {'format': 'json'}

def bulkAssertIn(self, items: list, data, is_list: bool = False):
def bulkAssertIn(self, items, data, is_list: bool = False):
"""
Source: https://github.com/jourdanrodrigues/drf_test_utils/blob/master/functions.py
:param self: object
Expand All @@ -26,14 +40,58 @@ def bulkAssertIn(self, items: list, data, is_list: bool = False):
else:
return

# Check if these are the only attributes in the dictionary
self.assertEqual(len(items), len(data),
msg='Missing attributes: ' + (', '.join([x for x in items if x not in data])
if len(items) > len(data) else
', '.join([x for x in data if x not in items])))
for item in items:
# Check the existence of each field
self.assertIn(item, data)
def which_params(missing, containing):
def mount_list(attributes, its_list):
for attribute in attributes:
if isinstance(attribute, dict):
its_list += list(attribute.keys())
else:
its_list.append(attribute)

missing_attributes = []
containing_attributes = []

mount_list(missing, missing_attributes)
mount_list(containing, containing_attributes)

return ', '.join([x for x in missing_attributes if x not in containing_attributes])

def bulk_test(entries: list, target: dict):
len_entries = 0

# Check each entry
for entry in entries:
# If entry is a dict, target has sub items
if isinstance(entry, dict):
for key, sub_entries in entry.items():
len_entries += 1

if isinstance(sub_entries, dict): # Has a configuration
if sub_entries.get('is_list'):
target = target[0]
if sub_entries.get('entries'):
sub_entries = sub_entries.get('entries') # List of entries to test
elif sub_entries.get('value'):
self.assertEqual(sub_entries['value'], target[key], # Test specific value
msg='"{key}": "{0} != {1}"'.format(sub_entries['value'], target[key],
key=key))
continue
else:
raise AssertionError('"{}" missing "entries" or "key" key.'.format(key))

self.assertIn(key, target, msg='"{}" key missing.')
bulk_test(sub_entries, target[key])
else:
len_entries += 1
self.assertIn(entry, target)

# Check if these are the only attributes in the dictionary
self.assertEqual(len_entries, len(target),
msg='Missing keys: {}.'.format(which_params(entries, target)
if len_entries > len(target) else
which_params(target, entries)))

bulk_test(items, data)


class Person(models.Model):
Expand Down
2 changes: 1 addition & 1 deletion controk_webservice/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__title__ = 'Controk WebService'
__version__ = 'v0.1.5'
__version__ = 'v0.2.0'
__author__ = 'Jourdan Rodrigues'
__copyright__ = 'Copyright 2016 Jourdan Rodrigues'

Expand Down
9 changes: 9 additions & 0 deletions controk_webservice/addresses/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import serializers

from controk_webservice.addresses.models import Address


class AddressSerializer(serializers.ModelSerializer):
class Meta:
model = Address
fields = ['place', 'place_name', 'number', 'complement', 'neighborhood', 'city', 'state', 'cep']
16 changes: 15 additions & 1 deletion controk_webservice/clients/serializers.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
from rest_framework import serializers

from controk_webservice.addresses.serializers import AddressSerializer
from controk_webservice.clients.models import Client


class ClientSerializer(serializers.ModelSerializer):
class ClientListSerializer(serializers.ModelSerializer):
class Meta:
model = Client
fields = ['id', 'name', 'email', 'cpf', 'observation']


class ClientSerializer(serializers.ModelSerializer):
place_options = serializers.SerializerMethodField()
address = AddressSerializer()

@staticmethod
def get_place_options(client):
return dict(client.address.PLACES)

class Meta:
model = Client
fields = ['phone', 'mobile', 'address', 'place_options']
13 changes: 9 additions & 4 deletions controk_webservice/clients/tests.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
from rest_framework import status

from assets.models import CustomAPITestCase
from controk_webservice.clients.models import Client
from controk_webservice.clients.models import Client, Address


class ClientTest(CustomAPITestCase):
fixtures = ['clients', 'addresses']
items = ['id', 'name', 'email', 'cpf', 'observation']

def test_clients_list(self):
response = self.client.get('/api/v1/clients/', **self.request_kwargs)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.bulkAssertIn(self.items, response.data, is_list=True)

items = ['id', 'name', 'email', 'cpf', 'observation']
self.bulkAssertIn(items, response.data, is_list=True)

def test_retrieve_client(self):
client_id = Client.objects.values_list('id', flat=True).first()
response = self.client.get('/api/v1/clients/{}/'.format(client_id), **self.request_kwargs)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.bulkAssertIn(self.items, response.data)

items = [{'address': ['place', 'place_name', 'number', 'complement', 'neighborhood', 'city', 'state', 'cep'],
'place_options': dict(Address.PLACES).keys()},
'phone', 'mobile']
self.bulkAssertIn(items, response.data)
19 changes: 16 additions & 3 deletions controk_webservice/clients/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
from rest_framework import viewsets

from controk_webservice.clients.serializers import Client, ClientSerializer
from assets.models import MultiSerializerViewSet
from controk_webservice.clients.serializers import Client, ClientListSerializer, ClientSerializer


class ClientsViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = ClientSerializer
class ClientsViewSet(MultiSerializerViewSet, viewsets.ReadOnlyModelViewSet):
queryset = Client.objects.all()
serializers = {
'default': ClientSerializer,
'list': ClientListSerializer
}

def get_queryset(self):
queryset = self.queryset

# Bring the address within the main query only on retrieve
if self.action == 'retrieve':
queryset = queryset.select_related('address')

return queryset

0 comments on commit d956ddc

Please sign in to comment.