mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-10 19:56:59 +03:00
3.2, 3.3 compat
This commit is contained in:
parent
d9c7b1c585
commit
f4f237e3ee
|
@ -1,3 +1,6 @@
|
||||||
__version__ = '2.1.17'
|
__version__ = '2.1.17'
|
||||||
|
|
||||||
VERSION = __version__ # synonym
|
VERSION = __version__ # synonym
|
||||||
|
|
||||||
|
# Header encoding (see RFC5987)
|
||||||
|
HTTP_HEADER_ENCODING = 'iso-8859-1'
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
"""
|
"""
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
"""
|
"""
|
||||||
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):
|
||||||
"""
|
"""
|
||||||
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 = {
|
||||||
'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',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
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):
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
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):
|
||||||
}
|
}
|
||||||
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):
|
||||||
|
|
||||||
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):
|
||||||
}
|
}
|
||||||
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):
|
||||||
}
|
}
|
||||||
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):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
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):
|
||||||
|
|
||||||
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 @@
|
||||||
# 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
|
||||||
|
|
36
tox.ini
36
tox.ini
|
@ -1,13 +1,28 @@
|
||||||
[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:py3.3-django1.5]
|
||||||
|
basepython = python3.3
|
||||||
|
deps = https://www.djangoproject.com/download/1.5c1/tarball/
|
||||||
|
django-filter==0.5.4
|
||||||
|
|
||||||
|
[testenv:py3.2-django1.5]
|
||||||
|
basepython = python3.2
|
||||||
|
deps = https://www.djangoproject.com/download/1.5c1/tarball/
|
||||||
|
django-filter==0.5.4
|
||||||
|
|
||||||
[testenv:py2.7-django1.5]
|
[testenv:py2.7-django1.5]
|
||||||
basepython = python2.7
|
basepython = python2.7
|
||||||
deps = https://github.com/django/django/zipball/master
|
deps = https://www.djangoproject.com/download/1.5c1/tarball/
|
||||||
|
django-filter==0.5.4
|
||||||
|
|
||||||
|
[testenv:py2.6-django1.5]
|
||||||
|
basepython = python2.6
|
||||||
|
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:py2.7-django1.4]
|
||||||
|
@ -15,22 +30,19 @@ basepython = python2.7
|
||||||
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
|
|
||||||
|
|
||||||
[testenv:py2.6-django1.5]
|
|
||||||
basepython = python2.6
|
|
||||||
deps = https://github.com/django/django/zipball/master
|
|
||||||
django-filter==0.5.4
|
|
||||||
|
|
||||||
[testenv:py2.6-django1.4]
|
[testenv:py2.6-django1.4]
|
||||||
basepython = python2.6
|
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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user