Author: russellm
Date: 2009-04-11 04:20:10 -0500 (Sat, 11 Apr 2009)
New Revision: 10513

Modified:
   django/trunk/AUTHORS
   django/trunk/django/test/client.py
   django/trunk/tests/regressiontests/test_client_regress/models.py
   django/trunk/tests/regressiontests/test_client_regress/urls.py
   django/trunk/tests/regressiontests/test_client_regress/views.py
Log:
Fixed #10571 -- Ensured that unicode POST data is correctly encoded by the test 
client. Thanks to Rick Wagner for his help identifying and fixing this problem.

Modified: django/trunk/AUTHORS
===================================================================
--- django/trunk/AUTHORS        2009-04-11 07:52:07 UTC (rev 10512)
+++ django/trunk/AUTHORS        2009-04-11 09:20:10 UTC (rev 10513)
@@ -436,6 +436,7 @@
     Vlado <[email protected]>
     Milton Waddams
     Chris Wagner <[email protected]>
+    Rick Wagner <[email protected]>
     [email protected]
     Wang Chun <[email protected]>
     Filip Wasilewski <[email protected]>

Modified: django/trunk/django/test/client.py
===================================================================
--- django/trunk/django/test/client.py  2009-04-11 07:52:07 UTC (rev 10512)
+++ django/trunk/django/test/client.py  2009-04-11 09:20:10 UTC (rev 10513)
@@ -2,6 +2,7 @@
 from urlparse import urlparse, urlunparse, urlsplit
 import sys
 import os
+import re
 try:
     from cStringIO import StringIO
 except ImportError:
@@ -25,8 +26,8 @@
 
 BOUNDARY = 'BoUnDaRyStRiNg'
 MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
+CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?')
 
-
 class FakePayload(object):
     """
     A wrapper around StringIO that restricts what can be read since data from
@@ -290,7 +291,13 @@
         if content_type is MULTIPART_CONTENT:
             post_data = encode_multipart(BOUNDARY, data)
         else:
-            post_data = data
+            # Encode the content so that the byte representation is correct.
+            match = CONTENT_TYPE_RE.match(content_type)
+            if match:
+                charset = match.group(1)
+            else:
+                charset = settings.DEFAULT_CHARSET
+            post_data = smart_str(data, encoding=charset)
 
         parsed = urlparse(path)
         r = {

Modified: django/trunk/tests/regressiontests/test_client_regress/models.py
===================================================================
--- django/trunk/tests/regressiontests/test_client_regress/models.py    
2009-04-11 07:52:07 UTC (rev 10512)
+++ django/trunk/tests/regressiontests/test_client_regress/models.py    
2009-04-11 09:20:10 UTC (rev 10513)
@@ -624,3 +624,36 @@
         self.assertEqual(response.context['post-bar'], 'bang')
         self.assertEqual(response.context['request-foo'], 'whiz')
         self.assertEqual(response.context['request-bar'], 'bang')
+
+class UnicodePayloadTests(TestCase):
+    def test_simple_unicode_payload(self):
+        "A simple ASCII-only unicode JSON document can be POSTed"
+        # Regression test for #10571
+        json = u'{"english": "mountain pass"}'
+        response = 
self.client.post("/test_client_regress/parse_unicode_json/", json,
+                                    content_type="application/json")
+        self.assertEqual(response.content, json)
+
+    def test_unicode_payload_utf8(self):
+        "A non-ASCII unicode data encoded as UTF-8 can be POSTed"
+        # Regression test for #10571
+        json = u'{"dog": "собака"}'
+        response = 
self.client.post("/test_client_regress/parse_unicode_json/", json,
+                                    content_type="application/json; 
charset=utf-8")
+        self.assertEqual(response.content, json.encode('utf-8'))
+
+    def test_unicode_payload_utf16(self):
+        "A non-ASCII unicode data encoded as UTF-16 can be POSTed"
+        # Regression test for #10571
+        json = u'{"dog": "собака"}'
+        response = 
self.client.post("/test_client_regress/parse_unicode_json/", json,
+                                    content_type="application/json; 
charset=utf-16")
+        self.assertEqual(response.content, json.encode('utf-16'))
+
+    def test_unicode_payload_non_utf(self):
+        "A non-ASCII unicode data as a non-UTF based encoding can be POSTed"
+        #Regression test for #10571
+        json = u'{"dog": "собака"}'
+        response = 
self.client.post("/test_client_regress/parse_unicode_json/", json,
+                                    content_type="application/json; 
charset=koi8-r")
+        self.assertEqual(response.content, json.encode('koi8-r'))

Modified: django/trunk/tests/regressiontests/test_client_regress/urls.py
===================================================================
--- django/trunk/tests/regressiontests/test_client_regress/urls.py      
2009-04-11 07:52:07 UTC (rev 10512)
+++ django/trunk/tests/regressiontests/test_client_regress/urls.py      
2009-04-11 09:20:10 UTC (rev 10513)
@@ -23,4 +23,5 @@
     (r'^check_session/$', views.check_session_view),
     (r'^request_methods/$', views.request_methods_view),
     (r'^check_unicode/$', views.return_unicode),
+    (r'^parse_unicode_json/$', views.return_json_file),
 )

Modified: django/trunk/tests/regressiontests/test_client_regress/views.py
===================================================================
--- django/trunk/tests/regressiontests/test_client_regress/views.py     
2009-04-11 07:52:07 UTC (rev 10512)
+++ django/trunk/tests/regressiontests/test_client_regress/views.py     
2009-04-11 09:20:10 UTC (rev 10513)
@@ -1,3 +1,4 @@
+from django.conf import settings
 from django.contrib.auth.decorators import login_required
 from django.http import HttpResponse, HttpResponseRedirect
 from django.core.exceptions import SuspiciousOperation
@@ -2,2 +3,6 @@
 from django.shortcuts import render_to_response
+from django.utils import simplejson
+from django.utils.encoding import smart_str
+from django.core.serializers.json import DjangoJSONEncoder
+from django.test.client import CONTENT_TYPE_RE
 
@@ -63,3 +68,21 @@
 
 def return_unicode(request):
     return render_to_response('unicode.html')
+
+def return_json_file(request):
+    "A view that parses and returns a JSON string as a file."
+    match = CONTENT_TYPE_RE.match(request.META['CONTENT_TYPE'])
+    if match:
+        charset = match.group(1)
+    else:
+        charset = settings.DEFAULT_CHARSET
+
+    # This just checks that the uploaded data is JSON
+    obj_dict = simplejson.loads(request.raw_post_data.decode(charset))
+    obj_json = simplejson.dumps(obj_dict, encoding=charset,
+                                cls=DjangoJSONEncoder,
+                                ensure_ascii=False)
+    response = HttpResponse(smart_str(obj_json, encoding=charset), status=200,
+                            mimetype='application/json; charset=' + charset)
+    response['Content-Disposition'] = 'attachment; filename=testfile.json'
+    return response


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to