##// END OF EJS Templates
add missing fixture to test/unit/query_test.rb...
Toshi MARUYAMA -
r13169:41023cb5ff66
parent child
Show More
@@ -1,1417 +1,1418
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class QueryTest < ActiveSupport::TestCase
20 class QueryTest < ActiveSupport::TestCase
21 include Redmine::I18n
21 include Redmine::I18n
22
22
23 fixtures :projects, :enabled_modules, :users, :members,
23 fixtures :projects, :enabled_modules, :users, :members,
24 :member_roles, :roles, :trackers, :issue_statuses,
24 :member_roles, :roles, :trackers, :issue_statuses,
25 :issue_categories, :enumerations, :issues,
25 :issue_categories, :enumerations, :issues,
26 :watchers, :custom_fields, :custom_values, :versions,
26 :watchers, :custom_fields, :custom_values, :versions,
27 :queries,
27 :queries,
28 :projects_trackers,
28 :projects_trackers,
29 :custom_fields_trackers
29 :custom_fields_trackers,
30 :workflows
30
31
31 def test_query_with_roles_visibility_should_validate_roles
32 def test_query_with_roles_visibility_should_validate_roles
32 set_language_if_valid 'en'
33 set_language_if_valid 'en'
33 query = IssueQuery.new(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES)
34 query = IssueQuery.new(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES)
34 assert !query.save
35 assert !query.save
35 assert_include "Roles can't be blank", query.errors.full_messages
36 assert_include "Roles can't be blank", query.errors.full_messages
36 query.role_ids = [1, 2]
37 query.role_ids = [1, 2]
37 assert query.save
38 assert query.save
38 end
39 end
39
40
40 def test_changing_roles_visibility_should_clear_roles
41 def test_changing_roles_visibility_should_clear_roles
41 query = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES, :role_ids => [1, 2])
42 query = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES, :role_ids => [1, 2])
42 assert_equal 2, query.roles.count
43 assert_equal 2, query.roles.count
43
44
44 query.visibility = IssueQuery::VISIBILITY_PUBLIC
45 query.visibility = IssueQuery::VISIBILITY_PUBLIC
45 query.save!
46 query.save!
46 assert_equal 0, query.roles.count
47 assert_equal 0, query.roles.count
47 end
48 end
48
49
49 def test_available_filters_should_be_ordered
50 def test_available_filters_should_be_ordered
50 set_language_if_valid 'en'
51 set_language_if_valid 'en'
51 query = IssueQuery.new
52 query = IssueQuery.new
52 assert_equal 0, query.available_filters.keys.index('status_id')
53 assert_equal 0, query.available_filters.keys.index('status_id')
53 expected_order = [
54 expected_order = [
54 "Status",
55 "Status",
55 "Project",
56 "Project",
56 "Tracker",
57 "Tracker",
57 "Priority"
58 "Priority"
58 ]
59 ]
59 assert_equal expected_order,
60 assert_equal expected_order,
60 (query.available_filters.values.map{|v| v[:name]} & expected_order)
61 (query.available_filters.values.map{|v| v[:name]} & expected_order)
61 end
62 end
62
63
63 def test_available_filters_with_custom_fields_should_be_ordered
64 def test_available_filters_with_custom_fields_should_be_ordered
64 set_language_if_valid 'en'
65 set_language_if_valid 'en'
65 UserCustomField.create!(
66 UserCustomField.create!(
66 :name => 'order test', :field_format => 'string',
67 :name => 'order test', :field_format => 'string',
67 :is_for_all => true, :is_filter => true
68 :is_for_all => true, :is_filter => true
68 )
69 )
69 query = IssueQuery.new
70 query = IssueQuery.new
70 expected_order = [
71 expected_order = [
71 "Searchable field",
72 "Searchable field",
72 "Database",
73 "Database",
73 "Project's Development status",
74 "Project's Development status",
74 "Author's order test",
75 "Author's order test",
75 "Assignee's order test"
76 "Assignee's order test"
76 ]
77 ]
77 assert_equal expected_order,
78 assert_equal expected_order,
78 (query.available_filters.values.map{|v| v[:name]} & expected_order)
79 (query.available_filters.values.map{|v| v[:name]} & expected_order)
79 end
80 end
80
81
81 def test_custom_fields_for_all_projects_should_be_available_in_global_queries
82 def test_custom_fields_for_all_projects_should_be_available_in_global_queries
82 query = IssueQuery.new(:project => nil, :name => '_')
83 query = IssueQuery.new(:project => nil, :name => '_')
83 assert query.available_filters.has_key?('cf_1')
84 assert query.available_filters.has_key?('cf_1')
84 assert !query.available_filters.has_key?('cf_3')
85 assert !query.available_filters.has_key?('cf_3')
85 end
86 end
86
87
87 def test_system_shared_versions_should_be_available_in_global_queries
88 def test_system_shared_versions_should_be_available_in_global_queries
88 Version.find(2).update_attribute :sharing, 'system'
89 Version.find(2).update_attribute :sharing, 'system'
89 query = IssueQuery.new(:project => nil, :name => '_')
90 query = IssueQuery.new(:project => nil, :name => '_')
90 assert query.available_filters.has_key?('fixed_version_id')
91 assert query.available_filters.has_key?('fixed_version_id')
91 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
92 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
92 end
93 end
93
94
94 def test_project_filter_in_global_queries
95 def test_project_filter_in_global_queries
95 query = IssueQuery.new(:project => nil, :name => '_')
96 query = IssueQuery.new(:project => nil, :name => '_')
96 project_filter = query.available_filters["project_id"]
97 project_filter = query.available_filters["project_id"]
97 assert_not_nil project_filter
98 assert_not_nil project_filter
98 project_ids = project_filter[:values].map{|p| p[1]}
99 project_ids = project_filter[:values].map{|p| p[1]}
99 assert project_ids.include?("1") #public project
100 assert project_ids.include?("1") #public project
100 assert !project_ids.include?("2") #private project user cannot see
101 assert !project_ids.include?("2") #private project user cannot see
101 end
102 end
102
103
103 def find_issues_with_query(query)
104 def find_issues_with_query(query)
104 Issue.joins(:status, :tracker, :project, :priority).where(
105 Issue.joins(:status, :tracker, :project, :priority).where(
105 query.statement
106 query.statement
106 ).to_a
107 ).to_a
107 end
108 end
108
109
109 def assert_find_issues_with_query_is_successful(query)
110 def assert_find_issues_with_query_is_successful(query)
110 assert_nothing_raised do
111 assert_nothing_raised do
111 find_issues_with_query(query)
112 find_issues_with_query(query)
112 end
113 end
113 end
114 end
114
115
115 def assert_query_statement_includes(query, condition)
116 def assert_query_statement_includes(query, condition)
116 assert_include condition, query.statement
117 assert_include condition, query.statement
117 end
118 end
118
119
119 def assert_query_result(expected, query)
120 def assert_query_result(expected, query)
120 assert_nothing_raised do
121 assert_nothing_raised do
121 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
122 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
122 assert_equal expected.size, query.issue_count
123 assert_equal expected.size, query.issue_count
123 end
124 end
124 end
125 end
125
126
126 def test_query_should_allow_shared_versions_for_a_project_query
127 def test_query_should_allow_shared_versions_for_a_project_query
127 subproject_version = Version.find(4)
128 subproject_version = Version.find(4)
128 query = IssueQuery.new(:project => Project.find(1), :name => '_')
129 query = IssueQuery.new(:project => Project.find(1), :name => '_')
129 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
130 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
130
131
131 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
132 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
132 end
133 end
133
134
134 def test_query_with_multiple_custom_fields
135 def test_query_with_multiple_custom_fields
135 query = IssueQuery.find(1)
136 query = IssueQuery.find(1)
136 assert query.valid?
137 assert query.valid?
137 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
138 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
138 issues = find_issues_with_query(query)
139 issues = find_issues_with_query(query)
139 assert_equal 1, issues.length
140 assert_equal 1, issues.length
140 assert_equal Issue.find(3), issues.first
141 assert_equal Issue.find(3), issues.first
141 end
142 end
142
143
143 def test_operator_none
144 def test_operator_none
144 query = IssueQuery.new(:project => Project.find(1), :name => '_')
145 query = IssueQuery.new(:project => Project.find(1), :name => '_')
145 query.add_filter('fixed_version_id', '!*', [''])
146 query.add_filter('fixed_version_id', '!*', [''])
146 query.add_filter('cf_1', '!*', [''])
147 query.add_filter('cf_1', '!*', [''])
147 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
148 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
148 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
149 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
149 find_issues_with_query(query)
150 find_issues_with_query(query)
150 end
151 end
151
152
152 def test_operator_none_for_integer
153 def test_operator_none_for_integer
153 query = IssueQuery.new(:project => Project.find(1), :name => '_')
154 query = IssueQuery.new(:project => Project.find(1), :name => '_')
154 query.add_filter('estimated_hours', '!*', [''])
155 query.add_filter('estimated_hours', '!*', [''])
155 issues = find_issues_with_query(query)
156 issues = find_issues_with_query(query)
156 assert !issues.empty?
157 assert !issues.empty?
157 assert issues.all? {|i| !i.estimated_hours}
158 assert issues.all? {|i| !i.estimated_hours}
158 end
159 end
159
160
160 def test_operator_none_for_date
161 def test_operator_none_for_date
161 query = IssueQuery.new(:project => Project.find(1), :name => '_')
162 query = IssueQuery.new(:project => Project.find(1), :name => '_')
162 query.add_filter('start_date', '!*', [''])
163 query.add_filter('start_date', '!*', [''])
163 issues = find_issues_with_query(query)
164 issues = find_issues_with_query(query)
164 assert !issues.empty?
165 assert !issues.empty?
165 assert issues.all? {|i| i.start_date.nil?}
166 assert issues.all? {|i| i.start_date.nil?}
166 end
167 end
167
168
168 def test_operator_none_for_string_custom_field
169 def test_operator_none_for_string_custom_field
169 query = IssueQuery.new(:project => Project.find(1), :name => '_')
170 query = IssueQuery.new(:project => Project.find(1), :name => '_')
170 query.add_filter('cf_2', '!*', [''])
171 query.add_filter('cf_2', '!*', [''])
171 assert query.has_filter?('cf_2')
172 assert query.has_filter?('cf_2')
172 issues = find_issues_with_query(query)
173 issues = find_issues_with_query(query)
173 assert !issues.empty?
174 assert !issues.empty?
174 assert issues.all? {|i| i.custom_field_value(2).blank?}
175 assert issues.all? {|i| i.custom_field_value(2).blank?}
175 end
176 end
176
177
177 def test_operator_all
178 def test_operator_all
178 query = IssueQuery.new(:project => Project.find(1), :name => '_')
179 query = IssueQuery.new(:project => Project.find(1), :name => '_')
179 query.add_filter('fixed_version_id', '*', [''])
180 query.add_filter('fixed_version_id', '*', [''])
180 query.add_filter('cf_1', '*', [''])
181 query.add_filter('cf_1', '*', [''])
181 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
182 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
182 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
183 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
183 find_issues_with_query(query)
184 find_issues_with_query(query)
184 end
185 end
185
186
186 def test_operator_all_for_date
187 def test_operator_all_for_date
187 query = IssueQuery.new(:project => Project.find(1), :name => '_')
188 query = IssueQuery.new(:project => Project.find(1), :name => '_')
188 query.add_filter('start_date', '*', [''])
189 query.add_filter('start_date', '*', [''])
189 issues = find_issues_with_query(query)
190 issues = find_issues_with_query(query)
190 assert !issues.empty?
191 assert !issues.empty?
191 assert issues.all? {|i| i.start_date.present?}
192 assert issues.all? {|i| i.start_date.present?}
192 end
193 end
193
194
194 def test_operator_all_for_string_custom_field
195 def test_operator_all_for_string_custom_field
195 query = IssueQuery.new(:project => Project.find(1), :name => '_')
196 query = IssueQuery.new(:project => Project.find(1), :name => '_')
196 query.add_filter('cf_2', '*', [''])
197 query.add_filter('cf_2', '*', [''])
197 assert query.has_filter?('cf_2')
198 assert query.has_filter?('cf_2')
198 issues = find_issues_with_query(query)
199 issues = find_issues_with_query(query)
199 assert !issues.empty?
200 assert !issues.empty?
200 assert issues.all? {|i| i.custom_field_value(2).present?}
201 assert issues.all? {|i| i.custom_field_value(2).present?}
201 end
202 end
202
203
203 def test_numeric_filter_should_not_accept_non_numeric_values
204 def test_numeric_filter_should_not_accept_non_numeric_values
204 query = IssueQuery.new(:name => '_')
205 query = IssueQuery.new(:name => '_')
205 query.add_filter('estimated_hours', '=', ['a'])
206 query.add_filter('estimated_hours', '=', ['a'])
206
207
207 assert query.has_filter?('estimated_hours')
208 assert query.has_filter?('estimated_hours')
208 assert !query.valid?
209 assert !query.valid?
209 end
210 end
210
211
211 def test_operator_is_on_float
212 def test_operator_is_on_float
212 Issue.where(:id => 2).update_all("estimated_hours = 171.2")
213 Issue.where(:id => 2).update_all("estimated_hours = 171.2")
213 query = IssueQuery.new(:name => '_')
214 query = IssueQuery.new(:name => '_')
214 query.add_filter('estimated_hours', '=', ['171.20'])
215 query.add_filter('estimated_hours', '=', ['171.20'])
215 issues = find_issues_with_query(query)
216 issues = find_issues_with_query(query)
216 assert_equal 1, issues.size
217 assert_equal 1, issues.size
217 assert_equal 2, issues.first.id
218 assert_equal 2, issues.first.id
218 end
219 end
219
220
220 def test_operator_is_on_integer_custom_field
221 def test_operator_is_on_integer_custom_field
221 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true, :trackers => Tracker.all)
222 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true, :trackers => Tracker.all)
222 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
223 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
223 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
224 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
224 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
225 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
225
226
226 query = IssueQuery.new(:name => '_')
227 query = IssueQuery.new(:name => '_')
227 query.add_filter("cf_#{f.id}", '=', ['12'])
228 query.add_filter("cf_#{f.id}", '=', ['12'])
228 issues = find_issues_with_query(query)
229 issues = find_issues_with_query(query)
229 assert_equal 1, issues.size
230 assert_equal 1, issues.size
230 assert_equal 2, issues.first.id
231 assert_equal 2, issues.first.id
231 end
232 end
232
233
233 def test_operator_is_on_integer_custom_field_should_accept_negative_value
234 def test_operator_is_on_integer_custom_field_should_accept_negative_value
234 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true, :trackers => Tracker.all)
235 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true, :trackers => Tracker.all)
235 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
236 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
236 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12')
237 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12')
237 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
238 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
238
239
239 query = IssueQuery.new(:name => '_')
240 query = IssueQuery.new(:name => '_')
240 query.add_filter("cf_#{f.id}", '=', ['-12'])
241 query.add_filter("cf_#{f.id}", '=', ['-12'])
241 assert query.valid?
242 assert query.valid?
242 issues = find_issues_with_query(query)
243 issues = find_issues_with_query(query)
243 assert_equal 1, issues.size
244 assert_equal 1, issues.size
244 assert_equal 2, issues.first.id
245 assert_equal 2, issues.first.id
245 end
246 end
246
247
247 def test_operator_is_on_float_custom_field
248 def test_operator_is_on_float_custom_field
248 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
249 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
249 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
250 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
250 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
251 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
251 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
252 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
252
253
253 query = IssueQuery.new(:name => '_')
254 query = IssueQuery.new(:name => '_')
254 query.add_filter("cf_#{f.id}", '=', ['12.7'])
255 query.add_filter("cf_#{f.id}", '=', ['12.7'])
255 issues = find_issues_with_query(query)
256 issues = find_issues_with_query(query)
256 assert_equal 1, issues.size
257 assert_equal 1, issues.size
257 assert_equal 2, issues.first.id
258 assert_equal 2, issues.first.id
258 end
259 end
259
260
260 def test_operator_is_on_float_custom_field_should_accept_negative_value
261 def test_operator_is_on_float_custom_field_should_accept_negative_value
261 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
262 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
262 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
263 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
263 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12.7')
264 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '-12.7')
264 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
265 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
265
266
266 query = IssueQuery.new(:name => '_')
267 query = IssueQuery.new(:name => '_')
267 query.add_filter("cf_#{f.id}", '=', ['-12.7'])
268 query.add_filter("cf_#{f.id}", '=', ['-12.7'])
268 assert query.valid?
269 assert query.valid?
269 issues = find_issues_with_query(query)
270 issues = find_issues_with_query(query)
270 assert_equal 1, issues.size
271 assert_equal 1, issues.size
271 assert_equal 2, issues.first.id
272 assert_equal 2, issues.first.id
272 end
273 end
273
274
274 def test_operator_is_on_multi_list_custom_field
275 def test_operator_is_on_multi_list_custom_field
275 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
276 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
276 :possible_values => ['value1', 'value2', 'value3'], :multiple => true, :trackers => Tracker.all)
277 :possible_values => ['value1', 'value2', 'value3'], :multiple => true, :trackers => Tracker.all)
277 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
278 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
278 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
279 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
279 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
280 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
280
281
281 query = IssueQuery.new(:name => '_')
282 query = IssueQuery.new(:name => '_')
282 query.add_filter("cf_#{f.id}", '=', ['value1'])
283 query.add_filter("cf_#{f.id}", '=', ['value1'])
283 issues = find_issues_with_query(query)
284 issues = find_issues_with_query(query)
284 assert_equal [1, 3], issues.map(&:id).sort
285 assert_equal [1, 3], issues.map(&:id).sort
285
286
286 query = IssueQuery.new(:name => '_')
287 query = IssueQuery.new(:name => '_')
287 query.add_filter("cf_#{f.id}", '=', ['value2'])
288 query.add_filter("cf_#{f.id}", '=', ['value2'])
288 issues = find_issues_with_query(query)
289 issues = find_issues_with_query(query)
289 assert_equal [1], issues.map(&:id).sort
290 assert_equal [1], issues.map(&:id).sort
290 end
291 end
291
292
292 def test_operator_is_not_on_multi_list_custom_field
293 def test_operator_is_not_on_multi_list_custom_field
293 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
294 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
294 :possible_values => ['value1', 'value2', 'value3'], :multiple => true, :trackers => Tracker.all)
295 :possible_values => ['value1', 'value2', 'value3'], :multiple => true, :trackers => Tracker.all)
295 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
296 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
296 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
297 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
297 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
298 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
298
299
299 query = IssueQuery.new(:name => '_')
300 query = IssueQuery.new(:name => '_')
300 query.add_filter("cf_#{f.id}", '!', ['value1'])
301 query.add_filter("cf_#{f.id}", '!', ['value1'])
301 issues = find_issues_with_query(query)
302 issues = find_issues_with_query(query)
302 assert !issues.map(&:id).include?(1)
303 assert !issues.map(&:id).include?(1)
303 assert !issues.map(&:id).include?(3)
304 assert !issues.map(&:id).include?(3)
304
305
305 query = IssueQuery.new(:name => '_')
306 query = IssueQuery.new(:name => '_')
306 query.add_filter("cf_#{f.id}", '!', ['value2'])
307 query.add_filter("cf_#{f.id}", '!', ['value2'])
307 issues = find_issues_with_query(query)
308 issues = find_issues_with_query(query)
308 assert !issues.map(&:id).include?(1)
309 assert !issues.map(&:id).include?(1)
309 assert issues.map(&:id).include?(3)
310 assert issues.map(&:id).include?(3)
310 end
311 end
311
312
312 def test_operator_is_on_is_private_field
313 def test_operator_is_on_is_private_field
313 # is_private filter only available for those who can set issues private
314 # is_private filter only available for those who can set issues private
314 User.current = User.find(2)
315 User.current = User.find(2)
315
316
316 query = IssueQuery.new(:name => '_')
317 query = IssueQuery.new(:name => '_')
317 assert query.available_filters.key?('is_private')
318 assert query.available_filters.key?('is_private')
318
319
319 query.add_filter("is_private", '=', ['1'])
320 query.add_filter("is_private", '=', ['1'])
320 issues = find_issues_with_query(query)
321 issues = find_issues_with_query(query)
321 assert issues.any?
322 assert issues.any?
322 assert_nil issues.detect {|issue| !issue.is_private?}
323 assert_nil issues.detect {|issue| !issue.is_private?}
323 ensure
324 ensure
324 User.current = nil
325 User.current = nil
325 end
326 end
326
327
327 def test_operator_is_not_on_is_private_field
328 def test_operator_is_not_on_is_private_field
328 # is_private filter only available for those who can set issues private
329 # is_private filter only available for those who can set issues private
329 User.current = User.find(2)
330 User.current = User.find(2)
330
331
331 query = IssueQuery.new(:name => '_')
332 query = IssueQuery.new(:name => '_')
332 assert query.available_filters.key?('is_private')
333 assert query.available_filters.key?('is_private')
333
334
334 query.add_filter("is_private", '!', ['1'])
335 query.add_filter("is_private", '!', ['1'])
335 issues = find_issues_with_query(query)
336 issues = find_issues_with_query(query)
336 assert issues.any?
337 assert issues.any?
337 assert_nil issues.detect {|issue| issue.is_private?}
338 assert_nil issues.detect {|issue| issue.is_private?}
338 ensure
339 ensure
339 User.current = nil
340 User.current = nil
340 end
341 end
341
342
342 def test_operator_greater_than
343 def test_operator_greater_than
343 query = IssueQuery.new(:project => Project.find(1), :name => '_')
344 query = IssueQuery.new(:project => Project.find(1), :name => '_')
344 query.add_filter('done_ratio', '>=', ['40'])
345 query.add_filter('done_ratio', '>=', ['40'])
345 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
346 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
346 find_issues_with_query(query)
347 find_issues_with_query(query)
347 end
348 end
348
349
349 def test_operator_greater_than_a_float
350 def test_operator_greater_than_a_float
350 query = IssueQuery.new(:project => Project.find(1), :name => '_')
351 query = IssueQuery.new(:project => Project.find(1), :name => '_')
351 query.add_filter('estimated_hours', '>=', ['40.5'])
352 query.add_filter('estimated_hours', '>=', ['40.5'])
352 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
353 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
353 find_issues_with_query(query)
354 find_issues_with_query(query)
354 end
355 end
355
356
356 def test_operator_greater_than_on_int_custom_field
357 def test_operator_greater_than_on_int_custom_field
357 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
358 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
358 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
359 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
359 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
360 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
360 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
361 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
361
362
362 query = IssueQuery.new(:project => Project.find(1), :name => '_')
363 query = IssueQuery.new(:project => Project.find(1), :name => '_')
363 query.add_filter("cf_#{f.id}", '>=', ['8'])
364 query.add_filter("cf_#{f.id}", '>=', ['8'])
364 issues = find_issues_with_query(query)
365 issues = find_issues_with_query(query)
365 assert_equal 1, issues.size
366 assert_equal 1, issues.size
366 assert_equal 2, issues.first.id
367 assert_equal 2, issues.first.id
367 end
368 end
368
369
369 def test_operator_lesser_than
370 def test_operator_lesser_than
370 query = IssueQuery.new(:project => Project.find(1), :name => '_')
371 query = IssueQuery.new(:project => Project.find(1), :name => '_')
371 query.add_filter('done_ratio', '<=', ['30'])
372 query.add_filter('done_ratio', '<=', ['30'])
372 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
373 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
373 find_issues_with_query(query)
374 find_issues_with_query(query)
374 end
375 end
375
376
376 def test_operator_lesser_than_on_custom_field
377 def test_operator_lesser_than_on_custom_field
377 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
378 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
378 query = IssueQuery.new(:project => Project.find(1), :name => '_')
379 query = IssueQuery.new(:project => Project.find(1), :name => '_')
379 query.add_filter("cf_#{f.id}", '<=', ['30'])
380 query.add_filter("cf_#{f.id}", '<=', ['30'])
380 assert_match /CAST.+ <= 30\.0/, query.statement
381 assert_match /CAST.+ <= 30\.0/, query.statement
381 find_issues_with_query(query)
382 find_issues_with_query(query)
382 end
383 end
383
384
384 def test_operator_lesser_than_on_date_custom_field
385 def test_operator_lesser_than_on_date_custom_field
385 f = IssueCustomField.create!(:name => 'filter', :field_format => 'date', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
386 f = IssueCustomField.create!(:name => 'filter', :field_format => 'date', :is_filter => true, :is_for_all => true, :trackers => Tracker.all)
386 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '2013-04-11')
387 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '2013-04-11')
387 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '2013-05-14')
388 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '2013-05-14')
388 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
389 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
389
390
390 query = IssueQuery.new(:project => Project.find(1), :name => '_')
391 query = IssueQuery.new(:project => Project.find(1), :name => '_')
391 query.add_filter("cf_#{f.id}", '<=', ['2013-05-01'])
392 query.add_filter("cf_#{f.id}", '<=', ['2013-05-01'])
392 issue_ids = find_issues_with_query(query).map(&:id)
393 issue_ids = find_issues_with_query(query).map(&:id)
393 assert_include 1, issue_ids
394 assert_include 1, issue_ids
394 assert_not_include 2, issue_ids
395 assert_not_include 2, issue_ids
395 assert_not_include 3, issue_ids
396 assert_not_include 3, issue_ids
396 end
397 end
397
398
398 def test_operator_between
399 def test_operator_between
399 query = IssueQuery.new(:project => Project.find(1), :name => '_')
400 query = IssueQuery.new(:project => Project.find(1), :name => '_')
400 query.add_filter('done_ratio', '><', ['30', '40'])
401 query.add_filter('done_ratio', '><', ['30', '40'])
401 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
402 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
402 find_issues_with_query(query)
403 find_issues_with_query(query)
403 end
404 end
404
405
405 def test_operator_between_on_custom_field
406 def test_operator_between_on_custom_field
406 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
407 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
407 query = IssueQuery.new(:project => Project.find(1), :name => '_')
408 query = IssueQuery.new(:project => Project.find(1), :name => '_')
408 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
409 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
409 assert_match /CAST.+ BETWEEN 30.0 AND 40.0/, query.statement
410 assert_match /CAST.+ BETWEEN 30.0 AND 40.0/, query.statement
410 find_issues_with_query(query)
411 find_issues_with_query(query)
411 end
412 end
412
413
413 def test_date_filter_should_not_accept_non_date_values
414 def test_date_filter_should_not_accept_non_date_values
414 query = IssueQuery.new(:name => '_')
415 query = IssueQuery.new(:name => '_')
415 query.add_filter('created_on', '=', ['a'])
416 query.add_filter('created_on', '=', ['a'])
416
417
417 assert query.has_filter?('created_on')
418 assert query.has_filter?('created_on')
418 assert !query.valid?
419 assert !query.valid?
419 end
420 end
420
421
421 def test_date_filter_should_not_accept_invalid_date_values
422 def test_date_filter_should_not_accept_invalid_date_values
422 query = IssueQuery.new(:name => '_')
423 query = IssueQuery.new(:name => '_')
423 query.add_filter('created_on', '=', ['2011-01-34'])
424 query.add_filter('created_on', '=', ['2011-01-34'])
424
425
425 assert query.has_filter?('created_on')
426 assert query.has_filter?('created_on')
426 assert !query.valid?
427 assert !query.valid?
427 end
428 end
428
429
429 def test_relative_date_filter_should_not_accept_non_integer_values
430 def test_relative_date_filter_should_not_accept_non_integer_values
430 query = IssueQuery.new(:name => '_')
431 query = IssueQuery.new(:name => '_')
431 query.add_filter('created_on', '>t-', ['a'])
432 query.add_filter('created_on', '>t-', ['a'])
432
433
433 assert query.has_filter?('created_on')
434 assert query.has_filter?('created_on')
434 assert !query.valid?
435 assert !query.valid?
435 end
436 end
436
437
437 def test_operator_date_equals
438 def test_operator_date_equals
438 query = IssueQuery.new(:name => '_')
439 query = IssueQuery.new(:name => '_')
439 query.add_filter('due_date', '=', ['2011-07-10'])
440 query.add_filter('due_date', '=', ['2011-07-10'])
440 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
441 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
441 find_issues_with_query(query)
442 find_issues_with_query(query)
442 end
443 end
443
444
444 def test_operator_date_lesser_than
445 def test_operator_date_lesser_than
445 query = IssueQuery.new(:name => '_')
446 query = IssueQuery.new(:name => '_')
446 query.add_filter('due_date', '<=', ['2011-07-10'])
447 query.add_filter('due_date', '<=', ['2011-07-10'])
447 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
448 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
448 find_issues_with_query(query)
449 find_issues_with_query(query)
449 end
450 end
450
451
451 def test_operator_date_lesser_than_with_timestamp
452 def test_operator_date_lesser_than_with_timestamp
452 query = IssueQuery.new(:name => '_')
453 query = IssueQuery.new(:name => '_')
453 query.add_filter('updated_on', '<=', ['2011-07-10T19:13:52'])
454 query.add_filter('updated_on', '<=', ['2011-07-10T19:13:52'])
454 assert_match /issues\.updated_on <= '2011-07-10 19:13:52/, query.statement
455 assert_match /issues\.updated_on <= '2011-07-10 19:13:52/, query.statement
455 find_issues_with_query(query)
456 find_issues_with_query(query)
456 end
457 end
457
458
458 def test_operator_date_greater_than
459 def test_operator_date_greater_than
459 query = IssueQuery.new(:name => '_')
460 query = IssueQuery.new(:name => '_')
460 query.add_filter('due_date', '>=', ['2011-07-10'])
461 query.add_filter('due_date', '>=', ['2011-07-10'])
461 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
462 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
462 find_issues_with_query(query)
463 find_issues_with_query(query)
463 end
464 end
464
465
465 def test_operator_date_greater_than_with_timestamp
466 def test_operator_date_greater_than_with_timestamp
466 query = IssueQuery.new(:name => '_')
467 query = IssueQuery.new(:name => '_')
467 query.add_filter('updated_on', '>=', ['2011-07-10T19:13:52'])
468 query.add_filter('updated_on', '>=', ['2011-07-10T19:13:52'])
468 assert_match /issues\.updated_on > '2011-07-10 19:13:51(\.0+)?'/, query.statement
469 assert_match /issues\.updated_on > '2011-07-10 19:13:51(\.0+)?'/, query.statement
469 find_issues_with_query(query)
470 find_issues_with_query(query)
470 end
471 end
471
472
472 def test_operator_date_between
473 def test_operator_date_between
473 query = IssueQuery.new(:name => '_')
474 query = IssueQuery.new(:name => '_')
474 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
475 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
475 assert_match /issues\.due_date > '2011-06-22 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?'/, query.statement
476 assert_match /issues\.due_date > '2011-06-22 23:59:59(\.9+)?' AND issues\.due_date <= '2011-07-10 23:59:59(\.9+)?'/, query.statement
476 find_issues_with_query(query)
477 find_issues_with_query(query)
477 end
478 end
478
479
479 def test_operator_in_more_than
480 def test_operator_in_more_than
480 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
481 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
481 query = IssueQuery.new(:project => Project.find(1), :name => '_')
482 query = IssueQuery.new(:project => Project.find(1), :name => '_')
482 query.add_filter('due_date', '>t+', ['15'])
483 query.add_filter('due_date', '>t+', ['15'])
483 issues = find_issues_with_query(query)
484 issues = find_issues_with_query(query)
484 assert !issues.empty?
485 assert !issues.empty?
485 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
486 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
486 end
487 end
487
488
488 def test_operator_in_less_than
489 def test_operator_in_less_than
489 query = IssueQuery.new(:project => Project.find(1), :name => '_')
490 query = IssueQuery.new(:project => Project.find(1), :name => '_')
490 query.add_filter('due_date', '<t+', ['15'])
491 query.add_filter('due_date', '<t+', ['15'])
491 issues = find_issues_with_query(query)
492 issues = find_issues_with_query(query)
492 assert !issues.empty?
493 assert !issues.empty?
493 issues.each {|issue| assert(issue.due_date <= (Date.today + 15))}
494 issues.each {|issue| assert(issue.due_date <= (Date.today + 15))}
494 end
495 end
495
496
496 def test_operator_in_the_next_days
497 def test_operator_in_the_next_days
497 query = IssueQuery.new(:project => Project.find(1), :name => '_')
498 query = IssueQuery.new(:project => Project.find(1), :name => '_')
498 query.add_filter('due_date', '><t+', ['15'])
499 query.add_filter('due_date', '><t+', ['15'])
499 issues = find_issues_with_query(query)
500 issues = find_issues_with_query(query)
500 assert !issues.empty?
501 assert !issues.empty?
501 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
502 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
502 end
503 end
503
504
504 def test_operator_less_than_ago
505 def test_operator_less_than_ago
505 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
506 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
506 query = IssueQuery.new(:project => Project.find(1), :name => '_')
507 query = IssueQuery.new(:project => Project.find(1), :name => '_')
507 query.add_filter('due_date', '>t-', ['3'])
508 query.add_filter('due_date', '>t-', ['3'])
508 issues = find_issues_with_query(query)
509 issues = find_issues_with_query(query)
509 assert !issues.empty?
510 assert !issues.empty?
510 issues.each {|issue| assert(issue.due_date >= (Date.today - 3))}
511 issues.each {|issue| assert(issue.due_date >= (Date.today - 3))}
511 end
512 end
512
513
513 def test_operator_in_the_past_days
514 def test_operator_in_the_past_days
514 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
515 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
515 query = IssueQuery.new(:project => Project.find(1), :name => '_')
516 query = IssueQuery.new(:project => Project.find(1), :name => '_')
516 query.add_filter('due_date', '><t-', ['3'])
517 query.add_filter('due_date', '><t-', ['3'])
517 issues = find_issues_with_query(query)
518 issues = find_issues_with_query(query)
518 assert !issues.empty?
519 assert !issues.empty?
519 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
520 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
520 end
521 end
521
522
522 def test_operator_more_than_ago
523 def test_operator_more_than_ago
523 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
524 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
524 query = IssueQuery.new(:project => Project.find(1), :name => '_')
525 query = IssueQuery.new(:project => Project.find(1), :name => '_')
525 query.add_filter('due_date', '<t-', ['10'])
526 query.add_filter('due_date', '<t-', ['10'])
526 assert query.statement.include?("#{Issue.table_name}.due_date <=")
527 assert query.statement.include?("#{Issue.table_name}.due_date <=")
527 issues = find_issues_with_query(query)
528 issues = find_issues_with_query(query)
528 assert !issues.empty?
529 assert !issues.empty?
529 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
530 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
530 end
531 end
531
532
532 def test_operator_in
533 def test_operator_in
533 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
534 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
534 query = IssueQuery.new(:project => Project.find(1), :name => '_')
535 query = IssueQuery.new(:project => Project.find(1), :name => '_')
535 query.add_filter('due_date', 't+', ['2'])
536 query.add_filter('due_date', 't+', ['2'])
536 issues = find_issues_with_query(query)
537 issues = find_issues_with_query(query)
537 assert !issues.empty?
538 assert !issues.empty?
538 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
539 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
539 end
540 end
540
541
541 def test_operator_ago
542 def test_operator_ago
542 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
543 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
543 query = IssueQuery.new(:project => Project.find(1), :name => '_')
544 query = IssueQuery.new(:project => Project.find(1), :name => '_')
544 query.add_filter('due_date', 't-', ['3'])
545 query.add_filter('due_date', 't-', ['3'])
545 issues = find_issues_with_query(query)
546 issues = find_issues_with_query(query)
546 assert !issues.empty?
547 assert !issues.empty?
547 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
548 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
548 end
549 end
549
550
550 def test_operator_today
551 def test_operator_today
551 query = IssueQuery.new(:project => Project.find(1), :name => '_')
552 query = IssueQuery.new(:project => Project.find(1), :name => '_')
552 query.add_filter('due_date', 't', [''])
553 query.add_filter('due_date', 't', [''])
553 issues = find_issues_with_query(query)
554 issues = find_issues_with_query(query)
554 assert !issues.empty?
555 assert !issues.empty?
555 issues.each {|issue| assert_equal Date.today, issue.due_date}
556 issues.each {|issue| assert_equal Date.today, issue.due_date}
556 end
557 end
557
558
558 def test_operator_this_week_on_date
559 def test_operator_this_week_on_date
559 query = IssueQuery.new(:project => Project.find(1), :name => '_')
560 query = IssueQuery.new(:project => Project.find(1), :name => '_')
560 query.add_filter('due_date', 'w', [''])
561 query.add_filter('due_date', 'w', [''])
561 find_issues_with_query(query)
562 find_issues_with_query(query)
562 end
563 end
563
564
564 def test_operator_this_week_on_datetime
565 def test_operator_this_week_on_datetime
565 query = IssueQuery.new(:project => Project.find(1), :name => '_')
566 query = IssueQuery.new(:project => Project.find(1), :name => '_')
566 query.add_filter('created_on', 'w', [''])
567 query.add_filter('created_on', 'w', [''])
567 find_issues_with_query(query)
568 find_issues_with_query(query)
568 end
569 end
569
570
570 def test_operator_contains
571 def test_operator_contains
571 query = IssueQuery.new(:project => Project.find(1), :name => '_')
572 query = IssueQuery.new(:project => Project.find(1), :name => '_')
572 query.add_filter('subject', '~', ['uNable'])
573 query.add_filter('subject', '~', ['uNable'])
573 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
574 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
574 result = find_issues_with_query(query)
575 result = find_issues_with_query(query)
575 assert result.empty?
576 assert result.empty?
576 result.each {|issue| assert issue.subject.downcase.include?('unable') }
577 result.each {|issue| assert issue.subject.downcase.include?('unable') }
577 end
578 end
578
579
579 def test_range_for_this_week_with_week_starting_on_monday
580 def test_range_for_this_week_with_week_starting_on_monday
580 I18n.locale = :fr
581 I18n.locale = :fr
581 assert_equal '1', I18n.t(:general_first_day_of_week)
582 assert_equal '1', I18n.t(:general_first_day_of_week)
582
583
583 Date.stubs(:today).returns(Date.parse('2011-04-29'))
584 Date.stubs(:today).returns(Date.parse('2011-04-29'))
584
585
585 query = IssueQuery.new(:project => Project.find(1), :name => '_')
586 query = IssueQuery.new(:project => Project.find(1), :name => '_')
586 query.add_filter('due_date', 'w', [''])
587 query.add_filter('due_date', 'w', [''])
587 assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}"
588 assert query.statement.match(/issues\.due_date > '2011-04-24 23:59:59(\.9+)?' AND issues\.due_date <= '2011-05-01 23:59:59(\.9+)?/), "range not found in #{query.statement}"
588 I18n.locale = :en
589 I18n.locale = :en
589 end
590 end
590
591
591 def test_range_for_this_week_with_week_starting_on_sunday
592 def test_range_for_this_week_with_week_starting_on_sunday
592 I18n.locale = :en
593 I18n.locale = :en
593 assert_equal '7', I18n.t(:general_first_day_of_week)
594 assert_equal '7', I18n.t(:general_first_day_of_week)
594
595
595 Date.stubs(:today).returns(Date.parse('2011-04-29'))
596 Date.stubs(:today).returns(Date.parse('2011-04-29'))
596
597
597 query = IssueQuery.new(:project => Project.find(1), :name => '_')
598 query = IssueQuery.new(:project => Project.find(1), :name => '_')
598 query.add_filter('due_date', 'w', [''])
599 query.add_filter('due_date', 'w', [''])
599 assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}"
600 assert query.statement.match(/issues\.due_date > '2011-04-23 23:59:59(\.9+)?' AND issues\.due_date <= '2011-04-30 23:59:59(\.9+)?/), "range not found in #{query.statement}"
600 end
601 end
601
602
602 def test_operator_does_not_contains
603 def test_operator_does_not_contains
603 query = IssueQuery.new(:project => Project.find(1), :name => '_')
604 query = IssueQuery.new(:project => Project.find(1), :name => '_')
604 query.add_filter('subject', '!~', ['uNable'])
605 query.add_filter('subject', '!~', ['uNable'])
605 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
606 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
606 find_issues_with_query(query)
607 find_issues_with_query(query)
607 end
608 end
608
609
609 def test_filter_assigned_to_me
610 def test_filter_assigned_to_me
610 user = User.find(2)
611 user = User.find(2)
611 group = Group.find(10)
612 group = Group.find(10)
612 User.current = user
613 User.current = user
613 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
614 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
614 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
615 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
615 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
616 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
616 group.users << user
617 group.users << user
617
618
618 query = IssueQuery.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
619 query = IssueQuery.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
619 result = query.issues
620 result = query.issues
620 assert_equal Issue.visible.where(:assigned_to_id => ([2] + user.reload.group_ids)).sort_by(&:id), result.sort_by(&:id)
621 assert_equal Issue.visible.where(:assigned_to_id => ([2] + user.reload.group_ids)).sort_by(&:id), result.sort_by(&:id)
621
622
622 assert result.include?(i1)
623 assert result.include?(i1)
623 assert result.include?(i2)
624 assert result.include?(i2)
624 assert !result.include?(i3)
625 assert !result.include?(i3)
625 end
626 end
626
627
627 def test_user_custom_field_filtered_on_me
628 def test_user_custom_field_filtered_on_me
628 User.current = User.find(2)
629 User.current = User.find(2)
629 cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])
630 cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])
630 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
631 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
631 issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
632 issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
632
633
633 query = IssueQuery.new(:name => '_', :project => Project.find(1))
634 query = IssueQuery.new(:name => '_', :project => Project.find(1))
634 filter = query.available_filters["cf_#{cf.id}"]
635 filter = query.available_filters["cf_#{cf.id}"]
635 assert_not_nil filter
636 assert_not_nil filter
636 assert_include 'me', filter[:values].map{|v| v[1]}
637 assert_include 'me', filter[:values].map{|v| v[1]}
637
638
638 query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
639 query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
639 result = query.issues
640 result = query.issues
640 assert_equal 1, result.size
641 assert_equal 1, result.size
641 assert_equal issue1, result.first
642 assert_equal issue1, result.first
642 end
643 end
643
644
644 def test_filter_my_projects
645 def test_filter_my_projects
645 User.current = User.find(2)
646 User.current = User.find(2)
646 query = IssueQuery.new(:name => '_')
647 query = IssueQuery.new(:name => '_')
647 filter = query.available_filters['project_id']
648 filter = query.available_filters['project_id']
648 assert_not_nil filter
649 assert_not_nil filter
649 assert_include 'mine', filter[:values].map{|v| v[1]}
650 assert_include 'mine', filter[:values].map{|v| v[1]}
650
651
651 query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}}
652 query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}}
652 result = query.issues
653 result = query.issues
653 assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
654 assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
654 end
655 end
655
656
656 def test_filter_watched_issues
657 def test_filter_watched_issues
657 User.current = User.find(1)
658 User.current = User.find(1)
658 query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
659 query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
659 result = find_issues_with_query(query)
660 result = find_issues_with_query(query)
660 assert_not_nil result
661 assert_not_nil result
661 assert !result.empty?
662 assert !result.empty?
662 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
663 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
663 User.current = nil
664 User.current = nil
664 end
665 end
665
666
666 def test_filter_unwatched_issues
667 def test_filter_unwatched_issues
667 User.current = User.find(1)
668 User.current = User.find(1)
668 query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
669 query = IssueQuery.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
669 result = find_issues_with_query(query)
670 result = find_issues_with_query(query)
670 assert_not_nil result
671 assert_not_nil result
671 assert !result.empty?
672 assert !result.empty?
672 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
673 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
673 User.current = nil
674 User.current = nil
674 end
675 end
675
676
676 def test_filter_on_custom_field_should_ignore_projects_with_field_disabled
677 def test_filter_on_custom_field_should_ignore_projects_with_field_disabled
677 field = IssueCustomField.generate!(:trackers => Tracker.all, :project_ids => [1, 3, 4], :is_filter => true)
678 field = IssueCustomField.generate!(:trackers => Tracker.all, :project_ids => [1, 3, 4], :is_filter => true)
678 Issue.generate!(:project_id => 3, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'})
679 Issue.generate!(:project_id => 3, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'})
679 Issue.generate!(:project_id => 4, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'})
680 Issue.generate!(:project_id => 4, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'})
680
681
681 query = IssueQuery.new(:name => '_', :project => Project.find(1))
682 query = IssueQuery.new(:name => '_', :project => Project.find(1))
682 query.filters = {"cf_#{field.id}" => {:operator => '=', :values => ['Foo']}}
683 query.filters = {"cf_#{field.id}" => {:operator => '=', :values => ['Foo']}}
683 assert_equal 2, find_issues_with_query(query).size
684 assert_equal 2, find_issues_with_query(query).size
684
685
685 field.project_ids = [1, 3] # Disable the field for project 4
686 field.project_ids = [1, 3] # Disable the field for project 4
686 field.save!
687 field.save!
687 assert_equal 1, find_issues_with_query(query).size
688 assert_equal 1, find_issues_with_query(query).size
688 end
689 end
689
690
690 def test_filter_on_custom_field_should_ignore_trackers_with_field_disabled
691 def test_filter_on_custom_field_should_ignore_trackers_with_field_disabled
691 field = IssueCustomField.generate!(:tracker_ids => [1, 2], :is_for_all => true, :is_filter => true)
692 field = IssueCustomField.generate!(:tracker_ids => [1, 2], :is_for_all => true, :is_filter => true)
692 Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id.to_s => 'Foo'})
693 Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id.to_s => 'Foo'})
693 Issue.generate!(:project_id => 1, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'})
694 Issue.generate!(:project_id => 1, :tracker_id => 2, :custom_field_values => {field.id.to_s => 'Foo'})
694
695
695 query = IssueQuery.new(:name => '_', :project => Project.find(1))
696 query = IssueQuery.new(:name => '_', :project => Project.find(1))
696 query.filters = {"cf_#{field.id}" => {:operator => '=', :values => ['Foo']}}
697 query.filters = {"cf_#{field.id}" => {:operator => '=', :values => ['Foo']}}
697 assert_equal 2, find_issues_with_query(query).size
698 assert_equal 2, find_issues_with_query(query).size
698
699
699 field.tracker_ids = [1] # Disable the field for tracker 2
700 field.tracker_ids = [1] # Disable the field for tracker 2
700 field.save!
701 field.save!
701 assert_equal 1, find_issues_with_query(query).size
702 assert_equal 1, find_issues_with_query(query).size
702 end
703 end
703
704
704 def test_filter_on_project_custom_field
705 def test_filter_on_project_custom_field
705 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
706 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
706 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
707 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
707 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
708 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
708
709
709 query = IssueQuery.new(:name => '_')
710 query = IssueQuery.new(:name => '_')
710 filter_name = "project.cf_#{field.id}"
711 filter_name = "project.cf_#{field.id}"
711 assert_include filter_name, query.available_filters.keys
712 assert_include filter_name, query.available_filters.keys
712 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
713 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
713 assert_equal [3, 5], find_issues_with_query(query).map(&:project_id).uniq.sort
714 assert_equal [3, 5], find_issues_with_query(query).map(&:project_id).uniq.sort
714 end
715 end
715
716
716 def test_filter_on_author_custom_field
717 def test_filter_on_author_custom_field
717 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
718 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
718 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
719 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
719
720
720 query = IssueQuery.new(:name => '_')
721 query = IssueQuery.new(:name => '_')
721 filter_name = "author.cf_#{field.id}"
722 filter_name = "author.cf_#{field.id}"
722 assert_include filter_name, query.available_filters.keys
723 assert_include filter_name, query.available_filters.keys
723 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
724 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
724 assert_equal [3], find_issues_with_query(query).map(&:author_id).uniq.sort
725 assert_equal [3], find_issues_with_query(query).map(&:author_id).uniq.sort
725 end
726 end
726
727
727 def test_filter_on_assigned_to_custom_field
728 def test_filter_on_assigned_to_custom_field
728 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
729 field = UserCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
729 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
730 CustomValue.create!(:custom_field => field, :customized => User.find(3), :value => 'Foo')
730
731
731 query = IssueQuery.new(:name => '_')
732 query = IssueQuery.new(:name => '_')
732 filter_name = "assigned_to.cf_#{field.id}"
733 filter_name = "assigned_to.cf_#{field.id}"
733 assert_include filter_name, query.available_filters.keys
734 assert_include filter_name, query.available_filters.keys
734 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
735 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
735 assert_equal [3], find_issues_with_query(query).map(&:assigned_to_id).uniq.sort
736 assert_equal [3], find_issues_with_query(query).map(&:assigned_to_id).uniq.sort
736 end
737 end
737
738
738 def test_filter_on_fixed_version_custom_field
739 def test_filter_on_fixed_version_custom_field
739 field = VersionCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
740 field = VersionCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
740 CustomValue.create!(:custom_field => field, :customized => Version.find(2), :value => 'Foo')
741 CustomValue.create!(:custom_field => field, :customized => Version.find(2), :value => 'Foo')
741
742
742 query = IssueQuery.new(:name => '_')
743 query = IssueQuery.new(:name => '_')
743 filter_name = "fixed_version.cf_#{field.id}"
744 filter_name = "fixed_version.cf_#{field.id}"
744 assert_include filter_name, query.available_filters.keys
745 assert_include filter_name, query.available_filters.keys
745 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
746 query.filters = {filter_name => {:operator => '=', :values => ['Foo']}}
746 assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort
747 assert_equal [2], find_issues_with_query(query).map(&:fixed_version_id).uniq.sort
747 end
748 end
748
749
749 def test_filter_on_relations_with_a_specific_issue
750 def test_filter_on_relations_with_a_specific_issue
750 IssueRelation.delete_all
751 IssueRelation.delete_all
751 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
752 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
752 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
753 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
753
754
754 query = IssueQuery.new(:name => '_')
755 query = IssueQuery.new(:name => '_')
755 query.filters = {"relates" => {:operator => '=', :values => ['1']}}
756 query.filters = {"relates" => {:operator => '=', :values => ['1']}}
756 assert_equal [2, 3], find_issues_with_query(query).map(&:id).sort
757 assert_equal [2, 3], find_issues_with_query(query).map(&:id).sort
757
758
758 query = IssueQuery.new(:name => '_')
759 query = IssueQuery.new(:name => '_')
759 query.filters = {"relates" => {:operator => '=', :values => ['2']}}
760 query.filters = {"relates" => {:operator => '=', :values => ['2']}}
760 assert_equal [1], find_issues_with_query(query).map(&:id).sort
761 assert_equal [1], find_issues_with_query(query).map(&:id).sort
761 end
762 end
762
763
763 def test_filter_on_relations_with_any_issues_in_a_project
764 def test_filter_on_relations_with_any_issues_in_a_project
764 IssueRelation.delete_all
765 IssueRelation.delete_all
765 with_settings :cross_project_issue_relations => '1' do
766 with_settings :cross_project_issue_relations => '1' do
766 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
767 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
767 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(2).issues.first)
768 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(2).issues.first)
768 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
769 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
769 end
770 end
770
771
771 query = IssueQuery.new(:name => '_')
772 query = IssueQuery.new(:name => '_')
772 query.filters = {"relates" => {:operator => '=p', :values => ['2']}}
773 query.filters = {"relates" => {:operator => '=p', :values => ['2']}}
773 assert_equal [1, 2], find_issues_with_query(query).map(&:id).sort
774 assert_equal [1, 2], find_issues_with_query(query).map(&:id).sort
774
775
775 query = IssueQuery.new(:name => '_')
776 query = IssueQuery.new(:name => '_')
776 query.filters = {"relates" => {:operator => '=p', :values => ['3']}}
777 query.filters = {"relates" => {:operator => '=p', :values => ['3']}}
777 assert_equal [1], find_issues_with_query(query).map(&:id).sort
778 assert_equal [1], find_issues_with_query(query).map(&:id).sort
778
779
779 query = IssueQuery.new(:name => '_')
780 query = IssueQuery.new(:name => '_')
780 query.filters = {"relates" => {:operator => '=p', :values => ['4']}}
781 query.filters = {"relates" => {:operator => '=p', :values => ['4']}}
781 assert_equal [], find_issues_with_query(query).map(&:id).sort
782 assert_equal [], find_issues_with_query(query).map(&:id).sort
782 end
783 end
783
784
784 def test_filter_on_relations_with_any_issues_not_in_a_project
785 def test_filter_on_relations_with_any_issues_not_in_a_project
785 IssueRelation.delete_all
786 IssueRelation.delete_all
786 with_settings :cross_project_issue_relations => '1' do
787 with_settings :cross_project_issue_relations => '1' do
787 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
788 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
788 #IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first)
789 #IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(1).issues.first)
789 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
790 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(3).issues.first)
790 end
791 end
791
792
792 query = IssueQuery.new(:name => '_')
793 query = IssueQuery.new(:name => '_')
793 query.filters = {"relates" => {:operator => '=!p', :values => ['1']}}
794 query.filters = {"relates" => {:operator => '=!p', :values => ['1']}}
794 assert_equal [1], find_issues_with_query(query).map(&:id).sort
795 assert_equal [1], find_issues_with_query(query).map(&:id).sort
795 end
796 end
796
797
797 def test_filter_on_relations_with_no_issues_in_a_project
798 def test_filter_on_relations_with_no_issues_in_a_project
798 IssueRelation.delete_all
799 IssueRelation.delete_all
799 with_settings :cross_project_issue_relations => '1' do
800 with_settings :cross_project_issue_relations => '1' do
800 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
801 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first)
801 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first)
802 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first)
802 IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3))
803 IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3))
803 end
804 end
804
805
805 query = IssueQuery.new(:name => '_')
806 query = IssueQuery.new(:name => '_')
806 query.filters = {"relates" => {:operator => '!p', :values => ['2']}}
807 query.filters = {"relates" => {:operator => '!p', :values => ['2']}}
807 ids = find_issues_with_query(query).map(&:id).sort
808 ids = find_issues_with_query(query).map(&:id).sort
808 assert_include 2, ids
809 assert_include 2, ids
809 assert_not_include 1, ids
810 assert_not_include 1, ids
810 assert_not_include 3, ids
811 assert_not_include 3, ids
811 end
812 end
812
813
813 def test_filter_on_relations_with_no_issues
814 def test_filter_on_relations_with_no_issues
814 IssueRelation.delete_all
815 IssueRelation.delete_all
815 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
816 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
816 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
817 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
817
818
818 query = IssueQuery.new(:name => '_')
819 query = IssueQuery.new(:name => '_')
819 query.filters = {"relates" => {:operator => '!*', :values => ['']}}
820 query.filters = {"relates" => {:operator => '!*', :values => ['']}}
820 ids = find_issues_with_query(query).map(&:id)
821 ids = find_issues_with_query(query).map(&:id)
821 assert_equal [], ids & [1, 2, 3]
822 assert_equal [], ids & [1, 2, 3]
822 assert_include 4, ids
823 assert_include 4, ids
823 end
824 end
824
825
825 def test_filter_on_relations_with_any_issues
826 def test_filter_on_relations_with_any_issues
826 IssueRelation.delete_all
827 IssueRelation.delete_all
827 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
828 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))
828 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
829 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(3), :issue_to => Issue.find(1))
829
830
830 query = IssueQuery.new(:name => '_')
831 query = IssueQuery.new(:name => '_')
831 query.filters = {"relates" => {:operator => '*', :values => ['']}}
832 query.filters = {"relates" => {:operator => '*', :values => ['']}}
832 assert_equal [1, 2, 3], find_issues_with_query(query).map(&:id).sort
833 assert_equal [1, 2, 3], find_issues_with_query(query).map(&:id).sort
833 end
834 end
834
835
835 def test_filter_on_relations_should_not_ignore_other_filter
836 def test_filter_on_relations_should_not_ignore_other_filter
836 issue = Issue.generate!
837 issue = Issue.generate!
837 issue1 = Issue.generate!(:status_id => 1)
838 issue1 = Issue.generate!(:status_id => 1)
838 issue2 = Issue.generate!(:status_id => 2)
839 issue2 = Issue.generate!(:status_id => 2)
839 IssueRelation.create!(:relation_type => "relates", :issue_from => issue, :issue_to => issue1)
840 IssueRelation.create!(:relation_type => "relates", :issue_from => issue, :issue_to => issue1)
840 IssueRelation.create!(:relation_type => "relates", :issue_from => issue, :issue_to => issue2)
841 IssueRelation.create!(:relation_type => "relates", :issue_from => issue, :issue_to => issue2)
841
842
842 query = IssueQuery.new(:name => '_')
843 query = IssueQuery.new(:name => '_')
843 query.filters = {
844 query.filters = {
844 "status_id" => {:operator => '=', :values => ['1']},
845 "status_id" => {:operator => '=', :values => ['1']},
845 "relates" => {:operator => '=', :values => [issue.id.to_s]}
846 "relates" => {:operator => '=', :values => [issue.id.to_s]}
846 }
847 }
847 assert_equal [issue1], find_issues_with_query(query)
848 assert_equal [issue1], find_issues_with_query(query)
848 end
849 end
849
850
850 def test_statement_should_be_nil_with_no_filters
851 def test_statement_should_be_nil_with_no_filters
851 q = IssueQuery.new(:name => '_')
852 q = IssueQuery.new(:name => '_')
852 q.filters = {}
853 q.filters = {}
853
854
854 assert q.valid?
855 assert q.valid?
855 assert_nil q.statement
856 assert_nil q.statement
856 end
857 end
857
858
858 def test_default_columns
859 def test_default_columns
859 q = IssueQuery.new
860 q = IssueQuery.new
860 assert q.columns.any?
861 assert q.columns.any?
861 assert q.inline_columns.any?
862 assert q.inline_columns.any?
862 assert q.block_columns.empty?
863 assert q.block_columns.empty?
863 end
864 end
864
865
865 def test_set_column_names
866 def test_set_column_names
866 q = IssueQuery.new
867 q = IssueQuery.new
867 q.column_names = ['tracker', :subject, '', 'unknonw_column']
868 q.column_names = ['tracker', :subject, '', 'unknonw_column']
868 assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
869 assert_equal [:id, :tracker, :subject], q.columns.collect {|c| c.name}
869 end
870 end
870
871
871 def test_has_column_should_accept_a_column_name
872 def test_has_column_should_accept_a_column_name
872 q = IssueQuery.new
873 q = IssueQuery.new
873 q.column_names = ['tracker', :subject]
874 q.column_names = ['tracker', :subject]
874 assert q.has_column?(:tracker)
875 assert q.has_column?(:tracker)
875 assert !q.has_column?(:category)
876 assert !q.has_column?(:category)
876 end
877 end
877
878
878 def test_has_column_should_accept_a_column
879 def test_has_column_should_accept_a_column
879 q = IssueQuery.new
880 q = IssueQuery.new
880 q.column_names = ['tracker', :subject]
881 q.column_names = ['tracker', :subject]
881
882
882 tracker_column = q.available_columns.detect {|c| c.name==:tracker}
883 tracker_column = q.available_columns.detect {|c| c.name==:tracker}
883 assert_kind_of QueryColumn, tracker_column
884 assert_kind_of QueryColumn, tracker_column
884 category_column = q.available_columns.detect {|c| c.name==:category}
885 category_column = q.available_columns.detect {|c| c.name==:category}
885 assert_kind_of QueryColumn, category_column
886 assert_kind_of QueryColumn, category_column
886
887
887 assert q.has_column?(tracker_column)
888 assert q.has_column?(tracker_column)
888 assert !q.has_column?(category_column)
889 assert !q.has_column?(category_column)
889 end
890 end
890
891
891 def test_inline_and_block_columns
892 def test_inline_and_block_columns
892 q = IssueQuery.new
893 q = IssueQuery.new
893 q.column_names = ['subject', 'description', 'tracker']
894 q.column_names = ['subject', 'description', 'tracker']
894
895
895 assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
896 assert_equal [:id, :subject, :tracker], q.inline_columns.map(&:name)
896 assert_equal [:description], q.block_columns.map(&:name)
897 assert_equal [:description], q.block_columns.map(&:name)
897 end
898 end
898
899
899 def test_custom_field_columns_should_be_inline
900 def test_custom_field_columns_should_be_inline
900 q = IssueQuery.new
901 q = IssueQuery.new
901 columns = q.available_columns.select {|column| column.is_a? QueryCustomFieldColumn}
902 columns = q.available_columns.select {|column| column.is_a? QueryCustomFieldColumn}
902 assert columns.any?
903 assert columns.any?
903 assert_nil columns.detect {|column| !column.inline?}
904 assert_nil columns.detect {|column| !column.inline?}
904 end
905 end
905
906
906 def test_query_should_preload_spent_hours
907 def test_query_should_preload_spent_hours
907 q = IssueQuery.new(:name => '_', :column_names => [:subject, :spent_hours])
908 q = IssueQuery.new(:name => '_', :column_names => [:subject, :spent_hours])
908 assert q.has_column?(:spent_hours)
909 assert q.has_column?(:spent_hours)
909 issues = q.issues
910 issues = q.issues
910 assert_not_nil issues.first.instance_variable_get("@spent_hours")
911 assert_not_nil issues.first.instance_variable_get("@spent_hours")
911 end
912 end
912
913
913 def test_groupable_columns_should_include_custom_fields
914 def test_groupable_columns_should_include_custom_fields
914 q = IssueQuery.new
915 q = IssueQuery.new
915 column = q.groupable_columns.detect {|c| c.name == :cf_1}
916 column = q.groupable_columns.detect {|c| c.name == :cf_1}
916 assert_not_nil column
917 assert_not_nil column
917 assert_kind_of QueryCustomFieldColumn, column
918 assert_kind_of QueryCustomFieldColumn, column
918 end
919 end
919
920
920 def test_groupable_columns_should_not_include_multi_custom_fields
921 def test_groupable_columns_should_not_include_multi_custom_fields
921 field = CustomField.find(1)
922 field = CustomField.find(1)
922 field.update_attribute :multiple, true
923 field.update_attribute :multiple, true
923
924
924 q = IssueQuery.new
925 q = IssueQuery.new
925 column = q.groupable_columns.detect {|c| c.name == :cf_1}
926 column = q.groupable_columns.detect {|c| c.name == :cf_1}
926 assert_nil column
927 assert_nil column
927 end
928 end
928
929
929 def test_groupable_columns_should_include_user_custom_fields
930 def test_groupable_columns_should_include_user_custom_fields
930 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'user')
931 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'user')
931
932
932 q = IssueQuery.new
933 q = IssueQuery.new
933 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
934 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
934 end
935 end
935
936
936 def test_groupable_columns_should_include_version_custom_fields
937 def test_groupable_columns_should_include_version_custom_fields
937 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'version')
938 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1], :field_format => 'version')
938
939
939 q = IssueQuery.new
940 q = IssueQuery.new
940 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
941 assert q.groupable_columns.detect {|c| c.name == "cf_#{cf.id}".to_sym}
941 end
942 end
942
943
943 def test_grouped_with_valid_column
944 def test_grouped_with_valid_column
944 q = IssueQuery.new(:group_by => 'status')
945 q = IssueQuery.new(:group_by => 'status')
945 assert q.grouped?
946 assert q.grouped?
946 assert_not_nil q.group_by_column
947 assert_not_nil q.group_by_column
947 assert_equal :status, q.group_by_column.name
948 assert_equal :status, q.group_by_column.name
948 assert_not_nil q.group_by_statement
949 assert_not_nil q.group_by_statement
949 assert_equal 'status', q.group_by_statement
950 assert_equal 'status', q.group_by_statement
950 end
951 end
951
952
952 def test_grouped_with_invalid_column
953 def test_grouped_with_invalid_column
953 q = IssueQuery.new(:group_by => 'foo')
954 q = IssueQuery.new(:group_by => 'foo')
954 assert !q.grouped?
955 assert !q.grouped?
955 assert_nil q.group_by_column
956 assert_nil q.group_by_column
956 assert_nil q.group_by_statement
957 assert_nil q.group_by_statement
957 end
958 end
958
959
959 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
960 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
960 with_settings :user_format => 'lastname_coma_firstname' do
961 with_settings :user_format => 'lastname_coma_firstname' do
961 q = IssueQuery.new
962 q = IssueQuery.new
962 assert q.sortable_columns.has_key?('assigned_to')
963 assert q.sortable_columns.has_key?('assigned_to')
963 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
964 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
964 end
965 end
965 end
966 end
966
967
967 def test_sortable_columns_should_sort_authors_according_to_user_format_setting
968 def test_sortable_columns_should_sort_authors_according_to_user_format_setting
968 with_settings :user_format => 'lastname_coma_firstname' do
969 with_settings :user_format => 'lastname_coma_firstname' do
969 q = IssueQuery.new
970 q = IssueQuery.new
970 assert q.sortable_columns.has_key?('author')
971 assert q.sortable_columns.has_key?('author')
971 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
972 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
972 end
973 end
973 end
974 end
974
975
975 def test_sortable_columns_should_include_custom_field
976 def test_sortable_columns_should_include_custom_field
976 q = IssueQuery.new
977 q = IssueQuery.new
977 assert q.sortable_columns['cf_1']
978 assert q.sortable_columns['cf_1']
978 end
979 end
979
980
980 def test_sortable_columns_should_not_include_multi_custom_field
981 def test_sortable_columns_should_not_include_multi_custom_field
981 field = CustomField.find(1)
982 field = CustomField.find(1)
982 field.update_attribute :multiple, true
983 field.update_attribute :multiple, true
983
984
984 q = IssueQuery.new
985 q = IssueQuery.new
985 assert !q.sortable_columns['cf_1']
986 assert !q.sortable_columns['cf_1']
986 end
987 end
987
988
988 def test_default_sort
989 def test_default_sort
989 q = IssueQuery.new
990 q = IssueQuery.new
990 assert_equal [], q.sort_criteria
991 assert_equal [], q.sort_criteria
991 end
992 end
992
993
993 def test_set_sort_criteria_with_hash
994 def test_set_sort_criteria_with_hash
994 q = IssueQuery.new
995 q = IssueQuery.new
995 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
996 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
996 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
997 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
997 end
998 end
998
999
999 def test_set_sort_criteria_with_array
1000 def test_set_sort_criteria_with_array
1000 q = IssueQuery.new
1001 q = IssueQuery.new
1001 q.sort_criteria = [['priority', 'desc'], 'tracker']
1002 q.sort_criteria = [['priority', 'desc'], 'tracker']
1002 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
1003 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
1003 end
1004 end
1004
1005
1005 def test_create_query_with_sort
1006 def test_create_query_with_sort
1006 q = IssueQuery.new(:name => 'Sorted')
1007 q = IssueQuery.new(:name => 'Sorted')
1007 q.sort_criteria = [['priority', 'desc'], 'tracker']
1008 q.sort_criteria = [['priority', 'desc'], 'tracker']
1008 assert q.save
1009 assert q.save
1009 q.reload
1010 q.reload
1010 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
1011 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
1011 end
1012 end
1012
1013
1013 def test_sort_by_string_custom_field_asc
1014 def test_sort_by_string_custom_field_asc
1014 q = IssueQuery.new
1015 q = IssueQuery.new
1015 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
1016 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
1016 assert c
1017 assert c
1017 assert c.sortable
1018 assert c.sortable
1018 issues = q.issues(:order => "#{c.sortable} ASC")
1019 issues = q.issues(:order => "#{c.sortable} ASC")
1019 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
1020 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
1020 assert !values.empty?
1021 assert !values.empty?
1021 assert_equal values.sort, values
1022 assert_equal values.sort, values
1022 end
1023 end
1023
1024
1024 def test_sort_by_string_custom_field_desc
1025 def test_sort_by_string_custom_field_desc
1025 q = IssueQuery.new
1026 q = IssueQuery.new
1026 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
1027 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
1027 assert c
1028 assert c
1028 assert c.sortable
1029 assert c.sortable
1029 issues = q.issues(:order => "#{c.sortable} DESC")
1030 issues = q.issues(:order => "#{c.sortable} DESC")
1030 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
1031 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
1031 assert !values.empty?
1032 assert !values.empty?
1032 assert_equal values.sort.reverse, values
1033 assert_equal values.sort.reverse, values
1033 end
1034 end
1034
1035
1035 def test_sort_by_float_custom_field_asc
1036 def test_sort_by_float_custom_field_asc
1036 q = IssueQuery.new
1037 q = IssueQuery.new
1037 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
1038 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
1038 assert c
1039 assert c
1039 assert c.sortable
1040 assert c.sortable
1040 issues = q.issues(:order => "#{c.sortable} ASC")
1041 issues = q.issues(:order => "#{c.sortable} ASC")
1041 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
1042 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
1042 assert !values.empty?
1043 assert !values.empty?
1043 assert_equal values.sort, values
1044 assert_equal values.sort, values
1044 end
1045 end
1045
1046
1046 def test_invalid_query_should_raise_query_statement_invalid_error
1047 def test_invalid_query_should_raise_query_statement_invalid_error
1047 q = IssueQuery.new
1048 q = IssueQuery.new
1048 assert_raise Query::StatementInvalid do
1049 assert_raise Query::StatementInvalid do
1049 q.issues(:conditions => "foo = 1")
1050 q.issues(:conditions => "foo = 1")
1050 end
1051 end
1051 end
1052 end
1052
1053
1053 def test_issue_count
1054 def test_issue_count
1054 q = IssueQuery.new(:name => '_')
1055 q = IssueQuery.new(:name => '_')
1055 issue_count = q.issue_count
1056 issue_count = q.issue_count
1056 assert_equal q.issues.size, issue_count
1057 assert_equal q.issues.size, issue_count
1057 end
1058 end
1058
1059
1059 def test_issue_count_with_archived_issues
1060 def test_issue_count_with_archived_issues
1060 p = Project.generate! do |project|
1061 p = Project.generate! do |project|
1061 project.status = Project::STATUS_ARCHIVED
1062 project.status = Project::STATUS_ARCHIVED
1062 end
1063 end
1063 i = Issue.generate!( :project => p, :tracker => p.trackers.first )
1064 i = Issue.generate!( :project => p, :tracker => p.trackers.first )
1064 assert !i.visible?
1065 assert !i.visible?
1065
1066
1066 test_issue_count
1067 test_issue_count
1067 end
1068 end
1068
1069
1069 def test_issue_count_by_association_group
1070 def test_issue_count_by_association_group
1070 q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
1071 q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
1071 count_by_group = q.issue_count_by_group
1072 count_by_group = q.issue_count_by_group
1072 assert_kind_of Hash, count_by_group
1073 assert_kind_of Hash, count_by_group
1073 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
1074 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
1074 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
1075 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
1075 assert count_by_group.has_key?(User.find(3))
1076 assert count_by_group.has_key?(User.find(3))
1076 end
1077 end
1077
1078
1078 def test_issue_count_by_list_custom_field_group
1079 def test_issue_count_by_list_custom_field_group
1079 q = IssueQuery.new(:name => '_', :group_by => 'cf_1')
1080 q = IssueQuery.new(:name => '_', :group_by => 'cf_1')
1080 count_by_group = q.issue_count_by_group
1081 count_by_group = q.issue_count_by_group
1081 assert_kind_of Hash, count_by_group
1082 assert_kind_of Hash, count_by_group
1082 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
1083 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
1083 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
1084 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
1084 assert count_by_group.has_key?('MySQL')
1085 assert count_by_group.has_key?('MySQL')
1085 end
1086 end
1086
1087
1087 def test_issue_count_by_date_custom_field_group
1088 def test_issue_count_by_date_custom_field_group
1088 q = IssueQuery.new(:name => '_', :group_by => 'cf_8')
1089 q = IssueQuery.new(:name => '_', :group_by => 'cf_8')
1089 count_by_group = q.issue_count_by_group
1090 count_by_group = q.issue_count_by_group
1090 assert_kind_of Hash, count_by_group
1091 assert_kind_of Hash, count_by_group
1091 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
1092 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
1092 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
1093 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
1093 end
1094 end
1094
1095
1095 def test_issue_count_with_nil_group_only
1096 def test_issue_count_with_nil_group_only
1096 Issue.update_all("assigned_to_id = NULL")
1097 Issue.update_all("assigned_to_id = NULL")
1097
1098
1098 q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
1099 q = IssueQuery.new(:name => '_', :group_by => 'assigned_to')
1099 count_by_group = q.issue_count_by_group
1100 count_by_group = q.issue_count_by_group
1100 assert_kind_of Hash, count_by_group
1101 assert_kind_of Hash, count_by_group
1101 assert_equal 1, count_by_group.keys.size
1102 assert_equal 1, count_by_group.keys.size
1102 assert_nil count_by_group.keys.first
1103 assert_nil count_by_group.keys.first
1103 end
1104 end
1104
1105
1105 def test_issue_ids
1106 def test_issue_ids
1106 q = IssueQuery.new(:name => '_')
1107 q = IssueQuery.new(:name => '_')
1107 order = "issues.subject, issues.id"
1108 order = "issues.subject, issues.id"
1108 issues = q.issues(:order => order)
1109 issues = q.issues(:order => order)
1109 assert_equal issues.map(&:id), q.issue_ids(:order => order)
1110 assert_equal issues.map(&:id), q.issue_ids(:order => order)
1110 end
1111 end
1111
1112
1112 def test_label_for
1113 def test_label_for
1113 set_language_if_valid 'en'
1114 set_language_if_valid 'en'
1114 q = IssueQuery.new
1115 q = IssueQuery.new
1115 assert_equal 'Assignee', q.label_for('assigned_to_id')
1116 assert_equal 'Assignee', q.label_for('assigned_to_id')
1116 end
1117 end
1117
1118
1118 def test_label_for_fr
1119 def test_label_for_fr
1119 set_language_if_valid 'fr'
1120 set_language_if_valid 'fr'
1120 q = IssueQuery.new
1121 q = IssueQuery.new
1121 assert_equal "Assign\xc3\xa9 \xc3\xa0".force_encoding('UTF-8'), q.label_for('assigned_to_id')
1122 assert_equal "Assign\xc3\xa9 \xc3\xa0".force_encoding('UTF-8'), q.label_for('assigned_to_id')
1122 end
1123 end
1123
1124
1124 def test_editable_by
1125 def test_editable_by
1125 admin = User.find(1)
1126 admin = User.find(1)
1126 manager = User.find(2)
1127 manager = User.find(2)
1127 developer = User.find(3)
1128 developer = User.find(3)
1128
1129
1129 # Public query on project 1
1130 # Public query on project 1
1130 q = IssueQuery.find(1)
1131 q = IssueQuery.find(1)
1131 assert q.editable_by?(admin)
1132 assert q.editable_by?(admin)
1132 assert q.editable_by?(manager)
1133 assert q.editable_by?(manager)
1133 assert !q.editable_by?(developer)
1134 assert !q.editable_by?(developer)
1134
1135
1135 # Private query on project 1
1136 # Private query on project 1
1136 q = IssueQuery.find(2)
1137 q = IssueQuery.find(2)
1137 assert q.editable_by?(admin)
1138 assert q.editable_by?(admin)
1138 assert !q.editable_by?(manager)
1139 assert !q.editable_by?(manager)
1139 assert q.editable_by?(developer)
1140 assert q.editable_by?(developer)
1140
1141
1141 # Private query for all projects
1142 # Private query for all projects
1142 q = IssueQuery.find(3)
1143 q = IssueQuery.find(3)
1143 assert q.editable_by?(admin)
1144 assert q.editable_by?(admin)
1144 assert !q.editable_by?(manager)
1145 assert !q.editable_by?(manager)
1145 assert q.editable_by?(developer)
1146 assert q.editable_by?(developer)
1146
1147
1147 # Public query for all projects
1148 # Public query for all projects
1148 q = IssueQuery.find(4)
1149 q = IssueQuery.find(4)
1149 assert q.editable_by?(admin)
1150 assert q.editable_by?(admin)
1150 assert !q.editable_by?(manager)
1151 assert !q.editable_by?(manager)
1151 assert !q.editable_by?(developer)
1152 assert !q.editable_by?(developer)
1152 end
1153 end
1153
1154
1154 def test_visible_scope
1155 def test_visible_scope
1155 query_ids = IssueQuery.visible(User.anonymous).map(&:id)
1156 query_ids = IssueQuery.visible(User.anonymous).map(&:id)
1156
1157
1157 assert query_ids.include?(1), 'public query on public project was not visible'
1158 assert query_ids.include?(1), 'public query on public project was not visible'
1158 assert query_ids.include?(4), 'public query for all projects was not visible'
1159 assert query_ids.include?(4), 'public query for all projects was not visible'
1159 assert !query_ids.include?(2), 'private query on public project was visible'
1160 assert !query_ids.include?(2), 'private query on public project was visible'
1160 assert !query_ids.include?(3), 'private query for all projects was visible'
1161 assert !query_ids.include?(3), 'private query for all projects was visible'
1161 assert !query_ids.include?(7), 'public query on private project was visible'
1162 assert !query_ids.include?(7), 'public query on private project was visible'
1162 end
1163 end
1163
1164
1164 def test_query_with_public_visibility_should_be_visible_to_anyone
1165 def test_query_with_public_visibility_should_be_visible_to_anyone
1165 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_PUBLIC)
1166 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_PUBLIC)
1166
1167
1167 assert q.visible?(User.anonymous)
1168 assert q.visible?(User.anonymous)
1168 assert IssueQuery.visible(User.anonymous).find_by_id(q.id)
1169 assert IssueQuery.visible(User.anonymous).find_by_id(q.id)
1169
1170
1170 assert q.visible?(User.find(7))
1171 assert q.visible?(User.find(7))
1171 assert IssueQuery.visible(User.find(7)).find_by_id(q.id)
1172 assert IssueQuery.visible(User.find(7)).find_by_id(q.id)
1172
1173
1173 assert q.visible?(User.find(2))
1174 assert q.visible?(User.find(2))
1174 assert IssueQuery.visible(User.find(2)).find_by_id(q.id)
1175 assert IssueQuery.visible(User.find(2)).find_by_id(q.id)
1175
1176
1176 assert q.visible?(User.find(1))
1177 assert q.visible?(User.find(1))
1177 assert IssueQuery.visible(User.find(1)).find_by_id(q.id)
1178 assert IssueQuery.visible(User.find(1)).find_by_id(q.id)
1178 end
1179 end
1179
1180
1180 def test_query_with_roles_visibility_should_be_visible_to_user_with_role
1181 def test_query_with_roles_visibility_should_be_visible_to_user_with_role
1181 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES, :role_ids => [1,2])
1182 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_ROLES, :role_ids => [1,2])
1182
1183
1183 assert !q.visible?(User.anonymous)
1184 assert !q.visible?(User.anonymous)
1184 assert_nil IssueQuery.visible(User.anonymous).find_by_id(q.id)
1185 assert_nil IssueQuery.visible(User.anonymous).find_by_id(q.id)
1185
1186
1186 assert !q.visible?(User.find(7))
1187 assert !q.visible?(User.find(7))
1187 assert_nil IssueQuery.visible(User.find(7)).find_by_id(q.id)
1188 assert_nil IssueQuery.visible(User.find(7)).find_by_id(q.id)
1188
1189
1189 assert q.visible?(User.find(2))
1190 assert q.visible?(User.find(2))
1190 assert IssueQuery.visible(User.find(2)).find_by_id(q.id)
1191 assert IssueQuery.visible(User.find(2)).find_by_id(q.id)
1191
1192
1192 assert q.visible?(User.find(1))
1193 assert q.visible?(User.find(1))
1193 assert IssueQuery.visible(User.find(1)).find_by_id(q.id)
1194 assert IssueQuery.visible(User.find(1)).find_by_id(q.id)
1194 end
1195 end
1195
1196
1196 def test_query_with_private_visibility_should_be_visible_to_owner
1197 def test_query_with_private_visibility_should_be_visible_to_owner
1197 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_PRIVATE, :user => User.find(7))
1198 q = IssueQuery.create!(:name => 'Query', :visibility => IssueQuery::VISIBILITY_PRIVATE, :user => User.find(7))
1198
1199
1199 assert !q.visible?(User.anonymous)
1200 assert !q.visible?(User.anonymous)
1200 assert_nil IssueQuery.visible(User.anonymous).find_by_id(q.id)
1201 assert_nil IssueQuery.visible(User.anonymous).find_by_id(q.id)
1201
1202
1202 assert q.visible?(User.find(7))
1203 assert q.visible?(User.find(7))
1203 assert IssueQuery.visible(User.find(7)).find_by_id(q.id)
1204 assert IssueQuery.visible(User.find(7)).find_by_id(q.id)
1204
1205
1205 assert !q.visible?(User.find(2))
1206 assert !q.visible?(User.find(2))
1206 assert_nil IssueQuery.visible(User.find(2)).find_by_id(q.id)
1207 assert_nil IssueQuery.visible(User.find(2)).find_by_id(q.id)
1207
1208
1208 assert q.visible?(User.find(1))
1209 assert q.visible?(User.find(1))
1209 assert_nil IssueQuery.visible(User.find(1)).find_by_id(q.id)
1210 assert_nil IssueQuery.visible(User.find(1)).find_by_id(q.id)
1210 end
1211 end
1211
1212
1212 test "#available_filters should include users of visible projects in cross-project view" do
1213 test "#available_filters should include users of visible projects in cross-project view" do
1213 users = IssueQuery.new.available_filters["assigned_to_id"]
1214 users = IssueQuery.new.available_filters["assigned_to_id"]
1214 assert_not_nil users
1215 assert_not_nil users
1215 assert users[:values].map{|u|u[1]}.include?("3")
1216 assert users[:values].map{|u|u[1]}.include?("3")
1216 end
1217 end
1217
1218
1218 test "#available_filters should include users of subprojects" do
1219 test "#available_filters should include users of subprojects" do
1219 user1 = User.generate!
1220 user1 = User.generate!
1220 user2 = User.generate!
1221 user2 = User.generate!
1221 project = Project.find(1)
1222 project = Project.find(1)
1222 Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
1223 Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
1223
1224
1224 users = IssueQuery.new(:project => project).available_filters["assigned_to_id"]
1225 users = IssueQuery.new(:project => project).available_filters["assigned_to_id"]
1225 assert_not_nil users
1226 assert_not_nil users
1226 assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
1227 assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
1227 assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
1228 assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
1228 end
1229 end
1229
1230
1230 test "#available_filters should include visible projects in cross-project view" do
1231 test "#available_filters should include visible projects in cross-project view" do
1231 projects = IssueQuery.new.available_filters["project_id"]
1232 projects = IssueQuery.new.available_filters["project_id"]
1232 assert_not_nil projects
1233 assert_not_nil projects
1233 assert projects[:values].map{|u|u[1]}.include?("1")
1234 assert projects[:values].map{|u|u[1]}.include?("1")
1234 end
1235 end
1235
1236
1236 test "#available_filters should include 'member_of_group' filter" do
1237 test "#available_filters should include 'member_of_group' filter" do
1237 query = IssueQuery.new
1238 query = IssueQuery.new
1238 assert query.available_filters.keys.include?("member_of_group")
1239 assert query.available_filters.keys.include?("member_of_group")
1239 assert_equal :list_optional, query.available_filters["member_of_group"][:type]
1240 assert_equal :list_optional, query.available_filters["member_of_group"][:type]
1240 assert query.available_filters["member_of_group"][:values].present?
1241 assert query.available_filters["member_of_group"][:values].present?
1241 assert_equal Group.givable.sort.map {|g| [g.name, g.id.to_s]},
1242 assert_equal Group.givable.sort.map {|g| [g.name, g.id.to_s]},
1242 query.available_filters["member_of_group"][:values].sort
1243 query.available_filters["member_of_group"][:values].sort
1243 end
1244 end
1244
1245
1245 test "#available_filters should include 'assigned_to_role' filter" do
1246 test "#available_filters should include 'assigned_to_role' filter" do
1246 query = IssueQuery.new
1247 query = IssueQuery.new
1247 assert query.available_filters.keys.include?("assigned_to_role")
1248 assert query.available_filters.keys.include?("assigned_to_role")
1248 assert_equal :list_optional, query.available_filters["assigned_to_role"][:type]
1249 assert_equal :list_optional, query.available_filters["assigned_to_role"][:type]
1249
1250
1250 assert query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
1251 assert query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
1251 assert query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
1252 assert query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
1252 assert query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
1253 assert query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
1253
1254
1254 assert ! query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
1255 assert ! query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
1255 assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
1256 assert ! query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
1256 end
1257 end
1257
1258
1258 def test_available_filters_should_include_custom_field_according_to_user_visibility
1259 def test_available_filters_should_include_custom_field_according_to_user_visibility
1259 visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true)
1260 visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true)
1260 hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1])
1261 hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1])
1261
1262
1262 with_current_user User.find(3) do
1263 with_current_user User.find(3) do
1263 query = IssueQuery.new
1264 query = IssueQuery.new
1264 assert_include "cf_#{visible_field.id}", query.available_filters.keys
1265 assert_include "cf_#{visible_field.id}", query.available_filters.keys
1265 assert_not_include "cf_#{hidden_field.id}", query.available_filters.keys
1266 assert_not_include "cf_#{hidden_field.id}", query.available_filters.keys
1266 end
1267 end
1267 end
1268 end
1268
1269
1269 def test_available_columns_should_include_custom_field_according_to_user_visibility
1270 def test_available_columns_should_include_custom_field_according_to_user_visibility
1270 visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true)
1271 visible_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => true)
1271 hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1])
1272 hidden_field = IssueCustomField.generate!(:is_for_all => true, :is_filter => true, :visible => false, :role_ids => [1])
1272
1273
1273 with_current_user User.find(3) do
1274 with_current_user User.find(3) do
1274 query = IssueQuery.new
1275 query = IssueQuery.new
1275 assert_include :"cf_#{visible_field.id}", query.available_columns.map(&:name)
1276 assert_include :"cf_#{visible_field.id}", query.available_columns.map(&:name)
1276 assert_not_include :"cf_#{hidden_field.id}", query.available_columns.map(&:name)
1277 assert_not_include :"cf_#{hidden_field.id}", query.available_columns.map(&:name)
1277 end
1278 end
1278 end
1279 end
1279
1280
1280 context "#statement" do
1281 context "#statement" do
1281 context "with 'member_of_group' filter" do
1282 context "with 'member_of_group' filter" do
1282 setup do
1283 setup do
1283 Group.destroy_all # No fixtures
1284 Group.destroy_all # No fixtures
1284 @user_in_group = User.generate!
1285 @user_in_group = User.generate!
1285 @second_user_in_group = User.generate!
1286 @second_user_in_group = User.generate!
1286 @user_in_group2 = User.generate!
1287 @user_in_group2 = User.generate!
1287 @user_not_in_group = User.generate!
1288 @user_not_in_group = User.generate!
1288
1289
1289 @group = Group.generate!.reload
1290 @group = Group.generate!.reload
1290 @group.users << @user_in_group
1291 @group.users << @user_in_group
1291 @group.users << @second_user_in_group
1292 @group.users << @second_user_in_group
1292
1293
1293 @group2 = Group.generate!.reload
1294 @group2 = Group.generate!.reload
1294 @group2.users << @user_in_group2
1295 @group2.users << @user_in_group2
1295
1296
1296 end
1297 end
1297
1298
1298 should "search assigned to for users in the group" do
1299 should "search assigned to for users in the group" do
1299 @query = IssueQuery.new(:name => '_')
1300 @query = IssueQuery.new(:name => '_')
1300 @query.add_filter('member_of_group', '=', [@group.id.to_s])
1301 @query.add_filter('member_of_group', '=', [@group.id.to_s])
1301
1302
1302 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@group.id}')"
1303 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@group.id}')"
1303 assert_find_issues_with_query_is_successful @query
1304 assert_find_issues_with_query_is_successful @query
1304 end
1305 end
1305
1306
1306 should "search not assigned to any group member (none)" do
1307 should "search not assigned to any group member (none)" do
1307 @query = IssueQuery.new(:name => '_')
1308 @query = IssueQuery.new(:name => '_')
1308 @query.add_filter('member_of_group', '!*', [''])
1309 @query.add_filter('member_of_group', '!*', [''])
1309
1310
1310 # Users not in a group
1311 # Users not in a group
1311 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
1312 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
1312 assert_find_issues_with_query_is_successful @query
1313 assert_find_issues_with_query_is_successful @query
1313 end
1314 end
1314
1315
1315 should "search assigned to any group member (all)" do
1316 should "search assigned to any group member (all)" do
1316 @query = IssueQuery.new(:name => '_')
1317 @query = IssueQuery.new(:name => '_')
1317 @query.add_filter('member_of_group', '*', [''])
1318 @query.add_filter('member_of_group', '*', [''])
1318
1319
1319 # Only users in a group
1320 # Only users in a group
1320 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
1321 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}','#{@group.id}','#{@group2.id}')"
1321 assert_find_issues_with_query_is_successful @query
1322 assert_find_issues_with_query_is_successful @query
1322 end
1323 end
1323
1324
1324 should "return an empty set with = empty group" do
1325 should "return an empty set with = empty group" do
1325 @empty_group = Group.generate!
1326 @empty_group = Group.generate!
1326 @query = IssueQuery.new(:name => '_')
1327 @query = IssueQuery.new(:name => '_')
1327 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
1328 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
1328
1329
1329 assert_equal [], find_issues_with_query(@query)
1330 assert_equal [], find_issues_with_query(@query)
1330 end
1331 end
1331
1332
1332 should "return issues with ! empty group" do
1333 should "return issues with ! empty group" do
1333 @empty_group = Group.generate!
1334 @empty_group = Group.generate!
1334 @query = IssueQuery.new(:name => '_')
1335 @query = IssueQuery.new(:name => '_')
1335 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
1336 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
1336
1337
1337 assert_find_issues_with_query_is_successful @query
1338 assert_find_issues_with_query_is_successful @query
1338 end
1339 end
1339 end
1340 end
1340
1341
1341 context "with 'assigned_to_role' filter" do
1342 context "with 'assigned_to_role' filter" do
1342 setup do
1343 setup do
1343 @manager_role = Role.find_by_name('Manager')
1344 @manager_role = Role.find_by_name('Manager')
1344 @developer_role = Role.find_by_name('Developer')
1345 @developer_role = Role.find_by_name('Developer')
1345
1346
1346 @project = Project.generate!
1347 @project = Project.generate!
1347 @manager = User.generate!
1348 @manager = User.generate!
1348 @developer = User.generate!
1349 @developer = User.generate!
1349 @boss = User.generate!
1350 @boss = User.generate!
1350 @guest = User.generate!
1351 @guest = User.generate!
1351 User.add_to_project(@manager, @project, @manager_role)
1352 User.add_to_project(@manager, @project, @manager_role)
1352 User.add_to_project(@developer, @project, @developer_role)
1353 User.add_to_project(@developer, @project, @developer_role)
1353 User.add_to_project(@boss, @project, [@manager_role, @developer_role])
1354 User.add_to_project(@boss, @project, [@manager_role, @developer_role])
1354
1355
1355 @issue1 = Issue.generate!(:project => @project, :assigned_to_id => @manager.id)
1356 @issue1 = Issue.generate!(:project => @project, :assigned_to_id => @manager.id)
1356 @issue2 = Issue.generate!(:project => @project, :assigned_to_id => @developer.id)
1357 @issue2 = Issue.generate!(:project => @project, :assigned_to_id => @developer.id)
1357 @issue3 = Issue.generate!(:project => @project, :assigned_to_id => @boss.id)
1358 @issue3 = Issue.generate!(:project => @project, :assigned_to_id => @boss.id)
1358 @issue4 = Issue.generate!(:project => @project, :assigned_to_id => @guest.id)
1359 @issue4 = Issue.generate!(:project => @project, :assigned_to_id => @guest.id)
1359 @issue5 = Issue.generate!(:project => @project)
1360 @issue5 = Issue.generate!(:project => @project)
1360 end
1361 end
1361
1362
1362 should "search assigned to for users with the Role" do
1363 should "search assigned to for users with the Role" do
1363 @query = IssueQuery.new(:name => '_', :project => @project)
1364 @query = IssueQuery.new(:name => '_', :project => @project)
1364 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
1365 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
1365
1366
1366 assert_query_result [@issue1, @issue3], @query
1367 assert_query_result [@issue1, @issue3], @query
1367 end
1368 end
1368
1369
1369 should "search assigned to for users with the Role on the issue project" do
1370 should "search assigned to for users with the Role on the issue project" do
1370 other_project = Project.generate!
1371 other_project = Project.generate!
1371 User.add_to_project(@developer, other_project, @manager_role)
1372 User.add_to_project(@developer, other_project, @manager_role)
1372
1373
1373 @query = IssueQuery.new(:name => '_', :project => @project)
1374 @query = IssueQuery.new(:name => '_', :project => @project)
1374 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
1375 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
1375
1376
1376 assert_query_result [@issue1, @issue3], @query
1377 assert_query_result [@issue1, @issue3], @query
1377 end
1378 end
1378
1379
1379 should "return an empty set with empty role" do
1380 should "return an empty set with empty role" do
1380 @empty_role = Role.generate!
1381 @empty_role = Role.generate!
1381 @query = IssueQuery.new(:name => '_', :project => @project)
1382 @query = IssueQuery.new(:name => '_', :project => @project)
1382 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
1383 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
1383
1384
1384 assert_query_result [], @query
1385 assert_query_result [], @query
1385 end
1386 end
1386
1387
1387 should "search assigned to for users without the Role" do
1388 should "search assigned to for users without the Role" do
1388 @query = IssueQuery.new(:name => '_', :project => @project)
1389 @query = IssueQuery.new(:name => '_', :project => @project)
1389 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
1390 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
1390
1391
1391 assert_query_result [@issue2, @issue4, @issue5], @query
1392 assert_query_result [@issue2, @issue4, @issue5], @query
1392 end
1393 end
1393
1394
1394 should "search assigned to for users not assigned to any Role (none)" do
1395 should "search assigned to for users not assigned to any Role (none)" do
1395 @query = IssueQuery.new(:name => '_', :project => @project)
1396 @query = IssueQuery.new(:name => '_', :project => @project)
1396 @query.add_filter('assigned_to_role', '!*', [''])
1397 @query.add_filter('assigned_to_role', '!*', [''])
1397
1398
1398 assert_query_result [@issue4, @issue5], @query
1399 assert_query_result [@issue4, @issue5], @query
1399 end
1400 end
1400
1401
1401 should "search assigned to for users assigned to any Role (all)" do
1402 should "search assigned to for users assigned to any Role (all)" do
1402 @query = IssueQuery.new(:name => '_', :project => @project)
1403 @query = IssueQuery.new(:name => '_', :project => @project)
1403 @query.add_filter('assigned_to_role', '*', [''])
1404 @query.add_filter('assigned_to_role', '*', [''])
1404
1405
1405 assert_query_result [@issue1, @issue2, @issue3], @query
1406 assert_query_result [@issue1, @issue2, @issue3], @query
1406 end
1407 end
1407
1408
1408 should "return issues with ! empty role" do
1409 should "return issues with ! empty role" do
1409 @empty_role = Role.generate!
1410 @empty_role = Role.generate!
1410 @query = IssueQuery.new(:name => '_', :project => @project)
1411 @query = IssueQuery.new(:name => '_', :project => @project)
1411 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
1412 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
1412
1413
1413 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
1414 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
1414 end
1415 end
1415 end
1416 end
1416 end
1417 end
1417 end
1418 end
General Comments 0
You need to be logged in to leave comments. Login now