diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 64c2f69c48b..a1fda8e86f0 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -336,6 +336,8 @@ en: reading_time: "Reading time" likes: "Likes" + action_already_performed: "Oops! You already performed this action. Can you try refreshing the page?" + too_many_replies: one: "We're sorry, but new users are temporarily limited to %{count} reply in the same topic." other: "We're sorry, but new users are temporarily limited to %{count} replies in the same topic." diff --git a/lib/post_action_creator.rb b/lib/post_action_creator.rb index 0717fe6ddc7..409bb94eb0b 100644 --- a/lib/post_action_creator.rb +++ b/lib/post_action_creator.rb @@ -80,17 +80,27 @@ class PostActionCreator @post_action_name, opts: { is_warning: @is_warning, - taken_actions: PostAction.counts_for([@post].compact, @created_by)[@post&.id], + taken_actions: taken_actions, }, ) end + def taken_actions + return @taken_actions if defined?(@taken_actions) + @taken_actions = PostAction.counts_for([@post].compact, @created_by)[@post&.id] + end + def perform result = CreateResult.new if !post_can_act? || (@queue_for_review && !guardian.is_staff?) result.forbidden = true - result.add_error(I18n.t("invalid_access")) + + if taken_actions&.keys&.include?(PostActionType.types[@post_action_name]) + result.add_error(I18n.t("action_already_performed")) + else + result.add_error(I18n.t("invalid_access")) + end return result end diff --git a/spec/lib/post_action_creator_spec.rb b/spec/lib/post_action_creator_spec.rb index 07d704d000d..81aeba92dfd 100644 --- a/spec/lib/post_action_creator_spec.rb +++ b/spec/lib/post_action_creator_spec.rb @@ -61,6 +61,12 @@ RSpec.describe PostActionCreator do expect(result.post_action.user).to eq(user) expect(result.post_action.post).to eq(post) expect(result.post_action.post_action_type_id).to eq(like_type_id) + + # also test double like + result = PostActionCreator.new(user, post, like_type_id).perform + expect(result.success).not_to eq(true) + expect(result.forbidden).to eq(true) + expect(result.errors.full_messages.join).to eq(I18n.t("action_already_performed")) end it "notifies subscribers" do @@ -172,7 +178,7 @@ RSpec.describe PostActionCreator do end it "hides the post when the flagger is a TL3 user and the poster is a TL0 user" do - result = PostActionCreator.create(user, post, :spam) + PostActionCreator.create(user, post, :spam) expect(post.hidden?).to eq(true) end @@ -180,7 +186,7 @@ RSpec.describe PostActionCreator do it "does not hide the post if the setting is disabled" do SiteSetting.high_trust_flaggers_auto_hide_posts = false - result = PostActionCreator.create(user, post, :spam) + PostActionCreator.create(user, post, :spam) expect(post.hidden?).to eq(false) end @@ -223,14 +229,14 @@ RSpec.describe PostActionCreator do it "succeeds with other flag action types" do freeze_time 10.seconds.from_now - spam_result = PostActionCreator.create(user, post, :spam) + _spam_result = PostActionCreator.create(user, post, :spam) expect(reviewable.reload.pending?).to eq(true) end it "fails when other flag action types are open" do freeze_time 10.seconds.from_now - spam_result = PostActionCreator.create(user, post, :spam) + _spam_result = PostActionCreator.create(user, post, :spam) inappropriate_result = PostActionCreator.create(Fabricate(:user), post, :inappropriate) @@ -307,7 +313,7 @@ RSpec.describe PostActionCreator do it "hides the topic even if it has replies" do Fabricate(:post, topic: post.topic) - result = build_creator.perform + _result = build_creator.perform expect(post.topic.reload.visible?).to eq(false) end