diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb index d2e92f63086..ade3e97db9f 100644 --- a/app/services/user_updater.rb +++ b/app/services/user_updater.rb @@ -62,8 +62,13 @@ class UserUpdater user.locale = attributes.fetch(:locale) { user.locale } user.date_of_birth = attributes.fetch(:date_of_birth) { user.date_of_birth } - if guardian.can_grant_title?(user) - user.title = attributes.fetch(:title) { user.title } + if attributes[:title] && + attributes[:title] != user.title && + guardian.can_grant_title?(user, attributes[:title]) + user.title = attributes[:title] + if user.badges.where(name: user.title).exists? + user_profile.badge_granted_title = true + end end CATEGORY_IDS.each do |attribute, level| diff --git a/lib/guardian.rb b/lib/guardian.rb index d7b3e3fe93f..baa26363aa3 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -221,6 +221,7 @@ class Guardian def can_grant_title?(user, title = nil) return true if user && is_staff? + return false if title.nil? return false if user != @user return true if user.badges.where(name: title, allow_title: true).exists? user.groups.where(title: title).exists? diff --git a/spec/services/user_updater_spec.rb b/spec/services/user_updater_spec.rb index a65004ed7e3..14d820d488e 100644 --- a/spec/services/user_updater_spec.rb +++ b/spec/services/user_updater_spec.rb @@ -159,7 +159,7 @@ describe UserUpdater do it 'allows user to change title' do user = Fabricate(:user, title: 'Emperor') guardian = stub - guardian.stubs(:can_grant_title?).with(user).returns(true) + guardian.stubs(:can_grant_title?).with(user, 'Minion').returns(true) Guardian.stubs(:new).with(acting_user).returns(guardian) updater = UserUpdater.new(acting_user, user) @@ -169,11 +169,63 @@ describe UserUpdater do end end + context 'title is from a badge' do + let(:user) { Fabricate(:user, title: 'Emperor') } + let(:badge) { Fabricate(:badge, name: 'Minion') } + + context 'badge can be used as a title' do + before do + badge.update_attributes(allow_title: true) + end + + it 'can use as title, sets badge_granted_title' do + BadgeGranter.grant(badge, user) + updater = UserUpdater.new(user, user) + updater.update(title: badge.name) + user.reload + expect(user.user_profile.badge_granted_title).to eq(true) + end + + it 'badge has not been granted, does not change title' do + badge.update_attributes(allow_title: true) + updater = UserUpdater.new(user, user) + updater.update(title: badge.name) + user.reload + expect(user.title).not_to eq(badge.name) + expect(user.user_profile.badge_granted_title).to eq(false) + end + + it 'changing to a title that is not from a badge, unsets badge_granted_title' do + user.update_attributes(title: badge.name) + user.user_profile.update_attributes(badge_granted_title: true) + + guardian = stub + guardian.stubs(:can_grant_title?).with(user, 'Dancer').returns(true) + Guardian.stubs(:new).with(user).returns(guardian) + + updater = UserUpdater.new(user, user) + updater.update(title: 'Dancer') + user.reload + expect(user.title).to eq('Dancer') + expect(user.user_profile.badge_granted_title).to eq(false) + end + end + + it 'cannot use as title, does not change title' do + BadgeGranter.grant(badge, user) + updater = UserUpdater.new(user, user) + updater.update(title: badge.name) + user.reload + expect(user.title).not_to eq(badge.name) + expect(user.user_profile.badge_granted_title).to eq(false) + end + end + context 'without permission to update title' do it 'does not allow user to change title' do user = Fabricate(:user, title: 'Emperor') guardian = stub - guardian.stubs(:can_grant_title?).with(user).returns(false) + guardian.stubs(:can_grant_title?).with(user, 'Minion').returns(false) Guardian.stubs(:new).with(acting_user).returns(guardian) updater = UserUpdater.new(acting_user, user)