Back to index

plone3  3.1.7
test_DirectoryView.py
Go to the documentation of this file.
00001 import unittest
00002 import Testing
00003 
00004 import sys
00005 from os import remove, mkdir, rmdir
00006 from os.path import join
00007 from tempfile import mktemp
00008 
00009 from Globals import DevelopmentMode
00010 
00011 from Products.CMFCore.tests import _globals
00012 from Products.CMFCore.tests.base.dummy import DummyFolder
00013 from Products.CMFCore.tests.base.testcase import FSDVTest
00014 from Products.CMFCore.tests.base.testcase import WarningInterceptor
00015 from Products.CMFCore.tests.base.testcase import WritableFSDVTest
00016 
00017 from Products.CMFCore.DirectoryView import DirectoryView
00018 
00019 
00020 class DummyDirectoryView(DirectoryView):
00021     def __of__(self, parent):
00022         return DummyDirectoryViewSurrogate()
00023 
00024 class DummyDirectoryViewSurrogate:
00025     pass
00026 
00027 
00028 class DirectoryViewPathTests(unittest.TestCase, WarningInterceptor):
00029     """
00030     These test that, no matter what is stored in their dirpath,
00031     FSDV's will do their best to find an appropriate skin
00032     and only do nothing in the case where an appropriate skin
00033     can't be found.
00034     """
00035 
00036     def setUp(self):
00037         self._trap_warning_output()
00038         from Products.CMFCore.DirectoryView import registerDirectory
00039         from Products.CMFCore.DirectoryView import addDirectoryViews
00040         registerDirectory('fake_skins', _globals)
00041         self.ob = DummyFolder()
00042         addDirectoryViews(self.ob, 'fake_skins', _globals)
00043 
00044     def tearDown(self):
00045         self._free_warning_output()
00046 
00047     def test__generateKey(self):
00048         from Products.CMFCore.DirectoryView import _generateKey
00049 
00050         key = _generateKey('Products.CMFCore', 'tests')
00051         self.assertEqual(key.split(':')[0], 'Products.CMFCore')
00052 
00053         subkey = _generateKey('Products.CMFCore', 'tests\foo')
00054         self.failUnless(subkey.startswith(key))
00055 
00056     def test__findProductForPath(self):
00057         from Products.CMFCore.DirectoryView import _findProductForPath
00058 
00059         cmfpath = sys.modules['Products.CMFCore'].__path__[0]
00060         self.assertEqual(_findProductForPath(cmfpath),
00061                          ('Products.CMFCore', ''))
00062 
00063         cmfpath = join(cmfpath, 'tests')
00064         self.assertEqual(_findProductForPath(cmfpath),
00065                 ('Products.CMFCore', 'tests'))
00066 
00067     def test_getDirectoryInfo(self):
00068         skin = self.ob.fake_skin
00069         skin.manage_properties('Products.CMFCore.tests:fake_skins/fake_skin')
00070         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00071                          self.ob.fake_skin.getDirPath() )
00072 
00073     # 1 - 7, in effect, test the pre CMF 1.5 backwards compatibility code in
00074     # DirectoryView's __of__ method. See DirectoryView.py for details
00075 
00076     # windows INSTANCE_HOME
00077     def test_getDirectoryInfo1(self):
00078         skin = self.ob.fake_skin
00079         skin.manage_properties(r'Products\CMFCore\tests\fake_skins\fake_skin')
00080         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00081                          self.ob.fake_skin.getDirPath() )
00082 
00083     # windows SOFTWARE_HOME
00084     def test_getDirectoryInfo2(self):
00085         skin = self.ob.fake_skin
00086         skin.manage_properties(
00087                   r'C:\Zope\2.5.1\Products\CMFCore\tests\fake_skins\fake_skin')
00088         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00089                          self.ob.fake_skin.getDirPath() )
00090 
00091     # *nix INSTANCE_HOME
00092     def test_getDirectoryInfo3(self):
00093         skin = self.ob.fake_skin
00094         skin.manage_properties('Products/CMFCore/tests/fake_skins/fake_skin')
00095         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00096                          self.ob.fake_skin.getDirPath() )
00097 
00098     # *nix SOFTWARE_HOME
00099     def test_getDirectoryInfo4(self):
00100         skin = self.ob.fake_skin
00101         skin.manage_properties(
00102            '/usr/local/zope/2.5.1/Products/CMFCore/tests/fake_skins/fake_skin')
00103         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00104                          self.ob.fake_skin.getDirPath() )
00105 
00106     # windows PRODUCTS_PATH
00107     def test_getDirectoryInfo5(self):
00108         skin = self.ob.fake_skin
00109         skin.manage_properties( mktemp() +
00110                                r'\Products\CMFCore\tests\fake_skins\fake_skin')
00111         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00112                          self.ob.fake_skin.getDirPath() )
00113 
00114     # linux PRODUCTS_PATH
00115     def test_getDirectoryInfo6(self):
00116         skin = self.ob.fake_skin
00117         skin.manage_properties( mktemp() +
00118                                 '/Products/CMFCore/tests/fake_skins/fake_skin')
00119         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00120                          self.ob.fake_skin.getDirPath() )
00121 
00122     # second 'Products' in path
00123     def test_getDirectoryInfo7(self):
00124         skin = self.ob.fake_skin
00125         skin.manage_properties(
00126            r'C:\CoolProducts\Zope\Products\CMFCore\tests\fake_skins\fake_skin')
00127         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00128                          self.ob.fake_skin.getDirPath() )
00129 
00130     # Test pre CMF 2.1 backwards compatibility code in DirectoryView's __of__
00131     # method.
00132     def test_getDirectoryInfo8(self):
00133         skin = self.ob.fake_skin
00134         skin.manage_properties('CMFCore/tests/fake_skins/fake_skin')
00135         self.failUnless( hasattr(self.ob.fake_skin, 'test1'),
00136                          self.ob.fake_skin.getDirPath() )
00137 
00138     # Test we do nothing if given a really wacky path
00139     def test_UnhandleableExpandPath( self ):
00140         from tempfile import mktemp
00141         self._trap_warning_output()
00142         file = mktemp()
00143         self.ob.fake_skin.manage_properties(file)
00144         self.assertEqual(self.ob.fake_skin.objectIds(),[])
00145         # Check that a warning was raised.
00146         from Products.CMFCore import DirectoryView
00147         warnings = [t[0] for t in DirectoryView.__warningregistry__]
00148         text = 'DirectoryView fake_skin refers to a non-existing path %r' % file
00149         self.assert_(text in warnings)
00150         self.failUnless(text in self._our_stderr_stream.getvalue())
00151 
00152     def test_UnhandleableMinimalPath( self ):
00153         from Products.CMFCore.utils import minimalpath, normalize
00154         from tempfile import mktemp
00155         weirdpath = mktemp()
00156         # we need to normalize 'cos minimalpath does, btu we're not testing
00157         # normalize in this unit test.
00158         self.assertEqual( normalize(weirdpath), minimalpath(weirdpath) )
00159 
00160     # this test tests that registerDirectory creates keys in the right format.
00161     def test_registerDirectoryKeys(self):
00162         from Products.CMFCore.DirectoryView import _dirreg
00163         dirs = _dirreg._directories
00164         self.failUnless( dirs.has_key('Products.CMFCore.tests:fake_skins/fake_skin'),
00165                          dirs.keys() )
00166         self.assertEqual( self.ob.fake_skin.getDirPath(),
00167                           'Products.CMFCore.tests:fake_skins/fake_skin' )
00168 
00169 
00170 class DirectoryViewTests( FSDVTest ):
00171 
00172     def setUp( self ):
00173         FSDVTest.setUp(self)
00174         self._registerDirectory(self)
00175 
00176     def test_addDirectoryViews( self ):
00177         # Test addDirectoryViews
00178         # also test registration of directory views doesn't barf
00179         pass
00180 
00181     def test_DirectoryViewExists( self ):
00182         # Check DirectoryView added by addDirectoryViews
00183         # appears as a DirectoryViewSurrogate due
00184         # to Acquisition hackery.
00185         from Products.CMFCore.DirectoryView import DirectoryViewSurrogate
00186         self.failUnless(isinstance(self.ob.fake_skin,DirectoryViewSurrogate))
00187 
00188     def test_DirectoryViewMethod( self ):
00189         # Check if DirectoryView method works
00190         self.assertEqual(self.ob.fake_skin.test1(),'test1')
00191 
00192     def test_properties(self):
00193         # Make sure the directory view is reading properties
00194         self.assertEqual(self.ob.fake_skin.testPT.title, 'Zope Pope')
00195 
00196     def test_ignored(self):
00197         # Test that "artifact" files and dirs are ignored
00198         for name in '#test1', 'CVS', '.test1', 'test1~':
00199             assert(name not in self.ob.fake_skin.objectIds(),
00200                    '%s not ignored' % name)
00201 
00202     def test_surrogate_writethrough(self):
00203         # CMF Collector 316: It is possible to cause ZODB writes because
00204         # setting attributes on the non-persistent surrogate writes them
00205         # into the persistent DirectoryView as well. This is bad in situations
00206         # where you only want to store markers and remove them before the
00207         # transaction has ended - they never got removed because there was
00208         # no equivalent __delattr__ on the surrogate that would clean up
00209         # the persistent DirectoryView as well.
00210         fs = self.ob.fake_skin
00211         test_foo = 'My Foovalue'
00212         fs.foo = test_foo
00213 
00214         self.assertEqual(fs.foo, test_foo)
00215         self.assertEqual(fs.__dict__['_real'].foo, test_foo)
00216 
00217         del fs.foo
00218 
00219         self.assertRaises(AttributeError, getattr, fs, 'foo')
00220         self.assertRaises( AttributeError
00221                          , getattr
00222                          , fs.__dict__['_real']
00223                          , 'foo'
00224                          )
00225 
00226 
00227 class DirectoryViewIgnoreTests(FSDVTest):
00228 
00229     def setUp( self ):
00230         FSDVTest.setUp(self)
00231         self.manual_ign = ('CVS', 'SVN', 'test_manual_ignore.py')
00232         self._registerDirectory(self , ignore=self.manual_ign)
00233 
00234     def test_ignored(self):
00235         # Test that "artifact" files and dirs are ignored,
00236         # even when a custom ignore list is used; and that the
00237         # custom ignore list is also honored
00238         auto_ign = ('#test1', '.test1', 'test1~')
00239         must_ignore = self.manual_ign + auto_ign + ('test_manual_ignore',)
00240         visible = self.ob.fake_skin.objectIds()
00241 
00242         for name in must_ignore:
00243             self.failIf(name in visible)
00244 
00245 
00246 class DirectoryViewFolderTests(FSDVTest):
00247 
00248     def setUp(self):
00249         FSDVTest.setUp(self)
00250         self._registerDirectory(self)
00251 
00252     def tearDown(self):
00253         from Products.CMFCore import DirectoryView
00254         # This is nasty, but there is no way to unregister anything
00255         # right now...
00256         metatype_registry = DirectoryView._dirreg._meta_types
00257         if 'FOLDER' in metatype_registry.keys():
00258             del metatype_registry['FOLDER']
00259         FSDVTest.tearDown(self)
00260 
00261     def test_DirectoryViewMetadata(self):
00262         # Test to determine if metadata shows up correctly on a
00263         # FSDV that has a corresponding .metadata file
00264         testfolder = self.ob.fake_skin.test_directory
00265         self.assertEqual(testfolder.title, 'test_directory Title')
00266 
00267     def test_DirectoryViewFolderDefault(self):
00268         # Test that a folder inside the fake skin really is of type
00269         # DirectoryViewSurrogate
00270         from Products.CMFCore.DirectoryView import DirectoryViewSurrogate
00271         testfolder = self.ob.fake_skin.test_directory
00272         self.failUnless(isinstance(testfolder, DirectoryViewSurrogate))
00273 
00274     def test_DirectoryViewFolderCustom(self):
00275         # Now we register a different class under the fake meta_type
00276         # "FOLDER" and test again...
00277         from Products.CMFCore.DirectoryView import registerMetaType
00278         registerMetaType('FOLDER', DummyDirectoryView)
00279 
00280         # In order to regenerate the FSDV data we need to remove and
00281         # register again, that way the newly registered meta_type is used
00282         self.ob._delObject('fake_skin')
00283         self._registerDirectory(self)
00284         testfolder = self.ob.fake_skin.test_directory
00285         self.failUnless(isinstance(testfolder, DummyDirectoryViewSurrogate))
00286 
00287 
00288 if DevelopmentMode:
00289 
00290   class DebugModeTests(WritableFSDVTest):
00291 
00292     def setUp( self ):
00293         WritableFSDVTest.setUp(self)
00294         self.test1path = join(self.skin_path_name,'test1.py')
00295         self.test2path = join(self.skin_path_name,'test2.py')
00296         self.test3path = join(self.skin_path_name,'test3')
00297 
00298         # initialise skins
00299         self._registerDirectory(self)
00300 
00301         # add a method to the fake skin folder
00302         self._writeFile(self.test2path, "return 'test2'")
00303 
00304         # edit the test1 method
00305         self._writeFile(self.test1path, "return 'new test1'")
00306 
00307         # add a new folder
00308         mkdir(self.test3path)
00309 
00310     def test_AddNewMethod( self ):
00311         # See if a method added to the skin folder can be found
00312         self.assertEqual(self.ob.fake_skin.test2(),'test2')
00313 
00314     def test_EditMethod( self ):
00315         # See if an edited method exhibits its new behaviour
00316         self.assertEqual(self.ob.fake_skin.test1(),'new test1')
00317 
00318     def test_NewFolder( self ):
00319         # See if a new folder shows up
00320         from Products.CMFCore.DirectoryView import DirectoryViewSurrogate
00321         self.failUnless(isinstance(self.ob.fake_skin.test3,DirectoryViewSurrogate))
00322         self.ob.fake_skin.test3.objectIds()
00323 
00324     def test_DeleteMethod( self ):
00325         # Make sure a deleted method goes away
00326         remove(self.test2path)
00327         self.failIf(hasattr(self.ob.fake_skin,'test2'))
00328 
00329     def test_DeleteAddEditMethod( self ):
00330         # Check that if we delete a method, then add it back,
00331         # then edit it, the DirectoryView notices.
00332         # This exercises yet another Win32 mtime weirdity.
00333         remove(self.test2path)
00334         self.failIf(hasattr(self.ob.fake_skin,'test2'))
00335 
00336         # add method back to the fake skin folder
00337         self._writeFile(self.test2path, "return 'test2.2'")
00338 
00339         # check
00340         self.assertEqual(self.ob.fake_skin.test2(),'test2.2')
00341 
00342         # edit method
00343         self._writeFile(self.test2path, "return 'test2.3'")
00344 
00345         # check
00346         self.assertEqual(self.ob.fake_skin.test2(),'test2.3')
00347 
00348     def test_DeleteFolder( self ):
00349         # Make sure a deleted folder goes away
00350         rmdir(self.test3path)
00351         self.failIf(hasattr(self.ob.fake_skin,'test3'))
00352 
00353 else:
00354 
00355     class DebugModeTests(unittest.TestCase):
00356         pass
00357 
00358 
00359 def test_suite():
00360     return unittest.TestSuite((
00361         unittest.makeSuite(DirectoryViewPathTests),
00362         unittest.makeSuite(DirectoryViewTests),
00363         unittest.makeSuite(DirectoryViewIgnoreTests),
00364         unittest.makeSuite(DirectoryViewFolderTests),
00365         unittest.makeSuite(DebugModeTests),
00366         ))
00367 
00368 if __name__ == '__main__':
00369     unittest.main(defaultTest='test_suite')