Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
4a21b355
Commit
4a21b355
authored
Oct 08, 2012
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix fiddly content-overloading bug
parent
b581ffe3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
142 deletions
+99
-142
rest_framework/request.py
+3
-5
rest_framework/tests/request.py
+13
-9
rest_framework/tests/views.py
+83
-128
No files found.
rest_framework/request.py
View file @
4a21b355
...
...
@@ -227,16 +227,14 @@ class Request(object):
self
.
_method
=
self
.
_data
[
self
.
_METHOD_PARAM
]
.
upper
()
self
.
_data
.
pop
(
self
.
_METHOD_PARAM
)
# Content overloading - modify the content type, and re-parse.
# Content overloading - modify the content type, and
force
re-parse.
if
(
self
.
_CONTENT_PARAM
and
self
.
_CONTENTTYPE_PARAM
and
self
.
_CONTENT_PARAM
in
self
.
_data
and
self
.
_CONTENTTYPE_PARAM
in
self
.
_data
):
self
.
_content_type
=
self
.
_data
[
self
.
_CONTENTTYPE_PARAM
]
self
.
_stream
=
StringIO
(
self
.
_data
[
self
.
_CONTENT_PARAM
])
self
.
_data
.
pop
(
self
.
_CONTENTTYPE_PARAM
)
self
.
_data
.
pop
(
self
.
_CONTENT_PARAM
)
self
.
_data
,
self
.
_files
=
self
.
_parse
()
self
.
_data
,
self
.
_files
=
(
Empty
,
Empty
)
def
_parse
(
self
):
"""
...
...
@@ -250,7 +248,7 @@ class Request(object):
parser
=
self
.
negotiator
.
select_parser
(
self
.
parsers
,
self
.
content_type
)
if
not
parser
:
raise
exceptions
.
UnsupportedMediaType
(
self
.
_
content_type
)
raise
exceptions
.
UnsupportedMediaType
(
self
.
content_type
)
parsed
=
parser
.
parse
(
self
.
stream
,
meta
=
self
.
META
,
upload_handlers
=
self
.
upload_handlers
)
...
...
rest_framework/tests/request.py
View file @
4a21b355
...
...
@@ -4,6 +4,7 @@ Tests for content parsing, and form-overloaded content parsing.
from
django.conf.urls.defaults
import
patterns
from
django.contrib.auth.models
import
User
from
django.test
import
TestCase
,
Client
from
django.utils
import
simplejson
as
json
from
rest_framework
import
status
from
rest_framework.authentication
import
SessionAuthentication
...
...
@@ -12,9 +13,11 @@ from rest_framework.parsers import (
FormParser
,
MultiPartParser
,
PlainTextParser
,
JSONParser
)
from
rest_framework.request
import
Request
from
rest_framework.response
import
Response
from
rest_framework.settings
import
api_settings
from
rest_framework.views
import
APIView
...
...
@@ -36,7 +39,7 @@ class TestMethodOverloading(TestCase):
POST requests can be overloaded to another method by setting a
reserved form field
"""
request
=
Request
(
factory
.
post
(
'/'
,
{
Request
.
_METHOD_PARAM
:
'DELETE'
}))
request
=
Request
(
factory
.
post
(
'/'
,
{
api_settings
.
FORM_METHOD_OVERRIDE
:
'DELETE'
}))
self
.
assertEqual
(
request
.
method
,
'DELETE'
)
...
...
@@ -117,15 +120,16 @@ class TestContentParsing(TestCase):
"""
Ensure request.DATA returns content for overloaded POST request.
"""
content
=
'qwerty'
content_type
=
'text/plain'
data
=
{
Request
.
_CONTENT_PARAM
:
content
,
Request
.
_CONTENTTYPE_PARAM
:
content_type
json_data
=
{
'foobar'
:
'qwerty'
}
content
=
json
.
dumps
(
json_data
)
content_type
=
'application/json'
form_data
=
{
api_settings
.
FORM_CONTENT_OVERRIDE
:
content
,
api_settings
.
FORM_CONTENTTYPE_OVERRIDE
:
content_type
}
request
=
Request
(
factory
.
post
(
'/'
,
data
))
request
.
parsers
=
(
PlainText
Parser
(),
)
self
.
assertEqual
(
request
.
DATA
,
content
)
request
=
Request
(
factory
.
post
(
'/'
,
form_
data
))
request
.
parsers
=
(
JSON
Parser
(),
)
self
.
assertEqual
(
request
.
DATA
,
json_data
)
# def test_accessing_post_after_data_form(self):
# """
...
...
rest_framework/tests/views.py
View file @
4a21b355
# from django.core.urlresolvers import reverse
# from django.conf.urls.defaults import patterns, url, include
# from django.http import HttpResponse
# from django.test import TestCase
# from django.utils import simplejson as json
# from rest_framework.views import View
# class MockView(View):
# """This is a basic mock view"""
# pass
# class MockViewFinal(View):
# """View with final() override"""
# def final(self, request, response, *args, **kwargs):
# return HttpResponse('{"test": "passed"}', content_type="application/json")
# # class ResourceMockView(View):
# # """This is a resource-based mock view"""
# # class MockForm(forms.Form):
# # foo = forms.BooleanField(required=False)
# # bar = forms.IntegerField(help_text='Must be an integer.')
# # baz = forms.CharField(max_length=32)
# # form = MockForm
# # class MockResource(ModelResource):
# # """This is a mock model-based resource"""
# # class MockResourceModel(models.Model):
# # foo = models.BooleanField()
# # bar = models.IntegerField(help_text='Must be an integer.')
# # baz = models.CharField(max_length=32, help_text='Free text. Max length 32 chars.')
# # model = MockResourceModel
# # fields = ('foo', 'bar', 'baz')
# urlpatterns = patterns('',
# url(r'^mock/$', MockView.as_view()),
# url(r'^mock/final/$', MockViewFinal.as_view()),
# # url(r'^resourcemock/$', ResourceMockView.as_view()),
# # url(r'^model/$', ListOrCreateModelView.as_view(resource=MockResource)),
# # url(r'^model/(?P<pk>[^/]+)/$', InstanceModelView.as_view(resource=MockResource)),
# url(r'^restframework/', include('rest_framework.urls', namespace='rest_framework')),
# )
# class BaseViewTests(TestCase):
# """Test the base view class of rest_framework"""
# urls = 'rest_framework.tests.views'
# def test_view_call_final(self):
# response = self.client.options('/mock/final/')
# self.assertEqual(response['Content-Type'].split(';')[0], "application/json")
# data = json.loads(response.content)
# self.assertEqual(data['test'], 'passed')
# def test_options_method_simple_view(self):
# response = self.client.options('/mock/')
# self._verify_options_response(response,
# name='Mock',
# description='This is a basic mock view')
# def test_options_method_resource_view(self):
# response = self.client.options('/resourcemock/')
# self._verify_options_response(response,
# name='Resource Mock',
# description='This is a resource-based mock view',
# fields={'foo': 'BooleanField',
# 'bar': 'IntegerField',
# 'baz': 'CharField',
# })
# def test_options_method_model_resource_list_view(self):
# response = self.client.options('/model/')
# self._verify_options_response(response,
# name='Mock List',
# description='This is a mock model-based resource',
# fields={'foo': 'BooleanField',
# 'bar': 'IntegerField',
# 'baz': 'CharField',
# })
# def test_options_method_model_resource_detail_view(self):
# response = self.client.options('/model/0/')
# self._verify_options_response(response,
# name='Mock Instance',
# description='This is a mock model-based resource',
# fields={'foo': 'BooleanField',
# 'bar': 'IntegerField',
# 'baz': 'CharField',
# })
# def _verify_options_response(self, response, name, description, fields=None, status=200,
# mime_type='application/json'):
# self.assertEqual(response.status_code, status)
# self.assertEqual(response['Content-Type'].split(';')[0], mime_type)
# data = json.loads(response.content)
# self.assertTrue('application/json' in data['renders'])
# self.assertEqual(name, data['name'])
# self.assertEqual(description, data['description'])
# if fields is None:
# self.assertFalse(hasattr(data, 'fields'))
# else:
# self.assertEqual(data['fields'], fields)
# class ExtraViewsTests(TestCase):
# """Test the extra views rest_framework provides"""
# urls = 'rest_framework.tests.views'
# def test_login_view(self):
# """Ensure the login view exists"""
# response = self.client.get(reverse('rest_framework:login'))
# self.assertEqual(response.status_code, 200)
# self.assertEqual(response['Content-Type'].split(';')[0], 'text/html')
# def test_logout_view(self):
# """Ensure the logout view exists"""
# response = self.client.get(reverse('rest_framework:logout'))
# self.assertEqual(response.status_code, 200)
# self.assertEqual(response['Content-Type'].split(';')[0], 'text/html')
from
django.test
import
TestCase
from
django.test.client
import
RequestFactory
from
rest_framework
import
status
from
rest_framework.decorators
import
api_view
from
rest_framework.response
import
Response
from
rest_framework.settings
import
api_settings
from
rest_framework.views
import
APIView
factory
=
RequestFactory
()
class
BasicView
(
APIView
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
return
Response
({
'method'
:
'GET'
})
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
return
Response
({
'method'
:
'POST'
,
'data'
:
request
.
DATA
})
@api_view
([
'GET'
,
'POST'
])
def
basic_view
(
request
):
if
request
.
method
==
'GET'
:
return
{
'method'
:
'GET'
}
elif
request
.
method
==
'POST'
:
return
{
'method'
:
'POST'
,
'data'
:
request
.
DATA
}
class
ClassBasedViewIntegrationTests
(
TestCase
):
def
setUp
(
self
):
self
.
view
=
BasicView
.
as_view
()
def
test_400_parse_error
(
self
):
request
=
factory
.
post
(
'/'
,
'f00bar'
,
content_type
=
'application/json'
)
response
=
self
.
view
(
request
)
expected
=
{
'detail'
:
u'JSON parse error - No JSON object could be decoded'
}
self
.
assertEquals
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
self
.
assertEquals
(
response
.
data
,
expected
)
def
test_400_parse_error_tunneled_content
(
self
):
content
=
'f00bar'
content_type
=
'application/json'
form_data
=
{
api_settings
.
FORM_CONTENT_OVERRIDE
:
content
,
api_settings
.
FORM_CONTENTTYPE_OVERRIDE
:
content_type
}
request
=
factory
.
post
(
'/'
,
form_data
)
response
=
self
.
view
(
request
)
expected
=
{
'detail'
:
u'JSON parse error - No JSON object could be decoded'
}
self
.
assertEquals
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
self
.
assertEquals
(
response
.
data
,
expected
)
class
FunctionBasedViewIntegrationTests
(
TestCase
):
def
setUp
(
self
):
self
.
view
=
basic_view
def
test_400_parse_error
(
self
):
request
=
factory
.
post
(
'/'
,
'f00bar'
,
content_type
=
'application/json'
)
response
=
self
.
view
(
request
)
expected
=
{
'detail'
:
u'JSON parse error - No JSON object could be decoded'
}
self
.
assertEquals
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
self
.
assertEquals
(
response
.
data
,
expected
)
def
test_400_parse_error_tunneled_content
(
self
):
content
=
'f00bar'
content_type
=
'application/json'
form_data
=
{
api_settings
.
FORM_CONTENT_OVERRIDE
:
content
,
api_settings
.
FORM_CONTENTTYPE_OVERRIDE
:
content_type
}
request
=
factory
.
post
(
'/'
,
form_data
)
response
=
self
.
view
(
request
)
expected
=
{
'detail'
:
u'JSON parse error - No JSON object could be decoded'
}
self
.
assertEquals
(
response
.
status_code
,
status
.
HTTP_400_BAD_REQUEST
)
self
.
assertEquals
(
response
.
data
,
expected
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment