diff --git a/app/logical/upload_limit.rb b/app/logical/upload_limit.rb index 752741d05..452e644fc 100644 --- a/app/logical/upload_limit.rb +++ b/app/logical/upload_limit.rb @@ -3,6 +3,7 @@ class UploadLimit INITIAL_POINTS = 1000 MAXIMUM_POINTS = 10_000 + APPEAL_COST = 3 attr_reader :user @@ -31,10 +32,15 @@ class UploadLimit end def used_upload_slots - pending = user.posts.pending - early_deleted = user.posts.deleted.where("created_at >= ?", 3.days.ago) + pending_count = user.posts.pending.count + appealed_count = user.post_appeals.pending.count + early_deleted_count = user.posts.deleted.where("created_at >= ?", 3.days.ago).count - pending.or(early_deleted).count + pending_count + early_deleted_count + (appealed_count * APPEAL_COST) + end + + def free_upload_slots + upload_slots - used_upload_slots end def upload_slots @@ -111,6 +117,4 @@ class UploadLimit points_for_next_level(n - 1) end.sum end - - memoize :used_upload_slots end diff --git a/app/models/post_appeal.rb b/app/models/post_appeal.rb index 5fe36eb5b..65536f478 100644 --- a/app/models/post_appeal.rb +++ b/app/models/post_appeal.rb @@ -1,8 +1,4 @@ class PostAppeal < ApplicationRecord - class Error < StandardError; end - - MAX_APPEALS_PER_DAY = 1 - belongs_to :creator, :class_name => "User" belongs_to :post @@ -33,19 +29,13 @@ class PostAppeal < ApplicationRecord extend SearchMethods def validate_creator_is_not_limited - if appeal_count_for_creator >= MAX_APPEALS_PER_DAY - errors[:creator] << "can appeal at most #{MAX_APPEALS_PER_DAY} post a day" - end + errors[:creator] << "have reached your appeal limit" if creator.is_appeal_limited? end def validate_post_is_appealable errors[:post] << "cannot be appealed" if post.is_status_locked? || !post.is_appealable? end - def appeal_count_for_creator - creator.post_appeals.recent.count - end - def self.available_includes [:creator, :post] end diff --git a/app/models/user.rb b/app/models/user.rb index be3db085d..c5cd85805 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -349,6 +349,11 @@ class User < ApplicationRecord end end + def is_appeal_limited? + return false if can_upload_free? + upload_limit.free_upload_slots < UploadLimit::APPEAL_COST + end + def upload_limit @upload_limit ||= UploadLimit.new(self) end diff --git a/test/unit/post_appeal_test.rb b/test/unit/post_appeal_test.rb index a37906ce2..7777bea68 100644 --- a/test/unit/post_appeal_test.rb +++ b/test/unit/post_appeal_test.rb @@ -3,37 +3,55 @@ require 'test_helper' class PostAppealTest < ActiveSupport::TestCase context "In all cases" do setup do - @alice = create(:user) + @user = create(:user, upload_points: 1000) end context "a user" do setup do - @post = FactoryBot.create(:post, :tag_string => "aaa", :is_deleted => true) + @post = create(:post, tag_string: "aaa", is_deleted: true) end - should "not be able to appeal a post more than twice" do - @post_appeal = create(:post_appeal, post: @post, creator: @alice) - @post_appeal = build(:post_appeal, post: @post, creator: @alice) + should "not be able to appeal a post more than once" do + @post_appeal = create(:post_appeal, post: @post, creator: @user) + @post_appeal = build(:post_appeal, post: @post, creator: @user) assert_equal(false, @post_appeal.valid?) assert_includes(@post_appeal.errors.full_messages, "You have already appealed this post") end - should "not be able to appeal more than 1 post in 24 hours" do - @post_appeal = create(:post_appeal, post: @post, creator: @alice) - @post_appeal = build(:post_appeal, post: create(:post, is_deleted: true), creator: @alice) - - assert_equal(false, @post_appeal.valid?) - assert_equal(["You can appeal at most 1 post a day"], @post_appeal.errors.full_messages) - end - should "not be able to appeal an active post" do - @post.update_attribute(:is_deleted, false) - @post_appeal = build(:post_appeal, post: @post, creator: @alice) + @post.update!(is_deleted: false) + @post_appeal = build(:post_appeal, post: @post, creator: @user) assert_equal(false, @post_appeal.valid?) assert_equal(["Post cannot be appealed"], @post_appeal.errors.full_messages) end + + context "appeal limits" do + context "for members" do + should "not be able to appeal more than their upload limit" do + create_list(:post_appeal, 5, creator: @user) + + assert_equal(15, @user.upload_limit.upload_slots) + assert_equal(15, @user.upload_limit.used_upload_slots) + + @post_appeal = build(:post_appeal, creator: @user) + assert_equal(false, @post_appeal.valid?) + assert_equal(["have reached your appeal limit"], @post_appeal.errors[:creator]) + end + end + + context "for users with unrestricted uploads" do + should "should not have an appeal limit" do + @user = create(:user, can_upload_free: true) + create_list(:post_appeal, 10, creator: @user) + + assert_equal(15, @user.upload_limit.upload_slots) + assert_equal(30, @user.upload_limit.used_upload_slots) + assert_equal(false, @user.is_appeal_limited?) + end + end + end end end end