commit
1d4b1e21c0
@ -0,0 +1,46 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module Queries::AvailableOrders |
||||
def order_for(key) |
||||
(find_registered_order(key) || Queries::NotExistingOrder).new(key) |
||||
end |
||||
|
||||
private |
||||
|
||||
def find_registered_order(key) |
||||
orders_register.detect do |s| |
||||
s.key === key.to_sym |
||||
end |
||||
end |
||||
|
||||
def orders_register |
||||
Queries::Register.orders[self.class] |
||||
end |
||||
end |
@ -0,0 +1,66 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::BaseOrder |
||||
include ActiveModel::Validations |
||||
|
||||
validates :direction, inclusion: { in: %i(asc desc) } |
||||
|
||||
class_attribute :model |
||||
attr_accessor :direction, |
||||
:attribute |
||||
|
||||
def initialize(attribute) |
||||
self.attribute = attribute |
||||
end |
||||
|
||||
def self.key |
||||
raise NotImplementedError |
||||
end |
||||
|
||||
def scope |
||||
scope = order |
||||
scope = scope.joins(joins) if joins |
||||
scope |
||||
end |
||||
|
||||
def name |
||||
attribute |
||||
end |
||||
|
||||
private |
||||
|
||||
def order |
||||
model.order(name => direction) |
||||
end |
||||
|
||||
def joins |
||||
nil |
||||
end |
||||
end |
@ -0,0 +1,124 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::BaseQuery |
||||
class << self |
||||
attr_accessor :model, :default_scope |
||||
end |
||||
|
||||
include Queries::AvailableFilters |
||||
include Queries::AvailableOrders |
||||
include ActiveModel::Validations |
||||
|
||||
validate :filters_valid, |
||||
:sortation_valid |
||||
|
||||
def initialize |
||||
@scope = self.class.default_scope |
||||
@filters = [] |
||||
@orders = [] |
||||
end |
||||
|
||||
def results |
||||
if valid? |
||||
filters.each do |filter| |
||||
self.scope = scope.merge(filter.scope) |
||||
end |
||||
|
||||
orders.each do |order| |
||||
self.scope = scope.merge(order.scope) |
||||
end |
||||
else |
||||
empty_scope |
||||
end |
||||
|
||||
scope |
||||
end |
||||
|
||||
def where(attribute, operator, values) |
||||
filter = filter_for(attribute) |
||||
filter.operator = operator |
||||
filter.values = values |
||||
filter.context = context |
||||
|
||||
filters << filter |
||||
|
||||
self |
||||
end |
||||
|
||||
def order(hash) |
||||
hash.each do |attribute, direction| |
||||
order = order_for(attribute) |
||||
order.direction = direction |
||||
orders << order |
||||
end |
||||
|
||||
self |
||||
end |
||||
|
||||
protected |
||||
|
||||
attr_accessor :scope, |
||||
:filters, |
||||
:orders |
||||
|
||||
def filters_valid |
||||
filters.each do |filter| |
||||
next if filter.valid? |
||||
|
||||
add_error(:filters, filter.human_name, filter) |
||||
end |
||||
end |
||||
|
||||
def sortation_valid |
||||
orders.each do |order| |
||||
next if order.valid? |
||||
|
||||
add_error(:orders, order.class.key, order) |
||||
end |
||||
end |
||||
|
||||
def add_error(local_attribute, attribute_name, object) |
||||
messages = object |
||||
.errors |
||||
.messages |
||||
.values |
||||
.flatten |
||||
.join(" #{I18n.t('support.array.sentence_connector')} ") |
||||
|
||||
errors.add local_attribute, errors.full_message(attribute_name, messages) |
||||
end |
||||
|
||||
def empty_scope |
||||
self.scope = self.class.model.where(Arel::Nodes::Equality.new(1, 0)) |
||||
end |
||||
|
||||
def context |
||||
nil |
||||
end |
||||
end |
@ -0,0 +1,55 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::NotExistingFilter < Queries::BaseFilter |
||||
def available? |
||||
false |
||||
end |
||||
|
||||
def type |
||||
:inexistent |
||||
end |
||||
|
||||
def self.key |
||||
:not_existent |
||||
end |
||||
|
||||
def human_name |
||||
name |
||||
end |
||||
|
||||
validate :always_false |
||||
|
||||
def always_false |
||||
errors.add :base, I18n.t(:'activerecord.errors.messages.does_not_exist') |
||||
end |
||||
|
||||
# deactivating superclass validation |
||||
def validate_inclusion_of_operator; end |
||||
end |
@ -0,0 +1,42 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::NotExistingOrder < Queries::BaseOrder |
||||
validate :always_false |
||||
|
||||
def self.key |
||||
:inexistent |
||||
end |
||||
|
||||
private |
||||
|
||||
def always_false |
||||
errors.add :base, I18n.t(:'activerecord.errors.messages.does_not_exist') |
||||
end |
||||
end |
@ -0,0 +1,40 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require Rails.root.join('config/constants/query_register') |
||||
|
||||
module Queries::Register |
||||
class << self |
||||
delegate :filter, |
||||
:filters, |
||||
:order, |
||||
:orders, |
||||
to: ::Constants::QueryRegister |
||||
end |
||||
end |
@ -0,0 +1,125 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module Queries::SqlForField |
||||
private |
||||
|
||||
# Helper method to generate the WHERE sql for a +field+, +operator+ and a +values+ array |
||||
def sql_for_field(field, operator, values, db_table, db_field, is_custom_filter = false) |
||||
# code expects strings (e.g. for quoting), but ints would work as well: unify them here |
||||
values = values.map(&:to_s) |
||||
|
||||
sql = '' |
||||
case operator |
||||
when '=' |
||||
if values.present? |
||||
if values.include?('-1') |
||||
sql = "#{db_table}.#{db_field} IS NULL OR " |
||||
end |
||||
|
||||
sql += "#{db_table}.#{db_field} IN (" + values.map { |val| "'#{connection.quote_string(val)}'" }.join(',') + ')' |
||||
else |
||||
# empty set of allowed values produces no result |
||||
sql = '0=1' |
||||
end |
||||
when '!' |
||||
if values.present? |
||||
sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + values.map { |val| "'#{connection.quote_string(val)}'" }.join(',') + '))' |
||||
else |
||||
# empty set of forbidden values allows all results |
||||
sql = '1=1' |
||||
end |
||||
when '!*' |
||||
sql = "#{db_table}.#{db_field} IS NULL" |
||||
sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter |
||||
when '*' |
||||
sql = "#{db_table}.#{db_field} IS NOT NULL" |
||||
sql << " AND #{db_table}.#{db_field} <> ''" if is_custom_filter |
||||
when '>=' |
||||
if is_custom_filter |
||||
sql = "#{db_table}.#{db_field} != '' AND CAST(#{db_table}.#{db_field} AS decimal(60,4)) >= #{values.first.to_f}" |
||||
else |
||||
sql = "#{db_table}.#{db_field} >= #{values.first.to_f}" |
||||
end |
||||
when '<=' |
||||
if is_custom_filter |
||||
sql = "#{db_table}.#{db_field} != '' AND CAST(#{db_table}.#{db_field} AS decimal(60,4)) <= #{values.first.to_f}" |
||||
else |
||||
sql = "#{db_table}.#{db_field} <= #{values.first.to_f}" |
||||
end |
||||
when 'o' |
||||
sql = "#{Status.table_name}.is_closed=#{connection.quoted_false}" if field == 'status_id' |
||||
when 'c' |
||||
sql = "#{Status.table_name}.is_closed=#{connection.quoted_true}" if field == 'status_id' |
||||
when '>t-' |
||||
sql = date_range_clause(db_table, db_field, - values.first.to_i, 0) |
||||
when '<t-' |
||||
sql = date_range_clause(db_table, db_field, nil, - values.first.to_i) |
||||
when 't-' |
||||
sql = date_range_clause(db_table, db_field, - values.first.to_i, - values.first.to_i) |
||||
when '>t+' |
||||
sql = date_range_clause(db_table, db_field, values.first.to_i, nil) |
||||
when '<t+' |
||||
sql = date_range_clause(db_table, db_field, 0, values.first.to_i) |
||||
when 't+' |
||||
sql = date_range_clause(db_table, db_field, values.first.to_i, values.first.to_i) |
||||
when 't' |
||||
sql = date_range_clause(db_table, db_field, 0, 0) |
||||
when 'w' |
||||
from = l(:general_first_day_of_week) == '7' ? |
||||
# week starts on sunday |
||||
((Date.today.cwday == 7) ? Time.now.at_beginning_of_day : Time.now.at_beginning_of_week - 1.day) : |
||||
# week starts on monday (Rails default) |
||||
Time.now.at_beginning_of_week |
||||
sql = "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date(from), connection.quoted_date(from + 7.days)] |
||||
when '~' |
||||
sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(values.first.to_s.downcase)}%'" |
||||
when '!~' |
||||
sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(values.first.to_s.downcase)}%'" |
||||
end |
||||
|
||||
sql |
||||
end |
||||
|
||||
# Returns a SQL clause for a date or datetime field. |
||||
def date_range_clause(table, field, from, to) |
||||
s = [] |
||||
if from |
||||
s << ("#{table}.#{field} > '%s'" % [connection.quoted_date((Date.yesterday + from).to_time.end_of_day)]) |
||||
end |
||||
if to |
||||
s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date((Date.today + to).to_time.end_of_day)]) |
||||
end |
||||
s.join(' AND ') |
||||
end |
||||
|
||||
def connection |
||||
self.class.connection |
||||
end |
||||
end |
@ -0,0 +1,38 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module Queries::Users |
||||
Queries::Register.filter Queries::Users::UserQuery, Queries::Users::Filters::NameFilter |
||||
Queries::Register.filter Queries::Users::UserQuery, Queries::Users::Filters::GroupFilter |
||||
Queries::Register.filter Queries::Users::UserQuery, Queries::Users::Filters::StatusFilter |
||||
|
||||
Queries::Register.order Queries::Users::UserQuery, Queries::Users::Orders::DefaultOrder |
||||
Queries::Register.order Queries::Users::UserQuery, Queries::Users::Orders::NameOrder |
||||
Queries::Register.order Queries::Users::UserQuery, Queries::Users::Orders::GroupOrder |
||||
end |
@ -0,0 +1,75 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::Users::Filters::NameFilter < Queries::Users::Filters::UserFilter |
||||
def type |
||||
:string |
||||
end |
||||
|
||||
def self.key |
||||
:name |
||||
end |
||||
|
||||
def where |
||||
case operator |
||||
when '=' |
||||
["#{sql_concat_name} IN (?)", sql_value] |
||||
when '!' |
||||
["#{sql_concat_name} NOT IN (?)", sql_value] |
||||
when '~' |
||||
["#{sql_concat_name} LIKE ?", "%#{sql_value}%"] |
||||
when '!~' |
||||
["#{sql_concat_name} NOT LIKE ?", "%#{sql_value}%"] |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def sql_value |
||||
case operator |
||||
when '=', '!' |
||||
values.map { |val| connection.quote_string(val.downcase) }.join(',') |
||||
when '~', '!~' |
||||
values.first.downcase |
||||
end |
||||
end |
||||
|
||||
def sql_concat_name |
||||
case Setting.user_format |
||||
when :firstname_lastname, :lastname_coma_firstname |
||||
"LOWER(CONCAT(firstname, CONCAT(' ', lastname)))" |
||||
when :firstname |
||||
'LOWER(firstname)' |
||||
when :lastname_firstname |
||||
"LOWER(CONCAT(lastname, CONCAT(' ', firstname)))" |
||||
when :username |
||||
"LOWER(login)" |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,44 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::Users::Filters::StatusFilter < Queries::Users::Filters::UserFilter |
||||
def allowed_values |
||||
Principal::STATUSES.keys.map do |key| |
||||
[I18n.t(:"status_#{key}"), key] |
||||
end |
||||
end |
||||
|
||||
def type |
||||
:list |
||||
end |
||||
|
||||
def self.key |
||||
:status |
||||
end |
||||
end |
@ -0,0 +1,50 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::Users::Orders::GroupOrder < Queries::BaseOrder |
||||
self.model = User |
||||
|
||||
def self.key |
||||
:group |
||||
end |
||||
|
||||
private |
||||
|
||||
def order |
||||
order_string = "groups_users.lastname" |
||||
|
||||
order_string += " DESC" if direction == :desc |
||||
|
||||
model.order(order_string) |
||||
end |
||||
|
||||
def joins |
||||
:groups |
||||
end |
||||
end |
@ -0,0 +1,48 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::Users::Orders::NameOrder < Queries::BaseOrder |
||||
self.model = User |
||||
|
||||
def self.key |
||||
:name |
||||
end |
||||
|
||||
private |
||||
|
||||
def order |
||||
ordered = User.order_by_name |
||||
|
||||
if direction == :desc |
||||
ordered = ordered.reverse_order |
||||
end |
||||
|
||||
ordered |
||||
end |
||||
end |
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module Queries::WorkPackages |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::AssignedToFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::AuthorFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::CategoryFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::CreatedAtFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::CustomFieldFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::DoneRatioFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::DueDateFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::EstimatedHoursFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::GroupFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::PriorityFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::ProjectFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::ResponsibleFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::RoleFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::StartDateFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::StatusFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::SubjectFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::SubprojectFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::TypeFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::UpdatedAtFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::VersionFilter |
||||
Queries::Register.filter Query, Queries::WorkPackages::Filter::WatcherFilter |
||||
end |
@ -0,0 +1,75 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class Queries::WorkPackages::Filter::WorkPackageFilter < ::Queries::BaseFilter |
||||
include ActiveModel::Serialization |
||||
# (de-)serialization |
||||
def self.from_hash(filter_hash) |
||||
filter_hash.keys.map { |field| new(field, filter_hash[field]) } |
||||
end |
||||
|
||||
def to_hash |
||||
{ name => attributes_hash } |
||||
end |
||||
|
||||
def human_name |
||||
WorkPackage.human_attribute_name(name) |
||||
end |
||||
|
||||
alias :project :context |
||||
alias :project= :context= |
||||
|
||||
def attributes |
||||
{ name: name, operator: operator, values: values } |
||||
end |
||||
|
||||
def possible_types_by_operator |
||||
@@operators_by_filter_type.select { |_key, operators| operators.include?(operator) }.keys.sort |
||||
end |
||||
|
||||
def ==(filter) |
||||
filter.attributes_hash == attributes_hash |
||||
end |
||||
|
||||
protected |
||||
|
||||
def attributes_hash |
||||
@@filter_params.inject({}) do |params, param_field| |
||||
params.merge(param_field => send(param_field)) |
||||
end |
||||
end |
||||
|
||||
private |
||||
|
||||
def stringify_values |
||||
unless values.nil? |
||||
values.map!(&:to_s) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,128 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
class ParamsToQueryService |
||||
attr_accessor :model |
||||
|
||||
def initialize(model) |
||||
self.model = model |
||||
end |
||||
|
||||
def call(params) |
||||
query = new_query |
||||
|
||||
query = apply_filters(query, params) |
||||
query = apply_order(query, params) |
||||
|
||||
query |
||||
end |
||||
|
||||
private |
||||
|
||||
def new_query |
||||
model_name = model.name |
||||
|
||||
query_class = Kernel.const_get "::Queries::#{model_name.pluralize}::#{model_name}Query" |
||||
|
||||
query_class.new |
||||
end |
||||
|
||||
def apply_filters(query, params) |
||||
return query unless params[:filters] |
||||
|
||||
filters = parse_filters_from_json(params[:filters]) |
||||
|
||||
filters[:attributes].each do |filter_name| |
||||
query = query.where(filter_name, |
||||
filters[:operators][filter_name], |
||||
filters[:values][filter_name]) |
||||
end |
||||
|
||||
query |
||||
end |
||||
|
||||
def apply_order(query, params) |
||||
return query unless params[:sortBy] |
||||
|
||||
sort = parse_sorting_from_json(params[:sortBy]) |
||||
|
||||
hash_sort = sort.each_with_object({}) do |(attribute, direction), hash| |
||||
hash[attribute.to_sym] = direction.to_sym |
||||
end |
||||
|
||||
query.order(hash_sort) |
||||
end |
||||
|
||||
# Expected format looks like: |
||||
# [ |
||||
# { |
||||
# "filtered_field_name": { |
||||
# "operator": "a name for a filter operation", |
||||
# "values": ["values", "for the", "operation"] |
||||
# } |
||||
# }, |
||||
# { /* more filters if needed */} |
||||
# ] |
||||
def parse_filters_from_json(json) |
||||
filters = JSON.parse(json) |
||||
operators = {} |
||||
values = {} |
||||
filters.each do |filter| |
||||
attribute = filter.keys.first # there should only be one attribute per filter |
||||
ar_attribute = convert_attribute attribute, append_id: true |
||||
operators[ar_attribute] = filter[attribute]['operator'] |
||||
values[ar_attribute] = filter[attribute]['values'] |
||||
end |
||||
|
||||
{ |
||||
attributes: values.keys, |
||||
operators: operators, |
||||
values: values |
||||
} |
||||
end |
||||
|
||||
def parse_sorting_from_json(json) |
||||
JSON.parse(json).map do |(attribute, order)| |
||||
[convert_attribute(attribute), order] |
||||
end |
||||
end |
||||
|
||||
def convert_attribute(attribute, append_id: false) |
||||
::API::Utilities::PropertyNameConverter.to_ar_name(attribute, |
||||
context: conversion_model, |
||||
refer_to_ids: append_id) |
||||
end |
||||
|
||||
def conversion_model |
||||
@conversion_model ||= model.new |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module Constants |
||||
module QueryRegister |
||||
class << self |
||||
def filter(query, filter) |
||||
self.filters ||= Hash.new do |hash, filter_key| |
||||
hash[filter_key] = [] |
||||
end |
||||
|
||||
self.filters[query] << filter |
||||
end |
||||
|
||||
def order(query, order) |
||||
self.orders ||= Hash.new do |hash, order_key| |
||||
hash[order_key] = [] |
||||
end |
||||
|
||||
self.orders[query] << order |
||||
end |
||||
|
||||
attr_accessor :filters, :orders |
||||
end |
||||
end |
||||
end |
@ -1,50 +0,0 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::AssignedToFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::AuthorFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::CategoryFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::CreatedAtFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::CustomFieldFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::DoneRatioFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::DueDateFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::EstimatedHoursFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::GroupFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::PriorityFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::ProjectFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::ResponsibleFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::RoleFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::StartDateFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::StatusFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::SubjectFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::SubprojectFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::TypeFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::UpdatedAtFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::VersionFilter |
||||
Queries::WorkPackages::FilterRegister.register Queries::WorkPackages::Filter::WatcherFilter |
@ -0,0 +1,44 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
# TODO: this is to be removed or rather the UserCollectionRepresenter is |
||||
# to be turned into an OffsetPaginatedCollection representer. |
||||
# It is not possible to do that right now as we do not have a |
||||
# solution for an accessible autocompleter drop down widget. We therefore |
||||
# have to fetch all users when we want to present them inside of a drop down. |
||||
|
||||
module API |
||||
module V3 |
||||
module Users |
||||
class PaginatedUserCollectionRepresenter < ::API::Decorators::OffsetPaginatedCollection |
||||
element_decorator ::API::V3::Users::UserRepresenter |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,69 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::Users::PaginatedUserCollectionRepresenter do |
||||
let(:self_base_link) { '/api/v3/users' } |
||||
let(:collection_inner_type) { 'User' } |
||||
let(:total) { 3 } |
||||
let(:page) { 1 } |
||||
let(:page_size) { 2 } |
||||
let(:actual_count) { 3 } |
||||
|
||||
let(:users) { |
||||
users = FactoryGirl.build_stubbed_list(:user, |
||||
actual_count, |
||||
created_on: Time.now, |
||||
updated_on: Time.now) |
||||
allow(users) |
||||
.to receive(:per_page) |
||||
.with(page_size) |
||||
.and_return(users) |
||||
|
||||
allow(users) |
||||
.to receive(:page) |
||||
.with(page) |
||||
.and_return(users) |
||||
|
||||
users |
||||
} |
||||
let(:representer) { |
||||
described_class.new(users, |
||||
'/api/v3/users', |
||||
per_page: page_size, |
||||
page: page, |
||||
current_user: users.first) |
||||
} |
||||
|
||||
context 'generation' do |
||||
subject(:collection) { representer.to_json } |
||||
|
||||
it_behaves_like 'offset-paginated APIv3 collection' |
||||
end |
||||
end |
@ -0,0 +1,198 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe Queries::BaseFilter, type: :model do |
||||
let(:integer_filter) do |
||||
filter_class = Class.new(described_class) do |
||||
def type |
||||
:integer |
||||
end |
||||
end |
||||
|
||||
filter_class.new |
||||
end |
||||
|
||||
let(:date_filter) do |
||||
filter_class = Class.new(described_class) do |
||||
def type |
||||
:date |
||||
end |
||||
end |
||||
|
||||
filter_class.new |
||||
end |
||||
|
||||
let(:date_past_filter) do |
||||
filter_class = Class.new(described_class) do |
||||
def type |
||||
:date_past |
||||
end |
||||
end |
||||
|
||||
filter_class.new |
||||
end |
||||
|
||||
shared_examples_for 'validity checked' do |
||||
describe '#valid?' do |
||||
context 'when the operator does not require values' do |
||||
before do |
||||
filter.operator = operator_without_value |
||||
end |
||||
|
||||
it 'is valid if no values are given' do |
||||
expect(filter).to be_valid |
||||
end |
||||
end |
||||
|
||||
context 'when the operator requires values' do |
||||
before do |
||||
filter.operator = valid_operator |
||||
end |
||||
|
||||
context 'and no value is given' do |
||||
it 'is invalid' do |
||||
expect(filter).to be_invalid |
||||
end |
||||
end |
||||
|
||||
context 'and only an empty string is given as value' do |
||||
before do |
||||
filter.values = [''] |
||||
end |
||||
|
||||
it 'is invalid' do |
||||
expect(filter).to be_invalid |
||||
end |
||||
end |
||||
|
||||
context 'and values are given' do |
||||
before do |
||||
filter.values = valid_values |
||||
end |
||||
|
||||
it 'is valid' do |
||||
expect(filter).to be_valid |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
shared_examples_for 'date validity checked' do |
||||
describe '#valid?' do |
||||
context "and the operator is 't' (today)" do |
||||
before do |
||||
filter.operator = 't' |
||||
end |
||||
|
||||
it 'is valid' do |
||||
expect(filter).to be_valid |
||||
end |
||||
end |
||||
|
||||
context "and the operator is 'w' (this week)" do |
||||
before do |
||||
filter.operator = 'w' |
||||
end |
||||
|
||||
it 'is valid' do |
||||
expect(filter).to be_valid |
||||
end |
||||
end |
||||
|
||||
context 'and the operator compares the current day' do |
||||
before do |
||||
filter.operator = '>t-' |
||||
end |
||||
|
||||
context 'and the value is an integer' do |
||||
before do |
||||
filter.values = ['4'] |
||||
end |
||||
|
||||
it 'is valid' do |
||||
expect(filter).to be_valid |
||||
end |
||||
end |
||||
|
||||
context 'and the value is not an integer' do |
||||
before do |
||||
filter.values = ['four'] |
||||
end |
||||
|
||||
it 'is invalid' do |
||||
expect(filter).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'for an integer filter' do |
||||
let(:filter) { integer_filter } |
||||
let(:valid_values) { [5] } |
||||
let(:valid_operator) { '=' } |
||||
let(:operator_without_value) { '*' } |
||||
|
||||
it_behaves_like 'validity checked' |
||||
|
||||
describe '#valid?' do |
||||
context 'when the filter values is not an integer' do |
||||
before do |
||||
filter.values == [1, 'asdf'] |
||||
end |
||||
|
||||
it 'is invalid' do |
||||
expect(filter).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'for a date filter' do |
||||
let(:filter) { date_filter } |
||||
let(:valid_values) { [5] } |
||||
let(:valid_operator) { '<t+' } |
||||
let(:operator_without_value) { 't' } |
||||
|
||||
it_behaves_like 'validity checked' |
||||
it_behaves_like 'date validity checked' |
||||
end |
||||
|
||||
context 'for a date_past filter' do |
||||
let(:filter) { date_past_filter } |
||||
let(:valid_values) { [5] } |
||||
let(:valid_operator) { '<t-' } |
||||
let(:operator_without_value) { 't' } |
||||
|
||||
it_behaves_like 'validity checked' |
||||
it_behaves_like 'date validity checked' |
||||
end |
||||
end |
@ -0,0 +1,62 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe Queries::Users::Filters::GroupFilter, type: :model do |
||||
let(:group1) { FactoryGirl.build_stubbed(:group) } |
||||
let(:group2) { FactoryGirl.build_stubbed(:group) } |
||||
|
||||
before do |
||||
allow(Group) |
||||
.to receive(:pluck) |
||||
.and_return([[group1.name, group1.id.to_s], [group2.name, group2.id.to_s]]) |
||||
end |
||||
|
||||
it_behaves_like 'basic query filter' do |
||||
let(:class_key) { :group } |
||||
let(:type) { :list_optional } |
||||
let(:name) { I18n.t('query_fields.member_of_group') } |
||||
|
||||
describe '#allowed_values' do |
||||
it 'is a list of the possible values' do |
||||
expected = [[group1.name, group1.id.to_s], [group2.name, group2.id.to_s]] |
||||
|
||||
expect(instance.allowed_values).to match_array(expected) |
||||
end |
||||
end |
||||
end |
||||
|
||||
it_behaves_like 'list_optional query filter' do |
||||
let(:attribute) { :id } |
||||
let(:model) { User } |
||||
let(:joins) { :groups } |
||||
let(:valid_values) { [group1.id.to_s] } |
||||
end |
||||
end |
@ -0,0 +1,96 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe Queries::Users::Filters::NameFilter, type: :model do |
||||
include_context 'filter tests' |
||||
let(:values) { ['A name'] } |
||||
let(:model) { User } |
||||
|
||||
it_behaves_like 'basic query filter' do |
||||
let(:class_key) { :name } |
||||
let(:type) { :string } |
||||
let(:model) { User } |
||||
|
||||
describe '#allowed_values' do |
||||
it 'is nil' do |
||||
expect(instance.allowed_values).to be_nil |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '#scope' do |
||||
before do |
||||
allow(Setting) |
||||
.to receive(:user_format) |
||||
.and_return(:firstname) |
||||
end |
||||
|
||||
context 'for "="' do |
||||
let(:operator) { '=' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = model.where("LOWER(firstname) IN ('#{values.first.downcase}')") |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "!"' do |
||||
let(:operator) { '!' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = model.where("LOWER(firstname) NOT IN ('#{values.first.downcase}')") |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "~"' do |
||||
let(:operator) { '~' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = model.where("LOWER(firstname) LIKE '%#{values.first.downcase}%'") |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "!~"' do |
||||
let(:operator) { '!~' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = model.where("LOWER(firstname) NOT LIKE '%#{values.first.downcase}%'") |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,53 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe Queries::Users::Filters::StatusFilter, type: :model do |
||||
it_behaves_like 'basic query filter' do |
||||
let(:class_key) { :status } |
||||
let(:type) { :list } |
||||
|
||||
describe '#allowed_values' do |
||||
it 'is a list of the possible values' do |
||||
expected = Principal::STATUSES.keys.map do |key| |
||||
[I18n.t(:"status_#{key}"), key] |
||||
end |
||||
|
||||
expect(instance.allowed_values).to match_array(expected) |
||||
end |
||||
end |
||||
end |
||||
|
||||
it_behaves_like 'list query filter' do |
||||
let(:attribute) { :status } |
||||
let(:model) { User } |
||||
let(:valid_values) { [Principal::STATUSES.keys.first] } |
||||
end |
||||
end |
@ -0,0 +1,225 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
# prevents test failures where the system user |
||||
# is mentioned in the User.not_builtin scope |
||||
require 'system_user' |
||||
|
||||
describe Queries::Users::UserQuery, type: :model do |
||||
let(:instance) { described_class.new } |
||||
let(:base_scope) { User.not_builtin } |
||||
|
||||
context 'without a filter' do |
||||
describe '#results' do |
||||
it 'is the same as getting all the users' do |
||||
expect(instance.results.to_sql).to eql base_scope.to_sql |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a name filter' do |
||||
before do |
||||
instance.where('name', '~', ['a user']) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'is the same as handwriting the query' do |
||||
expected = base_scope |
||||
.merge(User |
||||
.where(["LOWER(CONCAT(firstname, CONCAT(' ', lastname))) LIKE ?", |
||||
"%a user%"])) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
describe '#valid?' do |
||||
it 'is true' do |
||||
expect(instance).to be_valid |
||||
end |
||||
|
||||
it 'is invalid if the filter is invalid' do |
||||
instance.where('name', '=', ['']) |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a status filter' do |
||||
before do |
||||
instance.where('status', '=', ['active']) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'is the same as handwriting the query' do |
||||
expected = base_scope.merge(User.where(["users.status IN (?)", "active"])) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
describe '#valid?' do |
||||
it 'is true' do |
||||
expect(instance).to be_valid |
||||
end |
||||
|
||||
it 'is invalid if the filter is invalid' do |
||||
instance.where('status', '=', ['']) |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a group filter' do |
||||
let(:group_1) { FactoryGirl.build_stubbed(:group) } |
||||
|
||||
before do |
||||
allow(Group) |
||||
.to receive(:exists?) |
||||
.and_return(true) |
||||
|
||||
allow(Group) |
||||
.to receive(:all) |
||||
.and_return([group_1]) |
||||
|
||||
instance.where('group', '=', [group_1.id]) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'is the same as handwriting the query' do |
||||
expected = base_scope |
||||
.merge(User |
||||
.joins(:groups) |
||||
.where("groups.id IN ('#{group_1.id}')")) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
describe '#valid?' do |
||||
it 'is true' do |
||||
expect(instance).to be_valid |
||||
end |
||||
|
||||
it 'is invalid if the filter is invalid' do |
||||
instance.where('group', '=', ['']) |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a non existent filter' do |
||||
before do |
||||
instance.where('not_supposed_to_exist', '=', ['bogus']) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'returns a query not returning anything' do |
||||
expected = User.where(Arel::Nodes::Equality.new(1, 0)) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
describe 'valid?' do |
||||
it 'is false' do |
||||
expect(instance).to be_invalid |
||||
end |
||||
|
||||
it 'returns the error on the filter' do |
||||
instance.valid? |
||||
|
||||
expect(instance.errors[:filters]).to eql ["Not supposed to exist does not exist."] |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with an id sortation' do |
||||
before do |
||||
instance.order(id: :desc) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'is the same as handwriting the query' do |
||||
expected = base_scope.merge(User.order(id: :desc)) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a name sortation' do |
||||
before do |
||||
instance.order(name: :desc) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'is the same as handwriting the query' do |
||||
expected = base_scope.merge(User.order_by_name.reverse_order) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a group sortation' do |
||||
before do |
||||
instance.order(group: :desc) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'is the same as handwriting the query' do |
||||
expected = base_scope.merge(User.joins(:groups).order("groups_users.lastname DESC")) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'with a non existing sortation' do |
||||
# this is a field protected from sortation |
||||
before do |
||||
instance.order(password: :desc) |
||||
end |
||||
|
||||
describe '#results' do |
||||
it 'returns a query not returning anything' do |
||||
expected = User.where(Arel::Nodes::Equality.new(1, 0)) |
||||
|
||||
expect(instance.results.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
describe 'valid?' do |
||||
it 'is false' do |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,71 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
shared_examples_for 'work package query filter' do |
||||
let(:project) { FactoryGirl.build_stubbed(:project) } |
||||
let(:instance) { described_class.create(project)[instance_key || class_key] } |
||||
let(:instance_key) { nil } |
||||
let(:class_key) { raise "needs to be defined" } |
||||
let(:name) { WorkPackage.human_attribute_name(instance_key || class_key) } |
||||
|
||||
describe '.create' do |
||||
it 'returns a hash with a subject key and a filter instance' do |
||||
expect(described_class.create(project)[instance_key || class_key]).to be_a(described_class) |
||||
end |
||||
end |
||||
|
||||
describe '.key' do |
||||
it 'is the defined key' do |
||||
expect(described_class.key).to eql(class_key) |
||||
end |
||||
end |
||||
|
||||
describe '#key' do |
||||
it 'is the defined key' do |
||||
expect(instance.key).to eql(instance_key || class_key) |
||||
end |
||||
end |
||||
|
||||
describe '#order' do |
||||
it 'has the defined order' do |
||||
expect(instance.order).to eql(order) |
||||
end |
||||
end |
||||
|
||||
describe '#type' do |
||||
it 'is the defined filter type' do |
||||
expect(instance.type).to eql(type) |
||||
end |
||||
end |
||||
|
||||
describe '#name' do |
||||
it 'is the l10 name for the filter' do |
||||
expect(instance.name).to eql(name) |
||||
end |
||||
end |
||||
end |
@ -1,157 +0,0 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe Queries::WorkPackages::Filter, type: :model do |
||||
describe '#type' do |
||||
describe 'validations' do |
||||
subject { filter } |
||||
|
||||
let(:filter) { FactoryGirl.build :work_packages_filter } |
||||
|
||||
context 'when the operator does not require values' do |
||||
let(:filter) { FactoryGirl.build :work_packages_filter, field: :status_id, operator: '*', values: [] } |
||||
|
||||
it 'is valid if no values are given' do |
||||
expect(filter).to be_valid |
||||
end |
||||
end |
||||
|
||||
context 'when the operator requires values' do |
||||
let(:filter) { FactoryGirl.build :work_packages_filter, field: :done_ratio, operator: '>=', values: [] } |
||||
|
||||
context 'and no value is given' do |
||||
it { is_expected.not_to be_valid } |
||||
end |
||||
|
||||
context 'and only an empty string is given as value' do |
||||
let(:filter) { FactoryGirl.build :work_packages_filter, field: :due_date, operator: 't-', values: [''] } |
||||
|
||||
it { is_expected.not_to be_valid } |
||||
end |
||||
|
||||
context 'and values are given' do |
||||
before do filter.values = [5] end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
end |
||||
|
||||
context 'when it is of type integer' do |
||||
let(:filter) { FactoryGirl.build :work_packages_filter, field: :done_ratio, operator: '>=', values: [] } |
||||
|
||||
before do filter.field = 'done_ratio' end |
||||
|
||||
context 'and the filter values is an integer' do |
||||
before do filter.values = [1, '12', 123] end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
|
||||
context 'and the filter values is not an integer' do |
||||
before do filter.values == [1, 'asdf'] end |
||||
|
||||
it { is_expected.not_to be_valid } |
||||
|
||||
context 'and the operator is *' do |
||||
before do filter.operator = '*' end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'when it if of type date or date_past' do |
||||
let(:filter) { FactoryGirl.build :work_packages_filter, field: :created_at } |
||||
|
||||
context "and the operator is 't' (today)" do |
||||
before do filter.operator = 't' end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
|
||||
context "and the operator is 'w' (this week)" do |
||||
before do filter.operator = 'w' end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
|
||||
context 'and the operator compares the current day' do |
||||
before do filter.operator = '>t-' end |
||||
|
||||
context 'and the value is an integer' do |
||||
before do filter.values = ['4'] end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
|
||||
context 'and the value is not an integer' do |
||||
before do filter.values = ['four'] end |
||||
|
||||
it { is_expected.not_to be_valid } |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'when it is a work package filter' do |
||||
let(:filter) { FactoryGirl.build :work_packages_filter } |
||||
|
||||
context 'and the field is whitelisted' do |
||||
before do filter.field = :project_id end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
|
||||
# this context tests the case when a new item is injected in |
||||
# the filter_types_by_field hash afterwards |
||||
# from within some plugins that patch Queries::WorkPackages::Filter |
||||
context 'and the field is whitelisted afterwards' do |
||||
before do |
||||
filter.field = :some_new_key |
||||
filter.class.add_filter_type_by_field('some_new_key', 'list') |
||||
end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
|
||||
context 'and the field is not whitelisted and no custom field key' do |
||||
before do filter.field = :any_key end |
||||
|
||||
it { is_expected.not_to be_valid } |
||||
end |
||||
|
||||
context 'and the field is a custom field starting with "cf"' do |
||||
before do filter.field = :cf_any_key end |
||||
|
||||
it { is_expected.to be_valid } |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,237 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
shared_context 'filter tests' do |
||||
let(:context) { nil } |
||||
let(:values) { ['bogus'] } |
||||
let(:operator) { '=' } |
||||
let(:instance) do |
||||
filter = described_class.new |
||||
filter.context = context |
||||
filter.operator = operator |
||||
filter.values = values |
||||
filter |
||||
end |
||||
let(:name) { model.human_attribute_name(instance_key || class_key) } |
||||
let(:model) { WorkPackage } |
||||
end |
||||
|
||||
shared_examples_for 'basic query filter' do |
||||
include_context 'filter tests' |
||||
|
||||
let(:context) { project } |
||||
let(:project) { FactoryGirl.build_stubbed(:project) } |
||||
let(:instance_key) { nil } |
||||
let(:class_key) { raise 'needs to be defined' } |
||||
let(:type) { raise 'needs to be defined' } |
||||
let(:order) { nil } |
||||
|
||||
describe '.key' do |
||||
it 'is the defined key' do |
||||
expect(described_class.key).to eql(class_key) |
||||
end |
||||
end |
||||
|
||||
describe '#name' do |
||||
it 'is the defined key' do |
||||
expect(instance.name).to eql(instance_key || class_key) |
||||
end |
||||
end |
||||
|
||||
describe '#order' do |
||||
it 'has the defined order' do |
||||
if order |
||||
expect(instance.order).to eql(order) |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '#type' do |
||||
it 'is the defined filter type' do |
||||
expect(instance.type).to eql(type) |
||||
end |
||||
end |
||||
|
||||
describe '#human_name' do |
||||
it 'is the l10 name for the filter' do |
||||
expect(instance.human_name).to eql(name) |
||||
end |
||||
end |
||||
end |
||||
|
||||
shared_examples_for 'list query filter' do |
||||
include_context 'filter tests' |
||||
let(:attribute) { raise "needs to be defined" } |
||||
let(:type) { :list } |
||||
|
||||
describe '#scope' do |
||||
context 'for "="' do |
||||
let(:operator) { '=' } |
||||
let(:values) { valid_values } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = model.where(["#{model.table_name}.#{attribute} IN (?)", values]) |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "!"' do |
||||
let(:operator) { '!' } |
||||
let(:values) { valid_values } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
sql = "(#{model.table_name}.#{attribute} IS NULL |
||||
OR #{model.table_name}.#{attribute} NOT IN (?))".squish |
||||
expected = model.where([sql, values]) |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '#valid?' do |
||||
let(:operator) { '=' } |
||||
let(:values) { valid_values } |
||||
|
||||
it 'is valid' do |
||||
expect(instance).to be_valid |
||||
end |
||||
|
||||
context 'for an invalid operator' do |
||||
let(:operator) { '*' } |
||||
|
||||
it 'is invalid' do |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
|
||||
context 'for an invalid value' do |
||||
let(:values) { ['inexistent'] } |
||||
|
||||
it 'is invalid' do |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
shared_examples_for 'list_optional query filter' do |
||||
include_context 'filter tests' |
||||
let(:attribute) { raise "needs to be defined" } |
||||
let(:type) { :list_optional } |
||||
let(:joins) { nil } |
||||
let(:expected_base_scope) do |
||||
if joins |
||||
model.joins(joins) |
||||
else |
||||
model |
||||
end |
||||
end |
||||
let(:expected_table_name) do |
||||
if joins |
||||
joins |
||||
else |
||||
model.table_name |
||||
end |
||||
end |
||||
|
||||
describe '#scope' do |
||||
let(:values) { valid_values } |
||||
|
||||
context 'for "="' do |
||||
let(:operator) { '=' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = expected_base_scope |
||||
.where(["#{expected_table_name}.#{attribute} IN (?)", values]) |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "!"' do |
||||
let(:operator) { '!' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
sql = "(#{expected_table_name}.#{attribute} IS NULL |
||||
OR #{expected_table_name}.#{attribute} NOT IN (?))".squish |
||||
expected = expected_base_scope.where([sql, values]) |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "*"' do |
||||
let(:operator) { '*' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
sql = "#{expected_table_name}.#{attribute} IS NOT NULL" |
||||
expected = expected_base_scope.where([sql]) |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
|
||||
context 'for "!*"' do |
||||
let(:operator) { '!*' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
sql = "#{expected_table_name}.#{attribute} IS NULL" |
||||
expected = expected_base_scope.where([sql]) |
||||
|
||||
expect(instance.scope.to_sql).to eql expected.to_sql |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe '#valid?' do |
||||
let(:operator) { '=' } |
||||
let(:values) { valid_values } |
||||
|
||||
it 'is valid' do |
||||
expect(instance).to be_valid |
||||
end |
||||
|
||||
context 'for an invalid operator' do |
||||
let(:operator) { '~' } |
||||
|
||||
it 'is invalid' do |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
|
||||
context 'for an invalid value' do |
||||
let(:values) { ['inexistent'] } |
||||
|
||||
it 'is invalid' do |
||||
expect(instance).to be_invalid |
||||
end |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue