diff --git a/app/jobs/export_search_results_to_csv_job.rb b/app/jobs/export_search_results_to_csv_job.rb
index bc4416ad4..3d8b8d6d6 100644
--- a/app/jobs/export_search_results_to_csv_job.rb
+++ b/app/jobs/export_search_results_to_csv_job.rb
@@ -1,4 +1,4 @@
-class ExportSearchResultsToCsvJob
+class ExportSearchResultsToCsvJob < ActiveJob::Base
include Hyacinth::Csv::Flatten
SUPPRESSED_ON_EXPORT = ['_uuid', '_data_file_path', '_dc_type', '_state', '_title', '_created', '_modified', '_created_by', '_modified_by', '_project.uri', '_project.short_label']
@@ -16,9 +16,9 @@ class ExportSearchResultsToCsvJob
]
CONTROLLED_TERM_CORE_SUBFIELDS_ALLOWED_ON_IMPORT = ['uri', 'value', 'authority', 'type']
- @queue = Hyacinth::Queue::DIGITAL_OBJECT_CSV_EXPORT
+ queue_as Hyacinth::Queue::DIGITAL_OBJECT_CSV_EXPORT
- def self.perform(csv_export_id)
+ def perform(csv_export_id)
start_time = Time.now
csv_export = CsvExport.find(csv_export_id)
@@ -59,7 +59,7 @@ def self.perform(csv_export_id)
csv_export.save
end
- def self.map_temp_field_indexes(search_params, user, map = {})
+ def map_temp_field_indexes(search_params, user, map = {})
# Common fields to all objects
map['_pid'] ||= map.length
map['_project.string_key'] ||= map.length
@@ -111,7 +111,7 @@ def self.map_temp_field_indexes(search_params, user, map = {})
map
end
- def self.write_csv(path_to_csv_file, field_list, field_index_map)
+ def write_csv(path_to_csv_file, field_list, field_index_map)
# Open new CSV for writing
CSV.open(path_to_csv_file, 'wb') do |final_csv|
# Write out human-friendly column display labels
diff --git a/app/jobs/process_digital_object_import_job.rb b/app/jobs/process_digital_object_import_job.rb
index 281b02c58..04c00de08 100644
--- a/app/jobs/process_digital_object_import_job.rb
+++ b/app/jobs/process_digital_object_import_job.rb
@@ -1,9 +1,10 @@
-class ProcessDigitalObjectImportJob
- @queue = Hyacinth::Queue::DIGITAL_OBJECT_IMPORT_LOW
+class ProcessDigitalObjectImportJob < ActiveJob::Base
+ queue_as Hyacinth::Queue::DIGITAL_OBJECT_IMPORT_LOW
+
UNEXPECTED_PROCESSING_ERROR_RETRY_DELAY = 60
FIND_DIGITAL_OBJECT_IMPORT_RETRY_DELAY = 10
- def self.perform(digital_object_import_id)
+ def perform(digital_object_import_id)
# If the import job was previously deleted (and does not exist in the database), return immediately
return unless DigitalObjectImport.exists?(digital_object_import_id)
@@ -44,7 +45,7 @@ def self.perform(digital_object_import_id)
handle_unexpected_processing_error(digital_object_import_id, e)
end
- def self.find_or_create_digital_object(digital_object_data, user, digital_object_import)
+ def find_or_create_digital_object(digital_object_data, user, digital_object_import)
if existing_object?(digital_object_data)
# We're updating data for an existing object
existing_object_for_update(digital_object_data, user)
@@ -58,7 +59,7 @@ def self.find_or_create_digital_object(digital_object_data, user, digital_object
# digital_object_import instance because when it's called, we can't guarantee
# that we were able to successfully obtain a digital_object_import instance.
# We try multiple times, within this method, to obtain an instance.
- def self.handle_unexpected_processing_error(digital_object_import_id, e, queue_long_jobs = HYACINTH[:queue_long_jobs])
+ def handle_unexpected_processing_error(digital_object_import_id, e, queue_long_jobs = HYACINTH[:queue_long_jobs])
# In the case of some unexpected, otherwise unhandled error, mark this job
# as a failure so that it doesn't get stuck as pending forever, causing
# other jobs that depend on it to be requeued forever.
@@ -77,18 +78,18 @@ def self.handle_unexpected_processing_error(digital_object_import_id, e, queue_l
end
end
- def self.find_digital_object_import_with_retry(digital_object_import_id)
+ def find_digital_object_import_with_retry(digital_object_import_id)
# Retry in case database is briefly unavailable
Retriable.retriable(tries: 3, base_interval: FIND_DIGITAL_OBJECT_IMPORT_RETRY_DELAY) do
return DigitalObjectImport.find(digital_object_import_id)
end
end
- def self.existing_object?(digital_object_data)
+ def existing_object?(digital_object_data)
digital_object_data['pid'].present? && DigitalObject::Base.exists?(digital_object_data['pid'])
end
- def self.assign_data(digital_object, digital_object_data, digital_object_import)
+ def assign_data(digital_object, digital_object_data, digital_object_import)
digital_object.set_digital_object_data(digital_object_data, true)
:success
rescue Hyacinth::Exceptions::ParentDigitalObjectNotFoundError => e
@@ -99,17 +100,17 @@ def self.assign_data(digital_object, digital_object_data, digital_object_import)
:failure
end
- def self.exception_with_backtrace_as_error_message(e)
+ def exception_with_backtrace_as_error_message(e)
e.message + "\nBacktrace:\n\t#{e.backtrace.join("\n\t")}"
end
- def self.existing_object_for_update(digital_object_data, user)
+ def existing_object_for_update(digital_object_data, user)
digital_object = DigitalObject::Base.find(digital_object_data['pid'])
digital_object.updated_by = user
digital_object
end
- def self.new_object(digital_object_type, user, digital_object_import)
+ def new_object(digital_object_type, user, digital_object_import)
digital_object = DigitalObjectType.get_model_for_string_key(digital_object_type || :missing).new
digital_object.created_by = user
digital_object.updated_by = user
@@ -119,7 +120,7 @@ def self.new_object(digital_object_type, user, digital_object_import)
nil
end
- def self.handle_success_or_failure(status, digital_object, digital_object_import, do_solr_commit)
+ def handle_success_or_failure(status, digital_object, digital_object_import, do_solr_commit)
if status == :success && digital_object.save(do_solr_commit)
digital_object_import.digital_object_errors = []
digital_object_import.status = :success
@@ -137,7 +138,7 @@ def self.handle_success_or_failure(status, digital_object, digital_object_import
# If prerequisite rows are pending, then this digital_object_import will be requeued.
# If prerequisite rows failed, then this digital_object_import will also fail with
# a prerequisite-related error message.
- def self.prerequisite_row_check(digital_object_import, queue_long_jobs = HYACINTH[:queue_long_jobs])
+ def prerequisite_row_check(digital_object_import, queue_long_jobs = HYACINTH[:queue_long_jobs])
# If this import has prerequisite_csv_row_numbers, make sure that the job
# with that prerequisite_csv_row_numbers has been completed. If it hasn't,
# we'll re-queue this job.
@@ -192,7 +193,7 @@ def self.prerequisite_row_check(digital_object_import, queue_long_jobs = HYACINT
true
end
- def self.handle_remaining_prerequisite_case(digital_object_import, queue_long_jobs)
+ def handle_remaining_prerequisite_case(digital_object_import, queue_long_jobs)
if queue_long_jobs
# If prerequisite are still pending, then re-queue this import
digital_object_import.digital_object_errors = [] # clear earlier errors if we're re-queueing
diff --git a/app/jobs/reindex_digital_object_job.rb b/app/jobs/reindex_digital_object_job.rb
index a49b9a252..8c9b3c4d9 100644
--- a/app/jobs/reindex_digital_object_job.rb
+++ b/app/jobs/reindex_digital_object_job.rb
@@ -1,7 +1,7 @@
-class ReindexDigitalObjectJob
- @queue = Hyacinth::Queue::DIGITAL_OBJECT_REINDEX
+class ReindexDigitalObjectJob < ActiveJob::Base
+ queue_as Hyacinth::Queue::DIGITAL_OBJECT_REINDEX
- def self.perform(digital_object_pid)
+ def perform(digital_object_pid)
# Pass false param to update_index() method so that we don't do a Solr commit for each update (because that would be inefficient).
DigitalObject::Base.find(digital_object_pid).update_index(false)
end
diff --git a/lib/hyacinth/csv/flatten.rb b/lib/hyacinth/csv/flatten.rb
index 34ffc0c38..273159562 100644
--- a/lib/hyacinth/csv/flatten.rb
+++ b/lib/hyacinth/csv/flatten.rb
@@ -1,65 +1,63 @@
module Hyacinth::Csv::Flatten
extend ActiveSupport::Concern
- module ClassMethods
- def keys_for_document(document, omit_blank_values = false)
- document = document.clone
- df_data = document.delete(DigitalObject::DynamicField::DATA_KEY) || {}
+ def keys_for_document(document, omit_blank_values = false)
+ document = document.clone
+ df_data = document.delete(DigitalObject::DynamicField::DATA_KEY) || {}
- internals = pointers_for_hash(document, omit_blank_values)
- internals.map! { |pointer| Hyacinth::Csv::Fields::Internal.new(pointer) }
- dynamics = pointers_for_hash(df_data, omit_blank_values)
- dynamics.map! { |pointer| Hyacinth::Csv::Fields::Dynamic.new(pointer) }
- internals.map(&:to_header) + dynamics.map(&:to_header)
- end
+ internals = pointers_for_hash(document, omit_blank_values)
+ internals.map! { |pointer| Hyacinth::Csv::Fields::Internal.new(pointer) }
+ dynamics = pointers_for_hash(df_data, omit_blank_values)
+ dynamics.map! { |pointer| Hyacinth::Csv::Fields::Dynamic.new(pointer) }
+ internals.map(&:to_header) + dynamics.map(&:to_header)
+ end
- def pointers_for_hash(hash, omit_blank_values, prefix = [])
- keys = []
- hash.each do |key, value|
- if value.is_a?(Array)
- key_prefix = prefix + [key]
- keys += pointers_for_array(value, omit_blank_values, key_prefix)
- elsif uri_hash?(value)
- key_prefix = prefix + [key]
- keys += pointers_for_uri(value, omit_blank_values, key_prefix)
- elsif value.is_a?(Hash)
- key_prefix = prefix + [key]
- keys += pointers_for_hash(value, omit_blank_values, key_prefix)
- else
- key = pointer_for_value(key, value, omit_blank_values, prefix)
- keys << key unless keys.include?(key) || key.nil?
- end
+ def pointers_for_hash(hash, omit_blank_values, prefix = [])
+ keys = []
+ hash.each do |key, value|
+ if value.is_a?(Array)
+ key_prefix = prefix + [key]
+ keys += pointers_for_array(value, omit_blank_values, key_prefix)
+ elsif uri_hash?(value)
+ key_prefix = prefix + [key]
+ keys += pointers_for_uri(value, omit_blank_values, key_prefix)
+ elsif value.is_a?(Hash)
+ key_prefix = prefix + [key]
+ keys += pointers_for_hash(value, omit_blank_values, key_prefix)
+ else
+ key = pointer_for_value(key, value, omit_blank_values, prefix)
+ keys << key unless keys.include?(key) || key.nil?
end
- keys.uniq
end
+ keys.uniq
+ end
- def pointers_for_array(array, omit_blank_values, prefix)
- keys = []
- array.each_with_index do |value, index|
- if value.is_a? Hash
- keys += pointers_for_hash(value, omit_blank_values, prefix + [index])
- else
- key = pointer_for_value(index, value, omit_blank_values, prefix)
- keys << key unless keys.include?(key) || key.nil?
- end
+ def pointers_for_array(array, omit_blank_values, prefix)
+ keys = []
+ array.each_with_index do |value, index|
+ if value.is_a? Hash
+ keys += pointers_for_hash(value, omit_blank_values, prefix + [index])
+ else
+ key = pointer_for_value(index, value, omit_blank_values, prefix)
+ keys << key unless keys.include?(key) || key.nil?
end
- keys
end
+ keys
+ end
- def pointer_for_value(key, value, omit_blank_values, prefix = [])
- return nil if omit_blank_values && !value.is_a?(TrueClass) && !value.is_a?(FalseClass) && value.blank?
- prefix + [key]
- end
+ def pointer_for_value(key, value, omit_blank_values, prefix = [])
+ return nil if omit_blank_values && !value.is_a?(TrueClass) && !value.is_a?(FalseClass) && value.blank?
+ prefix + [key]
+ end
- def uri_hash?(hash)
- hash.is_a?(Hash) && hash.key?('uri') && !hash['uri'].is_a?(Hash)
- end
+ def uri_hash?(hash)
+ hash.is_a?(Hash) && hash.key?('uri') && !hash['uri'].is_a?(Hash)
+ end
- def pointers_for_uri(hash, omit_blank_values, prefix = [])
- return nil if omit_blank_values && hash.blank?
- hash.map do |key, value|
- pointer_for_value("#{prefix[-1]}.#{key}", value, omit_blank_values, prefix[0...-1])
- end.compact
- end
+ def pointers_for_uri(hash, omit_blank_values, prefix = [])
+ return nil if omit_blank_values && hash.blank?
+ hash.map do |key, value|
+ pointer_for_value("#{prefix[-1]}.#{key}", value, omit_blank_values, prefix[0...-1])
+ end.compact
end
end
diff --git a/lib/hyacinth/queue.rb b/lib/hyacinth/queue.rb
index 486b9de4b..8d335d5ab 100644
--- a/lib/hyacinth/queue.rb
+++ b/lib/hyacinth/queue.rb
@@ -35,25 +35,25 @@ def self.process_digital_object_import(digital_object_import)
raise 'Invalid priority: ' + priority.inspect
end
- Resque.enqueue_to(queue_name, ProcessDigitalObjectImportJob, digital_object_import_id)
+ ProcessDigitalObjectImportJob.set(queue: queue_name).perform_later(digital_object_import_id)
else
- ProcessDigitalObjectImportJob.perform(digital_object_import_id)
+ ProcessDigitalObjectImportJob.perform_now(digital_object_import_id)
end
end
def self.export_search_results_to_csv(csv_export_id)
if HYACINTH[:queue_long_jobs]
- Resque.enqueue(ExportSearchResultsToCsvJob, csv_export_id)
+ ExportSearchResultsToCsvJob.perform_later(csv_export_id)
else
- ExportSearchResultsToCsvJob.perform(csv_export_id)
+ ExportSearchResultsToCsvJob.perform_now(csv_export_id)
end
end
def self.reindex_digital_object(digital_object_pid)
if HYACINTH[:queue_long_jobs]
- Resque.enqueue(ReindexDigitalObjectJob, digital_object_pid)
+ ReindexDigitalObjectJob.perform_later(digital_object_pid)
else
- ReindexDigitalObjectJob.perform(digital_object_pid)
+ ReindexDigitalObjectJob.perform_now(digital_object_pid)
end
end
end
diff --git a/spec/features/digital_object_editor_ui_spec.rb b/spec/features/digital_object_editor_ui_spec.rb
index 62c957cc5..4e6bc1c5a 100644
--- a/spec/features/digital_object_editor_ui_spec.rb
+++ b/spec/features/digital_object_editor_ui_spec.rb
@@ -9,6 +9,5 @@
it "can create a new Digital Object", :js => true do
expect(page).to have_content 'New Digital Object'
-
end
end
diff --git a/spec/integration/csv_export_import_round_trip_spec.rb b/spec/integration/csv_export_import_round_trip_spec.rb
index 8b1d12078..8c2dac4a1 100644
--- a/spec/integration/csv_export_import_round_trip_spec.rb
+++ b/spec/integration/csv_export_import_round_trip_spec.rb
@@ -95,7 +95,7 @@
'fq' => { 'hyacinth_type_sim' => [{ 'does_not_equal' => 'publish_target' }] }
})
)
- ExportSearchResultsToCsvJob.perform(first_csv_export.id)
+ ExportSearchResultsToCsvJob.perform_now(first_csv_export.id)
first_csv_export.reload # Reload the ActiveRecord object, getting the latest data in the DB (so we have the path to the csv file)
path_to_first_csv_file = first_csv_export.path_to_csv_file
@@ -131,7 +131,7 @@
'fq' => { 'hyacinth_type_sim' => [{ 'does_not_equal' => 'publish_target' }] }
})
)
- ExportSearchResultsToCsvJob.perform(second_csv_export.id)
+ ExportSearchResultsToCsvJob.perform_now(second_csv_export.id)
second_csv_export.reload # Reload the ActiveRecord object, getting the latest data in the DB (so we have the path to the csv file)
path_to_second_csv_file = second_csv_export.path_to_csv_file
expect(CSV.read(path_to_first_csv_file)).to eq(CSV.read(path_to_second_csv_file))
diff --git a/spec/jobs/export_search_results_to_csv_job_spec.rb b/spec/jobs/export_search_results_to_csv_job_spec.rb
index 7c862c563..b4dc24a79 100644
--- a/spec/jobs/export_search_results_to_csv_job_spec.rb
+++ b/spec/jobs/export_search_results_to_csv_job_spec.rb
@@ -10,12 +10,14 @@
let(:user) { User.new }
let(:search_params) { Hash.new }
+ let(:instance) { described_class.new }
+
before do
allow(DigitalObject::Base).to receive(:search_in_batches)
.and_yield(doc1).and_yield(doc2)
end
- describe '.map_temp_field_indexes' do
+ describe '#map_temp_field_indexes' do
let(:expected) do
{
'_pid' => 0,
@@ -27,7 +29,7 @@
}
end
- subject { ExportSearchResultsToCsvJob.map_temp_field_indexes(search_params, user) }
+ subject { instance.map_temp_field_indexes(search_params, user) }
it do
is_expected.to eql expected
@@ -79,7 +81,7 @@
allow(CsvExport).to receive(:find).with(export_id).and_return(export)
allow(DigitalObject::Base).to receive(:search_in_batches).and_yield(sample_json_document)
expect(export).to receive(:path_to_csv_file).and_call_original
- described_class.perform(export_id)
+ instance.perform(export_id)
expect(export.number_of_records_processed).to eq(1)
actual_csv = CSV.read(export.path_to_csv_file)
diff --git a/spec/jobs/process_digital_object_import_job_spec.rb b/spec/jobs/process_digital_object_import_job_spec.rb
index 400fb766a..1ced73776 100644
--- a/spec/jobs/process_digital_object_import_job_spec.rb
+++ b/spec/jobs/process_digital_object_import_job_spec.rb
@@ -1,12 +1,12 @@
require 'rails_helper'
-RSpec.describe ProcessDigitalObjectImportJob, :type => :job do
+RSpec.describe ProcessDigitalObjectImportJob, type: :job do
before(:example) {
stub_const("ProcessDigitalObjectImportJob::UNEXPECTED_PROCESSING_ERROR_RETRY_DELAY", 0) # Make tests run more quickly
stub_const("ProcessDigitalObjectImportJob::FIND_DIGITAL_OBJECT_IMPORT_RETRY_DELAY", 0) # Make tests run more quickly
}
- let (:klass) { ProcessDigitalObjectImportJob }
+ let (:instance) { described_class.new }
let(:user) {
User.new(
:email => 'abc@example.com',
@@ -33,19 +33,19 @@
}
}
- describe ".existing_object?" do
+ describe "#existing_object?" do
it "returns true if digital object data contains a pid field for an existing object" do
existing_pid = 'it:exists'
nonexisting_pid = 'it:doesnoteist'
allow(DigitalObject::Base).to receive(:'exists?').with(existing_pid).and_return(true)
allow(DigitalObject::Base).to receive(:'exists?').with(nonexisting_pid).and_return(false)
- expect(klass.existing_object?({'pid' => existing_pid})).to eq(true)
- expect(klass.existing_object?({'pid' => nonexisting_pid})).to eq(false)
- expect(klass.existing_object?({})).to eq(false)
+ expect(instance.existing_object?({'pid' => existing_pid})).to eq(true)
+ expect(instance.existing_object?({'pid' => nonexisting_pid})).to eq(false)
+ expect(instance.existing_object?({})).to eq(false)
end
end
- describe ".find_digital_object_import_with_retry" do
+ describe "#find_digital_object_import_with_retry" do
context "finds and returns a DigitalObjectImport when no error is raised by internal call to DigitalObjectImport.find" do
let(:digital_object_import_id) {
allow(DigitalObjectImport).to receive(:find).with(12345).and_return(digital_object_import)
@@ -55,7 +55,7 @@
DigitalObjectImport.new
}
it do
- expect(klass.find_digital_object_import_with_retry(digital_object_import_id)).to eq(digital_object_import)
+ expect(instance.find_digital_object_import_with_retry(digital_object_import_id)).to eq(digital_object_import)
end
end
context "retries multiple times when an error is raised by internal call to DigitalObjectImport.find" do
@@ -65,27 +65,27 @@
}
it do
expect(DigitalObjectImport).to receive(:find).exactly(3).times
- expect{klass.find_digital_object_import_with_retry(digital_object_import_id)}.to raise_error(StandardError)
+ expect{instance.find_digital_object_import_with_retry(digital_object_import_id)}.to raise_error(StandardError)
end
end
end
- describe ".find_or_create_digital_object" do
+ describe "#find_or_create_digital_object" do
let(:digital_object_import) {
DigitalObjectImport.new
}
it "internally calls .existing_object_for_update when .existing_object? returns true" do
- allow(klass).to receive(:existing_object?).and_return(true)
- expect(klass).to receive(:existing_object_for_update)
- klass.find_or_create_digital_object(digital_object_data, user, digital_object_import)
+ allow(instance).to receive(:existing_object?).and_return(true)
+ expect(instance).to receive(:existing_object_for_update)
+ instance.find_or_create_digital_object(digital_object_data, user, digital_object_import)
end
it "internally calls .new_object when .existing_object? returns false" do
- allow(klass).to receive(:existing_object?).and_return(false)
- expect(klass).to receive(:new_object)
- klass.find_or_create_digital_object(digital_object_data, user, digital_object_import)
+ allow(instance).to receive(:existing_object?).and_return(false)
+ expect(instance).to receive(:new_object)
+ instance.find_or_create_digital_object(digital_object_data, user, digital_object_import)
end
context "no digital_object_type given for a new object" do
- let(:digital_object) { klass.find_or_create_digital_object(digital_object_data, user, digital_object_import) }
+ let(:digital_object) { instance.find_or_create_digital_object(digital_object_data, user, digital_object_import) }
let(:expected_message) { "Invalid DigitalObjectType string key: missing" }
before do
digital_object_data.delete('digital_object_type')
@@ -98,7 +98,7 @@
end
end
- describe ".handle_unexpected_processing_error" do
+ describe "#handle_unexpected_processing_error" do
let(:digital_object_import_id) { 12345 }
let(:digital_object_import) {
DigitalObjectImport.new
@@ -111,67 +111,67 @@
end
}
it "marks the DigitalObjectImport with given id as failure, and stores the exception object's message in the DigitalObjectImport's digital_object_errors" do
- allow(klass).to receive(:find_digital_object_import_with_retry).and_return(digital_object_import)
+ allow(instance).to receive(:find_digital_object_import_with_retry).and_return(digital_object_import)
expect(digital_object_import).to receive(:save!).once
- klass.handle_unexpected_processing_error(digital_object_import_id, e, false)
- expect(digital_object_import.digital_object_errors).to eq([klass.exception_with_backtrace_as_error_message(e)])
+ instance.handle_unexpected_processing_error(digital_object_import_id, e, false)
+ expect(digital_object_import.digital_object_errors).to eq([instance.exception_with_backtrace_as_error_message(e)])
end
it "when encountering an error retrieving or saving the DigitalObjectImport, retries retrieval/saving code three times, and then raises the error encountered on the final retry" do
- allow(klass).to receive(:find_digital_object_import_with_retry).and_raise(StandardError)
- expect(klass).to receive(:find_digital_object_import_with_retry).exactly(3).times
- expect{klass.handle_unexpected_processing_error(digital_object_import_id, e, false)}.to raise_error(StandardError)
+ allow(instance).to receive(:find_digital_object_import_with_retry).and_raise(StandardError)
+ expect(instance).to receive(:find_digital_object_import_with_retry).exactly(3).times
+ expect{instance.handle_unexpected_processing_error(digital_object_import_id, e, false)}.to raise_error(StandardError)
end
end
- describe ".exception_with_backtrace_as_error_message" do
+ describe "#exception_with_backtrace_as_error_message" do
let(:error_message) { 'This is the error message' }
it "formats as expected" do
begin
raise StandardError, error_message
rescue StandardError => e
- expect(klass.exception_with_backtrace_as_error_message(e)).to eq(e.message + "\nBacktrace:\n\t#{e.backtrace.join("\n\t")}")
+ expect(instance.exception_with_backtrace_as_error_message(e)).to eq(e.message + "\nBacktrace:\n\t#{e.backtrace.join("\n\t")}")
end
end
end
- describe ".assign_data" do
+ describe "#assign_data" do
let(:digital_object) { DigitalObject::Item.new }
let(:digital_object_import) { DigitalObjectImport.new }
it "returns :success when everything works as expected and doesn't set any errors on passed DigitalObjectImport arg" do
allow_any_instance_of(DigitalObject::Item).to receive(:set_digital_object_data).and_return({})
- expect(klass.assign_data(digital_object, digital_object_data, digital_object_import)).to eq(:success)
+ expect(instance.assign_data(digital_object, digital_object_data, digital_object_import)).to eq(:success)
expect(digital_object_import.digital_object_errors).to be_blank
end
it "returns :parent_not_found and sets digital_object_errors on passed DigitalObjectImport arg when DigitalObject::Base#set_digital_object_data raises Hyacinth::Exceptions::ParentDigitalObjectNotFoundError" do
allow_any_instance_of(DigitalObject::Item).to receive(:set_digital_object_data).and_raise(Hyacinth::Exceptions::ParentDigitalObjectNotFoundError)
- expect(klass.assign_data(digital_object, digital_object_data, digital_object_import)).to eq(:parent_not_found)
+ expect(instance.assign_data(digital_object, digital_object_data, digital_object_import)).to eq(:parent_not_found)
expect(digital_object_import.digital_object_errors).to be_present
end
it "returns :failure and sets digital_object_errors on passed DigitalObjectImport arg when DigitalObject::Base#set_digital_object_data raises any StandardError other than Hyacinth::Exceptions::ParentDigitalObjectNotFoundError" do
[StandardError, Hyacinth::Exceptions::NotFoundError, Hyacinth::Exceptions::MalformedControlledTermFieldValue, UriService::Error].each do |exception_class|
allow_any_instance_of(DigitalObject::Item).to receive(:set_digital_object_data).and_raise(exception_class)
- expect(klass.assign_data(digital_object, digital_object_data, digital_object_import)).to eq(:failure)
+ expect(instance.assign_data(digital_object, digital_object_data, digital_object_import)).to eq(:failure)
expect(digital_object_import.digital_object_errors).to be_present
end
end
end
- describe ".existing_object_for_update" do
+ describe "#existing_object_for_update" do
let(:pid) { 'abc:123' }
let(:digital_object_data) { {'pid' => pid} }
it "returns an existing object with given user assigned to updated_by field" do
allow(DigitalObject::Base).to receive(:find).with(pid).and_return(DigitalObject::Item.new)
- obj = klass.existing_object_for_update(digital_object_data, user)
+ obj = instance.existing_object_for_update(digital_object_data, user)
expect(obj).to be_a(DigitalObject::Item)
expect(obj.updated_by).to eq(user)
end
end
- describe ".new_object" do
+ describe "#new_object" do
let(:digital_object_import) {
DigitalObjectImport.new
}
@@ -180,7 +180,7 @@
let(:digital_object_type) { 'item' }
it "returns a new object with expected created_by and updated_by values and correct type" do
- obj = klass.new_object(digital_object_type, user, digital_object_import)
+ obj = instance.new_object(digital_object_type, user, digital_object_import)
expect(obj).to be_a(DigitalObject::Item)
expect(obj.created_by).to eq(user)
expect(obj.updated_by).to eq(user)
@@ -191,14 +191,14 @@
context "valid digital object type" do
let(:digital_object_type) { 'invalid_item_type' }
it "passes an error to the digital_object_import.digital_object_errors array when an invalid digital object type is given" do
- klass.new_object(digital_object_type, user, digital_object_import)
+ instance.new_object(digital_object_type, user, digital_object_import)
expect(digital_object_import.digital_object_errors.length).to eq(1)
expect(digital_object_import.digital_object_errors[0]).to eq("Invalid DigitalObjectType string key: #{digital_object_type}")
end
end
end
- describe ".handle_success_or_failure" do
+ describe "#handle_success_or_failure" do
let(:digital_object_import) {
DigitalObjectImport.new
}
@@ -209,26 +209,26 @@
it "sets success status on digital_object_import when passed in status is :success and digital object save operation is successful" do
allow_any_instance_of(DigitalObject::Item).to receive(:save).and_return(true)
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
- klass.handle_success_or_failure(:success, digital_object, digital_object_import, :success)
+ instance.handle_success_or_failure(:success, digital_object, digital_object_import, :success)
expect(digital_object_import.status).to eq('success')
end
it "sets failure status on digital_object_import when passed in status is :failure, even if digital object save would have returned true" do
allow_any_instance_of(DigitalObject::Item).to receive(:save).and_return(true)
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
- klass.handle_success_or_failure(:failure, digital_object, digital_object_import, :success)
+ instance.handle_success_or_failure(:failure, digital_object, digital_object_import, :success)
expect(digital_object_import.status).to eq('failure')
end
it "sets failure status on digital_object_import when passed in status is :success, but digital object save returns false" do
allow_any_instance_of(DigitalObject::Item).to receive(:save).and_return(false)
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
- klass.handle_success_or_failure(:success, digital_object, digital_object_import, :success)
+ instance.handle_success_or_failure(:success, digital_object, digital_object_import, :success)
expect(digital_object_import.status).to eq('failure')
end
end
- describe ".handle_remaining_prerequisite_case" do
+ describe "#handle_remaining_prerequisite_case" do
let(:import_job) {
import_job = ImportJob.new
import_job.user = user
@@ -244,7 +244,7 @@
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
expect(Hyacinth::Queue).to receive(:process_digital_object_import).with(digital_object_import)
digital_object_import.digital_object_errors << 'An error'
- klass.handle_remaining_prerequisite_case(digital_object_import, queue_long_jobs)
+ instance.handle_remaining_prerequisite_case(digital_object_import, queue_long_jobs)
expect(digital_object_import.digital_object_errors).to be_blank
end
end
@@ -255,14 +255,14 @@
error_message = 'An error'
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
digital_object_import.digital_object_errors << error_message
- klass.handle_remaining_prerequisite_case(digital_object_import, queue_long_jobs)
+ instance.handle_remaining_prerequisite_case(digital_object_import, queue_long_jobs)
expect(digital_object_import.digital_object_errors).to include(error_message)
expect(digital_object_import.digital_object_errors.length).to eq(2)
end
end
end
- describe ".prerequisite_row_check" do
+ describe "#prerequisite_row_check" do
let(:digital_object_import_1) {
digital_object_import = DigitalObjectImport.new
digital_object_import.csv_row_number = 1
@@ -281,7 +281,7 @@
context "returns true if digital_object_import has no prerequisite rows" do
let(:digital_object_import) { digital_object_import_1 }
it do
- expect(klass.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(true)
+ expect(instance.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(true)
end
end
context "returns true if digital_object_import has prerequisite rows that have already been successfully processed" do
@@ -292,7 +292,7 @@
}
it do
allow(DigitalObjectImport).to receive(:where).and_return(prerequisite_digital_object_imports)
- expect(klass.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(true)
+ expect(instance.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(true)
end
end
@@ -304,7 +304,7 @@
}
it do
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
- expect(klass.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(false)
+ expect(instance.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(false)
expect(digital_object_import.digital_object_errors).to include('A CSV row cannot have itself as a prerequisite row. (Did you accidentally try to make this object its own parent?)')
end
end
@@ -316,8 +316,8 @@
}
it do
allow(DigitalObjectImport).to receive(:where).and_return(prerequisite_digital_object_imports)
- expect(klass).to receive(:handle_remaining_prerequisite_case).with(digital_object_import, queue_long_jobs)
- expect(klass.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(false)
+ expect(instance).to receive(:handle_remaining_prerequisite_case).with(digital_object_import, queue_long_jobs)
+ expect(instance.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(false)
end
end
context "returns false if any of this digital_object_import's prerequisite rows have failed, and also adds an error to this digital_object_import that describes the failure, and marks the digital_object_import as a failure" do
@@ -329,7 +329,7 @@
it do
allow(DigitalObjectImport).to receive(:where).and_return(prerequisite_digital_object_imports)
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
- expect(klass.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(false)
+ expect(instance.prerequisite_row_check(digital_object_import, queue_long_jobs)).to eq(false)
expect(digital_object_import.status).to eq('failure')
expect(digital_object_import.digital_object_errors.length).to eq(1)
expect(digital_object_import.digital_object_errors[0]).to eq("Failed because prerequisite row 1 failed to import properly")
@@ -337,7 +337,7 @@
end
end
- describe ".perform" do
+ describe "#perform" do
let(:digital_object_import_id) {
import_id = 12345
allow(DigitalObjectImport).to receive(:find).with(import_id).and_return(digital_object_import)
@@ -357,44 +357,44 @@
digital_object_import
}
it "calls .handle_unexpected_processing_error when an unexpected error occurs" do
- expect(klass).to receive(:handle_unexpected_processing_error)
- allow(klass).to receive(:find_digital_object_import_with_retry).and_raise(StandardError)
- klass.perform(digital_object_import_id)
+ expect(instance).to receive(:handle_unexpected_processing_error)
+ allow(instance).to receive(:find_digital_object_import_with_retry).and_raise(StandardError)
+ instance.perform(digital_object_import_id)
end
it "returns early when .prerequisite_row_check fails" do
- allow(klass).to receive(:prerequisite_row_check).and_return(false)
- expect(klass).not_to receive(:existing_object?)
- klass.perform(digital_object_import_id)
+ allow(instance).to receive(:prerequisite_row_check).and_return(false)
+ expect(instance).not_to receive(:existing_object?)
+ instance.perform(digital_object_import_id)
end
context "successful .prerequisite_row_check" do
before {
- allow(klass).to receive(:prerequisite_row_check).and_return(true)
+ allow(instance).to receive(:prerequisite_row_check).and_return(true)
}
context "internally creates new digital object or retrieves existing digital object" do
context "internally calls handle_success_or_failure if the result returned by .assign_data is not :parent_not_found" do
it ":success" do
- allow(klass).to receive(:assign_data).and_return(:success)
- expect(klass).to receive(:handle_success_or_failure)
- klass.perform(digital_object_import_id)
+ allow(instance).to receive(:assign_data).and_return(:success)
+ expect(instance).to receive(:handle_success_or_failure)
+ instance.perform(digital_object_import_id)
end
it ":failure" do
- allow(klass).to receive(:assign_data).and_return(:failure)
- expect(klass).to receive(:handle_success_or_failure)
- klass.perform(digital_object_import_id)
+ allow(instance).to receive(:assign_data).and_return(:failure)
+ expect(instance).to receive(:handle_success_or_failure)
+ instance.perform(digital_object_import_id)
end
end
context "when receiving :parent_not_found from first internal call to .assign_data" do
it "sleep when :parent_not_found is returned the first time, and then internally call handle_success_or_failure when :success is returned after the second .assign_data call (to simulate scenario when parent object was in the middle of concurrent processing, perhaps coming from a different csv import job)" do
- allow(klass).to receive(:assign_data).and_return(:parent_not_found, :success).twice
- expect(klass).to receive(:sleep).once
- expect(klass).to receive(:handle_success_or_failure)
- klass.perform(digital_object_import_id)
+ allow(instance).to receive(:assign_data).and_return(:parent_not_found, :success).twice
+ expect(instance).to receive(:sleep).once
+ expect(instance).to receive(:handle_success_or_failure)
+ instance.perform(digital_object_import_id)
end
it "sleep when :parent_not_found is returned the first time, and then sleep two more times after :parent_not_found is returned again and again for .assign_data, and sets failure status and an error message on the digital_object_import" do
- allow(klass).to receive(:assign_data).and_return(:parent_not_found).exactly(4).times
+ allow(instance).to receive(:assign_data).and_return(:parent_not_found).exactly(4).times
allow_any_instance_of(DigitalObjectImport).to receive(:save!).and_return(true)
- expect(klass).to receive(:sleep).exactly(3).times
- klass.perform(digital_object_import_id)
+ expect(instance).to receive(:sleep).exactly(3).times
+ instance.perform(digital_object_import_id)
expect(digital_object_import.status).to eq('failure')
expect(digital_object_import.digital_object_errors.length).to eq(1)
expect(digital_object_import.digital_object_errors[0]).to eq("Failed because referenced parent object could not be found.")
diff --git a/spec/models/concerns/digital_object/dynamic_field_spec.rb b/spec/models/concerns/digital_object/dynamic_field_spec.rb
index 00af920b3..37e80d701 100644
--- a/spec/models/concerns/digital_object/dynamic_field_spec.rb
+++ b/spec/models/concerns/digital_object/dynamic_field_spec.rb
@@ -501,7 +501,7 @@
_c = Class.new
_c.send :include, Hyacinth::Csv::Flatten
end
- subject { test_class.keys_for_document('dynamic_field_data' => new_dynamic_field_data) }
+ subject { test_class.new.keys_for_document('dynamic_field_data' => new_dynamic_field_data) }
it { is_expected.to eql(flattened_csv_style_dynamic_field_data.keys)}
end
end