Decoupled test client encoding tests from JSON handling
Using JSON as non-UTF-8 content is controversial, and the RFC 7159 discourages it. Thanks Tim Graham for the review.
This commit is contained in:
parent
c577d8a498
commit
29592eef19
|
@ -1268,35 +1268,32 @@ class QueryStringTests(SimpleTestCase):
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='test_client_regress.urls')
|
@override_settings(ROOT_URLCONF='test_client_regress.urls')
|
||||||
class UnicodePayloadTests(SimpleTestCase):
|
class PayloadEncodingTests(SimpleTestCase):
|
||||||
|
"""Regression tests for #10571."""
|
||||||
|
|
||||||
def test_simple_unicode_payload(self):
|
def test_simple_payload(self):
|
||||||
"A simple ASCII-only JSON document can be POSTed"
|
"""A simple ASCII-only text can be POSTed."""
|
||||||
# Regression test for #10571
|
text = 'English: mountain pass'
|
||||||
json_str = '{"english": "mountain pass"}'
|
response = self.client.post('/parse_encoded_text/', text, content_type='text/plain')
|
||||||
response = self.client.post("/parse_unicode_json/", json_str, content_type="application/json")
|
self.assertEqual(response.content, text.encode())
|
||||||
self.assertEqual(response.content, json_str.encode())
|
|
||||||
|
|
||||||
def test_unicode_payload_utf8(self):
|
def test_utf8_payload(self):
|
||||||
"A non-ASCII unicode data encoded as UTF-8 can be POSTed"
|
"""Non-ASCII data encoded as UTF-8 can be POSTed."""
|
||||||
# Regression test for #10571
|
text = 'dog: собака'
|
||||||
json_str = '{"dog": "собака"}'
|
response = self.client.post('/parse_encoded_text/', text, content_type='text/plain; charset=utf-8')
|
||||||
response = self.client.post("/parse_unicode_json/", json_str, content_type="application/json; charset=utf-8")
|
self.assertEqual(response.content, text.encode())
|
||||||
self.assertEqual(response.content, json_str.encode())
|
|
||||||
|
|
||||||
def test_unicode_payload_utf16(self):
|
def test_utf16_payload(self):
|
||||||
"A non-ASCII unicode data encoded as UTF-16 can be POSTed"
|
"""Non-ASCII data encoded as UTF-16 can be POSTed."""
|
||||||
# Regression test for #10571
|
text = 'dog: собака'
|
||||||
json_str = '{"dog": "собака"}'
|
response = self.client.post('/parse_encoded_text/', text, content_type='text/plain; charset=utf-16')
|
||||||
response = self.client.post("/parse_unicode_json/", json_str, content_type="application/json; charset=utf-16")
|
self.assertEqual(response.content, text.encode('utf-16'))
|
||||||
self.assertEqual(response.content, json_str.encode('utf-16'))
|
|
||||||
|
|
||||||
def test_unicode_payload_non_utf(self):
|
def test_non_utf_payload(self):
|
||||||
"A non-ASCII unicode data as a non-UTF based encoding can be POSTed"
|
"""Non-ASCII data as a non-UTF based encoding can be POSTed."""
|
||||||
# Regression test for #10571
|
text = 'dog: собака'
|
||||||
json_str = '{"dog": "собака"}'
|
response = self.client.post('/parse_encoded_text/', text, content_type='text/plain; charset=koi8-r')
|
||||||
response = self.client.post("/parse_unicode_json/", json_str, content_type="application/json; charset=koi8-r")
|
self.assertEqual(response.content, text.encode('koi8-r'))
|
||||||
self.assertEqual(response.content, json_str.encode('koi8-r'))
|
|
||||||
|
|
||||||
|
|
||||||
class DummyFile:
|
class DummyFile:
|
||||||
|
|
|
@ -31,7 +31,7 @@ urlpatterns = [
|
||||||
url(r'^check_unicode/$', views.return_unicode),
|
url(r'^check_unicode/$', views.return_unicode),
|
||||||
url(r'^check_binary/$', views.return_undecodable_binary),
|
url(r'^check_binary/$', views.return_undecodable_binary),
|
||||||
url(r'^json_response/$', views.return_json_response),
|
url(r'^json_response/$', views.return_json_response),
|
||||||
url(r'^parse_unicode_json/$', views.return_json_file),
|
url(r'^parse_encoded_text/$', views.return_text_file),
|
||||||
url(r'^check_headers/$', views.check_headers),
|
url(r'^check_headers/$', views.check_headers),
|
||||||
url(r'^check_headers_redirect/$', RedirectView.as_view(url='/check_headers/')),
|
url(r'^check_headers_redirect/$', RedirectView.as_view(url='/check_headers/')),
|
||||||
url(r'^body/$', views.body),
|
url(r'^body/$', views.body),
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import json
|
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
|
||||||
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
|
@ -111,20 +109,15 @@ def return_json_response(request):
|
||||||
return JsonResponse({'key': 'value'}, **kwargs)
|
return JsonResponse({'key': 'value'}, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def return_json_file(request):
|
def return_text_file(request):
|
||||||
"A view that parses and returns a JSON string as a file."
|
"A view that parses and returns text as a file."
|
||||||
match = CONTENT_TYPE_RE.match(request.META['CONTENT_TYPE'])
|
match = CONTENT_TYPE_RE.match(request.META['CONTENT_TYPE'])
|
||||||
if match:
|
if match:
|
||||||
charset = match.group(1)
|
charset = match.group(1)
|
||||||
else:
|
else:
|
||||||
charset = settings.DEFAULT_CHARSET
|
charset = settings.DEFAULT_CHARSET
|
||||||
|
|
||||||
# This just checks that the uploaded data is JSON
|
response = HttpResponse(request.body, status=200, content_type='text/plain; charset=%s' % charset)
|
||||||
obj_dict = json.loads(request.body.decode(charset))
|
|
||||||
obj_json = json.dumps(obj_dict, cls=DjangoJSONEncoder, ensure_ascii=False)
|
|
||||||
response = HttpResponse(obj_json.encode(charset), status=200,
|
|
||||||
content_type='application/json; charset=%s' % charset)
|
|
||||||
response['Content-Disposition'] = 'attachment; filename=testfile.json'
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue