Commit 3202ce7b authored by Jérome Perrin's avatar Jérome Perrin

return error message has "translatable" strings with a mapping, otherwise using

constraints will generate tons of messages.



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@18241 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 6bf9fff1
......@@ -53,33 +53,38 @@ class AttributeEquality(PropertyExistence):
if not self._checkConstraintCondition(obj):
return []
errors = PropertyExistence.checkConsistency(self, obj, fixit=fixit)
for attribute_name, attribute_value in self.constraint_definition.items():
for attribute_name, expected_value in self.constraint_definition.items():
error_message = None
mapping = dict()
# If property does not exist, error will be raise by
# PropertyExistence Constraint.
if obj.hasProperty(attribute_name):
identical = 1
if type(attribute_value) in (type(()), type([])):
if isinstance(expected_value, (list, tuple)):
# List type
if len(obj.getProperty(attribute_name)) != len(attribute_value):
if len(obj.getProperty(attribute_name)) != len(expected_value):
identical = 0
else:
for item in obj.getProperty(attribute_name):
if item not in attribute_value:
if item not in expected_value:
identical = 0
break
else:
# Other type
identical = (attribute_value == obj.getProperty(attribute_name))
identical = (expected_value == obj.getProperty(attribute_name))
if not identical:
# Generate error_message
error_message = "Attribute %s is '%s' but should be '%s'" % \
(attribute_name, obj.getProperty(attribute_name),
attribute_value)
error_message = "Attribute ${attribute_name} value is "\
"${current_value} but should be ${expected_value}"
mapping(attribute_name=attribute_name,
attribute_value=obj.getProperty(attribute_name),
expected_value=expected_value)
# Generate error
if error_message is not None:
if fixit:
obj._setProperty(attribute_name, attribute_value)
error_message += " (Fixed)"
errors.append(self._generateError(obj, error_message))
obj._setProperty(attribute_name, expected_value)
error_message = "Attribute ${attribute_name} value is "\
"${current_value} but should be ${expected_value} (Fixed)"
errors.append(self._generateError(obj, error_message, mapping))
return errors
......@@ -55,21 +55,21 @@ class CategoryExistence(Constraint):
for base_category in self.constraint_definition.keys():
if base_category in ('portal_type', ):
continue
mapping = dict(base_category=base_category)
# Check existence of base category
error_message = "Category existence error for base category '%s': " % \
base_category
if base_category not in obj.getBaseCategoryList():
error_message += " this document has no such category"
error_message = "Category existence error for base category "\
"${base_category}, this document has no such category"
elif len(obj.getCategoryMembershipList(base_category,
portal_type = self.constraint_definition\
.get('portal_type', ()))) == 0:
error_message += " this category was not defined"
error_message = "Category existence error for base category "\
"${base_category}, this category is not defined"
else:
error_message = None
# Raise error
if error_message:
errors.append(self._generateError(obj, error_message))
errors.append(self._generateError(obj, error_message, mapping))
return errors
......@@ -63,7 +63,7 @@ class CategoryMembershipArity(Constraint):
if not self._checkConstraintCondition(obj):
return []
errors = []
# Retrieve values inside de PropertySheet (_constraints)
# Retrieve configuration values from PropertySheet (_constraints)
base_category = self.constraint_definition['base_category']
min_arity = int(self.constraint_definition['min_arity'])
max_arity = None
......@@ -74,19 +74,33 @@ class CategoryMembershipArity(Constraint):
arity = self._calculateArity(obj)
if not (max_arity is None and (min_arity <= arity)
or (min_arity <= arity <= max_arity)):
mapping = dict(base_category=base_category,
portal_type=portal_type,
current_arity=arity,
min_arity=min_arity,
max_arity=max_arity,)
# Generate error message
error_message = "Arity error for relation '%s'" % \
base_category
if portal_type is not ():
error_message += " and portal_type: '%s'" % str(portal_type)
if max_arity is None:
error_message += \
", arity is equal to %i but should be at least %i" % \
(arity, min_arity)
error_message = "Arity Error for Relation ${base_category}"\
" and Type ${portal_type}"\
", arity is equal to ${current_arity} but "\
"should be at least ${min_arity}"
else:
error_message += \
", arity is equal to %i but should be between %i and %i" % \
(arity, min_arity, max_arity)
error_message = "Arity Error for Relation ${base_category}"\
" and Type ${portal_type}"\
", arity is equal to ${current_arity} but "\
"should be between ${min_arity} and ${max_arity}"
else:
if max_arity is None:
error_message = "Arity Error for Relation ${base_category}"\
", arity is equal to ${current_arity} but "\
"should be at least ${min_arity}"
else:
error_message = "Arity Error for Relation ${base_category}"\
", arity is equal to ${current_arity} but "\
"should be between ${min_arity} and ${max_arity}"
# Add error
errors.append(self._generateError(obj, error_message))
errors.append(self._generateError(obj, error_message, mapping))
return errors
......@@ -46,17 +46,24 @@ class ContentExistence(Constraint):
each string corresponds to an error.
We are checking that object contains a subobject.
"""
from Products.ERP5Type.Message import Message
obj = object
errors = []
if self._checkConstraintCondition(object):
# Retrieve configuration values from PropertySheet (_constraints)
portal_type = self.constraint_definition['portal_type']
portal_type = self.constraint_definition.get('portal_type', ())
if not len(obj.contentValues(portal_type=portal_type)):
# Generate error message
error_message = "Does not contain any subobject"
mapping = {}
error_message = "The document does not contain any subobject"
if portal_type is not ():
error_message += " of portal type: '%s'" % str(portal_type)
error_message += " of portal type ${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
errors.append(self._generateError(obj, error_message))
errors.append(self._generateError(obj, error_message, mapping))
return errors
......@@ -59,20 +59,25 @@ class PortalTypeClass(Constraint):
type_info = types_tool._getOb(obj.getPortalType(), None)
if type_info is None :
errors.append(self._generateError(obj,
"Type information for '%s' not registred with the TypeTool"))
"Type Information ${type_name} not registred with the TypeTool",
mapping=dict(type_name=obj.getPortalType())))
elif type_info.content_meta_type != obj.meta_type :
errors.append(self._generateError(obj,
"Meta type is inconsistant with portal type definition."\
" Portal type meta type is '%s' class meta type is '%s' " % (
type_info.content_meta_type, obj.meta_type )))
" Portal type meta type is ${portal_type_meta_type}"\
" class meta type is ${class_meta_type} ",
mapping=dict(portal_type_meta_type=type_info.content_meta_type,
class_meta_type=obj.meta_type)))
else :
portal_type_class = self._getClassForPortalType(obj, type_info)
obj_class = str(obj.__class__)
if portal_type_class != obj_class :
errors.append(self._generateError(obj,
"__class__ is inconsistant with portal type definition."\
" Portal_type class is %s, document class is %s" % (
portal_type_class, obj_class)))
" Portal Type class is ${portal_type_class},"
" document class is ${document_class}",
mapping=dict(portal_type_class=portal_type_class,
document_class=obj_class)))
# TODO fixit argument can be implemented here.
return errors
......
......@@ -55,18 +55,19 @@ class PropertyExistence(Constraint):
# For each attribute name, we check if defined
for property_id in self.constraint_definition.keys():
# Check existence of property
error_message = \
"Property existence error for property '%s': " % property_id
mapping = dict(property_id=property_id)
if not obj.hasProperty(property_id):
error_message += " this document has no such property"
error_message = "Property existence error for property "\
"${property_id}, this document has no such property"
elif obj.getProperty(property_id) is None:
# If value is '', attribute is considered a defined
# XXX is this the default API ?
error_message += " this property was not defined"
error_message = "Property existence error for property "\
"${property_id}, this property is not defined"
else:
error_message = None
# Return error
error = self._generateError(obj, error_message)
error = self._generateError(obj, error_message, mapping)
if error is not None:
errors.append(error)
return errors
......@@ -88,25 +88,36 @@ class PropertyTypeValidity(Constraint):
wrong_type = not isinstance(value, self._type_dict[property_type])
except KeyError:
wrong_type = 0
error_message = "Attribute %s is defined with unknown type %s" % \
(property_id, property_type)
errors.append(self._generateError(obj, error_message))
errors.append(self._generateError(obj,
"Attribute ${attribute_name} is defined with "
"an unknown type ${type_name}",
mapping=dict(attribute_name=property_id,
type_name=property_type)))
if wrong_type:
# Type is wrong, so, raise constraint error
error_message = \
"Attribute %s should be of type %s but is of type %s" % \
(property_id, property_type, str(type(value)))
error_message = "Attribute ${attribute_name} should be of type"\
" ${expected_type} but is of type ${actual_type}"
mapping = dict(attribute_name=property_id,
expected_type=property_type,
actual_type=str(type(value)))
if fixit:
# try to cast to correct type
if wrong_type:
try:
value = self._type_dict[property_type][0](value)
except (KeyError, ValueError), error:
error_message += " (Type cast failed : %s)" % error
error_message = "Attribute ${attribute_name} should be of type"\
" ${expected_type} but is of type ${actual_type} (Type cast"\
" failed with error ${type_cast_error}"
mapping['type_cast_error'] = str(error)
else:
obj.setProperty(property_id, value)
error_message += " (Fixed)"
errors.append(self._generateError(obj, error_message))
error_message = "Attribute ${attribute_name} should be of type"\
" ${expected_type} but is of type ${actual_type} (Fixed)"
errors.append(self._generateError(obj, error_message, mapping))
elif fixit:
oldvalue = getattr(obj, property_id, value)
if oldvalue != value:
......
......@@ -47,20 +47,24 @@ class StringAttributeMatch(PropertyExistence):
each string corresponds to an error.
Check that each attribute does not match the RE
"""
errors = PropertyExistence.checkConsistency(self, object, fixit=fixit)
if not errors:
for attribute_name, attribute_value in self.constraint_definition.items():
error_list = PropertyExistence.checkConsistency(
self, object, fixit=fixit)
if not error_list:
for attribute_name, regular_expression in\
self.constraint_definition.items():
error_message = None
# If property does not exist, error will be raise by
# If property does not exist, error will be raised by
# PropertyExistence Constraint.
current_value = object.getProperty(attribute_name)
regexp = re.compile(attribute_value)
regexp = re.compile(regular_expression)
if (current_value is not None) and \
(regexp.match(current_value) is None):
# Generate error_message
error_message = "Attribute %s is '%s' and not match '%s'" % \
(attribute_name, current_value,
attribute_value)
# Generate error
errors.append(self._generateError(object, error_message))
return errors
error_list.append(self._generateError(object,
"Attribute ${attribute_name} is ${attribute_value} and"
" does not match ${regular_expression}.",
mapping=dict(attribute_name=attribute_name,
attribute_value=repr(current_value),
regular_expression=repr(regular_expression))))
return error_list
......@@ -70,6 +70,7 @@ class TALESConstraint(Constraint):
LOG('ERP5Type', PROBLEM, 'TALESConstraint error on "%s" on %s' %
(self.constraint_definition['expression'], obj), error=sys.exc_info())
errors.append(self._generateError(obj,
'Error while evaluating expression: %s' % str(e)))
'Error while evaluating expression: ${error_text}',
mapping=dict(error_text=str(e))))
return errors
......@@ -282,6 +282,11 @@ class TestConstraint(PropertySheetTestCase):
error_list = sequence.get('error_list')
self.failUnless(error_list != [],
"error_list : %s" % error_list)
# call getTranslatedMessage, to make sure messages have a valid mapping.
for error in error_list:
self.assertNotEquals('',
error.getTranslatedMessage())
def stepCreateConstraint(self, sequence=None,
sequence_list=None, **kw):
......@@ -964,7 +969,9 @@ class TestConstraint(PropertySheetTestCase):
base_category=('group',),
klass_name='CategoryMembershipArity',
min_arity=1)
self.assertEquals(1, len(constraint.checkConsistency(obj)))
message_list = constraint.checkConsistency(obj)
self.assertEquals(1, len(message_list))
self.assertNotEquals('', message_list[0].getTranslatedMessage())
obj.setGroup('testGroup1')
self.assertEquals(0, len(constraint.checkConsistency(obj)))
......@@ -976,7 +983,9 @@ class TestConstraint(PropertySheetTestCase):
base_category=('group',),
klass_name='CategoryAcquiredMembershipArity',
min_arity=1)
self.assertEquals(1, len(constraint.checkConsistency(obj)))
message_list = constraint.checkConsistency(obj)
self.assertEquals(1, len(message_list))
self.assertNotEquals('', message_list[0].getTranslatedMessage())
obj.setGroup('testGroup1')
self.assertEquals(0, len(constraint.checkConsistency(obj)))
......@@ -1106,7 +1115,9 @@ class TestConstraint(PropertySheetTestCase):
base_category=('group',),
klass_name='CategoryRelatedMembershipArity',
min_arity=1)
self.assertEquals(1, len(constraint.checkConsistency(obj)))
message_list = constraint.checkConsistency(obj)
self.assertEquals(1, len(message_list))
self.assertNotEquals('', message_list[0].getTranslatedMessage())
related_obj.setGroupValue(obj)
get_transaction().commit()
self.tic()
......@@ -1141,7 +1152,9 @@ class TestConstraint(PropertySheetTestCase):
obj = self._makeOne()
self.assertEquals([], constraint.checkConsistency(obj))
obj.setTitle('foo')
self.assertEquals(1, len(constraint.checkConsistency(obj)))
message_list = constraint.checkConsistency(obj)
self.assertEquals(1, len(message_list))
self.assertNotEquals('', message_list[0].getTranslatedMessage())
def test_TALESConstraintInvalidExpression(self):
"""Tests TALESConstraint with an invalid expression
......@@ -1152,7 +1165,9 @@ class TestConstraint(PropertySheetTestCase):
expression='python: None / 3') # ValueError
obj = self._makeOne()
# an error during expression evaluation simply makes a consistency error
self.assertEquals(1, len(constraint.checkConsistency(obj)))
message_list = constraint.checkConsistency(obj)
self.assertEquals(1, len(message_list))
self.assertNotEquals('', message_list[0].getTranslatedMessage())
# an error during expression compilation is reraised to the programmer
constraint = self._createGenericConstraint(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment