FEATURE: Generous badge
This commit is contained in:
parent
cfe18c3f5b
commit
06591022fe
|
@ -75,9 +75,13 @@ class ApplicationController < ActionController::Base
|
|||
render 'default/empty'
|
||||
end
|
||||
|
||||
def render_rate_limit_error(e)
|
||||
render_json_error e.description, type: :rate_limit, status: 429
|
||||
end
|
||||
|
||||
# If they hit the rate limiter
|
||||
rescue_from RateLimiter::LimitExceeded do |e|
|
||||
render_json_error e.description, type: :rate_limit, status: 429
|
||||
render_rate_limit_error(e)
|
||||
end
|
||||
|
||||
rescue_from PG::ReadOnlySqlTransaction do |e|
|
||||
|
|
|
@ -23,6 +23,15 @@ class PostActionsController < ApplicationController
|
|||
@post.reload
|
||||
render_post_json(@post, _add_raw = false)
|
||||
end
|
||||
rescue RateLimiter::LimitExceeded => e
|
||||
# Special case: if we hit the create like rate limit, record it in user history
|
||||
# so we can award a badge
|
||||
if e.type == "create_like"
|
||||
UserHistory.create!(action: UserHistory.actions[:rate_limited_like],
|
||||
target_user_id: current_user.id,
|
||||
post_id: @post.id)
|
||||
end
|
||||
render_rate_limit_error(e)
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
|
@ -28,6 +28,7 @@ class Badge < ActiveRecord::Base
|
|||
FamousLink = 30
|
||||
Admired = 31
|
||||
GivesBack = 32
|
||||
Generous = 33
|
||||
|
||||
# other consts
|
||||
AutobiographerMinBioLength = 10
|
||||
|
@ -218,6 +219,14 @@ SQL
|
|||
HAVING us.likes_given::float / count(*) > 5.0
|
||||
SQL
|
||||
|
||||
Generous = <<-SQL
|
||||
SELECT uh.target_user_id AS user_id, MIN(uh.created_at) AS granted_at
|
||||
FROM user_histories AS uh
|
||||
WHERE uh.action = #{UserHistory.actions[:rate_limited_like]}
|
||||
AND (:backfill OR uh.target_user_id IN (:user_ids))
|
||||
GROUP BY uh.target_user_id
|
||||
SQL
|
||||
|
||||
def self.invite_badge(count,trust_level)
|
||||
"
|
||||
SELECT u.id user_id, current_timestamp granted_at
|
||||
|
|
|
@ -51,7 +51,8 @@ class UserHistory < ActiveRecord::Base
|
|||
revoke_admin: 33,
|
||||
grant_moderation: 34,
|
||||
revoke_moderation: 35,
|
||||
backup_operation: 36)
|
||||
backup_operation: 36,
|
||||
rate_limited_like: 37)
|
||||
end
|
||||
|
||||
# Staff actions is a subset of all actions, used to audit actions taken by staff users.
|
||||
|
|
|
@ -2970,6 +2970,9 @@ en:
|
|||
gives_back:
|
||||
name: Gives Back
|
||||
description: Has a high ratio of likes given to likes received
|
||||
generous:
|
||||
name: Generous
|
||||
description: Used the maximum amount of likes in a day
|
||||
|
||||
google_search: |
|
||||
<h3>Search with Google</h3>
|
||||
|
|
|
@ -316,6 +316,18 @@ Badge.seed do |b|
|
|||
b.system = true
|
||||
end
|
||||
|
||||
Badge.seed do |b|
|
||||
b.id = Badge::Generous
|
||||
b.default_name = "Generous"
|
||||
b.default_icon = "fa-heart"
|
||||
b.badge_type_id = BadgeType::Silver
|
||||
b.query = Badge::Queries::Generous
|
||||
b.default_badge_grouping_id = BadgeGrouping::Community
|
||||
b.trigger = Badge::Trigger::None
|
||||
b.auto_revoke = false
|
||||
b.system = true
|
||||
end
|
||||
|
||||
Badge.where("NOT system AND id < 100").each do |badge|
|
||||
new_id = [Badge.maximum(:id) + 1, 100].max
|
||||
old_id = badge.id
|
||||
|
|
|
@ -2,6 +2,7 @@ class RateLimiter
|
|||
|
||||
# A rate limit has been exceeded.
|
||||
class LimitExceeded < StandardError
|
||||
attr_reader :type
|
||||
|
||||
def initialize(available_in, type=nil)
|
||||
@available_in = available_in
|
||||
|
|
|
@ -94,10 +94,6 @@ describe RateLimiter do
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -7,7 +7,22 @@ describe PostActionsController do
|
|||
expect { xhr :post, :create }.to raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
describe 'logged in' do
|
||||
describe 'logged in as regular user' do
|
||||
before do
|
||||
@user = log_in(:user)
|
||||
@post = Fabricate(:post, user: Fabricate(:coding_horror))
|
||||
end
|
||||
|
||||
it 'creates user history if the rate limit for a like is hit' do
|
||||
PostAction.expects(:act).once.raises(RateLimiter::LimitExceeded.new(60, 'create_like'))
|
||||
expect(-> {
|
||||
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like]
|
||||
puts response.success?
|
||||
}).to change(UserHistory, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'logged in as moderator' do
|
||||
before do
|
||||
@user = log_in(:moderator)
|
||||
@post = Fabricate(:post, user: Fabricate(:coding_horror))
|
||||
|
|
Loading…
Reference in New Issue