Change Anniversary badge to be multiple grant, once per year
This commit is contained in:
parent
bb82e0a041
commit
f05f1a24d3
|
@ -0,0 +1,17 @@
|
|||
require_dependency 'jobs/scheduled/grant_anniversary_badges'
|
||||
|
||||
module Jobs
|
||||
|
||||
class RetroGrantAnniversary < Jobs::Onceoff
|
||||
def execute_onceoff(args)
|
||||
return unless SiteSetting.enable_badges
|
||||
|
||||
# Fill in the years of anniversary badges we missed
|
||||
(2..3).each do |year|
|
||||
Jobs::GrantAnniversaryBadges.new.execute(start_date: year.years.ago)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
module Jobs
|
||||
class GrantAnniversaryBadges < Jobs::Scheduled
|
||||
every 1.day
|
||||
|
||||
def execute(args)
|
||||
return unless SiteSetting.enable_badges?
|
||||
|
||||
start_date = args[:start_date] || 1.year.ago
|
||||
end_date = start_date + 1.year
|
||||
|
||||
fmt_end_date = end_date.iso8601(6)
|
||||
fmt_start_date = start_date.iso8601(6)
|
||||
|
||||
results = User.exec_sql <<~SQL
|
||||
SELECT u.id AS user_id
|
||||
FROM users AS u
|
||||
INNER JOIN posts AS p ON p.user_id = u.id
|
||||
INNER JOIN topics AS t ON p.topic_id = t.id
|
||||
LEFT OUTER JOIN user_badges AS ub ON ub.user_id = u.id AND
|
||||
ub.badge_id = #{Badge::Anniversary} AND
|
||||
ub.granted_at BETWEEN '#{fmt_start_date}' AND '#{fmt_end_date}'
|
||||
WHERE u.active AND
|
||||
NOT u.blocked AND
|
||||
NOT p.hidden AND
|
||||
p.deleted_at IS NULL AND
|
||||
t.visible AND
|
||||
t.archetype <> 'private_message' AND
|
||||
p.created_at BETWEEN '#{fmt_start_date}' AND '#{fmt_end_date}' AND
|
||||
u.created_at <= '#{fmt_start_date}'
|
||||
GROUP BY u.id
|
||||
HAVING COUNT(p.id) > 0 AND COUNT(ub.id) = 0
|
||||
SQL
|
||||
|
||||
badge = Badge.find(Badge::Anniversary)
|
||||
user_ids = results.map {|r| r['user_id'].to_i }
|
||||
|
||||
User.where(id: user_ids).each do |user|
|
||||
BadgeGranter.grant(badge, user, created_at: end_date)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -34,7 +34,7 @@ class Badge < ActiveRecord::Base
|
|||
NiceShare = 21
|
||||
GoodShare = 22
|
||||
GreatShare = 23
|
||||
OneYearAnniversary = 24
|
||||
Anniversary = 24
|
||||
|
||||
Promoter = 25
|
||||
Campaigner = 26
|
||||
|
|
|
@ -37,6 +37,7 @@ class BadgeGranter
|
|||
post_id: @post_id,
|
||||
seq: seq)
|
||||
|
||||
return unless SiteSetting.enable_badges
|
||||
if @granted_by != Discourse.system_user
|
||||
StaffActionLogger.new(@granted_by).log_badge_grant(user_badge)
|
||||
end
|
||||
|
|
|
@ -256,15 +256,16 @@ end
|
|||
end
|
||||
|
||||
Badge.seed do |b|
|
||||
b.id = Badge::OneYearAnniversary
|
||||
b.id = Badge::Anniversary
|
||||
b.name = "Anniversary"
|
||||
b.default_icon = "fa-clock-o"
|
||||
b.badge_type_id = BadgeType::Silver
|
||||
b.query = BadgeQueries::OneYearAnniversary
|
||||
b.default_badge_grouping_id = BadgeGrouping::Community
|
||||
b.query = nil
|
||||
b.trigger = Badge::Trigger::None
|
||||
b.auto_revoke = false
|
||||
b.system = true
|
||||
b.multiple_grant = true
|
||||
end
|
||||
|
||||
[
|
||||
|
|
|
@ -117,23 +117,6 @@ SQL
|
|||
(:backfill OR u.id IN (:user_ids) )
|
||||
SQL
|
||||
|
||||
# member for a year + has posted at least once during that year
|
||||
OneYearAnniversary = <<-SQL
|
||||
SELECT u.id AS user_id, MIN(u.created_at + interval '1 year') AS granted_at
|
||||
FROM users u
|
||||
JOIN posts p ON p.user_id = u.id
|
||||
WHERE u.id > 0
|
||||
AND u.active
|
||||
AND NOT u.blocked
|
||||
AND u.created_at + interval '1 year' < now()
|
||||
AND p.deleted_at IS NULL
|
||||
AND NOT p.hidden
|
||||
AND p.created_at + interval '1 year' > now()
|
||||
AND (:backfill OR u.id IN (:user_ids))
|
||||
GROUP BY u.id
|
||||
HAVING COUNT(p.id) > 0
|
||||
SQL
|
||||
|
||||
FirstMention = <<-SQL
|
||||
SELECT acting_user_id AS user_id, min(target_post_id) AS post_id, min(p.created_at) AS granted_at
|
||||
FROM user_actions
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
require 'rails_helper'
|
||||
require_dependency 'jobs/scheduled/grant_anniversary_badges'
|
||||
|
||||
describe Jobs::GrantAnniversaryBadges do
|
||||
|
||||
let(:granter) { described_class.new }
|
||||
|
||||
it "doesn't award to a user who is less than a year old" do
|
||||
user = Fabricate(:user, created_at: 1.month.ago)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award to an inactive user" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago, active: false)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award to a blocked user" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago, blocked: true)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award when a post is deleted" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago, deleted_at: 1.day.ago)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award when a post is hidden" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago, hidden: true)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award to PMs" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago)
|
||||
Fabricate(:private_message_post, user: user, created_at: 1.week.ago)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award to a user without a post" do
|
||||
user = Fabricate(:user, created_at: 1.month.ago)
|
||||
granter.execute({})
|
||||
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge).to be_blank
|
||||
end
|
||||
|
||||
it "doesn't award when badges are disabled" do
|
||||
SiteSetting.enable_badges = false
|
||||
|
||||
user = Fabricate(:user, created_at: 400.days.ago)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago)
|
||||
|
||||
granter.execute({})
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(0)
|
||||
end
|
||||
|
||||
it "awards the badge to a user with a post active for a year" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago)
|
||||
|
||||
granter.execute({})
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(1)
|
||||
end
|
||||
|
||||
context "repeated grants" do
|
||||
it "won't award twice in the same year" do
|
||||
user = Fabricate(:user, created_at: 400.days.ago)
|
||||
Fabricate(:post, user: user, created_at: 1.week.ago)
|
||||
|
||||
granter.execute({})
|
||||
granter.execute({})
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(1)
|
||||
end
|
||||
|
||||
it "will award again if a year has passed" do
|
||||
user = Fabricate(:user, created_at: 800.days.ago)
|
||||
Fabricate(:post, user: user, created_at: 450.days.ago)
|
||||
|
||||
Timecop.freeze(400.days.ago) do
|
||||
granter.execute({})
|
||||
end
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(1)
|
||||
|
||||
Fabricate(:post, user: user, created_at: 50.days.ago)
|
||||
granter.execute({})
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(2)
|
||||
end
|
||||
|
||||
it "supports date ranges" do
|
||||
user = Fabricate(:user, created_at: 3.years.ago)
|
||||
Fabricate(:post, user: user, created_at: 750.days.ago)
|
||||
|
||||
granter.execute(start_date: 800.days.ago)
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(1)
|
||||
|
||||
Fabricate(:post, user: user, created_at: 50.days.ago)
|
||||
granter.execute(start_date: 800.days.ago)
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(1)
|
||||
|
||||
granter.execute(start_date: 60.days.ago)
|
||||
badge = user.user_badges.where(badge_id: Badge::Anniversary)
|
||||
expect(badge.count).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
Loading…
Reference in New Issue