diff --git a/app/jobs/doi_failure_job.rb b/app/jobs/doi_failure_job.rb new file mode 100644 index 000000000..5ec6c1fcd --- /dev/null +++ b/app/jobs/doi_failure_job.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class DOIFailureJob < ContentEventJob + def action + 'DOI failed to mint for this work' + end +end diff --git a/app/services/doi_service.rb b/app/services/doi_service.rb index d4aea3775..ef287e7a8 100644 --- a/app/services/doi_service.rb +++ b/app/services/doi_service.rb @@ -6,13 +6,15 @@ class DOIService EZID_RESOURCE_TYPES = { 'Article' => 'Text', 'Audio' => 'Sound', - 'Book' => 'Book', + 'Book' => 'Text', 'Capstone Project' => 'Text', 'Conference Proceeding' => 'Text', + 'Dissertation' => 'Text', 'Dataset' => 'Dataset', 'Image' => 'Image', 'Journal' => 'Text', 'Map or Cartographic Material' => 'Image', + 'Masters Thesis' => 'Text', 'Part of Book' => 'Text', 'Poster' => 'Audiovisual', 'Presentation' => 'Audiovisual', @@ -35,10 +37,15 @@ def run(object) current_doi = doi(object) return current_doi.first if current_doi.present? - response = client.mint_identifier(handle, response_body(object)) - object.identifier += [response.id] - object.save - response.id + begin + response = client.mint_identifier(handle, response_body(object)) + object.identifier += [response.id] + object.save + response.id + rescue Ezid::Error => e + Rails.logger.warn "Got an Ezid::Error: #{e}, No DOI was created!" + DOIFailureJob.perform_later(object, User.find_by(login: object.depositor)) + end end private @@ -51,16 +58,18 @@ def response_body(object) if object.resource_type.empty? base_body(object) else + Rails.logger.warn "Resource type: #{object.resource_type.first} translation: #{EZID_RESOURCE_TYPES[object.resource_type.first]}" base_body(object).merge!('datacite.resourcetype' => EZID_RESOURCE_TYPES[object.resource_type.first]) end end def base_body(object) { + # '_profile' => 'datacite', 'datacite.creator' => formatted_creators(object), 'datacite.title' => object.title.first, 'datacite.publisher' => 'ScholarSphere', - 'datacite.publicationyear' => '2018', + 'datacite.publicationyear' => object.date_uploaded.year.to_s, target: object.url } end diff --git a/spec/services/doi_service_spec.rb b/spec/services/doi_service_spec.rb index e68f82b9f..7bc8792d1 100644 --- a/spec/services/doi_service_spec.rb +++ b/spec/services/doi_service_spec.rb @@ -9,12 +9,14 @@ let(:first_creator) { create(:alias, display_name: 'First Creator', agent: Agent.new(given_name: 'First', sur_name: 'Creator')) } let(:second_creator) { create(:alias, display_name: 'Second Creator', agent: Agent.new(given_name: 'Second', sur_name: 'Creator')) } + let(:upload_date) { Time.now } let(:object) do create(:work, title: ['DOI Title'], creators: [first_creator, second_creator], identifier: identifier, - resource_type: ['Article']) + resource_type: ['Article'], + date_uploaded: upload_date) end context 'existing doi' do @@ -32,7 +34,7 @@ let(:metadata) { { 'datacite.creator' => 'Creator, First; Creator, Second', 'datacite.title' => 'DOI Title', 'datacite.publisher' => 'ScholarSphere', - 'datacite.publicationyear' => '2018', + 'datacite.publicationyear' => upload_date.year.to_s, 'datacite.resourcetype' => 'Text', target: object.url } } @@ -46,10 +48,19 @@ expect(object.reload.identifier).to eq([identifier.first, doi]) expect(minted_id).to eq(doi) end + + context 'the client errors' do + it 'logs an error' do + expect(client).to receive(:mint_identifier).with('testhandle', metadata).and_raise(Ezid::Error, 'bad error') + expect(DOIFailureJob).to receive(:perform_later).with(object, anything) + minted_id = service.run(object) + expect(minted_id).to be_blank + end + end end context 'with a collection' do - let(:object) { create(:collection, title: ['DOI Collection']) } + let(:object) { create(:collection, title: ['DOI Collection'], date_uploaded: upload_date) } let(:doi) { 'doi:10.5072/FK2VT1Q90B' } let(:response_body) { 'success: doi:10.5072/FK2VT1Q90B | ark:/b5072/fk2vt1q90b' } let(:client) { instance_double(Ezid::Client) } @@ -57,7 +68,7 @@ let(:metadata) { { 'datacite.creator' => 'Creator, Creator C.', 'datacite.title' => 'DOI Collection', 'datacite.publisher' => 'ScholarSphere', - 'datacite.publicationyear' => '2018', + 'datacite.publicationyear' => upload_date.year.to_s, target: object.url } } before do @@ -70,4 +81,59 @@ expect(minted_id).to eq(doi) end end + + context 'all the resource types' do + let(:doi) { 'doi:10.5072/FK2VT1Q90B' } + let(:response_body) { 'success: doi:10.5072/FK2VT1Q90B | ark:/b5072/fk2vt1q90b' } + let(:client) { instance_double(Ezid::Client) } + let(:response) { instance_double(Ezid::MintIdentifierResponse, id: doi) } + let(:work) do + create(:work, title: ['DOI Title'], + creators: [first_creator, second_creator], + resource_type: [], date_uploaded: upload_date) + end + + it 'maps the resource type correctly' do + allow(Ezid::Client).to receive(:new).and_return(client) + check_resource_type(work: work, client: client, + resource_types: ['Audio'], datacite_type: 'Sound') + check_resource_type(work: work, client: client, + resource_types: ['Dataset'], datacite_type: 'Dataset') + check_resource_type(work: work, client: client, + resource_types: ['Image', 'Map or Cartographic Material'], + datacite_type: 'Image') + check_resource_type(work: work, client: client, + resource_types: ['Poster', 'Presentation', 'Video'], + datacite_type: 'Audiovisual') + check_resource_type(work: work, client: client, + resource_types: ['Project', 'Other'], + datacite_type: 'Other') + check_resource_type(work: work, client: client, + resource_types: [ + 'Software or Program Code' + ], datacite_type: 'Software') + check_resource_type(work: work, client: client, + resource_types: ['Article', 'Book', 'Capstone Project', + 'Conference Proceeding', 'Dissertation', + 'Journal', 'Masters Thesis', 'Part of Book', + 'Report', 'Research Paper'], + datacite_type: 'Text') + end + end +end + +def check_resource_type(work:, client:, resource_types:, datacite_type:) + resource_types.each do |resource_type| + work.resource_type = [resource_type] + work.identifier = [] + + metadata = { 'datacite.creator' => 'Creator, First; Creator, Second', + 'datacite.title' => 'DOI Title', + 'datacite.publisher' => 'ScholarSphere', + 'datacite.publicationyear' => work.date_uploaded.year.to_s, + 'datacite.resourcetype' => datacite_type, + target: work.url } + expect(client).to receive(:mint_identifier).with('testhandle', metadata).and_return(response) + service.run(work) + end end