From 21c6dbb0ceb5121e74b1907597139d30bb4821e7 Mon Sep 17 00:00:00 2001 From: Martin Artnik Date: Mon, 24 Feb 2025 15:07:18 +0100 Subject: [PATCH] Fix search for special characters and add specs [SCI-11597] --- app/models/concerns/searchable_model.rb | 5 +- spec/models/concerns/searchable_model_spec.rb | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 spec/models/concerns/searchable_model_spec.rb diff --git a/app/models/concerns/searchable_model.rb b/app/models/concerns/searchable_model.rb index d18688cb5..29b2cce58 100644 --- a/app/models/concerns/searchable_model.rb +++ b/app/models/concerns/searchable_model.rb @@ -206,11 +206,10 @@ module SearchableModel new_phrase.map! { |t| "#{t}:*" } unless exact_match new_phrase = sanitize_sql_like(new_phrase.join('&').tr('\'', '"')) else - new_phrase = sanitize_sql_like(Regexp.escape(new_phrase)) - new_phrase = exact_match ? "(^|\\s)#{new_phrase}(\\s|$)" : "%#{new_phrase}%" + new_phrase = exact_match ? "(^|\\s)#{Regexp.escape(new_phrase)}(\\s|$)" : "%#{sanitize_sql_like(new_phrase)}%" end - ["t#{i}".to_sym, new_phrase] + [:"t#{i}", new_phrase] end).to_h ) end diff --git a/spec/models/concerns/searchable_model_spec.rb b/spec/models/concerns/searchable_model_spec.rb new file mode 100644 index 000000000..9abee0494 --- /dev/null +++ b/spec/models/concerns/searchable_model_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'rails_helper' + +SEARCH_SPECIAL_CHARACTER_TEST_NAMES = %w( + NameWithNoSpecialCharacters + NameWith_Underscore + NameWith@At + NameWith.Dot + NameWith-Minus + NameWith+Plus + NameWith&Ampersand + NameWith;Semicolon + NameWith:Colon + NameWith,Comma + NameWith$Dollar + NameWith/Slash + NameWith=Equals + NameWith~Tilde + NameWith^Caret + NameWith°Degree + NameWith`Backtick + NameWith"DoubleQuote + NameWith'SingleQuote + NameWith*Asterisk + NameWith?QuestionMark + NameWith%Percent + NameWith\Backslash + NameWith[SquareBracket] + NameWith{CurlyBracket} + NameWith(Parenthesis) + NameWith|Pipe + NameWith!Exclamation +).freeze + +describe SearchableModel, type: :concern do + let!(:user) { create :user } + let!(:team) { create :team, created_by: user } + + let!(:projects) do + SEARCH_SPECIAL_CHARACTER_TEST_NAMES.map do |name| + Project.create!(name: name, team: user.teams.first, created_by: user) + end + end + + it '#where_attributes_like_boolean finds all projects by name' do + SEARCH_SPECIAL_CHARACTER_TEST_NAMES.each do |name| + expect(Project.where_attributes_like_boolean(:name, "#{name} OR something")&.first&.name).to eq name + puts "Found #{name}" + end + end + + it '#where_attributes_like_boolean finds all projects by exact name' do + SEARCH_SPECIAL_CHARACTER_TEST_NAMES.filter { |n| n != 'NameWith"DoubleQuote' }.each do |name| + expect(Project.where_attributes_like_boolean(:name, "\"#{name}\"")&.first&.name).to eq name + expect(Project.where_attributes_like_boolean(:name, "\"#{name} not exact\"").count).to eq 0 + puts "Found #{name}" + end + end + + it '#where_attributes_like finds all projects by name ' do + SEARCH_SPECIAL_CHARACTER_TEST_NAMES.each do |name| + expect(Project.where_attributes_like(:name, name)&.first&.name).to eq name + puts "Found #{name}" + end + end +end