Exemplo n.º 1
0
def test_datacite_reserve_register_update_delete(app, db):
    """Test datacite provider reserve."""
    with app.app_context():
        api = MagicMock()
        provider = DataCiteProvider.create('10.1234/a', client=api)
        assert provider.reserve('mydoc')
        assert provider.pid.status == PIDStatus.RESERVED
        api.metadata_post.assert_called_with('mydoc')

        assert provider.register('myurl', 'anotherdoc')
        assert provider.pid.status == PIDStatus.REGISTERED
        api.metadata_post.assert_called_with('anotherdoc')
        api.doi_post.assert_called_with('10.1234/a', 'myurl')

        assert provider.update('anotherurl', 'yetanother')
        assert provider.pid.status == PIDStatus.REGISTERED
        api.metadata_post.assert_called_with('yetanother')
        api.doi_post.assert_called_with('10.1234/a', 'anotherurl')

        assert provider.delete()
        assert provider.pid.status == PIDStatus.DELETED
        api.metadata_delete.assert_called_with('10.1234/a')

        assert provider.update('newurl', 'newdoc')
        assert provider.pid.status == PIDStatus.REGISTERED
        api.metadata_post.assert_called_with('newdoc')
        api.doi_post.assert_called_with('10.1234/a', 'newurl')
Exemplo n.º 2
0
def test_datacite_error_delete(logger, app, db):
    """Test reserve errors."""
    with app.app_context():
        api = MagicMock()
        provider = DataCiteProvider.create('10.1234/a', client=api)

        # DOIs in new state doesn't contact datacite
        api.metadata_delete.side_effect = DataCiteError
        assert provider.delete()

        # Already registered DOIs do contact datacite to delete
        provider = DataCiteProvider.create('10.1234/b', client=api,
                                           status=PIDStatus.REGISTERED)

        api.metadata_delete.side_effect = DataCiteError
        pytest.raises(DataCiteError, provider.delete)
        assert logger.exception.call_args[0][0] == \
            "Failed to delete in DataCite"
Exemplo n.º 3
0
def test_datacite_create_get(app, db):
    """Test datacite provider create/get."""
    with app.app_context():
        provider = DataCiteProvider.create('10.1234/a')
        assert provider.pid.status == PIDStatus.NEW
        assert provider.pid.pid_provider == 'datacite'

        # Crete passing client kwarg to provider object creation
        provider = DataCiteProvider.create('10.1234/b', client=MagicMock())
        assert provider.pid.status == PIDStatus.NEW
        assert provider.pid.pid_provider == 'datacite'
        assert isinstance(provider.api, MagicMock)

        provider = DataCiteProvider.get('10.1234/a')
        assert provider.pid.status == PIDStatus.NEW
        assert provider.pid.pid_provider == 'datacite'

        provider = DataCiteProvider.get('10.1234/a', client=MagicMock())
        assert isinstance(provider.api, MagicMock)
Exemplo n.º 4
0
def test_datacite_error_reserve(logger, app, db):
    """Test reserve errors."""
    with app.app_context():
        api = MagicMock()
        provider = DataCiteProvider.create('10.1234/a', client=api)

        api.metadata_post.side_effect = DataCiteError
        pytest.raises(DataCiteError, provider.reserve, "testdoc")
        assert logger.exception.call_args[0][0] == \
            "Failed to reserve in DataCite"
Exemplo n.º 5
0
def create_doi(doi):
    """
    :param doi: Creates a DOI using the data provider. If it already exists, we return back the existing provider.
    :return: DataCiteProvider
    """
    try:
        return DataCiteProvider.create(doi)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except Exception:
        return DataCiteProvider.get(doi, 'doi')
Exemplo n.º 6
0
def create_doi(doi):
    """
    :param doi: Creates a DOI using the data provider. If it already exists, we return back the existing provider.
    :return: DataCiteProvider
    """
    try:
        return DataCiteProvider.create(doi)
    except DataCiteUnauthorizedError:
        log.error('Unable to mint DOI. No authorisation credentials provided.')
    except Exception:
        return DataCiteProvider.get(doi, 'doi')
Exemplo n.º 7
0
def test_datacite_error_register_update(logger, app):
    """Test register errors."""
    with app.app_context():
        api = MagicMock()
        provider = DataCiteProvider.create('10.1234/a', client=api)

        api.doi_post.side_effect = DataCiteError
        pytest.raises(DataCiteError, provider.register, "testurl", "testdoc")
        assert logger.exception.call_args[0][0] == \
            "Failed to register in DataCite"

        pytest.raises(DataCiteError, provider.update, "testurl", "testdoc")
        assert logger.exception.call_args[0][0] == \
            "Failed to update in DataCite"
Exemplo n.º 8
0
def test_datacite_sync(logger, app, db):
    """Test sync."""
    with app.app_context():
        api = MagicMock()

        provider = DataCiteProvider.create('10.1234/a', client=api)
        assert provider.pid.status == PIDStatus.NEW

        # Status can be set from api.doi_get reply
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.REGISTERED
        api.doi_get.assert_called_with(provider.pid.pid_value)

        api.doi_get.side_effect = DataCiteGoneError
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.DELETED

        api.doi_get.side_effect = DataCiteNoContentError
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.REGISTERED

        # Status *cannot/ be set from api.doi_get reply
        # Try with api.metadata_get
        api.doi_get.side_effect = DataCiteNotFoundError
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.RESERVED
        api.metadata_get.assert_called_with(provider.pid.pid_value)

        api.doi_get.side_effect = DataCiteNotFoundError
        api.metadata_get.side_effect = DataCiteGoneError
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.DELETED

        api.doi_get.side_effect = DataCiteNotFoundError
        api.metadata_get.side_effect = DataCiteNoContentError
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.REGISTERED

        api.doi_get.side_effect = DataCiteNotFoundError
        api.metadata_get.side_effect = DataCiteNotFoundError
        assert provider.sync_status()
        assert provider.pid.status == PIDStatus.NEW

        api.doi_get.side_effect = HttpError
        assert provider.pid.status == PIDStatus.NEW
        pytest.raises(HttpError, provider.sync_status)
        assert provider.pid.status == PIDStatus.NEW
        assert logger.exception.call_args[0][0] == \
            "Failed to sync status from DataCite"
Exemplo n.º 9
0
def b2share_doi_minter(rec_pid, data, fake_it=False):
    from invenio_pidstore.models import PIDStatus, PersistentIdentifier
    from invenio_pidstore.providers.datacite import DataCiteProvider
    from .serializers import datacite_v31

    def select_doi(metadata, status):
        doi_list = [DataCiteProvider.get(d.get('value'))
                    for d in metadata['_pid']
                    if d.get('type') == 'DOI']
        return [d for d in doi_list
                if d and d.pid and d.pid.status == status]

    if select_doi(data, PIDStatus.REGISTERED):
        return # DOI already allocated

    url = make_record_url(rec_pid.pid_value)

    reserved_doi = select_doi(data, PIDStatus.RESERVED)
    if reserved_doi:
        doi = reserved_doi[0]
    else:
        doi_id = generate_doi(rec_pid.pid_value)
        doi = DataCiteProvider.create(doi_id,
                                      object_type='rec',
                                      object_uuid=rec_pid.object_uuid,
                                      status=PIDStatus.RESERVED)
        data['_pid'].append({'value': doi_id, 'type': 'DOI'})

    throw_on_failure = current_app.config.get('CFG_FAIL_ON_MISSING_DOI', True)
    try:
        doc = datacite_v31.serialize(doi.pid, data)
        if fake_it: # don't actually register DOI, just pretend to do so
            doi.pid.register()
        else:
            doi.register(url=url, doc=doc)
    except DataCiteError as e:
        if throw_on_failure:
            raise e
        else:
            current_app.logger.warning(e)
Exemplo n.º 10
0
def b2share_doi_minter(record_uuid, data):
    from invenio_pidstore.models import PIDStatus, PersistentIdentifier
    from invenio_pidstore.providers.datacite import DataCiteProvider
    from .serializers import datacite_v31

    def filter_out_reserved_dois(data):
        ret = [d for d in data['_pid'] if d.get('type') != 'DOI_RESERVED']
        data['_pid'] = ret

    doi_list = [d for d in data['_pid'] if d.get('type') == 'DOI']
    if len(doi_list) > 0:
        return

    doi = generate_doi(record_uuid)
    url = make_record_url(record_uuid)

    filter_out_reserved_dois(data)
    data['_pid'].append({
        'value': doi,
        'type': 'DOI_RESERVED',
    })

    throw_on_failure = current_app.config.get('CFG_FAIL_ON_MISSING_DOI', True)
    try:
        dcp = DataCiteProvider.create(doi,
                                      object_type='rec',
                                      object_uuid=record_uuid,
                                      status=PIDStatus.RESERVED)
        doc = datacite_v31.serialize(dcp.pid, data)
        dcp.register(url=url, doc=doc)
        filter_out_reserved_dois(data)
        data['_pid'].append({
            'value': doi,
            'type': 'DOI',
        })
    except DataCiteError as e:
        if throw_on_failure:
            raise e
        else:
            current_app.logger.warning(e)
Exemplo n.º 11
0
def b2share_doi_minter(rec_pid, data, fake_it=False):
    from invenio_pidstore.models import PIDStatus, PersistentIdentifier
    from invenio_pidstore.providers.datacite import DataCiteProvider
    from .serializers import datacite_v31

    def select_doi(metadata, status):
        doi_list = [DataCiteProvider.get(d.get('value'))
                    for d in metadata['_pid']
                    if d.get('type') == 'DOI']
        return [d for d in doi_list
                if d and d.pid and d.pid.status == status]

    if select_doi(data, PIDStatus.REGISTERED):
        return # DOI already allocated

    url = make_record_url(rec_pid.pid_value)

    reserved_doi = select_doi(data, PIDStatus.RESERVED)
    if reserved_doi:
        doi = reserved_doi[0]
    else:
        doi_id = generate_doi(rec_pid.pid_value)
        doi = DataCiteProvider.create(doi_id,
                                      object_type='rec',
                                      object_uuid=rec_pid.object_uuid,
                                      status=PIDStatus.RESERVED)
        data['_pid'].append({'value': doi_id, 'type': 'DOI'})

    throw_on_failure = current_app.config.get('CFG_FAIL_ON_MISSING_DOI', True)
    try:
        doc = datacite_v31.serialize(doi.pid, data)
        if fake_it: # don't actually register DOI, just pretend to do so
            doi.pid.register()
        else:
            doi.register(url=url, doc=doc)
    except DataCiteError as e:
        if throw_on_failure:
            raise e
        else:
            current_app.logger.warning(e)