Automatically reward thumbs-up milestone badges (#20338)
* initial work on #20111 * initial work on #20111 * fix cron * is this a good test * add in initial check, fix test data * Update spec --------- Co-authored-by: Mac Siri <krairit.siri@gmail.com>
This commit is contained in:
parent
9c268e3ca5
commit
779701d5f6
5 changed files with 93 additions and 0 deletions
55
app/services/badges/award_thumbs_up.rb
Normal file
55
app/services/badges/award_thumbs_up.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
module Badges
|
||||
class AwardThumbsUp
|
||||
THUMBS_UP_BADGES = {
|
||||
100 => "100 Thumbs Up Milestone",
|
||||
500 => "500 Thumbs Up Milestone",
|
||||
1000 => "1,000 Thumbs Up Milestone",
|
||||
5000 => "5,000 Thumbs Up Milestone",
|
||||
10_000 => "10,000 Thumbs Up Milestone"
|
||||
}.freeze
|
||||
|
||||
MIN_THRESHOLD = THUMBS_UP_BADGES.keys.min
|
||||
|
||||
def self.call
|
||||
badge_ids = fetch_badge_ids
|
||||
|
||||
# Early return if any badge is not found
|
||||
return if badge_ids.values.any?(&:nil?)
|
||||
|
||||
user_thumbsup_counts = get_user_thumbsup_counts
|
||||
|
||||
user_thumbsup_counts.each do |user_id, count|
|
||||
THUMBS_UP_BADGES.each do |threshold, _|
|
||||
break unless count >= threshold
|
||||
|
||||
badge_id = badge_ids[threshold]
|
||||
next unless badge_id
|
||||
next unless (user = User.find_by(id: user_id))
|
||||
|
||||
user.badge_achievements.create(
|
||||
badge_id: badge_id,
|
||||
rewarding_context_message_markdown: generate_message(threshold: threshold),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_user_thumbsup_counts
|
||||
Reaction.where(category: "thumbsup", reactable_type: "Article")
|
||||
.group(:user_id)
|
||||
.having("COUNT(*) >= ?", MIN_THRESHOLD)
|
||||
.order(Arel.sql("COUNT(*) DESC"))
|
||||
.count
|
||||
end
|
||||
|
||||
def self.fetch_badge_ids
|
||||
THUMBS_UP_BADGES.transform_values do |title|
|
||||
Badge.find_by(title: title)&.id
|
||||
end
|
||||
end
|
||||
|
||||
def self.generate_message(threshold:)
|
||||
I18n.t("services.badges.thumbs_up", count: threshold)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -31,6 +31,7 @@ en:
|
|||
first: Thank you for participating in constructive conversation! You posted two or more comments this week. Keep it up to continue the streak!
|
||||
longest: 32 weeks! You've achieved the longest streak possible for the Community Wellness badge. Amazing job engaging in the community and keep up your amazing contributions to our community!
|
||||
other: Congrats on achieving a %{weeks} week streak for the Community Wellness Badge! Keep the constructive comments flowing to continue the streak!
|
||||
thumbs_up: Thank you for your efforts reviewing posts on and reaching %{count} thumbs-up reactions!
|
||||
broadcasts:
|
||||
welcome_notification:
|
||||
generator:
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ fr:
|
|||
first: Merci de participer à une conversation constructive ! Vous avez posté deux commentaires ou plus cette semaine. Continuez comme ça pour poursuivre la série !
|
||||
longest: 32 semaines ! Vous avez atteint la plus longue période possible pour l'insigne du bien-être communautaire. Vous avez fait un travail remarquable en vous engageant dans la communauté et continuez à apporter votre contribution à notre communauté !
|
||||
other: Félicitations pour avoir atteint une série de %{weeks} semaines pour l'insigne du bien-être communautaire ! Continuez à envoyer des commentaires constructifs pour que la série continue !
|
||||
thumbs_up: Merci pour vos efforts en examinant les messages et en obtenant %{count} réactions positives!
|
||||
broadcasts:
|
||||
welcome_notification:
|
||||
generator:
|
||||
|
|
|
|||
|
|
@ -86,6 +86,14 @@ award_community_wellness_badges:
|
|||
- ""
|
||||
- award_community_wellness
|
||||
- ""
|
||||
award_thumbs_up_badges:
|
||||
description: "Awards Thumbs Up Milestone badge to users (runs daily at 01:00 UTC) "
|
||||
cron: "0 1 * * *"
|
||||
class: "BadgeAchievements::BadgeAwardWorker"
|
||||
args:
|
||||
- ""
|
||||
- award_thumbs_up
|
||||
- ""
|
||||
resave_supported_tags:
|
||||
description: "Resaves supported tags to recalculate scores (runs daily at 00:25 UTC)"
|
||||
cron: "25 0 * * *"
|
||||
|
|
|
|||
28
spec/services/badges/award_thumbs_up_spec.rb
Normal file
28
spec/services/badges/award_thumbs_up_spec.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Badges::AwardThumbsUp, type: :service do
|
||||
let(:thumbs_up_tiers) { described_class::THUMBS_UP_BADGES.keys }
|
||||
|
||||
it "does nothing if there are no thumbsup badges" do
|
||||
user = create(:user)
|
||||
allow(described_class).to receive(:get_user_thumbsup_counts).and_return(user.id => thumbs_up_tiers.max)
|
||||
|
||||
expect { described_class.call }.not_to change { user.badges.count }
|
||||
end
|
||||
|
||||
it "awards the correct badge to the correct user" do
|
||||
all_badges = described_class::THUMBS_UP_BADGES.map do |_, badge_title|
|
||||
create(:badge, title: badge_title)
|
||||
end
|
||||
ghost_user = create(:user)
|
||||
user = create(:user)
|
||||
prolific_user = create(:user)
|
||||
|
||||
allow(described_class).to receive(:get_user_thumbsup_counts)
|
||||
.and_return(user.id => thumbs_up_tiers.min, prolific_user.id => thumbs_up_tiers.max)
|
||||
described_class.call
|
||||
expect(ghost_user.badges.count).to eq(0)
|
||||
expect(user.badges).to eq([Badge.find_by(title: described_class::THUMBS_UP_BADGES[thumbs_up_tiers.min])])
|
||||
expect(prolific_user.badges).to eq(all_badges)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue