##// END OF EJS Templates
remove trailing white-spaces from test/unit/query_test.rb....
Toshi MARUYAMA -
r6650:fce0c83c0a58
parent child
Show More
@@ -1,764 +1,764
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class QueryTest < ActiveSupport::TestCase
20 class QueryTest < ActiveSupport::TestCase
21 fixtures :projects, :enabled_modules, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :watchers, :custom_fields, :custom_values, :versions, :queries
21 fixtures :projects, :enabled_modules, :users, :members, :member_roles, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :watchers, :custom_fields, :custom_values, :versions, :queries
22
22
23 def test_custom_fields_for_all_projects_should_be_available_in_global_queries
23 def test_custom_fields_for_all_projects_should_be_available_in_global_queries
24 query = Query.new(:project => nil, :name => '_')
24 query = Query.new(:project => nil, :name => '_')
25 assert query.available_filters.has_key?('cf_1')
25 assert query.available_filters.has_key?('cf_1')
26 assert !query.available_filters.has_key?('cf_3')
26 assert !query.available_filters.has_key?('cf_3')
27 end
27 end
28
28
29 def test_system_shared_versions_should_be_available_in_global_queries
29 def test_system_shared_versions_should_be_available_in_global_queries
30 Version.find(2).update_attribute :sharing, 'system'
30 Version.find(2).update_attribute :sharing, 'system'
31 query = Query.new(:project => nil, :name => '_')
31 query = Query.new(:project => nil, :name => '_')
32 assert query.available_filters.has_key?('fixed_version_id')
32 assert query.available_filters.has_key?('fixed_version_id')
33 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
33 assert query.available_filters['fixed_version_id'][:values].detect {|v| v.last == '2'}
34 end
34 end
35
35
36 def test_project_filter_in_global_queries
36 def test_project_filter_in_global_queries
37 query = Query.new(:project => nil, :name => '_')
37 query = Query.new(:project => nil, :name => '_')
38 project_filter = query.available_filters["project_id"]
38 project_filter = query.available_filters["project_id"]
39 assert_not_nil project_filter
39 assert_not_nil project_filter
40 project_ids = project_filter[:values].map{|p| p[1]}
40 project_ids = project_filter[:values].map{|p| p[1]}
41 assert project_ids.include?("1") #public project
41 assert project_ids.include?("1") #public project
42 assert !project_ids.include?("2") #private project user cannot see
42 assert !project_ids.include?("2") #private project user cannot see
43 end
43 end
44
44
45 def find_issues_with_query(query)
45 def find_issues_with_query(query)
46 Issue.find :all,
46 Issue.find :all,
47 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
47 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
48 :conditions => query.statement
48 :conditions => query.statement
49 end
49 end
50
50
51 def assert_find_issues_with_query_is_successful(query)
51 def assert_find_issues_with_query_is_successful(query)
52 assert_nothing_raised do
52 assert_nothing_raised do
53 find_issues_with_query(query)
53 find_issues_with_query(query)
54 end
54 end
55 end
55 end
56
56
57 def assert_query_statement_includes(query, condition)
57 def assert_query_statement_includes(query, condition)
58 assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}"
58 assert query.statement.include?(condition), "Query statement condition not found in: #{query.statement}"
59 end
59 end
60
60
61 def test_query_should_allow_shared_versions_for_a_project_query
61 def test_query_should_allow_shared_versions_for_a_project_query
62 subproject_version = Version.find(4)
62 subproject_version = Version.find(4)
63 query = Query.new(:project => Project.find(1), :name => '_')
63 query = Query.new(:project => Project.find(1), :name => '_')
64 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
64 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
65
65
66 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
66 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
67 end
67 end
68
68
69 def test_query_with_multiple_custom_fields
69 def test_query_with_multiple_custom_fields
70 query = Query.find(1)
70 query = Query.find(1)
71 assert query.valid?
71 assert query.valid?
72 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
72 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
73 issues = find_issues_with_query(query)
73 issues = find_issues_with_query(query)
74 assert_equal 1, issues.length
74 assert_equal 1, issues.length
75 assert_equal Issue.find(3), issues.first
75 assert_equal Issue.find(3), issues.first
76 end
76 end
77
77
78 def test_operator_none
78 def test_operator_none
79 query = Query.new(:project => Project.find(1), :name => '_')
79 query = Query.new(:project => Project.find(1), :name => '_')
80 query.add_filter('fixed_version_id', '!*', [''])
80 query.add_filter('fixed_version_id', '!*', [''])
81 query.add_filter('cf_1', '!*', [''])
81 query.add_filter('cf_1', '!*', [''])
82 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
82 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
83 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
83 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
84 find_issues_with_query(query)
84 find_issues_with_query(query)
85 end
85 end
86
86
87 def test_operator_none_for_integer
87 def test_operator_none_for_integer
88 query = Query.new(:project => Project.find(1), :name => '_')
88 query = Query.new(:project => Project.find(1), :name => '_')
89 query.add_filter('estimated_hours', '!*', [''])
89 query.add_filter('estimated_hours', '!*', [''])
90 issues = find_issues_with_query(query)
90 issues = find_issues_with_query(query)
91 assert !issues.empty?
91 assert !issues.empty?
92 assert issues.all? {|i| !i.estimated_hours}
92 assert issues.all? {|i| !i.estimated_hours}
93 end
93 end
94
94
95 def test_operator_all
95 def test_operator_all
96 query = Query.new(:project => Project.find(1), :name => '_')
96 query = Query.new(:project => Project.find(1), :name => '_')
97 query.add_filter('fixed_version_id', '*', [''])
97 query.add_filter('fixed_version_id', '*', [''])
98 query.add_filter('cf_1', '*', [''])
98 query.add_filter('cf_1', '*', [''])
99 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
99 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
100 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
100 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
101 find_issues_with_query(query)
101 find_issues_with_query(query)
102 end
102 end
103
103
104 def test_numeric_filter_should_not_accept_non_numeric_values
104 def test_numeric_filter_should_not_accept_non_numeric_values
105 query = Query.new(:name => '_')
105 query = Query.new(:name => '_')
106 query.add_filter('estimated_hours', '=', ['a'])
106 query.add_filter('estimated_hours', '=', ['a'])
107
107
108 assert query.has_filter?('estimated_hours')
108 assert query.has_filter?('estimated_hours')
109 assert !query.valid?
109 assert !query.valid?
110 end
110 end
111
111
112 def test_operator_is_on_float
112 def test_operator_is_on_float
113 Issue.update_all("estimated_hours = 171.2", "id=2")
113 Issue.update_all("estimated_hours = 171.2", "id=2")
114
114
115 query = Query.new(:name => '_')
115 query = Query.new(:name => '_')
116 query.add_filter('estimated_hours', '=', ['171.20'])
116 query.add_filter('estimated_hours', '=', ['171.20'])
117 issues = find_issues_with_query(query)
117 issues = find_issues_with_query(query)
118 assert_equal 1, issues.size
118 assert_equal 1, issues.size
119 assert_equal 2, issues.first.id
119 assert_equal 2, issues.first.id
120 end
120 end
121
121
122 def test_operator_greater_than
122 def test_operator_greater_than
123 query = Query.new(:project => Project.find(1), :name => '_')
123 query = Query.new(:project => Project.find(1), :name => '_')
124 query.add_filter('done_ratio', '>=', ['40'])
124 query.add_filter('done_ratio', '>=', ['40'])
125 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
125 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
126 find_issues_with_query(query)
126 find_issues_with_query(query)
127 end
127 end
128
128
129 def test_operator_greater_than_a_float
129 def test_operator_greater_than_a_float
130 query = Query.new(:project => Project.find(1), :name => '_')
130 query = Query.new(:project => Project.find(1), :name => '_')
131 query.add_filter('estimated_hours', '>=', ['40.5'])
131 query.add_filter('estimated_hours', '>=', ['40.5'])
132 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
132 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
133 find_issues_with_query(query)
133 find_issues_with_query(query)
134 end
134 end
135
135
136 def test_operator_greater_than_on_custom_field
136 def test_operator_greater_than_on_custom_field
137 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
137 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
138 query = Query.new(:project => Project.find(1), :name => '_')
138 query = Query.new(:project => Project.find(1), :name => '_')
139 query.add_filter("cf_#{f.id}", '>=', ['40'])
139 query.add_filter("cf_#{f.id}", '>=', ['40'])
140 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) >= 40.0")
140 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) >= 40.0")
141 find_issues_with_query(query)
141 find_issues_with_query(query)
142 end
142 end
143
143
144 def test_operator_lesser_than
144 def test_operator_lesser_than
145 query = Query.new(:project => Project.find(1), :name => '_')
145 query = Query.new(:project => Project.find(1), :name => '_')
146 query.add_filter('done_ratio', '<=', ['30'])
146 query.add_filter('done_ratio', '<=', ['30'])
147 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
147 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
148 find_issues_with_query(query)
148 find_issues_with_query(query)
149 end
149 end
150
150
151 def test_operator_lesser_than_on_custom_field
151 def test_operator_lesser_than_on_custom_field
152 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
152 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
153 query = Query.new(:project => Project.find(1), :name => '_')
153 query = Query.new(:project => Project.find(1), :name => '_')
154 query.add_filter("cf_#{f.id}", '<=', ['30'])
154 query.add_filter("cf_#{f.id}", '<=', ['30'])
155 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0")
155 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0")
156 find_issues_with_query(query)
156 find_issues_with_query(query)
157 end
157 end
158
158
159 def test_operator_between
159 def test_operator_between
160 query = Query.new(:project => Project.find(1), :name => '_')
160 query = Query.new(:project => Project.find(1), :name => '_')
161 query.add_filter('done_ratio', '><', ['30', '40'])
161 query.add_filter('done_ratio', '><', ['30', '40'])
162 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
162 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
163 find_issues_with_query(query)
163 find_issues_with_query(query)
164 end
164 end
165
165
166 def test_operator_between_on_custom_field
166 def test_operator_between_on_custom_field
167 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
167 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
168 query = Query.new(:project => Project.find(1), :name => '_')
168 query = Query.new(:project => Project.find(1), :name => '_')
169 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
169 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
170 assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement
170 assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement
171 find_issues_with_query(query)
171 find_issues_with_query(query)
172 end
172 end
173
173
174 def test_date_filter_should_not_accept_non_date_values
174 def test_date_filter_should_not_accept_non_date_values
175 query = Query.new(:name => '_')
175 query = Query.new(:name => '_')
176 query.add_filter('created_on', '=', ['a'])
176 query.add_filter('created_on', '=', ['a'])
177
177
178 assert query.has_filter?('created_on')
178 assert query.has_filter?('created_on')
179 assert !query.valid?
179 assert !query.valid?
180 end
180 end
181
181
182 def test_date_filter_should_not_accept_invalid_date_values
182 def test_date_filter_should_not_accept_invalid_date_values
183 query = Query.new(:name => '_')
183 query = Query.new(:name => '_')
184 query.add_filter('created_on', '=', ['2011-01-34'])
184 query.add_filter('created_on', '=', ['2011-01-34'])
185
185
186 assert query.has_filter?('created_on')
186 assert query.has_filter?('created_on')
187 assert !query.valid?
187 assert !query.valid?
188 end
188 end
189
189
190 def test_relative_date_filter_should_not_accept_non_integer_values
190 def test_relative_date_filter_should_not_accept_non_integer_values
191 query = Query.new(:name => '_')
191 query = Query.new(:name => '_')
192 query.add_filter('created_on', '>t-', ['a'])
192 query.add_filter('created_on', '>t-', ['a'])
193
193
194 assert query.has_filter?('created_on')
194 assert query.has_filter?('created_on')
195 assert !query.valid?
195 assert !query.valid?
196 end
196 end
197
197
198 def test_operator_date_equals
198 def test_operator_date_equals
199 query = Query.new(:name => '_')
199 query = Query.new(:name => '_')
200 query.add_filter('due_date', '=', ['2011-07-10'])
200 query.add_filter('due_date', '=', ['2011-07-10'])
201 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
201 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
202 find_issues_with_query(query)
202 find_issues_with_query(query)
203 end
203 end
204
204
205 def test_operator_date_lesser_than
205 def test_operator_date_lesser_than
206 query = Query.new(:name => '_')
206 query = Query.new(:name => '_')
207 query.add_filter('due_date', '<=', ['2011-07-10'])
207 query.add_filter('due_date', '<=', ['2011-07-10'])
208 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
208 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
209 find_issues_with_query(query)
209 find_issues_with_query(query)
210 end
210 end
211
211
212 def test_operator_date_greater_than
212 def test_operator_date_greater_than
213 query = Query.new(:name => '_')
213 query = Query.new(:name => '_')
214 query.add_filter('due_date', '>=', ['2011-07-10'])
214 query.add_filter('due_date', '>=', ['2011-07-10'])
215 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
215 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
216 find_issues_with_query(query)
216 find_issues_with_query(query)
217 end
217 end
218
218
219 def test_operator_date_between
219 def test_operator_date_between
220 query = Query.new(:name => '_')
220 query = Query.new(:name => '_')
221 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
221 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
222 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
222 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
223 find_issues_with_query(query)
223 find_issues_with_query(query)
224 end
224 end
225
225
226 def test_operator_in_more_than
226 def test_operator_in_more_than
227 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
227 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
228 query = Query.new(:project => Project.find(1), :name => '_')
228 query = Query.new(:project => Project.find(1), :name => '_')
229 query.add_filter('due_date', '>t+', ['15'])
229 query.add_filter('due_date', '>t+', ['15'])
230 issues = find_issues_with_query(query)
230 issues = find_issues_with_query(query)
231 assert !issues.empty?
231 assert !issues.empty?
232 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
232 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
233 end
233 end
234
234
235 def test_operator_in_less_than
235 def test_operator_in_less_than
236 query = Query.new(:project => Project.find(1), :name => '_')
236 query = Query.new(:project => Project.find(1), :name => '_')
237 query.add_filter('due_date', '<t+', ['15'])
237 query.add_filter('due_date', '<t+', ['15'])
238 issues = find_issues_with_query(query)
238 issues = find_issues_with_query(query)
239 assert !issues.empty?
239 assert !issues.empty?
240 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
240 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
241 end
241 end
242
242
243 def test_operator_less_than_ago
243 def test_operator_less_than_ago
244 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
244 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
245 query = Query.new(:project => Project.find(1), :name => '_')
245 query = Query.new(:project => Project.find(1), :name => '_')
246 query.add_filter('due_date', '>t-', ['3'])
246 query.add_filter('due_date', '>t-', ['3'])
247 issues = find_issues_with_query(query)
247 issues = find_issues_with_query(query)
248 assert !issues.empty?
248 assert !issues.empty?
249 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
249 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
250 end
250 end
251
251
252 def test_operator_more_than_ago
252 def test_operator_more_than_ago
253 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
253 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
254 query = Query.new(:project => Project.find(1), :name => '_')
254 query = Query.new(:project => Project.find(1), :name => '_')
255 query.add_filter('due_date', '<t-', ['10'])
255 query.add_filter('due_date', '<t-', ['10'])
256 assert query.statement.include?("#{Issue.table_name}.due_date <=")
256 assert query.statement.include?("#{Issue.table_name}.due_date <=")
257 issues = find_issues_with_query(query)
257 issues = find_issues_with_query(query)
258 assert !issues.empty?
258 assert !issues.empty?
259 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
259 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
260 end
260 end
261
261
262 def test_operator_in
262 def test_operator_in
263 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
263 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
264 query = Query.new(:project => Project.find(1), :name => '_')
264 query = Query.new(:project => Project.find(1), :name => '_')
265 query.add_filter('due_date', 't+', ['2'])
265 query.add_filter('due_date', 't+', ['2'])
266 issues = find_issues_with_query(query)
266 issues = find_issues_with_query(query)
267 assert !issues.empty?
267 assert !issues.empty?
268 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
268 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
269 end
269 end
270
270
271 def test_operator_ago
271 def test_operator_ago
272 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
272 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
273 query = Query.new(:project => Project.find(1), :name => '_')
273 query = Query.new(:project => Project.find(1), :name => '_')
274 query.add_filter('due_date', 't-', ['3'])
274 query.add_filter('due_date', 't-', ['3'])
275 issues = find_issues_with_query(query)
275 issues = find_issues_with_query(query)
276 assert !issues.empty?
276 assert !issues.empty?
277 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
277 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
278 end
278 end
279
279
280 def test_operator_today
280 def test_operator_today
281 query = Query.new(:project => Project.find(1), :name => '_')
281 query = Query.new(:project => Project.find(1), :name => '_')
282 query.add_filter('due_date', 't', [''])
282 query.add_filter('due_date', 't', [''])
283 issues = find_issues_with_query(query)
283 issues = find_issues_with_query(query)
284 assert !issues.empty?
284 assert !issues.empty?
285 issues.each {|issue| assert_equal Date.today, issue.due_date}
285 issues.each {|issue| assert_equal Date.today, issue.due_date}
286 end
286 end
287
287
288 def test_operator_this_week_on_date
288 def test_operator_this_week_on_date
289 query = Query.new(:project => Project.find(1), :name => '_')
289 query = Query.new(:project => Project.find(1), :name => '_')
290 query.add_filter('due_date', 'w', [''])
290 query.add_filter('due_date', 'w', [''])
291 find_issues_with_query(query)
291 find_issues_with_query(query)
292 end
292 end
293
293
294 def test_operator_this_week_on_datetime
294 def test_operator_this_week_on_datetime
295 query = Query.new(:project => Project.find(1), :name => '_')
295 query = Query.new(:project => Project.find(1), :name => '_')
296 query.add_filter('created_on', 'w', [''])
296 query.add_filter('created_on', 'w', [''])
297 find_issues_with_query(query)
297 find_issues_with_query(query)
298 end
298 end
299
299
300 def test_operator_contains
300 def test_operator_contains
301 query = Query.new(:project => Project.find(1), :name => '_')
301 query = Query.new(:project => Project.find(1), :name => '_')
302 query.add_filter('subject', '~', ['uNable'])
302 query.add_filter('subject', '~', ['uNable'])
303 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
303 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
304 result = find_issues_with_query(query)
304 result = find_issues_with_query(query)
305 assert result.empty?
305 assert result.empty?
306 result.each {|issue| assert issue.subject.downcase.include?('unable') }
306 result.each {|issue| assert issue.subject.downcase.include?('unable') }
307 end
307 end
308
308
309 def test_range_for_this_week_with_week_starting_on_monday
309 def test_range_for_this_week_with_week_starting_on_monday
310 I18n.locale = :fr
310 I18n.locale = :fr
311 assert_equal '1', I18n.t(:general_first_day_of_week)
311 assert_equal '1', I18n.t(:general_first_day_of_week)
312
312
313 Date.stubs(:today).returns(Date.parse('2011-04-29'))
313 Date.stubs(:today).returns(Date.parse('2011-04-29'))
314
314
315 query = Query.new(:project => Project.find(1), :name => '_')
315 query = Query.new(:project => Project.find(1), :name => '_')
316 query.add_filter('due_date', 'w', [''])
316 query.add_filter('due_date', 'w', [''])
317 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}"
317 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}"
318 I18n.locale = :en
318 I18n.locale = :en
319 end
319 end
320
320
321 def test_range_for_this_week_with_week_starting_on_sunday
321 def test_range_for_this_week_with_week_starting_on_sunday
322 I18n.locale = :en
322 I18n.locale = :en
323 assert_equal '7', I18n.t(:general_first_day_of_week)
323 assert_equal '7', I18n.t(:general_first_day_of_week)
324
324
325 Date.stubs(:today).returns(Date.parse('2011-04-29'))
325 Date.stubs(:today).returns(Date.parse('2011-04-29'))
326
326
327 query = Query.new(:project => Project.find(1), :name => '_')
327 query = Query.new(:project => Project.find(1), :name => '_')
328 query.add_filter('due_date', 'w', [''])
328 query.add_filter('due_date', 'w', [''])
329 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}"
329 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}"
330 end
330 end
331
331
332 def test_operator_does_not_contains
332 def test_operator_does_not_contains
333 query = Query.new(:project => Project.find(1), :name => '_')
333 query = Query.new(:project => Project.find(1), :name => '_')
334 query.add_filter('subject', '!~', ['uNable'])
334 query.add_filter('subject', '!~', ['uNable'])
335 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
335 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
336 find_issues_with_query(query)
336 find_issues_with_query(query)
337 end
337 end
338
338
339 def test_filter_assigned_to_me
339 def test_filter_assigned_to_me
340 user = User.find(2)
340 user = User.find(2)
341 group = Group.find(10)
341 group = Group.find(10)
342 User.current = user
342 User.current = user
343 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
343 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
344 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
344 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
345 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
345 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
346 group.users << user
346 group.users << user
347
347
348 query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
348 query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
349 result = query.issues
349 result = query.issues
350 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
350 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
351
351
352 assert result.include?(i1)
352 assert result.include?(i1)
353 assert result.include?(i2)
353 assert result.include?(i2)
354 assert !result.include?(i3)
354 assert !result.include?(i3)
355 end
355 end
356
356
357 def test_filter_watched_issues
357 def test_filter_watched_issues
358 User.current = User.find(1)
358 User.current = User.find(1)
359 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
359 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
360 result = find_issues_with_query(query)
360 result = find_issues_with_query(query)
361 assert_not_nil result
361 assert_not_nil result
362 assert !result.empty?
362 assert !result.empty?
363 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
363 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
364 User.current = nil
364 User.current = nil
365 end
365 end
366
366
367 def test_filter_unwatched_issues
367 def test_filter_unwatched_issues
368 User.current = User.find(1)
368 User.current = User.find(1)
369 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
369 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
370 result = find_issues_with_query(query)
370 result = find_issues_with_query(query)
371 assert_not_nil result
371 assert_not_nil result
372 assert !result.empty?
372 assert !result.empty?
373 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
373 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
374 User.current = nil
374 User.current = nil
375 end
375 end
376
376
377 def test_statement_should_be_nil_with_no_filters
377 def test_statement_should_be_nil_with_no_filters
378 q = Query.new(:name => '_')
378 q = Query.new(:name => '_')
379 q.filters = {}
379 q.filters = {}
380
380
381 assert q.valid?
381 assert q.valid?
382 assert_nil q.statement
382 assert_nil q.statement
383 end
383 end
384
384
385 def test_default_columns
385 def test_default_columns
386 q = Query.new
386 q = Query.new
387 assert !q.columns.empty?
387 assert !q.columns.empty?
388 end
388 end
389
389
390 def test_set_column_names
390 def test_set_column_names
391 q = Query.new
391 q = Query.new
392 q.column_names = ['tracker', :subject, '', 'unknonw_column']
392 q.column_names = ['tracker', :subject, '', 'unknonw_column']
393 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
393 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
394 c = q.columns.first
394 c = q.columns.first
395 assert q.has_column?(c)
395 assert q.has_column?(c)
396 end
396 end
397
397
398 def test_groupable_columns_should_include_custom_fields
398 def test_groupable_columns_should_include_custom_fields
399 q = Query.new
399 q = Query.new
400 assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn}
400 assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn}
401 end
401 end
402
402
403 def test_grouped_with_valid_column
403 def test_grouped_with_valid_column
404 q = Query.new(:group_by => 'status')
404 q = Query.new(:group_by => 'status')
405 assert q.grouped?
405 assert q.grouped?
406 assert_not_nil q.group_by_column
406 assert_not_nil q.group_by_column
407 assert_equal :status, q.group_by_column.name
407 assert_equal :status, q.group_by_column.name
408 assert_not_nil q.group_by_statement
408 assert_not_nil q.group_by_statement
409 assert_equal 'status', q.group_by_statement
409 assert_equal 'status', q.group_by_statement
410 end
410 end
411
411
412 def test_grouped_with_invalid_column
412 def test_grouped_with_invalid_column
413 q = Query.new(:group_by => 'foo')
413 q = Query.new(:group_by => 'foo')
414 assert !q.grouped?
414 assert !q.grouped?
415 assert_nil q.group_by_column
415 assert_nil q.group_by_column
416 assert_nil q.group_by_statement
416 assert_nil q.group_by_statement
417 end
417 end
418
418
419 def test_default_sort
419 def test_default_sort
420 q = Query.new
420 q = Query.new
421 assert_equal [], q.sort_criteria
421 assert_equal [], q.sort_criteria
422 end
422 end
423
423
424 def test_set_sort_criteria_with_hash
424 def test_set_sort_criteria_with_hash
425 q = Query.new
425 q = Query.new
426 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
426 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
427 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
427 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
428 end
428 end
429
429
430 def test_set_sort_criteria_with_array
430 def test_set_sort_criteria_with_array
431 q = Query.new
431 q = Query.new
432 q.sort_criteria = [['priority', 'desc'], 'tracker']
432 q.sort_criteria = [['priority', 'desc'], 'tracker']
433 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
433 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
434 end
434 end
435
435
436 def test_create_query_with_sort
436 def test_create_query_with_sort
437 q = Query.new(:name => 'Sorted')
437 q = Query.new(:name => 'Sorted')
438 q.sort_criteria = [['priority', 'desc'], 'tracker']
438 q.sort_criteria = [['priority', 'desc'], 'tracker']
439 assert q.save
439 assert q.save
440 q.reload
440 q.reload
441 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
441 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
442 end
442 end
443
443
444 def test_sort_by_string_custom_field_asc
444 def test_sort_by_string_custom_field_asc
445 q = Query.new
445 q = Query.new
446 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
446 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
447 assert c
447 assert c
448 assert c.sortable
448 assert c.sortable
449 issues = Issue.find :all,
449 issues = Issue.find :all,
450 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
450 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
451 :conditions => q.statement,
451 :conditions => q.statement,
452 :order => "#{c.sortable} ASC"
452 :order => "#{c.sortable} ASC"
453 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
453 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
454 assert !values.empty?
454 assert !values.empty?
455 assert_equal values.sort, values
455 assert_equal values.sort, values
456 end
456 end
457
457
458 def test_sort_by_string_custom_field_desc
458 def test_sort_by_string_custom_field_desc
459 q = Query.new
459 q = Query.new
460 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
460 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
461 assert c
461 assert c
462 assert c.sortable
462 assert c.sortable
463 issues = Issue.find :all,
463 issues = Issue.find :all,
464 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
464 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
465 :conditions => q.statement,
465 :conditions => q.statement,
466 :order => "#{c.sortable} DESC"
466 :order => "#{c.sortable} DESC"
467 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
467 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
468 assert !values.empty?
468 assert !values.empty?
469 assert_equal values.sort.reverse, values
469 assert_equal values.sort.reverse, values
470 end
470 end
471
471
472 def test_sort_by_float_custom_field_asc
472 def test_sort_by_float_custom_field_asc
473 q = Query.new
473 q = Query.new
474 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
474 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
475 assert c
475 assert c
476 assert c.sortable
476 assert c.sortable
477 issues = Issue.find :all,
477 issues = Issue.find :all,
478 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
478 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
479 :conditions => q.statement,
479 :conditions => q.statement,
480 :order => "#{c.sortable} ASC"
480 :order => "#{c.sortable} ASC"
481 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
481 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
482 assert !values.empty?
482 assert !values.empty?
483 assert_equal values.sort, values
483 assert_equal values.sort, values
484 end
484 end
485
485
486 def test_invalid_query_should_raise_query_statement_invalid_error
486 def test_invalid_query_should_raise_query_statement_invalid_error
487 q = Query.new
487 q = Query.new
488 assert_raise Query::StatementInvalid do
488 assert_raise Query::StatementInvalid do
489 q.issues(:conditions => "foo = 1")
489 q.issues(:conditions => "foo = 1")
490 end
490 end
491 end
491 end
492
492
493 def test_issue_count
493 def test_issue_count
494 q = Query.new(:name => '_')
494 q = Query.new(:name => '_')
495 issue_count = q.issue_count
495 issue_count = q.issue_count
496 assert_equal q.issues.size, issue_count
496 assert_equal q.issues.size, issue_count
497 end
497 end
498
498
499 def test_issue_count_with_archived_issues
499 def test_issue_count_with_archived_issues
500 p = Project.generate!( :status => Project::STATUS_ARCHIVED )
500 p = Project.generate!( :status => Project::STATUS_ARCHIVED )
501 i = Issue.generate!( :project => p, :tracker => p.trackers.first )
501 i = Issue.generate!( :project => p, :tracker => p.trackers.first )
502 assert !i.visible?
502 assert !i.visible?
503
503
504 test_issue_count
504 test_issue_count
505 end
505 end
506
506
507 def test_issue_count_by_association_group
507 def test_issue_count_by_association_group
508 q = Query.new(:name => '_', :group_by => 'assigned_to')
508 q = Query.new(:name => '_', :group_by => 'assigned_to')
509 count_by_group = q.issue_count_by_group
509 count_by_group = q.issue_count_by_group
510 assert_kind_of Hash, count_by_group
510 assert_kind_of Hash, count_by_group
511 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
511 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
512 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
512 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
513 assert count_by_group.has_key?(User.find(3))
513 assert count_by_group.has_key?(User.find(3))
514 end
514 end
515
515
516 def test_issue_count_by_list_custom_field_group
516 def test_issue_count_by_list_custom_field_group
517 q = Query.new(:name => '_', :group_by => 'cf_1')
517 q = Query.new(:name => '_', :group_by => 'cf_1')
518 count_by_group = q.issue_count_by_group
518 count_by_group = q.issue_count_by_group
519 assert_kind_of Hash, count_by_group
519 assert_kind_of Hash, count_by_group
520 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
520 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
521 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
521 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
522 assert count_by_group.has_key?('MySQL')
522 assert count_by_group.has_key?('MySQL')
523 end
523 end
524
524
525 def test_issue_count_by_date_custom_field_group
525 def test_issue_count_by_date_custom_field_group
526 q = Query.new(:name => '_', :group_by => 'cf_8')
526 q = Query.new(:name => '_', :group_by => 'cf_8')
527 count_by_group = q.issue_count_by_group
527 count_by_group = q.issue_count_by_group
528 assert_kind_of Hash, count_by_group
528 assert_kind_of Hash, count_by_group
529 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
529 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
530 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
530 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
531 end
531 end
532
532
533 def test_label_for
533 def test_label_for
534 q = Query.new
534 q = Query.new
535 assert_equal 'assigned_to', q.label_for('assigned_to_id')
535 assert_equal 'assigned_to', q.label_for('assigned_to_id')
536 end
536 end
537
537
538 def test_editable_by
538 def test_editable_by
539 admin = User.find(1)
539 admin = User.find(1)
540 manager = User.find(2)
540 manager = User.find(2)
541 developer = User.find(3)
541 developer = User.find(3)
542
542
543 # Public query on project 1
543 # Public query on project 1
544 q = Query.find(1)
544 q = Query.find(1)
545 assert q.editable_by?(admin)
545 assert q.editable_by?(admin)
546 assert q.editable_by?(manager)
546 assert q.editable_by?(manager)
547 assert !q.editable_by?(developer)
547 assert !q.editable_by?(developer)
548
548
549 # Private query on project 1
549 # Private query on project 1
550 q = Query.find(2)
550 q = Query.find(2)
551 assert q.editable_by?(admin)
551 assert q.editable_by?(admin)
552 assert !q.editable_by?(manager)
552 assert !q.editable_by?(manager)
553 assert q.editable_by?(developer)
553 assert q.editable_by?(developer)
554
554
555 # Private query for all projects
555 # Private query for all projects
556 q = Query.find(3)
556 q = Query.find(3)
557 assert q.editable_by?(admin)
557 assert q.editable_by?(admin)
558 assert !q.editable_by?(manager)
558 assert !q.editable_by?(manager)
559 assert q.editable_by?(developer)
559 assert q.editable_by?(developer)
560
560
561 # Public query for all projects
561 # Public query for all projects
562 q = Query.find(4)
562 q = Query.find(4)
563 assert q.editable_by?(admin)
563 assert q.editable_by?(admin)
564 assert !q.editable_by?(manager)
564 assert !q.editable_by?(manager)
565 assert !q.editable_by?(developer)
565 assert !q.editable_by?(developer)
566 end
566 end
567
567
568 def test_visible_scope
568 def test_visible_scope
569 query_ids = Query.visible(User.anonymous).map(&:id)
569 query_ids = Query.visible(User.anonymous).map(&:id)
570
570
571 assert query_ids.include?(1), 'public query on public project was not visible'
571 assert query_ids.include?(1), 'public query on public project was not visible'
572 assert query_ids.include?(4), 'public query for all projects was not visible'
572 assert query_ids.include?(4), 'public query for all projects was not visible'
573 assert !query_ids.include?(2), 'private query on public project was visible'
573 assert !query_ids.include?(2), 'private query on public project was visible'
574 assert !query_ids.include?(3), 'private query for all projects was visible'
574 assert !query_ids.include?(3), 'private query for all projects was visible'
575 assert !query_ids.include?(7), 'public query on private project was visible'
575 assert !query_ids.include?(7), 'public query on private project was visible'
576 end
576 end
577
577
578 context "#available_filters" do
578 context "#available_filters" do
579 setup do
579 setup do
580 @query = Query.new(:name => "_")
580 @query = Query.new(:name => "_")
581 end
581 end
582
582
583 should "include users of visible projects in cross-project view" do
583 should "include users of visible projects in cross-project view" do
584 users = @query.available_filters["assigned_to_id"]
584 users = @query.available_filters["assigned_to_id"]
585 assert_not_nil users
585 assert_not_nil users
586 assert users[:values].map{|u|u[1]}.include?("3")
586 assert users[:values].map{|u|u[1]}.include?("3")
587 end
587 end
588
588
589 should "include visible projects in cross-project view" do
589 should "include visible projects in cross-project view" do
590 projects = @query.available_filters["project_id"]
590 projects = @query.available_filters["project_id"]
591 assert_not_nil projects
591 assert_not_nil projects
592 assert projects[:values].map{|u|u[1]}.include?("1")
592 assert projects[:values].map{|u|u[1]}.include?("1")
593 end
593 end
594
594
595 context "'member_of_group' filter" do
595 context "'member_of_group' filter" do
596 should "be present" do
596 should "be present" do
597 assert @query.available_filters.keys.include?("member_of_group")
597 assert @query.available_filters.keys.include?("member_of_group")
598 end
598 end
599
599
600 should "be an optional list" do
600 should "be an optional list" do
601 assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
601 assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
602 end
602 end
603
603
604 should "have a list of the groups as values" do
604 should "have a list of the groups as values" do
605 Group.destroy_all # No fixtures
605 Group.destroy_all # No fixtures
606 group1 = Group.generate!.reload
606 group1 = Group.generate!.reload
607 group2 = Group.generate!.reload
607 group2 = Group.generate!.reload
608
608
609 expected_group_list = [
609 expected_group_list = [
610 [group1.name, group1.id.to_s],
610 [group1.name, group1.id.to_s],
611 [group2.name, group2.id.to_s]
611 [group2.name, group2.id.to_s]
612 ]
612 ]
613 assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
613 assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
614 end
614 end
615
615
616 end
616 end
617
617
618 context "'assigned_to_role' filter" do
618 context "'assigned_to_role' filter" do
619 should "be present" do
619 should "be present" do
620 assert @query.available_filters.keys.include?("assigned_to_role")
620 assert @query.available_filters.keys.include?("assigned_to_role")
621 end
621 end
622
622
623 should "be an optional list" do
623 should "be an optional list" do
624 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
624 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
625 end
625 end
626
626
627 should "have a list of the Roles as values" do
627 should "have a list of the Roles as values" do
628 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
628 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
629 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
629 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
630 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
630 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
631 end
631 end
632
632
633 should "not include the built in Roles as values" do
633 should "not include the built in Roles as values" do
634 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
634 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
635 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
635 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
636 end
636 end
637
637
638 end
638 end
639
639
640 end
640 end
641
641
642 context "#statement" do
642 context "#statement" do
643 context "with 'member_of_group' filter" do
643 context "with 'member_of_group' filter" do
644 setup do
644 setup do
645 Group.destroy_all # No fixtures
645 Group.destroy_all # No fixtures
646 @user_in_group = User.generate!
646 @user_in_group = User.generate!
647 @second_user_in_group = User.generate!
647 @second_user_in_group = User.generate!
648 @user_in_group2 = User.generate!
648 @user_in_group2 = User.generate!
649 @user_not_in_group = User.generate!
649 @user_not_in_group = User.generate!
650
650
651 @group = Group.generate!.reload
651 @group = Group.generate!.reload
652 @group.users << @user_in_group
652 @group.users << @user_in_group
653 @group.users << @second_user_in_group
653 @group.users << @second_user_in_group
654
654
655 @group2 = Group.generate!.reload
655 @group2 = Group.generate!.reload
656 @group2.users << @user_in_group2
656 @group2.users << @user_in_group2
657
657
658 end
658 end
659
659
660 should "search assigned to for users in the group" do
660 should "search assigned to for users in the group" do
661 @query = Query.new(:name => '_')
661 @query = Query.new(:name => '_')
662 @query.add_filter('member_of_group', '=', [@group.id.to_s])
662 @query.add_filter('member_of_group', '=', [@group.id.to_s])
663
663
664 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
664 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
665 assert_find_issues_with_query_is_successful @query
665 assert_find_issues_with_query_is_successful @query
666 end
666 end
667
667
668 should "search not assigned to any group member (none)" do
668 should "search not assigned to any group member (none)" do
669 @query = Query.new(:name => '_')
669 @query = Query.new(:name => '_')
670 @query.add_filter('member_of_group', '!*', [''])
670 @query.add_filter('member_of_group', '!*', [''])
671
671
672 # Users not in a group
672 # Users not in a group
673 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}')"
673 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}')"
674 assert_find_issues_with_query_is_successful @query
674 assert_find_issues_with_query_is_successful @query
675 end
675 end
676
676
677 should "search assigned to any group member (all)" do
677 should "search assigned to any group member (all)" do
678 @query = Query.new(:name => '_')
678 @query = Query.new(:name => '_')
679 @query.add_filter('member_of_group', '*', [''])
679 @query.add_filter('member_of_group', '*', [''])
680
680
681 # Only users in a group
681 # Only users in a group
682 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}')"
682 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}')"
683 assert_find_issues_with_query_is_successful @query
683 assert_find_issues_with_query_is_successful @query
684 end
684 end
685
685
686 should "return an empty set with = empty group" do
686 should "return an empty set with = empty group" do
687 @empty_group = Group.generate!
687 @empty_group = Group.generate!
688 @query = Query.new(:name => '_')
688 @query = Query.new(:name => '_')
689 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
689 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
690
690
691 assert_equal [], find_issues_with_query(@query)
691 assert_equal [], find_issues_with_query(@query)
692 end
692 end
693
693
694 should "return issues with ! empty group" do
694 should "return issues with ! empty group" do
695 @empty_group = Group.generate!
695 @empty_group = Group.generate!
696 @query = Query.new(:name => '_')
696 @query = Query.new(:name => '_')
697 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
697 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
698
698
699 assert_find_issues_with_query_is_successful @query
699 assert_find_issues_with_query_is_successful @query
700 end
700 end
701 end
701 end
702
702
703 context "with 'assigned_to_role' filter" do
703 context "with 'assigned_to_role' filter" do
704 setup do
704 setup do
705 # No fixtures
705 # No fixtures
706 MemberRole.delete_all
706 MemberRole.delete_all
707 Member.delete_all
707 Member.delete_all
708 Role.delete_all
708 Role.delete_all
709
709
710 @manager_role = Role.generate!(:name => 'Manager')
710 @manager_role = Role.generate!(:name => 'Manager')
711 @developer_role = Role.generate!(:name => 'Developer')
711 @developer_role = Role.generate!(:name => 'Developer')
712
712
713 @project = Project.generate!
713 @project = Project.generate!
714 @manager = User.generate!
714 @manager = User.generate!
715 @developer = User.generate!
715 @developer = User.generate!
716 @boss = User.generate!
716 @boss = User.generate!
717 User.add_to_project(@manager, @project, @manager_role)
717 User.add_to_project(@manager, @project, @manager_role)
718 User.add_to_project(@developer, @project, @developer_role)
718 User.add_to_project(@developer, @project, @developer_role)
719 User.add_to_project(@boss, @project, [@manager_role, @developer_role])
719 User.add_to_project(@boss, @project, [@manager_role, @developer_role])
720 end
720 end
721
721
722 should "search assigned to for users with the Role" do
722 should "search assigned to for users with the Role" do
723 @query = Query.new(:name => '_')
723 @query = Query.new(:name => '_')
724 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
724 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
725
725
726 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@boss.id}')"
726 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@boss.id}')"
727 assert_find_issues_with_query_is_successful @query
727 assert_find_issues_with_query_is_successful @query
728 end
728 end
729
729
730 should "search assigned to for users not assigned to any Role (none)" do
730 should "search assigned to for users not assigned to any Role (none)" do
731 @query = Query.new(:name => '_')
731 @query = Query.new(:name => '_')
732 @query.add_filter('assigned_to_role', '!*', [''])
732 @query.add_filter('assigned_to_role', '!*', [''])
733
733
734 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')"
734 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')"
735 assert_find_issues_with_query_is_successful @query
735 assert_find_issues_with_query_is_successful @query
736 end
736 end
737
737
738 should "search assigned to for users assigned to any Role (all)" do
738 should "search assigned to for users assigned to any Role (all)" do
739 @query = Query.new(:name => '_')
739 @query = Query.new(:name => '_')
740 @query.add_filter('assigned_to_role', '*', [''])
740 @query.add_filter('assigned_to_role', '*', [''])
741
741
742 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')"
742 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')"
743 assert_find_issues_with_query_is_successful @query
743 assert_find_issues_with_query_is_successful @query
744 end
744 end
745
745
746 should "return an empty set with empty role" do
746 should "return an empty set with empty role" do
747 @empty_role = Role.generate!
747 @empty_role = Role.generate!
748 @query = Query.new(:name => '_')
748 @query = Query.new(:name => '_')
749 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
749 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
750
750
751 assert_equal [], find_issues_with_query(@query)
751 assert_equal [], find_issues_with_query(@query)
752 end
752 end
753
753
754 should "return issues with ! empty role" do
754 should "return issues with ! empty role" do
755 @empty_role = Role.generate!
755 @empty_role = Role.generate!
756 @query = Query.new(:name => '_')
756 @query = Query.new(:name => '_')
757 @query.add_filter('member_of_group', '!', [@empty_role.id.to_s])
757 @query.add_filter('member_of_group', '!', [@empty_role.id.to_s])
758
758
759 assert_find_issues_with_query_is_successful @query
759 assert_find_issues_with_query_is_successful @query
760 end
760 end
761 end
761 end
762 end
762 end
763
763
764 end
764 end
General Comments 0
You need to be logged in to leave comments. Login now