Forbid comments on draft cards
- Add Card#commentable? method that returns true only for published cards. - CardsController#create ensures that the card is commentable. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@ class Cards::CommentsController < ApplicationController
|
||||
|
||||
before_action :set_comment, only: %i[ show edit update destroy ]
|
||||
before_action :ensure_creatorship, only: %i[ edit update destroy ]
|
||||
before_action :ensure_card_is_commentable, only: :create
|
||||
|
||||
def index
|
||||
set_page_and_extract_portion_from @card.comments.chronologically
|
||||
@@ -50,6 +51,10 @@ class Cards::CommentsController < ApplicationController
|
||||
head :forbidden if Current.user != @comment.creator
|
||||
end
|
||||
|
||||
def ensure_card_is_commentable
|
||||
head :forbidden unless @card.commentable?
|
||||
end
|
||||
|
||||
def comment_params
|
||||
params.expect(comment: [ :body, :created_at ])
|
||||
end
|
||||
|
||||
@@ -5,6 +5,10 @@ module Card::Commentable
|
||||
has_many :comments, dependent: :destroy
|
||||
end
|
||||
|
||||
def commentable?
|
||||
published?
|
||||
end
|
||||
|
||||
private
|
||||
STORAGE_BATCH_SIZE = 1000
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ class Comment < ApplicationRecord
|
||||
|
||||
has_rich_text :body
|
||||
|
||||
validate :card_is_commentable
|
||||
|
||||
scope :chronologically, -> { order created_at: :asc, id: :desc }
|
||||
scope :preloaded, -> { with_rich_text_body.includes(reactions: :reacter) }
|
||||
scope :by_system, -> { joins(:creator).where(creator: { role: :system }) }
|
||||
@@ -22,6 +24,10 @@ class Comment < ApplicationRecord
|
||||
end
|
||||
|
||||
private
|
||||
def card_is_commentable
|
||||
errors.add(:card, "does not allow comments") unless card.commentable?
|
||||
end
|
||||
|
||||
def watch_card_by_creator
|
||||
card.watch_by creator
|
||||
end
|
||||
|
||||
@@ -13,6 +13,16 @@ class Cards::CommentsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create on draft card is forbidden" do
|
||||
draft_card = boards(:writebook).cards.create!(status: :drafted, creator: users(:kevin))
|
||||
|
||||
assert_no_difference -> { draft_card.comments.count } do
|
||||
post card_comments_path(draft_card), params: { comment: { body: "This should be forbidden" } }, as: :json
|
||||
end
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "update" do
|
||||
put card_comment_path(cards(:logo), comments(:logo_agreement_kevin)), params: { comment: { body: "I've changed my mind" } }, as: :turbo_stream
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
require "test_helper"
|
||||
|
||||
class Card::CommentableTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
Current.session = sessions(:david)
|
||||
end
|
||||
|
||||
test "capturing comments" do
|
||||
assert_difference -> { cards(:logo).comments.count }, +1 do
|
||||
cards(:logo).comments.create!(body: "Agreed.")
|
||||
@@ -19,4 +23,9 @@ class Card::CommentableTest < ActiveSupport::TestCase
|
||||
|
||||
assert cards(:text).watched_by?(users(:kevin))
|
||||
end
|
||||
|
||||
test "commentable is true for published cards, false for drafts" do
|
||||
assert cards(:logo).commentable?
|
||||
assert_not cards(:unfinished_thoughts).commentable?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,19 @@ class CommentTest < ActiveSupport::TestCase
|
||||
Current.session = sessions(:david)
|
||||
end
|
||||
|
||||
test "cannot create comment on a draft card" do
|
||||
draft_card = cards(:unfinished_thoughts)
|
||||
|
||||
comment = draft_card.comments.build(body: "This should fail")
|
||||
|
||||
assert_not comment.valid?
|
||||
assert_includes comment.errors[:card], "does not allow comments"
|
||||
|
||||
assert_raises(ActiveRecord::RecordInvalid) do
|
||||
draft_card.comments.create!(body: "This should raise")
|
||||
end
|
||||
end
|
||||
|
||||
test "rich text embed variants are processed immediately on attachment" do
|
||||
comment = cards(:logo).comments.create!(body: "Check this out")
|
||||
comment.body.body.attachables # force load
|
||||
|
||||
@@ -70,16 +70,6 @@ class MentionsTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
test "don't create mentions from comments when belonging to unpublished cards" do
|
||||
perform_enqueued_jobs only: Mention::CreateJob do
|
||||
card = boards(:writebook).cards.create title: "Cleanup", description: "Some initial content"
|
||||
|
||||
assert_no_difference -> { Mention.count } do
|
||||
card.comments.create!(body: "Great work on this #{mention_html_for(users(:david))}!")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "can't mention users that don't have access to the board" do
|
||||
boards(:writebook).update! all_access: false
|
||||
boards(:writebook).accesses.revoke_from(users(:david))
|
||||
|
||||
Reference in New Issue
Block a user