[Erp5-report] r45575 nicolas - in /erp5/trunk/products/CMFCategory: ./ tests/

nobody at svn.erp5.org nobody at svn.erp5.org
Tue Apr 19 16:40:53 CEST 2011


Author: nicolas
Date: Tue Apr 19 16:40:53 2011
New Revision: 45575

URL: http://svn.erp5.org?rev=45575&view=rev
Log:
Avoid implicit acquisition which access base_category twice if
stored category value are like 'region/region/west'.
This can be worse when base_category id is 'resource', because 'resource'
is also a namespace adapter in z2.12. So TraversalableHandler returns a non expected object and 
keep objects to be correctly indexed.


Modified:
    erp5/trunk/products/CMFCategory/CategoryTool.py
    erp5/trunk/products/CMFCategory/tests/testCMFCategory.py

Modified: erp5/trunk/products/CMFCategory/CategoryTool.py
URL: http://svn.erp5.org/erp5/trunk/products/CMFCategory/CategoryTool.py?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- erp5/trunk/products/CMFCategory/CategoryTool.py [utf8] (original)
+++ erp5/trunk/products/CMFCategory/CategoryTool.py [utf8] Tue Apr 19 16:40:53 2011
@@ -222,6 +222,9 @@ class CategoryTool( UniqueObject, Folder
         relative_url = str(relative_url)
         if base_category is not None:
           relative_url = '%s/%s' % (base_category, relative_url)
+        relative_url = \
+        self._removeDuplicateBaseCategoryIdInCategoryPath(base_category,
+                                                                 relative_url)
         node = self.unrestrictedTraverse(relative_url)
         value = node
       except (TypeError, KeyError, NotFound):
@@ -567,6 +570,7 @@ class CategoryTool( UniqueObject, Folder
           else:
             category = my_category.getRelativeUrl()
           if my_base_category == category:
+            path = self._removeDuplicateBaseCategoryIdInCategoryPath(my_base_category, path)
             if spec_len == 0:
               if base:
                 membership.append(path)
@@ -825,6 +829,7 @@ class CategoryTool( UniqueObject, Folder
         for category_url in self._getCategoryList(context):
           my_base_category = category_url.split('/', 1)[0]
           if my_base_category == base_category:
+            category_url = self._removeDuplicateBaseCategoryIdInCategoryPath(my_base_category, category_url)
             #LOG("getSingleCategoryMembershipList",0,"%s %s %s %s" % (context.getRelativeUrl(),
             #                  my_base_category, base_category, category_url))
             if (checked_permission is None) or \
@@ -1739,6 +1744,24 @@ class CategoryTool( UniqueObject, Folder
     getProperty = Base.getProperty
     hasProperty = Base.hasProperty
 
+    def _removeDuplicateBaseCategoryIdInCategoryPath(self, base_category_id,
+                                                     path):
+      """Specific Handling to remove duplicated base_categories in path
+      values like in following example: 'region/region/europe/west'.
+
+      If duplicated id is a real subobject of base_category,
+      then the path its keept as it is
+      """
+      splitted_path = path.split('/', 2)
+      if len(splitted_path) >= 2 and base_category_id == splitted_path[1]:
+        # It needs to be checked.
+        base_category_value = self._getOb(base_category_id)
+        if base_category_value._getOb(splitted_path[1], None) is None:
+          # Duplicate found, strip len(base_category_id + '/') in path
+          path = path[len(base_category_id)+1:]
+      return path
+
+
 InitializeClass( CategoryTool )
 
 # Psyco

Modified: erp5/trunk/products/CMFCategory/tests/testCMFCategory.py
URL: http://svn.erp5.org/erp5/trunk/products/CMFCategory/tests/testCMFCategory.py?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- erp5/trunk/products/CMFCategory/tests/testCMFCategory.py [utf8] (original)
+++ erp5/trunk/products/CMFCategory/tests/testCMFCategory.py [utf8] Tue Apr 19 16:40:53 2011
@@ -33,6 +33,8 @@ from Testing.ZopeTestCase.PortalTestCase
 from AccessControl.SecurityManagement import newSecurityManager
 from AccessControl.SecurityManagement import noSecurityManager
 
+import transaction
+
 try:
   from transaction import get as get_transaction
 except ImportError:
@@ -88,7 +90,7 @@ class TestCMFCategory(ERP5TypeTestCase):
     # we also enable 'destination' category on organisations
     self._organisation_categories = organisation_ti.getTypeBaseCategoryList()
     organisation_ti._setTypeBaseCategoryList(self._organisation_categories
-                                             + ['destination'])
+                                             + ['destination', 'resource'])
 
     # Make persons.
     person_module = self.getPersonModule()
@@ -151,11 +153,18 @@ class TestCMFCategory(ERP5TypeTestCase):
       portal_categories[bc].setAcquisitionCopyValue(0)
       portal_categories[bc].setAcquisitionAppendValue(0)
       portal_categories[bc].setFallbackBaseCategoryList(['subordination'])
+    for bc in ('resource', ):
+      if not hasattr(portal_categories, bc):
+        portal_categories.newContent(portal_type='Base Category',id=bc)
+      portal_categories[bc].setAcquisitionPortalTypeList("python: []")
+      portal_categories[bc].setAcquisitionMaskValue(0)
+      portal_categories[bc].setAcquisitionCopyValue(0)
+      portal_categories[bc].setAcquisitionAppendValue(0)
 
   def beforeTearDown(self):
     """Clean up."""
     # categories
-    for bc in ('region', 'subordination', 'gender'):
+    for bc in ('region', 'subordination', 'gender', 'resource'):
       bc_obj = self.getPortal().portal_categories[bc]
       bc_obj.manage_delObjects()
     # type informations
@@ -1010,6 +1019,67 @@ class TestCMFCategory(ERP5TypeTestCase):
     self.assertNotEquals([], list(category_tool.objectIds()))
     self.assertNotEquals([], list(category_tool.searchFolder()))
 
+  def test_duplicate_base_category_id_in_categories_list_properties(self):
+    """check that stored values like 'region/region/west' on categories property
+    are cleaned up by Getters to avoid accessing base_category through
+    implicit Acquisition.
+
+    If region is a sub Category of Base Category region,
+    Relative Url must not be stripped
+    """
+    portal_categories = self.getCategoriesTool()
+    organisation = self.getOrganisationModule().newContent(
+                                                  portal_type='Organisation',
+                                                  region='region/europe/west')
+    person = self.getPersonModule().newContent(portal_type='Person',
+                              default_career_subordination_value=organisation)
+    self.assertTrue(organisation.hasRegion())
+    self.assertEquals(organisation.getRegion(), 'europe/west')
+    self.assertEquals(organisation.getRegionList(), ['europe/west'])
+    old_west_region = organisation.getRegionValue()
+    self.assertEquals(old_west_region.getPortalType(), 'Category')
+
+    # Check acquired categories
+    self.assertEquals(person.getRegion(), 'europe/west')
+    self.assertEquals(person.getRegionList(), ['europe/west'])
+
+    region_base_category = portal_categories.region
+    new_region = region_base_category.newContent(portal_type='Category',
+                                                 id='region')
+    new_region = new_region.newContent(portal_type='Category', id='europe')
+    new_region = new_region.newContent(portal_type='Category', id='west')
+
+    self.assertEquals(organisation.getRegion(), 'region/europe/west')
+    self.assertEquals(organisation.getRegionList(), ['region/europe/west'])
+    self.assertEquals(organisation.getRegionValue().getPortalType(), 'Category')
+    self.assertNotEquals(organisation.getRegionValue(), old_west_region)
+
+    self.assertEquals(person.getRegion(), 'region/europe/west')
+    self.assertEquals(person.getRegionList(), ['region/europe/west'])
+
+    # Let's continue with resource because its ID conflict with 
+    # "traversing namespaces" names
+    resource_value = portal_categories.resource.newContent(portal_type='Category', id='id1')
+    organisation.setResource('resource/id1')
+    self.assertEquals(organisation.getResource(), 'id1')
+    self.assertEquals(organisation.getResourceValue(), resource_value)
+    self.assertEquals(organisation.getResourceList(), ['id1'])
+    self.assertEquals(organisation.getResourceValue(portal_type='Category'),
+                      resource_value)
+    self.assertEquals(organisation.getResourceValueList(portal_type='Category'),
+                      [resource_value])
+
+    # Check other public methods of CategoryTool
+    self.assertEquals(portal_categories.getCategoryMembershipList(organisation,
+                                           'resource', portal_type='Category'),
+                      ['id1'])
+    self.assertEquals(portal_categories.getSingleCategoryMembershipList(
+                                                    organisation, 'resource',
+                                                    portal_type='Category'),
+                      ['id1'])
+    # Check indexation
+    transaction.commit()
+    self.tic()
 
 def test_suite():
   suite = unittest.TestSuite()



More information about the Erp5-report mailing list