Back to index

plone3  3.1.7
test_utils.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2002 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ Unit tests for utils module.
00014 
00015 $Id: test_utils.py 79407 2007-08-31 17:05:54Z jens $
00016 """
00017 
00018 import unittest
00019 import Testing
00020 
00021 from Products.CMFCore.tests.base.content import FAUX_HTML_LEADING_TEXT
00022 from Products.CMFCore.tests.base.content import SIMPLE_HTML
00023 from Products.CMFCore.tests.base.content import SIMPLE_STRUCTUREDTEXT
00024 from Products.CMFCore.tests.base.content import SIMPLE_XHTML
00025 from Products.CMFCore.tests.base.content import STX_WITH_HTML
00026 
00027 
00028 class DefaultUtilsTests(unittest.TestCase):
00029 
00030     COMMON_HEADERS = '''Author: Tres Seaver
00031 Title: Test Products.CMFDefault.utils.parseHeadersBody'''
00032 
00033     MULTILINE_DESCRIPTION = '''Description: this description spans
00034         multiple lines.'''
00035 
00036     MULTIPARAGRAPH_DESCRIPTION = \
00037         '''Description: this description spans multiple lines.
00038         
00039         It includes a second paragraph'''
00040 
00041     TEST_BODY = '''Body goes here, and can span multiple
00042 lines.  It can even include "headerish" lines, like:
00043 
00044 Header: value
00045 '''
00046 
00047     def test_parseHeadersBody_no_body( self ):
00048         from Products.CMFDefault.utils import parseHeadersBody
00049 
00050         headers, body = parseHeadersBody( '%s\n\n' % self.COMMON_HEADERS )
00051         self.assertEqual( len( headers ), 2 )
00052         self.failUnless( 'Author' in headers.keys() )
00053         self.assertEqual( headers[ 'Author' ], 'Tres Seaver' )
00054         self.failUnless( 'Title' in headers.keys() )
00055         self.assertEqual( len( body ), 0 )
00056 
00057     def test_parseHeadersBody_continuation( self ):
00058         from Products.CMFDefault.utils import parseHeadersBody
00059 
00060         headers, body = parseHeadersBody( '%s\n%s\n\n'
00061                                         % ( self.COMMON_HEADERS
00062                                           , self.MULTILINE_DESCRIPTION
00063                                           )
00064                                         )
00065         self.assertEqual( len( headers ), 3 )
00066         self.failUnless( 'Description' in headers.keys() )
00067         desc_len = len( headers[ 'Description' ].split('\n') )
00068         self.assertEqual( desc_len, 2 )
00069         self.assertEqual( len( body ), 0 )
00070 
00071     def test_parseHeadersBody_embedded_blank_line( self ):
00072         from Products.CMFDefault.utils import parseHeadersBody
00073 
00074         headers, body = parseHeadersBody( '%s\n%s\n\n%s'
00075                                         % ( self.COMMON_HEADERS
00076                                           , self.MULTIPARAGRAPH_DESCRIPTION
00077                                           , self.TEST_BODY
00078                                           )
00079                                         )
00080         self.assertEqual( len( headers ), 3 )
00081         self.failUnless( 'Description' in headers.keys() )
00082         desc_lines = headers[ 'Description' ].split('\n')
00083         desc_len = len( desc_lines )
00084         self.assertEqual( desc_len, 3, desc_lines )
00085         self.assertEqual( desc_lines[1], ' ' )
00086         self.assertEqual( body, self.TEST_BODY )
00087 
00088     def test_parseHeadersBody_body( self ):
00089         from Products.CMFDefault.utils import parseHeadersBody
00090 
00091         headers, body = parseHeadersBody( '%s\n\n%s'
00092                                         % ( self.COMMON_HEADERS
00093                                           , self.TEST_BODY
00094                                           )
00095                                         )
00096         self.assertEqual( len( headers ), 2 )
00097         self.assertEqual( body, self.TEST_BODY )
00098 
00099     def test_parseHeadersBody_body_malformed_terminator( self ):
00100         from Products.CMFDefault.utils import parseHeadersBody
00101 
00102         headers, body = parseHeadersBody( '%s\n \n%s'
00103                                         % ( self.COMMON_HEADERS
00104                                           , self.TEST_BODY
00105                                           )
00106                                         )
00107         self.assertEqual( len( headers ), 2 )
00108         self.assertEqual( body, self.TEST_BODY )
00109 
00110     def test_parseHeadersBody_preload( self ):
00111         from Products.CMFDefault.utils import parseHeadersBody
00112 
00113         preloaded = { 'Author' : 'xxx', 'text_format' : 'structured_text' }
00114         headers, body = parseHeadersBody( '%s\n%s\n\n%s'
00115                                         % ( self.COMMON_HEADERS
00116                                           , self.MULTILINE_DESCRIPTION
00117                                           , self.TEST_BODY
00118                                           )
00119                                         , preloaded
00120                                         )
00121         self.assertEqual( len( headers ), 4 )
00122         self.assertNotEqual( preloaded[ 'Author' ], headers[ 'Author' ] )
00123         self.assertEqual( preloaded[ 'text_format' ], headers[ 'text_format' ] )
00124 
00125     def test_scrubHTML_no_adapter_falls_back(self):
00126         from Products.CMFDefault.utils import scrubHTML
00127 
00128         self.assertEqual( scrubHTML('<a href="foo.html">bar</a>'),
00129                           '<a href="foo.html">bar</a>' )
00130         self.assertEqual( scrubHTML('<b>bar</b>'),
00131                           '<b>bar</b>' )
00132         self.assertEqual( scrubHTML('<base href="" /><base>'),
00133                           '<base href="" /><base />' )
00134         self.assertEqual( scrubHTML('<blockquote>bar</blockquote>'),
00135                           '<blockquote>bar</blockquote>' )
00136         self.assertEqual( scrubHTML('<body bgcolor="#ffffff">bar</body>'),
00137                           '<body bgcolor="#ffffff">bar</body>' )
00138         self.assertEqual( scrubHTML('<br /><br>'),
00139                           '<br /><br />' )
00140         self.assertEqual( scrubHTML('<hr /><hr>'),
00141                           '<hr /><hr />' )
00142         self.assertEqual( scrubHTML('<img src="foo.png" /><img>'),
00143                           '<img src="foo.png" /><img />' )
00144         self.assertEqual( scrubHTML('<meta name="title" content="" /><meta>'),
00145                           '<meta name="title" content="" /><meta />' )
00146 
00147     def test_scrubHTML_with_adapter(self):
00148         from zope.interface import implements
00149         from zope.component.testing import setUp
00150         from zope.component.testing import tearDown
00151         from zope.app.testing import ztapi
00152         from Products.CMFDefault.interfaces import IHTMLScrubber
00153         from Products.CMFDefault.utils import scrubHTML
00154 
00155         class _Scrubber:
00156             implements(IHTMLScrubber)
00157             def scrub(self, html):
00158                 return html.upper()
00159 
00160 
00161         setUp()
00162         try:
00163             ztapi.provideUtility(IHTMLScrubber, _Scrubber())
00164             self.assertEqual( scrubHTML('<a href="foo.html">bar</a>'),
00165                             '<A HREF="FOO.HTML">BAR</A>' )
00166             self.assertEqual( scrubHTML('<b>bar</b>'),
00167                             '<B>BAR</B>' )
00168             self.assertEqual( scrubHTML('<base href="" /><base>'),
00169                             '<BASE HREF="" /><BASE>' )
00170             self.assertEqual( scrubHTML('<blockquote>bar</blockquote>'),
00171                             '<BLOCKQUOTE>BAR</BLOCKQUOTE>' )
00172             self.assertEqual( scrubHTML('<body bgcolor="#ffffff">bar</body>'),
00173                             '<BODY BGCOLOR="#FFFFFF">BAR</BODY>' )
00174             self.assertEqual( scrubHTML('<br /><br>'),
00175                             '<BR /><BR>' )
00176             self.assertEqual( scrubHTML('<hr /><hr>'),
00177                             '<HR /><HR>' )
00178             self.assertEqual( scrubHTML('<img src="foo.png" /><img>'),
00179                             '<IMG SRC="FOO.PNG" /><IMG>' )
00180             self.assertEqual( scrubHTML(
00181                                 '<meta name="title" content="" /><meta>'),
00182                             '<META NAME="TITLE" CONTENT="" /><META>' )
00183 
00184         finally:
00185             tearDown()
00186 
00187     def test_bodyfinder(self):
00188         from Products.CMFDefault.utils import bodyfinder
00189 
00190         self.assertEqual( bodyfinder(FAUX_HTML_LEADING_TEXT),
00191                           '\n  <h1>Not a lot here</h1>\n ' )
00192         self.assertEqual( bodyfinder(SIMPLE_HTML),
00193                           '\n  <h1>Not a lot here</h1>\n ' )
00194         self.assertEqual( bodyfinder(SIMPLE_STRUCTUREDTEXT),
00195                           SIMPLE_STRUCTUREDTEXT )
00196         self.assertEqual( bodyfinder(SIMPLE_XHTML),
00197                           '\n  <h1>Not a lot here</h1>\n ' )
00198         self.assertEqual( bodyfinder(STX_WITH_HTML),
00199                           '<p>Hello world, I am Bruce.</p>' )
00200 
00201     def test_html_headcheck(self):
00202         from Products.CMFDefault.utils import html_headcheck
00203 
00204         self.assertEqual( html_headcheck(FAUX_HTML_LEADING_TEXT), 0 )
00205         self.assertEqual( html_headcheck(SIMPLE_HTML), 1 )
00206         self.assertEqual( html_headcheck(SIMPLE_STRUCTUREDTEXT), 0 )
00207         self.assertEqual( html_headcheck(SIMPLE_XHTML), 1 )
00208         self.assertEqual( html_headcheck(STX_WITH_HTML), 0 )
00209 
00210     def test_tuplize(self):
00211         from Products.CMFDefault.utils import comma_split
00212         from Products.CMFDefault.utils import tuplize
00213         wanted = ('one','two','three')
00214 
00215         self.assertEqual( tuplize('string', 'one two three'), wanted )
00216         self.assertEqual( tuplize('unicode', u'one two three'), wanted )
00217         self.assertEqual( tuplize('string', 'one,two,three', comma_split),
00218                           wanted )
00219         self.assertEqual( tuplize('list', ['one',' two','three ']), wanted )
00220         self.assertEqual( tuplize('tuple', ('one','two','three')), wanted )
00221 
00222     def test_seq_strip(self):
00223         from Products.CMFDefault.utils import seq_strip
00224 
00225         self.assertEqual( seq_strip(['one ', ' two', ' three ']),
00226                           ['one','two','three'] )
00227         self.assertEqual( seq_strip(('one ', ' two', ' three ')),
00228                           ('one','two','three') )
00229 
00230     def test_html_marshal(self):
00231         from Products.CMFDefault.utils import html_marshal
00232 
00233         self.assertEqual( html_marshal(foo=1), ( ('foo:int', 1), ) )
00234         self.assertEqual( html_marshal(foo=1, bar='baz >&baz'),
00235                           ( ('foo:int', 1), ('bar', 'baz >&baz') ) )
00236 
00237     def test_toUnicode(self):
00238         from Products.CMFDefault.utils import toUnicode
00239 
00240         self.assertEqual( toUnicode('foo'), u'foo' )
00241         self.assertEqual( toUnicode( ('foo', 'bar'), 'ascii' ),
00242                           (u'foo', u'bar') )
00243         self.assertEqual( toUnicode( {'foo': 'bar'}, 'iso-8859-1' ),
00244                           {'foo': u'bar'} )
00245 
00246     def test_checkEmailAddress(self):
00247         from Products.CMFDefault.exceptions import EmailAddressInvalid
00248         from Products.CMFDefault.utils import checkEmailAddress
00249 
00250         self.assertEqual(checkEmailAddress('foo@example.com'), None)
00251         self.assertEqual(checkEmailAddress('foo@1bar.example.com'), None)
00252         self.assertEqual(checkEmailAddress('foo@123456.com'), None)
00253         self.assertEqual(checkEmailAddress('$.-@example.com'), None)
00254         self.assertEqual(checkEmailAddress(u'foo@example.com'), None)
00255         # CMF Collector issue #322
00256         self.assertEqual(checkEmailAddress('user+site@example.com'), None)
00257         # CMF Collector issue #326
00258         self.assertEqual(checkEmailAddress('username_@example.com'), None)
00259         # CMF Collector issue #401
00260         self.assertEqual(checkEmailAddress("user'site@example.com"), None)
00261         # CMF Collector issue #495
00262         self.assertEqual(checkEmailAddress("user@a.example.com"), None)
00263         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00264                           'this is not an e-mail address')
00265         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00266                           'foo@example.com, bar@example.com')
00267         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00268                           'foo.@example.com')
00269         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00270                           '.foo@example.com')
00271         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00272                           'foo@-bar.example.com')
00273         # RFC 2821 local-part: max 64 characters
00274         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00275                           'f'*63+'oo@example.com')
00276         # RFC 2821 domain: max 255 characters
00277         self.assertRaises(EmailAddressInvalid, checkEmailAddress,
00278                           'foo@'+'b'*242+'ar.example.com')
00279 
00280     def test_formatRFC822Headers_simple(self):
00281         from Products.CMFDefault.utils import formatRFC822Headers
00282 
00283         HEADERS = [ ('Foo', 'foo')
00284                   , ('Bar', 'bar')
00285                   ]
00286 
00287         formatted = formatRFC822Headers( HEADERS )
00288 
00289         self.assertEqual( formatted, 'Foo: foo\r\nBar: bar' )
00290 
00291     def test_formatRFC822Headers_empty(self):
00292         from Products.CMFDefault.utils import formatRFC822Headers
00293 
00294         HEADERS = [ ('Foo', 'foo')
00295                   , ('Bar', '')
00296                   ]
00297 
00298         formatted = formatRFC822Headers( HEADERS )
00299 
00300         self.assertEqual( formatted, 'Foo: foo\r\nBar: ' )
00301 
00302     def test_formatRFC822Headers_multiline(self):
00303         from Products.CMFDefault.utils import formatRFC822Headers
00304 
00305         HEADERS = [ ('Foo', 'foo')
00306                   , ('Bar', 'bar\nwith multiline')
00307                   ]
00308 
00309         formatted = formatRFC822Headers( HEADERS )
00310 
00311         self.assertEqual( formatted
00312                         , 'Foo: foo\r\nBar: bar\r\n  with multiline' )
00313 
00314     def test_formatRFC822Headers_multiline_trailing_blank_line(self):
00315         from Products.CMFDefault.utils import formatRFC822Headers
00316 
00317         HEADERS = [ ('Foo', 'foo')
00318                   , ('Bar', 'bar\nwith multiline\n')
00319                   ]
00320 
00321         formatted = formatRFC822Headers( HEADERS )
00322 
00323         self.assertEqual( formatted
00324                         , 'Foo: foo\r\nBar: bar\r\n  with multiline' )
00325 
00326     def test_formatRFC822Headers_multiline_intermediate_blank_line(self):
00327         from Products.CMFDefault.utils import formatRFC822Headers
00328 
00329         HEADERS = [ ('Foo', 'foo')
00330                   , ('Bar', 'bar\n\nwith multiline')
00331                   ]
00332 
00333         formatted = formatRFC822Headers( HEADERS )
00334 
00335         self.assertEqual( formatted
00336                         , 'Foo: foo\r\nBar: bar\r\n  \r\n  with multiline' )
00337 
00338 
00339 def test_suite():
00340     return unittest.TestSuite((
00341         unittest.makeSuite(DefaultUtilsTests),
00342         ))
00343 
00344 if __name__ == '__main__':
00345     unittest.main(defaultTest='test_suite')