def test_dependent_attributes_structmap(schematron_fx, nspace):
    """Test attribute dependencies with another attribute. Some attributes
    become mandatory or disallowed, if another attribute is used.

    :schematron_fx: Schematron compile fixture
    :nspace: Namespace key of the attributes
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, 'structMap', 'mets')
    if nspace == 'fi':
        fix_version_17(root)

    # Both attributes
    set_attribute(elem_handler, 'PID', nspace, 'xxx')
    set_attribute(elem_handler, 'PIDTYPE', nspace, 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Just the second attribute
    del_attribute(elem_handler, 'PID', nspace)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    # No attributes
    del_attribute(elem_handler, 'PIDTYPE', nspace)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Just the first attribute
    set_attribute(elem_handler, 'PID', nspace, 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_dependent_attributes_mdwrap(schematron_fx):
    """Test attribute dependencies with another attribute. Some attributes
    become mandatory or disallowed, if another attribute is used.

    :schematron_fx: Schematron compile fixture
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, 'mdWrap', 'mets')

    # Both attributes
    set_attribute(elem_handler, 'CHECKSUM', 'mets', 'xxx')
    set_attribute(elem_handler, 'CHECKSUMTYPE', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Just the second attribute
    del_attribute(elem_handler, 'CHECKSUM', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    # No attributes
    del_attribute(elem_handler, 'CHECKSUMTYPE', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Just the first attribute
    set_attribute(elem_handler, 'CHECKSUM', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_fileid(schematron_fx):
    """Test that FILEID is allowed in fptr or area, but disallowed,
    if missing.

    :schematron_fx: Schematron compile fixture
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')

    # FILEID in fptr and area
    elem_handler = find_element(root, 'fptr', 'mets')
    elem_handler_area = set_element(elem_handler, 'area', 'mets')
    set_attribute(elem_handler_area, 'FILEID', 'mets',
                  get_attribute(elem_handler, 'FILEID', 'mets'))
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # FILEID only in area
    del_attribute(elem_handler, 'FILEID', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Also area missing
    del_element(elem_handler, 'area', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_othermdtype(schematron_fx, context):
    """Test that OTHERMDTYPE and the version are mandatory, but can be anything
    in all METS sections, if MDTYPE is OTHER.

    :schematron_fx: Schematron compile fixture
    :context: METS section to be tested
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')

    # OTHERMDTYPE and version can be anything
    elem_handler = find_element(root, context, 'mets')
    elem_handler = find_element(elem_handler, 'mdWrap', 'mets')
    set_attribute(elem_handler, 'MDTYPE', 'mets', 'OTHER')
    set_attribute(elem_handler, 'OTHERMDTYPE', 'mets', 'xxx')
    set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Version is mandatory
    del_attribute(elem_handler, 'MDTYPEVERSION', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    # OTHERMDTYPE is missing
    del_attribute(elem_handler, 'OTHERMDTYPE', 'mets')
    set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 2
def test_arbitrary_attributes_structmap(schematron_fx, context):
    """Test that arbitrary attributes are forbidden in METS anyAttribute
       sections.
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, context, 'mets')
    for spec in [None, '1.7.0']:
        if spec == '1.7.0':
            fix_version_17(root)
        for ns in ['fi', 'fikdk', 'dc']:
            set_attribute(elem_handler, 'xxx', ns, 'xxx')
            svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
            assert svrl.count(SVRL_FAILED) == 1
            del_attribute(elem_handler, 'xxx', ns)
def test_mandatory_items_mdref(schematron_fx, mandatory, nspace):
    """Test mandatory attributes of mdRef

    :schematron_fx: Schematron compile fixture
    :mandatory: Mandatory attribute
    :nspace: Namespace key of the mandatory attribute
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, 'mdRef', 'mets')

    # Remove mandatory attribute
    del_attribute(elem_handler, mandatory, nspace)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_mandatory_items_structmap(schematron_fx, mandatory, nspace, context):
    """Test mandatory attributes

    :schematron_fx: Schematron compile fixture
    :mandatory: Mandatory attribute
    :nspace: Namespace key of the mandatory attribute
    :context: Element, where the attribute exists
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, context, 'mets')

    # Remove mandatory attribute
    del_attribute(elem_handler, mandatory, nspace)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_catalogs(schematron_fx):
    """Test the Schema catalog version numbering in METS.

    :schematron_fx: Schematron compile fixture
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')

    # Conflict between fi:CATALOG and fi:SPECIFICATION
    set_attribute(root, 'CATALOG', 'fikdk', '1.5.0')
    del_attribute(root, 'CONTENTID', 'fikdk')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)

    assert svrl.count(SVRL_FAILED) == 1
    assert svrl.count(SVRL_REPORT) == 1

    # Deprecated specification
    set_attribute(root, 'SPECIFICATION', 'fikdk', '1.5.0')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0
    assert svrl.count(SVRL_REPORT) == 1
def test_mandatory_items_metshdr(schematron_fx, mandatory, nspace, context):
    """

    :schematron_fx: Schematron compile fixture
    :mandatory: Mandatory attribute
    :nspace: Namespace key of the mandatory attribute
    :context: Element, where the attribute exists
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, context, 'mets')

    # Missing attribute in agent gives more than one error
    extra = 0
    if context == 'agent':
        extra = 1

    # Remove mandatory attribute
    del_attribute(elem_handler, mandatory, nspace)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1 + extra
Example #10
0
def test_dependent_attributes_amdsec(schematron_fx, context, nspaces,
                                     attributes, error):
    """Test attribute dependencies with another attribute. Some attributes
    become mandatory or disallowed, if another attribute is used.

    :schematron_fx: Schematron compile fixture
    :context: Element where the attributes exist
    :nspaces: Namespace keys of the attributes (two)
    :attributes: Dependent attributes (two)
    :error: The error table [a, b, c, d] where the values are the number of
            expected errors. (a) both attributes missing, (b) first exists,
            (c) second exists, (d) both exist.
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, context, 'mets')
    if nspaces[0] == 'fi':
        fix_version_17(root)

    # Both attributes
    set_attribute(elem_handler, attributes[0], nspaces[0], 'xxx')
    set_attribute(elem_handler, attributes[1], nspaces[1], 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == error[3]

    # Just the second attribute
    del_attribute(elem_handler, attributes[0], nspaces[0])
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == error[2]

    # No attributes
    del_attribute(elem_handler, attributes[1], nspaces[1])
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == error[0]

    # Just the first attribute
    set_attribute(elem_handler, attributes[0], nspaces[0], 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == error[1]
def test_dependent_attributes_root(schematron_fx, nspaces, attributes,
                                   version):
    """Test attribute dependencies with another attribute. Some attributes
    become mandatory or disallowed, if another attribute is used.

    :schematron_fx: Schematron compile fixture
    :nspaces: Namespace keys of the attributes (two)
    :attributes: Dependent attributes (two)
    :version: Specification version
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, 'mets', 'mets')
    failed = 2
    if nspaces[0] == 'fi':
        fix_version_17(root)
        failed = 1

    # Both attributes
    set_attribute(elem_handler, attributes[0], nspaces[0], version)
    set_attribute(elem_handler, attributes[1], nspaces[1], version)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Just the second attribute
    del_attribute(elem_handler, attributes[0], nspaces[0])
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # No attributes
    del_attribute(elem_handler, attributes[1], nspaces[1])
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == failed

    # Just the first attribute
    set_attribute(elem_handler, attributes[0], nspaces[0], version)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0
def test_mdtype_namespace(schematron_fx, section, mdinfo):
    """Test that the check for comparing given metadata type and the actual
    metadata works.

    :schematron_fx: Schematron compile fixture
    :section: Context section to be tested
    :mdinfo: Working metadata info: [MDTYPE, OTHERMDTYPE, MDTYPEVERSION,
             root element in the metadata section, namespace of the root]
    """
    xml = '''<mets:mets fi:CATALOG="1.6.0" xmlns:mets="%(mets)s"
             xmlns:premis="%(premis)s" xmlns:fi="%(fikdk)s" xmlns:dc="%(dc)s"
             xmlns:marc21="%(marc21)s" xmlns:ead="%(ead)s"
             xmlns:ead3="%(ead3)s" xmlns:lido="%(lido)s" xmlns:vra="%(vra)s"
              xmlns:mods="%(mods)s" xmlns:eac="%(eac)s"
              xmlns:ddilc32="%(ddilc32)s" xmlns:ddilc31="%(ddilc31)s"
              xmlns:ddicb25="%(ddicb25)s" xmlns:ddicb21="%(ddicb21)s"
              xmlns:mix="%(mix)s"
              xmlns:addml="%(addml)s" xmlns:audiomd="%(audiomd)s"
              xmlns:videomd="%(videomd)s">
               <mets:dmdSec><mets:mdWrap MDTYPE='DC' MDTYPEVERSION='1.1'>
                 <mets:xmlData>
                 <dc:subject/></mets:xmlData></mets:mdWrap></mets:dmdSec>
               <mets:dmdSec><mets:mdWrap MDTYPE='DC' MDTYPEVERSION='1.1'>
                 <mets:xmlData>
                 <dc:subject/></mets:xmlData></mets:mdWrap></mets:dmdSec>
               <mets:amdSec>
               <mets:techMD>
                 <mets:mdWrap MDTYPE='PREMIS:OBJECT' MDTYPEVERSION='2.3'>
                 <mets:xmlData><premis:object/></mets:xmlData></mets:mdWrap>
               </mets:techMD>
               <mets:techMD>
                 <mets:mdWrap MDTYPE='PREMIS:OBJECT' MDTYPEVERSION='2.3'>
                 <mets:xmlData><premis:object/></mets:xmlData></mets:mdWrap>
               </mets:techMD>
               <mets:rightsMD>
                 <mets:mdWrap MDTYPE="PREMIS:RIGHTS" MDTYPEVERSION='2.3'>
                 <mets:xmlData><premis:rights/></mets:xmlData></mets:mdWrap>
               </mets:rightsMD>
               <mets:rightsMD>
                 <mets:mdWrap MDTYPE="PREMIS:RIGHTS" MDTYPEVERSION='2.3'>
                 <mets:xmlData><premis:rights/></mets:xmlData></mets:mdWrap>
               </mets:rightsMD>
               <mets:digiprovMD>
                 <mets:mdWrap MDTYPE='PREMIS:EVENT' MDTYPEVERSION='2.3'>
                 <mets:xmlData><premis:event/></mets:xmlData></mets:mdWrap>
               </mets:digiprovMD><mets:digiprovMD>
                 <mets:mdWrap MDTYPE='PREMIS:EVENT' MDTYPEVERSION='2.3'>
                 <mets:xmlData><premis:event/></mets:xmlData></mets:mdWrap>
               </mets:digiprovMD>
             </mets:amdSec></mets:mets>''' % NAMESPACES
    (mets, root) = parse_xml_string(xml)
    if mdinfo[1] == 'DATACITE':
        fix_version_17(root)

    # Test that the given combination works
    elem_section = find_element(root, section, 'mets')
    elem_wrap = find_element(elem_section, 'mdWrap', 'mets')
    set_attribute(elem_wrap, 'MDTYPE', 'mets', mdinfo[0])
    if mdinfo[1] is not None:
        set_attribute(elem_wrap, 'OTHERMDTYPE', 'mets', mdinfo[1])
    set_attribute(elem_wrap, 'MDTYPEVERSION', 'mets', mdinfo[2])
    elem_handler = find_element(elem_wrap, 'xmlData', 'mets')
    elem_handler.clear()
    set_element(elem_handler, mdinfo[3], mdinfo[4])
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Wrong (empty) namespace
    elem_handler.clear()
    set_element(elem_handler, mdinfo[3], None)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    # Arbitrary MDTYPE (wrong)
    set_attribute(elem_wrap, 'MDTYPE', 'mets', 'xxx')
    if mdinfo[1] is not None:
        del_attribute(elem_wrap, 'OTHERMDTYPE', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    set_attribute(elem_wrap, 'MDTYPE', 'mets', mdinfo[0])
    if mdinfo[1] is not None:
        set_attribute(elem_wrap, 'OTHERMDTYPE', 'mets', mdinfo[1])
    assert svrl.count(SVRL_FAILED) == 1

    # Arbitrary MDTYPEVERSION (wrong)
    set_attribute(elem_wrap, 'MDTYPEVERSION', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    set_attribute(elem_wrap, 'MDTYPEVERSION', 'mets', mdinfo[2])
    assert svrl.count(SVRL_FAILED) == 1

    # Check that the metadata fails in other sections
    for othersection in ['dmdSec', 'techMD', 'rightsMD', 'digiprovMD']:
        if othersection != section:
            svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
            assert svrl.count(SVRL_FAILED) == 1