[Checkins] SVN: Zope/branches/tseaver-fix_wsgi/src/ZPublisher/ Partial coverage for setBody.

Tres Seaver tseaver at palladion.com
Mon Dec 21 17:28:16 EST 2009


Log message for revision 106839:
  Partial coverage for setBody.

Changed:
  U   Zope/branches/tseaver-fix_wsgi/src/ZPublisher/HTTPResponse.py
  U   Zope/branches/tseaver-fix_wsgi/src/ZPublisher/tests/testHTTPResponse.py

-=-
Modified: Zope/branches/tseaver-fix_wsgi/src/ZPublisher/HTTPResponse.py
===================================================================
--- Zope/branches/tseaver-fix_wsgi/src/ZPublisher/HTTPResponse.py	2009-12-21 22:21:33 UTC (rev 106838)
+++ Zope/branches/tseaver-fix_wsgi/src/ZPublisher/HTTPResponse.py	2009-12-21 22:28:15 UTC (rev 106839)
@@ -424,21 +424,31 @@
                 r'(iso[-_]8859[-_]1(:1987)?)))?$',re.I).match,
                 lock=None
                 ):
-        '''\
-        Set the body of the response
+        """ Set the body of the response
 
         Sets the return body equal to the (string) argument "body". Also
         updates the "content-length" return header.
 
+        If the body is already locked via a previous call, do nothing and
+        return None.
+
         You can also specify a title, in which case the title and body
         will be wrapped up in html, head, title, and body tags.
 
         If the body is a 2-element tuple, then it will be treated
         as (title,body)
 
-        If is_error is true then the HTML will be formatted as a Zope error
-        message instead of a generic HTML page.
-        '''
+        If body is unicode, encode it.
+
+        If body is not a string or unicode, but has an 'asHTML' method, use
+        the result of that method as the body;  otherwise, use the 'str'
+        of body.
+
+        If is_error is true, format the HTML as a Zope error message instead
+        of a generic HTML page.
+
+        Return 'self' (XXX as a true value?).
+        """
         # allow locking of the body in the same way as the status
         if self._locked_body:
             return
@@ -470,7 +480,7 @@
             bogus_str_search(body) is not None):
             self.notFoundError(body[1:-1])
         else:
-            if(title):
+            if title:
                 title = str(title)
                 if not is_error:
                     self.body = self._html(title, body)
@@ -480,18 +490,17 @@
                 self.body = body
 
 
-        isHTML = self.isHTML(self.body)
-        if not self.headers.has_key('content-type'):
-            if isHTML:
-                c = 'text/html; charset=%s' % default_encoding
+        ct = self.headers.get('content-type')
+        if ct is None:
+            if self.isHTML(self.body):
+                ct = 'text/html; charset=%s' % default_encoding
             else:
-                c = 'text/plain; charset=%s' % default_encoding
-            self.setHeader('content-type', c)
+                ct = 'text/plain; charset=%s' % default_encoding
+            self.setHeader('content-type', ct)
         else:
-            c = self.headers['content-type']
-            if c.startswith('text/') and not 'charset=' in  c:
-                c = '%s; charset=%s' % (c, default_encoding)                
-                self.setHeader('content-type', c)
+            if ct.startswith('text/') and not 'charset=' in  ct:
+                ct = '%s; charset=%s' % (ct, default_encoding)                
+                self.setHeader('content-type', ct)
 
         # Some browsers interpret certain characters in Latin 1 as html
         # special characters. These cannot be removed by html_quote,
@@ -606,10 +615,10 @@
 
 
     def _encode_unicode(self,body,
-                        charset_re=re.compile(r'(?:application|text)/[-+0-9a-z]+\s*;\s*' +
-                                              r'charset=([-_0-9a-z]+' +
-                                              r')(?:(?:\s*;)|\Z)',
-                                              re.IGNORECASE)):
+                        charset_re=re.compile(
+                           r'(?:application|text)/[-+0-9a-z]+\s*;\s*' +
+                           r'charset=([-_0-9a-z]+' +
+                           r')(?:(?:\s*;)|\Z)', re.IGNORECASE)):
 
         def fix_xml_preamble(body, encoding):
             """ fixes the encoding in the XML preamble according
@@ -618,7 +627,8 @@
 
             if body.startswith('<?xml'):
                 pos_right = body.find('?>')  # right end of the XML preamble
-                body = ('<?xml version="1.0" encoding="%s" ?>' % encoding) + body[pos_right+2:]
+                body = ('<?xml version="1.0" encoding="%s" ?>'
+                            % encoding) + body[pos_right+2:]
             return body
 
         # Encode the Unicode data as requested

Modified: Zope/branches/tseaver-fix_wsgi/src/ZPublisher/tests/testHTTPResponse.py
===================================================================
--- Zope/branches/tseaver-fix_wsgi/src/ZPublisher/tests/testHTTPResponse.py	2009-12-21 22:21:33 UTC (rev 106838)
+++ Zope/branches/tseaver-fix_wsgi/src/ZPublisher/tests/testHTTPResponse.py	2009-12-21 22:28:15 UTC (rev 106839)
@@ -501,6 +501,108 @@
         self.assertEqual(response.getHeader('Content-Length'),
                          str(len(MUNGED)))
 
+    def test_setBody_w_locking(self):
+        response = self._makeOne()
+        response.setBody('BEFORE', lock=True)
+        result = response.setBody('AFTER')
+        self.failIf(result)
+        self.assertEqual(response.body, 'BEFORE')
+
+    def test_setBody_empty_unchanged(self):
+        response = self._makeOne()
+        response.body = 'BEFORE'
+        result = response.setBody('')
+        self.failUnless(result)
+        self.assertEqual(response.body, 'BEFORE')
+        self.assertEqual(response.getHeader('Content-Type'), None)
+        self.assertEqual(response.getHeader('Content-Length'), None)
+
+    def test_setBody_2_tuple_wo_is_error_converted_to_HTML(self):
+        EXPECTED = ("<html>\n"
+                    "<head>\n<title>TITLE</title>\n</head>\n"
+                    "<body>\nBODY\n</body>\n"
+                    "</html>\n")
+        response = self._makeOne()
+        response.body = 'BEFORE'
+        result = response.setBody(('TITLE', 'BODY'))
+        self.failUnless(result)
+        self.assertEqual(response.body, EXPECTED)
+        self.assertEqual(response.getHeader('Content-Type'),
+                         'text/html; charset=iso-8859-15')
+        self.assertEqual(response.getHeader('Content-Length'),
+                         str(len(EXPECTED)))
+
+    def test_setBody_2_tuple_w_is_error_converted_to_Site_Error(self):
+        response = self._makeOne()
+        response.body = 'BEFORE'
+        result = response.setBody(('TITLE', 'BODY'), is_error=True)
+        self.failUnless(result)
+        self.failIf('BEFORE' in response.body)
+        self.failUnless('<h2>Site Error</h2>' in response.body)
+        self.failUnless('TITLE' in response.body)
+        self.failUnless('BODY' in response.body)
+        self.assertEqual(response.getHeader('Content-Type'),
+                         'text/html; charset=iso-8859-15')
+
+    def test_setBody_string_not_HTML(self):
+        response = self._makeOne()
+        result = response.setBody('BODY')
+        self.failUnless(result)
+        self.assertEqual(response.body, 'BODY')
+        self.assertEqual(response.getHeader('Content-Type'),
+                         'text/plain; charset=iso-8859-15')
+        self.assertEqual(response.getHeader('Content-Length'), '4')
+
+    def test_setBody_string_HTML(self):
+        HTML = '<html><head></head><body></body></html>'
+        response = self._makeOne()
+        result = response.setBody(HTML)
+        self.failUnless(result)
+        self.assertEqual(response.body, HTML)
+        self.assertEqual(response.getHeader('Content-Type'),
+                         'text/html; charset=iso-8859-15')
+        self.assertEqual(response.getHeader('Content-Length'), str(len(HTML)))
+
+    def test_setBody_object_with_asHTML(self):
+        HTML = '<html><head></head><body></body></html>'
+        class Dummy:
+            def asHTML(self):
+                return HTML
+        response = self._makeOne()
+        result = response.setBody(Dummy())
+        self.failUnless(result)
+        self.assertEqual(response.body, HTML)
+        self.assertEqual(response.getHeader('Content-Type'),
+                         'text/html; charset=iso-8859-15')
+        self.assertEqual(response.getHeader('Content-Length'), str(len(HTML)))
+
+    def test_setBody_object_with_unicode(self):
+        HTML = u'<html><head></head><body><h1>Tr\u0039</body></html>'
+        ENCODED = HTML.encode('iso-8859-15')
+        response = self._makeOne()
+        result = response.setBody(HTML)
+        self.failUnless(result)
+        self.assertEqual(response.body, ENCODED)
+        self.assertEqual(response.getHeader('Content-Type'),
+                         'text/html; charset=iso-8859-15')
+        self.assertEqual(response.getHeader('Content-Length'),
+                         str(len(ENCODED)))
+
+    def test_setBody_w_bogus_pseudo_HTML(self):
+        # The 2001 checkin message which added the path-under-test says:
+        # (r19315): "merged content type on error fixes from 2.3
+        # If the str of the object returs a Python "pointer" looking mess,
+        # don't let it get treated as HTML.
+        from ZPublisher import NotFound
+        BOGUS = '<Bogus a39d53d>'
+        response = self._makeOne()
+        self.assertRaises(NotFound, response.setBody, BOGUS)
+
+    #TODO
+    #def test_setBody_escapes_latin1_gt_lt(self):
+    #def test_setBody_w_base(self):
+    #def test_setBody_w_HTTP_content_compression(self):
+
     def test_setBody_compression_vary(self):
         # Vary header should be added here
         response = self._makeOne()



More information about the checkins mailing list