[Zope-Checkins] SVN: Zope/branches/2.11/lib/python/Products/PageTemplates/ Launchpad #254570:
Andreas Jung
andreas at andreas-jung.com
Sat Aug 16 02:47:53 EDT 2008
Log message for revision 89904:
Launchpad #254570:
the PreferredCharset resolver now deals with situations
where 'context' has no REQUEST attribute
Changed:
U Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py
U Zope/branches/2.11/lib/python/Products/PageTemplates/unicodeconflictresolver.py
-=-
Modified: Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py
===================================================================
--- Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py 2008-08-16 05:50:04 UTC (rev 89903)
+++ Zope/branches/2.11/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py 2008-08-16 06:47:53 UTC (rev 89904)
@@ -18,11 +18,14 @@
from Testing.makerequest import makerequest
from Testing.ZopeTestCase import ZopeTestCase, installProduct
-from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate, manage_addPageTemplate
-from Products.PageTemplates.utils import encodingFromXMLPreamble, charsetFromMetaEquiv
+from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
+from Products.PageTemplates.ZopePageTemplate import manage_addPageTemplate
+from Products.PageTemplates.utils import encodingFromXMLPreamble
+from Products.PageTemplates.utils import charsetFromMetaEquiv
from zope.component import provideUtility
from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
-from Products.PageTemplates.unicodeconflictresolver import PreferredCharsetResolver
+from Products.PageTemplates.unicodeconflictresolver \
+ import PreferredCharsetResolver
ascii_str = '<html><body>hello world</body></html>'
@@ -50,7 +53,8 @@
'''
html_iso_8859_15_w_header = html_template_w_header % 'iso-8859-15'
-html_utf8_w_header = unicode(html_template_w_header, 'iso-8859-15').encode('utf-8') % 'utf-8'
+html_utf8_w_header = unicode(html_template_w_header,
+ 'iso-8859-15').encode('utf-8') % 'utf-8'
html_template_wo_header = '''
<html>
@@ -61,9 +65,23 @@
'''
html_iso_8859_15_wo_header = html_template_wo_header
-html_utf8_wo_header = unicode(html_template_wo_header, 'iso-8859-15').encode('utf-8')
+html_utf8_wo_header = unicode(html_template_wo_header,
+ 'iso-8859-15').encode('utf-8')
+xml_with_upper_attr = '''<?xml version="1.0"?>
+<foo>
+ <bar ATTR="1" />
+</foo>
+'''
+html_with_upper_attr = '''<html><body>
+<foo>
+ <bar ATTR="1" />
+</foo>
+</body></html>
+'''
+
+
installProduct('PageTemplates')
class ZPTUtilsTests(unittest.TestCase):
@@ -71,16 +89,32 @@
def testExtractEncodingFromXMLPreamble(self):
extract = encodingFromXMLPreamble
self.assertEqual(extract('<?xml version="1.0" ?>'), 'utf-8')
- self.assertEqual(extract('<?xml encoding="utf-8" version="1.0" ?>'), 'utf-8')
- self.assertEqual(extract('<?xml encoding="UTF-8" version="1.0" ?>'), 'utf-8')
- self.assertEqual(extract('<?xml encoding="ISO-8859-15" version="1.0" ?>'), 'iso-8859-15')
- self.assertEqual(extract('<?xml encoding="iso-8859-15" version="1.0" ?>'), 'iso-8859-15')
+ self.assertEqual(extract('<?xml encoding="utf-8" '
+ 'version="1.0" ?>'),
+ 'utf-8')
+ self.assertEqual(extract('<?xml encoding="UTF-8" '
+ 'version="1.0" ?>'),
+ 'utf-8')
+ self.assertEqual(extract('<?xml encoding="ISO-8859-15" '
+ 'version="1.0" ?>'),
+ 'iso-8859-15')
+ self.assertEqual(extract('<?xml encoding="iso-8859-15" '
+ 'version="1.0" ?>'),
+ 'iso-8859-15')
def testExtractCharsetFromMetaHTTPEquivTag(self):
extract = charsetFromMetaEquiv
- self.assertEqual(extract('<html><META http-equiv="content-type" content="text/html; charset=UTF-8"></html>'), 'utf-8')
- self.assertEqual(extract('<html><META http-equiv="content-type" content="text/html; charset=iso-8859-15"></html>'), 'iso-8859-15')
- self.assertEqual(extract('<html><META http-equiv="content-type" content="text/html"></html>'), None)
+ self.assertEqual(extract('<html><META http-equiv="content-type" '
+ 'content="text/html; '
+ 'charset=UTF-8"></html>'),
+ 'utf-8')
+ self.assertEqual(extract('<html><META http-equiv="content-type" '
+ 'content="text/html; '
+ 'charset=iso-8859-15"></html>'),
+ 'iso-8859-15')
+ self.assertEqual(extract('<html><META http-equiv="content-type" '
+ 'content="text/html"></html>'),
+ None)
self.assertEqual(extract('<html>...<html>'), None)
@@ -89,57 +123,73 @@
def afterSetUp(self):
zope.component.provideAdapter(DefaultTraversable, (None,))
zope.component.provideAdapter(HTTPCharsets, (None,))
- provideUtility(PreferredCharsetResolver, IUnicodeEncodingConflictResolver)
+ provideUtility(PreferredCharsetResolver,
+ IUnicodeEncodingConflictResolver)
def testISO_8859_15(self):
manage_addPageTemplate(self.app, 'test',
- text='<div tal:content="python: request.get(\'data\')" />',
+ text=('<div tal:content="python: '
+ 'request.get(\'data\')" />'),
encoding='ascii')
zpt = self.app['test']
self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'ISO-8859-15,utf-8')
self.app.REQUEST.set('data', 'üöä')
result = zpt.pt_render()
- self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), True)
+ self.failUnless(result.startswith(unicode('<div>üöä</div>',
+ 'iso-8859-15')))
def testUTF8(self):
manage_addPageTemplate(self.app, 'test',
- text='<div tal:content="python: request.get(\'data\')" />',
+ text=('<div tal:content="python: '
+ 'request.get(\'data\')" />'),
encoding='ascii')
zpt = self.app['test']
self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'utf-8,ISO-8859-15')
- self.app.REQUEST.set('data', unicode('üöä', 'iso-8859-15').encode('utf-8'))
+ self.app.REQUEST.set('data',
+ unicode('üöä', 'iso-8859-15').encode('utf-8'))
result = zpt.pt_render()
- self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), True)
+ self.failUnless(result.startswith(unicode('<div>üöä</div>',
+ 'iso-8859-15')))
def testUTF8WrongPreferredCharset(self):
manage_addPageTemplate(self.app, 'test',
- text='<div tal:content="python: request.get(\'data\')" />',
+ text=('<div tal:content="python: '
+ 'request.get(\'data\')" />'),
encoding='ascii')
zpt = self.app['test']
self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'iso-8859-15')
- self.app.REQUEST.set('data', unicode('üöä', 'iso-8859-15').encode('utf-8'))
+ self.app.REQUEST.set('data',
+ unicode('üöä', 'iso-8859-15').encode('utf-8'))
result = zpt.pt_render()
- self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), False)
+ self.failIf(result.startswith(unicode('<div>üöä</div>',
+ 'iso-8859-15')))
def testStructureWithAccentedChars(self):
manage_addPageTemplate(self.app, 'test',
- text='<div tal:content="structure python: %s" />' % "'üöä'",
+ text=('<div tal:content="structure '
+ 'python: %s" />' % "'üöä'"),
encoding='iso-8859-15')
zpt = self.app['test']
self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'iso-8859-15,utf-8')
- self.app.REQUEST.set('data', unicode('üöä', 'iso-8859-15').encode('utf-8'))
+ self.app.REQUEST.set('data', unicode('üöä',
+ 'iso-8859-15').encode('utf-8'))
result = zpt.pt_render()
- self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), True)
+ self.failUnless(result.startswith(unicode('<div>üöä</div>',
+ 'iso-8859-15')))
def testBug151020(self):
manage_addPageTemplate(self.app, 'test',
- text='<div tal:content="structure python: %s" />' % "'üöä'",
+ text=('<div tal:content="structure '
+ 'python: %s" />' % "'üöä'"),
encoding='iso-8859-15')
zpt = self.app['test']
- self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'x-user-defined, iso-8859-15,utf-8')
- self.app.REQUEST.set('data', unicode('üöä', 'iso-8859-15').encode('utf-8'))
+ self.app.REQUEST.set('HTTP_ACCEPT_CHARSET',
+ 'x-user-defined, iso-8859-15,utf-8')
+ self.app.REQUEST.set('data',
+ unicode('üöä', 'iso-8859-15').encode('utf-8'))
result = zpt.pt_render()
- self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), True)
+ self.failUnless(result.startswith(unicode('<div>üöä</div>',
+ 'iso-8859-15')))
def test_bug_198274(self):
# See https://bugs.launchpad.net/bugs/198274
@@ -168,8 +218,14 @@
class ZopePageTemplateFileTests(ZopeTestCase):
+ def test_class_conforms_to_IWriteLock(self):
+ from zope.interface.verify import verifyClass
+ from webdav.interfaces import IWriteLock
+ verifyClass(IWriteLock, ZopePageTemplate)
+
def testPT_RenderWithAscii(self):
- manage_addPageTemplate(self.app, 'test', text=ascii_str, encoding='ascii')
+ manage_addPageTemplate(self.app, 'test',
+ text=ascii_str, encoding='ascii')
zpt = self.app['test']
result = zpt.pt_render()
# use startswith() because the renderer appends a trailing \n
@@ -180,21 +236,25 @@
# Check workaround for unicode incompatibility of ZRPythonExpr.
# See http://mail.zope.org/pipermail/zope/2007-February/170537.html
manage_addPageTemplate(self.app, 'test',
- text='<span tal:content="python: unicode(\'\xfe\', \'iso-8859-15\')" />',
+ text=('<span tal:content="python: '
+ 'unicode(\'\xfe\', \'iso-8859-15\')" />'),
encoding='iso-8859-15')
zpt = self.app['test']
result = zpt.pt_render() # should not raise a UnicodeDecodeError
def testPT_RenderWithISO885915(self):
- manage_addPageTemplate(self.app, 'test', text=iso885915_str, encoding='iso-8859-15')
+ manage_addPageTemplate(self.app, 'test',
+ text=iso885915_str, encoding='iso-8859-15')
zpt = self.app['test']
result = zpt.pt_render()
# use startswith() because the renderer appends a trailing \n
- self.assertEqual(result.encode('iso-8859-15').startswith(iso885915_str), True)
+ self.failUnless(result.encode('iso-8859-15'
+ ).startswith(iso885915_str))
self.assertEqual(zpt.output_encoding, 'iso-8859-15')
def testPT_RenderWithUTF8(self):
- manage_addPageTemplate(self.app, 'test', text=utf8_str, encoding='utf-8')
+ manage_addPageTemplate(self.app, 'test',
+ text=utf8_str, encoding='utf-8')
zpt = self.app['test']
result = zpt.pt_render()
# use startswith() because the renderer appends a trailing \n
@@ -218,7 +278,8 @@
self.assertEqual(zpt.read(), xml_unicode)
def _createZPT(self):
- manage_addPageTemplate(self.app, 'test', text=utf8_str, encoding='utf-8')
+ manage_addPageTemplate(self.app, 'test',
+ text=utf8_str, encoding='utf-8')
zpt = self.app['test']
return zpt
@@ -266,6 +327,36 @@
self.assertEqual(zpt.content_type, 'text/xml')
result = zpt.pt_render() # should not raise an exception
+ def testXMLAttrsMustNotBeLowercased(self):
+ zpt = self._put(xml_with_upper_attr)
+ self.assertEqual(zpt.content_type, 'text/xml')
+ result = zpt.pt_render()
+ self.assertEqual('ATTR' in result, True)
+
+ def testHTMLAttrsAreLowerCased(self):
+ zpt = self._put(html_with_upper_attr)
+ self.content_type = 'text/html'
+ result = zpt.pt_render()
+ self.assertEqual('ATTR' in result, False)
+
+class PreferredCharsetUnicodeResolverTests(unittest.TestCase):
+
+ def testPreferredCharsetResolverWithoutRequestAndWithoutEncoding(self):
+ # This test checks the edgecase where the unicode conflict resolver
+ # is called with a context object having no REQUEST
+ context = object()
+ result = PreferredCharsetResolver.resolve(context, 'üöä', None)
+ self.assertEqual(result, 'üöä')
+
+ def testPreferredCharsetResolverWithoutRequestAndWithEncoding(self):
+ # This test checks the edgecase where the unicode conflict resolver
+ # is called with a context object having no REQUEST
+ class ContextMock:
+ management_page_charset = 'iso-8859-15'
+ result = PreferredCharsetResolver.resolve(ContextMock(), 'üöä', None)
+ self.assertEqual(result, u'üöä')
+
+
class ZPTRegressions(unittest.TestCase):
def setUp(self):
@@ -389,6 +480,7 @@
suite.addTests(unittest.makeSuite(ZPTMacros))
suite.addTests(unittest.makeSuite(ZopePageTemplateFileTests))
suite.addTests(unittest.makeSuite(ZPTUnicodeEncodingConflictResolution))
+ suite.addTests(unittest.makeSuite(PreferredCharsetUnicodeResolverTests))
return suite
if __name__ == '__main__':
Modified: Zope/branches/2.11/lib/python/Products/PageTemplates/unicodeconflictresolver.py
===================================================================
--- Zope/branches/2.11/lib/python/Products/PageTemplates/unicodeconflictresolver.py 2008-08-16 05:50:04 UTC (rev 89903)
+++ Zope/branches/2.11/lib/python/Products/PageTemplates/unicodeconflictresolver.py 2008-08-16 06:47:53 UTC (rev 89904)
@@ -62,25 +62,43 @@
def resolve(self, context, text, expression):
- request = context.REQUEST
+ request = getattr(context, 'REQUEST', None)
- charsets = getattr(request, '__zpt_available_charsets', None)
- if charsets is None:
- charsets = IUserPreferredCharsets(request).getPreferredCharsets()
+ # Deal with the fact that a REQUEST is not always available.
+ # In this case fall back to the encoding of the ZMI and the
+ # Python default encoding.
- # add management_page_charset as one fallback
+ if request is None:
+ charsets = [default_encoding]
management_charset = getattr(context, 'management_page_charset', None)
if management_charset:
- charsets.append(management_charset)
+ charsets.insert(0, management_charset)
+ else:
+ # charsets might by cached within the request
+ charsets = getattr(request, '__zpt_available_charsets', None)
+ # No uncached charsets found: investigate the HTTP_ACCEPT_CHARSET
+ # header. This code is only called if 'context' has a request
+ # object. The condition is true because otherwise 'charsets' contains
+ # at least the default encoding of Python.
+ if charsets is None:
+
+ charsets = list()
+
# add Python's default encoding as last fallback
charsets.append(default_encoding)
+ # include the charsets based on the HTTP_ACCEPT_CHARSET
+ # header
+ charsets = IUserPreferredCharsets(request).getPreferredCharsets() +\
+ charsets
+
# cache list of charsets
request.__zpt_available_charsets = charsets
for enc in charsets:
- if enc == '*': continue
+ if enc == '*':
+ continue
try:
return unicode(text, enc)
More information about the Zope-Checkins
mailing list