diff --git a/app/controllers/admin/badge_achievements_controller.rb b/app/controllers/admin/badge_achievements_controller.rb
index 94ca4a49d..4c536b730 100644
--- a/app/controllers/admin/badge_achievements_controller.rb
+++ b/app/controllers/admin/badge_achievements_controller.rb
@@ -32,9 +32,14 @@ module Admin
end
usernames = permitted_params[:usernames].downcase.split(/\s*,\s*/)
+ include_default_description = permitted_params[:include_default_description] == "1"
message = permitted_params[:message_markdown].presence ||
I18n.t("admin.badge_achievements_controller.congrats", community: ::Settings::Community.community_name)
- BadgeAchievements::BadgeAwardWorker.perform_async(usernames, permitted_params[:badge], message)
+ BadgeAchievements::BadgeAwardWorker
+ .perform_async(usernames,
+ permitted_params[:badge],
+ message,
+ include_default_description)
flash[:success] = I18n.t("admin.badge_achievements_controller.rewarded")
redirect_to admin_badge_achievements_path
@@ -46,7 +51,7 @@ module Admin
private
def permitted_params
- params.permit(:usernames, :badge, :message_markdown)
+ params.permit(:usernames, :badge, :message_markdown, :include_default_description)
end
end
end
diff --git a/app/services/badges/award.rb b/app/services/badges/award.rb
index afdb3d1a6..a1c92d478 100644
--- a/app/services/badges/award.rb
+++ b/app/services/badges/award.rb
@@ -1,6 +1,6 @@
module Badges
class Award
- def self.call(user_relation, slug, message_markdown)
+ def self.call(user_relation, slug, message_markdown, include_default_description: true)
return unless (badge_id = Badge.id_for_slug(slug))
user_relation.find_each do |user|
@@ -9,6 +9,7 @@ module Badges
achievement = user.badge_achievements.create(
badge_id: badge_id,
rewarding_context_message_markdown: message_markdown,
+ include_default_description: include_default_description,
)
user.touch if achievement.persisted?
end
diff --git a/app/services/badges/award_first_post.rb b/app/services/badges/award_first_post.rb
index 8dc3ee4ac..55c9f2d71 100644
--- a/app/services/badges/award_first_post.rb
+++ b/app/services/badges/award_first_post.rb
@@ -6,6 +6,7 @@ module Badges
return unless (badge_id = Badge.id_for_slug(BADGE_SLUG))
Article.joins(:user)
+ .published
.where("articles.published_at > ?", 1.week.ago)
.where("articles.published_at < ?", 1.hour.ago)
.where("articles.score >= ?", 0)
diff --git a/app/services/notifications/new_badge_achievement/send.rb b/app/services/notifications/new_badge_achievement/send.rb
index 75ee7c5e1..7bacaccb1 100644
--- a/app/services/notifications/new_badge_achievement/send.rb
+++ b/app/services/notifications/new_badge_achievement/send.rb
@@ -27,6 +27,7 @@ module Notifications
attr_reader :badge_achievement
def json_data
+ description = badge_achievement.include_default_description ? badge_achievement.badge.description : nil
{
user: user_data(badge_achievement.user),
badge_achievement: {
@@ -34,7 +35,7 @@ module Notifications
rewarding_context_message: badge_achievement.rewarding_context_message,
badge: {
title: badge_achievement.badge.title,
- description: badge_achievement.badge.description,
+ description: description,
badge_image_url: badge_achievement.badge.badge_image_url,
credits_awarded: badge_achievement.badge.credits_awarded
}
diff --git a/app/views/admin/badge_achievements/award.html.erb b/app/views/admin/badge_achievements/award.html.erb
index 6e5bb6796..8dfd68d18 100644
--- a/app/views/admin/badge_achievements/award.html.erb
+++ b/app/views/admin/badge_achievements/award.html.erb
@@ -19,10 +19,17 @@
<%= f.label :message_markdown, "Override Default Message", class: "crayons-field__label" %>
- Supports Markdown
+ Supports Markdown. This overrides the "message" sent in notifications and emails, it does not override the badge description.
<%= f.text_area :message_markdown, size: "40x3", class: "crayons-textfield" %>
+
+ <%= f.check_box :include_default_description, checked: true %>
+ <%= f.label :include_default_description, "Include Default Description", class: "crayons-field__label pt-2" %>
+
+
+ If checked, the default badge description will be included above the message. If unchecked, only the message will be included.
+
<%= f.submit "Award Badges", class: "c-btn c-btn--primary" %>
diff --git a/app/views/mailers/notify_mailer/new_badge_email.html.erb b/app/views/mailers/notify_mailer/new_badge_email.html.erb
index 1f320eb0a..43f035546 100644
--- a/app/views/mailers/notify_mailer/new_badge_email.html.erb
+++ b/app/views/mailers/notify_mailer/new_badge_email.html.erb
@@ -5,9 +5,12 @@
-
- <%= @badge.description %>
-
+
+ <% if @badge_achievement.include_default_description %>
+
+ <%= @badge.description %>
+
+ <% end %>
<% if @badge_achievement.rewarding_context_message.present? %>
@@ -21,7 +24,7 @@
+ style="font-weight:bold;color:white;background:#4e57ef;padding: 12px 15px;border-radius:6px;text-decoration:none">
Check out your profile
diff --git a/app/views/mailers/notify_mailer/new_badge_email.text.erb b/app/views/mailers/notify_mailer/new_badge_email.text.erb
index 71fcc72ea..7ec9369e2 100644
--- a/app/views/mailers/notify_mailer/new_badge_email.text.erb
+++ b/app/views/mailers/notify_mailer/new_badge_email.text.erb
@@ -1,6 +1,6 @@
Congratulations, <%= @user.name %>! You got the <%= @badge.title %> badge! Be sure to check out your profile.
-<%= @badge.description %>
+<%= @badge.description if @badge_achievement.include_default_description %>
<%= strip_tags @badge_achievement.rewarding_context_message %>
diff --git a/app/views/notifications/_badgeachievement.html.erb b/app/views/notifications/_badgeachievement.html.erb
index 081ccc580..ec8fa2911 100644
--- a/app/views/notifications/_badgeachievement.html.erb
+++ b/app/views/notifications/_badgeachievement.html.erb
@@ -4,7 +4,9 @@
<%= t("views.notifications.badge.heading_html", badge: tag.strong(sanitize(json_data["badge_achievement"]["badge"]["title"]), class: "fw-bold")) %>
- <%= json_data["badge_achievement"]["badge"]["description"] %>
+ <% if json_data["badge_achievement"]["badge"]["description"] %>
+ <%= json_data["badge_achievement"]["badge"]["description"] %>
+ <% end %>
diff --git a/app/workers/badge_achievements/badge_award_worker.rb b/app/workers/badge_achievements/badge_award_worker.rb
index fc97e338b..2cc92d353 100644
--- a/app/workers/badge_achievements/badge_award_worker.rb
+++ b/app/workers/badge_achievements/badge_award_worker.rb
@@ -4,7 +4,7 @@ module BadgeAchievements
sidekiq_options queue: :high_priority, retry: 10
- def perform(usernames, badge_slug, message)
+ def perform(usernames, badge_slug, message, include_default_description = true) # rubocop:disable Style/OptionalBooleanParameter
if (award_class = "Badges::#{badge_slug.classify}".safe_constantize)
award_class.call
else
@@ -12,6 +12,7 @@ module BadgeAchievements
User.where(username: usernames),
badge_slug,
message,
+ include_default_description: include_default_description,
)
end
end
diff --git a/db/migrate/20240227181740_add_include_badge_description_in_email.rb b/db/migrate/20240227181740_add_include_badge_description_in_email.rb
new file mode 100644
index 000000000..2b82cb2ea
--- /dev/null
+++ b/db/migrate/20240227181740_add_include_badge_description_in_email.rb
@@ -0,0 +1,5 @@
+class AddIncludeBadgeDescriptionInEmail < ActiveRecord::Migration[7.0]
+ def change
+ add_column :badge_achievements, :include_default_description, :boolean, default: true, null: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 9983464bd..b4742e0e4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_02_12_142953) do
+ActiveRecord::Schema[7.0].define(version: 2024_02_27_181740) do
# These are extensions that must be enabled in order to support this database
enable_extension "citext"
enable_extension "ltree"
@@ -200,6 +200,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_02_12_142953) do
create_table "badge_achievements", force: :cascade do |t|
t.bigint "badge_id", null: false
t.datetime "created_at", precision: nil, null: false
+ t.boolean "include_default_description", default: true, null: false
t.bigint "rewarder_id"
t.text "rewarding_context_message"
t.text "rewarding_context_message_markdown"
diff --git a/spec/requests/admin/badge_achievements_spec.rb b/spec/requests/admin/badge_achievements_spec.rb
index c031ca557..b87c9f090 100644
--- a/spec/requests/admin/badge_achievements_spec.rb
+++ b/spec/requests/admin/badge_achievements_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe "/admin/content_manager/badge_achievements" do
message_markdown: "you got a badge nice one"
}
expect(BadgeAchievements::BadgeAwardWorker).to have_received(:perform_async).with(
- usernames_array, badge.slug, "you got a badge nice one"
+ usernames_array, badge.slug, "you got a badge nice one", false
)
expect(request.flash[:success]).to include("Badges are being rewarded. The task will finish shortly.")
end
@@ -60,7 +60,10 @@ RSpec.describe "/admin/content_manager/badge_achievements" do
message_markdown: "Hinder me? Thou fool. No living man may hinder me!"
}
expect(BadgeAchievements::BadgeAwardWorker).to have_received(:perform_async).with(
- usernames_array, badge.slug, "Hinder me? Thou fool. No living man may hinder me!"
+ usernames_array,
+ badge.slug,
+ "Hinder me? Thou fool. No living man may hinder me!",
+ false,
)
expect(request.flash[:success]).to include("Badges are being rewarded. The task will finish shortly.")
end
@@ -72,9 +75,43 @@ RSpec.describe "/admin/content_manager/badge_achievements" do
usernames: usernames_string,
message_markdown: ""
}
- expect(BadgeAchievements::BadgeAwardWorker).to have_received(:perform_async).with(usernames_array,
- badge.slug,
- expected_message)
+ expect(BadgeAchievements::BadgeAwardWorker)
+ .to have_received(:perform_async).with(usernames_array,
+ badge.slug,
+ expected_message,
+ false)
+ expect(request.flash[:success]).to include("Badges are being rewarded. The task will finish shortly.")
+ end
+
+ it "includes default description if passed as true" do
+ allow(BadgeAchievements::BadgeAwardWorker).to receive(:perform_async)
+ post admin_badge_achievements_award_badges_path, params: {
+ badge: badge.slug,
+ usernames: usernames_string,
+ message_markdown: "",
+ include_default_description: "1"
+ }
+ expect(BadgeAchievements::BadgeAwardWorker)
+ .to have_received(:perform_async).with(usernames_array,
+ badge.slug,
+ expected_message,
+ true)
+ expect(request.flash[:success]).to include("Badges are being rewarded. The task will finish shortly.")
+ end
+
+ it "does not include default description if passed as false" do
+ allow(BadgeAchievements::BadgeAwardWorker).to receive(:perform_async)
+ post admin_badge_achievements_award_badges_path, params: {
+ badge: badge.slug,
+ usernames: usernames_string,
+ message_markdown: "",
+ include_default_description: "0"
+ }
+ expect(BadgeAchievements::BadgeAwardWorker)
+ .to have_received(:perform_async).with(usernames_array,
+ badge.slug,
+ expected_message,
+ false)
expect(request.flash[:success]).to include("Badges are being rewarded. The task will finish shortly.")
end
@@ -83,8 +120,11 @@ RSpec.describe "/admin/content_manager/badge_achievements" do
usernames: usernames_string,
message_markdown: ""
}
- expect(BadgeAchievements::BadgeAwardWorker).not_to have_received(:perform_async).with(usernames_array,
- badge.slug, "")
+ expect(BadgeAchievements::BadgeAwardWorker)
+ .not_to have_received(:perform_async).with(usernames_array,
+ badge.slug,
+ "",
+ false)
end
it "does not award a badge if the username provided is not lowercase" do
@@ -93,8 +133,11 @@ RSpec.describe "/admin/content_manager/badge_achievements" do
usernames: user.username.upcase,
message_markdown: ""
}
- expect(BadgeAchievements::BadgeAwardWorker).not_to have_received(:perform_async).with(user.username.upcase,
- badge.slug, "")
+ expect(BadgeAchievements::BadgeAwardWorker)
+ .not_to have_received(:perform_async).with(user.username.upcase,
+ badge.slug,
+ "",
+ false)
end
end
diff --git a/spec/services/badges/award_spec.rb b/spec/services/badges/award_spec.rb
index 01b86fae4..248dcb6a1 100644
--- a/spec/services/badges/award_spec.rb
+++ b/spec/services/badges/award_spec.rb
@@ -8,21 +8,31 @@ RSpec.describe Badges::Award, type: :service do
it "awards badges" do
expect do
- described_class.call(User.all, "one-year-club", "Congrats on a badge!")
+ described_class.call(User.all, "one-year-club", "Congrats on a badge!", include_default_description: true)
end.to change(BadgeAchievement, :count).by(2)
end
it "creates correct badge achievements" do
- described_class.call(User.all, "one-year-club", "Congrats on a badge!")
+ described_class.call(User.all, "one-year-club", "Congrats on a badge!", include_default_description: true)
expect(user.badge_achievements.pluck(:badge_id)).to eq([badge.id])
expect(user2.badge_achievements.pluck(:rewarding_context_message_markdown))
.to eq(["Congrats on a badge!"])
end
+ it "creates correct badge achievements without default description" do
+ described_class.call(User.all, "one-year-club", "Congrats on a badge!", include_default_description: false)
+ expect(user.badge_achievements.pluck(:include_default_description)).to eq([false])
+ end
+
+ it "creates correct badge achievements with default description" do
+ described_class.call(User.all, "one-year-club", "Congrats on a badge!", include_default_description: true)
+ expect(user.badge_achievements.pluck(:include_default_description)).to eq([true])
+ end
+
it "doesn't award badges to spam accounts" do
spammer = create(:user, username: "spam_account")
- described_class.call(User.all, "one-year-club", "Congrats on a badge!")
+ described_class.call(User.all, "one-year-club", "Congrats on a badge!", include_default_description: true)
expect(user.badge_achievements.any?).to be true
expect(spammer.badge_achievements.any?).to be false
end
diff --git a/spec/workers/badge_achievements/badge_award_worker_spec.rb b/spec/workers/badge_achievements/badge_award_worker_spec.rb
index f2227c53e..6c351ec92 100644
--- a/spec/workers/badge_achievements/badge_award_worker_spec.rb
+++ b/spec/workers/badge_achievements/badge_award_worker_spec.rb
@@ -15,16 +15,16 @@ RSpec.describe BadgeAchievements::BadgeAwardWorker, type: :worker do
it "sends badge email" do
relation = User.none
allow(User).to receive(:where).with(username: ["jess"]).and_return(relation)
- worker.perform(["jess"], "test", "yo")
+ worker.perform(["jess"], "test", "yo", false)
- expect(Badges::Award).to have_received(:call).with(relation, "test", "yo")
+ expect(Badges::Award).to have_received(:call).with(relation, "test", "yo", include_default_description: false)
end
end
context "with predefined badge_slug" do
it "sends badge email" do
allow(Badges::AwardYearlyClub).to receive(:call)
- worker.perform([], "award_yearly_club", "")
+ worker.perform([], "award_yearly_club", "", true)
expect(Badges::AwardYearlyClub).to have_received(:call)
expect(Badges::Award).not_to have_received(:call)