Skip to content

Add text search to webhooks view#23

Merged
mensfeld merged 1 commit intomasterfrom
feature/webhook-text-search
Feb 5, 2026
Merged

Add text search to webhooks view#23
mensfeld merged 1 commit intomasterfrom
feature/webhook-text-search

Conversation

@mensfeld
Copy link
Owner

@mensfeld mensfeld commented Feb 5, 2026

Summary

Implements case-insensitive text search for the webhooks index, allowing filtering by headers or payload content.

Changes

  • Model: Added search_text scope to Webhook model using SQLite json_quote() for headers and direct LIKE for payload
  • Controller: Added filter_by_search method and integrated it into the index action
  • View: Added search input field as the first filter alongside existing date filters, with responsive flex-wrap layout
  • Tests: Added 8 comprehensive test cases covering all search scenarios
  • Changelog: Updated with feature entry

Security

  • SQL injection protection via sanitize_sql_like for user input
  • Handles special characters (%, _, etc.) safely

Test Coverage

  • All 263 tests pass
  • Line coverage: 94.38%
  • Branch coverage: 85.71%
  • Added comprehensive tests for:
    • Payload content search
    • Header content search
    • Case-insensitive behavior
    • Combined search with date filters
    • Special character handling
    • Empty term handling

Verification

  • ✅ RuboCop: No offenses detected
  • ✅ Tests: All passing
  • ✅ Coverage: Above minimum thresholds (85%)

- Add search_text scope to Webhook model with SQL injection protection
- Add filter_by_search method to WebhooksController
- Update index view with search input field alongside date filters
- Add comprehensive test coverage for search functionality
- Update CHANGELOG with feature entry

Supports case-insensitive searching of both headers and payload content.
@mensfeld mensfeld requested a review from Copilot February 5, 2026 11:14
@mensfeld mensfeld self-assigned this Feb 5, 2026
@mensfeld mensfeld merged commit a014865 into master Feb 5, 2026
9 checks passed
@mensfeld mensfeld deleted the feature/webhook-text-search branch February 5, 2026 11:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements case-insensitive text search functionality for the webhooks admin interface, allowing administrators to filter webhooks by searching within header or payload content.

Changes:

  • Added search_text scope to the Webhook model for filtering by headers and payload content using SQL LIKE queries
  • Added filter_by_search controller method to apply search filtering in the webhooks index action
  • Updated the view to include a search input field with responsive layout and updated clear button logic

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
app/models/webhook.rb Added search_text scope using SQLite json_quote() and LIKE queries for searching headers and payload
app/controllers/admin/webhooks_controller.rb Added filter_by_search method and integrated it into the index action's filter chain
app/views/admin/webhooks/index.html.erb Added search input field with responsive flex-wrap layout and updated clear button condition
spec/requests/admin/webhooks_spec.rb Added 8 comprehensive test cases covering payload search, header search, case-insensitivity, combined filters, and special characters
CHANGELOG.md Added feature entry for the text search functionality
Comments suppressed due to low confidence (2)

spec/requests/admin/webhooks_spec.rb:46

  • This assignment to old_webhook is useless, since its value is never read.
      old_webhook = create(:webhook, received_at: 10.days.ago)

spec/requests/admin/webhooks_spec.rb:47

  • This assignment to new_webhook is useless, since its value is never read.
      new_webhook = create(:webhook, received_at: 1.day.ago)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +133 to +139
it "handles special characters safely" do
webhook = create(:webhook, payload: '{"data":"test%value"}')

get "/admin/webhooks", params: { q: "test%" }, headers: auth_headers

expect(response).to have_http_status(:ok)
end
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The test only verifies that the request doesn't crash when searching for special characters, but doesn't verify that the webhook is actually found. Consider adding an assertion like expect(response.body).to include(webhook.id.to_s) to ensure the special character search works correctly and finds the matching webhook.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +20
where(
"json_quote(headers) LIKE ? OR payload LIKE ?",
"%#{sanitize_sql_like(term)}%",
"%#{sanitize_sql_like(term)}%"
)
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The LIKE queries on headers and payload columns will perform full table scans since they use leading wildcards (%term%). This could become a performance bottleneck as the number of webhooks grows. Consider adding documentation about this limitation, or if this becomes an issue in production, consider implementing full-text search using SQLite's FTS5 extension or adding a separate searchable text column with an index.

Copilot uses AI. Check for mistakes.
return all if term.blank?

where(
"json_quote(headers) LIKE ? OR payload LIKE ?",
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The use of json_quote(headers) may not be necessary and could cause unexpected behavior. In SQLite, the json column type stores data as TEXT, so you can search it directly with LIKE similar to the payload column.

Consider simplifying to: "headers LIKE ? OR payload LIKE ?"

The json_quote() function converts a value to a JSON string literal, which adds extra quoting that may not be needed since the headers are already stored as JSON text in SQLite. While the current implementation may work, direct LIKE matching would be simpler and more predictable.

Suggested change
"json_quote(headers) LIKE ? OR payload LIKE ?",
"headers LIKE ? OR payload LIKE ?",

Copilot uses AI. Check for mistakes.
end

it "handles special characters safely" do
webhook = create(:webhook, payload: '{"data":"test%value"}')
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

This assignment to webhook is useless, since its value is never read.

Suggested change
webhook = create(:webhook, payload: '{"data":"test%value"}')
create(:webhook, payload: '{"data":"test%value"}')

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant