Commit f4f237e3 by Tom Christie

3.2, 3.3 compat

parent d9c7b1c5
__version__ = '2.1.17' __version__ = '2.1.17'
VERSION = __version__ # synonym VERSION = __version__ # synonym
# Header encoding (see RFC5987)
HTTP_HEADER_ENCODING = 'iso-8859-1'
""" """
Provides a set of pluggable authentication policies. Provides a set of pluggable authentication policies.
""" """
from __future__ import unicode_literals
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.utils.encoding import DjangoUnicodeDecodeError from django.utils.encoding import DjangoUnicodeDecodeError
from rest_framework import exceptions from rest_framework import exceptions, HTTP_HEADER_ENCODING
from rest_framework.compat import CsrfViewMiddleware from rest_framework.compat import CsrfViewMiddleware
from rest_framework.compat import smart_text from rest_framework.compat import smart_text
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
...@@ -43,23 +44,25 @@ class BasicAuthentication(BaseAuthentication): ...@@ -43,23 +44,25 @@ class BasicAuthentication(BaseAuthentication):
Returns a `User` if a correct username and password have been supplied Returns a `User` if a correct username and password have been supplied
using HTTP Basic authentication. Otherwise returns `None`. using HTTP Basic authentication. Otherwise returns `None`.
""" """
auth = request.META.get('HTTP_AUTHORIZATION', '').split() auth = request.META.get('HTTP_AUTHORIZATION', b'')
if type(auth) == type(''):
# Work around django test client oddness
auth = auth.encode(HTTP_HEADER_ENCODING)
auth = auth.split()
if not auth or auth[0].lower() != "basic": if not auth or auth[0].lower() != b'basic':
return None return None
if len(auth) != 2: if len(auth) != 2:
raise exceptions.AuthenticationFailed('Invalid basic header') raise exceptions.AuthenticationFailed('Invalid basic header')
encoding = api_settings.HTTP_HEADER_ENCODING
try: try:
auth_parts = base64.b64decode(auth[1].encode(encoding)).partition(':') auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':')
except TypeError: except (TypeError, UnicodeDecodeError):
raise exceptions.AuthenticationFailed('Invalid basic header') raise exceptions.AuthenticationFailed('Invalid basic header')
try: try:
userid = smart_text(auth_parts[0]) userid, password = auth_parts[0], auth_parts[2]
password = smart_text(auth_parts[2])
except DjangoUnicodeDecodeError: except DjangoUnicodeDecodeError:
raise exceptions.AuthenticationFailed('Invalid basic header') raise exceptions.AuthenticationFailed('Invalid basic header')
......
...@@ -311,7 +311,7 @@ class SlugRelatedField(RelatedField): ...@@ -311,7 +311,7 @@ class SlugRelatedField(RelatedField):
return self.queryset.get(**{self.slug_field: data}) return self.queryset.get(**{self.slug_field: data})
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise ValidationError(self.error_messages['does_not_exist'] % raise ValidationError(self.error_messages['does_not_exist'] %
(self.slug_field, unicode(data))) (self.slug_field, smart_text(data)))
except (TypeError, ValueError): except (TypeError, ValueError):
msg = self.error_messages['invalid'] msg = self.error_messages['invalid']
raise ValidationError(msg) raise ValidationError(msg)
......
...@@ -212,7 +212,7 @@ class BaseSerializer(Field): ...@@ -212,7 +212,7 @@ class BaseSerializer(Field):
reverted_data = {} reverted_data = {}
if data is not None and not isinstance(data, dict): if data is not None and not isinstance(data, dict):
self._errors['non_field_errors'] = [u'Invalid data'] self._errors['non_field_errors'] = ['Invalid data']
return None return None
for field_name, field in self.fields.items(): for field_name, field in self.fields.items():
...@@ -287,7 +287,7 @@ class BaseSerializer(Field): ...@@ -287,7 +287,7 @@ class BaseSerializer(Field):
""" """
Deserialize primitives -> objects. Deserialize primitives -> objects.
""" """
if hasattr(data, '__iter__') and not isinstance(data, dict): if hasattr(data, '__iter__') and not isinstance(data, (dict, six.text_type)):
# TODO: error data when deserializing lists # TODO: error data when deserializing lists
return [self.from_native(item, None) for item in data] return [self.from_native(item, None) for item in data]
...@@ -525,7 +525,7 @@ class ModelSerializer(Serializer): ...@@ -525,7 +525,7 @@ class ModelSerializer(Serializer):
""" """
try: try:
instance.full_clean(exclude=self.get_validation_exclusions()) instance.full_clean(exclude=self.get_validation_exclusions())
except ValidationError, err: except ValidationError as err:
self._errors = err.message_dict self._errors = err.message_dict
return None return None
return instance return instance
......
...@@ -75,9 +75,6 @@ DEFAULTS = { ...@@ -75,9 +75,6 @@ DEFAULTS = {
'URL_FORMAT_OVERRIDE': 'format', 'URL_FORMAT_OVERRIDE': 'format',
'FORMAT_SUFFIX_KWARG': 'format', 'FORMAT_SUFFIX_KWARG': 'format',
# Header encoding (see RFC5987)
'HTTP_HEADER_ENCODING': 'iso-8859-1',
} }
......
from __future__ import unicode_literals
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.http import HttpResponse from django.http import HttpResponse
from django.test import Client, TestCase from django.test import Client, TestCase
from rest_framework import HTTP_HEADER_ENCODING
from rest_framework import permissions from rest_framework import permissions
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from rest_framework.authentication import TokenAuthentication, BasicAuthentication, SessionAuthentication from rest_framework.authentication import TokenAuthentication, BasicAuthentication, SessionAuthentication
...@@ -41,13 +44,17 @@ class BasicAuthTests(TestCase): ...@@ -41,13 +44,17 @@ class BasicAuthTests(TestCase):
def test_post_form_passing_basic_auth(self): def test_post_form_passing_basic_auth(self):
"""Ensure POSTing json over basic auth with correct credentials passes and does not require CSRF""" """Ensure POSTing json over basic auth with correct credentials passes and does not require CSRF"""
auth = 'Basic %s' % base64.encodestring('%s:%s' % (self.username, self.password)).encode('iso-8859-1').strip().decode('iso-8859-1') credentials = ('%s:%s' % (self.username, self.password))
base64_credentials = base64.b64encode(credentials.encode(HTTP_HEADER_ENCODING)).decode(HTTP_HEADER_ENCODING)
auth = 'Basic %s' % base64_credentials
response = self.csrf_client.post('/basic/', {'example': 'example'}, HTTP_AUTHORIZATION=auth) response = self.csrf_client.post('/basic/', {'example': 'example'}, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_post_json_passing_basic_auth(self): def test_post_json_passing_basic_auth(self):
"""Ensure POSTing form over basic auth with correct credentials passes and does not require CSRF""" """Ensure POSTing form over basic auth with correct credentials passes and does not require CSRF"""
auth = 'Basic %s' % base64.encodestring('%s:%s' % (self.username, self.password)).encode('iso-8859-1').strip().decode('iso-8859-1') credentials = ('%s:%s' % (self.username, self.password))
base64_credentials = base64.b64encode(credentials.encode(HTTP_HEADER_ENCODING)).decode(HTTP_HEADER_ENCODING)
auth = 'Basic %s' % base64_credentials
response = self.csrf_client.post('/basic/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth) response = self.csrf_client.post('/basic/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
......
...@@ -86,16 +86,16 @@ class TestGenericRelations(TestCase): ...@@ -86,16 +86,16 @@ class TestGenericRelations(TestCase):
serializer = TagSerializer(Tag.objects.all()) serializer = TagSerializer(Tag.objects.all())
expected = [ expected = [
{ {
'tag': u'django', 'tag': 'django',
'tagged_item': u'Bookmark: https://www.djangoproject.com/' 'tagged_item': 'Bookmark: https://www.djangoproject.com/'
}, },
{ {
'tag': u'python', 'tag': 'python',
'tagged_item': u'Bookmark: https://www.djangoproject.com/' 'tagged_item': 'Bookmark: https://www.djangoproject.com/'
}, },
{ {
'tag': u'reminder', 'tag': 'reminder',
'tagged_item': u'Note: Remember the milk' 'tagged_item': 'Note: Remember the milk'
} }
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -218,11 +218,11 @@ class HyperlinkedForeignKeyTests(TestCase): ...@@ -218,11 +218,11 @@ class HyperlinkedForeignKeyTests(TestCase):
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_update_incorrect_type(self): def test_foreign_key_update_incorrect_type(self):
data = {'url': '/foreignkeysource/1/', 'name': u'source-1', 'target': 2} data = {'url': '/foreignkeysource/1/', 'name': 'source-1', 'target': 2}
instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'target': [u'Incorrect type. Expected url string, received int.']}) self.assertEquals(serializer.errors, {'target': ['Incorrect type. Expected url string, received int.']})
def test_reverse_foreign_key_update(self): def test_reverse_foreign_key_update(self):
data = {'url': '/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['/foreignkeysource/1/', '/foreignkeysource/3/']} data = {'url': '/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['/foreignkeysource/1/', '/foreignkeysource/3/']}
...@@ -439,7 +439,7 @@ class HyperlinkedNullableOneToOneTests(TestCase): ...@@ -439,7 +439,7 @@ class HyperlinkedNullableOneToOneTests(TestCase):
queryset = OneToOneTarget.objects.all() queryset = OneToOneTarget.objects.all()
serializer = NullableOneToOneTargetSerializer(queryset) serializer = NullableOneToOneTargetSerializer(queryset)
expected = [ expected = [
{'url': '/onetoonetarget/1/', 'name': u'target-1', 'nullable_source': '/nullableonetoonesource/1/'}, {'url': '/onetoonetarget/1/', 'name': 'target-1', 'nullable_source': '/nullableonetoonesource/1/'},
{'url': '/onetoonetarget/2/', 'name': u'target-2', 'nullable_source': None}, {'url': '/onetoonetarget/2/', 'name': 'target-2', 'nullable_source': None},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -109,7 +109,7 @@ class NestedNullableOneToOneTests(TestCase): ...@@ -109,7 +109,7 @@ class NestedNullableOneToOneTests(TestCase):
queryset = OneToOneTarget.objects.all() queryset = OneToOneTarget.objects.all()
serializer = NullableOneToOneTargetSerializer(queryset) serializer = NullableOneToOneTargetSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'target-1', 'nullable_source': {'id': 1, 'name': u'source-1', 'target': 1}}, {'id': 1, 'name': 'target-1', 'nullable_source': {'id': 1, 'name': 'source-1', 'target': 1}},
{'id': 2, 'name': u'target-2', 'nullable_source': None}, {'id': 2, 'name': 'target-2', 'nullable_source': None},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -198,11 +198,11 @@ class PKForeignKeyTests(TestCase): ...@@ -198,11 +198,11 @@ class PKForeignKeyTests(TestCase):
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_update_incorrect_type(self): def test_foreign_key_update_incorrect_type(self):
data = {'id': 1, 'name': u'source-1', 'target': 'foo'} data = {'id': 1, 'name': 'source-1', 'target': 'foo'}
instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'target': [u'Incorrect type. Expected pk value, received str.']}) self.assertEquals(serializer.errors, {'target': ['Incorrect type. Expected pk value, received str.']})
def test_reverse_foreign_key_update(self): def test_reverse_foreign_key_update(self):
data = {'id': 2, 'name': 'target-2', 'sources': [1, 3]} data = {'id': 2, 'name': 'target-2', 'sources': [1, 3]}
...@@ -415,7 +415,7 @@ class PKNullableOneToOneTests(TestCase): ...@@ -415,7 +415,7 @@ class PKNullableOneToOneTests(TestCase):
queryset = OneToOneTarget.objects.all() queryset = OneToOneTarget.objects.all()
serializer = NullableOneToOneTargetSerializer(queryset) serializer = NullableOneToOneTargetSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'target-1', 'nullable_source': 1}, {'id': 1, 'name': 'target-1', 'nullable_source': 1},
{'id': 2, 'name': u'target-2', 'nullable_source': None}, {'id': 2, 'name': 'target-2', 'nullable_source': None},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -39,9 +39,9 @@ class PKForeignKeyTests(TestCase): ...@@ -39,9 +39,9 @@ class PKForeignKeyTests(TestCase):
queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
serializer = ForeignKeySourceSerializer(queryset) serializer = ForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': 'target-1'} {'id': 3, 'name': 'source-3', 'target': 'target-1'}
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -49,13 +49,13 @@ class PKForeignKeyTests(TestCase): ...@@ -49,13 +49,13 @@ class PKForeignKeyTests(TestCase):
queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
serializer = ForeignKeyTargetSerializer(queryset) serializer = ForeignKeyTargetSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']},
{'id': 2, 'name': u'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_update(self): def test_foreign_key_update(self):
data = {'id': 1, 'name': u'source-1', 'target': 'target-2'} data = {'id': 1, 'name': 'source-1', 'target': 'target-2'}
instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
...@@ -66,21 +66,21 @@ class PKForeignKeyTests(TestCase): ...@@ -66,21 +66,21 @@ class PKForeignKeyTests(TestCase):
queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
serializer = ForeignKeySourceSerializer(queryset) serializer = ForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': 'target-2'}, {'id': 1, 'name': 'source-1', 'target': 'target-2'},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': 'target-1'} {'id': 3, 'name': 'source-3', 'target': 'target-1'}
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_update_incorrect_type(self): def test_foreign_key_update_incorrect_type(self):
data = {'id': 1, 'name': u'source-1', 'target': 123} data = {'id': 1, 'name': 'source-1', 'target': 123}
instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'target': [u'Object with name=123 does not exist.']}) self.assertEquals(serializer.errors, {'target': ['Object with name=123 does not exist.']})
def test_reverse_foreign_key_update(self): def test_reverse_foreign_key_update(self):
data = {'id': 2, 'name': u'target-2', 'sources': ['source-1', 'source-3']} data = {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']}
instance = ForeignKeyTarget.objects.get(pk=2) instance = ForeignKeyTarget.objects.get(pk=2)
serializer = ForeignKeyTargetSerializer(instance, data=data) serializer = ForeignKeyTargetSerializer(instance, data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
...@@ -89,8 +89,8 @@ class PKForeignKeyTests(TestCase): ...@@ -89,8 +89,8 @@ class PKForeignKeyTests(TestCase):
queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
new_serializer = ForeignKeyTargetSerializer(queryset) new_serializer = ForeignKeyTargetSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']},
{'id': 2, 'name': u'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
] ]
self.assertEquals(new_serializer.data, expected) self.assertEquals(new_serializer.data, expected)
...@@ -101,55 +101,55 @@ class PKForeignKeyTests(TestCase): ...@@ -101,55 +101,55 @@ class PKForeignKeyTests(TestCase):
queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
serializer = ForeignKeyTargetSerializer(queryset) serializer = ForeignKeyTargetSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'target-1', 'sources': ['source-2']}, {'id': 1, 'name': 'target-1', 'sources': ['source-2']},
{'id': 2, 'name': u'target-2', 'sources': ['source-1', 'source-3']}, {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_create(self): def test_foreign_key_create(self):
data = {'id': 4, 'name': u'source-4', 'target': 'target-2'} data = {'id': 4, 'name': 'source-4', 'target': 'target-2'}
serializer = ForeignKeySourceSerializer(data=data) serializer = ForeignKeySourceSerializer(data=data)
serializer.is_valid() serializer.is_valid()
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
obj = serializer.save() obj = serializer.save()
self.assertEquals(serializer.data, data) self.assertEquals(serializer.data, data)
self.assertEqual(obj.name, u'source-4') self.assertEqual(obj.name, 'source-4')
# Ensure source 4 is added, and everything else is as expected # Ensure source 4 is added, and everything else is as expected
queryset = ForeignKeySource.objects.all() queryset = ForeignKeySource.objects.all()
serializer = ForeignKeySourceSerializer(queryset) serializer = ForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': 'target-1'}, {'id': 3, 'name': 'source-3', 'target': 'target-1'},
{'id': 4, 'name': u'source-4', 'target': 'target-2'}, {'id': 4, 'name': 'source-4', 'target': 'target-2'},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_reverse_foreign_key_create(self): def test_reverse_foreign_key_create(self):
data = {'id': 3, 'name': u'target-3', 'sources': ['source-1', 'source-3']} data = {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']}
serializer = ForeignKeyTargetSerializer(data=data) serializer = ForeignKeyTargetSerializer(data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
obj = serializer.save() obj = serializer.save()
self.assertEquals(serializer.data, data) self.assertEquals(serializer.data, data)
self.assertEqual(obj.name, u'target-3') self.assertEqual(obj.name, 'target-3')
# Ensure target 3 is added, and everything else is as expected # Ensure target 3 is added, and everything else is as expected
queryset = ForeignKeyTarget.objects.all() queryset = ForeignKeyTarget.objects.all()
serializer = ForeignKeyTargetSerializer(queryset) serializer = ForeignKeyTargetSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'target-1', 'sources': ['source-2']}, {'id': 1, 'name': 'target-1', 'sources': ['source-2']},
{'id': 2, 'name': u'target-2', 'sources': []}, {'id': 2, 'name': 'target-2', 'sources': []},
{'id': 3, 'name': u'target-3', 'sources': ['source-1', 'source-3']}, {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_update_with_invalid_null(self): def test_foreign_key_update_with_invalid_null(self):
data = {'id': 1, 'name': u'source-1', 'target': None} data = {'id': 1, 'name': 'source-1', 'target': None}
instance = ForeignKeySource.objects.get(pk=1) instance = ForeignKeySource.objects.get(pk=1)
serializer = ForeignKeySourceSerializer(instance, data=data) serializer = ForeignKeySourceSerializer(instance, data=data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) self.assertEquals(serializer.errors, {'target': ['Value may not be null']})
class SlugNullableForeignKeyTests(TestCase): class SlugNullableForeignKeyTests(TestCase):
...@@ -166,28 +166,28 @@ class SlugNullableForeignKeyTests(TestCase): ...@@ -166,28 +166,28 @@ class SlugNullableForeignKeyTests(TestCase):
queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset) serializer = NullableForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': None}, {'id': 3, 'name': 'source-3', 'target': None},
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_create_with_valid_null(self): def test_foreign_key_create_with_valid_null(self):
data = {'id': 4, 'name': u'source-4', 'target': None} data = {'id': 4, 'name': 'source-4', 'target': None}
serializer = NullableForeignKeySourceSerializer(data=data) serializer = NullableForeignKeySourceSerializer(data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
obj = serializer.save() obj = serializer.save()
self.assertEquals(serializer.data, data) self.assertEquals(serializer.data, data)
self.assertEqual(obj.name, u'source-4') self.assertEqual(obj.name, 'source-4')
# Ensure source 4 is created, and everything else is as expected # Ensure source 4 is created, and everything else is as expected
queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset) serializer = NullableForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': None}, {'id': 3, 'name': 'source-3', 'target': None},
{'id': 4, 'name': u'source-4', 'target': None} {'id': 4, 'name': 'source-4', 'target': None}
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -196,27 +196,27 @@ class SlugNullableForeignKeyTests(TestCase): ...@@ -196,27 +196,27 @@ class SlugNullableForeignKeyTests(TestCase):
The emptystring should be interpreted as null in the context The emptystring should be interpreted as null in the context
of relationships. of relationships.
""" """
data = {'id': 4, 'name': u'source-4', 'target': ''} data = {'id': 4, 'name': 'source-4', 'target': ''}
expected_data = {'id': 4, 'name': u'source-4', 'target': None} expected_data = {'id': 4, 'name': 'source-4', 'target': None}
serializer = NullableForeignKeySourceSerializer(data=data) serializer = NullableForeignKeySourceSerializer(data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
obj = serializer.save() obj = serializer.save()
self.assertEquals(serializer.data, expected_data) self.assertEquals(serializer.data, expected_data)
self.assertEqual(obj.name, u'source-4') self.assertEqual(obj.name, 'source-4')
# Ensure source 4 is created, and everything else is as expected # Ensure source 4 is created, and everything else is as expected
queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset) serializer = NullableForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': 'target-1'}, {'id': 1, 'name': 'source-1', 'target': 'target-1'},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': None}, {'id': 3, 'name': 'source-3', 'target': None},
{'id': 4, 'name': u'source-4', 'target': None} {'id': 4, 'name': 'source-4', 'target': None}
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
def test_foreign_key_update_with_valid_null(self): def test_foreign_key_update_with_valid_null(self):
data = {'id': 1, 'name': u'source-1', 'target': None} data = {'id': 1, 'name': 'source-1', 'target': None}
instance = NullableForeignKeySource.objects.get(pk=1) instance = NullableForeignKeySource.objects.get(pk=1)
serializer = NullableForeignKeySourceSerializer(instance, data=data) serializer = NullableForeignKeySourceSerializer(instance, data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
...@@ -227,9 +227,9 @@ class SlugNullableForeignKeyTests(TestCase): ...@@ -227,9 +227,9 @@ class SlugNullableForeignKeyTests(TestCase):
queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset) serializer = NullableForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': None}, {'id': 1, 'name': 'source-1', 'target': None},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': None} {'id': 3, 'name': 'source-3', 'target': None}
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -238,8 +238,8 @@ class SlugNullableForeignKeyTests(TestCase): ...@@ -238,8 +238,8 @@ class SlugNullableForeignKeyTests(TestCase):
The emptystring should be interpreted as null in the context The emptystring should be interpreted as null in the context
of relationships. of relationships.
""" """
data = {'id': 1, 'name': u'source-1', 'target': ''} data = {'id': 1, 'name': 'source-1', 'target': ''}
expected_data = {'id': 1, 'name': u'source-1', 'target': None} expected_data = {'id': 1, 'name': 'source-1', 'target': None}
instance = NullableForeignKeySource.objects.get(pk=1) instance = NullableForeignKeySource.objects.get(pk=1)
serializer = NullableForeignKeySourceSerializer(instance, data=data) serializer = NullableForeignKeySourceSerializer(instance, data=data)
self.assertTrue(serializer.is_valid()) self.assertTrue(serializer.is_valid())
...@@ -250,8 +250,8 @@ class SlugNullableForeignKeyTests(TestCase): ...@@ -250,8 +250,8 @@ class SlugNullableForeignKeyTests(TestCase):
queryset = NullableForeignKeySource.objects.all() queryset = NullableForeignKeySource.objects.all()
serializer = NullableForeignKeySourceSerializer(queryset) serializer = NullableForeignKeySourceSerializer(queryset)
expected = [ expected = [
{'id': 1, 'name': u'source-1', 'target': None}, {'id': 1, 'name': 'source-1', 'target': None},
{'id': 2, 'name': u'source-2', 'target': 'target-1'}, {'id': 2, 'name': 'source-2', 'target': 'target-1'},
{'id': 3, 'name': u'source-3', 'target': None} {'id': 3, 'name': 'source-3', 'target': None}
] ]
self.assertEquals(serializer.data, expected) self.assertEquals(serializer.data, expected)
...@@ -236,17 +236,17 @@ class ValidationTests(TestCase): ...@@ -236,17 +236,17 @@ class ValidationTests(TestCase):
data = ['i am', 'a', 'list'] data = ['i am', 'a', 'list']
serializer = CommentSerializer(self.comment, data=data) serializer = CommentSerializer(self.comment, data=data)
self.assertEquals(serializer.is_valid(), False) self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']}) self.assertEquals(serializer.errors, {'non_field_errors': ['Invalid data']})
data = 'and i am a string' data = 'and i am a string'
serializer = CommentSerializer(self.comment, data=data) serializer = CommentSerializer(self.comment, data=data)
self.assertEquals(serializer.is_valid(), False) self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']}) self.assertEquals(serializer.errors, {'non_field_errors': ['Invalid data']})
data = 42 data = 42
serializer = CommentSerializer(self.comment, data=data) serializer = CommentSerializer(self.comment, data=data)
self.assertEquals(serializer.is_valid(), False) self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']}) self.assertEquals(serializer.errors, {'non_field_errors': ['Invalid data']})
def test_cross_field_validation(self): def test_cross_field_validation(self):
...@@ -300,7 +300,7 @@ class ValidationTests(TestCase): ...@@ -300,7 +300,7 @@ class ValidationTests(TestCase):
} }
serializer = ActionItemSerializerCustomRestore(data=data) serializer = ActionItemSerializerCustomRestore(data=data)
self.assertEquals(serializer.is_valid(), False) self.assertEquals(serializer.is_valid(), False)
self.assertEquals(serializer.errors, {'title': [u'Ensure this value has at most 200 characters (it has 201).']}) self.assertEquals(serializer.errors, {'title': ['Ensure this value has at most 200 characters (it has 201).']})
def test_default_modelfield_max_length_exceeded(self): def test_default_modelfield_max_length_exceeded(self):
data = { data = {
...@@ -340,7 +340,7 @@ class CustomValidationTests(TestCase): ...@@ -340,7 +340,7 @@ class CustomValidationTests(TestCase):
serializer = self.CommentSerializerWithFieldValidator(data=data) serializer = self.CommentSerializerWithFieldValidator(data=data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'content': [u'Test not in value']}) self.assertEquals(serializer.errors, {'content': ['Test not in value']})
def test_missing_data(self): def test_missing_data(self):
""" """
...@@ -352,7 +352,7 @@ class CustomValidationTests(TestCase): ...@@ -352,7 +352,7 @@ class CustomValidationTests(TestCase):
} }
serializer = self.CommentSerializerWithFieldValidator(data=incomplete_data) serializer = self.CommentSerializerWithFieldValidator(data=incomplete_data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'content': [u'This field is required.']}) self.assertEquals(serializer.errors, {'content': ['This field is required.']})
def test_wrong_data(self): def test_wrong_data(self):
""" """
...@@ -365,7 +365,7 @@ class CustomValidationTests(TestCase): ...@@ -365,7 +365,7 @@ class CustomValidationTests(TestCase):
} }
serializer = self.CommentSerializerWithFieldValidator(data=wrong_data) serializer = self.CommentSerializerWithFieldValidator(data=wrong_data)
self.assertFalse(serializer.is_valid()) self.assertFalse(serializer.is_valid())
self.assertEquals(serializer.errors, {'email': [u'Enter a valid e-mail address.']}) self.assertEquals(serializer.errors, {'email': ['Enter a valid e-mail address.']})
class PositiveIntegerAsChoiceTests(TestCase): class PositiveIntegerAsChoiceTests(TestCase):
......
from django.test.client import RequestFactory, FakePayload from django.test.client import RequestFactory, FakePayload
from django.test.client import MULTIPART_CONTENT from django.test.client import MULTIPART_CONTENT
from urlparse import urlparse from rest_framework.compat import urlparse
class RequestFactory(RequestFactory): class RequestFactory(RequestFactory):
...@@ -14,7 +14,7 @@ class RequestFactory(RequestFactory): ...@@ -14,7 +14,7 @@ class RequestFactory(RequestFactory):
patch_data = self._encode_data(data, content_type) patch_data = self._encode_data(data, content_type)
parsed = urlparse(path) parsed = urlparse.urlparse(path)
r = { r = {
'CONTENT_LENGTH': len(patch_data), 'CONTENT_LENGTH': len(patch_data),
'CONTENT_TYPE': content_type, 'CONTENT_TYPE': content_type,
......
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
# raise errors on unexpected request data""" # raise errors on unexpected request data"""
# content = {'qwerty': 'uiop', 'extra': 'extra'} # content = {'qwerty': 'uiop', 'extra': 'extra'}
# validator.allow_unknown_form_fields = True # validator.allow_unknown_form_fields = True
# self.assertEqual({'qwerty': u'uiop'}, # self.assertEqual({'qwerty': 'uiop'},
# validator.validate_request(content, None), # validator.validate_request(content, None),
# "Resource didn't accept unknown fields.") # "Resource didn't accept unknown fields.")
# validator.allow_unknown_form_fields = False # validator.allow_unknown_form_fields = False
......
[tox] [tox]
downloadcache = {toxworkdir}/cache/ downloadcache = {toxworkdir}/cache/
envlist = py2.7-django1.5,py2.7-django1.4,py2.7-django1.3,py2.6-django1.5,py2.6-django1.4,py2.6-django1.3 envlist = py3.3-django1.5,py3.2-django1.5,py2.7-django1.5,py2.7-django1.4,py2.7-django1.3,py2.6-django1.5,py2.6-django1.4,py2.6-django1.3
[testenv] [testenv]
commands = {envpython} rest_framework/runtests/runtests.py commands = {envpython} rest_framework/runtests/runtests.py
[testenv:py2.7-django1.5] [testenv:py3.3-django1.5]
basepython = python2.7 basepython = python3.3
deps = https://github.com/django/django/zipball/master deps = https://www.djangoproject.com/download/1.5c1/tarball/
django-filter==0.5.4 django-filter==0.5.4
[testenv:py2.7-django1.4] [testenv:py3.2-django1.5]
basepython = python2.7 basepython = python3.2
deps = django==1.4.3 deps = https://www.djangoproject.com/download/1.5c1/tarball/
django-filter==0.5.4 django-filter==0.5.4
[testenv:py2.7-django1.3] [testenv:py2.7-django1.5]
basepython = python2.7 basepython = python2.7
deps = django==1.3.5 deps = https://www.djangoproject.com/download/1.5c1/tarball/
django-filter==0.5.4 django-filter==0.5.4
[testenv:py2.6-django1.5] [testenv:py2.6-django1.5]
basepython = python2.6 basepython = python2.6
deps = https://github.com/django/django/zipball/master deps = https://www.djangoproject.com/download/1.5c1/tarball/
django-filter==0.5.4
[testenv:py2.7-django1.4]
basepython = python2.7
deps = django==1.4.3
django-filter==0.5.4 django-filter==0.5.4
[testenv:py2.6-django1.4] [testenv:py2.6-django1.4]
...@@ -30,7 +35,14 @@ basepython = python2.6 ...@@ -30,7 +35,14 @@ basepython = python2.6
deps = django==1.4.3 deps = django==1.4.3
django-filter==0.5.4 django-filter==0.5.4
[testenv:py2.7-django1.3]
basepython = python2.7
deps = django==1.3.5
django-filter==0.5.4
six
[testenv:py2.6-django1.3] [testenv:py2.6-django1.3]
basepython = python2.6 basepython = python2.6
deps = django==1.3.5 deps = django==1.3.5
django-filter==0.5.4 django-filter==0.5.4
six
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment