Redmine 4.1.1
This commit is contained in:
parent
33e7b881a5
commit
3d976f1b3b
1593 changed files with 36180 additions and 19489 deletions
|
@ -1,7 +1,7 @@
|
|||
# encoding: utf-8
|
||||
#
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
|
@ -22,7 +22,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
|||
class QueryTest < ActiveSupport::TestCase
|
||||
include Redmine::I18n
|
||||
|
||||
fixtures :projects, :enabled_modules, :users, :members,
|
||||
fixtures :projects, :enabled_modules, :users, :user_preferences, :members,
|
||||
:member_roles, :roles, :trackers, :issue_statuses,
|
||||
:issue_categories, :enumerations, :issues,
|
||||
:watchers, :custom_fields, :custom_values, :versions,
|
||||
|
@ -30,7 +30,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
:projects_trackers,
|
||||
:custom_fields_trackers,
|
||||
:workflows, :journals,
|
||||
:attachments
|
||||
:attachments, :time_entries
|
||||
|
||||
INTEGER_KLASS = RUBY_VERSION >= "2.4" ? Integer : Fixnum
|
||||
|
||||
|
@ -106,8 +106,8 @@ class QueryTest < ActiveSupport::TestCase
|
|||
project_filter = query.available_filters["project_id"]
|
||||
assert_not_nil project_filter
|
||||
project_ids = project_filter[:values].map{|p| p[1]}
|
||||
assert project_ids.include?("1") #public project
|
||||
assert !project_ids.include?("2") #private project user cannot see
|
||||
assert project_ids.include?("1") # public project
|
||||
assert !project_ids.include?("2") # private project user cannot see
|
||||
end
|
||||
|
||||
def test_available_filters_should_not_include_fields_disabled_on_all_trackers
|
||||
|
@ -128,7 +128,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
q.available_filters.each do |name, filter|
|
||||
values = filter.values
|
||||
assert (values.nil? || values.is_a?(Array)),
|
||||
"#values for #{name} filter returned a #{values.class.name}"
|
||||
"#values for #{name} filter returned a #{values.class.name}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -139,7 +139,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
q.available_filters.each do |name, filter|
|
||||
values = filter.values
|
||||
assert (values.nil? || values.is_a?(Array)),
|
||||
"#values for #{name} filter returned a #{values.class.name}"
|
||||
"#values for #{name} filter returned a #{values.class.name}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -280,6 +280,26 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_equal [1,3], issues.map(&:id).sort
|
||||
end
|
||||
|
||||
def test_operator_is_on_parent_id_should_accept_comma_separated_values
|
||||
Issue.where(:id => [2,4]).update_all(:parent_id => 1)
|
||||
Issue.where(:id => 5).update_all(:parent_id => 3)
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.add_filter("parent_id", '=', ['1,3'])
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal 3, issues.size
|
||||
assert_equal [2,4,5], issues.map(&:id).sort
|
||||
end
|
||||
|
||||
def test_operator_is_on_child_id_should_accept_comma_separated_values
|
||||
Issue.where(:id => [2,4]).update_all(:parent_id => 1)
|
||||
Issue.where(:id => 5).update_all(:parent_id => 3)
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.add_filter("child_id", '=', ['2,4,5'])
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal 2, issues.size
|
||||
assert_equal [1,3], issues.map(&:id).sort
|
||||
end
|
||||
|
||||
def test_operator_between_on_issue_id_should_return_range
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.add_filter("issue_id", '><', ['2','3'])
|
||||
|
@ -519,7 +539,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
query = IssueQuery.new(:name => '_')
|
||||
query.add_filter('due_date', '=', ['2011-07-10'])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-07-09"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-07-10"} 23:59:59(\.\d+)?/,
|
||||
query.statement
|
||||
query.statement
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
|
@ -555,7 +575,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
query = IssueQuery.new(:name => '_')
|
||||
query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-06-22"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-07-10"} 23:59:59(\.\d+)?'/,
|
||||
query.statement
|
||||
query.statement
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
|
@ -638,8 +658,20 @@ class QueryTest < ActiveSupport::TestCase
|
|||
issues.each {|issue| assert_equal Date.today, issue.due_date}
|
||||
end
|
||||
|
||||
def test_operator_tomorrow
|
||||
issue = Issue.generate!(:due_date => User.current.today.tomorrow)
|
||||
other_issues = []
|
||||
other_issues << Issue.generate!(:due_date => User.current.today.yesterday)
|
||||
other_issues << Issue.generate!(:due_date => User.current.today + 2)
|
||||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'nd', [''])
|
||||
issues = find_issues_with_query(query)
|
||||
assert_include issue, issues
|
||||
other_issues.each {|i| assert_not_include i, issues }
|
||||
end
|
||||
|
||||
def test_operator_date_periods
|
||||
%w(t ld w lw l2w m lm y).each do |operator|
|
||||
%w(t ld w lw l2w m lm y nd nw nm).each do |operator|
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.add_filter('due_date', operator, [''])
|
||||
assert query.valid?
|
||||
|
@ -694,7 +726,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'w', [''])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-04-24"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-05-01"} 23:59:59(\.\d+)?/,
|
||||
query.statement
|
||||
query.statement
|
||||
I18n.locale = :en
|
||||
end
|
||||
|
||||
|
@ -707,7 +739,41 @@ class QueryTest < ActiveSupport::TestCase
|
|||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'w', [''])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-04-23"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-04-30"} 23:59:59(\.\d+)?/,
|
||||
query.statement
|
||||
query.statement
|
||||
end
|
||||
|
||||
def test_range_for_next_week_with_week_starting_on_monday
|
||||
I18n.locale = :fr
|
||||
assert_equal '1', I18n.t(:general_first_day_of_week)
|
||||
|
||||
Date.stubs(:today).returns(Date.parse('2011-04-29')) # Friday
|
||||
|
||||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'nw', [''])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-05-01"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-05-08"} 23:59:59(\.\d+)?/,
|
||||
query.statement
|
||||
I18n.locale = :en
|
||||
end
|
||||
|
||||
def test_range_for_next_week_with_week_starting_on_sunday
|
||||
I18n.locale = :en
|
||||
assert_equal '7', I18n.t(:general_first_day_of_week)
|
||||
|
||||
Date.stubs(:today).returns(Date.parse('2011-04-29')) # Friday
|
||||
|
||||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'nw', [''])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-04-30"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-05-07"} 23:59:59(\.\d+)?/,
|
||||
query.statement
|
||||
end
|
||||
|
||||
def test_range_for_next_month
|
||||
Date.stubs(:today).returns(Date.parse('2011-04-29')) # Friday
|
||||
|
||||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'nm', [''])
|
||||
assert_match /issues\.due_date > '#{quoted_date "2011-04-30"} 23:59:59(\.\d+)?' AND issues\.due_date <= '#{quoted_date "2011-05-31"} 23:59:59(\.\d+)?/,
|
||||
query.statement
|
||||
end
|
||||
|
||||
def test_filter_assigned_to_me
|
||||
|
@ -856,6 +922,55 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
|
||||
end
|
||||
|
||||
def test_filter_my_bookmarks
|
||||
User.current = User.find(1)
|
||||
query = ProjectQuery.new(:name => '_')
|
||||
filter = query.available_filters['id']
|
||||
assert_not_nil filter
|
||||
assert_include 'bookmarks', filter[:values].map{|v| v[1]}
|
||||
|
||||
query.filters = { 'id' => {:operator => '=', :values => ['bookmarks']}}
|
||||
result = query.results_scope
|
||||
|
||||
assert_equal [1,5], result.map(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_my_bookmarks_for_user_without_bookmarked_projects
|
||||
User.current = User.find(2)
|
||||
query = ProjectQuery.new(:name => '_')
|
||||
filter = query.available_filters['id']
|
||||
|
||||
assert_not_include 'bookmarks', filter[:values].map{|v| v[1]}
|
||||
end
|
||||
|
||||
def test_filter_project_parent_id_with_my_projects
|
||||
User.current = User.find(1)
|
||||
query = ProjectQuery.new(:name => '_')
|
||||
filter = query.available_filters['parent_id']
|
||||
assert_not_nil filter
|
||||
assert_include 'mine', filter[:values].map{|v| v[1]}
|
||||
|
||||
query.filters = { 'parent_id' => {:operator => '=', :values => ['mine']}}
|
||||
result = query.results_scope
|
||||
|
||||
my_projects = User.current.memberships.map(&:project_id)
|
||||
assert_equal Project.where(parent_id: my_projects).ids, result.map(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_project_parent_id_with_my_bookmarks
|
||||
User.current = User.find(1)
|
||||
query = ProjectQuery.new(:name => '_')
|
||||
filter = query.available_filters['parent_id']
|
||||
assert_not_nil filter
|
||||
assert_include 'bookmarks', filter[:values].map{|v| v[1]}
|
||||
|
||||
query.filters = { 'parent_id' => {:operator => '=', :values => ['bookmarks']}}
|
||||
result = query.results_scope
|
||||
|
||||
bookmarks = User.current.bookmarked_project_ids
|
||||
assert_equal Project.where(parent_id: bookmarks).ids, result.map(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_watched_issues
|
||||
User.current = User.find(1)
|
||||
query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
|
||||
|
@ -1066,6 +1181,10 @@ class QueryTest < ActiveSupport::TestCase
|
|||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {"relates" => {:operator => '=', :values => ['2']}}
|
||||
assert_equal [1], find_issues_with_query(query).map(&:id).sort
|
||||
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {"relates" => {:operator => '!', :values => ['1']}}
|
||||
assert_equal Issue.where.not(:id => [2, 3]).order(:id).ids, find_issues_with_query(query).map(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_on_relations_with_any_issues_in_a_project
|
||||
|
@ -1093,7 +1212,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
IssueRelation.delete_all
|
||||
with_settings :cross_project_issue_relations => '1' do
|
||||
IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
|
||||
#IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first)
|
||||
# IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first)
|
||||
IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
|
||||
end
|
||||
|
||||
|
@ -1201,7 +1320,6 @@ class QueryTest < ActiveSupport::TestCase
|
|||
Issue.delete_all
|
||||
parent = Issue.generate_with_descendants!
|
||||
|
||||
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {"parent_id" => {:operator => '=', :values => [parent.id.to_s]}}
|
||||
assert_equal parent.children.map(&:id).sort, find_issues_with_query(query).map(&:id).sort
|
||||
|
@ -1231,7 +1349,6 @@ class QueryTest < ActiveSupport::TestCase
|
|||
child, leaf = parent.children.sort_by(&:id)
|
||||
grandchild = child.children.first
|
||||
|
||||
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {"child_id" => {:operator => '=', :values => [grandchild.id.to_s]}}
|
||||
assert_equal [child.id], find_issues_with_query(query).map(&:id).sort
|
||||
|
@ -1287,6 +1404,34 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_nil issues.detect {|issue| issue.attachments.any? {|attachment| attachment.filename.include?('error281')}}
|
||||
end
|
||||
|
||||
def test_filter_on_attachment_when_starts_with
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {"attachment" => {:operator => '^', :values => ['testfile']}}
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal [14], issues.collect(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_on_attachment_when_ends_with
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {"attachment" => {:operator => '$', :values => ['zip']}}
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal [3, 4], issues.collect(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_on_subject_when_starts_with
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {'subject' => {:operator => '^', :values => ['issue']}}
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal [4, 6, 7, 10], issues.collect(&:id).sort
|
||||
end
|
||||
|
||||
def test_filter_on_subject_when_ends_with
|
||||
query = IssueQuery.new(:name => '_')
|
||||
query.filters = {'subject' => {:operator => '$', :values => ['issue']}}
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal [5, 8, 9], issues.collect(&:id).sort
|
||||
end
|
||||
|
||||
def test_statement_should_be_nil_with_no_filters
|
||||
q = IssueQuery.new(:name => '_')
|
||||
q.filters = {}
|
||||
|
@ -1490,9 +1635,15 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_equal [['id', 'desc']], q.sort_criteria
|
||||
end
|
||||
|
||||
def test_sort_criteria_should_remove_blank_keys
|
||||
def test_sort_criteria_should_have_only_first_three_elements
|
||||
q = IssueQuery.new
|
||||
q.sort_criteria = [['priority', 'desc'], [nil, 'desc'], ['', 'asc'], ['project', 'asc']]
|
||||
q.sort_criteria = [['priority', 'desc'], ['tracker', 'asc'], ['priority', 'asc'], ['id', 'asc'], ['project', 'asc'], ['subject', 'asc']]
|
||||
assert_equal [['priority', 'desc'], ['tracker', 'asc'], ['id', 'asc']], q.sort_criteria
|
||||
end
|
||||
|
||||
def test_sort_criteria_should_remove_blank_or_duplicate_keys
|
||||
q = IssueQuery.new
|
||||
q.sort_criteria = [['priority', 'desc'], [nil, 'desc'], ['', 'asc'], ['priority', 'asc'], ['project', 'asc']]
|
||||
assert_equal [['priority', 'desc'], ['project', 'asc']], q.sort_criteria
|
||||
end
|
||||
|
||||
|
@ -1521,7 +1672,8 @@ class QueryTest < ActiveSupport::TestCase
|
|||
c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
|
||||
assert c
|
||||
assert c.sortable
|
||||
issues = q.issues(:order => "#{c.sortable} ASC")
|
||||
q.sort_criteria = [[c.name.to_s, 'asc']]
|
||||
issues = q.issues
|
||||
values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
|
||||
assert !values.empty?
|
||||
assert_equal values.sort, values
|
||||
|
@ -1532,7 +1684,8 @@ class QueryTest < ActiveSupport::TestCase
|
|||
c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
|
||||
assert c
|
||||
assert c.sortable
|
||||
issues = q.issues(:order => "#{c.sortable} DESC")
|
||||
q.sort_criteria = [[c.name.to_s, 'desc']]
|
||||
issues = q.issues
|
||||
values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
|
||||
assert !values.empty?
|
||||
assert_equal values.sort.reverse, values
|
||||
|
@ -1543,12 +1696,41 @@ class QueryTest < ActiveSupport::TestCase
|
|||
c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
|
||||
assert c
|
||||
assert c.sortable
|
||||
issues = q.issues(:order => "#{c.sortable} ASC")
|
||||
q.sort_criteria = [[c.name.to_s, 'asc']]
|
||||
issues = q.issues
|
||||
values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
|
||||
assert !values.empty?
|
||||
assert_equal values.sort, values
|
||||
end
|
||||
|
||||
def test_sort_with_group_by_timestamp_query_column_should_sort_after_date_value
|
||||
User.current = User.find(1)
|
||||
|
||||
# Touch Issue#10 in order to be the last updated issue
|
||||
Issue.find(10).update_attribute(:updated_on, Issue.find(10).updated_on + 1)
|
||||
|
||||
q = IssueQuery.new(
|
||||
:name => '_',
|
||||
:filters => { 'updated_on' => {:operator => 't', :values => ['']} },
|
||||
:group_by => 'updated_on',
|
||||
:sort_criteria => [['subject', 'asc']]
|
||||
)
|
||||
|
||||
# The following 3 issues are updated today (ordered by updated_on):
|
||||
# Issue#10: Issue Doing the Blocking
|
||||
# Issue#9: Blocked Issue
|
||||
# Issue#6: Issue of a private subproject
|
||||
|
||||
# When we group by a timestamp query column, all the issues in the group have the same date value (today)
|
||||
# and the time of the value should not be taken into consideration when sorting
|
||||
#
|
||||
# For the same issues after subject ascending should return the following:
|
||||
# Issue#9: Blocked Issue
|
||||
# Issue#10: Issue Doing the Blocking
|
||||
# Issue#6: Issue of a private subproject
|
||||
assert_equal [9, 10, 6], q.issues.map(&:id)
|
||||
end
|
||||
|
||||
def test_sort_by_total_for_estimated_hours
|
||||
# Prepare issues
|
||||
parent = issues(:issues_001)
|
||||
|
@ -1565,7 +1747,6 @@ class QueryTest < ActiveSupport::TestCase
|
|||
|
||||
[parent, child, private_child, other].each(&:save!)
|
||||
|
||||
|
||||
q = IssueQuery.new(
|
||||
:name => '_',
|
||||
:filters => { 'issue_id' => {:operator => '=', :values => ['1,7']} },
|
||||
|
@ -1774,9 +1955,9 @@ class QueryTest < ActiveSupport::TestCase
|
|||
|
||||
def test_issue_ids
|
||||
q = IssueQuery.new(:name => '_')
|
||||
order = "issues.subject, issues.id"
|
||||
issues = q.issues(:order => order)
|
||||
assert_equal issues.map(&:id), q.issue_ids(:order => order)
|
||||
q.sort_criteria = ['subject', 'id']
|
||||
issues = q.issues
|
||||
assert_equal issues.map(&:id), q.issue_ids
|
||||
end
|
||||
|
||||
def test_label_for
|
||||
|
@ -1788,7 +1969,7 @@ class QueryTest < ActiveSupport::TestCase
|
|||
def test_label_for_fr
|
||||
set_language_if_valid 'fr'
|
||||
q = IssueQuery.new
|
||||
assert_equal "Assign\xc3\xa9 \xc3\xa0".force_encoding('UTF-8'), q.label_for('assigned_to_id')
|
||||
assert_equal 'Assigné à', q.label_for('assigned_to_id')
|
||||
end
|
||||
|
||||
def test_editable_by
|
||||
|
@ -1813,9 +1994,28 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert q.editable_by?(admin)
|
||||
assert !q.editable_by?(manager)
|
||||
assert q.editable_by?(developer)
|
||||
end
|
||||
|
||||
def test_editable_by_for_global_query
|
||||
admin = User.find(1)
|
||||
manager = User.find(2)
|
||||
developer = User.find(3)
|
||||
|
||||
# Public query for all projects
|
||||
q = IssueQuery.find(4)
|
||||
|
||||
assert q.editable_by?(admin)
|
||||
assert !q.editable_by?(manager)
|
||||
assert !q.editable_by?(developer)
|
||||
end
|
||||
|
||||
def test_editable_by_for_global_query_with_project_set
|
||||
admin = User.find(1)
|
||||
manager = User.find(2)
|
||||
developer = User.find(3)
|
||||
|
||||
q = IssueQuery.find(4)
|
||||
q.project = Project.find(1)
|
||||
|
||||
assert q.editable_by?(admin)
|
||||
assert !q.editable_by?(manager)
|
||||
assert !q.editable_by?(developer)
|
||||
|
@ -1884,10 +2084,25 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_nil IssueQuery.visible(User.find(1)).find_by_id(q.id)
|
||||
end
|
||||
|
||||
def test_build_from_params_should_not_update_query_with_nil_param_values
|
||||
q = IssueQuery.create!(:name => 'Query',
|
||||
:type => "IssueQuery",
|
||||
:user => User.find(7),
|
||||
:filters => {"status_id" => {:values => ["1"], :operator => "o"}},
|
||||
:column_names => [:tracker, :status],
|
||||
:sort_criteria => ['id', 'asc'],
|
||||
:group_by => "project",
|
||||
:options => { :totalable_names=>[:estimated_hours], :draw_relations => '1', :draw_progress_line => '1' }
|
||||
)
|
||||
old_attributes = q.attributes
|
||||
q.build_from_params({})
|
||||
assert_equal old_attributes, q.attributes
|
||||
end
|
||||
|
||||
test "#available_filters should include users of visible projects in cross-project view" do
|
||||
users = IssueQuery.new.available_filters["assigned_to_id"]
|
||||
assert_not_nil users
|
||||
assert users[:values].map{|u|u[1]}.include?("3")
|
||||
assert users[:values].map{|u| u[1]}.include?("3")
|
||||
end
|
||||
|
||||
test "#available_filters should include users of subprojects" do
|
||||
|
@ -1895,31 +2110,30 @@ class QueryTest < ActiveSupport::TestCase
|
|||
user2 = User.generate!
|
||||
project = Project.find(1)
|
||||
Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
|
||||
|
||||
users = IssueQuery.new(:project => project).available_filters["assigned_to_id"]
|
||||
assert_not_nil users
|
||||
assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
|
||||
assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
|
||||
assert users[:values].map{|u| u[1]}.include?(user1.id.to_s)
|
||||
assert !users[:values].map{|u| u[1]}.include?(user2.id.to_s)
|
||||
end
|
||||
|
||||
test "#available_filters should include visible projects in cross-project view" do
|
||||
projects = IssueQuery.new.available_filters["project_id"]
|
||||
assert_not_nil projects
|
||||
assert projects[:values].map{|u|u[1]}.include?("1")
|
||||
assert projects[:values].map{|u| u[1]}.include?("1")
|
||||
end
|
||||
|
||||
test "#available_filters should include 'member_of_group' filter" do
|
||||
query = IssueQuery.new
|
||||
assert query.available_filters.keys.include?("member_of_group")
|
||||
assert query.available_filters.key?("member_of_group")
|
||||
assert_equal :list_optional, query.available_filters["member_of_group"][:type]
|
||||
assert query.available_filters["member_of_group"][:values].present?
|
||||
assert_equal Group.givable.sort.map {|g| [g.name, g.id.to_s]},
|
||||
query.available_filters["member_of_group"][:values].sort
|
||||
query.available_filters["member_of_group"][:values].sort
|
||||
end
|
||||
|
||||
test "#available_filters should include 'assigned_to_role' filter" do
|
||||
query = IssueQuery.new
|
||||
assert query.available_filters.keys.include?("assigned_to_role")
|
||||
assert query.available_filters.key?("assigned_to_role")
|
||||
assert_equal :list_optional, query.available_filters["assigned_to_role"][:type]
|
||||
|
||||
assert query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
|
||||
|
@ -2215,6 +2429,30 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_equal ['1','2','3','4','5','6'], query.available_filters['status_id'][:values].map(&:second)
|
||||
end
|
||||
|
||||
def test_project_status_filter_should_be_available_in_global_queries
|
||||
query = IssueQuery.new(:project => nil, :name => '_')
|
||||
assert query.available_filters.has_key?('project.status')
|
||||
end
|
||||
|
||||
def test_project_status_filter_should_be_available_when_project_has_subprojects
|
||||
query = IssueQuery.new(:project => Project.find(1), :name => '_')
|
||||
assert query.available_filters.has_key?('project.status')
|
||||
end
|
||||
|
||||
def test_project_status_filter_should_not_be_available_when_project_is_leaf
|
||||
query = IssueQuery.new(:project => Project.find(2), :name => '_')
|
||||
assert !query.available_filters.has_key?('project.status')
|
||||
end
|
||||
|
||||
def test_project_statuses_values_should_return_only_active_and_closed_statuses
|
||||
set_language_if_valid 'en'
|
||||
query = IssueQuery.new(:project => nil, :name => '_')
|
||||
project_status_filter = query.available_filters['project.status']
|
||||
assert_not_nil project_status_filter
|
||||
|
||||
assert_equal [["active", "1"], ["closed", "5"]], project_status_filter[:values]
|
||||
end
|
||||
|
||||
def test_as_params_should_serialize_query
|
||||
query = IssueQuery.new(name: "_")
|
||||
query.add_filter('subject', '!~', ['asdf'])
|
||||
|
@ -2229,4 +2467,37 @@ class QueryTest < ActiveSupport::TestCase
|
|||
assert_equal query.column_names, new_query.column_names
|
||||
assert_equal query.totalable_names, new_query.totalable_names
|
||||
end
|
||||
|
||||
def test_issue_query_filter_by_spent_time
|
||||
query = IssueQuery.new(:name => '_')
|
||||
|
||||
query.filters = {'spent_time' => {:operator => '*', :values => ['']}}
|
||||
assert_equal [3, 1], query.issues.pluck(:id)
|
||||
|
||||
query.filters = {'spent_time' => {:operator => '!*', :values => ['']}}
|
||||
assert_equal [13, 12, 11, 8, 7, 5, 2], query.issues.pluck(:id)
|
||||
|
||||
query.filters = {'spent_time' => {:operator => '>=', :values => ['10']}}
|
||||
assert_equal [1], query.issues.pluck(:id)
|
||||
|
||||
query.filters = {'spent_time' => {:operator => '<=', :values => ['10']}}
|
||||
assert_equal [13, 12, 11, 8, 7, 5, 3, 2], query.issues.pluck(:id)
|
||||
|
||||
query.filters = {'spent_time' => {:operator => '><', :values => ['1', '2']}}
|
||||
assert_equal [3], query.issues.pluck(:id)
|
||||
end
|
||||
|
||||
def test_issues_should_be_in_the_same_order_when_paginating
|
||||
q = IssueQuery.new
|
||||
q.sort_criteria = {'0' => ['priority', 'desc']}
|
||||
issue_ids = q.issues.pluck(:id)
|
||||
paginated_issue_ids = []
|
||||
# Test with a maximum of 2 records per page.
|
||||
((q.issue_count / 2) + 1).times do |i|
|
||||
paginated_issue_ids += q.issues(:offset => (i * 2), :limit => 2).pluck(:id)
|
||||
end
|
||||
|
||||
# Non-paginated issue ids and paginated issue ids should be in the same order.
|
||||
assert_equal issue_ids, paginated_issue_ids
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue