Skip to content

Commit

Permalink
Metadata Model fixes for performance (#1141)
Browse files Browse the repository at this point in the history
* Fixed metadata performance issues

* Fixed the test data

* Added more tests

* Fixed rubocop

---------

Co-authored-by: kudakwashe siziva <[email protected]>
  • Loading branch information
ashwinisukale and kaysiz authored Apr 3, 2024
1 parent 99ddcde commit 4e80c87
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 13 deletions.
2 changes: 1 addition & 1 deletion app/controllers/metadata_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class MetadataController < ApplicationController
before_action :authenticate_user!

def index
@doi = DataciteDoi.where(doi: params[:doi_id]).first
@doi = DataciteDoi.includes(:metadata).find_by(doi: params[:doi_id])
fail ActiveRecord::RecordNotFound if @doi.blank?

collection = @doi.metadata
Expand Down
24 changes: 12 additions & 12 deletions app/models/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ def doi_id
end

def doi_id=(value)
r = Doi.where(doi: value).first
fail ActiveRecord::RecordNotFound if r.blank?
r = Doi.find_by(doi: value)
raise ActiveRecord::RecordNotFound if r.blank?

write_attribute(:dataset, r.id)
self.dataset = r.id
end

def client_id
Expand All @@ -41,21 +41,21 @@ def client_id
def client_id=(value); end

def metadata_must_be_valid
return nil if doi&.draft?
return nil if xml.blank?
return if doi&.draft? || xml.blank?

doc = Nokogiri.XML(xml, nil, "UTF-8", &:noblanks)
return nil if doc.blank?
return if doc.blank?

errors.add(:xml, "XML has no namespace.") && return if namespace.blank?
if namespace.blank?
errors.add(:xml, "XML has no namespace.")
return
end

# load XSD from bolognese gem
kernel = namespace.to_s.split("/").last
filepath =
Bundler.rubygems.find_name("bolognese").first.full_gem_path +
"/resources/#{kernel}/metadata.xsd"
schema = Nokogiri::XML.Schema(open(filepath))
err = schema.validate(doc).map(&:to_s).unwrap
filepath = File.join(Gem.loaded_specs["bolognese"].full_gem_path, "resources", kernel, "metadata.xsd")
schema = Nokogiri::XML::Schema(File.open(filepath))
err = schema.validate(doc).map(&:to_s).join(", ")
errors.add(:xml, err) if err.present?
end

Expand Down
81 changes: 81 additions & 0 deletions spec/models/metadata_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,92 @@
require "rails_helper"

describe Metadata, type: :model, vcr: true do
let(:provider) { create(:provider, symbol: "ADMIN") }
let(:client) { create(:client, provider: provider) }
let(:doi) { create(:doi, client: client, aasm_state: "findable") }
let(:xml) { file_fixture("datacite.xml").read }

context "validations" do
it { should validate_presence_of(:xml) }
it { should validate_presence_of(:namespace) }
end

describe "associations" do
it { should belong_to(:doi).with_foreign_key(:dataset).inverse_of(:metadata) }
end

describe "#doi_id" do
let(:metadata) { build(:metadata, doi: doi, xml: xml) }

it "returns the DOI ID associated with the metadata" do
expect(metadata.doi_id).to eq(doi.doi)
end
end

describe "before_validation callbacks" do
let(:metadata) { build(:metadata, doi: doi, xml: xml) }

it "sets the namespace before validation" do
metadata.valid?
expect(metadata.namespace).not_to be_nil
end

it "sets the metadata version before validation" do
metadata.valid?
expect(metadata.metadata_version).to eq(1)
end
end

describe "#uid" do
let(:metadata) { Metadata.create(xml: xml, doi: doi) }

it "generates a uid for the metadata" do
expect(metadata.uid).not_to be_nil
end
end

describe "#client_id" do
let(:metadata) { build(:metadata, doi: doi, xml: xml) }

it "returns the client ID" do
expect(metadata.client_id).to eq(client.symbol.downcase)
end
end

describe "#metadata_must_be_valid" do
context "with invalid XML" do
let(:xml) { "invalid xml" }
let(:metadata) { build(:metadata, doi: doi) }
it "adds errors if XML is invalid" do
metadata.valid?
expect(metadata.errors[:xml]).not_to be_empty
end
end

context "with valid XML" do
let(:xml) { file_fixture("datacite.xml").read }
let(:metadata) { build(:metadata, doi: doi, xml: xml) }

it "does not add errors if XML is valid" do
metadata.valid?
expect(metadata.errors[:xml]).to be_empty
end
end
end

describe "#doi_id=" do
let(:metadata) { build(:metadata) }

it "sets the dataset attribute with the DOI id" do
metadata.doi_id = doi.doi
expect(metadata.dataset).to eq(doi.id)
end

it "raises ActiveRecord::RecordNotFound if DOI is not found" do
expect { metadata.doi_id = "invalid_doi" }.to raise_error(ActiveRecord::RecordNotFound)
end
end

context "parses xml" do
let(:provider) { create(:provider, symbol: "ADMIN") }
let(:client) { create(:client, provider: provider) }
Expand Down

0 comments on commit 4e80c87

Please sign in to comment.