示例#1
0
def test_list_sets_long(app):
    """Test listing of sets."""
    from invenio_db import db
    from invenio_oaiserver.models import OAISet

    with app.app_context():
        current_oaiserver.unregister_signals_oaiset()
        with db.session.begin_nested():
            for i in range(27):
                oaiset = OAISet(
                    spec='test{0}'.format(i),
                    name='Test{0}'.format(i),
                    description='test desc {0}'.format(i),
                    search_pattern='title_statement.title:Test{0}'.format(i),
                )
                db.session.add(oaiset)
        db.session.commit()

    run_after_insert_oai_set()

    with app.test_client() as c:
        # First page:
        result = c.get('/oai2d?verb=ListSets')
        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 10

        resumption_token = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:resumptionToken', namespaces=NAMESPACES
        )[0]
        assert resumption_token.text

        # Second page:
        result = c.get('/oai2d?verb=ListSets&resumptionToken={0}'.format(
            resumption_token.text
        ))
        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 10

        resumption_token = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:resumptionToken', namespaces=NAMESPACES
        )[0]
        assert resumption_token.text

        # Third page:
        result = c.get('/oai2d?verb=ListSets&resumptionToken={0}'.format(
            resumption_token.text
        ))
        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 7

        resumption_token = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:resumptionToken', namespaces=NAMESPACES
        )[0]
        assert not resumption_token.text
示例#2
0
def without_oaiset_signals(app):
    """Temporary disable oaiset signals."""
    from invenio_oaiserver import current_oaiserver

    current_oaiserver.unregister_signals_oaiset()
    yield
    current_oaiserver.register_signals_oaiset()
def test_list_sets_long(app):
    """Test listing of sets."""
    from invenio_db import db
    from invenio_oaiserver.models import OAISet

    with app.app_context():
        current_oaiserver.unregister_signals_oaiset()
        with db.session.begin_nested():
            for i in range(27):
                oaiset = OAISet(
                    spec='test{0}'.format(i),
                    name='Test{0}'.format(i),
                    description='test desc {0}'.format(i),
                    search_pattern='title_statement.title:Test{0}'.format(i),
                )
                db.session.add(oaiset)
        db.session.commit()

    run_after_insert_oai_set()

    with app.test_client() as c:
        # First page:
        result = c.get('/oai2d?verb=ListSets')
        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 10

        resumption_token = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:resumptionToken', namespaces=NAMESPACES
        )[0]
        assert resumption_token.text

        # Second page:
        result = c.get('/oai2d?verb=ListSets&resumptionToken={0}'.format(
            resumption_token.text
        ))
        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 10

        resumption_token = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:resumptionToken', namespaces=NAMESPACES
        )[0]
        assert resumption_token.text

        # Third page:
        result = c.get('/oai2d?verb=ListSets&resumptionToken={0}'.format(
            resumption_token.text
        ))
        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 7

        resumption_token = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:resumptionToken', namespaces=NAMESPACES
        )[0]
        assert not resumption_token.text
def test_listsets_invalid_name(app):
    """Test ListSets with invalid unicode character for XML."""
    with app.test_request_context():
        current_oaiserver.unregister_signals_oaiset()
        with db.session.begin_nested():
            a = OAISet(spec='test', name=u'uni\x01co\x0bde',
                       description='test desc')
            db.session.add(a)

        with app.test_client() as c:
            result = c.get('/oai2d?verb=ListSets')

        tree = etree.fromstring(result.data)

        assert tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setName',
                          namespaces=NAMESPACES)[0].text == 'unicode'
示例#5
0
def test_listsets_invalid_name(app):
    """Test ListSets with invalid unicode character for XML."""
    with app.test_request_context():
        current_oaiserver.unregister_signals_oaiset()
        with db.session.begin_nested():
            a = OAISet(spec='test', name=u'uni\x01co\x0bde',
                       description='test desc')
            db.session.add(a)

        with app.test_client() as c:
            result = c.get('/oai2d?verb=ListSets')

        tree = etree.fromstring(result.data)

        assert tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setName',
                          namespaces=NAMESPACES)[0].text == 'unicode'
示例#6
0
def test_listsets(app):
    """Test ListSets."""
    with app.test_request_context():
        current_oaiserver.unregister_signals_oaiset()
        with db.session.begin_nested():
            a = OAISet(spec='test', name='Test', description='test desc')
            db.session.add(a)

        with app.test_client() as c:
            result = c.get('/oai2d?verb=ListSets')

        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH', namespaces=NAMESPACES)) == 1

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets',
                              namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                       namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setSpec',
                       namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setName',
                       namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setDescription',
                       namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setDescription/y:dc',
                       namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath(
                '/x:OAI-PMH/x:ListSets/x:set/x:setDescription/y:dc/'
                'z:description',
                namespaces=NAMESPACES)) == 1
        text = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:set/x:setDescription/y:dc/'
            'z:description/text()',
            namespaces=NAMESPACES)
        assert len(text) == 1
        assert text[0] == 'test desc'
def test_listsets(app):
    """Test ListSets."""
    with app.test_request_context():
        current_oaiserver.unregister_signals_oaiset()
        with db.session.begin_nested():
            a = OAISet(spec='test', name='Test', description='test desc')
            db.session.add(a)

        with app.test_client() as c:
            result = c.get('/oai2d?verb=ListSets')

        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH', namespaces=NAMESPACES)) == 1

        assert len(tree.xpath('/x:OAI-PMH/x:ListSets',
                              namespaces=NAMESPACES)) == 1
        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set',
                              namespaces=NAMESPACES)) == 1
        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setSpec',
                              namespaces=NAMESPACES)) == 1
        assert len(tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setName',
                              namespaces=NAMESPACES)) == 1
        assert len(tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:set/x:setDescription',
            namespaces=NAMESPACES
        )) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setDescription/y:dc',
                       namespaces=NAMESPACES)
        ) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListSets/x:set/x:setDescription/y:dc/'
                       'z:description', namespaces=NAMESPACES)
        ) == 1
        text = tree.xpath(
            '/x:OAI-PMH/x:ListSets/x:set/x:setDescription/y:dc/'
            'z:description/text()', namespaces=NAMESPACES)
        assert len(text) == 1
        assert text[0] == 'test desc'
示例#8
0
def test_listidentifiers(app):
    """Test verb ListIdentifiers."""
    from invenio_oaiserver.models import OAISet

    with app.app_context():
        current_oaiserver.unregister_signals_oaiset()
        # create new OAI Set
        with db.session.begin_nested():
            oaiset = OAISet(
                spec='test0',
                name='Test0',
                description='test desc 0',
                search_pattern='title_statement.title:Test0',
            )
            db.session.add(oaiset)
        db.session.commit()

    run_after_insert_oai_set()

    with app.test_request_context():
        indexer = RecordIndexer()

        # create a new record (inside the OAI Set)
        with db.session.begin_nested():
            record_id = uuid.uuid4()
            data = {'title_statement': {'title': 'Test0'}}
            recid_minter(record_id, data)
            pid = oaiid_minter(record_id, data)
            record = Record.create(data, id_=record_id)

        db.session.commit()

        indexer.index_by_id(record_id)
        current_search.flush_and_refresh('_all')

        pid_value = pid.pid_value

        # get the list of identifiers
        with app.test_client() as c:
            result = c.get('/oai2d?verb=ListIdentifiers&metadataPrefix=oai_dc')

        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH', namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListIdentifiers',
                       namespaces=NAMESPACES)) == 1
        assert len(
            tree.xpath('/x:OAI-PMH/x:ListIdentifiers/x:header',
                       namespaces=NAMESPACES)) == 1
        identifier = tree.xpath(
            '/x:OAI-PMH/x:ListIdentifiers/x:header/x:identifier',
            namespaces=NAMESPACES)
        assert len(identifier) == 1
        assert identifier[0].text == str(pid_value)
        datestamp = tree.xpath(
            '/x:OAI-PMH/x:ListIdentifiers/x:header/x:datestamp',
            namespaces=NAMESPACES)
        assert len(datestamp) == 1
        assert datestamp[0].text == datetime_to_datestamp(record.updated)

        # Check from:until range
        with app.test_client() as c:
            # Check date and datetime timestamps.
            for granularity in (False, True):
                result = c.get(
                    '/oai2d?verb=ListIdentifiers&metadataPrefix=oai_dc'
                    '&from={0}&until={1}&set=test0'.format(
                        datetime_to_datestamp(record.updated - timedelta(1),
                                              day_granularity=granularity),
                        datetime_to_datestamp(record.updated + timedelta(1),
                                              day_granularity=granularity),
                    ))
                assert result.status_code == 200

                tree = etree.fromstring(result.data)
                identifier = tree.xpath(
                    '/x:OAI-PMH/x:ListIdentifiers/x:header/x:identifier',
                    namespaces=NAMESPACES)
                assert len(identifier) == 1
示例#9
0
def without_oaiset_signals(app):
    """Temporary disable oaiset signals."""
    from invenio_oaiserver import current_oaiserver
    current_oaiserver.unregister_signals_oaiset()
    yield
    current_oaiserver.register_signals_oaiset()
示例#10
0
def test_populate_oaisets(app, without_oaiset_signals, schema):
    """Populate OAISets."""
    def create_oaiset(**kwargs):
        oaiset = OAISet(**kwargs)
        db.session.add(oaiset)
        db.session.commit()
        return oaiset

    a = create_oaiset(spec='a')
    create_oaiset(spec='b')
    create_oaiset(
        spec="e", search_pattern="title_statement.title:Test2 OR "
        "title_statement.title:Test3")
    create_oaiset(spec="c", search_pattern="title_statement.title:Test0")
    create_oaiset(spec="d", search_pattern="title_statement.title:Test1")
    f = create_oaiset(spec="f", search_pattern="title_statement.title:Test2")
    create_oaiset(spec="g")
    create_oaiset(spec="h")
    i = create_oaiset(spec="i", search_pattern="title_statement.title:Test3")
    j = create_oaiset(spec="j with space",
                      search_pattern="title_statement.title:Test4")
    # Note below: brackets around AND search query are required
    create_oaiset(spec="math",
                  search_pattern="(title_statement.title:foo AND genre:math)")
    create_oaiset(spec="nonmath",
                  search_pattern="(title_statement.title:foo AND -genre:math)")

    run_after_insert_oai_set()

    a_id = OAISet.query.filter_by(spec=a.spec).one().id
    i_id = OAISet.query.filter_by(spec=i.spec).one().id

    # start tests

    record0 = create_record(app, {
        '_oai': {'sets': ['a']}, 'title_statement': {'title': 'Test0'},
        '$schema': schema
    })

    assert 'a' in record0['_oai']['sets'], 'Keep manually managed set "a".'
    assert 'c' in record0['_oai']['sets']
    assert len(record0['_oai']['sets']) == 2

    record_not_found = create_record(
        app, {'title': 'TestNotFound', '$schema': schema}
    )

    # Don't create empty sets list just because of commit
    assert 'sets' not in record_not_found['_oai']

    record1 = create_record(app, {'title_statement': {'title': 'Test1'},
                            '$schema': schema})

    assert 'd' in record1['_oai']['sets']
    assert len(record1['_oai']['sets']) == 1

    record2 = create_record(app, {'title_statement': {'title': 'Test2'},
                            '$schema': schema})
    record2_id = record2.id

    assert 'e' in record2['_oai']['sets']
    assert 'f' in record2['_oai']['sets']
    assert len(record2['_oai']['sets']) == 2

    record3 = create_record(app, {'title_statement': {'title': 'Test3'},
                            '$schema': schema})
    record3_id = record3.id

    assert 'e' in record3['_oai']['sets']
    assert 'i' in record3['_oai']['sets']
    assert len(record3['_oai']['sets']) == 2

    record4 = create_record(app, {'title_statement': {'title': 'Test4'},
                            '$schema': schema})
    record4_id = record4.id

    assert 'j with space' in record4['_oai']['sets']
    assert len(record4['_oai']['sets']) == 1

    # If record does not have '_oai', don't add any sets,
    # nor even the default '_oai' key
    record5 = create_record(app, {'title_statement': {'title': 'Test1'},
                            '$schema': schema},
                            mint_oaiid=False)
    assert '_oai' not in record5

    # Test 'AND' keyword for records
    record6 = create_record(app, {
        'title_statement': {'title': 'foo'},
        'genre': 'math', '$schema': schema
    })
    assert record6['_oai']['sets'] == ['math', ]

    record7 = create_record(app, {
        'title_statement': {'title': 'foo'},
        'genre': 'physics', '$schema': schema
    })
    assert record7['_oai']['sets'] == ['nonmath', ]

    record8 = create_record(app, {
        'title_statement': {'title': 'bar'},
        'genre': 'math', '$schema': schema
    })
    assert 'sets' not in record8['_oai']  # title is not 'foo'

    # wait ElasticSearch end to index records
    sleep(5)

    # test delete
    current_oaiserver.unregister_signals_oaiset()
    with patch('invenio_oaiserver.receivers.after_delete_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            db.session.delete(j)
        db.session.commit()
        assert f.called
        after_delete_oai_set(None, None, j)
        record4_model = RecordMetadata.query.filter_by(
            id=record4_id).first().json

        assert 'j with space' not in record4_model['_oai']['sets']
        assert len(record4_model['_oai']['sets']) == 0

        current_oaiserver.unregister_signals_oaiset()

    # test update search_pattern
    with patch('invenio_oaiserver.receivers.after_update_oai_set') as f:
        current_oaiserver.register_signals_oaiset()
        with db.session.begin_nested():
            i.search_pattern = None
            assert current_oaiserver.sets is None, 'Cache should be empty.'
            db.session.merge(i)
        db.session.commit()
        assert f.called
        i = OAISet.query.get(i_id)
        after_update_oai_set(None, None, i)
        record3_model = RecordMetadata.query.filter_by(
            id=record3_id).first().json

        assert 'i' in record3_model['_oai']['sets'], \
            'Set "i" is manually managed.'
        assert 'e' in record3_model['_oai']['sets']
        assert len(record3_model['_oai']['sets']) == 2

        current_oaiserver.unregister_signals_oaiset()

    # test update search_pattern
    with patch('invenio_oaiserver.receivers.after_update_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            i.search_pattern = 'title_statement.title:Test3'
            db.session.merge(i)
        db.session.commit()
        assert f.called
        i = OAISet.query.get(i_id)
        after_update_oai_set(None, None, i)
        record3_model = RecordMetadata.query.filter_by(
            id=record3_id).first().json

        assert 'e' in record3_model['_oai']['sets']
        assert 'i' in record3_model['_oai']['sets']
        assert len(record3_model['_oai']['sets']) == 2

        current_oaiserver.unregister_signals_oaiset()

    # test update the spec
    with pytest.raises(OAISetSpecUpdateError) as exc_info:
        a = OAISet.query.get(a_id)
        a.spec = 'new-a'
    assert exc_info.type is OAISetSpecUpdateError

    # test create new set
    with patch('invenio_oaiserver.receivers.after_insert_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            k = OAISet(spec="k", search_pattern="title_statement.title:Test2")
            db.session.add(k)
        db.session.commit()
        assert f.called
        after_insert_oai_set(None, None, k)
        record2_model = RecordMetadata.query.filter_by(
            id=record2_id).first().json

        assert 'e' in record2_model['_oai']['sets']
        assert 'f' in record2_model['_oai']['sets']
        assert 'k' in record2_model['_oai']['sets']
        assert len(record2_model['_oai']['sets']) == 3

        current_oaiserver.register_signals_oaiset()
def test_populate_oaisets(app, with_record_signals):
    """Populate OAISets."""
    indexer = RecordIndexer()
    schema = {
        'allOf': [{
            'type': 'object',
            'properties': {
                'title': {'type': 'string'},
                'genre': {'type': 'string'},
                'field': {'type': 'boolean'},
            },
            'required': ['title'],
        }, {
            '$ref': 'http://inveniosoftware.org/schemas/'
                    'oaiserver/internal-v1.0.0.json',
        }]
    }

    def create_record(item_dict, mint_oaiid=True):
        """Create test record."""
        with app.test_request_context():
            record_id = uuid.uuid4()
            recid_minter(record_id, item_dict)
            if mint_oaiid:
                oaiid_minter(record_id, item_dict)
            record = Record.create(item_dict, id_=record_id)
            indexer.index(record)
            return record

    a = OAISet(spec='a')
    b = OAISet(spec='b')
    e = OAISet(
        spec="e", search_pattern="title:Test2 OR title:Test3")
    c = OAISet(spec="c", search_pattern="title:Test0")
    d = OAISet(spec="d", search_pattern="title:Test1")
    f = OAISet(spec="f", search_pattern="title:Test2")
    g = OAISet(spec="g")
    h = OAISet(spec="h")
    i = OAISet(spec="i", search_pattern="title:Test3")
    j = OAISet(spec="j with space", search_pattern="title:Test4")
    # Note below: brackets around AND search query are required
    l = OAISet(spec="math",
               search_pattern="(title:foo AND genre:math)")
    m = OAISet(spec="nonmath",
               search_pattern="(title:foo AND -genre:math)")

    with db.session.begin_nested():
        for oaiset in [a, b, c, d, e, f, g, h, i, j, l, m]:
            db.session.add(oaiset)

    db.session.commit()

    a_id = a.id
    i_id = i.id

    # start tests

    record0 = create_record({
        '_oai': {'sets': ['a']}, 'title': 'Test0', '$schema': schema
    })

    assert 'a' in record0['_oai']['sets'], 'Keep manually managed set "a".'
    assert 'c' in record0['_oai']['sets']
    assert len(record0['_oai']['sets']) == 2

    record_not_found = create_record(
        {'title': 'TestNotFound', '$schema': schema}
    )

    # Don't create empty sets list just because of commit
    assert 'sets' not in record_not_found['_oai']

    record1 = create_record({'title': 'Test1', '$schema': schema})

    assert 'd' in record1['_oai']['sets']
    assert len(record1['_oai']['sets']) == 1

    record2 = create_record({'title': 'Test2', '$schema': schema})
    record2_id = record2.id

    assert 'e' in record2['_oai']['sets']
    assert 'f' in record2['_oai']['sets']
    assert len(record2['_oai']['sets']) == 2

    record3 = create_record({'title': 'Test3', '$schema': schema})
    record3_id = record3.id

    assert 'e' in record3['_oai']['sets']
    assert 'i' in record3['_oai']['sets']
    assert len(record3['_oai']['sets']) == 2

    record4 = create_record({'title': 'Test4', '$schema': schema})
    record4_id = record4.id

    assert 'j with space' in record4['_oai']['sets']
    assert len(record4['_oai']['sets']) == 1

    # If record does not have '_oai', don't add any sets,
    # nor even the default '_oai' key
    record5 = create_record({'title': 'Test1', '$schema': schema},
                            mint_oaiid=False)
    assert '_oai' not in record5

    # If 'sets' before and after record commit are equivalent
    # don't bump up the '_oai.updated' timestamp...
    record6 = create_record({'title': 'Test1', '$schema': schema})
    assert record6['_oai']['sets'] == ['d']
    prev_updated_r6 = record6['_oai']['updated']
    record6.commit()
    assert record6['_oai']['sets'] == ['d']
    assert record6['_oai']['updated'] == prev_updated_r6  # date stays the same

    # ...but do bump up '_oai.updated' if the sets are different
    record7 = create_record({'title': 'Test1', '$schema': schema})
    assert record7['_oai']['sets'] == ['d']
    prev_updated_r7 = record7['_oai']['updated']
    sleep(1)  # 'updated' timestamp is accurate to a second, hence the wait
    record7['_oai']['sets'] = ['d', 'f']  # 'f' should be removed after commit
    record7.commit()
    assert record7['_oai']['sets'] == ['d']
    assert record7['_oai']['updated'] != prev_updated_r7  # date bumped

    # Test 'AND' keyword for records
    record8 = create_record(
        {'title': 'foo', 'genre': 'math', '$schema': schema})
    assert record8['_oai']['sets'] == ['math', ]

    record9 = create_record(
        {'title': 'foo', 'genre': 'physics', '$schema': schema})
    assert record9['_oai']['sets'] == ['nonmath', ]

    record10 = create_record(
        {'title': 'bar', 'genre': 'math', '$schema': schema})
    assert 'sets' not in record10['_oai']  # title is not 'foo'

    # wait ElasticSearch end to index records
    sleep(10)

    # test delete
    current_oaiserver.unregister_signals_oaiset()
    with patch('invenio_oaiserver.receivers.after_delete_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            db.session.delete(j)
        db.session.commit()
        assert f.called
        after_delete_oai_set(None, None, j)
        record4_model = RecordMetadata.query.filter_by(
            id=record4_id).first().json

        assert 'j with space' not in record4_model['_oai']['sets']
        assert len(record4_model['_oai']['sets']) == 0

        current_oaiserver.unregister_signals_oaiset()

    # test update search_pattern
    with patch('invenio_oaiserver.receivers.after_update_oai_set') as f:
        current_oaiserver.register_signals_oaiset()
        with db.session.begin_nested():
            i.search_pattern = None
            assert current_oaiserver.sets is None, 'Cache should be empty.'
            db.session.merge(i)
        db.session.commit()
        assert f.called
        i = OAISet.query.get(i_id)
        after_update_oai_set(None, None, i)
        record3_model = RecordMetadata.query.filter_by(
            id=record3_id).first().json

        assert 'i' in record3['_oai']['sets'], 'Set "i" is manually managed.'
        assert 'e' in record3_model['_oai']['sets']
        assert len(record3_model['_oai']['sets']) == 2

        current_oaiserver.unregister_signals_oaiset()

    # test update search_pattern
    with patch('invenio_oaiserver.receivers.after_update_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            i.search_pattern = 'title:Test3'
            db.session.merge(i)
        db.session.commit()
        assert f.called
        i = OAISet.query.get(i_id)
        after_update_oai_set(None, None, i)
        record3_model = RecordMetadata.query.filter_by(
            id=record3_id).first().json

        assert 'e' in record3_model['_oai']['sets']
        assert 'i' in record3_model['_oai']['sets']
        assert len(record3_model['_oai']['sets']) == 2

        current_oaiserver.unregister_signals_oaiset()

    # test update the spec
    with pytest.raises(OAISetSpecUpdateError) as exc_info:
        a = OAISet.query.get(a_id)
        a.spec = 'new-a'
    assert exc_info.type is OAISetSpecUpdateError

    # test create new set
    with patch('invenio_oaiserver.receivers.after_insert_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            k = OAISet(spec="k", search_pattern="title:Test2")
            db.session.add(k)
        db.session.commit()
        assert f.called
        after_insert_oai_set(None, None, k)
        record2_model = RecordMetadata.query.filter_by(
            id=record2_id).first().json

        assert 'e' in record2_model['_oai']['sets']
        assert 'f' in record2_model['_oai']['sets']
        assert 'k' in record2_model['_oai']['sets']
        assert len(record2_model['_oai']['sets']) == 3

        current_oaiserver.register_signals_oaiset()
示例#12
0
def test_listidentifiers(app):
    """Test verb ListIdentifiers."""
    from invenio_oaiserver.models import OAISet

    with app.app_context():
        current_oaiserver.unregister_signals_oaiset()
        # create new OAI Set
        with db.session.begin_nested():
            oaiset = OAISet(
                spec='test0',
                name='Test0',
                description='test desc 0',
                search_pattern='title_statement.title:Test0',
            )
            db.session.add(oaiset)
        db.session.commit()

    run_after_insert_oai_set()

    with app.test_request_context():
        indexer = RecordIndexer()

        # create a new record (inside the OAI Set)
        with db.session.begin_nested():
            record_id = uuid.uuid4()
            data = {'title_statement': {'title': 'Test0'}}
            recid_minter(record_id, data)
            pid = oaiid_minter(record_id, data)
            record = Record.create(data, id_=record_id)

        db.session.commit()

        indexer.index_by_id(record_id)
        current_search.flush_and_refresh('_all')

        pid_value = pid.pid_value

        # get the list of identifiers
        with app.test_client() as c:
            result = c.get(
                '/oai2d?verb=ListIdentifiers&metadataPrefix=oai_dc'
            )

        tree = etree.fromstring(result.data)

        assert len(tree.xpath('/x:OAI-PMH', namespaces=NAMESPACES)) == 1
        assert len(tree.xpath('/x:OAI-PMH/x:ListIdentifiers',
                              namespaces=NAMESPACES)) == 1
        assert len(tree.xpath('/x:OAI-PMH/x:ListIdentifiers/x:header',
                              namespaces=NAMESPACES)) == 1
        identifier = tree.xpath(
            '/x:OAI-PMH/x:ListIdentifiers/x:header/x:identifier',
            namespaces=NAMESPACES
        )
        assert len(identifier) == 1
        assert identifier[0].text == str(pid_value)
        datestamp = tree.xpath(
            '/x:OAI-PMH/x:ListIdentifiers/x:header/x:datestamp',
            namespaces=NAMESPACES
        )
        assert len(datestamp) == 1
        assert datestamp[0].text == datetime_to_datestamp(record.updated)

        # Check from:until range
        with app.test_client() as c:
            # Check date and datetime timestamps.
            for granularity in (False, True):
                result = c.get(
                    '/oai2d?verb=ListIdentifiers&metadataPrefix=oai_dc'
                    '&from={0}&until={1}&set=test0'.format(
                        datetime_to_datestamp(
                            record.updated - timedelta(1),
                            day_granularity=granularity),
                        datetime_to_datestamp(
                            record.updated + timedelta(1),
                            day_granularity=granularity),
                    )
                )
                assert result.status_code == 200

                tree = etree.fromstring(result.data)
                identifier = tree.xpath(
                    '/x:OAI-PMH/x:ListIdentifiers/x:header/x:identifier',
                    namespaces=NAMESPACES
                )
                assert len(identifier) == 1
def _try_populate_oaisets():
    """Try to update collections."""
    indexer = RecordIndexer()
    schema = {
        'type': 'object',
        'properties': {
                'title': {'type': 'string'},
                'field': {'type': 'boolean'},
            },
        'required': ['title'],
    }

    def create_record(item_dict):
        """Create test record."""
        record_id = uuid.uuid4()
        recid_minter(record_id, item_dict)
        oaiid_minter(record_id, item_dict)
        record = Record.create(item_dict, id_=record_id)
        indexer.index(record)
        return record

    a = OAISet(spec='a')
    b = OAISet(spec='b')
    e = OAISet(
        spec="e", search_pattern="title:Test2 OR title:Test3")
    c = OAISet(spec="c", search_pattern="title:Test0")
    d = OAISet(spec="d", search_pattern="title:Test1")
    f = OAISet(spec="f", search_pattern="title:Test2")
    g = OAISet(spec="g")
    h = OAISet(spec="h")
    i = OAISet(spec="i", search_pattern="title:Test3")
    j = OAISet(spec="j with space", search_pattern="title:Test4")

    with db.session.begin_nested():
        for oaiset in [a, b, c, d, e, f, g, h, i, j]:
            db.session.add(oaiset)

    db.session.commit()

    a_id = a.id
    i_id = i.id

    # start tests

    record0 = create_record({
        '_oai': {'sets': ['a']}, 'title': 'Test0', '$schema': schema
    })

    assert 'a' in record0['_oai']['sets'], 'Keep manually managed set "a".'
    assert 'c' in record0['_oai']['sets']
    assert len(record0['_oai']['sets']) == 2

    record_not_found = create_record(
        {'title': 'TestNotFound', '$schema': schema}
    )

    assert record_not_found['_oai']['sets'] == []

    record1 = create_record({'title': 'Test1', '$schema': schema})

    assert 'd' in record1['_oai']['sets']
    assert len(record1['_oai']['sets']) == 1

    record2 = create_record({'title': 'Test2', '$schema': schema})
    record2_id = record2.id

    assert 'e' in record2['_oai']['sets']
    assert 'f' in record2['_oai']['sets']
    assert len(record2['_oai']['sets']) == 2

    record3 = create_record({'title': 'Test3', '$schema': schema})
    record3_id = record3.id

    assert 'e' in record3['_oai']['sets']
    assert 'i' in record3['_oai']['sets']
    assert len(record3['_oai']['sets']) == 2

    record4 = create_record({'title': 'Test4', '$schema': schema})
    record4_id = record4.id

    assert 'j with space' in record4['_oai']['sets']
    assert len(record4['_oai']['sets']) == 1

    # wait ElasticSearch end to index records
    sleep(10)

    # test delete
    current_oaiserver.unregister_signals_oaiset()
    with patch('invenio_oaiserver.receivers.after_delete_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            db.session.delete(j)
        db.session.commit()
        assert f.called
        after_delete_oai_set(None, None, j)
        record4_model = RecordMetadata.query.filter_by(
            id=record4_id).first().json

        assert 'j with space' not in record4_model['_oai']['sets']
        assert len(record4_model['_oai']['sets']) == 0

        current_oaiserver.unregister_signals_oaiset()

    # test update search_pattern
    with patch('invenio_oaiserver.receivers.after_update_oai_set') as f:
        current_oaiserver.register_signals_oaiset()
        with db.session.begin_nested():
            i.search_pattern = None
            assert current_oaiserver.sets is None, 'Cache should be empty.'
            db.session.merge(i)
        db.session.commit()
        assert f.called
        i = OAISet.query.get(i_id)
        after_update_oai_set(None, None, i)
        record3_model = RecordMetadata.query.filter_by(
            id=record3_id).first().json

        assert 'i' in record3['_oai']['sets'], 'Set "i" is manually managed.'
        assert 'e' in record3_model['_oai']['sets']
        assert len(record3_model['_oai']['sets']) == 2

        current_oaiserver.unregister_signals_oaiset()

    # test update search_pattern
    with patch('invenio_oaiserver.receivers.after_update_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            i.search_pattern = 'title:Test3'
            db.session.merge(i)
        db.session.commit()
        assert f.called
        i = OAISet.query.get(i_id)
        after_update_oai_set(None, None, i)
        record3_model = RecordMetadata.query.filter_by(
            id=record3_id).first().json

        assert 'e' in record3_model['_oai']['sets']
        assert 'i' in record3_model['_oai']['sets']
        assert len(record3_model['_oai']['sets']) == 2

        current_oaiserver.unregister_signals_oaiset()

    # test update the spec
    with pytest.raises(OAISetSpecUpdateError) as exc_info:
        a = OAISet.query.get(a_id)
        a.spec = 'new-a'
    assert exc_info.type is OAISetSpecUpdateError

    # test create new set
    with patch('invenio_oaiserver.receivers.after_insert_oai_set') as f:
        current_oaiserver.register_signals_oaiset()

        with db.session.begin_nested():
            k = OAISet(spec="k", search_pattern="title:Test2")
            db.session.add(k)
        db.session.commit()
        assert f.called
        after_insert_oai_set(None, None, k)
        record2_model = RecordMetadata.query.filter_by(
            id=record2_id).first().json

        assert 'e' in record2_model['_oai']['sets']
        assert 'f' in record2_model['_oai']['sets']
        assert 'k' in record2_model['_oai']['sets']
        assert len(record2_model['_oai']['sets']) == 3

        current_oaiserver.register_signals_oaiset()