Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_datacite_register_fail(mocker, app, db, es, minimal_record):
# Make the datacite API unavailable
dc_mock = mocker.patch(
'invenio_pidstore.providers.datacite.DataCiteMDSClient')
dc_mock().metadata_post.side_effect = datacite.errors.HttpError()
# Create a reserved recid
record = Record.create(minimal_record)
record_uuid = record.id
recid = record['recid']
recid_pid = PersistentIdentifier.create(
'recid', recid, status=PIDStatus.RESERVED)
# Mint the record
zenodo_record_minter(record_uuid, record)
record.commit()
db.session.commit()
with pytest.raises(datacite.errors.HttpError):
datacite_register.apply((recid_pid.pid_value, str(record_uuid)))
'invenio_pidstore.providers.datacite.DataCiteMDSClient')
dc_mock().metadata_post.side_effect = datacite.errors.HttpError()
# Create a reserved recid
record = Record.create(minimal_record)
record_uuid = record.id
recid = record['recid']
recid_pid = PersistentIdentifier.create(
'recid', recid, status=PIDStatus.RESERVED)
# Mint the record
zenodo_record_minter(record_uuid, record)
record.commit()
db.session.commit()
with pytest.raises(datacite.errors.HttpError):
datacite_register.apply((recid_pid.pid_value, str(record_uuid)))
# Check that the task was retried ("max_retries" + 1) times
dc_calls = len(dc_mock().metadata_post.mock_calls)
assert dc_calls == datacite_register.max_retries + 1
Note that retries are done on another thread so only the initial call to
retry can be tested.
"""
patched_client = mocker.patch(
'cd2h_repo_project.modules.doi.tasks.DataCiteMDSClient')()
patched_retry = mocker.patch(
'cd2h_repo_project.modules.doi.tasks.register_doi.retry')
# Because publish() triggers the task, we need to perform some of the steps
# of publish() without calling publish()
record = create_record(published=False)
mint_pids_for_record(record.id, record)
doi_pid = PersistentIdentifier.get(pid_type='doi', pid_value=record['id'])
# Test HttpError
patched_client.metadata_post.side_effect = datacite.errors.HttpError()
register_doi(record['id'])
number_retries = len(patched_retry.mock_calls)
assert number_retries == 1
# Test DataCiteError
patched_client.metadata_post.side_effect = datacite.errors.DataCiteError()
register_doi(record['id'])
number_retries = len(patched_retry.mock_calls)
assert number_retries == 2
def test_datacite_build_metadata(self, registration, datacite_client):
metadata_xml = datacite_client.build_metadata(registration).encode('utf-8')
parser = lxml.etree.XMLParser(ns_clean=True, recover=True, encoding='utf-8')
root = lxml.etree.fromstring(metadata_xml, parser=parser)
xsi_location = '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation'
expected_location = 'http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4/metadata.xsd'
assert root.attrib[xsi_location] == expected_location
identifier = root.find('{%s}identifier' % schema40.ns[None])
assert identifier.attrib['identifierType'] == 'DOI'
assert identifier.text == settings.DOI_FORMAT.format(prefix=settings.DATACITE_PREFIX, guid=registration._id)
creators = root.find('{%s}creators' % schema40.ns[None])
assert len(creators.getchildren()) == len(registration.visible_contributors)
publisher = root.find('{%s}publisher' % schema40.ns[None])
assert publisher.text == 'Open Science Framework'
pub_year = root.find('{%s}publicationYear' % schema40.ns[None])
assert pub_year.text == str(registration.registered_date.year)
resource_type = root.find('{%s}resourceType' % schema40.ns[None])
assert resource_type.text == 'Project'
assert resource_type.attrib['resourceTypeGeneral'] == 'Text'
assert root.attrib[xsi_location] == expected_location
identifier = root.find('{%s}identifier' % schema40.ns[None])
assert identifier.attrib['identifierType'] == 'DOI'
assert identifier.text == settings.DOI_FORMAT.format(prefix=settings.DATACITE_PREFIX, guid=registration._id)
creators = root.find('{%s}creators' % schema40.ns[None])
assert len(creators.getchildren()) == len(registration.visible_contributors)
publisher = root.find('{%s}publisher' % schema40.ns[None])
assert publisher.text == 'Open Science Framework'
pub_year = root.find('{%s}publicationYear' % schema40.ns[None])
assert pub_year.text == str(registration.registered_date.year)
resource_type = root.find('{%s}resourceType' % schema40.ns[None])
assert resource_type.text == 'Project'
assert resource_type.attrib['resourceTypeGeneral'] == 'Text'
# Because publish() triggers the task, we need to perform some of the steps
# of publish() without calling publish()
record = create_record(published=False)
mint_pids_for_record(record.id, record)
doi_pid = PersistentIdentifier.get(pid_type='doi', pid_value=record['id'])
# Test HttpError
patched_client.metadata_post.side_effect = datacite.errors.HttpError()
register_doi(record['id'])
number_retries = len(patched_retry.mock_calls)
assert number_retries == 1
# Test DataCiteError
patched_client.metadata_post.side_effect = datacite.errors.DataCiteError()
register_doi(record['id'])
number_retries = len(patched_retry.mock_calls)
assert number_retries == 2
doi_pid.register()
# Update deposit/record
deposit['doi'] = minted_doi
record['doi'] = minted_doi
deposit.commit()
record.commit()
# The above only flushes (no db commit). The below is needed to
# persist the changes to the db.
db.session.commit()
# Re-index deposit/record
RecordIndexer().index(deposit)
RecordIndexer().index(record)
except (HttpError, DataCiteError) as e:
register_doi.retry(exc=e)
except RequestError:
current_app.logger.exception('Could not index {}.'.format(record))
except Exception as e:
current_app.logger.exception(
'Exception in register_doi for recid_pid_value: {}. Retrying...'
.format(recid_pid_value))
register_doi.retry(exc=e)
`default_retry_delay` is in seconds.
:param recid_pid_value: pid_value of recid-PID for the target record.
Note that this pid_value is also the pid_value of
the doi-PID associated with the target record if
it has not been DOI-minted yet.
"""
try:
recid_pid, record = record_resolver.resolve(str(recid_pid_value))
depid_pid, deposit = Deposit.fetch_deposit(record)
doi_pid_value = record.get('doi') or recid_pid_value
doi_pid = PersistentIdentifier.get(
pid_type='doi', pid_value=doi_pid_value)
client = DataCiteMDSClient(
username=current_app.config['PIDSTORE_DATACITE_USERNAME'],
password=current_app.config['PIDSTORE_DATACITE_PASSWORD'],
prefix=current_app.config['PIDSTORE_DATACITE_DOI_PREFIX'],
test_mode=current_app.config['PIDSTORE_DATACITE_TESTMODE'],
url=current_app.config['PIDSTORE_DATACITE_URL']
)
# Update DataCite metadata and let DataCite mint new DOI if unknown DOI
serialized_record = datacite_v41.serialize(doi_pid, record)
result = client.metadata_post(serialized_record)
minted_doi = extract_doi(result)
if not RecordPermissions.is_private(record):
landing_url = url_for_record_ui_recid_external(recid_pid_value)
client.doi_post(minted_doi, landing_url)
data['descriptions'] = [{
'descriptionType': 'Abstract',
'description': node.description
}]
if node.node_license:
data['rightsList'] = [{
'rights': node.node_license.name,
'rightsURI': node.node_license.url
}]
# Validate dictionary
assert schema40.validate(data)
# Generate DataCite XML from dictionary.
return schema40.tostring(data)
def serialize_xml(cls, record):
data = json.loads(cls.serialize_json(record))
return schema40.tostring(data)