Back to index

plone3  3.1.7
test_FSPythonScript.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 FSPythonScript module.
00014 
00015 $Id: test_FSPythonScript.py 76996 2007-06-24 00:18:49Z hannosch $
00016 """
00017 
00018 import unittest
00019 from Testing import ZopeTestCase
00020 ZopeTestCase.installProduct('PythonScripts', 1)
00021 
00022 from os.path import join
00023 from sys import exc_info
00024 from thread import start_new_thread
00025 from time import sleep
00026 
00027 from Acquisition import aq_base
00028 from OFS.Folder import Folder
00029 from OFS.SimpleItem import SimpleItem
00030 from Products.StandardCacheManagers import RAMCacheManager
00031 
00032 from Products.CMFCore.FSMetadata import FSMetadata
00033 from Products.CMFCore.FSPythonScript import FSPythonScript
00034 from Products.CMFCore.tests.base.testcase import FSDVTest
00035 from Products.CMFCore.tests.base.testcase import SecurityTest
00036 from Products.CMFCore.tests.base.testcase import WarningInterceptor
00037 
00038 
00039 class FSPSMaker(FSDVTest):
00040 
00041     def _makeOne( self, id, filename ):
00042         path = join(self.skin_path_name, filename)
00043         metadata = FSMetadata(path)
00044         metadata.read()
00045         return FSPythonScript( id, path, properties=metadata.getProperties() ) 
00046 
00047 
00048 class FSPythonScriptTests(FSPSMaker):
00049 
00050     def test_get_size( self ):
00051         # Test get_size returns correct value
00052         script = self._makeOne('test1', 'test1.py')
00053         self.assertEqual(len(script.read()),script.get_size())
00054 
00055     def test_initialization_race_condition(self):
00056         # Tries to exercise a former race condition where
00057         # FSObject._updateFromFS() set self._parsed before the
00058         # object was really parsed.
00059         for n in range(10):
00060             f = Folder()
00061             script = self._makeOne('test1', 'test1.py').__of__(f)
00062             res = []
00063 
00064             def call_script(script=script, res=res):
00065                 try:
00066                     res.append(script())
00067                 except:
00068                     res.append('%s: %s' % exc_info()[:2])
00069 
00070             start_new_thread(call_script, ())
00071             call_script()
00072             while len(res) < 2:
00073                 sleep(0.05)
00074             self.assertEqual(res, ['test1', 'test1'], res)
00075 
00076     def test_foreign_line_endings( self ):
00077         # Load the various line ending files and get their output
00078         container = Folder('container_for_execution')
00079         for fformat in ('unix', 'dos', 'mac'):
00080             container._setObject(fformat,
00081                 self._makeOne(fformat, 'test_%s.py' % fformat))
00082             script = getattr(container, fformat)
00083             self.assertEqual(script(), fformat)
00084 
00085 
00086 class FSPythonScriptCustomizationTests(SecurityTest, FSPSMaker):
00087 
00088     def setUp( self ):
00089         FSPSMaker.setUp(self)
00090         SecurityTest.setUp( self )
00091 
00092     def tearDown(self):
00093         SecurityTest.tearDown(self)
00094         FSPSMaker.tearDown(self)
00095 
00096     def _makeSkins(self):
00097 
00098         root = self.root
00099         root._setObject( 'portal_skins', Folder( 'portal_skins' ) )
00100         tool = self.root.portal_skins
00101 
00102         tool._setObject( 'custom', Folder( 'custom' ) )
00103         custom = tool.custom
00104 
00105         tool._setObject( 'fsdir', Folder( 'fsdir' ) )
00106         fsdir = tool.fsdir
00107 
00108         fsdir._setObject( 'test6'
00109                         , self._makeOne( 'test6', 'test6.py' ) )
00110 
00111         fsPS = fsdir.test6
00112 
00113         return root, tool, custom, fsdir, fsPS
00114 
00115     def test_customize( self ):
00116 
00117         from Products.CMFCore.FSPythonScript import CustomizedPythonScript
00118 
00119         root, tool, custom, fsdir, fsPS = self._makeSkins()
00120 
00121         fsPS.manage_doCustomize( folder_path='custom' )
00122 
00123         self.assertEqual( len( custom.objectIds() ), 1 )
00124         self.failUnless( 'test6' in custom.objectIds() )  
00125 
00126         test6 = custom._getOb('test6')
00127 
00128         self.failUnless(isinstance(test6, CustomizedPythonScript))
00129         self.assertEqual(test6.original_source, fsPS.read())
00130 
00131     def test_customize_alternate_root( self ):
00132 
00133         root, tool, custom, fsdir, fsPS = self._makeSkins()
00134         root.other = Folder('other')
00135 
00136         fsPS.manage_doCustomize( folder_path='other', root=root )
00137 
00138         self.failIf( 'test6' in custom.objectIds() )  
00139         self.failUnless( 'test6' in root.other.objectIds() )  
00140 
00141     def test_customize_fspath_as_dot( self ):
00142 
00143         root, tool, custom, fsdir, fsPS = self._makeSkins()
00144 
00145         fsPS.manage_doCustomize( folder_path='.' )
00146 
00147         self.failIf( 'test6' in custom.objectIds() )  
00148         self.failUnless( 'test6' in root.portal_skins.objectIds() )  
00149 
00150     def test_customize_manual_clone( self ):
00151 
00152         root, tool, custom, fsdir, fsPS = self._makeSkins()
00153         clone = Folder('test6')
00154 
00155         fsPS.manage_doCustomize( folder_path='custom', obj=clone )
00156 
00157         self.failUnless( 'test6' in custom.objectIds() )  
00158         self.failUnless( aq_base(custom._getOb('test6')) is clone )  
00159 
00160     def test_customize_caching(self):
00161         # Test to ensure that cache manager associations survive customizing
00162         root, tool, custom, fsdir, fsPS = self._makeSkins()
00163 
00164         cache_id = 'gofast'
00165         RAMCacheManager.manage_addRAMCacheManager( root
00166                                                  , cache_id
00167                                                  , REQUEST=None
00168                                                  )
00169         fsPS.ZCacheable_setManagerId(cache_id, REQUEST=None)
00170 
00171         self.assertEqual(fsPS.ZCacheable_getManagerId(), cache_id)
00172 
00173         fsPS.manage_doCustomize(folder_path='custom')
00174         custom_ps = custom.test6
00175 
00176         self.assertEqual(custom_ps.ZCacheable_getManagerId(), cache_id)
00177 
00178     def test_customize_proxyroles(self):
00179         # Test to ensure that proxy roles survive customizing
00180         root, tool, custom, fsdir, fsPS = self._makeSkins()
00181 
00182         fsPS._proxy_roles = ('Manager', 'Anonymous')
00183         self.failUnless(fsPS.manage_haveProxy('Anonymous'))
00184         self.failUnless(fsPS.manage_haveProxy('Manager'))
00185 
00186         fsPS.manage_doCustomize(folder_path='custom')
00187         custom_ps = custom.test6
00188         self.failUnless(custom_ps.manage_haveProxy('Anonymous'))
00189         self.failUnless(custom_ps.manage_haveProxy('Manager'))
00190 
00191     def test_customization_permissions(self):
00192         # Test to ensure that permission settings survive customizing
00193         root, tool, custom, fsdir, fsPS = self._makeSkins()
00194         perm = 'View management screens'
00195 
00196         # First, set a permission to an odd role and verify
00197         fsPS.manage_permission( perm
00198                               , roles=('Anonymous',)
00199                               , acquire=0
00200                               )
00201         rop = fsPS.rolesOfPermission(perm)
00202         for rop_info in rop:
00203             if rop_info['name'] == 'Anonymous':
00204                 self.failIf(rop_info['selected'] == '')
00205             else:
00206                 self.failUnless(rop_info['selected'] == '')
00207 
00208         # Now customize and verify again
00209         fsPS.manage_doCustomize(folder_path='custom')
00210         custom_ps = custom.test6
00211         rop = custom_ps.rolesOfPermission(perm)
00212         for rop_info in rop:
00213             if rop_info['name'] == 'Anonymous':
00214                 self.failIf(rop_info['selected'] == '')
00215             else:
00216                 self.failUnless(rop_info['selected'] == '')
00217 
00218 _ORIGINAL_TEXT = """\
00219 ## Script (Python) "cps"
00220 ##bind container=container
00221 ##bind context=context
00222 ##bind namespace=
00223 ##bind script=script
00224 ##bind subpath=traverse_subpath
00225 ##parameters=
00226 ##title=
00227 ##
00228 return 'cps'
00229 """
00230 
00231 _REPLACEMENT_TEXT = """\
00232 ## Script (Python) "cps"
00233 ##bind container=container
00234 ##bind context=context
00235 ##bind namespace=
00236 ##bind script=script
00237 ##bind subpath=traverse_subpath
00238 ##parameters=
00239 ##title=
00240 ##
00241 return 'cps -- replaced'
00242 """
00243 
00244 _DIFF_TEXT = """\
00245 --- original 
00246 +++ modified 
00247 @@ -7,4 +7,4 @@
00248  ##parameters=
00249  ##title=
00250  ##
00251 -return 'cps'
00252 +return 'cps -- replaced'
00253 """
00254 
00255 class CustomizedPythonScriptTests(unittest.TestCase):
00256 
00257     def _getTargetClass(self):
00258         from Products.CMFCore.FSPythonScript import CustomizedPythonScript
00259         return CustomizedPythonScript
00260 
00261     def _makeOne(self, id, text):
00262         return self._getTargetClass()(id, text)
00263 
00264     def test_write_leaves_original_source(self):
00265         cps = self._makeOne('cps', _ORIGINAL_TEXT)
00266         self.assertEqual(cps.read(), _ORIGINAL_TEXT)
00267         self.assertEqual(cps.original_source, _ORIGINAL_TEXT)
00268         cps.write(_REPLACEMENT_TEXT)
00269         self.assertEqual(cps.read(), _REPLACEMENT_TEXT)
00270         self.assertEqual(cps.original_source, _ORIGINAL_TEXT)
00271 
00272     def test_getDiff(self):
00273         cps = self._makeOne('cps', _ORIGINAL_TEXT)
00274         self.assertEqual(len(list(cps.getDiff())), 0)
00275 
00276         cps.write(_REPLACEMENT_TEXT)
00277         self.assertEqual(list(cps.getDiff()), _DIFF_TEXT.splitlines())
00278 
00279 
00280 class WarnMe(SimpleItem):
00281     """Emits a UserWarning when called"""
00282 
00283     def __init__(self, stacklevel):
00284         self._stacklevel = stacklevel
00285 
00286     def __call__(self):
00287         import warnings
00288         warnings.warn('foo', stacklevel=self._stacklevel)
00289 
00290 
00291 class FSPythonScriptWarningsTests(SecurityTest, FSPSMaker, WarningInterceptor):
00292 
00293     def setUp( self ):
00294         SecurityTest.setUp(self)
00295         FSPSMaker.setUp(self)
00296         self._trap_warning_output()
00297 
00298     def tearDown(self):
00299         self._free_warning_output()
00300         FSPSMaker.tearDown(self)
00301         SecurityTest.tearDown(self)
00302 
00303     def testFSPSWarn(self):
00304         self.root._setObject('warn_me', WarnMe(2))
00305         self.root._setObject('warn1', self._makeOne('warn1', 'test_warn.py'))
00306         # This used to raise an error:
00307         #   File "/usr/local/python2.3/lib/python2.3/warnings.py", line 63, in warn_explicit
00308         #     if module[-3:].lower() == ".py":
00309         # TypeError: unsubscriptable object
00310         self.root.warn1()
00311 
00312 
00313 def test_suite():
00314     return unittest.TestSuite((
00315         unittest.makeSuite(FSPythonScriptTests),
00316         unittest.makeSuite(FSPythonScriptCustomizationTests),
00317         unittest.makeSuite(CustomizedPythonScriptTests),
00318         unittest.makeSuite(FSPythonScriptWarningsTests),
00319         ))
00320 
00321 if __name__ == '__main__':
00322     unittest.main(defaultTest='test_suite')