Hi, I tried to post this to trac, but it was rejected as potential
ticket spam.

At present BrowsingSession.response is an str object, rather than a
unicode object.  In writing unit tests it is often necessary to test for
the presence of a substring within the response, but if the substring is
a unicode object, then Python will try to decode the response using the
ASCII codec, which will fail if any character in the response is not in
ASCII, resulting in the dread UnicodeDecodeError.

The attached patch against the 1.0 branch adds a unicode_response field
to the browsing session object if an encoding is specified in the
Content-Type header.  Tests can use this much more safely.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" 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/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Index: turbogears/tests/test_testutil.py
===================================================================
--- turbogears/tests/test_testutil.py	(revision 4353)
+++ turbogears/tests/test_testutil.py	(working copy)
@@ -19,6 +19,11 @@
             return "cookie not found"
     get_name = turbogears.expose()(get_name)
 
+    def get_unicode_name(self):
+        """Return a nonsense string of non-ascii characters"""
+        cherrypy.response.headers['Content-Type'] = 'text/plain; encoding=utf-8'
+        return u'\u1234\u9876\u3456'.encode('utf-8')
+    get_unicode_name = turbogears.expose()(get_unicode_name)
 
 def test_browser_session():
     cherrypy.root = MyRoot()
@@ -39,3 +44,11 @@
     assert bs1.response == 'bs1'
     bs2.goto('/get_name')
     assert bs2.response == 'bs2'
+
+def test_unicode_response():
+    cherrypy.root = MyRoot()
+    bs = testutil.BrowsingSession()
+    bs.goto('/get_unicode_name')
+    assert bs.response == u'\u1234\u9876\u3456'.encode('utf-8')
+    assert bs.unicode_response == u'\u1234\u9876\u3456'
+    assert type(bs.unicode_response) == unicode
Index: turbogears/testutil.py
===================================================================
--- turbogears/testutil.py	(revision 4353)
+++ turbogears/testutil.py	(working copy)
@@ -107,6 +107,18 @@
             headers = kwargs.setdefault('headers', {})
             headers['Cookie'] = self.cookie.output()
         create_request(*args, **kwargs)
+        # If we were given an encoding in the content type we should use it to
+        # decode the response:
+        ctype_parts = cherrypy.response.headers['Content-Type'].split(';')
+        for parameter in ctype_parts[1:]:
+            attribute, value = parameter.strip().split('=')
+            try:
+                self.unicode_response = cherrypy.response.body[0].decode(value)
+                break
+            except:
+                # If the named encoding doesn't work then it doesn't work.  We
+                # just won't create the unicode_response field.
+                pass
         self.response = cherrypy.response.body[0]
         self.status = cherrypy.response.status
         if cherrypy.response.simple_cookie:

Reply via email to