def test_recordstatus(schematron_fx):
    """Test that RECORDSTATUS can always be 'submission',
    and also 'update' and 'dissemination' for CSC.
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    hdr = find_element(root, 'metsHdr', 'mets')

    set_attribute(hdr, 'RECORDSTATUS', 'mets', 'update')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    set_attribute(hdr, 'RECORDSTATUS', 'mets', 'dissemination')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    agent = find_element(hdr, 'name', 'mets')
    agent.text = 'CSC - IT Center for Science Ltd.'

    set_attribute(hdr, 'RECORDSTATUS', 'mets', 'submission')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    set_attribute(hdr, 'RECORDSTATUS', 'mets', 'update')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    set_attribute(hdr, 'RECORDSTATUS', 'mets', 'dissemination')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0
def test_mdtype_items_digiprovmd(schematron_fx, mdtype, othermdtype,
                                 mdtypeversion):
    """Test that all valid metadata types and their versions work properly.

    :schematron_fx: Schematron compile fixture
    :mdtype: MDTYPE attribute value
    :othermdtype: OTHERMDTYPE attribute valur
    :mdtypeversion: MDTYPEVERSION attribute value
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, 'digiprovMD', 'mets')
    elem_handler = find_element(elem_handler, 'mdWrap', 'mets')
    set_attribute(elem_handler, 'MDTYPE', 'mets', mdtype)
    if othermdtype is not None:
        set_attribute(elem_handler, 'OTHERMDTYPE', 'mets', othermdtype)

    # Test that all MDTYPEVERSIONs work with all specifications
    for specversion in [
            '1.5.0', '1.6.0', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.7.4'
    ]:
        if specversion in ['1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.7.4']:
            fix_version_17(root)
        else:
            set_attribute(root, 'CATALOG', 'fikdk', specversion)
            set_attribute(root, 'SPECIFICATION', 'fikdk', specversion)
        for version in mdtypeversion:
            set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', version)
            svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
            assert svrl.count(SVRL_FAILED) == 0

    # Test unknown version
    fix_version_17(root)
    set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
Example #3
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_mdtype_items_mdwrap(schematron_fx, context, mdtype, othermdtype,
                             mdtypeversion):
    """Test that all valid metadata types and their versions work properly.

    :schematron_fx: Schematron compile fixture
    :context: METS section to be tested
    :mdtype: MDTYPE attribute value
    :othermdtype: OTHERMDTYPE attribute valur
    :mdtypeversion: MDTYPEVERSION attribute value
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    fix_version_17(root)
    elem_handler = find_element(root, context, 'mets')
    elem_handler = find_element(elem_handler, 'mdWrap', 'mets')
    set_attribute(elem_handler, 'MDTYPE', 'mets', mdtype)
    if othermdtype is not None:
        set_attribute(elem_handler, 'OTHERMDTYPE', 'mets', othermdtype)

    # Test that unknown OTHERMDTYPE gives error, if MDTYPE is not 'OTHER'
    set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', mdtypeversion[0])
    set_attribute(elem_handler, 'OTHERMDTYPE', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    if mdtype == 'OTHER':
        assert svrl.count(SVRL_FAILED) == 0
    else:
        assert svrl.count(SVRL_FAILED) == 1
Example #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
Example #6
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_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 make_colorsample(colorspace, sample, addsample, extrasample):
    """ Modifies MIX metadata with given colorspace and sample info.

    :colorspace: Colorspace to be tested
    :sample: Number of samples required by the colorspace
    :addsample: Offset for the required sample
    :extraSample: Boolean, true if extra sample is defined.
    :returns: Modified MIX XML tree
    """
    # Prepare the MIX data for the colorspace and sample test
    (mix, root) = parse_xml_file('mix_valid_minimal.xml')
    make_colorprofile(root)
    elem_handler = find_element(root, 'ImageColorEncoding', 'mix')
    xml = '''<mix:Colormap xmlns:mix="%(mix)s">
             <mix:colormapReference/></mix:Colormap>''' % NAMESPACES
    elem_handler.append(ET.XML(xml))
    elem_handler = find_element(root, 'colorSpace', 'mix')
    elem_handler.text = colorspace
    elem_handler = find_element(root, 'samplesPerPixel', 'mix')
    elem_handler.text = str(sample + addsample)
    elem_handler = find_element(root, 'ImageColorEncoding', 'mix')
    elem_extra = find_element(elem_handler, 'extraSamples', 'mix')
    if elem_extra is not None:
        elem_handler.remove(elem_extra)
    if extrasample:
        extra = '{%(mix)s}extraSamples' % NAMESPACES
        elem_handler.insert(2, ET.Element(extra))

    return mix
Example #9
0
def test_mdtype_items_rightsmd(schematron_fx):
    """Test that all valid metadata types and their versions work properly.

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

    # Test that all MDTYPEVERSIONs work with all specifications
    for specversion in [
            '1.5.0', '1.6.0', '1.7.0', '1.7.1', '1.7.2', '1.7.3', '1.7.4'
    ]:
        if specversion in ['1.7.0', '1.7.1', '1.7.3', '1.7.4']:
            fix_version_17(root)
        else:
            set_attribute(root, 'CATALOG', 'fikdk', specversion)
            set_attribute(root, 'SPECIFICATION', 'fikdk', specversion)
        for version in ['2.3', '2.2']:
            set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', version)
            svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
            assert svrl.count(SVRL_FAILED) == 0

    # Test unknown version
    fix_version_17(root)
    set_attribute(elem_handler, 'MDTYPEVERSION', 'mets', 'xxx')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
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_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_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_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_value_items_root(schematron_fx, attribute, nspace, fixed):
    """Test that a value is required in a certain attributes.

    :schematron_fx: Schematron compile fixture
    :attribute: Attribute, where the value is required
    :nspace: Namespace key of the attribute
    :fixed: Boolean, if the required value is fixed
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    if nspace == 'fi':
        fix_version_17(root)

    # Use arbitrary value
    elem_handler = find_element(root, 'mets', 'mets')
    set_attribute(elem_handler, attribute, nspace, 'aaa')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    if fixed:
        assert svrl.count(SVRL_FAILED) == 1
    else:
        assert svrl.count(SVRL_FAILED) == 0

    # Use empty value
    set_attribute(elem_handler, attribute, nspace, '')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
Example #15
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_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]
def test_objid_unique(schematron_fx):
    """Check that error is given, if OBJID is not unique with METS IDs,
    except for CONTENTID that can be identical to OBJID.

    :schematron_fx: Schematron compile fixture
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    objid = get_attribute(root, 'OBJID', 'mets')
    contentid = get_attribute(root, 'CONTENTID', 'fikdk')
    set_attribute(root, 'CONTENTID', 'fikdk', objid)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    set_attribute(root, 'CONTENTID', 'fikdk', contentid)
    elem_handler = find_element(root, 'dmdSec', 'mets')
    section_id = get_attribute(elem_handler, 'ID', 'mets')
    set_attribute(root, 'OBJID', 'mets', section_id)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    set_attribute(root, 'OBJID', 'mets', objid)
    fix_version_17(root)
    set_attribute(root, 'CONTRACTID', 'fi', objid)
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
Example #18
0
def test_mandatory_elements(
        schematron_fx, testset, namespace, filename, schfile):
    """Test mandatory element checks for metadata. Here we practically give a
    minimal XML, which is valid in a certain namespace. Then we start to remove
    elements from it one by one (until nothing remains). With every loop the
    number of fired schematron rules and failures are different. Since the
    next loop is dependent on the previous loop, the whole looping is done
    inside one test run.

    :schematron_fx: Schematron compile fixture
    :testset: A list of tuples containing the element to be removed, number of
              expected schematron checks, and number of expected failures.
    :namespace: Namespace key, where the test is done.
    :filename: File name containing the valid minimal METS
    :schfile: Schematron file to use in the test
    """
    (mets, root) = parse_xml_file(filename)
    for testcase in testset:
        (leafelement, fired, failed) = testcase
        if leafelement is not None:
            elem_handler = find_element(root, leafelement, namespace)
            elem_handler.clear()
        svrl = schematron_fx(schematronfile=schfile, xmltree=mets,
                             params=False)
        assert svrl.count(SVRL_FIRED) == fired
        assert svrl.count(SVRL_FAILED) == failed

        svrl = schematron_fx(schematronfile=schfile, xmltree=mets)
        assert svrl.count(SVRL_FAILED) == failed
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_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_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_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_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 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 make_colorprofile(root):
    """Add color profile to MIX XML tree
    :root: XML tree root element
    """
    elem_handler = find_element(root, 'PhotometricInterpretation', 'mix')
    xml = '''<mix:ColorProfile xmlns:mix="%(mix)s">
               <mix:IccProfile><mix:iccProfileName/></mix:IccProfile>
             </mix:ColorProfile>''' % NAMESPACES
    elem_handler.append(ET.XML(xml))
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
def test_digiprov_object(schematron_fx):
    """PREMIS:OBJECT is allowed in digiprovMD, if it's type is representation.

    :schematron_fx: Schematron compile fixture
    """
    xml = '''<mets:mets fi:CATALOG="1.6.0" xmlns:mets="%(mets)s"
             xmlns:premis="%(premis)s" xmlns:xsi="%(xsi)s"
             xmlns:fi="%(fikdk)s" xmlns:dc="%(dc)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:digiprovMD>
                 <mets:mdWrap MDTYPE='PREMIS:OBJECT' MDTYPEVERSION="2.3">
                 <mets:xmlData>
                   <premis:object xsi:type='premis:representation'/>
                 </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
    ET.register_namespace('premis', NAMESPACES['premis'])
    (mets, root) = parse_xml_string(xml)

    # Works with premis:representation
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 0

    # Fails with other values
    elem_handler = find_element(root, 'digiprovMD', 'mets')
    elem_handler = find_element(elem_handler, 'object', 'premis')
    set_attribute(elem_handler, 'type', 'xsi', 'premis:file')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1

    set_attribute(elem_handler, 'type', 'xsi', 'premis:bitstream')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == 1
Example #28
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_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
Example #30
0
def test_missing_links_dmdsec(schematron_fx):
    """Test the case where linking missing from ADMID, DMDID and FILEID to
    corresponding METS sections.

    :schematron_fx: Schematron compile fixture
    """
    (mets, root) = parse_xml_file('mets_valid_complete.xml')
    elem_handler = find_element(root, 'div', 'mets')
    refs = get_attribute(elem_handler, 'DMDID', 'mets').split()
    set_attribute(elem_handler, 'DMDID', 'mets', '')
    svrl = schematron_fx(schematronfile=SCHFILE, xmltree=mets)
    assert svrl.count(SVRL_FAILED) == len(refs)