Merge pull request #6879 from opf/feature/29116/search-filter-for-work-packages

Create SearchFilter on work packages
pull/6949/head
ulferts 6 years ago committed by GitHub
commit b23dceab63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/models/queries/filters.rb
  2. 36
      app/models/queries/filters/strategies/search.rb
  3. 4
      app/models/queries/operators.rb
  4. 36
      app/models/queries/operators/everywhere.rb
  5. 3
      app/models/queries/work_packages.rb
  6. 47
      app/models/queries/work_packages/filter/attachment_base_filter.rb
  7. 6
      app/models/queries/work_packages/filter/attachment_file_name_filter.rb
  8. 43
      app/models/queries/work_packages/filter/comment_filter.rb
  9. 35
      app/models/queries/work_packages/filter/description_filter.rb
  10. 40
      app/models/queries/work_packages/filter/filter_configuration.rb
  11. 40
      app/models/queries/work_packages/filter/filter_on_tsv_mixin.rb
  12. 75
      app/models/queries/work_packages/filter/or_filter_for_wp_mixin.rb
  13. 90
      app/models/queries/work_packages/filter/search_filter.rb
  14. 1
      config/locales/en.yml
  15. 39
      lib/api/v3/queries/schemas/search_filter_dependency_representer.rb
  16. 42
      lib/open_project/full_text_search.rb
  17. 24
      spec/models/queries/work_packages/filter/attachment_content_filter_spec.rb
  18. 61
      spec/models/queries/work_packages/filter/comment_filter_spec.rb
  19. 61
      spec/models/queries/work_packages/filter/description_filter_spec.rb
  20. 143
      spec/models/queries/work_packages/filter/search_filter_spec.rb

@ -38,6 +38,7 @@ module Queries::Filters
datetime_past: Queries::Filters::Strategies::DateTimePast,
string: Queries::Filters::Strategies::String,
text: Queries::Filters::Strategies::Text,
search: Queries::Filters::Strategies::Search,
float: Queries::Filters::Strategies::Float,
inexistent: Queries::Filters::Strategies::Inexistent
}.freeze

@ -0,0 +1,36 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
module Queries::Filters::Strategies
class Search < BaseStrategy
self.supported_operators = ['**']
self.default_operator = '**'
end
end

@ -33,7 +33,6 @@ module Queries::Operators
Queries::Operators::LessOrEqual,
Queries::Operators::Equals,
Queries::Operators::NotEquals,
Queries::Operators::NotEquals,
Queries::Operators::None,
Queries::Operators::All,
Queries::Operators::Contains,
@ -47,7 +46,8 @@ module Queries::Operators
Queries::Operators::MoreThanAgo,
Queries::Operators::Ago,
Queries::Operators::OnDate,
Queries::Operators::BetweenDate
Queries::Operators::BetweenDate,
Queries::Operators::Everywhere
]
OPERATORS = Hash[*(operators.map { |o| [o.symbol.to_s, o] }).flatten].freeze

@ -0,0 +1,36 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
module Queries::Operators
class Everywhere < Base
label 'everywhere'
set_symbol '**'
end
end

@ -70,6 +70,9 @@ module Queries::WorkPackages
register.filter Query, filters_module::IncludesFilter
register.filter Query, filters_module::RequiresFilter
register.filter Query, filters_module::RequiredFilter
register.filter Query, filters_module::DescriptionFilter
register.filter Query, filters_module::SearchFilter
register.filter Query, filters_module::CommentFilter
columns_module = Queries::WorkPackages::Columns

@ -29,56 +29,33 @@
#++
class Queries::WorkPackages::Filter::AttachmentBaseFilter < Queries::WorkPackages::Filter::WorkPackageFilter
DISALLOWED_CHARACTERS = /['?\\:()&|!*]/
include Queries::WorkPackages::Filter::FilterOnTsvMixin
def type
:text
end
def includes
:attachments
end
def available?
EnterpriseToken.allows_to?(:attachment_filters) && OpenProject::Database.allows_tsv?
end
def search_column
raise NotImplementedError
def includes
:attachments
end
def where
if OpenProject::Database.allows_tsv?
column = '"attachments"."' + search_column + '_tsv"'
query = tokenize
language = OpenProject::Configuration.main_content_language
ActiveRecord::Base.send(
:sanitize_sql_array, ["#{column} @@ to_tsquery(?, ?)",
language,
query]
)
end
end
private
def tokenize
terms = normalize_text(clean_terms).split(/[\s]+/).reject(&:blank?)
case operator
when '~'
terms.join ' & '
when '!~'
'! ' + terms.join(' & ! ')
end
OpenProject::FullTextSearch.tsv_where(Attachment.table_name,
search_column,
values.first,
concatenation: concatenation,
normalization: normalization_type)
end
def clean_terms
values.first.gsub(DISALLOWED_CHARACTERS, ' ')
def search_column
raise NotImplementedError
end
def normalize_text(text)
OpenProject::FullTextSearch.normalize_text(text)
def normalization_type
:text
end
end

@ -45,9 +45,7 @@ class Queries::WorkPackages::Filter::AttachmentFileNameFilter < Queries::WorkPac
'file'
end
private
def normalize_text(text)
OpenProject::FullTextSearch.normalize_filename(text)
def normalization_type
:filename
end
end

@ -0,0 +1,43 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
#
# 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-2017 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 doc/COPYRIGHT.rdoc for more details.
#++
class Queries::WorkPackages::Filter::CommentFilter < Queries::WorkPackages::Filter::WorkPackageFilter
def type
:text
end
def includes
%i{journals}
end
def where
operator_strategy.sql_for_field(values, Journal.table_name, 'notes')
end
end

@ -0,0 +1,35 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
class Queries::WorkPackages::Filter::DescriptionFilter < Queries::WorkPackages::Filter::WorkPackageFilter
def type
:text
end
end

@ -0,0 +1,40 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
class Queries::WorkPackages::Filter::FilterConfiguration
attr_accessor(:filter_class, :filter_name, :operator)
def initialize(filter_class, filter_name, operator)
@filter_class = filter_class
@filter_name = filter_name
@operator = operator
end
end

@ -0,0 +1,40 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
module Queries::WorkPackages::Filter::FilterOnTsvMixin
def concatenation
case operator
when '~'
:and
when '!~'
:and_not
end
end
end

@ -0,0 +1,75 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
#
# 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-2017 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 doc/COPYRIGHT.rdoc for more details.
#++
module Queries::WorkPackages::Filter::OrFilterForWpMixin
def filters
if @filters
update_instances
else
@filters = create_instances
end
@filters.keep_if(&:validate)
end
def includes
filters.map(&:includes).flatten.uniq.reject(&:blank?)
end
def where
filters.map(&:where).join(' OR ')
end
def filter_configurations
raise NotImplementedError
end
def create_instances
filter_configurations.map do |conf|
conf.filter_class.create!(name: conf.filter_name,
context: context,
operator: conf.operator,
values: values)
end
end
def update_instances
configurations = filter_configurations
@filters.each_with_index do |filter, index|
filter.operator = configurations[index].operator
filter.values = values
end
end
def ar_object_filter?
false
end
end

@ -0,0 +1,90 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
#
# 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-2017 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 doc/COPYRIGHT.rdoc for more details.
#++
class Queries::WorkPackages::Filter::SearchFilter <
Queries::WorkPackages::Filter::WorkPackageFilter
include Queries::WorkPackages::Filter::OrFilterForWpMixin
include Queries::WorkPackages::Filter::FilterOnTsvMixin
CONTAINS_OPERATOR = '~'.freeze
CE_FILTERS = [
Queries::WorkPackages::Filter::FilterConfiguration.new(
Queries::WorkPackages::Filter::SubjectFilter,
:subject,
CONTAINS_OPERATOR
),
Queries::WorkPackages::Filter::FilterConfiguration.new(
Queries::WorkPackages::Filter::DescriptionFilter,
:subject,
CONTAINS_OPERATOR
),
Queries::WorkPackages::Filter::FilterConfiguration.new(
Queries::WorkPackages::Filter::CommentFilter,
:subject,
CONTAINS_OPERATOR
)
].freeze
EE_TSV_FILTERS = [
Queries::WorkPackages::Filter::FilterConfiguration.new(
Queries::WorkPackages::Filter::AttachmentContentFilter,
:subject,
CONTAINS_OPERATOR
),
Queries::WorkPackages::Filter::FilterConfiguration.new(
Queries::WorkPackages::Filter::AttachmentFileNameFilter,
:subject,
CONTAINS_OPERATOR
)
].freeze
def self.key
:search
end
def name
:search
end
def type
:search
end
def human_name
I18n.t('label_search')
end
def filter_configurations
list = CE_FILTERS
list += EE_TSV_FILTERS if EnterpriseToken.allows_to?(:attachment_filters) && OpenProject::Database.allows_tsv?
list
end
end

@ -1238,6 +1238,7 @@ en:
label_environment: "Environment"
label_estimates_and_time: "Estimates and time"
label_equals: "is"
label_everywhere: "everywhere"
label_example: "Example"
label_export_to: "Also available in:"
label_expanded_click_to_collapse: "Expanded. Click to collapse"

@ -0,0 +1,39 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
module API
module V3
module Queries
module Schemas
class SearchFilterDependencyRepresenter < TextFilterDependencyRepresenter; end
end
end
end
end

@ -31,6 +31,44 @@
module OpenProject
# This module provides utility methods to work with PostgreSQL's full-text capabilities (TSVECTOR)
module FullTextSearch
DISALLOWED_CHARACTERS = /['?\\:()&|!*]/
def self.tsv_where(table_name, column_name, value, options = { concatenation: :and, normalization: :text })
if OpenProject::Database.allows_tsv?
column = '"' + table_name.to_s + '"."' + column_name.to_s + '_tsv"'
query = tokenize(value, options[:concatenation], options[:normalization])
language = OpenProject::Configuration.main_content_language
ActiveRecord::Base.send(
:sanitize_sql_array, ["#{column} @@ to_tsquery(?, ?)",
language,
query]
)
end
end
def self.tokenize(text, concatenation = :and, normalization = :text)
terms = normalize(clean_terms(text), normalization).split(/[\s]+/).reject(&:blank?)
case concatenation
when :and
# all terms need to hit
terms.join ' & '
when :and_not
# all terms must not hit.
'! ' + terms.join(' & ! ')
end
end
def self.normalize(text, type = :text)
case type
when :text
normalize_text(text)
when :filename
normalize_filename(text)
end
end
def self.normalize_text(text)
I18n.with_locale(:en) { I18n.transliterate(text.to_s.downcase) }
end
@ -43,5 +81,9 @@ module OpenProject
def self.to_words(text)
text.gsub /[^[:alnum:]]/, ' '
end
def self.clean_terms(terms)
terms.gsub(DISALLOWED_CHARACTERS, ' ')
end
end
end

@ -36,6 +36,30 @@ describe Queries::WorkPackages::Filter::AttachmentContentFilter, type: :model do
allow(EnterpriseToken).to receive(:allows_to?).with(:attachment_filters).and_return(true)
end
context 'WP with attachment' do
let(:context) { nil }
let(:value) { 'ipsum' }
let(:operator) { '~' }
let(:instance) do
described_class.create!(name: :search, context: context, operator: operator, values: [value])
end
let(:work_package) { FactoryBot.create(:work_package) }
let(:text) { 'lorem ipsum' }
let(:attachment) { FactoryBot.create(:attachment, container: work_package) }
before do
allow_any_instance_of(Plaintext::Resolver).to receive(:text).and_return(text)
allow(attachment).to receive(:readable?).and_return(true)
attachment.reload
end
it 'finds WP through attachment content' do
expect(WorkPackage.joins(:attachments).where(instance.where))
.to match_array [work_package]
end
end
it_behaves_like 'basic query filter' do
let(:type) { :text }
let(:class_key) { :attachment_content }

@ -0,0 +1,61 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe Queries::WorkPackages::Filter::CommentFilter, type: :model do
it_behaves_like 'basic query filter' do
let(:type) { :text }
let(:class_key) { :comment }
describe '#available?' do
it 'is available' do
expect(instance).to be_available
end
end
describe '#allowed_values' do
it 'is nil' do
expect(instance.allowed_values).to be_nil
end
end
describe '#valid_values!' do
it 'is a noop' do
instance.values = ['none', 'is', 'changed']
instance.valid_values!
expect(instance.values)
.to match_array ['none', 'is', 'changed']
end
end
it_behaves_like 'non ar filter'
end
end

@ -0,0 +1,61 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
#
# 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-2017 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 docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe Queries::WorkPackages::Filter::DescriptionFilter, type: :model do
it_behaves_like 'basic query filter' do
let(:type) { :text }
let(:class_key) { :description }
describe '#available?' do
it 'is available' do
expect(instance).to be_available
end
end
describe '#allowed_values' do
it 'is nil' do
expect(instance.allowed_values).to be_nil
end
end
describe '#valid_values!' do
it 'is a noop' do
instance.values = ['none', 'is', 'changed']
instance.valid_values!
expect(instance.values)
.to match_array ['none', 'is', 'changed']
end
end
it_behaves_like 'non ar filter'
end
end

@ -0,0 +1,143 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2017 the OpenProject Foundation (OPF)
#
# 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-2017 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 doc/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe Queries::WorkPackages::Filter::SearchFilter, type: :model do
let(:context) { nil }
let(:value) { 'bogus' }
let(:operator) { '**' }
let(:subject) { 'Some subject' }
let(:work_package) { FactoryBot.create(:work_package, subject: subject) }
let(:journal) { work_package.journals.last }
let(:instance) do
described_class.create!(name: :search, context: context, operator: operator, values: [value])
end
shared_examples "subject, description, and comment filter" do
context '' do
let!(:work_package) { FactoryBot.create(:work_package, subject: "A bogus subject", description: "And a short description") }
it 'finds in subject' do
instance.values = ['bogus subject']
expect(WorkPackage.eager_load(instance.includes).where(instance.where))
.to match_array [work_package]
end
it 'finds in description' do
instance.values = ['short description']
expect(WorkPackage.eager_load(instance.includes).where(instance.where))
.to match_array [work_package]
end
it 'finds in comments' do
journal.notes = "bogus comment"
journal.save
instance.values = [journal.notes]
expect(WorkPackage.eager_load(instance.includes).where(instance.where))
.to match_array [work_package]
end
end
end
if OpenProject::Database.allows_tsv?
context 'DB allows tsv' do
context 'with EE' do
before do
allow(EnterpriseToken).to receive(:allows_to?).and_return(false)
allow(EnterpriseToken).to receive(:allows_to?).with(:attachment_filters).and_return(true)
end
it_behaves_like 'subject, description, and comment filter'
context 'WP with attachment' do
let(:text) { 'lorem ipsum' }
let(:filename) { 'plaintext-file.txt' }
let(:attachment) { FactoryBot.create(:attachment, container: work_package, filename: filename) }
before do
allow_any_instance_of(Plaintext::Resolver).to receive(:text).and_return(text)
allow(attachment).to receive(:readable?).and_return(true)
attachment.reload
work_package.reload
end
it "finds in attachment content" do
instance.values = ['ipsum']
expect(WorkPackage.eager_load(instance.includes).where(instance.where))
.to match_array [work_package]
end
it "finds in attachment file name" do
instance.values = [filename]
expect(WorkPackage.eager_load(instance.includes).where(instance.where))
.to match_array [work_package]
end
end
end
it_behaves_like 'basic query filter' do
let(:type) { :search }
let(:class_key) { :search }
describe '#available?' do
it 'is available' do
expect(instance).to be_available
end
end
describe '#allowed_values' do
it 'is nil' do
expect(instance.allowed_values).to be_nil
end
end
describe '#valid_values!' do
it 'is a noop' do
instance.values = ['none', 'is', 'changed']
instance.valid_values!
expect(instance.values)
.to match_array ['none', 'is', 'changed']
end
end
it_behaves_like 'non ar filter'
end
end
else
context 'DB does not support TSV' do
context 'WP without attachment' do
it_behaves_like 'subject, description, and comment filter'
end
end
end
end
Loading…
Cancel
Save