diff --git a/app/contracts/members/delete_contract.rb b/app/contracts/members/delete_contract.rb index bd8d14803cbc..4d71ee1fe302 100644 --- a/app/contracts/members/delete_contract.rb +++ b/app/contracts/members/delete_contract.rb @@ -35,7 +35,7 @@ class DeleteContract < ::DeleteContract private def member_is_deletable - errors.add(:base, :not_deletable) unless model.deletable? + errors.add(:base, :not_deletable) unless model.some_roles_deletable? end end end diff --git a/app/contracts/work_package_members/delete_contract.rb b/app/contracts/work_package_members/delete_contract.rb index 554caf743d50..41726467fa50 100644 --- a/app/contracts/work_package_members/delete_contract.rb +++ b/app/contracts/work_package_members/delete_contract.rb @@ -35,7 +35,7 @@ class DeleteContract < ::DeleteContract private def member_is_deletable - errors.add(:base, :not_deletable) unless model.deletable? + errors.add(:base, :not_deletable) unless model.some_roles_deletable? end end end diff --git a/app/models/member.rb b/app/models/member.rb index 566acc3adfd6..2fa3251d31b8 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -77,6 +77,10 @@ def <=>(other) end def deletable? + member_roles.none?(&:inherited_from?) + end + + def some_roles_deletable? !member_roles.all?(&:inherited_from?) end diff --git a/spec/contracts/members/delete_contract_spec.rb b/spec/contracts/members/delete_contract_spec.rb index 057a24ff7239..d1e9045010f0 100644 --- a/spec/contracts/members/delete_contract_spec.rb +++ b/spec/contracts/members/delete_contract_spec.rb @@ -60,7 +60,7 @@ context 'when member is not deletable' do before do - allow(member).to receive(:deletable?).and_return(false) + allow(member).to receive(:some_roles_deletable?).and_return(false) end context 'for admin' do diff --git a/spec/contracts/work_package_members/delete_contract_spec.rb b/spec/contracts/work_package_members/delete_contract_spec.rb index 518dfffd23cb..90d31f45527e 100644 --- a/spec/contracts/work_package_members/delete_contract_spec.rb +++ b/spec/contracts/work_package_members/delete_contract_spec.rb @@ -67,7 +67,7 @@ context 'when member is not deletable' do before do - allow(member).to receive(:deletable?).and_return(false) + allow(member).to receive(:some_roles_deletable?).and_return(false) end context 'for admin' do diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 91362a42ef4b..9399930124fa 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -55,17 +55,39 @@ end describe '#deletable?' do - it 'is deletable, when no roles are inherited' do + it 'is true, when no roles are inherited' do member.member_roles.first.inherited_from = nil expect(member).to be_deletable end - it 'is not deletable, when roles are inherited' do + it 'is false, when roles are inherited' do member.member_roles.first.inherited_from = 1 expect(member).not_to be_deletable end end + describe '#some_roles_deletable?' do + before do + member.roles << project_role + end + + it 'is true, when no roles are inherited' do + member.member_roles.first.inherited_from = nil + expect(member).to be_some_roles_deletable + end + + it 'is true, when not all roles are inherited' do + member.member_roles.first.inherited_from = 1 + expect(member).to be_some_roles_deletable + end + + it 'is false, when all roles are inherited' do + member.member_roles.first.inherited_from = 1 + member.member_roles.second.inherited_from = 1 + expect(member).not_to be_some_roles_deletable + end + end + describe '#deletable_role?' do it 'can delete directly assigned roles, but not if role is inherited through a group membership' do # user has the global_role by directly being assigned