Merge pull request #8514 from opf/feature/milestone-filter
Add filter to select only (non-) milestonespull/8515/head
commit
2f1eb680c7
@ -0,0 +1,75 @@ |
||||
#-- encoding: UTF-8 |
||||
|
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-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::MilestoneFilter < Queries::WorkPackages::Filter::WorkPackageFilter |
||||
include Queries::Filters::Shared::BooleanFilter |
||||
|
||||
def self.key |
||||
:is_milestone |
||||
end |
||||
|
||||
def available? |
||||
types.exists? |
||||
end |
||||
|
||||
def dependency_class |
||||
'::API::V3::Queries::Schemas::BooleanFilterDependencyRepresenter' |
||||
end |
||||
|
||||
def where |
||||
if positive? |
||||
"type_id IN (#{milestone_subselect})" |
||||
else |
||||
"type_id NOT IN (#{milestone_subselect})" |
||||
end |
||||
end |
||||
|
||||
def positive? |
||||
(operator == '=' && values == [OpenProject::Database::DB_VALUE_TRUE]) || |
||||
(operator == '!' && values == [OpenProject::Database::DB_VALUE_FALSE]) |
||||
end |
||||
|
||||
def human_name |
||||
I18n.t('activerecord.attributes.type.is_milestone') |
||||
end |
||||
|
||||
private |
||||
|
||||
def types |
||||
project.nil? ? ::Type.order(Arel.sql('position')) : project.rolled_up_types |
||||
end |
||||
|
||||
def milestone_subselect |
||||
Type |
||||
.where(is_milestone: true) |
||||
.select(:id) |
||||
.to_sql |
||||
end |
||||
end |
@ -0,0 +1,135 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2020 the OpenProject GmbH |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-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::MilestoneFilter, type: :model do |
||||
it_behaves_like 'basic query filter' do |
||||
let(:type) { :list } |
||||
let(:class_key) { :is_milestone } |
||||
|
||||
describe '#available?' do |
||||
context 'within a project' do |
||||
before do |
||||
allow(project) |
||||
.to receive_message_chain(:rolled_up_types, :exists?) |
||||
.and_return true |
||||
end |
||||
|
||||
it 'is true' do |
||||
expect(instance).to be_available |
||||
end |
||||
|
||||
it 'is false without a type' do |
||||
allow(project) |
||||
.to receive_message_chain(:rolled_up_types, :exists?) |
||||
.and_return false |
||||
|
||||
expect(instance).to_not be_available |
||||
end |
||||
end |
||||
|
||||
context 'without a project' do |
||||
let(:project) { nil } |
||||
|
||||
before do |
||||
allow(Type) |
||||
.to receive_message_chain(:order, :exists?) |
||||
.and_return true |
||||
end |
||||
|
||||
it 'is true' do |
||||
expect(instance).to be_available |
||||
end |
||||
|
||||
it 'is false without a type' do |
||||
allow(Type) |
||||
.to receive_message_chain(:order, :exists?) |
||||
.and_return false |
||||
|
||||
expect(instance).to_not be_available |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
it_behaves_like 'boolean query filter', scope: false do |
||||
let(:model) { WorkPackage.unscoped } |
||||
let(:attribute) { :id } |
||||
|
||||
describe '#scope' do |
||||
context 'for the true value' do |
||||
let(:values) { [OpenProject::Database::DB_VALUE_TRUE] } |
||||
|
||||
context 'for "="' do |
||||
let(:operator) { '=' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = 'type_id IN (SELECT "types"."id" FROM "types" WHERE "types"."is_milestone" = TRUE ORDER BY position ASC)' |
||||
|
||||
expect(instance.where).to eql expected |
||||
end |
||||
end |
||||
|
||||
context 'for "!"' do |
||||
let(:operator) { '!' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = 'type_id NOT IN (SELECT "types"."id" FROM "types" WHERE "types"."is_milestone" = TRUE ORDER BY position ASC)' |
||||
|
||||
expect(instance.where).to eql expected |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'for the false value' do |
||||
let(:values) { [OpenProject::Database::DB_VALUE_FALSE] } |
||||
|
||||
context 'for "="' do |
||||
let(:operator) { '=' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = 'type_id NOT IN (SELECT "types"."id" FROM "types" WHERE "types"."is_milestone" = TRUE ORDER BY position ASC)' |
||||
|
||||
expect(instance.where).to eql expected |
||||
end |
||||
end |
||||
|
||||
context 'for "!"' do |
||||
let(:operator) { '!' } |
||||
|
||||
it 'is the same as handwriting the query' do |
||||
expected = 'type_id IN (SELECT "types"."id" FROM "types" WHERE "types"."is_milestone" = TRUE ORDER BY position ASC)' |
||||
|
||||
expect(instance.where).to eql expected |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue