From 0598a50c930dd135574a31052c0cb48819988643 Mon Sep 17 00:00:00 2001 From: Caio Almeida <117518+caiosba@users.noreply.github.com> Date: Wed, 28 Aug 2024 08:09:09 -0300 Subject: [PATCH] Search for fact-checks by multiple keywords regardless the order. (#2012) * Search by multiple keywords regardless the order. Fixes: CV2-5129. * CV2-5129: apply same search for Explainer * CV2-5129: apply PR comment * No need to split, strip, and join with websearch_to_tsquery * CV2-5129: fix CC --------- Co-authored-by: Sawy Co-authored-by: computermacgyver --- app/models/team.rb | 14 ++++++++++++-- test/models/team_2_test.rb | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/app/models/team.rb b/app/models/team.rb index 6ba123bb6b..a3d8572e51 100644 --- a/app/models/team.rb +++ b/app/models/team.rb @@ -495,7 +495,7 @@ def filtered_explainers(filters = {}) query = query.where(updated_at: Range.new(*format_times_search_range_filter(JSON.parse(filters[:updated_at]), nil))) unless filters[:updated_at].blank? # Filter by text - query = query.where('(title ILIKE ? OR url ILIKE ? OR description ILIKE ?)', *["%#{filters[:text]}%"]*3) if filters[:text].to_s.size > 2 + query = self.filter_by_keywords(query, filters, 'Explainer') if filters[:text].to_s.size > 2 # Exclude the ones already applied to a target item target = ProjectMedia.find_by_id(filters[:target_id].to_i) @@ -535,7 +535,7 @@ def filtered_fact_checks(filters = {}) query = query.where('fact_checks.report_status' => filters[:report_status].to_a.map(&:to_s)) unless filters[:report_status].blank? # Filter by text - query = query.where('(fact_checks.title ILIKE ? OR fact_checks.url ILIKE ? OR fact_checks.summary ILIKE ?)', *["%#{filters[:text]}%"]*3) if filters[:text].to_s.size > 2 + query = self.filter_by_keywords(query, filters) if filters[:text].to_s.size > 2 # Exclude the ones already applied to a target item target = ProjectMedia.find_by_id(filters[:target_id].to_i) @@ -544,6 +544,16 @@ def filtered_fact_checks(filters = {}) query end + def filter_by_keywords(query, filters, type = 'FactCheck') + tsquery = Team.sanitize_sql_array(["websearch_to_tsquery(?)", filters[:text]]) # FIXME: May not work for all languages + if type == 'FactCheck' + tsvector = "to_tsvector('simple', coalesce(title, '') || ' ' || coalesce(summary, '') || coalesce(url, ''))" + else + tsvector = "to_tsvector('simple', coalesce(title, '') || ' ' || coalesce(description, '') || coalesce(url, ''))" + end + query.where(Arel.sql("#{tsvector} @@ #{tsquery}")) + end + # private # # Please add private methods to app/models/concerns/team_private.rb diff --git a/test/models/team_2_test.rb b/test/models/team_2_test.rb index 53275867ab..1542c9491e 100644 --- a/test/models/team_2_test.rb +++ b/test/models/team_2_test.rb @@ -1527,4 +1527,29 @@ def setup tbi.save! assert_equal ['none', 'link_preview'], t.available_newsletter_header_types end + + test "should search for fact-checks and explainers by keywords" do + Sidekiq::Testing.fake! + t = create_team + # Fact-checks + create_fact_check title: 'Some Other Test', claim_description: create_claim_description(project_media: create_project_media(team: t)) + create_fact_check title: 'Bar Bravo Foo Test', claim_description: create_claim_description(project_media: create_project_media(team: t)) + create_fact_check title: 'Foo Alpha Bar Test', claim_description: create_claim_description(project_media: create_project_media(team: t)) + assert_equal 3, t.filtered_fact_checks.count + assert_equal 3, t.filtered_fact_checks(text: 'Test').count + assert_equal 2, t.filtered_fact_checks(text: 'Foo Bar').count + assert_equal 1, t.filtered_fact_checks(text: 'Foo Bar Bravo').count + assert_equal 1, t.filtered_fact_checks(text: 'Foo Bar Alpha').count + assert_equal 0, t.filtered_fact_checks(text: 'Foo Bar Delta').count + # Explainer + create_explainer title: 'Some Other Test', team: t + create_explainer title: 'Bar Bravo Foo Test', team: t + create_explainer title: 'Foo Alpha Bar Test', team: t + assert_equal 3, t.filtered_explainers.count + assert_equal 3, t.filtered_explainers(text: 'Test').count + assert_equal 2, t.filtered_explainers(text: 'Foo Bar').count + assert_equal 1, t.filtered_explainers(text: 'Foo Bar Bravo').count + assert_equal 1, t.filtered_explainers(text: 'Foo Bar Alpha').count + assert_equal 0, t.filtered_fact_checks(text: 'Foo Bar Delta').count + end end