diff --git a/app/controllers/dois_controller.rb b/app/controllers/dois_controller.rb index c28b41134..05549c63a 100644 --- a/app/controllers/dois_controller.rb +++ b/app/controllers/dois_controller.rb @@ -217,7 +217,11 @@ def show def validate logger = Logger.new(STDOUT) # logger.info safe_params.inspect - @doi = Doi.new(safe_params.merge(only_validate: true)) + + doi = Doi.where(doi: params.dig(:data,:attributes,:doi)).first + exists = doi.present? + + @doi = Doi.new(safe_params.merge(only_validate: true, exists: exists)) authorize! :validate, @doi diff --git a/app/models/doi.rb b/app/models/doi.rb index 00bde26bd..3d63a5e36 100644 --- a/app/models/doi.rb +++ b/app/models/doi.rb @@ -64,6 +64,7 @@ class Doi < ActiveRecord::Base attribute :regenerate, :boolean, default: false attribute :only_validate, :boolean, default: false + attribute :exists, :boolean, default: false attribute :should_validate, :boolean, default: false attribute :agency, :string, default: "DataCite" @@ -77,7 +78,7 @@ class Doi < ActiveRecord::Base # validates_presence_of :url, if: :is_registered_or_findable? # from https://www.crossref.org/blog/dois-and-matching-regular-expressions/ but using uppercase - validates_format_of :doi, :with => /\A10\.\d{4,5}\/[-\._;()\/:a-zA-Z0-9\*~\$\=]+\z/, :on => :create + validates_format_of :doi, :with => /\A10\.\d{4,5}\/[-\._;()\/:a-zA-Z0-9\*~\$\=]+\z/, :on => :create, unless: :exists validates_format_of :url, :with => /\A(ftp|http|https):\/\/[\S]+/ , if: :url?, message: "URL is not valid" validates_uniqueness_of :doi, message: "This DOI has already been taken", unless: :only_validate validates :last_landing_page_status, numericality: { only_integer: true }, if: :last_landing_page_status? diff --git a/spec/requests/dois_spec.rb b/spec/requests/dois_spec.rb index a1f27eafd..db23555f2 100644 --- a/spec/requests/dois_spec.rb +++ b/spec/requests/dois_spec.rb @@ -1435,6 +1435,36 @@ end end + context 'when doi has unpermitted characters' do + let(:xml) { Base64.strict_encode64(file_fixture('datacite.xml').read) } + let(:valid_attributes) do + { + "data" => { + "type" => "dois", + "attributes" => { + "doi" => "10.14454/107+03", + "url" => "http://www.bl.uk/pdf/patspec.pdf", + "xml" => xml, + "source" => "test", + "event" => "publish" + } + } + } + end + + before { post '/dois', params: valid_attributes.to_json, headers: headers } + + it 'returns validation error' do + expect(json.dig('errors')).to eq([{"source"=>"doi", "title"=>"Is invalid"}]) + end + + + it 'returns status code 422' do + expect(response).to have_http_status(422) + end + + end + context 'creators no xml' do let(:creators) { [{ "name"=>"Ollomi, Benjamin" }, { "name"=>"Duran, Patrick" }] } let(:valid_attributes) do @@ -1600,6 +1630,28 @@ end end + context 'validatation fails with unpermitted characters in new DOI' do + let(:xml) { ::Base64.strict_encode64(File.read(file_fixture('datacite.xml'))) } + let(:params) do + { + "data" => { + "type" => "dois", + "attributes" => { + "doi" => "10.14454/107+03", + "xml" => xml, + } + } + } + end + + before { post '/dois/validate', params: params.to_json, headers: headers } + + it 'returns validation error' do + expect(json.dig('errors')).to eq([{"source"=>"doi", "title"=>"Is invalid"}]) + end + + end + context 'validates schema 3' do let(:xml) { ::Base64.strict_encode64(File.read(file_fixture('datacite_schema_3.xml'))) } let(:params) do