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