flags: raise flag limits.
The old flag limits were: * 1 flag per day for regular members. * 10 flags per day for Gold users. * Unlimited flags for approvers. The new flag limits are: * 10 flags in the modqueue at once for regular users. * Unlimited flags for approvers. * Unlimited flags for users with a high enough flag success rate. If you have at least 30 flags in the last 3 months, and you have at least a 70% flag success rate, then you get unlimited flags. 10 flags at once means you can have up to 10 flagged posts in the modqueue at the same time. Because flags stay in the modqueue for 3 days, this means you can flag on average 10 posts every 3 days, or just over 3 posts per day.
This commit is contained in:
@@ -12,7 +12,7 @@ class PostFlag < ApplicationRecord
|
|||||||
belongs_to :post
|
belongs_to :post
|
||||||
validates :reason, presence: true, length: { in: 1..140 }
|
validates :reason, presence: true, length: { in: 1..140 }
|
||||||
validate :validate_creator_is_not_limited, on: :create
|
validate :validate_creator_is_not_limited, on: :create
|
||||||
validate :validate_post
|
validate :validate_post, on: :create
|
||||||
validates_uniqueness_of :creator_id, scope: :post_id, on: :create, unless: :is_deletion, message: "have already flagged this post"
|
validates_uniqueness_of :creator_id, scope: :post_id, on: :create, unless: :is_deletion, message: "have already flagged this post"
|
||||||
before_save :update_post
|
before_save :update_post
|
||||||
attr_accessor :is_deletion
|
attr_accessor :is_deletion
|
||||||
@@ -26,7 +26,6 @@ class PostFlag < ApplicationRecord
|
|||||||
scope :by_users, -> { where.not(creator: User.system) }
|
scope :by_users, -> { where.not(creator: User.system) }
|
||||||
scope :by_system, -> { where(creator: User.system) }
|
scope :by_system, -> { where(creator: User.system) }
|
||||||
scope :in_cooldown, -> { by_users.where("created_at >= ?", COOLDOWN_PERIOD.ago) }
|
scope :in_cooldown, -> { by_users.where("created_at >= ?", COOLDOWN_PERIOD.ago) }
|
||||||
scope :recent, -> { where("post_flags.created_at >= ?", 1.day.ago) }
|
|
||||||
scope :expired, -> { pending.where("post_flags.created_at <= ?", 3.days.ago) }
|
scope :expired, -> { pending.where("post_flags.created_at <= ?", 3.days.ago) }
|
||||||
|
|
||||||
module SearchMethods
|
module SearchMethods
|
||||||
@@ -97,30 +96,18 @@ class PostFlag < ApplicationRecord
|
|||||||
end
|
end
|
||||||
|
|
||||||
def validate_creator_is_not_limited
|
def validate_creator_is_not_limited
|
||||||
return if is_deletion
|
errors[:creator] << "have reached your flag limit" if creator.is_flag_limited? && !is_deletion
|
||||||
|
|
||||||
if creator.can_approve_posts?
|
|
||||||
# do nothing
|
|
||||||
elsif creator.is_gold? && flag_count_for_creator >= 10
|
|
||||||
errors[:creator] << "can flag 10 posts a day"
|
|
||||||
elsif !creator.is_gold? && flag_count_for_creator >= 1
|
|
||||||
errors[:creator] << "can flag 1 post a day"
|
|
||||||
end
|
|
||||||
|
|
||||||
flag = post.flags.in_cooldown.last
|
|
||||||
if flag.present?
|
|
||||||
errors[:post] << "cannot be flagged more than once every #{COOLDOWN_PERIOD.inspect} (last flagged: #{flag.created_at.to_s(:long)})"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_post
|
def validate_post
|
||||||
errors[:post] << "is pending and cannot be flagged" if post.is_pending? && !is_deletion
|
errors[:post] << "is pending and cannot be flagged" if post.is_pending? && !is_deletion
|
||||||
errors[:post] << "is deleted and cannot be flagged" if post.is_deleted? && !is_deletion
|
errors[:post] << "is deleted and cannot be flagged" if post.is_deleted? && !is_deletion
|
||||||
errors[:post] << "is locked and cannot be flagged" if post.is_status_locked?
|
errors[:post] << "is locked and cannot be flagged" if post.is_status_locked?
|
||||||
end
|
|
||||||
|
|
||||||
def flag_count_for_creator
|
flag = post.flags.in_cooldown.last
|
||||||
creator.post_flags.recent.count
|
if flag.present?
|
||||||
|
errors[:post] << "cannot be flagged more than once every #{COOLDOWN_PERIOD.inspect} (last flagged: #{flag.created_at.to_s(:long)})"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def uploader_id
|
def uploader_id
|
||||||
|
|||||||
@@ -354,6 +354,21 @@ class User < ApplicationRecord
|
|||||||
upload_limit.free_upload_slots < UploadLimit::APPEAL_COST
|
upload_limit.free_upload_slots < UploadLimit::APPEAL_COST
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def is_flag_limited?
|
||||||
|
return false if has_unlimited_flags?
|
||||||
|
post_flags.pending.count >= 10
|
||||||
|
end
|
||||||
|
|
||||||
|
# Flags are unlimited if you're an approver or you have at least 30 flags
|
||||||
|
# in the last 3 months and have a 70% flag success rate.
|
||||||
|
def has_unlimited_flags?
|
||||||
|
return true if can_approve_posts?
|
||||||
|
|
||||||
|
recent_flags = post_flags.where("created_at >= ?", 3.months.ago)
|
||||||
|
flag_ratio = recent_flags.succeeded.count / recent_flags.count.to_f
|
||||||
|
recent_flags.count >= 30 && flag_ratio >= 0.70
|
||||||
|
end
|
||||||
|
|
||||||
def upload_limit
|
def upload_limit
|
||||||
@upload_limit ||= UploadLimit.new(self)
|
@upload_limit ||= UploadLimit.new(self)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,64 +3,36 @@ require 'test_helper'
|
|||||||
class PostApprovalTest < ActiveSupport::TestCase
|
class PostApprovalTest < ActiveSupport::TestCase
|
||||||
context "a pending post" do
|
context "a pending post" do
|
||||||
setup do
|
setup do
|
||||||
@user = FactoryBot.create(:user, created_at: 2.weeks.ago)
|
@user = create(:user, created_at: 2.weeks.ago)
|
||||||
CurrentUser.user = @user
|
@post = create(:post, uploader: @user, is_pending: true)
|
||||||
CurrentUser.ip_addr = "127.0.0.1"
|
@approver = create(:user, can_approve_posts: true)
|
||||||
|
|
||||||
@post = FactoryBot.create(:post, uploader_id: @user.id, tag_string: "touhou", is_pending: true)
|
|
||||||
|
|
||||||
@approver = FactoryBot.create(:user)
|
|
||||||
@approver.can_approve_posts = true
|
|
||||||
@approver.save
|
|
||||||
CurrentUser.user = @approver
|
|
||||||
|
|
||||||
CurrentUser.stubs(:can_approve_posts?).returns(true)
|
|
||||||
end
|
|
||||||
|
|
||||||
teardown do
|
|
||||||
CurrentUser.user = nil
|
|
||||||
CurrentUser.ip_addr = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "That is approved" do
|
context "That is approved" do
|
||||||
should "create a postapproval record" do
|
should "create a postapproval record" do
|
||||||
assert_difference("PostApproval.count") do
|
assert_difference("PostApproval.count") do
|
||||||
@post.approve!
|
@post.approve!(@approver)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "that is then flagged" do
|
should "prevent an approver from approving the same post twice" do
|
||||||
setup do
|
@approval1 = create(:post_approval, post: @post, user: @approver)
|
||||||
@user2 = create(:user, created_at: 2.weeks.ago)
|
@approval2 = build(:post_approval, post: @post, user: @approver)
|
||||||
@user3 = create(:user, created_at: 2.weeks.ago)
|
|
||||||
@approver2 = FactoryBot.create(:user)
|
|
||||||
@approver2.can_approve_posts = true
|
|
||||||
@approver2.save
|
|
||||||
end
|
|
||||||
|
|
||||||
should "prevent the first approver from approving again" do
|
assert_equal(false, @approval2.valid?)
|
||||||
@post.approve!(@approver)
|
assert_equal(["You have previously approved this post and cannot approve it again"], @approval2.errors[:base])
|
||||||
CurrentUser.user = @user2
|
|
||||||
@post.flag!("blah")
|
|
||||||
@post.approve!(@approver2)
|
|
||||||
assert_not_equal(@approver.id, @post.approver_id)
|
|
||||||
CurrentUser.user = @user3
|
|
||||||
travel(PostFlag::COOLDOWN_PERIOD + 1.minute) do
|
|
||||||
@post.flag!("blah blah")
|
|
||||||
end
|
|
||||||
|
|
||||||
approval = @post.approve!(@approver)
|
|
||||||
assert_includes(approval.errors.full_messages, "You have previously approved this post and cannot approve it again")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "#search method" do
|
context "#search method" do
|
||||||
should "work" do
|
should "work" do
|
||||||
@approval = @post.approve!(@approver)
|
CurrentUser.scoped(@approver) do
|
||||||
@approvals = PostApproval.search(user_name: @approver.name, post_tags_match: "touhou", post_id: @post.id)
|
@post.update!(tag_string: "touhou")
|
||||||
|
@approval = @post.approve!(@approver)
|
||||||
|
@approvals = PostApproval.search(user_name: @approver.name, post_tags_match: "touhou", post_id: @post.id)
|
||||||
|
|
||||||
assert_equal([@approval.id], @approvals.map(&:id))
|
assert_equal([@approval.id], @approvals.map(&:id))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,82 +1,75 @@
|
|||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class PostFlagTest < ActiveSupport::TestCase
|
class PostFlagTest < ActiveSupport::TestCase
|
||||||
context "In all cases" do
|
context "PostFlag: " do
|
||||||
setup do
|
context "an approver" do
|
||||||
travel_to(2.weeks.ago) do
|
should "be able to flag an unlimited number of posts" do
|
||||||
@alice = create(:gold_user)
|
@user = create(:user, can_approve_posts: true)
|
||||||
|
|
||||||
|
assert_nothing_raised do
|
||||||
|
create_list(:post_flag, 6, creator: @user, status: :pending)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
as(@alice) do
|
end
|
||||||
@post = create(:post, tag_string: "aaa", uploader: @alice)
|
|
||||||
|
context "a user with unlimited flags" do
|
||||||
|
should "be able to flag an unlimited number of posts" do
|
||||||
|
@user = create(:user)
|
||||||
|
create_list(:post_flag, 30, status: :succeeded, creator: @user)
|
||||||
|
|
||||||
|
assert_equal(true, @user.has_unlimited_flags?)
|
||||||
|
assert_equal(false, @user.is_flag_limited?)
|
||||||
|
|
||||||
|
assert_nothing_raised do
|
||||||
|
create_list(:post_flag, 11, creator: @user, status: :pending)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "a basic user" do
|
context "a basic user" do
|
||||||
should "not be able to flag more than 1 post in 24 hours" do
|
should "be able to flag up to 10 posts" do
|
||||||
@bob = create(:user, created_at: 2.weeks.ago)
|
@user = create(:user)
|
||||||
@post_flag = build(:post_flag, creator: @bob)
|
@flags = create_list(:post_flag, 10, creator: @user, status: :pending)
|
||||||
@post_flag.expects(:flag_count_for_creator).returns(1)
|
@flag = build(:post_flag, creator: @user, status: :pending)
|
||||||
|
|
||||||
assert_equal(false, @post_flag.valid?)
|
assert_equal(false, @flag.valid?)
|
||||||
assert_equal(["You can flag 1 post a day"], @post_flag.errors.full_messages)
|
assert_equal(["have reached your flag limit"], @flag.errors[:creator])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "a gold user" do
|
context "a user" do
|
||||||
setup do
|
should "not be able to flag a post more than once" do
|
||||||
@bob = create(:gold_user, created_at: 1.month.ago)
|
@user = create(:user)
|
||||||
end
|
@post = create(:post)
|
||||||
|
@post_flag = create(:post_flag, post: @post, creator: @user)
|
||||||
should "not be able to flag a post more than twice" do
|
@post_flag = build(:post_flag, post: @post, creator: @user)
|
||||||
@post_flag = create(:post_flag, post: @post, creator: @bob)
|
|
||||||
@post_flag = build(:post_flag, post: @post, creator: @bob)
|
|
||||||
|
|
||||||
assert_equal(false, @post_flag.valid?)
|
assert_equal(false, @post_flag.valid?)
|
||||||
assert_equal(["have already flagged this post"], @post_flag.errors[:creator_id])
|
assert_equal(["have already flagged this post"], @post_flag.errors[:creator_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
should "not be able to flag more than 10 posts in 24 hours" do
|
|
||||||
@post_flag = build(:post_flag, post: @post, creator: @bob)
|
|
||||||
@post_flag.expects(:flag_count_for_creator).returns(10)
|
|
||||||
|
|
||||||
assert_difference(-> { PostFlag.count }, 0) do
|
|
||||||
@post_flag.save
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal(["You can flag 10 posts a day"], @post_flag.errors.full_messages)
|
|
||||||
end
|
|
||||||
|
|
||||||
should "not be able to flag a deleted post" do
|
should "not be able to flag a deleted post" do
|
||||||
as(@alice) do
|
@post = create(:post, is_deleted: true)
|
||||||
@post.update(is_deleted: true)
|
@post_flag = build(:post_flag, post: @post)
|
||||||
end
|
|
||||||
|
|
||||||
@post_flag = build(:post_flag, post: @post, creator: @bob)
|
assert_equal(false, @post_flag.valid?)
|
||||||
@post_flag.save
|
|
||||||
assert_equal(["Post is deleted and cannot be flagged"], @post_flag.errors.full_messages)
|
assert_equal(["Post is deleted and cannot be flagged"], @post_flag.errors.full_messages)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "not be able to flag a pending post" do
|
should "not be able to flag a pending post" do
|
||||||
as(@alice) do
|
@post = create(:post, is_pending: true)
|
||||||
@post.update(is_pending: true)
|
@flag = build(:post_flag, post: @post)
|
||||||
end
|
|
||||||
@flag = @post.flags.create(reason: "test", creator: @bob)
|
|
||||||
|
|
||||||
|
assert_equal(false, @flag.valid?)
|
||||||
assert_equal(["Post is pending and cannot be flagged"], @flag.errors.full_messages)
|
assert_equal(["Post is pending and cannot be flagged"], @flag.errors.full_messages)
|
||||||
end
|
end
|
||||||
|
|
||||||
should "not be able to flag a post in the cooldown period" do
|
should "not be able to flag a post in the cooldown period" do
|
||||||
@mod = create(:moderator_user)
|
@mod = create(:moderator_user)
|
||||||
|
@users = create_list(:user, 2)
|
||||||
travel_to(2.weeks.ago) do
|
@post = create(:post)
|
||||||
@users = FactoryBot.create_list(:user, 2)
|
@flag1 = create(:post_flag, post: @post, creator: @users.first)
|
||||||
end
|
as(@mod) { @post.approve! }
|
||||||
|
|
||||||
@flag1 = create(:post_flag, post: @post, reason: "something", creator: @users.first)
|
|
||||||
|
|
||||||
as(@mod) do
|
|
||||||
@post.approve!
|
|
||||||
end
|
|
||||||
|
|
||||||
travel_to(PostFlag::COOLDOWN_PERIOD.from_now - 1.minute) do
|
travel_to(PostFlag::COOLDOWN_PERIOD.from_now - 1.minute) do
|
||||||
@flag2 = build(:post_flag, post: @post, reason: "something", creator: @users.second)
|
@flag2 = build(:post_flag, post: @post, reason: "something", creator: @users.second)
|
||||||
@@ -89,11 +82,6 @@ class PostFlagTest < ActiveSupport::TestCase
|
|||||||
assert(@flag3.errors.empty?)
|
assert(@flag3.errors.empty?)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
should "initialize its creator" do
|
|
||||||
@post_flag = create(:post_flag, creator: @alice)
|
|
||||||
assert_equal(@alice.id, @post_flag.creator_id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user