[forms] Do not raise errors on composite required relation being deleted
The entity included in the composite will be deleted in such a case, so
the field is not required even when the cardinality is '1' or '+'.
Related to #8529868
--- a/web/formfields.py Mon Dec 07 11:58:17 2015 +0100
+++ b/web/formfields.py Mon Dec 14 14:29:22 2015 +0100
@@ -76,7 +76,7 @@
from yams.constraints import (SizeConstraint, StaticVocabularyConstraint,
FormatConstraint)
-from cubicweb import Binary, tags, uilib
+from cubicweb import Binary, tags, uilib, neg_role
from cubicweb.utils import support_args
from cubicweb.web import INTERNAL_FIELD_VALUE, ProcessFormError, eid_param, \
formwidgets as fw
@@ -1195,10 +1195,13 @@
else:
targetschema = rdef.subject
card = rdef.role_cardinality(role)
+ composite = getattr(rdef, 'composite', None)
kwargs['name'] = rschema.type
kwargs['role'] = role
kwargs['eidparam'] = True
- kwargs.setdefault('required', card in '1+')
+ # don't mark composite relation as required, we want the composite element
+ # to be removed when not linked to its parent
+ kwargs.setdefault('required', card in '1+' and composite != neg_role(role))
if role == 'object':
kwargs.setdefault('label', (eschema.type, rschema.type + '_object'))
else:
--- a/web/test/data/schema.py Mon Dec 07 11:58:17 2015 +0100
+++ b/web/test/data/schema.py Mon Dec 14 14:29:22 2015 +0100
@@ -96,6 +96,9 @@
class Filesystem(EntityType):
name = String()
+class DirectoryPermission(EntityType):
+ value = String()
+
class parent_fs(RelationDefinition):
name = 'parent'
subject = 'Directory'
@@ -103,6 +106,8 @@
class Directory(EntityType):
name = String(required=True)
+ has_permission = SubjectRelation('DirectoryPermission', cardinality='*1',
+ composite='subject')
class parent_directory(RelationDefinition):
name = 'parent'
--- a/web/test/unittest_application.py Mon Dec 07 11:58:17 2015 +0100
+++ b/web/test/unittest_application.py Mon Dec 14 14:29:22 2015 +0100
@@ -451,6 +451,29 @@
self.assertFalse(cnx.find('Directory', eid=subd.eid))
self.assertTrue(cnx.find('Filesystem', eid=fs.eid))
+ def test_delete_mandatory_composite(self):
+ with self.admin_access.repo_cnx() as cnx:
+ perm = cnx.create_entity('DirectoryPermission')
+ mydir = cnx.create_entity('Directory', name=u'dir',
+ has_permission=perm)
+ cnx.commit()
+
+ with self.admin_access.web_request() as req:
+ dir_eid = unicode(mydir.eid)
+ perm_eid = unicode(perm.eid)
+ req.form = {
+ 'eid': [dir_eid, perm_eid],
+ '__maineid' : dir_eid,
+ '__type:%s' % dir_eid: 'Directory',
+ '__type:%s' % perm_eid: 'DirectoryPermission',
+ '_cw_entity_fields:%s' % dir_eid: '',
+ '_cw_entity_fields:%s' % perm_eid: 'has_permission-object',
+ 'has_permission-object:%s' % perm_eid: '',
+ }
+ path, _params = self.expect_redirect_handle_request(req, 'edit')
+ self.assertTrue(req.find('Directory', eid=mydir.eid))
+ self.assertFalse(req.find('DirectoryPermission', eid=perm.eid))
+
def test_ajax_view_raise_arbitrary_error(self):
class ErrorAjaxView(view.View):
__regid__ = 'test.ajax.error'