[Erp5-report] r40750 arnaud.fontaine - in /erp5/trunk/products/ERP5Type: Core/ PropertyShee...
nobody at svn.erp5.org
nobody at svn.erp5.org
Fri Nov 26 03:11:15 CET 2010
Author: arnaud.fontaine
Date: Fri Nov 26 03:11:14 2010
New Revision: 40750
URL: http://svn.erp5.org?rev=40750&view=rev
Log:
Add Content Existence Constraint for ZODB Property Sheets and its
corresponding test
Added:
erp5/trunk/products/ERP5Type/Core/ContentExistenceConstraint.py
- copied, changed from r40596, erp5/trunk/products/ERP5Type/Constraint/ContentExistence.py
erp5/trunk/products/ERP5Type/PropertySheet/ContentExistenceConstraint.py
Modified:
erp5/trunk/products/ERP5Type/Core/AttributeEqualityConstraint.py
erp5/trunk/products/ERP5Type/Core/CategoryExistenceConstraint.py
erp5/trunk/products/ERP5Type/Core/PropertyExistenceConstraint.py
erp5/trunk/products/ERP5Type/PropertySheet/AttributeEqualityConstraint.py
erp5/trunk/products/ERP5Type/PropertySheet/__init__.py
erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
Modified: erp5/trunk/products/ERP5Type/Core/AttributeEqualityConstraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Core/AttributeEqualityConstraint.py?rev=40750&r1=40749&r2=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Core/AttributeEqualityConstraint.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Core/AttributeEqualityConstraint.py [utf8] Fri Nov 26 03:11:14 2010
@@ -38,13 +38,17 @@ from Products.ERP5Type.Utils import crea
class AttributeEqualityConstraint(ConstraintMixin):
"""
This constraint checks the values of a given attribute name on this
- object. This is only relevant for ZODB Property Sheets (filesystem
- Property Sheets rely on Products.ERP5Type.Constraint.PropertyExistence
- instead). Note that the attribute expected value is now a TALES
- Expression to be able to use any Python type and not only strings.
+ object.
+
+ This is only relevant for ZODB Property Sheets (filesystem Property
+ Sheets rely on Products.ERP5Type.Constraint.AttributeEquality
+ instead).
+
+ Note that the attribute expected value is now a TALES Expression to
+ be able to use any Python type and not only strings.
For example, if we would like to check whether the attribute 'title'
- has 'ObjectTitle' as its value, we would create a 'Attribute
+ has 'ObjectTitle' as its value, we would create an 'Attribute
Equality Constraint' within that Property Sheet and set 'title' as
the 'Attribute Name' and 'python: "ObjectTitle"' as the 'Attribute
Value', then set the 'Predicate' if necessary (known as 'condition'
@@ -121,7 +125,7 @@ class AttributeEqualityConstraint(Constr
error = self._generateError(
obj, self._getMessage(message_id),
dict(attribute_name=attribute_name,
- attribute_value=attribute_value,
+ current_value=attribute_value,
expected_value=attribute_expected_value))
return [error]
Modified: erp5/trunk/products/ERP5Type/Core/CategoryExistenceConstraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Core/CategoryExistenceConstraint.py?rev=40750&r1=40749&r2=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Core/CategoryExistenceConstraint.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Core/CategoryExistenceConstraint.py [utf8] Fri Nov 26 03:11:14 2010
@@ -35,9 +35,11 @@ from Products.ERP5Type import Permission
class CategoryExistenceConstraint(ConstraintMixin):
"""
This constraint checks whether a category has been defined on this
- object (without acquisition). This is only relevant for ZODB
- Property Sheets (filesystem Property Sheets rely on
- Products.ERP5Type.Constraint.CategoryExistence instead).
+ object (without acquisition).
+
+ This is only relevant for ZODB Property Sheets (filesystem Property
+ Sheets rely on Products.ERP5Type.Constraint.CategoryExistence
+ instead).
"""
meta_type = 'ERP5 Category Existence Constraint'
portal_type = 'Category Existence Constraint'
Copied: erp5/trunk/products/ERP5Type/Core/ContentExistenceConstraint.py (from r40596, erp5/trunk/products/ERP5Type/Constraint/ContentExistence.py)
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Core/ContentExistenceConstraint.py?p2=erp5/trunk/products/ERP5Type/Core/ContentExistenceConstraint.py&p1=erp5/trunk/products/ERP5Type/Constraint/ContentExistence.py&r1=40596&r2=40750&rev=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Constraint/ContentExistence.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Core/ContentExistenceConstraint.py [utf8] Fri Nov 26 03:11:14 2010
@@ -26,21 +26,44 @@
#
##############################################################################
-from Products.ERP5Type.Constraint import Constraint
+from Products.ERP5Type.mixin.constraint import ConstraintMixin
+from AccessControl import ClassSecurityInfo
+from Products.ERP5Type import Permissions, PropertySheet
+from Products.CMFCore.Expression import Expression
+from Products.ERP5Type.Utils import createExpressionContext
-class ContentExistence(Constraint):
+class ContentExistenceConstraint(ConstraintMixin):
"""
- This constraint class allows to check that an object contains at least one
- subobject.
-
- Configuration example:
- { 'id' : 'line',
- 'description' : 'Object have to contain a Line',
- 'type' : 'ContentExistence',
- 'portal_type' : ('Line', ),
- },
+ This constraint checks whether the given object contains at least
+ one subobject. It also allows to filter the subobjects by their
+ Portal Types.
+
+ This is only relevant for ZODB Property Sheets (filesystem Property
+ Sheets rely on Products.ERP5Type.Constraint.ContentExistence
+ instead).
+
+ Note that the portal_type is now a TALES Expression, meaningful to
+ be able to call a method returning a list of Portal Types.
+
+ For example, if we would like to check whether the object contains
+ subobjects whose Portal Types could be ("Foo", "Bar"), then we would
+ create a 'Content Existence Constraint' within that Property Sheet
+ and set 'Portal Types' to ("Foo", "Bar"), then set the 'Predicate'
+ if necessary (known as 'condition' for filesystem Property Sheets).
"""
+ meta_type = 'ERP5 Content Existence Constraint'
+ portal_type = 'Content Existence Constraint'
+
+ # Declarative security
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+ property_sheets = (PropertySheet.SimpleItem,
+ PropertySheet.Predicate,
+ PropertySheet.Reference,
+ PropertySheet.ContentExistenceConstraint)
+ # Define by default error messages
_message_id_list = [ 'message_no_subobject',
'message_no_subobject_portal_type' ]
@@ -49,26 +72,32 @@ class ContentExistence(Constraint):
" subobject of portal portal type ${portal_type}"
def checkConsistency(self, obj, fixit=0):
- """Checks that object contains a subobject.
"""
- from Products.ERP5Type.Message import Message
- error_list = []
- if self._checkConstraintCondition(obj):
- # Retrieve configuration values from PropertySheet (_constraints)
- portal_type = self.constraint_definition.get('portal_type', ())
- if not len(obj.contentValues(portal_type=portal_type)):
- # Generate error message
- mapping = {}
- message_id = 'message_no_subobject'
- if portal_type is not ():
- message_id = 'message_no_subobject_portal_type'
- # XXX maybe this could be factored out
- if isinstance(portal_type, basestring):
- portal_type = (portal_type, )
- mapping['portal_type'] = str(Message('erp5_ui', ' or ')).join(
- [str(Message('erp5_ui', pt)) for pt in portal_type])
- # Add error
- error_list.append(self._generateError(obj,
- self._getMessage(message_id), mapping))
- return error_list
+ Checks that object contains at least one subobject and, if a list
+ of Portal Type has been given, check their Portal Types
+ """
+ if not self.test(obj):
+ return []
+
+ portal_type = Expression(self.getConstraintPortalType())(
+ createExpressionContext(obj))
+ # If there is at least one subobject with the given Portal Type,
+ # then return now
+ if len(obj.contentValues(portal_type=portal_type)) > 0:
+ return []
+
+ # Otherwise, generate an error message
+ mapping = {}
+ if portal_type is ():
+ message_id = 'message_no_subobject'
+ else:
+ message_id = 'message_no_subobject_portal_type'
+
+ from Products.ERP5Type.Message import Message
+ mapping['portal_type'] = str(Message('erp5_ui', ' or ')).join(
+ [str(Message('erp5_ui', pt)) for pt in portal_type])
+
+ return [self._generateError(obj,
+ self._getMessage(message_id),
+ mapping)]
Modified: erp5/trunk/products/ERP5Type/Core/PropertyExistenceConstraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Core/PropertyExistenceConstraint.py?rev=40750&r1=40749&r2=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Core/PropertyExistenceConstraint.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Core/PropertyExistenceConstraint.py [utf8] Fri Nov 26 03:11:14 2010
@@ -35,8 +35,10 @@ from Products.ERP5Type import Permission
class PropertyExistenceConstraint(ConstraintMixin):
"""
This constraint checks whether a property has been defined on this
- object. This is only relevant for ZODB Property Sheets (filesystem
- Property Sheets rely on Products.ERP5Type.Constraint.PropertyExistence
+ object.
+
+ This is only relevant for ZODB Property Sheets (filesystem Property
+ Sheets rely on Products.ERP5Type.Constraint.PropertyExistence
instead).
For example, if we would like to check whether an invoice line has a
Modified: erp5/trunk/products/ERP5Type/PropertySheet/AttributeEqualityConstraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/PropertySheet/AttributeEqualityConstraint.py?rev=40750&r1=40749&r2=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/PropertySheet/AttributeEqualityConstraint.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/PropertySheet/AttributeEqualityConstraint.py [utf8] Fri Nov 26 03:11:14 2010
@@ -34,6 +34,7 @@ class AttributeEqualityConstraint:
{ 'id': 'constraint_attribute_name',
'type': 'string',
'description' : 'Attribute name whose values are checked' },
+ # TALES Expression
{ 'id': 'constraint_attribute_value',
'type': 'string',
'description' : 'Valid values of the Attribute' },
Added: erp5/trunk/products/ERP5Type/PropertySheet/ContentExistenceConstraint.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/PropertySheet/ContentExistenceConstraint.py?rev=40750&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Type/PropertySheet/ContentExistenceConstraint.py (added)
+++ erp5/trunk/products/ERP5Type/PropertySheet/ContentExistenceConstraint.py [utf8] Fri Nov 26 03:11:14 2010
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2010 Nexedi SARL and Contributors. All Rights Reserved.
+# Arnaud Fontaine <arnaud.fontaine at nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+##############################################################################
+
+class ContentExistenceConstraint:
+ """
+ Define a Content Existence Constraint for ZODB Property Sheets
+ """
+ _properties = (
+ # TALES Expression
+ { 'id': 'constraint_portal_type',
+ 'type': 'string',
+ 'description' : 'Portal type',
+ 'default': 'python: ()' },
+ { 'id': 'message_no_subobject',
+ 'type': 'string',
+ 'description' : 'Error message when there is no subobject' },
+ { 'id': 'message_no_subobject_portal_type',
+ 'type': 'string',
+ 'description' : 'Error message when there is no subobject of the given portal type' },
+ )
Modified: erp5/trunk/products/ERP5Type/PropertySheet/__init__.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/PropertySheet/__init__.py?rev=40750&r1=40749&r2=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/PropertySheet/__init__.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/PropertySheet/__init__.py [utf8] Fri Nov 26 03:11:14 2010
@@ -20,3 +20,4 @@ from DynamicCategoryProperty import Dyna
from CategoryExistenceConstraint import CategoryExistenceConstraint
from PropertyExistenceConstraint import PropertyExistenceConstraint
from AttributeEqualityConstraint import AttributeEqualityConstraint
+from ContentExistenceConstraint import ContentExistenceConstraint
Modified: erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py?rev=40750&r1=40749&r2=40750&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/tests/testDynamicClassGeneration.py [utf8] Fri Nov 26 03:11:14 2010
@@ -365,6 +365,12 @@ class TestZodbPropertySheet(ERP5TypeTest
constraint_attribute_name='categories_list',
constraint_attribute_value='python: ("sub_category1", "sub_category2")')
+ def _newContentExistenceConstraint(self):
+ self.test_property_sheet.newContent(
+ reference='test_content_existence_constraint',
+ portal_type='Content Existence Constraint',
+ constraint_portal_type='python: ("Folder")')
+
def afterSetUp(self):
"""
Create a test Property Sheet (and its properties)
@@ -395,6 +401,10 @@ class TestZodbPropertySheet(ERP5TypeTest
# Sheet
self._newAttributeEqualityConstraint()
+ # Create a Content Existence Constraint in the test Property
+ # Sheet
+ self._newContentExistenceConstraint()
+
# Create all the test Properties
for operation_type in ('change', 'delete', 'assign'):
self._newStandardProperty(operation_type)
@@ -419,7 +429,8 @@ class TestZodbPropertySheet(ERP5TypeTest
# XXX: to be renamed to type_property_sheet_list as soon as
# the migration has been finished
type_zodb_property_sheet_list=('TestMigration',),
- type_base_category_list=('test_category_existence_constraint',))
+ type_base_category_list=('test_category_existence_constraint',),
+ type_allowed_content_type_list=('Folder',))
# Create a test module, meaningful to force generation of
# TestMigration accessor holders and check the constraints
@@ -448,8 +459,8 @@ class TestZodbPropertySheet(ERP5TypeTest
accessor, which will run the interaction workflow trigger, on
commit at the latest
"""
- self.test_module.getId()
transaction.commit()
+ self.test_module.getId()
def assertHasAttribute(self, obj, attribute, msg=None):
self.failIfEqual(None, getattr(obj, attribute, None),
@@ -754,19 +765,20 @@ class TestZodbPropertySheet(ERP5TypeTest
def _checkConstraint(self,
constraint_reference,
setter_function,
- value):
+ *args,
+ **kw):
constraint = self._getConstraintByReference(constraint_reference)
self.failIfEqual(None, constraint)
self.assertEquals(1, len(constraint.checkConsistency(self.test_module)))
- setter_function(value)
+ setter_function(*args, **kw)
self.assertEquals([], constraint.checkConsistency(self.test_module))
def testPropertyExistenceConstraint(self):
"""
Take the test module and check whether the Property Existence
- Constraint is available. Until the property has been set to a
- value, the constraint should fail
+ Constraint is there. Until the property has been set to a value,
+ the constraint should fail
"""
# See ERP5Type.Base.Base.hasProperty()
self._checkConstraint('test_property_existence_constraint',
@@ -776,7 +788,7 @@ class TestZodbPropertySheet(ERP5TypeTest
def testCategoryExistenceConstraint(self):
"""
Take the test module and check whether the Property Existence
- Constraint is available. Until the category has been set to an
+ Constraint is there. Until the category has been set to an
existing category, the constraint should fail
"""
self._checkConstraint('test_category_existence_constraint',
@@ -786,9 +798,9 @@ class TestZodbPropertySheet(ERP5TypeTest
def testAttributeEqualityConstraint(self):
"""
Take the test module and check whether the Attribute Equality
- Constraint is available. Until the attribute to be checked has
- been set to its expected value, the constraint should fail. The
- purpose is to test only primitive types (e.g. not list)
+ Constraint is there. Until the attribute to be checked has been
+ set to its expected value, the constraint should fail. The purpose
+ is to test only primitive types (e.g. not list)
"""
# As checkConsistency calls hasProperty before checking the value,
# the property to be tested has to be set at least once (whatever
@@ -802,9 +814,9 @@ class TestZodbPropertySheet(ERP5TypeTest
def testAttributeListEqualityConstraint(self):
"""
Take the test module and check whether the Attribute Equality
- Constraint is available. Until the attribute to be checked has
- been set to its expected value (a list of categories), the
- constraint should fail. The purpose is to test only list types
+ Constraint is there. Until the attribute to be checked has been
+ set to its expected value (a list of categories), the constraint
+ should fail. The purpose is to test only list types
@see testAttributeEqualityConstraint
"""
@@ -814,6 +826,18 @@ class TestZodbPropertySheet(ERP5TypeTest
self.test_module.setCategoryList,
('sub_category1', 'sub_category2'))
+ def testContentExistenceConstraint(self):
+ """
+ Take the test module and check whether the Content Existence
+ Constraint is there. Until there is at least one subobject of
+ 'Test Module' whose Portal Type is 'Folder', the constraint should
+ fail
+ """
+ self._checkConstraint('test_content_existence_constraint',
+ self.test_module.newContent,
+ id='Test Content Existence Constraint',
+ portal_type='Folder')
+
TestZodbPropertySheet = skip("ZODB Property Sheets code is not enabled yet")(
TestZodbPropertySheet)
More information about the Erp5-report
mailing list