Skip to content

Commit

Permalink
Add ItemQueryService.validate_combinable_items
Browse files Browse the repository at this point in the history
Refs #365

This new class method takes an array of druids and makes sure each is combinable. If any are not, a hash of errors is created and returned.
  • Loading branch information
mjgiarlo committed Sep 4, 2019
1 parent 8923d60 commit 0ef98ae
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
14 changes: 14 additions & 0 deletions app/services/item_query_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@ def initialize(id:, item_relation: default_item_relation)

delegate :allows_modification?, to: :item

# @param [Array] druids a list of druids
# @raises [RuntimeError] if any items are dark, citation_only, or not modifiable
def self.validate_combinable_items(druids)
errors = {}

druids.each do |druid|
find_combinable_item(druid)
rescue RuntimeError => e
errors[druid] = e.message
end

errors
end

# @raises [RuntimeError] if the item is dark, citation_only, or not modifiable
def self.find_combinable_item(druid)
query_service = ItemQueryService.new(id: druid)
Expand Down
78 changes: 78 additions & 0 deletions spec/services/item_query_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@
allow(item).to receive(:allows_modification?).and_return(false)
expect { service.find_combinable_item('ab123cd4567') }.to raise_error(RuntimeError, 'Item druid:ab123cd4567 is not open for modification')
end

it 'raises error if object is dark' do
dra = instance_double(Dor::RightsAuth, dark?: true, citation_only?: false)
rights_ds = instance_double(Dor::RightsMetadataDS, dra_object: dra)
allow(item).to receive(:rightsMetadata).and_return(rights_ds)
allow(item).to receive(:allows_modification?).and_return(true)
expect { service.find_combinable_item('ab123cd4567') }.to raise_error(RuntimeError, 'Item druid:ab123cd4567 is dark')
end

it 'raises error if object is citation_only' do
dra = instance_double(Dor::RightsAuth, dark?: false, citation_only?: true)
rights_ds = instance_double(Dor::RightsMetadataDS, dra_object: dra)
allow(item).to receive(:rightsMetadata).and_return(rights_ds)
allow(item).to receive(:allows_modification?).and_return(true)
expect { service.find_combinable_item('ab123cd4567') }.to raise_error(RuntimeError, 'Item druid:ab123cd4567 is citation_only')
end

it 'returns item otherwise' do
dra = instance_double(Dor::RightsAuth, dark?: false, citation_only?: false)
rights_ds = instance_double(Dor::RightsMetadataDS, dra_object: dra)
Expand All @@ -39,4 +42,79 @@
service.find_combinable_item('ab123cd4567')
end
end

describe '.validate_combinable_items' do
let(:item2) { instantiate_fixture('druid:xh235dd9059', Dor::Item) }
let(:item3) { instantiate_fixture('druid:hj097bm8879', Dor::Item) }
let(:dark_rights) { instance_double(Dor::RightsAuth, dark?: true, citation_only?: false) }
let(:citation_only_rights) { instance_double(Dor::RightsAuth, dark?: false, citation_only?: true) }
let(:permissive_rights) { instance_double(Dor::RightsAuth, dark?: false, citation_only?: false) }
let(:dark_rights_ds) { instance_double(Dor::RightsMetadataDS, dra_object: dark_rights) }
let(:citation_only_rights_ds) { instance_double(Dor::RightsMetadataDS, dra_object: citation_only_rights) }
let(:permissive_rights_ds) { instance_double(Dor::RightsMetadataDS, dra_object: permissive_rights) }

# Set defaults on all fixture objects and avoid making HTTP calls. Set defaults to the non-error cases.
before do
allow(Dor::Item).to receive(:find).with('druid:xh235dd9059').and_return(item2)
allow(Dor::Item).to receive(:find).with('druid:hj097bm8879').and_return(item3)
[item, item2, item3].each do |i|
allow(i).to receive(:allows_modification?).and_return(true)
allow(i).to receive(:rightsMetadata).and_return(permissive_rights_ds)
end
end

context 'when any objects do not allow modification' do
before do
allow(item).to receive(:allows_modification?).and_return(false)
end

it 'returns a single error if one object does not allow modification' do
expect(service.validate_combinable_items(['druid:ab123cd4567', 'druid:xh235dd9059', 'druid:hj097bm8879'])).to eq(
'druid:ab123cd4567' => 'Item druid:ab123cd4567 is not open for modification'
)
end
end

context 'when any objects are dark' do
before do
[item2, item3].each do |i|
allow(i).to receive(:rightsMetadata).and_return(dark_rights_ds)
end
end

it 'returns errors if any objects are dark' do
expect(service.validate_combinable_items(['druid:ab123cd4567', 'druid:xh235dd9059', 'druid:hj097bm8879'])).to eq(
'druid:hj097bm8879' => 'Item druid:hj097bm8879 is dark',
'druid:xh235dd9059' => 'Item druid:xh235dd9059 is dark'
)
end
end

context 'when any objects are citation-only' do
before do
[item, item3].each do |i|
allow(i).to receive(:rightsMetadata).and_return(citation_only_rights_ds)
end
end

it 'raises error if any objects are citation_only' do
expect(service.validate_combinable_items(['druid:ab123cd4567', 'druid:xh235dd9059', 'druid:hj097bm8879'])).to eq(
'druid:ab123cd4567' => 'Item druid:ab123cd4567 is citation_only',
'druid:hj097bm8879' => 'Item druid:hj097bm8879 is citation_only'
)
end
end

context 'when none of the error conditions exist' do
before do
[item, item2, item3].each do |i|
allow(i).to receive(:rightsMetadata).and_return(permissive_rights_ds)
end
end

it 'returns an empty hash otherwise' do
expect(service.validate_combinable_items(['druid:ab123cd4567', 'druid:xh235dd9059', 'druid:hj097bm8879'])).to eq({})
end
end
end
end

0 comments on commit 0ef98ae

Please sign in to comment.