diff --git a/dor-services.gemspec b/dor-services.gemspec
index 26493b79..76f8a902 100644
--- a/dor-services.gemspec
+++ b/dor-services.gemspec
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
s.name = 'dor-services'
s.version = Dor::VERSION
s.platform = Gem::Platform::RUBY
- s.authors = ['Michael Klein', 'Willy Mene', 'Chris Fitzpatrick', 'Richard Anderson', 'Renzo Sanchez-Silva', 'Joseph Atzberger', 'Johnathan Martin']
- s.email = ['mbklein@stanford.edu']
+ s.authors = ['Michael Klein', 'Willy Mene', 'Chris Fitzpatrick', 'Richard Anderson', 'Renzo Sanchez-Silva', 'Joseph Atzberger', 'Johnathan Martin', 'Darren Weber']
+ s.email = ['dlss-developers@lists.stanford.edu']
s.summary = 'Ruby implmentation of DOR services used by the SULAIR Digital Library'
s.description = 'Contains classes to register objects and initialize workflows'
s.licenses = ['ALv2', 'Stanford University']
diff --git a/lib/dor-services.rb b/lib/dor-services.rb
index 8651c2cf..d2b21eaf 100644
--- a/lib/dor-services.rb
+++ b/lib/dor-services.rb
@@ -107,6 +107,7 @@ def root
autoload :Publishable, 'dor/models/publishable'
autoload :Shelvable, 'dor/models/shelvable'
autoload :Embargoable, 'dor/models/embargoable'
+ autoload :Permissable, 'dor/models/permissable'
autoload :Preservable, 'dor/models/preservable'
autoload :Assembleable, 'dor/models/assembleable'
autoload :Upgradable, 'dor/models/upgradable'
diff --git a/lib/dor/models/admin_policy_object.rb b/lib/dor/models/admin_policy_object.rb
index ab41b6e0..8200b0cf 100644
--- a/lib/dor/models/admin_policy_object.rb
+++ b/lib/dor/models/admin_policy_object.rb
@@ -4,6 +4,7 @@ class AdminPolicyObject < ::ActiveFedora::Base
include Governable
include Editable
include Describable
+ include Permissable
include Processable
include Versionable
diff --git a/lib/dor/models/collection.rb b/lib/dor/models/collection.rb
index 5c1875f5..a2c3d18b 100644
--- a/lib/dor/models/collection.rb
+++ b/lib/dor/models/collection.rb
@@ -4,6 +4,7 @@ class Collection < ::ActiveFedora::Base
include Processable
include Governable
include Describable
+ include Permissable
include Publishable
include Versionable
include Releaseable
diff --git a/lib/dor/models/governable.rb b/lib/dor/models/governable.rb
index 1d8abb3f..7cafaddb 100644
--- a/lib/dor/models/governable.rb
+++ b/lib/dor/models/governable.rb
@@ -27,7 +27,7 @@ def default_workflow_lane
end
def reset_to_apo_default
- rightsMetadata.content = admin_policy_object.rightsMetadata.ng_xml
+ rightsMetadata.content = admin_policy_object.rightsMetadata.ng_xml.to_s
end
def set_read_rights(rights)
@@ -52,14 +52,15 @@ def remove_collection(collection_or_druid)
when Dor::Collection
collection_or_druid
end
-
collections.delete(collection)
sets.delete(collection)
end
+
# set the rights metadata datastream to the content of the APO's default object rights
def reapplyAdminPolicyObjectDefaults
rightsMetadata.content = admin_policy_object.datastreams['defaultObjectRights'].content
end
+
def rights
return nil unless self.respond_to? :rightsMetadata
return nil if rightsMetadata.nil?
@@ -75,56 +76,5 @@ def rights
'None'
end
end
- def groups_which_manage_item
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
- end
- def groups_which_manage_desc_metadata
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-apo-metadata']
- end
- def groups_which_manage_system_metadata
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
- end
- def groups_which_manage_content
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
- end
- def groups_which_manage_rights
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
- end
- def groups_which_manage_embargo
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor']
- end
- def groups_which_view_content
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer']
- end
- def groups_which_view_metadata
- ['dor-administrator', 'sdr-administrator', 'dor-apo-manager', 'dor-apo-depositor', 'dor-viewer', 'sdr-viewer']
- end
- def intersect(arr1, arr2)
- (arr1 & arr2).length > 0
- end
- def can_manage_item?(roles)
- intersect roles, groups_which_manage_item
- end
- def can_manage_desc_metadata?(roles)
- intersect roles, groups_which_manage_desc_metadata
- end
- def can_manage_system_metadata?(roles)
- intersect roles, groups_which_manage_system_metadata
- end
- def can_manage_content?(roles)
- intersect roles, groups_which_manage_content
- end
- def can_manage_rights?(roles)
- intersect roles, groups_which_manage_rights
- end
- def can_manage_embargo?(roles)
- intersect roles, groups_which_manage_embargo
- end
- def can_view_content?(roles)
- intersect roles, groups_which_view_content
- end
- def can_view_metadata?(roles)
- intersect roles, groups_which_view_metadata
- end
end
end
diff --git a/lib/dor/models/permissable.rb b/lib/dor/models/permissable.rb
new file mode 100644
index 00000000..6c125dae
--- /dev/null
+++ b/lib/dor/models/permissable.rb
@@ -0,0 +1,160 @@
+module Dor
+ module Permissable
+ extend ActiveSupport::Concern
+
+ # General documentation about roles and permissions is on SUL Consul at
+ # https://consul.stanford.edu/display/chimera/Repository+Roles+and+Permissions
+ # All these constants are frozen arrays so the methods that use them can
+ # easily add them to return arrays.
+ SDR_ADMINS = %w(sdr-administrator).freeze
+ SDR_MANAGERS = %w(sdr-manager).freeze
+ SDR_VIEWERS = %w(sdr-viewer).freeze
+
+ APO_MANAGERS = %w(dor-apo-manager).freeze
+ APO_DEPOSITORS = %w(dor-apo-depositor).freeze
+ APO_METADATA = %w(dor-apo-metadata).freeze
+ APO_VIEWERS = %w(dor-apo-viewer).freeze
+
+ # A complete set of known roles. This can be used by clients to
+ # inspect all the possible roles available.
+ KNOWN_ROLES = (
+ SDR_ADMINS + SDR_MANAGERS + SDR_VIEWERS +
+ APO_MANAGERS + APO_DEPOSITORS + APO_METADATA + APO_VIEWERS
+ ).freeze
+
+ # ---
+ # APO permissions
+
+ def can_create_apo?(roles)
+ intersect roles, roles_which_create_apo
+ end
+
+ def can_manage_apo?(roles)
+ intersect roles, roles_which_manage_apo
+ end
+
+ def can_manage_collections?(roles)
+ intersect roles, roles_which_manage_collections
+ end
+
+ def can_manage_roles?(roles)
+ intersect roles, roles_which_manage_roles
+ end
+
+ def can_manage_sets?(roles)
+ intersect roles, roles_which_manage_sets
+ end
+
+ def can_release_objects?(roles)
+ intersect roles, roles_which_release_objects
+ end
+
+ # ---
+ # Item permissions
+
+ def can_manage_item?(roles)
+ intersect roles, roles_which_manage_item
+ end
+
+ def can_register_item?(roles)
+ intersect roles, roles_which_register_item
+ end
+
+ def can_manage_desc_metadata?(roles)
+ intersect roles, roles_which_manage_desc_md
+ end
+
+ def can_manage_system_metadata?(roles)
+ intersect roles, roles_which_manage_sys_md
+ end
+
+ def can_manage_contents?(roles)
+ intersect roles, roles_which_manage_contents
+ end
+
+ def can_manage_rights?(roles)
+ intersect roles, roles_which_manage_rights
+ end
+
+ def can_manage_workflows?(roles)
+ intersect roles, roles_which_manage_workflows
+ end
+
+ def can_manage_embargo?(roles)
+ intersect roles, roles_which_manage_embargo
+ end
+
+ # ---
+ # Common viewing permissions
+
+ def can_view_content?(roles)
+ intersect roles, roles_which_view_content
+ end
+
+ def can_view_metadata?(roles)
+ intersect roles, roles_which_view_metadata
+ end
+
+ private
+
+ # ---
+ # APO roles
+
+ def roles_which_create_apo
+ SDR_ADMINS + SDR_MANAGERS
+ end
+
+ def roles_which_manage_apo
+ SDR_ADMINS + SDR_MANAGERS + APO_MANAGERS
+ end
+
+ # When more granular roles are defined for APOs, these aliases
+ # could be redefined as stand-alone methods.
+ alias roles_which_manage_roles roles_which_manage_apo
+ alias roles_which_manage_collections roles_which_manage_apo
+ alias roles_which_manage_sets roles_which_manage_apo
+
+ def roles_which_release_objects
+ SDR_ADMINS + SDR_MANAGERS + APO_MANAGERS + APO_DEPOSITORS
+ end
+
+ # ---
+ # Item roles
+
+ def roles_which_manage_item
+ # exclude SDR_MANAGERS
+ SDR_ADMINS + APO_MANAGERS + APO_DEPOSITORS
+ end
+
+ def roles_which_manage_desc_md
+ SDR_ADMINS + APO_MANAGERS + APO_DEPOSITORS + APO_METADATA
+ end
+
+ # When more granular management roles are defined, these aliases
+ # should be redefined as stand-alone methods.
+ alias roles_which_register_item roles_which_manage_item
+ alias roles_which_manage_sys_md roles_which_manage_item
+ alias roles_which_manage_contents roles_which_manage_item
+ alias roles_which_manage_rights roles_which_manage_item
+ alias roles_which_manage_workflows roles_which_manage_item
+ alias roles_which_manage_embargo roles_which_manage_item
+
+ # ---
+ # Viewer roles (apply to both APO and Item)
+
+ # All roles can view metadata
+ def roles_which_view_metadata
+ KNOWN_ROLES
+ end
+
+ # Only SDR_MANAGERS cannot view content
+ def roles_which_view_content
+ SDR_ADMINS + SDR_VIEWERS +
+ APO_MANAGERS + APO_DEPOSITORS + APO_METADATA + APO_VIEWERS
+ end
+
+ def intersect(arr1, arr2)
+ (arr1 & arr2).length > 0
+ end
+ end
+end
diff --git a/lib/dor/models/publishable.rb b/lib/dor/models/publishable.rb
index b917fe23..10c8925e 100644
--- a/lib/dor/models/publishable.rb
+++ b/lib/dor/models/publishable.rb
@@ -7,6 +7,7 @@ module Publishable
include Governable
include Describable
include Itemizable
+ include Permissable
include Rightsable
def public_relationships
diff --git a/lib/dor/models/set.rb b/lib/dor/models/set.rb
index ce4ceefd..d566b02b 100644
--- a/lib/dor/models/set.rb
+++ b/lib/dor/models/set.rb
@@ -4,6 +4,7 @@ class Set < ::ActiveFedora::Base
include Processable
include Governable
include Describable
+ include Permissable
include Publishable
include Versionable
diff --git a/lib/dor/models/workflow_object.rb b/lib/dor/models/workflow_object.rb
index dac3d1fa..6411ed18 100644
--- a/lib/dor/models/workflow_object.rb
+++ b/lib/dor/models/workflow_object.rb
@@ -4,6 +4,7 @@ module Dor
class WorkflowObject < ::ActiveFedora::Base
include Identifiable
include Governable
+ include Permissable
@@xml_cache = {}
@@repo_cache = {}
diff --git a/spec/dor/governable_spec.rb b/spec/dor/governable_spec.rb
index e8d69887..3a579b19 100644
--- a/spec/dor/governable_spec.rb
+++ b/spec/dor/governable_spec.rb
@@ -11,6 +11,12 @@ class GovernableItem < ActiveFedora::Base
before(:each) { stub_config }
after(:each) { unstub_config }
+ before :each do
+ @item = instantiate_fixture('druid:oo201oo0001', Dor::AdminPolicyObject)
+ # @item.stub(:new_record? => false)
+ allow(Dor::Collection).to receive(:find).with('druid:oo201oo0002').and_return(mock_collection)
+ end
+
let(:mock_collection) {
coll = Dor::Collection.new
allow(coll).to receive(:new?).and_return false
@@ -20,21 +26,34 @@ class GovernableItem < ActiveFedora::Base
coll
}
- before :each do
- @item = instantiate_fixture('druid:oo201oo0001', Dor::AdminPolicyObject)
- # @item.stub(:new_record? => false)
- allow(Dor::Collection).to receive(:find).with('druid:oo201oo0002').and_return(mock_collection)
- end
-
describe 'set_read_rights error handling' do
- it 'should raise an exception if the rights option doesnt match the accepted values' do
+ it 'should raise an exception if the rights option does not match the accepted values' do
expect{@item.set_read_rights('"druid:oo201oo0001"', 'Something')}.to raise_error(ArgumentError)
end
- it 'should raise an exception if the rights option doesnt match the accepted values' do
+ it 'should raise an exception if the rights option does not match the accepted values' do
expect{@item.set_read_rights('mambo')}.to raise_error(ArgumentError)
end
end
+ describe 'rights' do
+ it 'returns "Stanford" for the "stanford" rights' do
+ @item.set_read_rights('stanford')
+ expect(@item.rights).to eq('Stanford')
+ end
+ it 'returns "World" for the "world" rights' do
+ @item.set_read_rights('world')
+ expect(@item.rights).to eq('World')
+ end
+ it 'returns "Dark" for the "dark" rights' do
+ @item.set_read_rights('dark')
+ expect(@item.rights).to eq('Dark')
+ end
+ it 'returns "None" for the "none" rights' do
+ @item.set_read_rights('none')
+ expect(@item.rights).to eq('None')
+ end
+ end
+
describe 'set_read_rights' do
it 'should set rights to dark (double none), removing the discovery rights' do
@item.set_read_rights('dark')
@@ -123,59 +142,6 @@ class GovernableItem < ActiveFedora::Base
XML
end
- end
-
- describe 'to_solr' do
- it 'should include a rights facet' do
- allow(@item).to receive(:milestones).and_return({})
- @item.set_read_rights('world')
- solr_doc = @item.to_solr
- expect(solr_doc).to match a_hash_including('rights_ssim' => ['World'], :id => @item.pid)
- end
- it 'should shouldnt error if there is nothing in the datastream' do
- allow(@item).to receive(:milestones).and_return({})
- allow(@item).to receive(:rightsMetadata).and_return(ActiveFedora::OmDatastream.new)
- solr_doc = @item.to_solr
- expect(solr_doc).not_to include('rights_facet')
- end
- end
-
- describe 'add_collection' do
- it 'should add a collection' do
- @item.add_collection('druid:oo201oo0002')
- rels_ext_ds = @item.datastreams['RELS-EXT']
- xml = Nokogiri::XML(rels_ext_ds.to_rels_ext.to_s)
- expect(xml).to be_equivalent_to <<-XML
-
-
-
-
-
-
-
-
-
- XML
- end
- end
-
- describe 'remove_collection' do
- it 'should delete a collection' do
- @item.add_collection('druid:oo201oo0002')
- rels_ext_ds = @item.datastreams['RELS-EXT']
- @item.remove_collection('druid:oo201oo0002')
- rels_ext_ds.serialize!
- xml = Nokogiri::XML(rels_ext_ds.content.to_s)
- expect(xml).to be_equivalent_to <<-XML
-
-
-
-
-
-
-
- XML
- end
it 'should change the read permissions value from stanford to ' do
expect(@item.datastreams['rightsMetadata'].ng_xml).to be_equivalent_to <<-XML
@@ -226,6 +192,91 @@ class GovernableItem < ActiveFedora::Base
end
end
+ describe 'reset_to_apo_default' do
+ it 'should set rights to APO rights' do
+ apo = instantiate_fixture('druid:fg890hi1234', Dor::AdminPolicyObject)
+ apo_rights = apo.rightsMetadata.ng_xml
+ allow(@item).to receive(:admin_policy_object).and_return(apo)
+ @item.set_read_rights('dark')
+ expect(@item.rightsMetadata.ng_xml).not_to be_equivalent_to apo_rights
+ @item.reset_to_apo_default
+ expect(@item.rightsMetadata.ng_xml).to be_equivalent_to apo_rights
+ end
+ end
+
+ describe 'to_solr' do
+ it 'should include a rights facet' do
+ allow(@item).to receive(:milestones).and_return({})
+ @item.set_read_rights('world')
+ solr_doc = @item.to_solr
+ expect(solr_doc).to match a_hash_including('rights_ssim' => ['World'], :id => @item.pid)
+ end
+ it 'should not error if there is nothing in the datastream' do
+ allow(@item).to receive(:milestones).and_return({})
+ allow(@item).to receive(:rightsMetadata).and_return(ActiveFedora::OmDatastream.new)
+ solr_doc = @item.to_solr
+ expect(solr_doc).not_to include('rights_facet')
+ end
+ end
+
+ describe 'add_collection' do
+ def check_collection
+ rels_ext_ds = @item.datastreams['RELS-EXT']
+ xml = Nokogiri::XML(rels_ext_ds.to_rels_ext.to_s)
+ expect(xml).to be_equivalent_to <<-XML
+
+
+
+
+
+
+
+
+
+ XML
+ end
+ it 'should find and add a collection' do
+ expect(Dor::Collection).to receive(:find).once
+ @item.add_collection('druid:oo201oo0002')
+ check_collection
+ end
+ it 'should add a collection' do
+ expect(Dor::Collection).not_to receive(:find)
+ @item.add_collection(mock_collection)
+ check_collection
+ end
+ end
+
+ describe 'remove_collection' do
+ def check_collection(rels_ext_ds)
+ rels_ext_ds.serialize!
+ xml = Nokogiri::XML(rels_ext_ds.content.to_s)
+ expect(xml).to be_equivalent_to <<-XML
+
+
+
+
+
+
+
+ XML
+ end
+ it 'should find and delete a collection' do
+ expect(Dor::Collection).to receive(:find).twice
+ @item.add_collection('druid:oo201oo0002')
+ rels_ext_ds = @item.datastreams['RELS-EXT']
+ @item.remove_collection('druid:oo201oo0002')
+ check_collection(rels_ext_ds)
+ end
+ it 'should delete a collection' do
+ expect(Dor::Collection).not_to receive(:find)
+ @item.add_collection(mock_collection)
+ rels_ext_ds = @item.datastreams['RELS-EXT']
+ @item.remove_collection(mock_collection)
+ check_collection(rels_ext_ds)
+ end
+ end
+
describe 'initiate_apo_workflow' do
it 'calls Processable.initialize_workflow without creating a datastream when the object is new' do
i = GovernableItem.new
@@ -282,83 +333,7 @@ class GovernableItem < ActiveFedora::Base
i.initiate_apo_workflow('accessionWF')
end
end
- describe 'can_manage_item?' do
- it 'should match a group that has rights' do
- expect(@item.can_manage_item?(['dor-administrator'])).to be_truthy
- end
- it 'should match a group that has rights' do
- expect(@item.can_manage_item?(['sdr-administrator'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_manage_item?(['dor-apo-metadata'])).to be_falsey
- end
- end
- describe 'can_manage_desc_metadata?' do
- it 'should match a group that has rights' do
- expect(@item.can_manage_desc_metadata?(['dor-apo-metadata'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_manage_desc_metadata?(['dor-viewer'])).to be_falsey
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_manage_desc_metadata?(['sdr-viewer'])).to be_falsey
- end
- end
- describe 'can_manage_content?' do
- it 'should match a group that has rights' do
- expect(@item.can_manage_content?(['dor-administrator'])).to be_truthy
- end
- it 'should match a group that has rights' do
- expect(@item.can_manage_content?(['sdr-administrator'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_manage_content?(['dor-apo-metadata'])).to be_falsey
- end
- end
- describe 'can_manage_rights?' do
- it 'should match a group that has rights' do
- expect(@item.can_manage_rights?(['dor-administrator'])).to be_truthy
- end
- it 'should match a group that has rights' do
- expect(@item.can_manage_rights?(['sdr-administrator'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_manage_rights?(['dor-apo-metadata'])).to be_falsey
- end
- end
- describe 'can_manage_embargo?' do
- it 'should match a group that has rights' do
- expect(@item.can_manage_embargo?(['dor-administrator'])).to be_truthy
- end
- it 'should match a group that has rights' do
- expect(@item.can_manage_embargo?(['sdr-administrator'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_manage_embargo?(['dor-apo-metadata'])).to be_falsey
- end
- end
- describe 'can_view_content?' do
- it 'should match a group that has rights' do
- expect(@item.can_view_content?(['dor-viewer'])).to be_truthy
- end
- it 'should match a group that has rights' do
- expect(@item.can_view_content?(['sdr-viewer'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_view_content?(['dor-people'])).to be_falsey
- end
- end
- describe 'can_view_metadata?' do
- it 'should match a group that has rights' do
- expect(@item.can_view_metadata?(['dor-viewer'])).to be_truthy
- end
- it 'should match a group that has rights' do
- expect(@item.can_view_metadata?(['sdr-viewer'])).to be_truthy
- end
- it 'shouldnt match a group that doesnt have rights' do
- expect(@item.can_view_metadata?(['dor-people'])).to be_falsey
- end
- end
+
describe 'reapplyAdminPolicyObjectDefaults' do
it 'should update rightsMetadata from the APO defaultObjectRights' do
expect(@item.rightsMetadata.ng_xml.search('//rightsMetadata/access[@type=\'read\']/machine/group').length).to eq(1)
diff --git a/spec/dor/permissable_spec.rb b/spec/dor/permissable_spec.rb
new file mode 100644
index 00000000..354d16ea
--- /dev/null
+++ b/spec/dor/permissable_spec.rb
@@ -0,0 +1,307 @@
+require 'spec_helper'
+
+describe Dor::Permissable do
+
+ let(:sdr_administrator) { 'sdr-administrator' }
+ let(:sdr_manager) { 'sdr-manager' }
+ let(:sdr_viewer) { 'sdr-viewer' }
+
+ let(:apo_manager) { 'dor-apo-manager' }
+ let(:apo_depositor) { 'dor-apo-depositor' }
+ let(:apo_metadata) { 'dor-apo-metadata' }
+ let(:apo_viewer) { 'dor-apo-viewer' }
+
+ let(:druid) { 'fg890hi1234' }
+ let(:apo) { instantiate_fixture(druid, Dor::AdminPolicyObject) }
+
+ before :each do
+ stub_config
+ end
+
+ after :each do
+ unstub_config
+ end
+
+ describe 'KNOWN_ROLES' do
+ it 'includes all known roles' do
+ expect(Dor::Permissable::KNOWN_ROLES).to include(sdr_administrator)
+ expect(Dor::Permissable::KNOWN_ROLES).to include(sdr_manager)
+ expect(Dor::Permissable::KNOWN_ROLES).to include(sdr_viewer)
+ expect(Dor::Permissable::KNOWN_ROLES).to include(apo_manager)
+ expect(Dor::Permissable::KNOWN_ROLES).to include(apo_depositor)
+ expect(Dor::Permissable::KNOWN_ROLES).to include(apo_metadata)
+ expect(Dor::Permissable::KNOWN_ROLES).to include(apo_viewer)
+ end
+ end
+
+ # ----
+ # Shared examples to allow/forbid all known roles
+
+ shared_examples 'allows sdr-administrator' do
+ it 'allows sdr-administrator' do
+ expect(apo.send(method, [sdr_administrator])).to be true
+ end
+ end
+ shared_examples 'forbids sdr-administrator' do
+ it 'forbids sdr-administrator' do
+ expect(apo.send(method, [sdr_administrator])).to be false
+ end
+ end
+
+ shared_examples 'allows sdr-manager' do
+ it 'allows sdr-manager' do
+ expect(apo.send(method, [sdr_manager])).to be true
+ end
+ end
+ shared_examples 'forbids sdr-manager' do
+ it 'forbids sdr-manager' do
+ expect(apo.send(method, [sdr_manager])).to be false
+ end
+ end
+
+ shared_examples 'allows sdr-viewer' do
+ it 'allows sdr-viewer' do
+ expect(apo.send(method, [sdr_viewer])).to be true
+ end
+ end
+ shared_examples 'forbids sdr-viewer' do
+ it 'forbids sdr-viewer' do
+ expect(apo.send(method, [sdr_viewer])).to be false
+ end
+ end
+
+ shared_examples 'allows dor-apo-manager' do
+ it 'allows dor-apo-manager' do
+ expect(apo.send(method, [apo_manager])).to be true
+ end
+ end
+ shared_examples 'forbids dor-apo-manager' do
+ it 'forbids dor-apo-manager' do
+ expect(apo.send(method, [apo_manager])).to be false
+ end
+ end
+
+ shared_examples 'allows dor-apo-depositor' do
+ it 'allows dor-apo-depositor' do
+ expect(apo.send(method, [apo_depositor])).to be true
+ end
+ end
+ shared_examples 'forbids dor-apo-depositor' do
+ it 'forbids dor-apo-depositor' do
+ expect(apo.send(method, [apo_depositor])).to be false
+ end
+ end
+
+ shared_examples 'allows dor-apo-metadata' do
+ it 'allows dor-apo-metadata' do
+ expect(apo.send(method, [apo_metadata])).to be true
+ end
+ end
+ shared_examples 'forbids dor-apo-metadata' do
+ it 'forbids dor-apo-metadata' do
+ expect(apo.send(method, [apo_metadata])).to be false
+ end
+ end
+
+ shared_examples 'allows dor-apo-viewer' do
+ it 'allows dor-apo-viewer' do
+ expect(apo.send(method, [apo_viewer])).to be true
+ end
+ end
+ shared_examples 'forbids dor-apo-viewer' do
+ it 'forbids dor-apo-viewer' do
+ expect(apo.send(method, [apo_viewer])).to be false
+ end
+ end
+
+ shared_examples 'forbids deprecated roles' do
+ it 'forbids dor-administrator' do
+ expect(apo.send(method, ['dor-administrator'])).to be false
+ end
+ it 'forbids dor-viewer' do
+ expect(apo.send(method, ['dor-viewer'])).to be false
+ end
+ end
+
+ shared_examples 'it only allows APO managers' do
+ # allows
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows sdr-manager'
+ it_behaves_like 'allows dor-apo-manager'
+ # forbids
+ it_behaves_like 'forbids sdr-viewer'
+ it_behaves_like 'forbids dor-apo-depositor'
+ it_behaves_like 'forbids dor-apo-metadata'
+ it_behaves_like 'forbids dor-apo-viewer'
+ it_behaves_like 'forbids deprecated roles'
+ end
+
+ shared_examples 'only allows ITEM managers' do
+ # allows
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows dor-apo-manager'
+ it_behaves_like 'allows dor-apo-depositor'
+ # forbids
+ it_behaves_like 'forbids sdr-manager'
+ it_behaves_like 'forbids sdr-viewer'
+ it_behaves_like 'forbids dor-apo-metadata'
+ it_behaves_like 'forbids dor-apo-viewer'
+ it_behaves_like 'forbids deprecated roles'
+ end
+
+ context 'with a Dor::AdminPolicyObject' do
+ # ---
+ # APO roles
+
+ describe 'can_create_apo?' do
+ let(:method) { :can_create_apo? }
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows sdr-manager'
+ # forbids
+ it_behaves_like 'forbids sdr-viewer'
+ it_behaves_like 'forbids dor-apo-manager'
+ it_behaves_like 'forbids dor-apo-depositor'
+ it_behaves_like 'forbids dor-apo-metadata'
+ it_behaves_like 'forbids dor-apo-viewer'
+ it_behaves_like 'forbids deprecated roles'
+ end
+
+ describe 'can_manage_apo?' do
+ let(:method) { :can_manage_apo? }
+ it_behaves_like 'it only allows APO managers'
+ end
+
+ describe 'can_manage_roles?' do
+ let(:method) { :can_manage_roles? }
+ it_behaves_like 'it only allows APO managers'
+ end
+
+ describe 'can_manage_collections?' do
+ let(:method) { :can_manage_collections? }
+ it_behaves_like 'it only allows APO managers'
+ end
+
+ describe 'can_manage_sets?' do
+ let(:method) { :can_manage_sets? }
+ it_behaves_like 'it only allows APO managers'
+ end
+
+ describe 'can_release_objects?' do
+ let(:method) { :can_release_objects? }
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows sdr-manager'
+ it_behaves_like 'allows dor-apo-manager'
+ it_behaves_like 'allows dor-apo-depositor'
+ # forbids
+ it_behaves_like 'forbids sdr-viewer'
+ it_behaves_like 'forbids dor-apo-metadata'
+ it_behaves_like 'forbids dor-apo-viewer'
+ it_behaves_like 'forbids deprecated roles'
+ end
+
+ # ---
+ # Item roles
+
+ describe 'can_manage_item?' do
+ let(:method) { :can_manage_item? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_register_item?' do
+ let(:method) { :can_register_item? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_manage_contents?' do
+ let(:method) { :can_manage_contents? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_manage_rights?' do
+ let(:method) { :can_manage_rights? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_manage_workflows?' do
+ let(:method) { :can_manage_workflows? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_manage_embargo?' do
+ let(:method) { :can_manage_embargo? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_manage_system_metadata?' do
+ let(:method) { :can_manage_system_metadata? }
+ it_behaves_like 'only allows ITEM managers'
+ end
+ describe 'can_manage_desc_metadata?' do
+ # differs from others by allowing dor-apo-metadata
+ let(:method) { :can_manage_desc_metadata? }
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows dor-apo-manager'
+ it_behaves_like 'allows dor-apo-depositor'
+ it_behaves_like 'allows dor-apo-metadata' # diff from others
+ # forbids
+ it_behaves_like 'forbids sdr-manager'
+ it_behaves_like 'forbids sdr-viewer'
+ it_behaves_like 'forbids dor-apo-viewer'
+ it_behaves_like 'forbids deprecated roles'
+ end
+
+ describe 'can_view_content?' do
+ let(:method) { :can_view_content? }
+ # allows
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows sdr-viewer'
+ it_behaves_like 'allows dor-apo-depositor'
+ it_behaves_like 'allows dor-apo-manager'
+ it_behaves_like 'allows dor-apo-metadata'
+ it_behaves_like 'allows dor-apo-viewer'
+ # forbids
+ it_behaves_like 'forbids sdr-manager'
+ it_behaves_like 'forbids deprecated roles'
+ end
+ describe 'can_view_metadata?' do
+ let(:method) { :can_view_metadata? }
+ # allows every role
+ it_behaves_like 'allows sdr-administrator'
+ it_behaves_like 'allows sdr-manager'
+ it_behaves_like 'allows sdr-viewer'
+ it_behaves_like 'allows dor-apo-depositor'
+ it_behaves_like 'allows dor-apo-manager'
+ it_behaves_like 'allows dor-apo-metadata'
+ it_behaves_like 'allows dor-apo-viewer'
+ # forbids
+ it_behaves_like 'forbids deprecated roles'
+ end
+ end
+
+ # ----
+ # alias_methods
+
+ describe 'aliases' do
+ it 'return :roles_which_manage_apo' do
+ aliases = [
+ :roles_which_manage_roles,
+ :roles_which_manage_collections,
+ :roles_which_manage_sets
+ ]
+ aliases.each do |a|
+ # Use Object.send to access private methods
+ expect(apo.send(a)).to eq apo.send(:roles_which_manage_apo)
+ end
+ end
+ it 'return :roles_which_manage_item' do
+ aliases = [
+ :roles_which_register_item,
+ :roles_which_manage_sys_md,
+ :roles_which_manage_contents,
+ :roles_which_manage_rights,
+ :roles_which_manage_workflows,
+ :roles_which_manage_embargo
+ ]
+ aliases.each do |a|
+ # Use Object.send to access private methods
+ expect(apo.send(a)).to eq apo.send(:roles_which_manage_item)
+ end
+ end
+ end
+end
+
+