FIX: Make favorite work with multiple grant badges (#13492)

Badges that are awarded multiple times can be favorite and not favorite
at the same time. This caused few problems when users tried to favorite
them as they were counted multiple times or their state was incorrectly
displayed.
This commit is contained in:
Bianca Nenciu 2021-06-23 14:41:23 +03:00 committed by GitHub
parent d3a3d1b94c
commit a22aa7562a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 2 deletions

View File

@ -105,11 +105,13 @@ class UserBadgesController < ApplicationController
return render json: failed_json, status: 403 return render json: failed_json, status: 403
end end
if !user_badge.is_favorite && user_badges.where(is_favorite: true).count >= SiteSetting.max_favorite_badges if !user_badge.is_favorite && user_badges.select(:badge_id).distinct.where(is_favorite: true).count >= SiteSetting.max_favorite_badges
return render json: failed_json, status: 400 return render json: failed_json, status: 400
end end
user_badge.toggle!(:is_favorite) UserBadge
.where(user_id: user_badge.user_id, badge_id: user_badge.badge_id)
.update(is_favorite: !user_badge.is_favorite)
UserBadge.update_featured_ranks!(user_badge.user_id) UserBadge.update_featured_ranks!(user_badge.user_id)
render_serialized(user_badge, DetailedUserBadgeSerializer, root: :user_badge) render_serialized(user_badge, DetailedUserBadgeSerializer, root: :user_badge)
end end

View File

@ -309,5 +309,31 @@ describe UserBadgesController do
user_badge = UserBadge.find_by(user: user, badge: badge) user_badge = UserBadge.find_by(user: user, badge: badge)
expect(user_badge.is_favorite).to be false expect(user_badge.is_favorite).to be false
end end
it "works with multiple grants" do
SiteSetting.max_favorite_badges = 2
sign_in(user)
badge = Fabricate(:badge, multiple_grant: true)
user_badge = UserBadge.create(badge: badge, user: user, granted_by: Discourse.system_user, granted_at: Time.now, seq: 0, is_favorite: true)
user_badge2 = UserBadge.create(badge: badge, user: user, granted_by: Discourse.system_user, granted_at: Time.now, seq: 1, is_favorite: true)
other_badge = Fabricate(:badge)
other_user_badge = UserBadge.create(badge: other_badge, user: user, granted_by: Discourse.system_user, granted_at: Time.now)
put "/user_badges/#{user_badge.id}/toggle_favorite.json"
expect(response.status).to eq(200)
expect(user_badge.reload.is_favorite).to eq(false)
expect(user_badge2.reload.is_favorite).to eq(false)
put "/user_badges/#{user_badge.id}/toggle_favorite.json"
expect(response.status).to eq(200)
expect(user_badge.reload.is_favorite).to eq(true)
expect(user_badge2.reload.is_favorite).to eq(true)
put "/user_badges/#{other_user_badge.id}/toggle_favorite.json"
expect(response.status).to eq(200)
expect(other_user_badge.reload.is_favorite).to eq(true)
end
end end
end end