Back to index

plone3  3.1.7
test_ModifierRegistryTool.py
Go to the documentation of this file.
00001 #########################################################################
00002 # Copyright (c) 2004, 2005 Alberto Berti, Gregoire Weber.
00003 # Reflab (Vincenzo Di Somma, Francesco Ciriaci, Riccardo Lemmi)
00004 # All Rights Reserved.
00005 # 
00006 # This file is part of CMFEditions.
00007 # 
00008 # CMFEditions is free software; you can redistribute it and/or modify
00009 # it under the terms of the GNU General Public License as published by
00010 # the Free Software Foundation; either version 2 of the License, or
00011 # (at your option) any later version.
00012 # 
00013 # CMFEditions is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 # GNU General Public License for more details.
00017 # 
00018 # You should have received a copy of the GNU General Public License
00019 # along with CMFEditions; if not, write to the Free Software
00020 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00021 #########################################################################
00022 """
00023 $Id: test_ModifierRegistryTool.py,v 1.12 2005/02/25 22:04:00 tomek1024 Exp $
00024 """
00025 
00026 from Products.PloneTestCase import PloneTestCase
00027 PloneTestCase.setupPloneSite()
00028 
00029 
00030 from pickle import dumps, loads, HIGHEST_PROTOCOL
00031 
00032 from Interface.Verify import verifyObject
00033 from Acquisition import aq_base
00034 
00035 from Products.CMFCore.utils import getToolByName
00036 
00037 from Products.CMFEditions.interfaces.IModifier import IModifierRegistrySet
00038 from Products.CMFEditions.interfaces.IModifier import ISaveRetrieveModifier
00039 from Products.CMFEditions.interfaces.IModifier import IAttributeModifier
00040 from Products.CMFEditions.interfaces.IModifier import ICloneModifier
00041 from Products.CMFEditions.interfaces.IModifier import IModifierRegistryQuery
00042 
00043 
00044 # provoke the warning messages before the first test
00045 from OFS.SimpleItem import SimpleItem
00046 class Dummy(SimpleItem):
00047     pass
00048 def deepcopy(obj):
00049     return loads(dumps(obj, HIGHEST_PROTOCOL))
00050 deepcopy(Dummy())
00051 
00052 
00053 class SimpleModifierBase:
00054 
00055     __implements__ = (ISaveRetrieveModifier,)
00056 
00057     def beforeSaveModifier(self, obj, copy_obj):
00058         try:
00059             bsm = getattr(copy_obj, self.beforeSaveModifierAttribute)
00060             bsm += 1
00061         except AttributeError:
00062             bsm = 1
00063         setattr(copy_obj, self.beforeSaveModifierAttribute, bsm)
00064         return {}, [], []
00065 
00066     def afterRetrieveModifier(self, obj, repo_obj):
00067         try:
00068             arm = getattr(repo_obj, self.afterRetrieveModifierAttribute)
00069             arm += 1
00070         except AttributeError:
00071             arm = 1
00072         setattr(repo_obj, self.afterRetrieveModifierAttribute, arm)
00073         return [], [], {}
00074 
00075 class SimpleModifier1(SimpleModifierBase):
00076     beforeSaveModifierAttribute = 'beforeSave1'
00077     afterRetrieveModifierAttribute = 'afterRetrieve1'
00078 
00079 class SimpleModifier2(SimpleModifierBase):
00080     beforeSaveModifierAttribute = 'beforeSave2'
00081     afterRetrieveModifierAttribute = 'afterRetrieve2'
00082 
00083 class SimpleModifier3(SimpleModifierBase):
00084     beforeSaveModifierAttribute = 'beforeSave3'
00085     afterRetrieveModifierAttribute = 'afterRetrieve3'
00086 
00087 class NonModifier(SimpleItem):
00088     pass
00089 
00090 mlog = []
00091 
00092 def dictToString(dict):
00093     dict_list = []
00094     keys = [key for key in dict.keys()]
00095     keys.sort()
00096     for k in keys:
00097         dict_list.append("%s = %s" % (k, dict[k]))
00098     return ', '.join(dict_list)
00099 
00100 class LoggingModifierBase:
00101 
00102     __implements__ = (IAttributeModifier, ICloneModifier, ISaveRetrieveModifier)
00103 
00104     def getReferencedAttributes(self, obj):
00105         referenced_data = {
00106             'k1': 'v1:'+str(self.__class__.__name__), 
00107             'k2': 'v2:'+str(self.__class__.__name__), 
00108         }
00109         mlog.append("%s.getReferencedAttributes: %s" % 
00110                     (self.__class__.__name__, dictToString(referenced_data)))
00111         return referenced_data
00112         
00113     def getOnCloneModifiers(self, obj):
00114         mlog.append("%s.getOnCloneModifiers" % (self.__class__.__name__))
00115         
00116         def persistent_id(obj):
00117             return None
00118             
00119         def persistent_load(pid):
00120             # should never reach this!
00121             assert False
00122         
00123         return persistent_id, persistent_load, [], [], ''
00124 
00125     def beforeSaveModifier(self, obj, obj_clone):
00126         mlog.append("%s.beforeSaveModifier" % (self.__class__.__name__))
00127         return {}, [], []
00128         
00129     def afterRetrieveModifier(self, obj, repo_clone, preserve=()):
00130         mlog.append("%s.afterRetrieveModifier" % (self.__class__.__name__))
00131         return [], [], {}
00132 
00133 class LoggingModifier_A(LoggingModifierBase):
00134     pass
00135 
00136 class LoggingModifier_B(LoggingModifierBase):
00137     pass
00138 
00139 class LoggingModifier_C(LoggingModifierBase):
00140     pass
00141 
00142 class LoggingModifier_D(LoggingModifierBase):
00143     pass
00144 
00145 loggingModifiers = (
00146     LoggingModifier_A(),
00147     LoggingModifier_B(),
00148     LoggingModifier_C(),
00149     LoggingModifier_D(),
00150 )
00151 
00152 class TestModifierRegistryTool(PloneTestCase.PloneTestCase):
00153 
00154     def afterSetUp(self):
00155         # we need to have the Manager role to be able to add things
00156         # to the portal root
00157         self.setRoles(['Manager',])
00158 
00159         # add an additional user
00160         self.portal.acl_users.userFolderAddUser('reviewer', 'reviewer',
00161                                                 ['Manager'], '')
00162         # add a document
00163         self.portal.invokeFactory('Document', 'doc')
00164 
00165         # just unregister the standard modifiers for the unit tests
00166         portal_modifier = getToolByName(self.portal, 'portal_modifier')
00167         modifiers = portal_modifier.modules.StandardModifiers.modifiers
00168         for m in modifiers:
00169             portal_modifier.unregister(m['id'])
00170 
00171     def test00_interface(self):
00172         portal_modifier = self.portal.portal_modifier
00173 
00174         # test interface conformance
00175         #verifyObject(IModifier, portal_modifier)
00176         verifyObject(IModifierRegistrySet, portal_modifier)
00177         verifyObject(IModifierRegistryQuery, portal_modifier)
00178 #        verifyObject(IBulkEditableSubscriberRegistry, portal_modifier)
00179 
00180     def test01_modifiersNotCalled(self):
00181         portal_modifier = self.portal.portal_modifier
00182         doc = self.portal.doc
00183         doc_copy = deepcopy(aq_base(doc))
00184 
00185         portal_modifier.register('1', SimpleModifier1())
00186         portal_modifier.edit('1', condition='python:True')
00187         portal_modifier.beforeSaveModifier(doc, doc_copy)
00188         portal_modifier.afterRetrieveModifier(doc, doc_copy)
00189         self.assertRaises(AttributeError, getattr, doc_copy, 'beforeSave1')
00190         self.assertRaises(AttributeError, getattr, doc_copy, 'afterRetrieve1')
00191 
00192     def test02_enabledModifierCalled(self):
00193         portal_modifier = self.portal.portal_modifier
00194         doc = self.portal.doc
00195         doc_copy = deepcopy(aq_base(doc))
00196 
00197         portal_modifier.register('1', SimpleModifier1())
00198         portal_modifier.edit('1', enabled=True, condition='python:True')
00199         portal_modifier.beforeSaveModifier(doc, doc_copy)
00200         portal_modifier.afterRetrieveModifier(doc, doc_copy)
00201 
00202         portal_modifier.beforeSaveModifier(doc, doc_copy)
00203         self.assertEqual(doc_copy.beforeSave1, 2)
00204         self.assertEqual(doc_copy.afterRetrieve1, 1)
00205 
00206     def test03_unregisteredModifiersNotCalled(self):
00207         portal_modifier = self.portal.portal_modifier
00208         doc = self.portal.doc
00209         doc_copy = deepcopy(aq_base(doc))
00210 
00211         portal_modifier.register('1', SimpleModifier1())
00212         portal_modifier.edit('1', enabled=True, condition='python:True')
00213         portal_modifier.beforeSaveModifier(doc, doc_copy)
00214         self.assertEqual(doc_copy.beforeSave1, 1)
00215         self.assertRaises(AttributeError, getattr, doc_copy, 'afterRetrieve1')
00216         portal_modifier.unregister('1')
00217         portal_modifier.beforeSaveModifier(doc, doc_copy)
00218         self.assertEqual(doc_copy.beforeSave1, 1)
00219         self.assertRaises(AttributeError, getattr, doc_copy, 'afterRetrieve1')
00220 
00221     def test04_conditionEvaluated(self):
00222         portal_modifier = self.portal.portal_modifier
00223         doc = self.portal.doc
00224         doc_copy = deepcopy(aq_base(doc))
00225 
00226         portal_modifier.register('1', SimpleModifier1())
00227         portal_modifier.edit('1', enabled=True, condition='python:False')
00228         portal_modifier.beforeSaveModifier(doc, doc_copy)
00229         portal_modifier.afterRetrieveModifier(doc, doc_copy)
00230         self.assertRaises(AttributeError, getattr, doc_copy, 'beforeSave1')
00231         self.assertRaises(AttributeError, getattr, doc_copy, 'afterRetrieve1')
00232 
00233     def test05_registerANonModifier(self):
00234         portal_modifier = self.portal.portal_modifier
00235         doc = self.portal.doc
00236         doc_copy = deepcopy(aq_base(doc))
00237 
00238         portal_modifier._setObject('doc', NonModifier())
00239         portal_modifier.beforeSaveModifier(doc, doc_copy)
00240         portal_modifier.afterRetrieveModifier(doc, doc_copy)
00241         self.assertRaises(AttributeError, getattr, doc_copy, 'beforeSave1')
00242         self.assertRaises(AttributeError, getattr, doc_copy, 'afterRetrieve1')
00243 
00244     def test06_modifierAddedToTheCorrectPosition(self):
00245         portal_modifier = self.portal.portal_modifier
00246 
00247         m1 = SimpleModifier1()
00248         m2 = SimpleModifier2()
00249         m3 = SimpleModifier3()
00250 
00251         portal_modifier.register('1', m1)
00252         portal_modifier.register('2', m2)
00253         portal_modifier.register('3', m3, pos=0)
00254 
00255         modifiers = [m.getModifier() for m in portal_modifier.objectValues()]
00256         self.assertEqual(modifiers, [m3, m1, m2])
00257 
00258     def test07_unregisterModifer(self):
00259         portal_modifier = self.portal.portal_modifier
00260 
00261         m1 = SimpleModifier1()
00262         m2 = SimpleModifier2()
00263         m3 = SimpleModifier3()
00264 
00265         portal_modifier.register('1', m1)
00266         portal_modifier.register('2', m2)
00267         portal_modifier.register('3', m3, pos=0)
00268 
00269         portal_modifier.unregister('1')
00270 
00271         modifiers = [m.getModifier() for m in portal_modifier.objectValues()]
00272         self.assertEqual(modifiers, [m3, m2])
00273 
00274     def test08_getModifiers(self):
00275         portal_modifier = self.portal.portal_modifier
00276 
00277         m1 = SimpleModifier1()
00278         m2 = SimpleModifier2()
00279         m3 = SimpleModifier3()
00280 
00281         portal_modifier.register('1', m1)
00282         portal_modifier.register('2', m2)
00283         portal_modifier.register('3', m3, pos=0)
00284 
00285         portal_modifier.unregister('1')
00286 
00287         self.assertEqual(portal_modifier.get('2').getModifier(), m2)
00288         self.assertEqual(portal_modifier.query('2').getModifier(), m2)
00289         self.assertRaises(AttributeError, portal_modifier.get, '1')
00290         self.assertEqual(portal_modifier.query('1', None), None)
00291 
00292     def test09_conditionContextSetUpCorretcly(self):
00293         portal_modifier = self.portal.portal_modifier
00294         doc = self.portal.doc
00295         doc_copy = deepcopy(aq_base(doc))
00296 
00297         # just check if variables got defined
00298         condition = 'python:"%s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s" % (' \
00299                     'object_url, ' \
00300                     'folder_url, ' \
00301                     'portal_url, ' \
00302                     'object, ' \
00303                     'folder, ' \
00304                     'portal, ' \
00305                     'nothing, ' \
00306                     'request, ' \
00307                     'modules, ' \
00308                     'member,' \
00309                     ')'
00310         portal_modifier.register('1', SimpleModifier1())
00311         portal_modifier.edit('1', enabled=True, condition=condition)
00312 
00313         portal_modifier.beforeSaveModifier(doc, doc_copy)
00314         portal_modifier.afterRetrieveModifier(doc, doc_copy)
00315         self.assertEqual(doc_copy.beforeSave1, 1)
00316         self.assertEqual(doc_copy.afterRetrieve1, 1)
00317 
00318     def test10_callingOrder(self):
00319         global mlog
00320         portal_modifier = self.portal.portal_modifier
00321         doc = self.portal.doc
00322         doc_copy = deepcopy(aq_base(doc))
00323 
00324         mlog = []
00325         counter = 0
00326         for m in loggingModifiers:
00327             counter += 1
00328             portal_modifier.register(str(counter), m)
00329             portal_modifier.edit(str(counter),
00330                                  enabled=True,
00331                                  condition='python:True')
00332 
00333         mlog.append('<save>')
00334         referenced_data = portal_modifier.getReferencedAttributes(doc)
00335         portal_modifier.getOnCloneModifiers(doc)
00336         portal_modifier.beforeSaveModifier(doc, doc_copy)
00337         mlog.append('<retrieve>')
00338 
00339         portal_modifier.afterRetrieveModifier(doc, doc_copy)
00340         mlog.append('<end>')
00341 
00342         mlog_str = '\n'.join(mlog).replace('__main__', 'CMFEditions.tests.test_ModifierRegistryTool')
00343         expected_result = \
00344 """<save>
00345 %(class)s_A.getReferencedAttributes: k1 = v1:%(class)s_A, k2 = v2:%(class)s_A
00346 %(class)s_B.getReferencedAttributes: k1 = v1:%(class)s_B, k2 = v2:%(class)s_B
00347 %(class)s_C.getReferencedAttributes: k1 = v1:%(class)s_C, k2 = v2:%(class)s_C
00348 %(class)s_D.getReferencedAttributes: k1 = v1:%(class)s_D, k2 = v2:%(class)s_D
00349 %(class)s_A.getOnCloneModifiers
00350 %(class)s_B.getOnCloneModifiers
00351 %(class)s_C.getOnCloneModifiers
00352 %(class)s_D.getOnCloneModifiers
00353 %(class)s_A.beforeSaveModifier
00354 %(class)s_B.beforeSaveModifier
00355 %(class)s_C.beforeSaveModifier
00356 %(class)s_D.beforeSaveModifier
00357 <retrieve>
00358 %(class)s_D.afterRetrieveModifier
00359 %(class)s_C.afterRetrieveModifier
00360 %(class)s_B.afterRetrieveModifier
00361 %(class)s_A.afterRetrieveModifier
00362 <end>"""%{'class':'LoggingModifier'}
00363         self.assertEqual(mlog_str, expected_result)
00364 
00365 
00366 from unittest import TestSuite, makeSuite
00367 def test_suite():
00368     suite = TestSuite()
00369     suite.addTest(makeSuite(TestModifierRegistryTool))
00370     return suite