module Ddr::Auth RSpec.describe Ability, type: :model, abilities: true do subject { described_class.new(auth_context) } let(:auth_context) { FactoryGirl.build(:auth_context) } describe "aliases" do it "should have :replace aliases" do expect(subject.aliased_actions[:replace]).to contain_exactly(:upload) end it "should have :add_children aliases" do expect(subject.aliased_actions[:add_children]).to contain_exactly(:add_attachment) end end describe "Datastream abilities" do let(:obj) { FactoryGirl.create(:component) } DatastreamAbilityDefinitions::DATASTREAM_DOWNLOAD_ABILITIES.each do |dsid, permission| describe "\"#{dsid}\"" do let(:ds) { obj.attached_files[dsid] } describe "can #{permission.inspect} object" do before { subject.can permission, obj.id } it { should be_able_to(:download, ds) } end describe "cannot #{permission.inspect} object" do before { subject.cannot permission, obj.id } it { should_not be_able_to(:download, ds) } end end end describe "non-downloadable attached_files" do (Component.child_resource_reflections.keys.map(&:to_s) - \ DatastreamAbilityDefinitions::DATASTREAM_DOWNLOAD_ABILITIES.keys).each do |dsid| describe "\"#{dsid}\"" do let(:ds) { obj.attached_files[dsid] } before { subject.can :download, obj.id } it { should_not be_able_to(:download, ds) } end end end end describe "Event abilities" do let(:event) { FactoryGirl.build(:event) } describe "can read object of the event" do before { subject.can :read, event.pid } it { should be_able_to(:read, event) } end describe "cannot read object of the event" do before { subject.cannot :read, event.pid } it { should_not be_able_to(:read, event) } end end describe "Collection abilities" do describe "collection creation" do before do allow(Ddr::Auth).to receive(:collection_creators_group) { "collection_creators" } end describe "when the user is a collection creator" do before do allow(auth_context).to receive(:member_of?).with("collection_creators") { true } end it { should be_able_to(:create, Collection) } end describe "when the user is not a collection creator" do before do allow(auth_context).to receive(:member_of?).with("collection_creators") { false } end it { should_not be_able_to(:create, Collection) } end end describe "metadata ingest" do let(:coll) { Collection.new } describe "ingest_metadata" do describe "when the collection can be edited" do before { subject.can :update, coll } it { should be_able_to(:ingest_metadata, coll) } end describe "when the collection cannot be edited" do before { subject.cannot :update, coll } it { should_not be_able_to(:ingest_metadata, coll) } end end end end describe "Item abilities" do let(:item) { FactoryGirl.build(:item) } describe "when the item has a parent" do let(:parent) { FactoryGirl.create(:collection) } before { item.parent = parent } describe "and can add children to the parent" do before { subject.can :add_children, parent } it { should be_able_to(:create, item) } end describe "and cannot add children to the parent" do before { subject.cannot :add_children, parent } it { should_not be_able_to(:create, item) } end end describe "when the item does not have a parent" do it { should_not be_able_to(:create, item) } end end describe "Component abilities" do let(:component) { FactoryGirl.build(:component) } describe "when the component has a parent" do let(:parent) { FactoryGirl.create(:item) } before { component.parent = parent } describe "and can add children to the parent" do before { subject.can :add_children, parent } it { should be_able_to(:create, component) } end describe "and cannot add children to the parent" do before { subject.cannot :add_children, parent } it { should_not be_able_to(:create, component) } end end describe "when the component does not have a parent" do it { should_not be_able_to(:create, component) } end end describe "Attachment abilities" do let(:attachment) { FactoryGirl.build(:attachment) } describe "when the attachment is attached" do let(:attached_to) { FactoryGirl.create(:collection) } before { attachment.attached_to = attached_to } describe "and can add attachment to the attached" do before { subject.can :add_attachment, attached_to } it { should be_able_to(:create, attachment) } end describe "and cannot add attachment to the attached" do before { subject.cannot :add_attachment, attached_to } it { should_not be_able_to(:create, attachment) } end end describe "when the attachment is not attached" do it { should_not be_able_to(:create, attachment) } end end describe "publication abilities" do let(:obj) { Ddr::Models::Base.new } describe "publish" do describe "when role-based permissions permit publish" do before do allow(obj).to receive(:effective_permissions) { [ Permissions::PUBLISH ] } end describe "when the object is published" do before { allow(obj).to receive(:published?) { true } } it { should_not be_able_to(:publish, obj) } end describe "when the object is not published" do describe "when the object is publishable" do before { allow(obj).to receive(:publishable?) { true } } it { should be_able_to(:publish, obj) } end describe "when the object is not publishable" do before { allow(obj).to receive(:publishable?) { false } } it { should_not be_able_to(:publish, obj) } end end end describe "when role-based permissions do not permit publish" do before { allow(obj).to receive(:publishable?) { true } } it { should_not be_able_to(:publish, obj) } end end describe "unpublish" do describe "when role-based permissions permit unpublish" do before do allow(obj).to receive(:effective_permissions) { [ Permissions::UNPUBLISH ] } end describe "when the object is published" do before { allow(obj).to receive(:published?) { true } } it { should be_able_to(:unpublish, obj) } end describe "when the object is not published" do it { should_not be_able_to(:unpublish, obj) } end end describe "when role-based permissions do not permit unpublish" do it { should_not be_able_to(:unpublish, obj) } end end end describe "locks" do let(:obj) { Ddr::Models::Base.new } describe "effects of locks on abilities" do before do allow(obj).to receive(:effective_permissions) { Permissions::ALL } allow(obj).to receive(:locked?) { true } end it { should be_able_to(:read, obj) } it { should be_able_to(:download, obj) } it { should_not be_able_to(:add_children, obj) } it { should_not be_able_to(:update, obj) } it { should_not be_able_to(:replace, obj) } it { should_not be_able_to(:arrange, obj) } it { should be_able_to(:audit, obj) } it { should_not be_able_to(:grant, obj) } end end describe "role based abilities" do shared_examples "it has role based abilities" do describe "when permissions are cached" do before { subject.cache[cache_key] = [ Permissions::READ ] } it "should use the cached permissions" do expect(perm_obj).not_to receive(:effective_permissions) expect(subject).to be_able_to(:read, obj) expect(subject).not_to be_able_to(:edit, obj) end end describe "when permissions are not cached" do describe "and user context has role based permission" do before do allow(perm_obj).to receive(:effective_permissions) do [ Permissions::UPDATE ] end end it { should be_able_to(:edit, obj) } end describe "and user context does not have role based permission" do before do allow(perm_obj).to receive(:effective_permissions) do [ Permissions::READ ] end end it { should_not be_able_to(:edit, obj) } end end end describe "with a Ddr model instance" do let(:obj) { Collection.new(id: "test-1") } let(:cache_key) { obj.id } let(:perm_obj) { obj } it_behaves_like "it has role based abilities" end describe "with a Solr document" do let(:obj) { SolrDocument.new({"id"=>"test-1"}) } let(:cache_key) { obj.id } let(:perm_obj) { obj } it_behaves_like "it has role based abilities" end describe "with a String" do let(:obj) { "test-1" } let(:cache_key) { obj } let(:perm_obj) { SolrDocument.new({"id"=>"test-1"}) } before do allow_any_instance_of(RoleBasedAbilityDefinitions).to receive(:permissions_doc).with(obj) { perm_obj } end it_behaves_like "it has role based abilities" end end end end