Skip to content

Commit

Permalink
Enable unaccent extension und use it for user filters
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverguenther committed Mar 11, 2024
1 parent ab70d1f commit aad4263
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 12 deletions.
13 changes: 8 additions & 5 deletions app/models/principals/scopes/like.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ def like(query)

s = "%#{query.to_s.downcase.strip.tr(',', '')}%"

where(['LOWER(login) LIKE :s OR ' +
"LOWER(#{firstnamelastname}) LIKE :s OR " +
"LOWER(#{lastnamefirstname}) LIKE :s OR " +
'LOWER(mail) LIKE :s',
{ s: }])
sql = <<~SQL
LOWER(login) LIKE :s
OR unaccent(LOWER(#{firstnamelastname})) LIKE unaccent(:s)
OR unaccent(LOWER(#{lastnamefirstname})) LIKE unaccent(:s)
OR LOWER(mail) LIKE :s
SQL

where([sql, { s: }])
.order(:type, :login, :lastname, :firstname, :mail)
end
end
Expand Down
10 changes: 5 additions & 5 deletions app/models/queries/filters/shared/user_name_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ def self.key
def where
case operator
when '='
["#{sql_concat_name} IN (?)", sql_value]
["#{sql_concat_name} IN (:s) OR unaccent(#{sql_concat_name}) IN (:s)", { s: sql_value }]
when '!'
["#{sql_concat_name} NOT IN (?)", sql_value]
["#{sql_concat_name} NOT IN (:s) AND unaccent(#{sql_concat_name}) NOT IN (:s)", { s: sql_value }]
when '~', '**'
["#{sql_concat_name} LIKE ?", "%#{sql_value}%"]
["unaccent(#{sql_concat_name}) LIKE unaccent(:s)", { s: "%#{sql_value}%" }]
when '!~'
["#{sql_concat_name} NOT LIKE ?", "%#{sql_value}%"]
["unaccent(#{sql_concat_name}) NOT LIKE :s", { s: "%#{sql_value}%" }]
end
end

Expand All @@ -70,7 +70,7 @@ def sql_concat_name
when :firstname_lastname
"LOWER(CONCAT(users.firstname, CONCAT(' ', users.lastname)))"
when :firstname
'LOWER(users.firstname)'
'LOWER(users.firstname))'
when :lastname_firstname, :lastname_coma_firstname
"LOWER(CONCAT(users.lastname, CONCAT(' ', users.firstname)))"
when :lastname_n_firstname
Expand Down
48 changes: 48 additions & 0 deletions db/migrate/20240311111957_enable_unaccent_extension.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2024 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

class EnableUnaccentExtension < ActiveRecord::Migration[7.1]
def up
ActiveRecord::Base.connection.execute("CREATE EXTENSION IF NOT EXISTS unaccent WITH SCHEMA pg_catalog;")
rescue StandardError => e
raise unless e.message.include?('unaccent')

raise <<~MESSAGE
\e[33mWARNING:\e[0m Could not find or enable the `unaccent` extension for PostgreSQL.
In order to benefit from this performance improvement, please install the postgresql-contrib module
for your PostgreSQL installation and re-run this migration.
Read more about the contrib module at `https://www.postgresql.org/docs/current/contrib.html` .
To re-run this migration use the following command `bin/rails db:migrate:redo VERSION=20230328154645`
MESSAGE
end

def down
ActiveRecord::Base.connection.execute("DROP EXTENSION IF EXISTS unaccent CASCADE;")
end
end
89 changes: 89 additions & 0 deletions spec/features/users/unaccent_user_filter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2024 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

require 'spec_helper'
require_relative '../principals/shared_memberships_examples'

RSpec.describe 'Finding users with accents', :js, :with_cuprite do
shared_let(:project) { create(:project) }
shared_let(:principal) { create(:user, firstname: 'Cécile', lastname: 'Foobar') }
shared_let(:admin) { create(:admin) }
shared_let(:work_package) { create(:work_package, project:) }
shared_let(:role) do
create(:project_role,
name: 'Developer',
permissions: %i[view_work_packages edit_work_packages work_package_assigned])
end

let(:members_page) { Pages::Members.new project.identifier }
let(:wp_page) { Pages::FullWorkPackage.new work_package }
let(:assignee_field) { wp_page.edit_field :assignee }

current_user { admin }

it 'finds a user with accents in the name in the global administration' do
visit users_path

fill_in 'name', with: 'Cecile'
click_on 'Apply'
expect(page).to have_current_path /name=Cecile/
expect(page).to have_css('td.firstname', text: 'Cécile')

fill_in 'name', with: 'Cécile'
click_on 'Apply'
expect(page).to have_current_path /name=C%C3%A9cile/
expect(page).to have_css('td.firstname', text: 'Cécile')
end

it 'can add the user as member and assignee' do
visit project_members_path(project)

members_page.open_new_member!
members_page.search_and_select_principal! 'Cecile',
'Cécile Foobar'
members_page.select_role! 'Developer'

click_on 'Add'
expect(members_page).to have_added_user 'Cécile Foobar'

members_page.open_filters!
members_page.search_for_name 'Cecile'
members_page.find_user 'Cécile Foobar'

visit project_work_package_path(project, work_package)
assignee_field.activate!

assignee_field.openSelectField
assignee_field.autocomplete('Cecile', select_text: 'Cécile Foobar', select: true)
wait_for_network_idle

wp_page.expect_and_dismiss_toaster message: 'Successful update.'
assignee_field.expect_inactive!
assignee_field.expect_state_text 'Cécile Foobar'
end
end
4 changes: 2 additions & 2 deletions spec/support/edit_fields/edit_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,11 @@ def set_value(content)
end
end

def autocomplete(query, select: true)
def autocomplete(query, select: true, select_text: query)
raise ArgumentError.new('Is not an autocompleter field') unless autocompleter_field?

if select
select_autocomplete field_container, query:, results_selector: 'body'
select_autocomplete field_container, query:, select_text:, results_selector: 'body'
else
search_autocomplete field_container, query:, results_selector: 'body'
end
Expand Down

0 comments on commit aad4263

Please sign in to comment.