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