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