[Zope-Checkins] SVN: Zope/branches/Zope-2_8-branch/lib/python/OFS/tests/testCopySupportHooks.py Added tests to go with http://www.zope.org/Collectors/Zope/2169

2006-08-21 Thread Stefan H. Holek
Log message for revision 69717:
  Added tests to go with http://www.zope.org/Collectors/Zope/2169
  

Changed:
  A   Zope/branches/Zope-2_8-branch/lib/python/OFS/tests/testCopySupportHooks.py

-=-
Added: 
Zope/branches/Zope-2_8-branch/lib/python/OFS/tests/testCopySupportHooks.py
===
--- Zope/branches/Zope-2_8-branch/lib/python/OFS/tests/testCopySupportHooks.py  
2006-08-21 11:59:41 UTC (rev 69716)
+++ Zope/branches/Zope-2_8-branch/lib/python/OFS/tests/testCopySupportHooks.py  
2006-08-21 12:27:33 UTC (rev 69717)
@@ -0,0 +1,244 @@
+import unittest
+import Testing
+import Zope2
+Zope2.startup()
+
+import transaction
+
+from Testing.makerequest import makerequest
+
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import noSecurityManager
+
+from OFS.SimpleItem import SimpleItem
+from OFS.Folder import Folder
+
+
+class HookCounter:
+'''Logs calls to old-school hooks'''
+
+def __init__(self):
+self.reset()
+
+def reset(self):
+self.count = 0
+self.afterAdd = [0]
+self.afterClone = [0]
+self.beforeDelete = [0]
+
+def manage_afterAdd(self, item, container):
+self.count = self.count + 1
+self.afterAdd.append(self.count)
+
+def manage_afterClone(self, item):
+self.count = self.count + 1
+self.afterClone.append(self.count)
+
+def manage_beforeDelete(self, item, container):
+self.count = self.count + 1
+self.beforeDelete.append(self.count)
+
+def order(self):
+return self.afterAdd[-1], self.afterClone[-1], self.beforeDelete[-1]
+
+
+class TestItem(HookCounter, SimpleItem):
+
+def __init__(self, id):
+HookCounter.__init__(self)
+self.id = id
+
+
+class TestFolder(HookCounter, Folder):
+
+def __init__(self, id):
+HookCounter.__init__(self)
+self.id = id
+
+def _verifyObjectPaste(self, object, validate_src=1):
+# Don't verify pastes as our test objects don't have
+# factory methods registered.
+pass
+
+def manage_afterAdd(self, item, container):
+HookCounter.manage_afterAdd(self, item, container)
+Folder.manage_afterAdd(self, item, container)
+
+def manage_afterClone(self, item):
+HookCounter.manage_afterClone(self, item)
+Folder.manage_afterClone(self, item)
+
+def manage_beforeDelete(self, item, container):
+HookCounter.manage_beforeDelete(self, item, container)
+Folder.manage_beforeDelete(self, item, container)
+
+
+try:
+from Products.Five.eventconfigure import setDeprecatedManageAddDelete
+setDeprecatedManageAddDelete(HookCounter)
+except ImportError:
+pass
+
+
+class HookTest(unittest.TestCase):
+
+def setUp(self):
+self.app = makerequest(Zope2.app())
+try:
+uf = self.app.acl_users
+uf._doAddUser('manager', 'secret', ['Manager'], [])
+user = uf.getUserById('manager').__of__(uf)
+newSecurityManager(None, user)
+except:
+self.tearDown()
+raise
+
+def tearDown(self):
+noSecurityManager()
+transaction.abort()
+self.app._p_jar.close()
+
+
+class TestCopySupport(HookTest):
+'''Tests the order in which the add/clone/del hooks are called'''
+
+def setUp(self):
+HookTest.setUp(self)
+# A folder
+self.app._setObject('folder', TestFolder('folder'))
+self.folder = self.app['folder']
+# A subfolder we are going to copy/move to
+self.folder._setObject('subfolder', TestFolder('subfolder'))
+self.subfolder = self.folder['subfolder']
+# A document we are going to copy/move
+self.folder._setObject('mydoc', TestItem('mydoc'))
+# Must have _p_jars
+transaction.savepoint(1)
+# Reset counters
+self.folder.mydoc.reset()
+
+def test_1_Clone(self):
+# Test clone
+self.subfolder.manage_clone(self.folder.mydoc, 'yourdoc')
+self.assertEqual(self.subfolder.yourdoc.order(), (1, 2, 0)) # add, 
clone
+
+def test_2_CopyPaste(self):
+# Test copy/paste
+cb = self.folder.manage_copyObjects(['mydoc'])
+self.subfolder.manage_pasteObjects(cb)
+self.assertEqual(self.subfolder.mydoc.order(), (1, 2, 0))   # add, 
clone
+
+def test_3_CutPaste(self):
+# Test cut/paste
+cb = self.folder.manage_cutObjects(['mydoc'])
+self.subfolder.manage_pasteObjects(cb)
+self.assertEqual(self.subfolder.mydoc.order(), (2, 0, 1))   # del, add
+
+def test_4_Rename(self):
+# Test rename
+self.folder.manage_renameObject('mydoc', 'yourdoc')
+self.assertEqual(self.folder.yourdoc.order(), (2, 0, 1))# del, add
+
+def test_5_COPY(self):
+# Test webdav COPY
+req = self.app.REQUEST
+req.environ['HTTP_DEPTH'] = 

[Zope-Checkins] SVN: Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py Added tests to go with http://www.zope.org/Collectors/Zope/2169

2006-08-21 Thread Stefan H. Holek
Log message for revision 69718:
  Added tests to go with http://www.zope.org/Collectors/Zope/2169
  

Changed:
  A   Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py

-=-
Added: Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py
===
--- Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py  
2006-08-21 12:27:33 UTC (rev 69717)
+++ Zope/branches/2.9/lib/python/OFS/tests/testCopySupportHooks.py  
2006-08-21 12:27:47 UTC (rev 69718)
@@ -0,0 +1,244 @@
+import unittest
+import Testing
+import Zope2
+Zope2.startup()
+
+import transaction
+
+from Testing.makerequest import makerequest
+
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import noSecurityManager
+
+from OFS.SimpleItem import SimpleItem
+from OFS.Folder import Folder
+
+
+class HookCounter:
+'''Logs calls to old-school hooks'''
+
+def __init__(self):
+self.reset()
+
+def reset(self):
+self.count = 0
+self.afterAdd = [0]
+self.afterClone = [0]
+self.beforeDelete = [0]
+
+def manage_afterAdd(self, item, container):
+self.count = self.count + 1
+self.afterAdd.append(self.count)
+
+def manage_afterClone(self, item):
+self.count = self.count + 1
+self.afterClone.append(self.count)
+
+def manage_beforeDelete(self, item, container):
+self.count = self.count + 1
+self.beforeDelete.append(self.count)
+
+def order(self):
+return self.afterAdd[-1], self.afterClone[-1], self.beforeDelete[-1]
+
+
+class TestItem(HookCounter, SimpleItem):
+
+def __init__(self, id):
+HookCounter.__init__(self)
+self.id = id
+
+
+class TestFolder(HookCounter, Folder):
+
+def __init__(self, id):
+HookCounter.__init__(self)
+self.id = id
+
+def _verifyObjectPaste(self, object, validate_src=1):
+# Don't verify pastes as our test objects don't have
+# factory methods registered.
+pass
+
+def manage_afterAdd(self, item, container):
+HookCounter.manage_afterAdd(self, item, container)
+Folder.manage_afterAdd(self, item, container)
+
+def manage_afterClone(self, item):
+HookCounter.manage_afterClone(self, item)
+Folder.manage_afterClone(self, item)
+
+def manage_beforeDelete(self, item, container):
+HookCounter.manage_beforeDelete(self, item, container)
+Folder.manage_beforeDelete(self, item, container)
+
+
+try:
+from Products.Five.eventconfigure import setDeprecatedManageAddDelete
+setDeprecatedManageAddDelete(HookCounter)
+except ImportError:
+pass
+
+
+class HookTest(unittest.TestCase):
+
+def setUp(self):
+self.app = makerequest(Zope2.app())
+try:
+uf = self.app.acl_users
+uf._doAddUser('manager', 'secret', ['Manager'], [])
+user = uf.getUserById('manager').__of__(uf)
+newSecurityManager(None, user)
+except:
+self.tearDown()
+raise
+
+def tearDown(self):
+noSecurityManager()
+transaction.abort()
+self.app._p_jar.close()
+
+
+class TestCopySupport(HookTest):
+'''Tests the order in which the add/clone/del hooks are called'''
+
+def setUp(self):
+HookTest.setUp(self)
+# A folder
+self.app._setObject('folder', TestFolder('folder'))
+self.folder = self.app['folder']
+# A subfolder we are going to copy/move to
+self.folder._setObject('subfolder', TestFolder('subfolder'))
+self.subfolder = self.folder['subfolder']
+# A document we are going to copy/move
+self.folder._setObject('mydoc', TestItem('mydoc'))
+# Must have _p_jars
+transaction.savepoint(1)
+# Reset counters
+self.folder.mydoc.reset()
+
+def test_1_Clone(self):
+# Test clone
+self.subfolder.manage_clone(self.folder.mydoc, 'yourdoc')
+self.assertEqual(self.subfolder.yourdoc.order(), (1, 2, 0)) # add, 
clone
+
+def test_2_CopyPaste(self):
+# Test copy/paste
+cb = self.folder.manage_copyObjects(['mydoc'])
+self.subfolder.manage_pasteObjects(cb)
+self.assertEqual(self.subfolder.mydoc.order(), (1, 2, 0))   # add, 
clone
+
+def test_3_CutPaste(self):
+# Test cut/paste
+cb = self.folder.manage_cutObjects(['mydoc'])
+self.subfolder.manage_pasteObjects(cb)
+self.assertEqual(self.subfolder.mydoc.order(), (2, 0, 1))   # del, add
+
+def test_4_Rename(self):
+# Test rename
+self.folder.manage_renameObject('mydoc', 'yourdoc')
+self.assertEqual(self.folder.yourdoc.order(), (2, 0, 1))# del, add
+
+def test_5_COPY(self):
+# Test webdav COPY
+req = self.app.REQUEST
+req.environ['HTTP_DEPTH'] = 'infinity'
+

[Zope-Checkins] SVN: Products.Five/branches/1.4/ Removed awful _zope_app usage which was causing ConnectionStateError problems.

2006-08-21 Thread Rocky Burt
Log message for revision 69719:
  Removed awful _zope_app usage which was causing ConnectionStateError problems.

Changed:
  U   Products.Five/branches/1.4/CHANGES.txt
  U   Products.Five/branches/1.4/fiveconfigure.py
  U   Products.Five/branches/1.4/pythonproducts.py
  U   Products.Five/branches/1.4/tests/test_pythonproducts.py

-=-
Modified: Products.Five/branches/1.4/CHANGES.txt
===
--- Products.Five/branches/1.4/CHANGES.txt  2006-08-21 12:27:47 UTC (rev 
69718)
+++ Products.Five/branches/1.4/CHANGES.txt  2006-08-21 13:53:13 UTC (rev 
69719)
@@ -2,6 +2,16 @@
 Five Changes
 
 
+Five 1.4.x
+==
+
+Bugfixes
+
+
+* Backported Zope 2.10's pythonproducts zope app handling to help resolve
+  an issue with ConnectionStateError's.
+
+
 Five 1.4.1 (2006-08-13)
 ===
 

Modified: Products.Five/branches/1.4/fiveconfigure.py
===
--- Products.Five/branches/1.4/fiveconfigure.py 2006-08-21 12:27:47 UTC (rev 
69718)
+++ Products.Five/branches/1.4/fiveconfigure.py 2006-08-21 13:53:13 UTC (rev 
69719)
@@ -27,6 +27,7 @@
 from App.ProductContext import ProductContext
 import Products
 from zLOG import LOG, ERROR
+import Zope2
 
 from zope.interface import classImplements, classImplementsOnly, implementedBy
 from zope.interface.interface import InterfaceClass
@@ -266,18 +267,25 @@
 raise ValueError(Must be a package and the  \
  package must be filesystem based)
 
-product = initializeProduct(module_, 
-module_.__name__, 
-module_.__path__[0], 
-pythonproducts._zope_app)
+app = Zope2.app()
+try:
+product = initializeProduct(module_, 
+module_.__name__, 
+module_.__path__[0],
+app)
 
-product.package_name = module_.__name__
+product.package_name = module_.__name__
 
-if initFunc is not None:
-newContext = ProductContext(product, pythonproducts._zope_app, module_)
-initFunc(newContext)
+if initFunc is not None:
+newContext = ProductContext(product, app, module_)
+initFunc(newContext)
+finally:
+try:
+import transaction
+transaction.commit()
+finally:
+app._p_jar.close()
 
-
 def registerPackage(_context, package, initialize=None):
 ZCML directive function for registering a python package product
 

Modified: Products.Five/branches/1.4/pythonproducts.py
===
--- Products.Five/branches/1.4/pythonproducts.py2006-08-21 12:27:47 UTC 
(rev 69718)
+++ Products.Five/branches/1.4/pythonproducts.py2006-08-21 13:53:13 UTC 
(rev 69719)
@@ -25,9 +25,8 @@
 from App.Product import initializeProduct
 from App.ProductContext import ProductContext
 from zope.testing import cleanup
+import Zope2
 
-_zope_app = None
-
 def isMonkeyPatched(m):
 return hasattr(m, '__five_method__')  
 
@@ -35,26 +34,18 @@
 Initialize the python-packages-as-products logic
 
 
-from OFS.Application import Application
-
-global _zope_app
-if isinstance(appOrContext, Application):
-_zope_app = appOrContext
-else:
-_zope_app = appOrContext._ProductContext__app
-
-applyPatches(_zope_app)
+applyPatches()
 
 
-def applyPatches(app):
+def applyPatches():
 Apply necessary monkey patches to force Zope 2 to be capable of
 handling products that are not necessarily located under the Products
 package.  Ultimately all functionality provided by these patches should
 be folded into Zope 2 core.
 
 
-patch_ProductDispatcher__bobo_traverse__(app)
-patch_externalmethod(app)
+patch_ProductDispatcher__bobo_traverse__()
+patch_externalmethod()
 
 def removePatches():
 Remove all monkey patches.
@@ -77,11 +68,11 @@
 # Most of these monkey patches were repurposed from the code I 
 # wrote for Basket - Rocky
 
-def product_packages(app):
+def product_packages():
 Returns all product packages including the regularly defined
 zope2 packages and those without the Products namespace package.
 
-
+
 old_product_packages = {}
 for x in dir(Products):
 m = getattr(Products, x)
@@ -89,23 +80,27 @@
 old_product_packages[x] = m
 
 packages = {}
-products = app.Control_Panel.Products
-for product_id in products.objectIds():
-product = products[product_id]
-if hasattr(product, 'package_name'):
-pos = product.package_name.rfind('.')
-if pos  -1:
-packages[product_id] = __import__(product.package_name, 
-