fast follow refactor, handle downthread blocked commenters (#19910)

* fast follow controller and spec refactor, handle downthread blocked commenters

* update only one column in spec, avoid recursion when traversing comments
This commit is contained in:
Duke Greene 2023-08-15 10:49:56 -04:00 committed by GitHub
parent 5c92f886ce
commit 945587b75d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 11 deletions

View file

@ -314,7 +314,16 @@ class CommentsController < ApplicationController
def user_blocked?
return false if current_user.blocked_by_count.zero?
UserBlock.blocking?(@comment.commentable.user_id, current_user.id) ||
UserBlock.blocking?(@comment.parent&.user_id, current_user.id)
blocked_by_commentable_author = UserBlock.blocking?(@comment.commentable.user_id, current_user.id)
blocked_by_comment_author = @comment.parent && UserBlock.blocking?(@comment.parent.user_id, current_user.id)
blocked_by_commentable_author || blocked_by_comment_author || blocker_upthread?(@comment.parent)
end
def blocker_upthread?(comment)
return false unless comment&.parent
thread_authors_ids = comment.ancestors.pluck(:user_id)
UserBlock.exists?(blocker_id: thread_authors_ids, blocked_id: current_user.id)
end
end

View file

@ -89,21 +89,42 @@ RSpec.describe "CommentsCreate" do
end
context "when user is commenting on a comment by an author who has blocked the user" do
let(:third_party_article) { create(:article, user_id: create(:user).id) }
it "raises a ModerationUnauthorizedError to prevent the comment from saving" do
before do
create(:user_block, blocker: blocker, blocked: user, config: "default")
# Manually manage the blocked_by_count attribute that counter_culture manages in prod
user.update(blocked_by_count: 1)
blocker_comment = create(:comment, user_id: blocker.id,
commentable_id: third_party_article.id,
commentable_type: "Article")
user.update_column(:blocked_by_count, 1)
end
let!(:third_party_article) { create(:article, user_id: create(:user).id) }
it "raises a ModerationUnauthorizedError to prevent the comment from saving" do
blocker_comment = create(:comment, user_id: blocker.id, commentable: third_party_article)
expect do
post comments_path, params: comment_params(body_markdown: "trolling attempted!",
parent_id: blocker_comment.id)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to eq("Not allowed due to moderation action")
end.not_to change(Comment, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to eq("Not allowed due to moderation action")
end
it "raises the error when the commenter is downthread of the blocker" do
# Simulate a conversation between the blocking user and two other users who aren't blocking anyone
replier_one = create(:user)
replier_two = create(:user)
blocker_comment = create(:comment, user: blocker, body_markdown: "I just block and then keep it moving",
commentable: third_party_article)
first_reply = create(:comment, user: replier_one, commentable: third_party_article, body_markdown: "+1!",
parent_id: blocker_comment.id)
downthread_reply = create(:comment, user: replier_two, commentable: third_party_article, body_markdown: "<3",
parent_id: first_reply.id)
expect do
post comments_path,
params: comment_params(body_markdown: "I'd love to derail this convo!", parent_id: downthread_reply.id)
end.not_to change(Comment, :count)
expect(response).to have_http_status(:unprocessable_entity)
expect(response.parsed_body["error"]).to eq("Not allowed due to moderation action")
end
end