[profile gen] Ensure data-objects are exported before sub-units in SEDA 0.2
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 29 Aug 2017 16:36:21 +0200
changeset 2666 68c5f87f8677
parent 2663 274dcd2aafbf
child 2667 ea897ca9b50b
[profile gen] Ensure data-objects are exported before sub-units in SEDA 0.2 else this won't be conform to the SEDA 0.2schema. But notice this is the opposite in SEDA 1.0. In this case, test cases were fine but the problem was actually the same: data-objects and sub-units order was random, and it's not anymore. As we are here, add eid so we get a total ordering, which is an expected property so that exported profiles are consistent during time. This should be enough until we want to control ordering from the UI. Closes extranet #33070904
cubicweb_seda/entities/profile_generation.py
test/data/seda_02_export.rng
test/data/seda_02_export.xsd
test/test_profile_generation.py
--- a/cubicweb_seda/entities/profile_generation.py	Thu Aug 24 16:24:04 2017 +0200
+++ b/cubicweb_seda/entities/profile_generation.py	Tue Aug 29 16:36:21 2017 +0200
@@ -814,11 +814,15 @@
         self.xsd_integrity(document_node, data_object)
         self.xsd_document_type(document_node, data_object)
 
+    # in SEDA 1 sub-archive units are exposed before data objects
+    last_children_type = 'SEDABinaryDataObject'
+
     def xsd_children(self, parent, entity):
         """Iter on archive/archive object children, which may be either
         archive objects or documents, and append XSD elements for them to the given parent node.
         """
-        for au_or_bdo in entity.cw_adapt_to('ITreeBase').iterchildren():
+        for au_or_bdo in sorted(entity.cw_adapt_to('ITreeBase').iterchildren(),
+                                key=lambda x: (x.cw_etype == self.last_children_type, x.eid)):
             if au_or_bdo.cw_etype == 'SEDABinaryDataObject':
                 self.xsd_document(parent, au_or_bdo)
             else:
@@ -1241,6 +1245,8 @@
     kw_tag_name = 'ContentDescriptive'
     kw_content_tag_type = 'udt:TextType'
     kw_content_tag_attributes = [XAttr('languageID', 'xsd:language')]
+    # in SEDA 0.2 data objects are exposed before sub-archive units
+    last_children_type = 'SEDAArchiveUnit'
 
 
 class OldSEDARNGExportMixin(RNGMixin):
--- a/test/data/seda_02_export.rng	Thu Aug 24 16:24:04 2017 +0200
+++ b/test/data/seda_02_export.rng	Tue Aug 29 16:36:21 2017 +0200
@@ -372,6 +372,36 @@
               <rng:data type="string"/>
             </rng:element>
           </rng:element>
+          <rng:zeroOrMore>
+            <rng:element name="Document" seda:profid="id%(bdo-eid)s">
+              <xsd:annotation>
+                <xsd:documentation>data object title</xsd:documentation>
+              </xsd:annotation>
+              <rng:optional>
+                <rng:attribute name="Id">
+                  <rng:data type="ID"/>
+                </rng:attribute>
+              </rng:optional>
+              <rng:element name="Attachment">
+                <rng:attribute name="format">
+                  <rng:value type="string">fmt/123</rng:value>
+                </rng:attribute>
+                <rng:attribute name="encodingCode">
+                  <rng:value type="string">6</rng:value>
+                </rng:attribute>
+                <rng:attribute name="filename">
+                  <rng:value type="string">this_is_the_filename.pdf</rng:value>
+                </rng:attribute>
+                <rng:data type="string"/>
+              </rng:element>
+              <rng:element name="Type">
+                <rng:attribute name="listVersionID">
+                  <rng:value type="token">edition 2009</rng:value>
+                </rng:attribute>
+                <rng:value type="string">CDO</rng:value>
+              </rng:element>
+            </rng:element>
+          </rng:zeroOrMore>
           <rng:oneOrMore>
             <rng:element name="Contains">
               <rng:element name="DescriptionLevel">
@@ -507,36 +537,6 @@
               </rng:element>
             </rng:element>
           </rng:oneOrMore>
-          <rng:zeroOrMore>
-            <rng:element name="Document" seda:profid="id%(bdo-eid)s">
-              <xsd:annotation>
-                <xsd:documentation>data object title</xsd:documentation>
-              </xsd:annotation>
-              <rng:optional>
-                <rng:attribute name="Id">
-                  <rng:data type="ID"/>
-                </rng:attribute>
-              </rng:optional>
-              <rng:element name="Attachment">
-                <rng:attribute name="format">
-                  <rng:value type="string">fmt/123</rng:value>
-                </rng:attribute>
-                <rng:attribute name="encodingCode">
-                  <rng:value type="string">6</rng:value>
-                </rng:attribute>
-                <rng:attribute name="filename">
-                  <rng:value type="string">this_is_the_filename.pdf</rng:value>
-                </rng:attribute>
-                <rng:data type="string"/>
-              </rng:element>
-              <rng:element name="Type">
-                <rng:attribute name="listVersionID">
-                  <rng:value type="token">edition 2009</rng:value>
-                </rng:attribute>
-                <rng:value type="string">CDO</rng:value>
-              </rng:element>
-            </rng:element>
-          </rng:zeroOrMore>
         </rng:element>
       </rng:oneOrMore>
     </rng:element>
--- a/test/data/seda_02_export.xsd	Thu Aug 24 16:24:04 2017 +0200
+++ b/test/data/seda_02_export.xsd	Tue Aug 29 16:36:21 2017 +0200
@@ -274,6 +274,39 @@
                   <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
                 </xsd:complexType>
               </xsd:element>
+              <xsd:element maxOccurs="unbounded" minOccurs="0" name="Document" seda:profid="id%(bdo-eid)s">
+                <xsd:annotation>
+                  <xsd:documentation>data object title</xsd:documentation>
+                </xsd:annotation>
+                <xsd:complexType>
+                  <xsd:sequence>
+                    <xsd:element name="Attachment">
+                      <xsd:complexType>
+                        <xsd:simpleContent>
+                          <xsd:extension base="qdt:ArchivesBinaryObjectType">
+                            <xsd:attribute fixed="fmt/123" name="format" type="clmDAFFileTypeCode:FileTypeCodeType" use="required"/>
+                            <xsd:attribute fixed="6" name="encodingCode" type="clm60133:CharacterSetEncodingCodeContentType" use="required"/>
+                            <xsd:attribute name="mimeCode" type="clmIANAMIMEMediaType:MIMEMediaTypeContentType" use="prohibited"/>
+                            <xsd:attribute fixed="this_is_the_filename.pdf" name="filename" type="xsd:string" use="required"/>
+                            <xsd:attribute name="characterSetCode" type="clmIANACharacterSetCode:CharacterSetCodeContentType" use="prohibited"/>
+                            <xsd:attribute name="uri" type="xsd:anyURI" use="prohibited"/>
+                          </xsd:extension>
+                        </xsd:simpleContent>
+                      </xsd:complexType>
+                    </xsd:element>
+                    <xsd:element fixed="CDO" name="Type">
+                      <xsd:complexType>
+                        <xsd:simpleContent>
+                          <xsd:extension base="qdt:CodeDocumentType">
+                            <xsd:attribute fixed="edition 2009" name="listVersionID" type="xsd:token" use="required"/>
+                          </xsd:extension>
+                        </xsd:simpleContent>
+                      </xsd:complexType>
+                    </xsd:element>
+                  </xsd:sequence>
+                  <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
+                </xsd:complexType>
+              </xsd:element>
               <xsd:element maxOccurs="unbounded" name="Contains">
                 <xsd:annotation>
                   <xsd:documentation>archive unit title</xsd:documentation>
@@ -410,39 +443,6 @@
                   <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
                 </xsd:complexType>
               </xsd:element>
-              <xsd:element maxOccurs="unbounded" minOccurs="0" name="Document" seda:profid="id%(bdo-eid)s">
-                <xsd:annotation>
-                  <xsd:documentation>data object title</xsd:documentation>
-                </xsd:annotation>
-                <xsd:complexType>
-                  <xsd:sequence>
-                    <xsd:element name="Attachment">
-                      <xsd:complexType>
-                        <xsd:simpleContent>
-                          <xsd:extension base="qdt:ArchivesBinaryObjectType">
-                            <xsd:attribute fixed="fmt/123" name="format" type="clmDAFFileTypeCode:FileTypeCodeType" use="required"/>
-                            <xsd:attribute fixed="6" name="encodingCode" type="clm60133:CharacterSetEncodingCodeContentType" use="required"/>
-                            <xsd:attribute name="mimeCode" type="clmIANAMIMEMediaType:MIMEMediaTypeContentType" use="prohibited"/>
-                            <xsd:attribute fixed="this_is_the_filename.pdf" name="filename" type="xsd:string" use="required"/>
-                            <xsd:attribute name="characterSetCode" type="clmIANACharacterSetCode:CharacterSetCodeContentType" use="prohibited"/>
-                            <xsd:attribute name="uri" type="xsd:anyURI" use="prohibited"/>
-                          </xsd:extension>
-                        </xsd:simpleContent>
-                      </xsd:complexType>
-                    </xsd:element>
-                    <xsd:element fixed="CDO" name="Type">
-                      <xsd:complexType>
-                        <xsd:simpleContent>
-                          <xsd:extension base="qdt:CodeDocumentType">
-                            <xsd:attribute fixed="edition 2009" name="listVersionID" type="xsd:token" use="required"/>
-                          </xsd:extension>
-                        </xsd:simpleContent>
-                      </xsd:complexType>
-                    </xsd:element>
-                  </xsd:sequence>
-                  <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
-                </xsd:complexType>
-              </xsd:element>
             </xsd:sequence>
             <xsd:attribute name="Id" type="xsd:ID" use="optional"/>
           </xsd:complexType>
--- a/test/test_profile_generation.py	Thu Aug 24 16:24:04 2017 +0200
+++ b/test/test_profile_generation.py	Tue Aug 29 16:36:21 2017 +0200
@@ -917,6 +917,33 @@
             root = self.profile_etree(transfer, 'SEDA-0.2.rng')
         self.check_xsd_profile(root, self.datapath('seda_02_bordereau_ref.xml'))
 
+    def test_children_order(self):
+        with self.admin_access.cnx() as cnx:
+            create = cnx.create_entity
+
+            transfer = create('SEDAArchiveTransfer', title=u'test profile',
+                              simplified_profile=True)
+            unit, unit_alt, unit_alt_seq = testutils.create_archive_unit(transfer)
+            subunit, subunit_alt, subunit_alt_seq = testutils.create_archive_unit(
+                unit_alt_seq)
+            bdo = testutils.create_data_object(transfer)
+            create('SEDADataObjectReference',
+                   seda_data_object_reference=unit_alt_seq,
+                   seda_data_object_reference_id=bdo)
+            cnx.commit()
+
+            # ensure Document appears before Contains in SEDA 0.2
+            adapter = transfer.cw_adapt_to('SEDA-0.2.xsd')
+            root = etree.Element('test-root')
+            adapter.xsd_children(root, unit)
+            self.assertEqual([node.attrib['name'] for node in root], ['Document', 'Contains'])
+
+            # ensure Document appears after ArchiveObject in SEDA 1
+            adapter = transfer.cw_adapt_to('SEDA-1.0.xsd')
+            root = etree.Element('test-root')
+            adapter.xsd_children(root, unit)
+            self.assertEqual([node.attrib['name'] for node in root], ['ArchiveObject', 'Document'])
+
 
 class SEDAExportUnitTest(unittest.TestCase):