Back to index

plone3  3.1.7
test_OpaqueItems.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 IOpaqueItems implementations.
00014 
00015 $Id: test_OpaqueItems.py 77004 2007-06-24 08:57:54Z yuppie $
00016 """
00017 
00018 import unittest
00019 import Testing
00020 
00021 from zope.interface import implements
00022 
00023 from Products.CMFCore.interfaces import ICallableOpaqueItem
00024 from Products.CMFCore.interfaces import ICallableOpaqueItemEvents
00025 from Products.CMFCore.interfaces import IContentish
00026 from Products.CMFCore.interfaces.IOpaqueItems \
00027         import ICallableOpaqueItem as z2ICallableOpaqueItem
00028 from Products.CMFCore.interfaces.IOpaqueItems \
00029         import ICallableOpaqueItemEvents as z2ICallableOpaqueItemEvents
00030 from Products.CMFCore.PortalFolder import PortalFolder
00031 from Products.CMFCore.testing import TraversingEventZCMLLayer
00032 from Products.CMFCore.tests.base.dummy \
00033     import DummyContent as OriginalDummyContent
00034 from Products.CMFCore.tests.base.testcase import SecurityTest
00035 from Products.CMFCore.TypesTool import TypesTool
00036 
00037 
00038 # -------------------------------------------
00039 # Helper classes and functions
00040 # -------------------------------------------
00041 
00042 def extra_meta_types():
00043     return [{'name': 'Dummy', 'action': 'manage_addFolder',
00044              'permission': 'View'}]
00045 
00046 def addDummyContent(container, id, opaqueItem):
00047     container._setObject(id, DummyContent(id, opaqueItem=opaqueItem, catalog=1))
00048     return getattr(container, id)
00049 
00050 
00051 class DummyContent(OriginalDummyContent):
00052 
00053     """ A Dummy piece of PortalContent with additional attributes
00054     """
00055     implements(IContentish)
00056 
00057     def __init__(self, id='dummy', opaqueItem=None, *args, **kw):
00058         OriginalDummyContent.__init__(self, id, *args, **kw)
00059         if opaqueItem is None:
00060             self.opaqueItem = 'noncallable'
00061             self.opaqueItemsId = 'opaqueItem'
00062         elif isinstance(opaqueItem, basestring):
00063             Hooks(self, opaqueItem)
00064             self.opaqueItemsId = opaqueItem
00065         else:
00066             opaqueItem(self, 'opaqueItem')
00067             self.opaqueItemsId = 'opaqueItem'
00068 
00069     # Ensure additional attributes get copied
00070     def _getCopy(self, container):
00071         obj = DummyContent(self.id, catalog=self.catalog)
00072         setattr(obj, self.opaqueItemsId, getattr(self, self.opaqueItemsId))
00073         return obj
00074 
00075     def isNotifiedByAfterAdd(self):
00076         return getattr(getattr(self, self.opaqueItemsId), 'addCount', None)
00077 
00078     def isNotifiedByAfterClone(self):
00079         return getattr(getattr(self, self.opaqueItemsId), 'cloneCount', None)
00080 
00081     def isNotifiedByBeforeDelete(self):
00082         return getattr(getattr(self, self.opaqueItemsId), 'deleteCount', None)
00083 
00084 
00085 class OpaqueBase:
00086     """ Dummy opaque item without manage_after/before hookes
00087     """
00088     def __init__(self, obj, id):
00089         self.addCount = self.cloneCount = self.deleteCount = 0
00090         self.addCounter = self.cloneCounter = self.deleteCounter = 1
00091         self.id = id
00092         setattr(obj, id, self)
00093 
00094     def __call__():
00095         return
00096 
00097     def getId(self):
00098         return self.id
00099 
00100 
00101 class Marker(OpaqueBase):
00102 
00103     """ Opaque item without manage_after/before hookes but marked as callable
00104     """
00105 
00106     implements(ICallableOpaqueItem)
00107     __implements__ = (
00108         z2ICallableOpaqueItem,
00109     )
00110 
00111 
00112 class Hooks(OpaqueBase):
00113 
00114     """ Opaque item with manage_after/before hooks but not marked as callable
00115     """
00116 
00117     implements(ICallableOpaqueItemEvents)
00118     __implements__ = (
00119         z2ICallableOpaqueItemEvents,
00120     )
00121 
00122     def manage_afterAdd(self, item, container):
00123         self.addCount = self.addCounter
00124         self.addCounter += 1
00125 
00126     def manage_afterClone(self, item):
00127         self.cloneCount = self.cloneCounter
00128         self.cloneCounter += 1
00129 
00130     def manage_beforeDelete(self, item, container):
00131         self.deleteCount = self.deleteCounter
00132         self.deleteCounter += 1
00133 
00134 
00135 class MarkerAndHooks(Marker, Hooks):
00136 
00137     """ Opaque item with manage_after/before hookes and marked as callable
00138     """
00139     __implements__ = Marker.__implements__ + Hooks.__implements__
00140 
00141 
00142 # -------------------------------------------
00143 # Unit Tests
00144 # -------------------------------------------
00145 
00146 class ManageBeforeAfterTests(SecurityTest):
00147 
00148     layer = TraversingEventZCMLLayer
00149 
00150     def setUp(self):
00151         SecurityTest.setUp(self)
00152 
00153         root = self.root
00154 
00155         # setting up types tool
00156         root._setObject( 'portal_types', TypesTool() )
00157 
00158         # setup portal
00159         try:
00160             root._delObject('test')
00161         except AttributeError:
00162             pass
00163         root._setObject('test', PortalFolder('test', ''))
00164         self.test = test = self.root.test
00165 
00166         # setting up folders
00167         test._setObject( 'folder', PortalFolder( 'folder', '' ) )
00168         folder = self.folder = test.folder
00169         folder._setObject( 'sub', PortalFolder( 'sub', '' ) )
00170         sub = self.sub = folder.sub
00171 
00172         #----- hacks to allow pasting (see also test_PortalFolder)
00173         # WAAA! force sub to allow paste of Dummy object.
00174         sub.all_meta_types = extra_meta_types()
00175 
00176         # delete items if necessary
00177         try:
00178             folder._delObject('dummy')
00179         except AttributeError:
00180             pass
00181         try:
00182             sub._delObject('dummy')
00183         except AttributeError:
00184             pass
00185 
00186     def test_nonCallableItem(self):
00187         # no exception should be raised
00188         folder = self.folder
00189         sub = self.sub
00190         dummy = addDummyContent(folder, 'dummy', None)
00191 
00192         # WAAAA! must get _p_jar set
00193         old, dummy._p_jar = sub._p_jar, self.root._p_jar
00194         try:
00195             cp = folder.manage_copyObjects(ids=['dummy'])
00196             sub.manage_pasteObjects(cp)
00197         finally:
00198             dummy._p_jar = old
00199 
00200     def test_callableItemWithMarkerOnly(self):
00201         folder = self.folder
00202         sub = self.sub
00203         dummy = addDummyContent(folder, 'dummy', Marker)
00204 
00205         self.failIf(dummy.isNotifiedByAfterAdd())
00206         self.failIf(dummy.isNotifiedByAfterClone())
00207         self.failIf(dummy.isNotifiedByBeforeDelete())
00208 
00209         # WAAAA! must get _p_jar set
00210         old, dummy._p_jar = sub._p_jar, self.root._p_jar
00211         try:
00212             cp = folder.manage_copyObjects(ids=['dummy'])
00213             sub.manage_pasteObjects(cp)
00214         finally:
00215             dummy._p_jar = old
00216 
00217         self.failIf(dummy.isNotifiedByAfterAdd())
00218         self.failIf(dummy.isNotifiedByAfterClone())
00219         self.failIf(dummy.isNotifiedByBeforeDelete())
00220 
00221     def test_callableItemWithHooksOnly(self):
00222         folder = self.folder
00223         sub = self.sub
00224         dummy = addDummyContent(folder, 'dummy', Hooks)
00225 
00226         self.failIf(dummy.isNotifiedByAfterAdd())
00227         self.failIf(dummy.isNotifiedByAfterClone())
00228         self.failIf(dummy.isNotifiedByBeforeDelete())
00229 
00230         # WAAAA! must get _p_jar set
00231         old, dummy._p_jar = sub._p_jar, self.root._p_jar
00232         try:
00233             cp = folder.manage_copyObjects(ids=['dummy'])
00234             sub.manage_pasteObjects(cp)
00235         finally:
00236             dummy._p_jar = old
00237 
00238         self.failIf(dummy.isNotifiedByAfterAdd())
00239         self.failIf(dummy.isNotifiedByAfterClone())
00240         self.failIf(dummy.isNotifiedByBeforeDelete())
00241 
00242     def test_callableItemWithMarkerAndHooks(self):
00243         folder = self.folder
00244         sub = self.sub
00245         dummy = addDummyContent(folder, 'dummy', MarkerAndHooks)
00246 
00247         self.assertEqual(dummy.isNotifiedByAfterAdd(), 1)
00248         self.failIf(dummy.isNotifiedByAfterClone())
00249         self.failIf(dummy.isNotifiedByBeforeDelete())
00250 
00251         # WAAAA! must get _p_jar set
00252         old, dummy._p_jar = sub._p_jar, self.root._p_jar
00253         try:
00254             cp = folder.manage_copyObjects(ids=['dummy'])
00255             sub.manage_pasteObjects(cp)
00256         finally:
00257             dummy._p_jar = old
00258 
00259         self.assertEqual(dummy.isNotifiedByAfterAdd(), 2)
00260         self.assertEqual(dummy.isNotifiedByAfterClone(), 1)
00261         self.failIf(dummy.isNotifiedByBeforeDelete())
00262 
00263     def test_talkbackItem(self):
00264         folder = self.folder
00265         sub = self.sub
00266 
00267         dummy = addDummyContent(folder, 'dummy', 'talkback')
00268 
00269         self.assertEqual(dummy.isNotifiedByAfterAdd(), 1)
00270         self.failIf(dummy.isNotifiedByAfterClone())
00271         self.failIf(dummy.isNotifiedByBeforeDelete())
00272 
00273         # WAAAA! must get _p_jar set
00274         old, dummy._p_jar = sub._p_jar, self.root._p_jar
00275         try:
00276             cp = folder.manage_copyObjects(ids=['dummy'])
00277             sub.manage_pasteObjects(cp)
00278         finally:
00279             dummy._p_jar = old
00280 
00281         self.assertEqual(dummy.isNotifiedByAfterAdd(), 2)
00282         self.assertEqual(dummy.isNotifiedByAfterClone(), 1)
00283         self.failIf(dummy.isNotifiedByBeforeDelete())
00284 
00285 
00286 def test_suite():
00287     return unittest.TestSuite((
00288         unittest.makeSuite(ManageBeforeAfterTests),
00289         ))
00290 
00291 if __name__ == '__main__':
00292     from Products.CMFCore.testing import run
00293     run(test_suite())