def test_checksums(schematron_fx, algorithm): """Test that the controlled vocabulary for messageDigestAlgorithm work. :schematron_fx: Schematron compile fixture :algorithm: Valid algorithm name or 'xxx' as invalid arbitrary name. """ xml = '''<mets:techMD xmlns:mets="%(mets)s" xmlns:premis="%(premis)s" xmlns:xsi="%(xsi)s"> <mets:mdWrap MDTYPE="PREMIS:OBJECT" MDTYPEVERSION="2.3"> <mets:xmlData> <premis:object xsi:type="premis:file"> <premis:objectCharacteristics><premis:fixity> <premis:messageDigestAlgorithm/> </premis:fixity></premis:objectCharacteristics> </premis:object> </mets:xmlData> </mets:mdWrap> </mets:techMD>''' % NAMESPACES (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') elem_handler = find_element(root, 'messageDigestAlgorithm', 'premis') elem_handler.text = algorithm svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) if algorithm == 'xxx': assert svrl.count(SVRL_FAILED) == 2 else: assert svrl.count(SVRL_FAILED) == 1
def test_pronom_codes(schematron_fx, fileformat, pronom): """Test that checks for PRONOM code matching to MIME type is done. :schematron_fx: Schematron compile fixture :fileformat: File format as MIME type :pronom: Allowed PRONOM codes for the file format """ xml = '''<mets:techMD xmlns:mets="%(mets)s" xmlns:premis="%(premis)s"> <mets:mdWrap MDTYPEVERSION="2.3"><mets:xmlData><premis:object> <premis:objectCharacteristics> <premis:format><premis:formatDesignation><premis:formatName/> </premis:formatDesignation><premis:formatRegistry> <premis:formatRegistryKey/></premis:formatRegistry> </premis:format></premis:objectCharacteristics> </premis:object></mets:xmlData></mets:mdWrap> </mets:techMD>''' % NAMESPACES (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') elem_handler = find_element(root, 'formatName', 'premis') elem_handler.text = fileformat elem_handler = find_element(root, 'formatRegistryKey', 'premis') # All acceptable PRONOM codes work for pronomcode in pronom: elem_handler.text = pronomcode svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0 # Arbitrary PRONOM code fails elem_handler.text = 'xxx' svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 1
def test_identifier_value_object(schematron_fx, nonempty): """PREMIS identifier elements can not be empty. Test that a value in the element is required. :schematron_fx: Schematron compile fixture :nonempty: element that requires a value """ xml = '''<mets:techMD xmlns:mets="%(mets)s" xmlns:premis="%(premis)s"> <mets:mdWrap MDTYPE="PREMIS:OBJECT" MDTYPEVERSION="2.3"> <mets:xmlData><premis:object><premis:objectIdentifier/> </premis:object></mets:xmlData></mets:mdWrap> </mets:techMD>''' % NAMESPACES (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') elem_handler = find_element(root, 'objectIdentifier', 'premis') elem_handler = set_element(elem_handler, nonempty, 'premis') # Empty identifier element fails svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 1 # Arbitrary value added elem_handler.text = 'xxx' svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0
def test_identifier_value_premis_event_agent(schematron_fx, premisroot, mdtype, nonempty): """PREMIS identifier elements can not be empty. Test that a value in the element is required. :schematron_fx: Schematron compile fixture :premisroot: PREMIS root element name :mdtype: MDTYPE :nonempty: element that requires a value """ xml = '''<mets:digiprovMD xmlns:mets="%(mets)s"> <mets:mdWrap MDTYPEVERSION="2.3"><mets:xmlData/></mets:mdWrap> </mets:digiprovMD>''' % NAMESPACES (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') elem_handler = find_element(root, 'mdWrap', 'mets') set_attribute(elem_handler, 'MDTYPE', 'mets', mdtype) elem_handler = find_element(elem_handler, 'xmlData', 'mets') for elem in premisroot: elem_handler = set_element(elem_handler, elem, 'premis') elem_handler = set_element(elem_handler, nonempty, 'premis') # Empty identifier element fails svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 1 # Arbitrary value added elem_handler.text = 'xxx' svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0
def test_disallowed_attribute_premis_rightsmd(schematron_fx): """Test that attributes 'authority', 'authorityURI', 'valueURI' in PREMIS 2.3 are disallowed in PREMIS 2.2. :schematron_fx: Schematron compile fixture """ xml = '''<mets:rightsMD xmlns:mets="%(mets)s" xmlns:premis="%(premis)s"> <mets:mdWrap MDTYPE="PREMIS:RIGHTS" MDTYPEVERSION="2.3"> <mets:xmlData><premis:rights><premis:rightsStatement/> </premis:rights></mets:xmlData></mets:mdWrap> </mets:rightsMD>''' % NAMESPACES (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') elem_handler = find_element(root, 'rightsStatement', 'premis') elem_handler = set_element(elem_handler, 'xxx', 'premis') for disallowed in ['authority', 'authorityURI', 'valueURI']: set_attribute(elem_handler, disallowed, 'premis', 'default') # Works in 2.3 svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0 # Disallowed in 2.2 elem_wrap = find_element(root, 'mdWrap', 'mets') set_attribute(elem_wrap, 'MDTYPEVERSION', 'mets', '2.2') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 3 # 2.2 works, if attributes removed elem_handler.clear() svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0
def test_disallowed_attribute_premis_digiprov(schematron_fx, premisroot, mdtype): """Test that attributes 'authority', 'authorityURI', 'valueURI' in PREMIS 2.3 are disallowed in PREMIS 2.2. :schematron_fx: Schematron compile fixture :premisroot: Root element in PREMIS. :mdtype: MDTYPE value """ xml = '''<mets:digiprovMD xmlns:mets="%(mets)s"> <mets:mdWrap MDTYPEVERSION="2.3"><mets:xmlData/></mets:mdWrap> </mets:digiprovMD>''' % NAMESPACES (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') elem_wrap = find_element(root, 'mdWrap', 'mets') set_attribute(elem_wrap, 'MDTYPE', 'mets', mdtype) elem_handler = find_element(elem_wrap, 'xmlData', 'mets') elem_handler = set_element(elem_handler, premisroot, 'premis') elem_handler = set_element(elem_handler, 'xxx', 'premis') for disallowed in ['authority', 'authorityURI', 'valueURI']: set_attribute(elem_handler, disallowed, 'premis', 'default') # Works in 2.3 svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0 # Disallowed in 2.2 set_attribute(elem_wrap, 'MDTYPEVERSION', 'mets', '2.2') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 3 # 2.2 works, if attributes removed elem_handler.clear() svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0
def test_addml_headerlevel_version(schematron_fx): """Test element 'headerLevel' with ADDML versions 8.2 and 8.3. It is a new element in 8.3 (forbidden in 8.2). :schematron_fx: Schematron compile fixture """ xml = '''<addml:addml><addml:dataset><addml:reference/><addml:flatFiles> <addml:flatFileDefinitions><addml:flatFileDefinition> <addml:recordDefinitions><addml:recordDefinition> <addml:headerLevel/> </addml:recordDefinition></addml:recordDefinitions> </addml:flatFileDefinition></addml:flatFileDefinitions> </addml:flatFiles></addml:dataset></addml:addml>''' \ % NAMESPACES (mets, root) = parse_xml_string(METS_HEAD+xml+METS_TAIL) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') # Element 'headerLevel' is forbidden in 8.2 svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets, params=False) assert svrl.count(SVRL_FIRED) == 2 assert svrl.count(SVRL_FAILED) == 1 # No checks with version 8.3 elem_handler = find_element(root, 'mdWrap', 'mets') set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', '8.3') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets, params=False) assert svrl.count(SVRL_FIRED) == 0 assert svrl.count(SVRL_FAILED) == 0
def test_addml_reference_version(schematron_fx): """Test element 'reference' with ADDML versions 8.2 and 8.3. It is required only in 8.2. :schematron_fx: Schematron compile fixture """ xml = METS_HEAD+'''<addml:addml><addml:dataset/></addml:addml>'''+METS_TAIL # Element 'reference' is required in 8.2, but missing (mets, root) = parse_xml_string(xml) (mets, root) = add_containers(root, 'mets:mets/mets:amdSec') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FIRED) == 1 assert svrl.count(SVRL_FAILED) == 1 # Element 'reference' is required in 8.2, and it exists elem_handler = find_element(root, 'dataset', 'addml') set_element(elem_handler, 'reference', 'addml') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets) assert svrl.count(SVRL_FAILED) == 0 # No checks with version 8.3 elem_handler = find_element(root, 'mdWrap', 'mets') set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', '8.3') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets, params=False) assert svrl.count(SVRL_FIRED) == 0 assert svrl.count(SVRL_FAILED) == 0
def test_container(): """Test container addition """ (_, root ) = parse_xml_string('<mets:foo xmlns:mets="http://www.loc.gov/METS/"/>') (_, root) = add_containers(root, 'mets:mets/mets:amdSec') xml = b'<mets:mets xmlns:mets="http://www.loc.gov/METS/">' \ b'<mets:amdSec><mets:foo/></mets:amdSec></mets:mets>' assert ET.tostring(root) == xml
def prepare_xml(context_element, version): """The EAD3 metadata is prepared here for all the tests below. :context_element: Context element, where the test is done :version: EAD3 version to be used. """ xml = '''<mets:dmdSec xmlns:mets="%(mets)s" xmlns:ead3="%(ead3)s"> <mets:mdWrap MDTYPE="EAD3" MDTYPEVERSION="1.1.0"> <mets:xmlData><ead3:ead/></mets:xmlData></mets:mdWrap> </mets:dmdSec>''' % NAMESPACES (ead3, root) = parse_xml_string(xml) (ead3, root) = add_containers(root, 'mets:mets') elem_handler = find_element(root, 'ead', 'ead3') if context_element is not None: elem_context = set_element(elem_handler, context_element, 'ead3') elem_version = find_element(root, 'mdWrap', 'mets') set_attribute(elem_version, 'MDTYPEVERSION', 'mets', version) return (ead3, elem_context, elem_version)
def test_ead3_extension(schematron_fx, xml, failures): """Test the rule which checks the content of the <objectxmlwrap> element in EAD3. It may contain any elements, but only outside EAD3 namespace. :schematron_fx: Schematron compile fixture :xml: XML to be validated :failures: Number of Schematron failures to expect """ (xmltree, root) = parse_xml_string(xml) (xmltree, mets_root) = add_containers( root, 'mets:mets/mets:dmdSec/mets:mdWrap/mets:xmlData/ead3:ead') mdwrap = find_element(mets_root, 'mdWrap', 'mets') set_attribute(mdwrap, 'MDTYPEVERSION', 'mets', '1.0.0') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=xmltree, params=False) assert svrl.count(SVRL_FIRED) == 1 assert svrl.count(SVRL_FAILED) == failures set_attribute(mdwrap, 'MDTYPEVERSION', 'mets', '1.1.0') svrl = schematron_fx(schematronfile=SCHFILE, xmltree=xmltree, params=False) assert svrl.count(SVRL_FIRED) == 0
def prepare_xml(context_element, version): """The MODS metadata is prepared here for all the tests below. :context_element: Context element, where the test is done :version: MODS version to be used. """ xml = '''<mets:dmdSec xmlns:mets="%(mets)s" xmlns:mods="%(mods)s"> <mets:mdWrap MDTYPE="MODS" MDTYPEVERSION="3.7"> <mets:xmlData><mods:mods/></mets:xmlData></mets:mdWrap> </mets:dmdSec>''' % NAMESPACES (mods, root) = parse_xml_string(xml) (mods, root) = add_containers(root, 'mets:mets') elem_handler = find_element(root, 'mods', 'mods') if context_element is not None: elem_context = set_element(elem_handler, context_element, 'mods') else: elem_context = elem_handler elem_version = find_element(root, 'mdWrap', 'mets') set_attribute(elem_version, 'MDTYPEVERSION', 'mets', version) return (mods, elem_context, elem_version)