Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/helpers/searches_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ def highlight_searched_content(leaf, content, query)
end

private
# Terms come from FTS5 highlight() spans, which can include document
# punctuation (e.g. a phrase match spanning "foo) bar"). Escape them so
# metacharacters are matched literally instead of raising a RegexpError.
def whole_word_matchers(terms)
terms.map { |term| /\b#{term}\b/ }
terms.map { |term| /\b#{Regexp.escape(term)}\b/ }
end
end
14 changes: 14 additions & 0 deletions test/controllers/leafables_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ class LeafablesControllerTest < ActionDispatch::IntegrationTest
assert_select "mark", "great"
end

test "show highlights a phrase match whose span contains regex metacharacters" do
sign_out
books(:handbook).update!(published: true)

section = Section.new(body: "alpha) omega in the body")
books(:handbook).press(section, title: "Punctuated")
Comment on lines +37 to +38

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reuse the existing section fixture

This test creates and presses a new Section even though leaves(:welcome_section) already provides a section-backed leaf. Update that fixture's body for the test and reindex it instead, avoiding unnecessary record creation and following the repository's explicit testing convention.

AGENTS.md reference: AGENTS.md:L5-L6

Useful? React with 👍 / 👎.

section.leaf.reindex
Comment on lines +37 to +39

get leafable_slug_path(section.leaf), params: { search: '"alpha omega"' }

assert_response :success
assert_select "mark", text: /alpha\) omega/
end

test "show does not allow public access to an unpublished book" do
sign_out

Expand Down
11 changes: 11 additions & 0 deletions test/helpers/searches_helper_test.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "test_helper"

class SearchesHelperTest < ActionView::TestCase
include PagesHelper
test "sanitize_search_result preserves mark tags" do
assert_equal "<mark>findme</mark> text", sanitize_search_result("<mark>findme</mark> text")
end
Expand All @@ -16,4 +17,14 @@ class SearchesHelperTest < ActionView::TestCase
test "sanitize_search_result strips attributes from mark tags" do
assert_equal "<mark>findme</mark> text", sanitize_search_result('<mark class="hidden">findme</mark> text')
end

test "highlight_searched_content handles matched terms containing regex metacharacters" do
leaf = Struct.new(:terms) do
def matches_for_highlight(_query) = terms
end.new([ "foo) bar" ])

result = highlight_searched_content(leaf, "foo) bar in the body", "foo bar")

assert_includes result, "<mark>foo) bar</mark>"
end
end
Loading