diff --git a/spec/services/hyrax/collections/collection_member_service_spec.rb b/spec/services/hyrax/collections/collection_member_service_spec.rb index d89c6aea70..2e90d50cc8 100644 --- a/spec/services/hyrax/collections/collection_member_service_spec.rb +++ b/spec/services/hyrax/collections/collection_member_service_spec.rb @@ -9,21 +9,66 @@ before { Hyrax.publisher.subscribe(listener) } after { Hyrax.publisher.unsubscribe(listener) } + shared_context('with two works and a collection with existing members') do + let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } + let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } + let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } + end + + shared_context('with existing members framework') do + let(:existing_members) { [] } + let(:existing_member_ids) { existing_members.map(&:id) } + end + + shared_context('with existing new work') do + let(:existing_work) { FactoryBot.valkyrie_create(:hyrax_work) } + let(:existing_members) { [existing_work] } + end + + shared_context('with two existing works') do + let(:existing_members) { [work1, work2] } + let(:existing_member_ids) { existing_members.map(&:id) } + end + + shared_context('with two non-existing works') do + let(:non_existing_work1) { FactoryBot.valkyrie_create(:hyrax_work) } + let(:non_existing_work2) { FactoryBot.valkyrie_create(:hyrax_work) } + end + + shared_examples('tests for members not in set') do + it "returns false if member isn't in member set" do + expect(described_class.member?(collection_id: collection.id, member: non_member)).to eq false + end + end + + shared_examples('tests for added member ids') do + it "updates the collection member set adding the new members" do + expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids + new_member_ids + end + end + + shared_examples('tests that set only contains new members') do + it "updates the collection member set to contain only the new members" do + expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array new_member_ids + end + end + describe '.member?' do let(:non_member) { FactoryBot.valkyrie_create(:hyrax_work) } + context 'when no members' do let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection) } - it 'returns false' do - expect(described_class.member?(collection_id: collection.id, member: non_member)).to eq false - end + + include_examples 'tests for members not in set' end + context 'when has members' do let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: [work1, work2]) } - it "returns false if member isn't in member set" do - expect(described_class.member?(collection_id: collection.id, member: non_member)).to eq false - end + + include_examples 'tests for members not in set' + it "returns true if member is in member set" do expect(described_class.member?(collection_id: collection.id, member: work1)).to eq true end @@ -31,100 +76,93 @@ end describe '.add_members_by_ids' do - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [] } - let(:existing_member_ids) { existing_members.map(&:id) } + include_context 'with two works and a collection with existing members' + include_context 'with existing members framework' let(:new_member_ids) { [work1.id, work2.id] } before { described_class.add_members_by_ids(collection_id: collection.id, new_member_ids: new_member_ids, user: user) } context 'when ids is empty' do let(:new_member_ids) { [] } - it "returns without making changes" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array new_member_ids - end + + include_examples 'tests that set only contains new members' end + context 'when collection currently has no members' do - it "updates the collection member set to contain only the new members" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array new_member_ids - end + include_examples 'tests that set only contains new members' end + context 'when collection already has members' do - let(:existing_work) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:existing_members) { [existing_work] } + include_context 'with existing new work' + context 'and one of the new members already exists in the member set' do let(:new_member_ids) { [work1.id, work2.id, existing_work.id] } - it "updates the collection member set adding only resources not already in the member set" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array new_member_ids - end + + include_examples 'tests that set only contains new members' end + context 'and none of the new members exist in the member set' do - it "updates the collection member set adding the new members" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids + new_member_ids - end + include_examples 'tests for added member ids' end end end describe '.add_members' do - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [] } - let(:existing_member_ids) { existing_members.map(&:id) } - let(:new_members) { [work1, work2] } + include_context 'with two works and a collection with existing members' + include_context 'with existing members framework' let(:new_member_ids) { [work1.id, work2.id] } + let(:new_members) { [work1, work2] } before { described_class.add_members(collection_id: collection.id, new_members: new_members, user: user) } context 'when no members' do - it "updates the collection member set to contain only the new members" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array new_member_ids - end + include_examples 'tests that set only contains new members' end + context 'when has members' do - let(:existing_work) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:existing_members) { [existing_work] } + include_context 'with existing new work' + context 'and a members already exists in the member set' do let(:new_members) { [work1, work2, existing_work] } let(:new_member_ids) { [work1.id, work2.id, existing_work.id] } - it "updates the collection member set adding only resources not already in the member set" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array new_member_ids - end + + include_examples 'tests that set only contains new members' end + context 'and none of the new members exist in the member set' do - it "updates the collection member set adding the new members" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids + new_member_ids - end + include_examples 'tests for added member ids' end end end + shared_examples('tests that set has only existing members') do + it "the collection member set remains unchanged" do + expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids + end + end + describe '.add_member_by_id' do - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [] } - let(:existing_member_ids) { existing_members.map(&:id) } + include_context 'with two works and a collection with existing members' + include_context 'with existing members framework' let(:new_member_id) { work1.id } before { described_class.add_member_by_id(collection_id: collection.id, new_member_id: new_member_id, user: user) } context 'when no members' do - it "updates the collection member set to contain only the new members" do + it "updates the collection member set to contain only the new member" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array [new_member_id] end end + context 'when has members' do - let(:existing_work) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:existing_members) { [existing_work] } + include_context 'with existing new work' + context 'and the new member already exists in the member set' do let(:new_member_id) { existing_work.id } - it "the collection member set remains unchanged" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids - end + + include_examples 'tests that set has only existing members' end + context 'and the new member does not exist in the member set' do it "updates the collection member set adding the new member" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids + [new_member_id] @@ -134,56 +172,52 @@ end describe '.add_member' do - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [] } - let(:existing_member_ids) { existing_members.map(&:id) } + include_context 'with two works and a collection with existing members' + include_context 'with existing members framework' let(:new_member) { work1 } before { described_class.add_member(collection_id: collection.id, new_member: new_member, user: user) } context 'when no members' do - it "updates the collection member set to contain only the new members" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)) - .to match_array [new_member.id] + it "updates the collection member set to contain only the new member" do + expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array [new_member.id] end end + context 'when has members' do - let(:existing_work) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:existing_members) { [existing_work] } + include_context 'with existing new work' + context 'and the new member already exists in the member set' do let(:new_member) { existing_work } - it "the collection member set remains unchanged" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)) - .to match_array existing_member_ids - end + + include_examples 'tests that set has only existing members' end + context 'and the new member does not exist in the member set' do it "updates the collection member set adding the new work member" do - expect(custom_query_service.find_members_of(collection: collection) - .map(&:id)).to match_array existing_member_ids + [new_member.id] + expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids + [new_member.id] end + it "publishes object metadata updated event for work member" do - updated_work = described_class.add_member(collection_id: collection.id, - new_member: new_member, - user: user) - expect(listener.object_metadata_updated&.payload) - .to eq object: updated_work, user: user + updated_work = described_class.add_member(collection_id: collection.id, new_member: new_member, user: user) + + expect(listener.object_metadata_updated&.payload).to eq object: updated_work, user: user end end + context 'and the new member is a collection' do let(:child_collection) { FactoryBot.valkyrie_create(:hyrax_collection) } let(:new_member) { child_collection } + it "updates the collection member set adding the child collection" do - expect(custom_query_service.find_members_of(collection: collection) - .map(&:id)).to match_array existing_member_ids + [new_member.id] + expect(custom_query_service.find_members_of(collection: collection).map(&:id)) + .to(match_array(existing_member_ids + [new_member.id])) end + it "publishes collection metadata updated event for collection member" do - updated_collection = described_class.add_member(collection_id: collection.id, - new_member: new_member, - user: user) - expect(listener.collection_metadata_updated&.payload) - .to eq collection: updated_collection, user: user + updated_collection = described_class.add_member(collection_id: collection.id, new_member: new_member, user: user) + + expect(listener.collection_metadata_updated&.payload).to eq collection: updated_collection, user: user end end end @@ -210,35 +244,36 @@ end describe '.remove_members_by_ids' do - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [work1, work2] } - let(:existing_member_ids) { existing_members.map(&:id) } - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } + include_context 'with two works and a collection with existing members' + include_context 'with two existing works' let(:members_to_remove_ids) { [work1.id, work2.id] } context 'when no members' do let(:existing_members) { [] } + it "collection member remains empty" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] described_class.remove_members_by_ids(collection_id: collection.id, member_ids: members_to_remove_ids, user: user) - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] end end + context 'when has members' do context 'and none of the members to remove exist in the member set' do - let(:non_existing_work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:non_existing_work2) { FactoryBot.valkyrie_create(:hyrax_work) } + include_context 'with two non-existing works' let(:members_to_remove_ids) { [non_existing_work1.id, non_existing_work2.id] } + it "collection members remain unchanged" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_members_by_ids(collection_id: collection.id, member_ids: members_to_remove_ids, user: user) expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids end end + context 'and the members to remove exist in the member set' do let(:work3) { FactoryBot.valkyrie_create(:hyrax_work) } let(:existing_members) { [work1, work2, work3] } + it "updates the collection member set removing the members" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_members_by_ids(collection_id: collection.id, member_ids: members_to_remove_ids, user: user) @@ -248,35 +283,36 @@ end describe '.remove_members' do - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [work1, work2] } - let(:existing_member_ids) { existing_members.map(&:id) } - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } + include_context 'with two works and a collection with existing members' + include_context 'with two existing works' let(:members_to_remove) { [work1, work2] } context 'when no members' do let(:existing_members) { [] } + it "collection member remains empty" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] described_class.remove_members(collection_id: collection.id, members: members_to_remove, user: user) - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] end end + context 'when has members' do context 'and none of the members to remove exist in the member set' do - let(:non_existing_work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:non_existing_work2) { FactoryBot.valkyrie_create(:hyrax_work) } + include_context 'with two non-existing works' let(:members_to_remove) { [non_existing_work1, non_existing_work2] } + it "collection members remain unchanged" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_members(collection_id: collection.id, members: members_to_remove, user: user) expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids end end + context 'and the members to remove exist in the member set' do let(:work3) { FactoryBot.valkyrie_create(:hyrax_work) } let(:existing_members) { [work1, work2, work3] } + it "updates the collection member set removing the members" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_members(collection_id: collection.id, members: members_to_remove, user: user) @@ -288,31 +324,32 @@ end describe '.remove_member_by_id' do - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [work1, work2] } - let(:existing_member_ids) { existing_members.map(&:id) } - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } + include_context 'with two works and a collection with existing members' + include_context 'with two existing works' let(:member_to_remove_id) { work1.id } context 'when no members' do let(:existing_members) { [] } + it "collection member remains empty" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] described_class.remove_member_by_id(collection_id: collection.id, member_id: member_to_remove_id, user: user) - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] end end + context 'when has members' do context 'and the member to remove does not exist in the member set' do let(:non_existing_work1) { FactoryBot.valkyrie_create(:hyrax_work) } let(:member_to_remove_id) { non_existing_work1.id } + it "collection members remain unchanged" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_member_by_id(collection_id: collection.id, member_id: member_to_remove_id, user: user) expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids end end + context 'and the member to remove exists in the member set' do it "updates the collection member set removing the members" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids @@ -324,41 +361,43 @@ end describe '.remove_member' do - let!(:collection) { FactoryBot.valkyrie_create(:hyrax_collection, members: existing_members) } - let(:existing_members) { [work1, work2] } - let(:existing_member_ids) { existing_members.map(&:id) } - let(:work1) { FactoryBot.valkyrie_create(:hyrax_work) } - let(:work2) { FactoryBot.valkyrie_create(:hyrax_work) } + include_context 'with two works and a collection with existing members' + include_context 'with two existing works' let(:member_to_remove) { work1 } context 'when no members' do let(:existing_members) { [] } + it "collection member remains empty" do - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] described_class.remove_member(collection_id: collection.id, member: member_to_remove, user: user) - expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to eq [] + expect(custom_query_service.find_members_of(collection: collection).map(&:id).to_a).to eq [] end end + context 'when has members' do context 'and the member to remove does not exist in the member set' do let(:non_existing_work1) { FactoryBot.valkyrie_create(:hyrax_work) } let(:member_to_remove) { non_existing_work1 } + it "collection members remain unchanged" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_member(collection_id: collection.id, member: member_to_remove, user: user) expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids end end + context 'and the member to remove exists in the member set' do it "updates the collection member set removing the members" do expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array existing_member_ids described_class.remove_member(collection_id: collection.id, member: member_to_remove, user: user) expect(custom_query_service.find_members_of(collection: collection).map(&:id)).to match_array [work2.id] end + it "publishes metadata updated event for member" do updated_work = described_class.remove_member(collection_id: collection.id, member: member_to_remove, user: user) - expect(listener.object_metadata_updated&.payload) - .to eq object: updated_work, user: user + + expect(listener.object_metadata_updated&.payload).to eq object: updated_work, user: user end end end