Skip to content

Commit

Permalink
Merge pull request #345 from sul-dlss/combinable-items
Browse files Browse the repository at this point in the history
Combinable items
  • Loading branch information
jcoyne committed Aug 29, 2019
2 parents e1381e1 + a862317 commit e34a6e0
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
6 changes: 3 additions & 3 deletions app/services/constituent_service.rb
Expand Up @@ -16,7 +16,7 @@ def initialize(parent_druid:)
# subsequent calls will erase the previous changes.
# @param [Array<String>] child_druids the identifiers of the child objects
def add(child_druids:)
ResetContentMetadataService.new(druid: parent_druid).reset
ResetContentMetadataService.new(item: parent).reset

child_druids.each do |child_druid|
add_constituent(child_druid: child_druid)
Expand All @@ -29,7 +29,7 @@ def add(child_druids:)
attr_reader :parent_druid

def add_constituent(child_druid:)
child = ItemQueryService.find_modifiable_item(child_druid)
child = ItemQueryService.find_combinable_item(child_druid)
child.contentMetadata.ng_xml.search('//resource').each do |resource|
parent.contentMetadata.add_virtual_resource(child.id, resource)
end
Expand All @@ -38,6 +38,6 @@ def add_constituent(child_druid:)
end

def parent
@parent ||= ItemQueryService.find_modifiable_item(parent_druid)
@parent ||= ItemQueryService.find_combinable_item(parent_druid)
end
end
6 changes: 4 additions & 2 deletions app/services/item_query_service.rb
Expand Up @@ -11,11 +11,13 @@ def initialize(id:, item_relation: default_item_relation)

delegate :allows_modification?, to: :item

# @raises [RuntimeError] if the item is not modifiable
def self.find_modifiable_item(druid)
# @raises [RuntimeError] if the item is dark, citation_only, or not modifiable
def self.find_combinable_item(druid)
query_service = ItemQueryService.new(id: druid)
query_service.item do |item|
raise "Item #{item.pid} is not open for modification" unless query_service.allows_modification?
raise "Item #{item.pid} is dark" if item.rightsMetadata.dra_object.dark?
raise "Item #{item.pid} is citation_only" if item.rightsMetadata.dra_object.citation_only?
end
end

Expand Down
10 changes: 5 additions & 5 deletions app/services/reset_content_metadata_service.rb
@@ -1,15 +1,15 @@
# frozen_string_literal: true

# Clears the contentMetadata datastream to the default, wiping out any members.
# item MUST allow modification, or save! will raise error
class ResetContentMetadataService
def initialize(druid:, type: 'image')
@druid = druid
def initialize(item:, type: 'image')
@item = item
@type = type
end

def reset
work = ItemQueryService.find_modifiable_item(@druid)
work.contentMetadata.content = "<contentMetadata objectId='#{work.id}' type='#{@type}'/>"
work.save!
@item.contentMetadata.content = "<contentMetadata objectId='#{@item.id}' type='#{@type}'/>"
@item.save!
end
end
14 changes: 7 additions & 7 deletions spec/services/constituent_service_spec.rb
Expand Up @@ -59,9 +59,9 @@
# Used in ContentMetadataDS#add_virtual_resource
allow(parent.contentMetadata).to receive(:pid).and_return('druid:parent1')

allow(ItemQueryService).to receive(:find_modifiable_item).with('druid:parent1').and_return(parent)
allow(ItemQueryService).to receive(:find_modifiable_item).with('druid:child1').and_return(child1)
allow(ItemQueryService).to receive(:find_modifiable_item).with('druid:child2').and_return(child2)
allow(ItemQueryService).to receive(:find_combinable_item).with('druid:parent1').and_return(parent)
allow(ItemQueryService).to receive(:find_combinable_item).with('druid:child1').and_return(child1)
allow(ItemQueryService).to receive(:find_combinable_item).with('druid:child2').and_return(child2)

allow(Dor::Services::Client).to receive(:object).and_return(client)
end
Expand All @@ -88,9 +88,9 @@
end
end

context 'when the parent is closed for modification' do
context 'when the parent is not combinable' do
before do
allow(ItemQueryService).to receive(:find_modifiable_item).with(parent.id).and_raise('nope')
allow(ItemQueryService).to receive(:find_combinable_item).with(parent.id).and_raise('nope')
end

it 'merges nothing' do
Expand All @@ -100,9 +100,9 @@
end
end

context 'when the child is closed for modification' do
context 'when a child is not combinable' do
before do
allow(ItemQueryService).to receive(:find_modifiable_item).with(child2.id).and_raise('not modifiable')
allow(ItemQueryService).to receive(:find_combinable_item).with(child2.id).and_raise('not modifiable')
end

it 'merges all the chidren before an error is encountered' do
Expand Down
42 changes: 42 additions & 0 deletions spec/services/item_query_service_spec.rb
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe ItemQueryService do
subject(:service) { described_class }

let(:druid) { 'ab123cd4567' }
let(:item) { instantiate_fixture('druid:ab123cd4567', Dor::Item) }

before do
allow(Dor::Item).to receive(:find).and_return(item)
end

describe '.find_combinable_item' do
it 'raises error if object does not allow modification' do
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)
allow(item).to receive(:rightsMetadata).and_return(rights_ds)
allow(item).to receive(:allows_modification?).and_return(true)
service.find_combinable_item('ab123cd4567')
end
end
end

0 comments on commit e34a6e0

Please sign in to comment.