def test_disallowed_field(schematron_fx, context_element, disallowedlist,
                          version):
    """Various elements and attributes have been added to newer EAD3 version.
    Test the checks that disallow the use of new element/attribute in an old
    EAD3 version.

    :schematron_fx: Schematron compile fixture
    :context_element: Context element, which may contain new elements or
                      attributes.
    :disallowedlist: List of new elements and attributes
    :version: Earliest EAD3 version where the list apply
    """
    (ead3, elem_context, elem_version) = prepare_xml(context_element, version)
    for disallowed in disallowedlist:
        if disallowed[0] == '@':
            set_attribute(elem_context, disallowed[1:], 'ead3', 'default')
        else:
            set_element(elem_context, disallowed, 'ead3')

    # The elements/attributes are allowed in the given EAD3 version
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets', version)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=ead3)
    assert svrl.count(SVRL_FAILED) == 0

    # The elements/attributes are disallowed in the previous EAD3 version
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets', '1.0.0')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=ead3)
    assert svrl.count(SVRL_FAILED) == len(disallowedlist)

    # No errors, if the disallowed items are removed
    elem_context.clear()
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=ead3)
    assert svrl.count(SVRL_FAILED) == 0
示例#2
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
示例#3
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_mix_optional_element_rules(schematron_fx, elementkey, subelements,
                                    condition, newfired):
    """Test for checks to elements that become mandatory when optional element
    has been used and optionally some condition in true.

    :schematron_fx: Schematron compile fixture
    :elementkey: Optional element
    :subelements: Subelement
    :condition: Element and value that is needed to make subelements mandatory
                If None, the subelement becomes mandatory with elementkey
    :newfired: Such errors that are expected to be generated, which are
               irrelevant in this test
    """
    (mix, root) = parse_xml_file('mix_valid_minimal.xml')
    found = root
    for iter_elem in elementkey:
        elem_handler = find_element(root, iter_elem, 'mix')
        if elem_handler is None:
            found = set_element(found, iter_elem, 'mix')
        else:
            found = elem_handler
    elem_handler = found
    if condition is not None:
        elem_condition = set_element(elem_handler, condition[0], 'mix')
        if condition[1] is not None:
            elem_condition.text = condition[1]
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mix)
    assert svrl.count(SVRL_FAILED) == len(subelements) + newfired[0]

    for subelement in subelements:
        set_element(elem_handler, subelement, 'mix')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mix)
    assert svrl.count(SVRL_FAILED) == newfired[1]
示例#5
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_palette_profile(schematron_fx):
    """Palette color profile test. Palettte requires Colormap.

    :schematron_fx: Schematron compile fixture
    """
    (mix, root) = parse_xml_file('mix_valid_minimal.xml')
    elem_handler = find_element(root, 'colorSpace', 'mix')
    elem_handler.text = 'PaletteColor'
    elem_handler = find_element(root, 'samplesPerPixel', 'mix')
    elem_handler.text = '1'

    # Colormap missing
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mix)
    assert svrl.count(SVRL_FAILED) == 1

    # Colormap exists, but it requires a reference
    elem_handler = find_element(root, 'ImageColorEncoding', 'mix')
    elem_handler = set_element(elem_handler, 'Colormap', 'mix')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mix)
    assert svrl.count(SVRL_FAILED) == 1

    # Reference added
    set_element(elem_handler, 'colormapReference', 'mix')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mix)
    assert svrl.count(SVRL_FAILED) == 0
def test_disallowed_items_sourcemd(schematron_fx):
    """Test if use of disallowed atrtibute or element causes error.

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

    # Set disallowed attribute/element
    elem_handler = find_element(root, 'sourceMD', 'mets')
    set_element(elem_handler, 'mdRef', 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_rightsstatement_failure(schematron_fx):
    """There was an accidential error in specification 1.5.0 where
    rightsStatement was accepted as root element in PREMIS:RIGHTS. The correct
    element is 'rights'. Test that 'rights' works in all versions, and
    'rightsStatement' gives a warning with specification 1.5.0 and error
    in all other versions.

    :schematron_fx: Schematron compile fixture
    """
    xml = '''<mets:mets fi:CATALOG="1.6.0" xmlns:mets="%(mets)s"
             xmlns:dc="%(dc)s" xmlns:premis="%(premis)s" xmlns:fi="%(fikdk)s">
               <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:rightsMD>
                 <mets:mdWrap MDTYPE="PREMIS:RIGHTS" MDTYPEVERSION="2.3">
                 <mets:xmlData><premis:rightsStatement/>
               </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:amdSec></mets:mets>''' % NAMESPACES
    (mets, root) = parse_xml_string(xml)

    # rightsStatement gives an error with specification 1.6.0
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    # rightsStatement works with specification 1.5.0
    set_attribute(root, 'CATALOG', 'fikdk', '1.5.0')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # rights works with specification 1.6.0
    set_attribute(root, 'CATALOG', 'fikdk', '1.6.0')
    elem_handler = find_element(root, 'mdWrap[@MDTYPE="PREMIS:RIGHTS"]',
                                'mets')
    elem_handler = find_element(elem_handler, 'xmlData', 'mets')
    elem_handler.clear()
    set_element(elem_handler, 'rights', 'premis')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # rights works with specification 1.5.0
    set_attribute(root, 'CATALOG', 'fikdk', '1.5.0')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0
def test_disallowed_items_root(schematron_fx, disallowed):
    """Test if use of disallowed atrtibute or element causes error.

    :schematron_fx: Schematron compile fixture
    :disallowed: Disallowed element or attribute, use '@' for attributes.
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')

    # Set disallowed attribute/element
    elem_handler = find_element(root, 'mets', 'mets')
    set_element(elem_handler, disallowed, 'mets')
    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_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_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
示例#13
0
def test_disallowed_hierarch_attrib(
        schematron_fx, container, context, disallowed_attribute, version):
    """Various attributes have been added to newer MODS versions. Test the
    checks that disallow the use of new element/attribute in an old MODS
    version. Here the context element require container, since MODS has other
    irrelevant context elements with the same name outside the container.

    :schematron_fx: Schematron compile fixture
    :container: Element, where the context exists
    :context: Context element, which may contain new attribute.
    :disallowed_attribute: The new attribute
    :version: Earliest MODS version where the attribute applies
    """
    (mods, elem_context, elem_version) = prepare_xml(container, version)
    elem_context = set_element(elem_context, context, 'mods')
    set_attribute(elem_context, disallowed_attribute, 'mods', 'default')

    # Success with given version
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0

    # Error with earlier versions
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets',
                  '%.1f' % (float(version)-0.1))
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 1

    # Success again, if attribute removed
    elem_context.clear()
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0
def test_disallowed_items_structmap(schematron_fx, disallowed, context):
    """Test if use of disallowed atrtibute or element causes error.

    :schematron_fx: Schematron compile fixture
    :disallowed: Disallowed element or attribute, use '@' for attributes.
    :context: Context element, where the attribute or element exists
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')

    # Set disallowed attribute/element
    elem_handler = find_element(root, context, 'mets')
    if disallowed[0] == '@':
        set_attribute(elem_handler, disallowed[1:], 'mets', 'default')
    else:
        set_element(elem_handler, disallowed, 'mets')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
def test_section_schemas(catalog_fx, rootelement, namespace, section):
    """Test that section schemas in the catalog work in validation.

    :catalog_fx: Schema catalog validation fixture
    :rootelement: Root element of the section metadata
    :namespace: Namespace of the section metadata
    :section: METS metadata section
    """
    (mets, root) = prepare_xml_for_tests()
    elem_handler = find_element(root, section, 'mets')
    elem_handler = find_element(elem_handler, 'xmlData', 'mets')
    elem_handler.clear()
    elem_handler = set_element(elem_handler, rootelement, namespace)
    if rootelement == 'object':
        set_attribute(elem_handler, 'type', 'xsi', 'premis:file')
    set_element(elem_handler, 'xxx', namespace)
    (returncode, _, stderr) = catalog_fx(xmltree=mets)
    assert returncode == 3
    assert b'xxx' in stderr
示例#16
0
def test_exempt_element(schematron_fx):
    """Element 'cartographics' could not be empty in MODS 3.0.

    :schematron_fx: Schematron compile fixture
    """
    (mods, elem_context, elem_version) = prepare_xml('cartographics', '3.0')

    # Add 'coordinates' to 'cartographics'
    set_element(elem_context, 'coordinates', 'mods')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0

    # Error, if no subelements
    elem_context.clear()
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 1

    # No error, if MODS version changed
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets', '3.1')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0
示例#17
0
def test_deprecated_element(schematron_fx):
    """Element 'province' was deprecated in MODS 3.6

    :schematron_fx: Schematron compile fixture
    """
    (mods, elem_context, elem_version) = prepare_xml(
        'hierarchicalGeographic', '3.6')

    # Success without 'province'
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_REPORT) == 0
    set_element(elem_context, 'province', 'mods')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)

    # Warning, if 'province' exists
    assert svrl.count(SVRL_REPORT) == 1

    # Success when version changed to 3.5
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets', '3.5')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_REPORT) == 0
示例#18
0
def test_removed_element(schematron_fx):
    """Element 'extraterrestrialArea' was removed in MODS 3.6

    :schematron_fx: Schematron compile fixture
    """
    (mods, elem_context, elem_version) = prepare_xml('hierarchicalGeographic',
                                                     '3.6')

    # Success without 'extraterrestrialArea'
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0

    # Error, if 'extraterrestrialArea' exists
    set_element(elem_context, 'extraterrestrialArea', 'mods')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 1

    # Success when version changed to 3.5
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets', '3.5')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0
示例#19
0
def test_required_subelements(schematron_fx, elementname, version):
    """Some MODS elements require subelements until certain MODS version.

    :elementname: Element which require subelements in earlier MODS versions
    :version: Earliest MODS version, where element may be empty
    :schematron_fx: Schematron compile fixture
    """
    (mods, elem_context, elem_version) = prepare_xml(elementname, version)

    # Element is empty, given MODS version
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0

    # Element is empty, earlier MODS version
    set_attribute(elem_version, 'MDTYPEVERSION', 'mets',
                  '%.1f' % (float(version)-0.1))
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 1

    # Success, when we add something
    set_element(elem_context, 'xxx', None)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mods)
    assert svrl.count(SVRL_FAILED) == 0
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)
示例#21
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)
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