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')
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"
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)
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"
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')
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')
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"
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"
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)
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)
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)