From d01ad1fc9793f145d3d916713fa2f45cebaf1186 Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Wed, 5 Aug 2026 14:43:05 +0530 Subject: [PATCH] fix: handle ActionController::Parameters in days_before filter (#15319) ## Description The `days_before` filter operator in `FilterService#days_before_filter_query` calls `with_indifferent_access` directly on the query hash. In production the filter payload arrives as `ActionController::Parameters` (the controller passes `params.permit!`), which does not respond to `with_indifferent_access`, so every conversation filter request using `days_before` raises `NoMethodError` and returns a 500. Existing specs pass plain hashes with `with_indifferent_access`, which is why this was never caught. This PR normalizes the query hash via `to_h` first (permitted parameters convert to a `HashWithIndifferentAccess`, plain hashes are unaffected) and adds a regression spec that builds the payload as `ActionController::Parameters`, mirroring the controller. Fixes https://linear.app/chatwoot/issue/CW-7832 ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Added a regression spec that passes the filter payload as permitted `ActionController::Parameters` with the `days_before` operator. It reproduces the `NoMethodError` on the current develop branch and passes with this change. - `bundle exec rspec spec/services/conversations/filter_service_spec.rb` (31 examples, 0 failures) - `bundle exec rspec spec/services/conversations/filter_service_frontend_alignment_spec.rb` (10 examples, 0 failures) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- app/services/filter_service.rb | 2 +- .../conversations/filter_service_spec.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/services/filter_service.rb b/app/services/filter_service.rb index 25f118d48..f2ee79ab9 100644 --- a/app/services/filter_service.rb +++ b/app/services/filter_service.rb @@ -99,7 +99,7 @@ class FilterService def days_before_filter_query(query_hash, current_index) date = Time.zone.today - query_hash['values'][0].to_i.days - updated_query_hash = query_hash.with_indifferent_access.merge( + updated_query_hash = query_hash.to_h.with_indifferent_access.merge( values: [date.strftime], filter_operator: 'is_less_than' ) diff --git a/spec/services/conversations/filter_service_spec.rb b/spec/services/conversations/filter_service_spec.rb index 2e449bee8..924b9a8b8 100644 --- a/spec/services/conversations/filter_service_spec.rb +++ b/spec/services/conversations/filter_service_spec.rb @@ -639,6 +639,23 @@ describe Conversations::FilterService do result = filter_service.new(params, user_1, account).perform expect(result[:conversations].length).to eq expected_count end + + it 'filter by last_activity_at days_before when payload is ActionController::Parameters' do + params[:payload] = [ + ActionController::Parameters.new( + attribute_key: 'last_activity_at', + filter_operator: 'days_before', + values: [3], + query_operator: nil, + custom_attribute_type: '' + ).permit! + ] + + expected_count = account.conversations.where('last_activity_at < ?', (Time.zone.today - 3.days)).count + + result = filter_service.new(params, user_1, account).perform + expect(result[:conversations].length).to eq expected_count + end end end end