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
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
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)
render_serialized(user_badge, DetailedUserBadgeSerializer, root: :user_badge)
end

View File

@ -309,5 +309,31 @@ describe UserBadgesController do
user_badge = UserBadge.find_by(user: user, badge: badge)
expect(user_badge.is_favorite).to be false
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