From 1cac9fa257331decc33f53cdff1b43fa9467e27a Mon Sep 17 00:00:00 2001 From: Robin Ward <robin.ward@gmail.com> Date: Thu, 19 Dec 2013 13:45:55 -0500 Subject: [PATCH] New users can only post `newuser_max_replies_per_topic` times per topic. --- app/assets/stylesheets/desktop/compose.scss | 6 +++++- app/models/user.rb | 5 +++++ config/locales/server.en.yml | 10 ++++++++++ config/site_settings.yml | 1 + lib/composer_messages_finder.rb | 7 +++++++ lib/validators/post_validator.rb | 7 +++++++ .../composer_messages_finder_spec.rb | 19 +++++++++++++++++++ .../validators/post_validator_spec.rb | 14 ++++++++++++++ 8 files changed, 68 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/desktop/compose.scss b/app/assets/stylesheets/desktop/compose.scss index c4b46c501..30a63b3fa 100644 --- a/app/assets/stylesheets/desktop/compose.scss +++ b/app/assets/stylesheets/desktop/compose.scss @@ -18,8 +18,12 @@ @include box-shadow(3px 3px 3px rgba($black, 0.14)); + h3 { + margin-bottom: 10px; + } + p { - margin: 0 0 10px 0; + margin-bottom: 10px; } a.close { diff --git a/app/models/user.rb b/app/models/user.rb index f175dfd03..4e4831c35 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -143,6 +143,7 @@ class User < ActiveRecord::Base where(username_lower: username.downcase).first end + def enqueue_welcome_message(message_type) return unless SiteSetting.send_welcome_message? Jobs.enqueue(:send_system_message, user_id: id, message_type: message_type) @@ -340,6 +341,10 @@ class User < ActiveRecord::Base topics_allowed.where(archetype: Archetype.private_message).count end + def posted_too_much_in_topic?(topic_id) + trust_level == TrustLevel.levels[:newuser] && (Post.where(topic_id: topic_id, user_id: id).count >= SiteSetting.newuser_max_replies_per_topic) + end + def bio_excerpt excerpt = PrettyText.excerpt(bio_cooked, 350) return excerpt if excerpt.blank? || has_trust_level?(:basic) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index de9d54678..1c54ddbf0 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -27,6 +27,8 @@ en: site_under_maintenance: 'Site is currently undergoing maintenance.' operation_already_running: "An %{operation} is currently running. Can't start a new %{operation} job right now." + too_many_replies: "Sorry you can't reply any more times in that topic." + too_many_mentions: zero: "Sorry, you can't mention other users." one: "Sorry, you can only mention one other user in a post." @@ -132,6 +134,13 @@ en: Are you sure you're providing adequate time for other people to share their points of view, too? + too_many_replies: | + ### You've replied too many times to this topic + + Sorry, but new users are limited to %{newuser_max_replies_per_topic} replies in a topic. + + You should consider editing one of your previous replies instead of a new reply. + activerecord: attributes: category: @@ -667,6 +676,7 @@ en: newuser_max_images: "How many images a new user can add to a post" newuser_max_attachments: "How many attachments a new user can add to a post" newuser_max_mentions_per_post: "Maximum number of @name notifications a new user can use in a post" + newuser_max_replies_per_topic: "Maximum number of replies a new user can make in a single topic" max_mentions_per_post: "Maximum number of @name notifications you can use in a post" create_thumbnails: "Create thumbnails for lightboxed images" diff --git a/config/site_settings.yml b/config/site_settings.yml index 4b1bbe40c..286d6e575 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -177,6 +177,7 @@ posting: default: true post_undo_action_window_mins: 10 max_mentions_per_post: 10 + newuser_max_replies_per_topic: 3 newuser_max_mentions_per_post: 2 onebox_max_chars: 5000 title_min_entropy: 10 diff --git a/lib/composer_messages_finder.rb b/lib/composer_messages_finder.rb index c39731d82..c7f27bcba 100644 --- a/lib/composer_messages_finder.rb +++ b/lib/composer_messages_finder.rb @@ -7,6 +7,7 @@ class ComposerMessagesFinder def find check_education_message || + check_new_user_many_replies || check_avatar_notification || check_sequential_replies || check_dominating_topic @@ -32,6 +33,12 @@ class ComposerMessagesFinder nil end + # New users have a limited number of replies in a topic + def check_new_user_many_replies + return unless replying? && @user.posted_too_much_in_topic?(@details[:topic_id]) + {templateName: 'composer/education', body: PrettyText.cook(I18n.t('education.too_many_replies', newuser_max_replies_per_topic: SiteSetting.newuser_max_replies_per_topic)) } + end + # Should a user be contacted to update their avatar? def check_avatar_notification diff --git a/lib/validators/post_validator.rb b/lib/validators/post_validator.rb index 124d55058..5c5dab1ef 100644 --- a/lib/validators/post_validator.rb +++ b/lib/validators/post_validator.rb @@ -5,6 +5,7 @@ class Validators::PostValidator < ActiveModel::Validator presence(record) stripped_length(record) raw_quality(record) + max_posts_validator(record) max_mention_validator(record) max_images_validator(record) max_attachments_validator(record) @@ -40,6 +41,12 @@ class Validators::PostValidator < ActiveModel::Validator end end + def max_posts_validator(post) + if post.acting_user.present? && post.acting_user.posted_too_much_in_topic?(post.topic_id) + post.errors.add(:base, I18n.t(:too_many_replies)) + end + end + # Ensure new users can not put too many images in a post def max_images_validator(post) add_error_if_count_exceeded(post, :too_many_images, post.image_count, SiteSetting.newuser_max_images) unless acting_user_is_trusted?(post) diff --git a/spec/components/composer_messages_finder_spec.rb b/spec/components/composer_messages_finder_spec.rb index df26e9be6..f211157a1 100644 --- a/spec/components/composer_messages_finder_spec.rb +++ b/spec/components/composer_messages_finder_spec.rb @@ -10,6 +10,7 @@ describe ComposerMessagesFinder do it "calls all the message finders" do finder.expects(:check_education_message).once + finder.expects(:check_new_user_many_replies).once finder.expects(:check_avatar_notification).once finder.expects(:check_sequential_replies).once finder.expects(:check_dominating_topic).once @@ -56,6 +57,24 @@ describe ComposerMessagesFinder do finder.check_education_message.should be_blank end end + end + + context '.check_new_user_many_replies' do + let(:user) { Fabricate.build(:user) } + + context 'replying' do + let(:finder) { ComposerMessagesFinder.new(user, composerAction: 'reply') } + + it "has no message when `posted_too_much_in_topic?` is false" do + user.expects(:posted_too_much_in_topic?).returns(false) + finder.check_new_user_many_replies.should be_blank + end + + it "has a message when a user has posted too much" do + user.expects(:posted_too_much_in_topic?).returns(true) + finder.check_new_user_many_replies.should be_present + end + end end diff --git a/spec/components/validators/post_validator_spec.rb b/spec/components/validators/post_validator_spec.rb index 76865503d..e1a5ed725 100644 --- a/spec/components/validators/post_validator_spec.rb +++ b/spec/components/validators/post_validator_spec.rb @@ -24,6 +24,20 @@ describe Validators::PostValidator do end end + context "too_many_posts" do + it "should be invalid when the user has posted too much" do + post.user.expects(:posted_too_much_in_topic?).returns(true) + validator.max_posts_validator(post) + expect(post.errors.count).to be > 0 + end + + it "should be valid when the user hasn't posted too much" do + post.user.expects(:posted_too_much_in_topic?).returns(false) + validator.max_posts_validator(post) + expect(post.errors.count).to be(0) + end + end + context "invalid post" do it "should be invalid" do validator.validate(post)