Fix seda_unit constraints when container root is a "component" archive unit
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 20 Oct 2016 08:51:14 +0200
changeset 1945 577f41dceb9f
parent 1944 90595e088196
child 1946 b73e68a968a9
Fix seda_unit constraints when container root is a "component" archive unit else a ValidationError is raised when a value is set, since constraint can't be verified.
schema/seda2.py
test/test_schema.py
xsd2yams.py
--- a/schema/seda2.py	Thu Oct 20 08:50:29 2016 +0200
+++ b/schema/seda2.py	Thu Oct 20 08:51:14 2016 +0200
@@ -2203,7 +2203,7 @@
     cardinality = '?*'
     composite = fulltext_container = None
     inlined = True
-    constraints = [RQLConstraint('O in_scheme CS, CACLV seda_appraisal_rule_code_list_version_from AT, CACLV seda_appraisal_rule_code_list_version_to CS,S container AT')]
+    constraints = [RQLConstraint('O in_scheme CS, EXISTS(CACLV seda_appraisal_rule_code_list_version_from AT,        CACLV seda_appraisal_rule_code_list_version_to CS,       S container AT) OR EXISTS(S container AU, AU is SEDAArchiveUnit)')]
 
 class seq_access_rule_rule_rule(RelationDefinition):
     name = 'seda_rule'
@@ -2212,7 +2212,7 @@
     cardinality = '?*'
     composite = fulltext_container = None
     inlined = True
-    constraints = [RQLConstraint('O in_scheme CS, CACLV seda_access_rule_code_list_version_from AT, CACLV seda_access_rule_code_list_version_to CS,S container AT')]
+    constraints = [RQLConstraint('O in_scheme CS, EXISTS(CACLV seda_access_rule_code_list_version_from AT,        CACLV seda_access_rule_code_list_version_to CS,       S container AT) OR EXISTS(S container AU, AU is SEDAArchiveUnit)')]
 
 class seq_dissemination_rule_rule_rule(RelationDefinition):
     name = 'seda_rule'
--- a/test/test_schema.py	Thu Oct 20 08:50:29 2016 +0200
+++ b/test/test_schema.py	Thu Oct 20 08:51:14 2016 +0200
@@ -21,7 +21,7 @@
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.schema import ERQLExpression, RRQLExpression
 
-from testutils import create_archive_unit, create_data_object, create_transfer_to_bdo
+import testutils
 
 
 class SchemaTC(CubicWebTC):
@@ -36,7 +36,7 @@
             reply_concept = reply_scheme.add_concept(label=u'ok')
             cnx.commit()
 
-            bdo = create_transfer_to_bdo(cnx)
+            bdo = testutils.create_transfer_to_bdo(cnx)
             bdo.container[0].cw_set(seda_reply_code_list_version=reply_scheme,
                                     seda_message_digest_algorithm_code_list_version=digest_scheme)
             cnx.commit()
@@ -59,7 +59,7 @@
             other_concept = other_scheme.add_concept(label=u'ok')
             cnx.commit()
 
-            bdo = create_transfer_to_bdo(cnx)
+            bdo = testutils.create_transfer_to_bdo(cnx)
             create('SEDAMimeTypeCodeListVersion',
                    seda_mime_type_code_list_version_from=bdo.container,
                    seda_mime_type_code_list_version_to=mt_scheme)
@@ -73,13 +73,29 @@
             create('SEDAMimeType', seda_mime_type_from=bdo, seda_mime_type_to=mt_concept)
             cnx.commit()
 
+    def test_component_archive_unit_rule_constraint(self):
+        with self.admin_access.client_cnx() as cnx:
+            for rule_type in ('access', 'appraisal'):
+                etype = 'SEDASeq{}RuleRule'.format(rule_type.capitalize())
+                scheme = testutils.scheme_for_type(cnx, 'seda_rule', etype)
+                concept = scheme.add_concept(label=u'whatever')
+                cnx.commit()
+
+                unit, unit_alt, unit_alt_seq = testutils.create_archive_unit(None, cnx=cnx)
+                rule_rule = cnx.create_entity(etype.format(rule_type.capitalize()),
+                                              seda_rule=concept)
+                cnx.create_entity('SEDA{0}Rule'.format(rule_type.capitalize()),
+                                  **{'seda_{0}_rule'.format(rule_type): unit_alt_seq,
+                                     'seda_seq_{0}_rule_rule'.format(rule_type): rule_rule})
+                cnx.commit()
+
     def test_identifier_unicity_constraint(self):
         """Check that an identifier must be unique within a profile."""
         with self.admin_access.client_cnx() as cnx:
             create = cnx.create_entity
             transfer1 = create('SEDAArchiveTransfer', title=u'Profile1')
             # Create an archive unit with an id
-            create_archive_unit(transfer1, id=u'id1')
+            testutils.create_archive_unit(transfer1, id=u'id1')
             cnx.commit()
             # Creating binary data object with same id should fail
             transfer1 = cnx.entity_from_eid(transfer1.eid)
@@ -93,7 +109,7 @@
                           cm.exception.errors.values().pop())
             # Creating an archive unit in another profile with same id works
             transfer2 = create('SEDAArchiveTransfer', title=u'Profile2')
-            create_archive_unit(transfer2, id=u'id1')
+            testutils.create_archive_unit(transfer2, id=u'id1')
             cnx.commit()
 
     def test_rdef_container_permissions(self):
@@ -157,12 +173,12 @@
         # entities that may live in the DB (e.g. Concepts) with similar text.
         with self.admin_access.client_cnx() as cnx:
             transfer = cnx.create_entity('SEDAArchiveTransfer', title=u'Profile')
-            unit, unit_alt, unit_alt_seq = create_archive_unit(transfer)
+            unit, unit_alt, unit_alt_seq = testutils.create_archive_unit(transfer)
             content = cnx.create_entity('SEDAContent', seda_content=unit_alt_seq)
             cnx.create_entity('SEDATitle', seda_title=content, title=u'transfer name'[::-1])
             cnx.create_entity('SEDAAccessRule', seda_access_rule=unit_alt_seq,
                               user_annotation=u'some annotation'[::-1])
-            create_data_object(transfer, id=u"bdo1", filename=u'fixed.txt'[::-1])
+            testutils.create_data_object(transfer, id=u"bdo1", filename=u'fixed.txt'[::-1])
             cnx.commit()
 
             for search in ('name', 'annotation', 'fixed'):
@@ -188,7 +204,7 @@
             cnx.commit()
         with self.new_access('alice').repo_cnx() as cnx:
             transfer = cnx.create_entity('SEDAArchiveTransfer', title=u'Alice Profile')
-            create_archive_unit(transfer)
+            testutils.create_archive_unit(transfer)
             cnx.create_entity('Agent', name=u'Archival inc.',
                               reverse_seda_archival_agency=transfer)
             cnx.create_entity('SEDAComment', comment=u'Whooot.',
@@ -234,7 +250,7 @@
 
     def test_archive_unit(self):
         with self.admin_access.repo_cnx() as cnx:
-            unit, unit_alt, unit_alt_seq = create_archive_unit(None, cnx=cnx)
+            unit, unit_alt, unit_alt_seq = testutils.create_archive_unit(None, cnx=cnx)
             content = cnx.create_entity('SEDAContent', seda_content=unit_alt_seq)
             title = cnx.create_entity('SEDATitle', seda_title=content)
             cnx.commit()
--- a/xsd2yams.py	Thu Oct 20 08:50:29 2016 +0200
+++ b/xsd2yams.py	Thu Oct 20 08:51:14 2016 +0200
@@ -153,13 +153,17 @@
         'CACLV seda_dissemination_rule_code_list_version_to CS,'
         'S container AT'),
     ('SEDASeqAccessRuleRule', 'seda_rule'): (
-        'O in_scheme CS, CACLV seda_access_rule_code_list_version_from AT, '
-        'CACLV seda_access_rule_code_list_version_to CS,'
-        'S container AT'),
+        'O in_scheme CS, '
+        'EXISTS(CACLV seda_access_rule_code_list_version_from AT, '
+        '       CACLV seda_access_rule_code_list_version_to CS,'
+        '       S container AT)'
+        ' OR EXISTS(S container AU, AU is SEDAArchiveUnit)'),
     ('SEDASeqAppraisalRuleRule', 'seda_rule'): (
-        'O in_scheme CS, CACLV seda_appraisal_rule_code_list_version_from AT, '
-        'CACLV seda_appraisal_rule_code_list_version_to CS,'
-        'S container AT'),
+        'O in_scheme CS, '
+        'EXISTS(CACLV seda_appraisal_rule_code_list_version_from AT, '
+        '       CACLV seda_appraisal_rule_code_list_version_to CS,'
+        '       S container AT)'
+        ' OR EXISTS(S container AU, AU is SEDAArchiveUnit)'),
     ('SEDASeqStorageRuleRule', 'seda_rule'): (
         'O in_scheme CS, CACLV seda_storage_rule_code_list_version_from AT, '
         'CACLV seda_storage_rule_code_list_version_to CS,'