Guard search indexing with searchable? check
Only index cards and comments if their card is `published?`, using a new method `searchable?` that is implemented on both Card and Comment. This prevents draft cards and their comments from being indexed. When drafts are published, the existing `update_in_search_index` callback creates the record via `upsert!`, or else ensures unpublished records are removed from the index. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,4 +25,8 @@ module Card::Searchable
|
||||
def search_board_id
|
||||
board_id
|
||||
end
|
||||
|
||||
def searchable?
|
||||
published?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,4 +20,8 @@ module Comment::Searchable
|
||||
def search_board_id
|
||||
card.board_id
|
||||
end
|
||||
|
||||
def searchable?
|
||||
card.published?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,11 +15,17 @@ module Searchable
|
||||
|
||||
private
|
||||
def create_in_search_index
|
||||
search_record_class.create!(search_record_attributes)
|
||||
if searchable?
|
||||
search_record_class.create!(search_record_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
def update_in_search_index
|
||||
search_record_class.upsert!(search_record_attributes)
|
||||
if searchable?
|
||||
search_record_class.upsert!(search_record_attributes)
|
||||
else
|
||||
remove_from_search_index
|
||||
end
|
||||
end
|
||||
|
||||
def remove_from_search_index
|
||||
@@ -53,4 +59,5 @@ module Searchable
|
||||
# - search_content: returns content string
|
||||
# - search_card_id: returns the card id (self.id for cards, card_id for comments)
|
||||
# - search_board_id: returns the board id
|
||||
# - searchable?: returns whether this record should be indexed
|
||||
end
|
||||
|
||||
@@ -3,6 +3,16 @@ require "test_helper"
|
||||
class Card::SearchableTest < ActiveSupport::TestCase
|
||||
include SearchTestHelper
|
||||
|
||||
test "searchable? returns true for published cards" do
|
||||
card = @board.cards.create!(title: "Published Card", status: "published", creator: @user)
|
||||
assert card.searchable?
|
||||
end
|
||||
|
||||
test "searchable? returns false for draft cards" do
|
||||
card = @board.cards.create!(title: "Draft Card", status: "drafted", creator: @user)
|
||||
assert_not card.searchable?
|
||||
end
|
||||
|
||||
test "card search" do
|
||||
# Searching by title
|
||||
card = @board.cards.create!(title: "layout is broken", status: "published", creator: @user)
|
||||
@@ -78,4 +88,46 @@ class Card::SearchableTest < ActiveSupport::TestCase
|
||||
assert_equal 0, fts_count, "FTS entry should be deleted"
|
||||
end
|
||||
end
|
||||
|
||||
test "updating a draft card does not index it" do
|
||||
search_record_class = Search::Record.for(@user.account_id)
|
||||
|
||||
card = @board.cards.create!(title: "Draft card", creator: @user, status: "drafted")
|
||||
assert_nil search_record_class.find_by(searchable_type: "Card", searchable_id: card.id)
|
||||
|
||||
card.update!(title: "Updated draft card")
|
||||
assert_nil search_record_class.find_by(searchable_type: "Card", searchable_id: card.id),
|
||||
"Draft card should not be indexed after update"
|
||||
|
||||
results = Card.mentioning("Updated", user: @user)
|
||||
assert_not_includes results, card
|
||||
end
|
||||
|
||||
test "publishing a draft card indexes it" do
|
||||
search_record_class = Search::Record.for(@user.account_id)
|
||||
|
||||
card = @board.cards.create!(title: "Draft to publish", creator: @user, status: "drafted")
|
||||
assert_nil search_record_class.find_by(searchable_type: "Card", searchable_id: card.id)
|
||||
|
||||
card.publish
|
||||
search_record = search_record_class.find_by(searchable_type: "Card", searchable_id: card.id)
|
||||
assert_not_nil search_record, "Published card should be indexed"
|
||||
assert_equal card.id, search_record.card_id
|
||||
|
||||
results = Card.mentioning("publish", user: @user)
|
||||
assert_includes results, card
|
||||
end
|
||||
|
||||
test "unpublishing a draft card removes it from the search index" do
|
||||
search_record_class = Search::Record.for(@user.account_id)
|
||||
|
||||
card = @board.cards.create!(title: "Draft to publish", creator: @user, status: "published")
|
||||
assert_not_nil search_record_class.find_by(searchable_type: "Card", searchable_id: card.id)
|
||||
|
||||
card.update!(status: "drafted")
|
||||
|
||||
assert_nil search_record_class.find_by(searchable_type: "Card", searchable_id: card.id)
|
||||
results = Card.mentioning("publish", user: @user)
|
||||
assert_not_includes results, card
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,17 @@ class Comment::SearchableTest < ActiveSupport::TestCase
|
||||
@card = @board.cards.create!(title: "Test Card", status: "published", creator: @user)
|
||||
end
|
||||
|
||||
test "searchable? returns true for comments on published cards" do
|
||||
comment = @card.comments.create!(body: "test comment", creator: @user)
|
||||
assert comment.searchable?
|
||||
end
|
||||
|
||||
test "searchable? returns false for comments on draft cards" do
|
||||
draft_card = @board.cards.create!(title: "Draft Card", status: "drafted", creator: @user)
|
||||
comment = draft_card.comments.build(body: "test comment", creator: @user)
|
||||
assert_not comment.searchable?
|
||||
end
|
||||
|
||||
test "comment search" do
|
||||
search_record_class = Search::Record.for(@user.account_id)
|
||||
# Comment is indexed on create
|
||||
|
||||
@@ -15,6 +15,11 @@ class SearchTest < ActiveSupport::TestCase
|
||||
results = Search::Record.for(@user.account_id).search("overflowing", user: @user)
|
||||
assert results.find { |it| it.card_id == comment_card.id && it.searchable_type == "Comment" }
|
||||
|
||||
# Drafted cards are excluded from search results
|
||||
drafted_card = @board.cards.create!(title: "drafted searchable content", creator: @user, status: "drafted")
|
||||
results = Search::Record.for(@user.account_id).search("drafted", user: @user)
|
||||
assert_not results.find { |it| it.card_id == drafted_card.id }
|
||||
|
||||
# Don't include inaccessible boards
|
||||
other_user = User.create!(name: "Other User", account: @account)
|
||||
inaccessible_board = Board.create!(name: "Inaccessible Board", account: @account, creator: other_user)
|
||||
|
||||
Reference in New Issue
Block a user