##// END OF EJS Templates
test: switch to Rails3 Active Record syntax at unit/query_test.rb...
Toshi MARUYAMA -
r9439:49fc255b48b6
parent child
Show More
@@ -1,985 +1,982
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 :projects_trackers
27
27
28 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
29 query = Query.new(:project => nil, :name => '_')
29 query = Query.new(:project => nil, :name => '_')
30 assert query.available_filters.has_key?('cf_1')
30 assert query.available_filters.has_key?('cf_1')
31 assert !query.available_filters.has_key?('cf_3')
31 assert !query.available_filters.has_key?('cf_3')
32 end
32 end
33
33
34 def test_system_shared_versions_should_be_available_in_global_queries
34 def test_system_shared_versions_should_be_available_in_global_queries
35 Version.find(2).update_attribute :sharing, 'system'
35 Version.find(2).update_attribute :sharing, 'system'
36 query = Query.new(:project => nil, :name => '_')
36 query = Query.new(:project => nil, :name => '_')
37 assert query.available_filters.has_key?('fixed_version_id')
37 assert query.available_filters.has_key?('fixed_version_id')
38 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'}
39 end
39 end
40
40
41 def test_project_filter_in_global_queries
41 def test_project_filter_in_global_queries
42 query = Query.new(:project => nil, :name => '_')
42 query = Query.new(:project => nil, :name => '_')
43 project_filter = query.available_filters["project_id"]
43 project_filter = query.available_filters["project_id"]
44 assert_not_nil project_filter
44 assert_not_nil project_filter
45 project_ids = project_filter[:values].map{|p| p[1]}
45 project_ids = project_filter[:values].map{|p| p[1]}
46 assert project_ids.include?("1") #public project
46 assert project_ids.include?("1") #public project
47 assert !project_ids.include?("2") #private project user cannot see
47 assert !project_ids.include?("2") #private project user cannot see
48 end
48 end
49
49
50 def find_issues_with_query(query)
50 def find_issues_with_query(query)
51 Issue.find :all,
51 Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
52 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
52 query.statement
53 :conditions => query.statement
53 ).all
54 end
54 end
55
55
56 def assert_find_issues_with_query_is_successful(query)
56 def assert_find_issues_with_query_is_successful(query)
57 assert_nothing_raised do
57 assert_nothing_raised do
58 find_issues_with_query(query)
58 find_issues_with_query(query)
59 end
59 end
60 end
60 end
61
61
62 def assert_query_statement_includes(query, condition)
62 def assert_query_statement_includes(query, condition)
63 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}"
64 end
64 end
65
65
66 def assert_query_result(expected, query)
66 def assert_query_result(expected, query)
67 assert_nothing_raised do
67 assert_nothing_raised do
68 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
68 assert_equal expected.map(&:id).sort, query.issues.map(&:id).sort
69 assert_equal expected.size, query.issue_count
69 assert_equal expected.size, query.issue_count
70 end
70 end
71 end
71 end
72
72
73 def test_query_should_allow_shared_versions_for_a_project_query
73 def test_query_should_allow_shared_versions_for_a_project_query
74 subproject_version = Version.find(4)
74 subproject_version = Version.find(4)
75 query = Query.new(:project => Project.find(1), :name => '_')
75 query = Query.new(:project => Project.find(1), :name => '_')
76 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
76 query.add_filter('fixed_version_id', '=', [subproject_version.id.to_s])
77
77
78 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
78 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IN ('4')")
79 end
79 end
80
80
81 def test_query_with_multiple_custom_fields
81 def test_query_with_multiple_custom_fields
82 query = Query.find(1)
82 query = Query.find(1)
83 assert query.valid?
83 assert query.valid?
84 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
84 assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
85 issues = find_issues_with_query(query)
85 issues = find_issues_with_query(query)
86 assert_equal 1, issues.length
86 assert_equal 1, issues.length
87 assert_equal Issue.find(3), issues.first
87 assert_equal Issue.find(3), issues.first
88 end
88 end
89
89
90 def test_operator_none
90 def test_operator_none
91 query = Query.new(:project => Project.find(1), :name => '_')
91 query = Query.new(:project => Project.find(1), :name => '_')
92 query.add_filter('fixed_version_id', '!*', [''])
92 query.add_filter('fixed_version_id', '!*', [''])
93 query.add_filter('cf_1', '!*', [''])
93 query.add_filter('cf_1', '!*', [''])
94 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
94 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
95 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
95 assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
96 find_issues_with_query(query)
96 find_issues_with_query(query)
97 end
97 end
98
98
99 def test_operator_none_for_integer
99 def test_operator_none_for_integer
100 query = Query.new(:project => Project.find(1), :name => '_')
100 query = Query.new(:project => Project.find(1), :name => '_')
101 query.add_filter('estimated_hours', '!*', [''])
101 query.add_filter('estimated_hours', '!*', [''])
102 issues = find_issues_with_query(query)
102 issues = find_issues_with_query(query)
103 assert !issues.empty?
103 assert !issues.empty?
104 assert issues.all? {|i| !i.estimated_hours}
104 assert issues.all? {|i| !i.estimated_hours}
105 end
105 end
106
106
107 def test_operator_none_for_date
107 def test_operator_none_for_date
108 query = Query.new(:project => Project.find(1), :name => '_')
108 query = Query.new(:project => Project.find(1), :name => '_')
109 query.add_filter('start_date', '!*', [''])
109 query.add_filter('start_date', '!*', [''])
110 issues = find_issues_with_query(query)
110 issues = find_issues_with_query(query)
111 assert !issues.empty?
111 assert !issues.empty?
112 assert issues.all? {|i| i.start_date.nil?}
112 assert issues.all? {|i| i.start_date.nil?}
113 end
113 end
114
114
115 def test_operator_all
115 def test_operator_all
116 query = Query.new(:project => Project.find(1), :name => '_')
116 query = Query.new(:project => Project.find(1), :name => '_')
117 query.add_filter('fixed_version_id', '*', [''])
117 query.add_filter('fixed_version_id', '*', [''])
118 query.add_filter('cf_1', '*', [''])
118 query.add_filter('cf_1', '*', [''])
119 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
119 assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
120 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
120 assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
121 find_issues_with_query(query)
121 find_issues_with_query(query)
122 end
122 end
123
123
124 def test_operator_all_for_date
124 def test_operator_all_for_date
125 query = Query.new(:project => Project.find(1), :name => '_')
125 query = Query.new(:project => Project.find(1), :name => '_')
126 query.add_filter('start_date', '*', [''])
126 query.add_filter('start_date', '*', [''])
127 issues = find_issues_with_query(query)
127 issues = find_issues_with_query(query)
128 assert !issues.empty?
128 assert !issues.empty?
129 assert issues.all? {|i| i.start_date.present?}
129 assert issues.all? {|i| i.start_date.present?}
130 end
130 end
131
131
132 def test_numeric_filter_should_not_accept_non_numeric_values
132 def test_numeric_filter_should_not_accept_non_numeric_values
133 query = Query.new(:name => '_')
133 query = Query.new(:name => '_')
134 query.add_filter('estimated_hours', '=', ['a'])
134 query.add_filter('estimated_hours', '=', ['a'])
135
135
136 assert query.has_filter?('estimated_hours')
136 assert query.has_filter?('estimated_hours')
137 assert !query.valid?
137 assert !query.valid?
138 end
138 end
139
139
140 def test_operator_is_on_float
140 def test_operator_is_on_float
141 Issue.update_all("estimated_hours = 171.2", "id=2")
141 Issue.update_all("estimated_hours = 171.2", "id=2")
142
142
143 query = Query.new(:name => '_')
143 query = Query.new(:name => '_')
144 query.add_filter('estimated_hours', '=', ['171.20'])
144 query.add_filter('estimated_hours', '=', ['171.20'])
145 issues = find_issues_with_query(query)
145 issues = find_issues_with_query(query)
146 assert_equal 1, issues.size
146 assert_equal 1, issues.size
147 assert_equal 2, issues.first.id
147 assert_equal 2, issues.first.id
148 end
148 end
149
149
150 def test_operator_is_on_integer_custom_field
150 def test_operator_is_on_integer_custom_field
151 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true)
151 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true)
152 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
152 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
153 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
153 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
154 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
154 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
155
155
156 query = Query.new(:name => '_')
156 query = Query.new(:name => '_')
157 query.add_filter("cf_#{f.id}", '=', ['12'])
157 query.add_filter("cf_#{f.id}", '=', ['12'])
158 issues = find_issues_with_query(query)
158 issues = find_issues_with_query(query)
159 assert_equal 1, issues.size
159 assert_equal 1, issues.size
160 assert_equal 2, issues.first.id
160 assert_equal 2, issues.first.id
161 end
161 end
162
162
163 def test_operator_is_on_float_custom_field
163 def test_operator_is_on_float_custom_field
164 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true)
164 f = IssueCustomField.create!(:name => 'filter', :field_format => 'float', :is_filter => true, :is_for_all => true)
165 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
165 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7.3')
166 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
166 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12.7')
167 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
167 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
168
168
169 query = Query.new(:name => '_')
169 query = Query.new(:name => '_')
170 query.add_filter("cf_#{f.id}", '=', ['12.7'])
170 query.add_filter("cf_#{f.id}", '=', ['12.7'])
171 issues = find_issues_with_query(query)
171 issues = find_issues_with_query(query)
172 assert_equal 1, issues.size
172 assert_equal 1, issues.size
173 assert_equal 2, issues.first.id
173 assert_equal 2, issues.first.id
174 end
174 end
175
175
176 def test_operator_is_on_multi_list_custom_field
176 def test_operator_is_on_multi_list_custom_field
177 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
177 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
178 :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
178 :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
179 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
179 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
180 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
180 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
181 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
181 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
182
182
183 query = Query.new(:name => '_')
183 query = Query.new(:name => '_')
184 query.add_filter("cf_#{f.id}", '=', ['value1'])
184 query.add_filter("cf_#{f.id}", '=', ['value1'])
185 issues = find_issues_with_query(query)
185 issues = find_issues_with_query(query)
186 assert_equal [1, 3], issues.map(&:id).sort
186 assert_equal [1, 3], issues.map(&:id).sort
187
187
188 query = Query.new(:name => '_')
188 query = Query.new(:name => '_')
189 query.add_filter("cf_#{f.id}", '=', ['value2'])
189 query.add_filter("cf_#{f.id}", '=', ['value2'])
190 issues = find_issues_with_query(query)
190 issues = find_issues_with_query(query)
191 assert_equal [1], issues.map(&:id).sort
191 assert_equal [1], issues.map(&:id).sort
192 end
192 end
193
193
194 def test_operator_is_not_on_multi_list_custom_field
194 def test_operator_is_not_on_multi_list_custom_field
195 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
195 f = IssueCustomField.create!(:name => 'filter', :field_format => 'list', :is_filter => true, :is_for_all => true,
196 :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
196 :possible_values => ['value1', 'value2', 'value3'], :multiple => true)
197 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
197 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value1')
198 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
198 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => 'value2')
199 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
199 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => 'value1')
200
200
201 query = Query.new(:name => '_')
201 query = Query.new(:name => '_')
202 query.add_filter("cf_#{f.id}", '!', ['value1'])
202 query.add_filter("cf_#{f.id}", '!', ['value1'])
203 issues = find_issues_with_query(query)
203 issues = find_issues_with_query(query)
204 assert !issues.map(&:id).include?(1)
204 assert !issues.map(&:id).include?(1)
205 assert !issues.map(&:id).include?(3)
205 assert !issues.map(&:id).include?(3)
206
206
207 query = Query.new(:name => '_')
207 query = Query.new(:name => '_')
208 query.add_filter("cf_#{f.id}", '!', ['value2'])
208 query.add_filter("cf_#{f.id}", '!', ['value2'])
209 issues = find_issues_with_query(query)
209 issues = find_issues_with_query(query)
210 assert !issues.map(&:id).include?(1)
210 assert !issues.map(&:id).include?(1)
211 assert issues.map(&:id).include?(3)
211 assert issues.map(&:id).include?(3)
212 end
212 end
213
213
214 def test_operator_greater_than
214 def test_operator_greater_than
215 query = Query.new(:project => Project.find(1), :name => '_')
215 query = Query.new(:project => Project.find(1), :name => '_')
216 query.add_filter('done_ratio', '>=', ['40'])
216 query.add_filter('done_ratio', '>=', ['40'])
217 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
217 assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40.0")
218 find_issues_with_query(query)
218 find_issues_with_query(query)
219 end
219 end
220
220
221 def test_operator_greater_than_a_float
221 def test_operator_greater_than_a_float
222 query = Query.new(:project => Project.find(1), :name => '_')
222 query = Query.new(:project => Project.find(1), :name => '_')
223 query.add_filter('estimated_hours', '>=', ['40.5'])
223 query.add_filter('estimated_hours', '>=', ['40.5'])
224 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
224 assert query.statement.include?("#{Issue.table_name}.estimated_hours >= 40.5")
225 find_issues_with_query(query)
225 find_issues_with_query(query)
226 end
226 end
227
227
228 def test_operator_greater_than_on_int_custom_field
228 def test_operator_greater_than_on_int_custom_field
229 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
229 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
230 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
230 CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
231 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
231 CustomValue.create!(:custom_field => f, :customized => Issue.find(2), :value => '12')
232 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
232 CustomValue.create!(:custom_field => f, :customized => Issue.find(3), :value => '')
233
233
234 query = Query.new(:project => Project.find(1), :name => '_')
234 query = Query.new(:project => Project.find(1), :name => '_')
235 query.add_filter("cf_#{f.id}", '>=', ['8'])
235 query.add_filter("cf_#{f.id}", '>=', ['8'])
236 issues = find_issues_with_query(query)
236 issues = find_issues_with_query(query)
237 assert_equal 1, issues.size
237 assert_equal 1, issues.size
238 assert_equal 2, issues.first.id
238 assert_equal 2, issues.first.id
239 end
239 end
240
240
241 def test_operator_lesser_than
241 def test_operator_lesser_than
242 query = Query.new(:project => Project.find(1), :name => '_')
242 query = Query.new(:project => Project.find(1), :name => '_')
243 query.add_filter('done_ratio', '<=', ['30'])
243 query.add_filter('done_ratio', '<=', ['30'])
244 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
244 assert query.statement.include?("#{Issue.table_name}.done_ratio <= 30.0")
245 find_issues_with_query(query)
245 find_issues_with_query(query)
246 end
246 end
247
247
248 def test_operator_lesser_than_on_custom_field
248 def test_operator_lesser_than_on_custom_field
249 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
249 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
250 query = Query.new(:project => Project.find(1), :name => '_')
250 query = Query.new(:project => Project.find(1), :name => '_')
251 query.add_filter("cf_#{f.id}", '<=', ['30'])
251 query.add_filter("cf_#{f.id}", '<=', ['30'])
252 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0")
252 assert query.statement.include?("CAST(custom_values.value AS decimal(60,3)) <= 30.0")
253 find_issues_with_query(query)
253 find_issues_with_query(query)
254 end
254 end
255
255
256 def test_operator_between
256 def test_operator_between
257 query = Query.new(:project => Project.find(1), :name => '_')
257 query = Query.new(:project => Project.find(1), :name => '_')
258 query.add_filter('done_ratio', '><', ['30', '40'])
258 query.add_filter('done_ratio', '><', ['30', '40'])
259 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
259 assert_include "#{Issue.table_name}.done_ratio BETWEEN 30.0 AND 40.0", query.statement
260 find_issues_with_query(query)
260 find_issues_with_query(query)
261 end
261 end
262
262
263 def test_operator_between_on_custom_field
263 def test_operator_between_on_custom_field
264 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
264 f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_filter => true, :is_for_all => true)
265 query = Query.new(:project => Project.find(1), :name => '_')
265 query = Query.new(:project => Project.find(1), :name => '_')
266 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
266 query.add_filter("cf_#{f.id}", '><', ['30', '40'])
267 assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement
267 assert_include "CAST(custom_values.value AS decimal(60,3)) BETWEEN 30.0 AND 40.0", query.statement
268 find_issues_with_query(query)
268 find_issues_with_query(query)
269 end
269 end
270
270
271 def test_date_filter_should_not_accept_non_date_values
271 def test_date_filter_should_not_accept_non_date_values
272 query = Query.new(:name => '_')
272 query = Query.new(:name => '_')
273 query.add_filter('created_on', '=', ['a'])
273 query.add_filter('created_on', '=', ['a'])
274
274
275 assert query.has_filter?('created_on')
275 assert query.has_filter?('created_on')
276 assert !query.valid?
276 assert !query.valid?
277 end
277 end
278
278
279 def test_date_filter_should_not_accept_invalid_date_values
279 def test_date_filter_should_not_accept_invalid_date_values
280 query = Query.new(:name => '_')
280 query = Query.new(:name => '_')
281 query.add_filter('created_on', '=', ['2011-01-34'])
281 query.add_filter('created_on', '=', ['2011-01-34'])
282
282
283 assert query.has_filter?('created_on')
283 assert query.has_filter?('created_on')
284 assert !query.valid?
284 assert !query.valid?
285 end
285 end
286
286
287 def test_relative_date_filter_should_not_accept_non_integer_values
287 def test_relative_date_filter_should_not_accept_non_integer_values
288 query = Query.new(:name => '_')
288 query = Query.new(:name => '_')
289 query.add_filter('created_on', '>t-', ['a'])
289 query.add_filter('created_on', '>t-', ['a'])
290
290
291 assert query.has_filter?('created_on')
291 assert query.has_filter?('created_on')
292 assert !query.valid?
292 assert !query.valid?
293 end
293 end
294
294
295 def test_operator_date_equals
295 def test_operator_date_equals
296 query = Query.new(:name => '_')
296 query = Query.new(:name => '_')
297 query.add_filter('due_date', '=', ['2011-07-10'])
297 query.add_filter('due_date', '=', ['2011-07-10'])
298 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
298 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
299 find_issues_with_query(query)
299 find_issues_with_query(query)
300 end
300 end
301
301
302 def test_operator_date_lesser_than
302 def test_operator_date_lesser_than
303 query = Query.new(:name => '_')
303 query = Query.new(:name => '_')
304 query.add_filter('due_date', '<=', ['2011-07-10'])
304 query.add_filter('due_date', '<=', ['2011-07-10'])
305 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
305 assert_match /issues\.due_date <= '2011-07-10 23:59:59(\.9+)?/, query.statement
306 find_issues_with_query(query)
306 find_issues_with_query(query)
307 end
307 end
308
308
309 def test_operator_date_greater_than
309 def test_operator_date_greater_than
310 query = Query.new(:name => '_')
310 query = Query.new(:name => '_')
311 query.add_filter('due_date', '>=', ['2011-07-10'])
311 query.add_filter('due_date', '>=', ['2011-07-10'])
312 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
312 assert_match /issues\.due_date > '2011-07-09 23:59:59(\.9+)?'/, query.statement
313 find_issues_with_query(query)
313 find_issues_with_query(query)
314 end
314 end
315
315
316 def test_operator_date_between
316 def test_operator_date_between
317 query = Query.new(:name => '_')
317 query = Query.new(:name => '_')
318 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
318 query.add_filter('due_date', '><', ['2011-06-23', '2011-07-10'])
319 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
319 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
320 find_issues_with_query(query)
320 find_issues_with_query(query)
321 end
321 end
322
322
323 def test_operator_in_more_than
323 def test_operator_in_more_than
324 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
324 Issue.find(7).update_attribute(:due_date, (Date.today + 15))
325 query = Query.new(:project => Project.find(1), :name => '_')
325 query = Query.new(:project => Project.find(1), :name => '_')
326 query.add_filter('due_date', '>t+', ['15'])
326 query.add_filter('due_date', '>t+', ['15'])
327 issues = find_issues_with_query(query)
327 issues = find_issues_with_query(query)
328 assert !issues.empty?
328 assert !issues.empty?
329 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
329 issues.each {|issue| assert(issue.due_date >= (Date.today + 15))}
330 end
330 end
331
331
332 def test_operator_in_less_than
332 def test_operator_in_less_than
333 query = Query.new(:project => Project.find(1), :name => '_')
333 query = Query.new(:project => Project.find(1), :name => '_')
334 query.add_filter('due_date', '<t+', ['15'])
334 query.add_filter('due_date', '<t+', ['15'])
335 issues = find_issues_with_query(query)
335 issues = find_issues_with_query(query)
336 assert !issues.empty?
336 assert !issues.empty?
337 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
337 issues.each {|issue| assert(issue.due_date >= Date.today && issue.due_date <= (Date.today + 15))}
338 end
338 end
339
339
340 def test_operator_less_than_ago
340 def test_operator_less_than_ago
341 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
341 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
342 query = Query.new(:project => Project.find(1), :name => '_')
342 query = Query.new(:project => Project.find(1), :name => '_')
343 query.add_filter('due_date', '>t-', ['3'])
343 query.add_filter('due_date', '>t-', ['3'])
344 issues = find_issues_with_query(query)
344 issues = find_issues_with_query(query)
345 assert !issues.empty?
345 assert !issues.empty?
346 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
346 issues.each {|issue| assert(issue.due_date >= (Date.today - 3) && issue.due_date <= Date.today)}
347 end
347 end
348
348
349 def test_operator_more_than_ago
349 def test_operator_more_than_ago
350 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
350 Issue.find(7).update_attribute(:due_date, (Date.today - 10))
351 query = Query.new(:project => Project.find(1), :name => '_')
351 query = Query.new(:project => Project.find(1), :name => '_')
352 query.add_filter('due_date', '<t-', ['10'])
352 query.add_filter('due_date', '<t-', ['10'])
353 assert query.statement.include?("#{Issue.table_name}.due_date <=")
353 assert query.statement.include?("#{Issue.table_name}.due_date <=")
354 issues = find_issues_with_query(query)
354 issues = find_issues_with_query(query)
355 assert !issues.empty?
355 assert !issues.empty?
356 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
356 issues.each {|issue| assert(issue.due_date <= (Date.today - 10))}
357 end
357 end
358
358
359 def test_operator_in
359 def test_operator_in
360 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
360 Issue.find(7).update_attribute(:due_date, (Date.today + 2))
361 query = Query.new(:project => Project.find(1), :name => '_')
361 query = Query.new(:project => Project.find(1), :name => '_')
362 query.add_filter('due_date', 't+', ['2'])
362 query.add_filter('due_date', 't+', ['2'])
363 issues = find_issues_with_query(query)
363 issues = find_issues_with_query(query)
364 assert !issues.empty?
364 assert !issues.empty?
365 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
365 issues.each {|issue| assert_equal((Date.today + 2), issue.due_date)}
366 end
366 end
367
367
368 def test_operator_ago
368 def test_operator_ago
369 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
369 Issue.find(7).update_attribute(:due_date, (Date.today - 3))
370 query = Query.new(:project => Project.find(1), :name => '_')
370 query = Query.new(:project => Project.find(1), :name => '_')
371 query.add_filter('due_date', 't-', ['3'])
371 query.add_filter('due_date', 't-', ['3'])
372 issues = find_issues_with_query(query)
372 issues = find_issues_with_query(query)
373 assert !issues.empty?
373 assert !issues.empty?
374 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
374 issues.each {|issue| assert_equal((Date.today - 3), issue.due_date)}
375 end
375 end
376
376
377 def test_operator_today
377 def test_operator_today
378 query = Query.new(:project => Project.find(1), :name => '_')
378 query = Query.new(:project => Project.find(1), :name => '_')
379 query.add_filter('due_date', 't', [''])
379 query.add_filter('due_date', 't', [''])
380 issues = find_issues_with_query(query)
380 issues = find_issues_with_query(query)
381 assert !issues.empty?
381 assert !issues.empty?
382 issues.each {|issue| assert_equal Date.today, issue.due_date}
382 issues.each {|issue| assert_equal Date.today, issue.due_date}
383 end
383 end
384
384
385 def test_operator_this_week_on_date
385 def test_operator_this_week_on_date
386 query = Query.new(:project => Project.find(1), :name => '_')
386 query = Query.new(:project => Project.find(1), :name => '_')
387 query.add_filter('due_date', 'w', [''])
387 query.add_filter('due_date', 'w', [''])
388 find_issues_with_query(query)
388 find_issues_with_query(query)
389 end
389 end
390
390
391 def test_operator_this_week_on_datetime
391 def test_operator_this_week_on_datetime
392 query = Query.new(:project => Project.find(1), :name => '_')
392 query = Query.new(:project => Project.find(1), :name => '_')
393 query.add_filter('created_on', 'w', [''])
393 query.add_filter('created_on', 'w', [''])
394 find_issues_with_query(query)
394 find_issues_with_query(query)
395 end
395 end
396
396
397 def test_operator_contains
397 def test_operator_contains
398 query = Query.new(:project => Project.find(1), :name => '_')
398 query = Query.new(:project => Project.find(1), :name => '_')
399 query.add_filter('subject', '~', ['uNable'])
399 query.add_filter('subject', '~', ['uNable'])
400 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
400 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
401 result = find_issues_with_query(query)
401 result = find_issues_with_query(query)
402 assert result.empty?
402 assert result.empty?
403 result.each {|issue| assert issue.subject.downcase.include?('unable') }
403 result.each {|issue| assert issue.subject.downcase.include?('unable') }
404 end
404 end
405
405
406 def test_range_for_this_week_with_week_starting_on_monday
406 def test_range_for_this_week_with_week_starting_on_monday
407 I18n.locale = :fr
407 I18n.locale = :fr
408 assert_equal '1', I18n.t(:general_first_day_of_week)
408 assert_equal '1', I18n.t(:general_first_day_of_week)
409
409
410 Date.stubs(:today).returns(Date.parse('2011-04-29'))
410 Date.stubs(:today).returns(Date.parse('2011-04-29'))
411
411
412 query = Query.new(:project => Project.find(1), :name => '_')
412 query = Query.new(:project => Project.find(1), :name => '_')
413 query.add_filter('due_date', 'w', [''])
413 query.add_filter('due_date', 'w', [''])
414 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}"
414 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}"
415 I18n.locale = :en
415 I18n.locale = :en
416 end
416 end
417
417
418 def test_range_for_this_week_with_week_starting_on_sunday
418 def test_range_for_this_week_with_week_starting_on_sunday
419 I18n.locale = :en
419 I18n.locale = :en
420 assert_equal '7', I18n.t(:general_first_day_of_week)
420 assert_equal '7', I18n.t(:general_first_day_of_week)
421
421
422 Date.stubs(:today).returns(Date.parse('2011-04-29'))
422 Date.stubs(:today).returns(Date.parse('2011-04-29'))
423
423
424 query = Query.new(:project => Project.find(1), :name => '_')
424 query = Query.new(:project => Project.find(1), :name => '_')
425 query.add_filter('due_date', 'w', [''])
425 query.add_filter('due_date', 'w', [''])
426 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}"
426 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}"
427 end
427 end
428
428
429 def test_operator_does_not_contains
429 def test_operator_does_not_contains
430 query = Query.new(:project => Project.find(1), :name => '_')
430 query = Query.new(:project => Project.find(1), :name => '_')
431 query.add_filter('subject', '!~', ['uNable'])
431 query.add_filter('subject', '!~', ['uNable'])
432 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
432 assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
433 find_issues_with_query(query)
433 find_issues_with_query(query)
434 end
434 end
435
435
436 def test_filter_assigned_to_me
436 def test_filter_assigned_to_me
437 user = User.find(2)
437 user = User.find(2)
438 group = Group.find(10)
438 group = Group.find(10)
439 User.current = user
439 User.current = user
440 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
440 i1 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => user)
441 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
441 i2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => group)
442 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
442 i3 = Issue.generate!(:project_id => 1, :tracker_id => 1, :assigned_to => Group.find(11))
443 group.users << user
443 group.users << user
444
444
445 query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
445 query = Query.new(:name => '_', :filters => { 'assigned_to_id' => {:operator => '=', :values => ['me']}})
446 result = query.issues
446 result = query.issues
447 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
447 assert_equal Issue.visible.all(:conditions => {:assigned_to_id => ([2] + user.reload.group_ids)}).sort_by(&:id), result.sort_by(&:id)
448
448
449 assert result.include?(i1)
449 assert result.include?(i1)
450 assert result.include?(i2)
450 assert result.include?(i2)
451 assert !result.include?(i3)
451 assert !result.include?(i3)
452 end
452 end
453
453
454 def test_user_custom_field_filtered_on_me
454 def test_user_custom_field_filtered_on_me
455 User.current = User.find(2)
455 User.current = User.find(2)
456 cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])
456 cf = IssueCustomField.create!(:field_format => 'user', :is_for_all => true, :is_filter => true, :name => 'User custom field', :tracker_ids => [1])
457 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
457 issue1 = Issue.create!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '2'}, :subject => 'Test', :author_id => 1)
458 issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
458 issue2 = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {cf.id.to_s => '3'})
459
459
460 query = Query.new(:name => '_', :project => Project.find(1))
460 query = Query.new(:name => '_', :project => Project.find(1))
461 filter = query.available_filters["cf_#{cf.id}"]
461 filter = query.available_filters["cf_#{cf.id}"]
462 assert_not_nil filter
462 assert_not_nil filter
463 assert_include 'me', filter[:values].map{|v| v[1]}
463 assert_include 'me', filter[:values].map{|v| v[1]}
464
464
465 query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
465 query.filters = { "cf_#{cf.id}" => {:operator => '=', :values => ['me']}}
466 result = query.issues
466 result = query.issues
467 assert_equal 1, result.size
467 assert_equal 1, result.size
468 assert_equal issue1, result.first
468 assert_equal issue1, result.first
469 end
469 end
470
470
471 def test_filter_my_projects
471 def test_filter_my_projects
472 User.current = User.find(2)
472 User.current = User.find(2)
473 query = Query.new(:name => '_')
473 query = Query.new(:name => '_')
474 filter = query.available_filters['project_id']
474 filter = query.available_filters['project_id']
475 assert_not_nil filter
475 assert_not_nil filter
476 assert_include 'mine', filter[:values].map{|v| v[1]}
476 assert_include 'mine', filter[:values].map{|v| v[1]}
477
477
478 query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}}
478 query.filters = { 'project_id' => {:operator => '=', :values => ['mine']}}
479 result = query.issues
479 result = query.issues
480 assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
480 assert_nil result.detect {|issue| !User.current.member_of?(issue.project)}
481 end
481 end
482
482
483 def test_filter_watched_issues
483 def test_filter_watched_issues
484 User.current = User.find(1)
484 User.current = User.find(1)
485 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
485 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
486 result = find_issues_with_query(query)
486 result = find_issues_with_query(query)
487 assert_not_nil result
487 assert_not_nil result
488 assert !result.empty?
488 assert !result.empty?
489 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
489 assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
490 User.current = nil
490 User.current = nil
491 end
491 end
492
492
493 def test_filter_unwatched_issues
493 def test_filter_unwatched_issues
494 User.current = User.find(1)
494 User.current = User.find(1)
495 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
495 query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
496 result = find_issues_with_query(query)
496 result = find_issues_with_query(query)
497 assert_not_nil result
497 assert_not_nil result
498 assert !result.empty?
498 assert !result.empty?
499 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
499 assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
500 User.current = nil
500 User.current = nil
501 end
501 end
502
502
503 def test_statement_should_be_nil_with_no_filters
503 def test_statement_should_be_nil_with_no_filters
504 q = Query.new(:name => '_')
504 q = Query.new(:name => '_')
505 q.filters = {}
505 q.filters = {}
506
506
507 assert q.valid?
507 assert q.valid?
508 assert_nil q.statement
508 assert_nil q.statement
509 end
509 end
510
510
511 def test_default_columns
511 def test_default_columns
512 q = Query.new
512 q = Query.new
513 assert !q.columns.empty?
513 assert !q.columns.empty?
514 end
514 end
515
515
516 def test_set_column_names
516 def test_set_column_names
517 q = Query.new
517 q = Query.new
518 q.column_names = ['tracker', :subject, '', 'unknonw_column']
518 q.column_names = ['tracker', :subject, '', 'unknonw_column']
519 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
519 assert_equal [:tracker, :subject], q.columns.collect {|c| c.name}
520 c = q.columns.first
520 c = q.columns.first
521 assert q.has_column?(c)
521 assert q.has_column?(c)
522 end
522 end
523
523
524 def test_query_should_preload_spent_hours
524 def test_query_should_preload_spent_hours
525 q = Query.new(:name => '_', :column_names => [:subject, :spent_hours])
525 q = Query.new(:name => '_', :column_names => [:subject, :spent_hours])
526 assert q.has_column?(:spent_hours)
526 assert q.has_column?(:spent_hours)
527 issues = q.issues
527 issues = q.issues
528 assert_not_nil issues.first.instance_variable_get("@spent_hours")
528 assert_not_nil issues.first.instance_variable_get("@spent_hours")
529 end
529 end
530
530
531 def test_groupable_columns_should_include_custom_fields
531 def test_groupable_columns_should_include_custom_fields
532 q = Query.new
532 q = Query.new
533 column = q.groupable_columns.detect {|c| c.name == :cf_1}
533 column = q.groupable_columns.detect {|c| c.name == :cf_1}
534 assert_not_nil column
534 assert_not_nil column
535 assert_kind_of QueryCustomFieldColumn, column
535 assert_kind_of QueryCustomFieldColumn, column
536 end
536 end
537
537
538 def test_groupable_columns_should_not_include_multi_custom_fields
538 def test_groupable_columns_should_not_include_multi_custom_fields
539 field = CustomField.find(1)
539 field = CustomField.find(1)
540 field.update_attribute :multiple, true
540 field.update_attribute :multiple, true
541
541
542 q = Query.new
542 q = Query.new
543 column = q.groupable_columns.detect {|c| c.name == :cf_1}
543 column = q.groupable_columns.detect {|c| c.name == :cf_1}
544 assert_nil column
544 assert_nil column
545 end
545 end
546
546
547 def test_grouped_with_valid_column
547 def test_grouped_with_valid_column
548 q = Query.new(:group_by => 'status')
548 q = Query.new(:group_by => 'status')
549 assert q.grouped?
549 assert q.grouped?
550 assert_not_nil q.group_by_column
550 assert_not_nil q.group_by_column
551 assert_equal :status, q.group_by_column.name
551 assert_equal :status, q.group_by_column.name
552 assert_not_nil q.group_by_statement
552 assert_not_nil q.group_by_statement
553 assert_equal 'status', q.group_by_statement
553 assert_equal 'status', q.group_by_statement
554 end
554 end
555
555
556 def test_grouped_with_invalid_column
556 def test_grouped_with_invalid_column
557 q = Query.new(:group_by => 'foo')
557 q = Query.new(:group_by => 'foo')
558 assert !q.grouped?
558 assert !q.grouped?
559 assert_nil q.group_by_column
559 assert_nil q.group_by_column
560 assert_nil q.group_by_statement
560 assert_nil q.group_by_statement
561 end
561 end
562
562
563 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
563 def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
564 with_settings :user_format => 'lastname_coma_firstname' do
564 with_settings :user_format => 'lastname_coma_firstname' do
565 q = Query.new
565 q = Query.new
566 assert q.sortable_columns.has_key?('assigned_to')
566 assert q.sortable_columns.has_key?('assigned_to')
567 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
567 assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
568 end
568 end
569 end
569 end
570
570
571 def test_sortable_columns_should_sort_authors_according_to_user_format_setting
571 def test_sortable_columns_should_sort_authors_according_to_user_format_setting
572 with_settings :user_format => 'lastname_coma_firstname' do
572 with_settings :user_format => 'lastname_coma_firstname' do
573 q = Query.new
573 q = Query.new
574 assert q.sortable_columns.has_key?('author')
574 assert q.sortable_columns.has_key?('author')
575 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
575 assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
576 end
576 end
577 end
577 end
578
578
579 def test_sortable_columns_should_include_custom_field
579 def test_sortable_columns_should_include_custom_field
580 q = Query.new
580 q = Query.new
581 assert q.sortable_columns['cf_1']
581 assert q.sortable_columns['cf_1']
582 end
582 end
583
583
584 def test_sortable_columns_should_not_include_multi_custom_field
584 def test_sortable_columns_should_not_include_multi_custom_field
585 field = CustomField.find(1)
585 field = CustomField.find(1)
586 field.update_attribute :multiple, true
586 field.update_attribute :multiple, true
587
587
588 q = Query.new
588 q = Query.new
589 assert !q.sortable_columns['cf_1']
589 assert !q.sortable_columns['cf_1']
590 end
590 end
591
591
592 def test_default_sort
592 def test_default_sort
593 q = Query.new
593 q = Query.new
594 assert_equal [], q.sort_criteria
594 assert_equal [], q.sort_criteria
595 end
595 end
596
596
597 def test_set_sort_criteria_with_hash
597 def test_set_sort_criteria_with_hash
598 q = Query.new
598 q = Query.new
599 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
599 q.sort_criteria = {'0' => ['priority', 'desc'], '2' => ['tracker']}
600 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
600 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
601 end
601 end
602
602
603 def test_set_sort_criteria_with_array
603 def test_set_sort_criteria_with_array
604 q = Query.new
604 q = Query.new
605 q.sort_criteria = [['priority', 'desc'], 'tracker']
605 q.sort_criteria = [['priority', 'desc'], 'tracker']
606 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
606 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
607 end
607 end
608
608
609 def test_create_query_with_sort
609 def test_create_query_with_sort
610 q = Query.new(:name => 'Sorted')
610 q = Query.new(:name => 'Sorted')
611 q.sort_criteria = [['priority', 'desc'], 'tracker']
611 q.sort_criteria = [['priority', 'desc'], 'tracker']
612 assert q.save
612 assert q.save
613 q.reload
613 q.reload
614 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
614 assert_equal [['priority', 'desc'], ['tracker', 'asc']], q.sort_criteria
615 end
615 end
616
616
617 def test_sort_by_string_custom_field_asc
617 def test_sort_by_string_custom_field_asc
618 q = Query.new
618 q = Query.new
619 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
619 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
620 assert c
620 assert c
621 assert c.sortable
621 assert c.sortable
622 issues = Issue.find :all,
622 issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
623 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
623 q.statement
624 :conditions => q.statement,
624 ).order("#{c.sortable} ASC").all
625 :order => "#{c.sortable} ASC"
626 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
625 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
627 assert !values.empty?
626 assert !values.empty?
628 assert_equal values.sort, values
627 assert_equal values.sort, values
629 end
628 end
630
629
631 def test_sort_by_string_custom_field_desc
630 def test_sort_by_string_custom_field_desc
632 q = Query.new
631 q = Query.new
633 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
632 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'string' }
634 assert c
633 assert c
635 assert c.sortable
634 assert c.sortable
636 issues = Issue.find :all,
635 issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
637 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
636 q.statement
638 :conditions => q.statement,
637 ).order("#{c.sortable} DESC").all
639 :order => "#{c.sortable} DESC"
640 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
638 values = issues.collect {|i| i.custom_value_for(c.custom_field).to_s}
641 assert !values.empty?
639 assert !values.empty?
642 assert_equal values.sort.reverse, values
640 assert_equal values.sort.reverse, values
643 end
641 end
644
642
645 def test_sort_by_float_custom_field_asc
643 def test_sort_by_float_custom_field_asc
646 q = Query.new
644 q = Query.new
647 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
645 c = q.available_columns.find {|col| col.is_a?(QueryCustomFieldColumn) && col.custom_field.field_format == 'float' }
648 assert c
646 assert c
649 assert c.sortable
647 assert c.sortable
650 issues = Issue.find :all,
648 issues = Issue.includes([:assigned_to, :status, :tracker, :project, :priority]).where(
651 :include => [ :assigned_to, :status, :tracker, :project, :priority ],
649 q.statement
652 :conditions => q.statement,
650 ).order("#{c.sortable} ASC").all
653 :order => "#{c.sortable} ASC"
654 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
651 values = issues.collect {|i| begin; Kernel.Float(i.custom_value_for(c.custom_field).to_s); rescue; nil; end}.compact
655 assert !values.empty?
652 assert !values.empty?
656 assert_equal values.sort, values
653 assert_equal values.sort, values
657 end
654 end
658
655
659 def test_invalid_query_should_raise_query_statement_invalid_error
656 def test_invalid_query_should_raise_query_statement_invalid_error
660 q = Query.new
657 q = Query.new
661 assert_raise Query::StatementInvalid do
658 assert_raise Query::StatementInvalid do
662 q.issues(:conditions => "foo = 1")
659 q.issues(:conditions => "foo = 1")
663 end
660 end
664 end
661 end
665
662
666 def test_issue_count
663 def test_issue_count
667 q = Query.new(:name => '_')
664 q = Query.new(:name => '_')
668 issue_count = q.issue_count
665 issue_count = q.issue_count
669 assert_equal q.issues.size, issue_count
666 assert_equal q.issues.size, issue_count
670 end
667 end
671
668
672 def test_issue_count_with_archived_issues
669 def test_issue_count_with_archived_issues
673 p = Project.generate! do |project|
670 p = Project.generate! do |project|
674 project.status = Project::STATUS_ARCHIVED
671 project.status = Project::STATUS_ARCHIVED
675 end
672 end
676 i = Issue.generate!( :project => p, :tracker => p.trackers.first )
673 i = Issue.generate!( :project => p, :tracker => p.trackers.first )
677 assert !i.visible?
674 assert !i.visible?
678
675
679 test_issue_count
676 test_issue_count
680 end
677 end
681
678
682 def test_issue_count_by_association_group
679 def test_issue_count_by_association_group
683 q = Query.new(:name => '_', :group_by => 'assigned_to')
680 q = Query.new(:name => '_', :group_by => 'assigned_to')
684 count_by_group = q.issue_count_by_group
681 count_by_group = q.issue_count_by_group
685 assert_kind_of Hash, count_by_group
682 assert_kind_of Hash, count_by_group
686 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
683 assert_equal %w(NilClass User), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
687 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
684 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
688 assert count_by_group.has_key?(User.find(3))
685 assert count_by_group.has_key?(User.find(3))
689 end
686 end
690
687
691 def test_issue_count_by_list_custom_field_group
688 def test_issue_count_by_list_custom_field_group
692 q = Query.new(:name => '_', :group_by => 'cf_1')
689 q = Query.new(:name => '_', :group_by => 'cf_1')
693 count_by_group = q.issue_count_by_group
690 count_by_group = q.issue_count_by_group
694 assert_kind_of Hash, count_by_group
691 assert_kind_of Hash, count_by_group
695 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
692 assert_equal %w(NilClass String), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
696 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
693 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
697 assert count_by_group.has_key?('MySQL')
694 assert count_by_group.has_key?('MySQL')
698 end
695 end
699
696
700 def test_issue_count_by_date_custom_field_group
697 def test_issue_count_by_date_custom_field_group
701 q = Query.new(:name => '_', :group_by => 'cf_8')
698 q = Query.new(:name => '_', :group_by => 'cf_8')
702 count_by_group = q.issue_count_by_group
699 count_by_group = q.issue_count_by_group
703 assert_kind_of Hash, count_by_group
700 assert_kind_of Hash, count_by_group
704 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
701 assert_equal %w(Date NilClass), count_by_group.keys.collect {|k| k.class.name}.uniq.sort
705 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
702 assert_equal %w(Fixnum), count_by_group.values.collect {|k| k.class.name}.uniq
706 end
703 end
707
704
708 def test_issue_count_with_nil_group_only
705 def test_issue_count_with_nil_group_only
709 Issue.update_all("assigned_to_id = NULL")
706 Issue.update_all("assigned_to_id = NULL")
710
707
711 q = Query.new(:name => '_', :group_by => 'assigned_to')
708 q = Query.new(:name => '_', :group_by => 'assigned_to')
712 count_by_group = q.issue_count_by_group
709 count_by_group = q.issue_count_by_group
713 assert_kind_of Hash, count_by_group
710 assert_kind_of Hash, count_by_group
714 assert_equal 1, count_by_group.keys.size
711 assert_equal 1, count_by_group.keys.size
715 assert_nil count_by_group.keys.first
712 assert_nil count_by_group.keys.first
716 end
713 end
717
714
718 def test_issue_ids
715 def test_issue_ids
719 q = Query.new(:name => '_')
716 q = Query.new(:name => '_')
720 order = "issues.subject, issues.id"
717 order = "issues.subject, issues.id"
721 issues = q.issues(:order => order)
718 issues = q.issues(:order => order)
722 assert_equal issues.map(&:id), q.issue_ids(:order => order)
719 assert_equal issues.map(&:id), q.issue_ids(:order => order)
723 end
720 end
724
721
725 def test_label_for
722 def test_label_for
726 q = Query.new
723 q = Query.new
727 assert_equal 'Assignee', q.label_for('assigned_to_id')
724 assert_equal 'Assignee', q.label_for('assigned_to_id')
728 end
725 end
729
726
730 def test_editable_by
727 def test_editable_by
731 admin = User.find(1)
728 admin = User.find(1)
732 manager = User.find(2)
729 manager = User.find(2)
733 developer = User.find(3)
730 developer = User.find(3)
734
731
735 # Public query on project 1
732 # Public query on project 1
736 q = Query.find(1)
733 q = Query.find(1)
737 assert q.editable_by?(admin)
734 assert q.editable_by?(admin)
738 assert q.editable_by?(manager)
735 assert q.editable_by?(manager)
739 assert !q.editable_by?(developer)
736 assert !q.editable_by?(developer)
740
737
741 # Private query on project 1
738 # Private query on project 1
742 q = Query.find(2)
739 q = Query.find(2)
743 assert q.editable_by?(admin)
740 assert q.editable_by?(admin)
744 assert !q.editable_by?(manager)
741 assert !q.editable_by?(manager)
745 assert q.editable_by?(developer)
742 assert q.editable_by?(developer)
746
743
747 # Private query for all projects
744 # Private query for all projects
748 q = Query.find(3)
745 q = Query.find(3)
749 assert q.editable_by?(admin)
746 assert q.editable_by?(admin)
750 assert !q.editable_by?(manager)
747 assert !q.editable_by?(manager)
751 assert q.editable_by?(developer)
748 assert q.editable_by?(developer)
752
749
753 # Public query for all projects
750 # Public query for all projects
754 q = Query.find(4)
751 q = Query.find(4)
755 assert q.editable_by?(admin)
752 assert q.editable_by?(admin)
756 assert !q.editable_by?(manager)
753 assert !q.editable_by?(manager)
757 assert !q.editable_by?(developer)
754 assert !q.editable_by?(developer)
758 end
755 end
759
756
760 def test_visible_scope
757 def test_visible_scope
761 query_ids = Query.visible(User.anonymous).map(&:id)
758 query_ids = Query.visible(User.anonymous).map(&:id)
762
759
763 assert query_ids.include?(1), 'public query on public project was not visible'
760 assert query_ids.include?(1), 'public query on public project was not visible'
764 assert query_ids.include?(4), 'public query for all projects was not visible'
761 assert query_ids.include?(4), 'public query for all projects was not visible'
765 assert !query_ids.include?(2), 'private query on public project was visible'
762 assert !query_ids.include?(2), 'private query on public project was visible'
766 assert !query_ids.include?(3), 'private query for all projects was visible'
763 assert !query_ids.include?(3), 'private query for all projects was visible'
767 assert !query_ids.include?(7), 'public query on private project was visible'
764 assert !query_ids.include?(7), 'public query on private project was visible'
768 end
765 end
769
766
770 context "#available_filters" do
767 context "#available_filters" do
771 setup do
768 setup do
772 @query = Query.new(:name => "_")
769 @query = Query.new(:name => "_")
773 end
770 end
774
771
775 should "include users of visible projects in cross-project view" do
772 should "include users of visible projects in cross-project view" do
776 users = @query.available_filters["assigned_to_id"]
773 users = @query.available_filters["assigned_to_id"]
777 assert_not_nil users
774 assert_not_nil users
778 assert users[:values].map{|u|u[1]}.include?("3")
775 assert users[:values].map{|u|u[1]}.include?("3")
779 end
776 end
780
777
781 should "include users of subprojects" do
778 should "include users of subprojects" do
782 user1 = User.generate!
779 user1 = User.generate!
783 user2 = User.generate!
780 user2 = User.generate!
784 project = Project.find(1)
781 project = Project.find(1)
785 Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
782 Member.create!(:principal => user1, :project => project.children.visible.first, :role_ids => [1])
786 @query.project = project
783 @query.project = project
787
784
788 users = @query.available_filters["assigned_to_id"]
785 users = @query.available_filters["assigned_to_id"]
789 assert_not_nil users
786 assert_not_nil users
790 assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
787 assert users[:values].map{|u|u[1]}.include?(user1.id.to_s)
791 assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
788 assert !users[:values].map{|u|u[1]}.include?(user2.id.to_s)
792 end
789 end
793
790
794 should "include visible projects in cross-project view" do
791 should "include visible projects in cross-project view" do
795 projects = @query.available_filters["project_id"]
792 projects = @query.available_filters["project_id"]
796 assert_not_nil projects
793 assert_not_nil projects
797 assert projects[:values].map{|u|u[1]}.include?("1")
794 assert projects[:values].map{|u|u[1]}.include?("1")
798 end
795 end
799
796
800 context "'member_of_group' filter" do
797 context "'member_of_group' filter" do
801 should "be present" do
798 should "be present" do
802 assert @query.available_filters.keys.include?("member_of_group")
799 assert @query.available_filters.keys.include?("member_of_group")
803 end
800 end
804
801
805 should "be an optional list" do
802 should "be an optional list" do
806 assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
803 assert_equal :list_optional, @query.available_filters["member_of_group"][:type]
807 end
804 end
808
805
809 should "have a list of the groups as values" do
806 should "have a list of the groups as values" do
810 Group.destroy_all # No fixtures
807 Group.destroy_all # No fixtures
811 group1 = Group.generate!.reload
808 group1 = Group.generate!.reload
812 group2 = Group.generate!.reload
809 group2 = Group.generate!.reload
813
810
814 expected_group_list = [
811 expected_group_list = [
815 [group1.name, group1.id.to_s],
812 [group1.name, group1.id.to_s],
816 [group2.name, group2.id.to_s]
813 [group2.name, group2.id.to_s]
817 ]
814 ]
818 assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
815 assert_equal expected_group_list.sort, @query.available_filters["member_of_group"][:values].sort
819 end
816 end
820
817
821 end
818 end
822
819
823 context "'assigned_to_role' filter" do
820 context "'assigned_to_role' filter" do
824 should "be present" do
821 should "be present" do
825 assert @query.available_filters.keys.include?("assigned_to_role")
822 assert @query.available_filters.keys.include?("assigned_to_role")
826 end
823 end
827
824
828 should "be an optional list" do
825 should "be an optional list" do
829 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
826 assert_equal :list_optional, @query.available_filters["assigned_to_role"][:type]
830 end
827 end
831
828
832 should "have a list of the Roles as values" do
829 should "have a list of the Roles as values" do
833 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
830 assert @query.available_filters["assigned_to_role"][:values].include?(['Manager','1'])
834 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
831 assert @query.available_filters["assigned_to_role"][:values].include?(['Developer','2'])
835 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
832 assert @query.available_filters["assigned_to_role"][:values].include?(['Reporter','3'])
836 end
833 end
837
834
838 should "not include the built in Roles as values" do
835 should "not include the built in Roles as values" do
839 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
836 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Non member','4'])
840 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
837 assert ! @query.available_filters["assigned_to_role"][:values].include?(['Anonymous','5'])
841 end
838 end
842
839
843 end
840 end
844
841
845 end
842 end
846
843
847 context "#statement" do
844 context "#statement" do
848 context "with 'member_of_group' filter" do
845 context "with 'member_of_group' filter" do
849 setup do
846 setup do
850 Group.destroy_all # No fixtures
847 Group.destroy_all # No fixtures
851 @user_in_group = User.generate!
848 @user_in_group = User.generate!
852 @second_user_in_group = User.generate!
849 @second_user_in_group = User.generate!
853 @user_in_group2 = User.generate!
850 @user_in_group2 = User.generate!
854 @user_not_in_group = User.generate!
851 @user_not_in_group = User.generate!
855
852
856 @group = Group.generate!.reload
853 @group = Group.generate!.reload
857 @group.users << @user_in_group
854 @group.users << @user_in_group
858 @group.users << @second_user_in_group
855 @group.users << @second_user_in_group
859
856
860 @group2 = Group.generate!.reload
857 @group2 = Group.generate!.reload
861 @group2.users << @user_in_group2
858 @group2.users << @user_in_group2
862
859
863 end
860 end
864
861
865 should "search assigned to for users in the group" do
862 should "search assigned to for users in the group" do
866 @query = Query.new(:name => '_')
863 @query = Query.new(:name => '_')
867 @query.add_filter('member_of_group', '=', [@group.id.to_s])
864 @query.add_filter('member_of_group', '=', [@group.id.to_s])
868
865
869 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
866 assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}')"
870 assert_find_issues_with_query_is_successful @query
867 assert_find_issues_with_query_is_successful @query
871 end
868 end
872
869
873 should "search not assigned to any group member (none)" do
870 should "search not assigned to any group member (none)" do
874 @query = Query.new(:name => '_')
871 @query = Query.new(:name => '_')
875 @query.add_filter('member_of_group', '!*', [''])
872 @query.add_filter('member_of_group', '!*', [''])
876
873
877 # Users not in a group
874 # Users not in a group
878 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}')"
875 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}')"
879 assert_find_issues_with_query_is_successful @query
876 assert_find_issues_with_query_is_successful @query
880 end
877 end
881
878
882 should "search assigned to any group member (all)" do
879 should "search assigned to any group member (all)" do
883 @query = Query.new(:name => '_')
880 @query = Query.new(:name => '_')
884 @query.add_filter('member_of_group', '*', [''])
881 @query.add_filter('member_of_group', '*', [''])
885
882
886 # Only users in a group
883 # Only users in a group
887 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}')"
884 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}')"
888 assert_find_issues_with_query_is_successful @query
885 assert_find_issues_with_query_is_successful @query
889 end
886 end
890
887
891 should "return an empty set with = empty group" do
888 should "return an empty set with = empty group" do
892 @empty_group = Group.generate!
889 @empty_group = Group.generate!
893 @query = Query.new(:name => '_')
890 @query = Query.new(:name => '_')
894 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
891 @query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
895
892
896 assert_equal [], find_issues_with_query(@query)
893 assert_equal [], find_issues_with_query(@query)
897 end
894 end
898
895
899 should "return issues with ! empty group" do
896 should "return issues with ! empty group" do
900 @empty_group = Group.generate!
897 @empty_group = Group.generate!
901 @query = Query.new(:name => '_')
898 @query = Query.new(:name => '_')
902 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
899 @query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
903
900
904 assert_find_issues_with_query_is_successful @query
901 assert_find_issues_with_query_is_successful @query
905 end
902 end
906 end
903 end
907
904
908 context "with 'assigned_to_role' filter" do
905 context "with 'assigned_to_role' filter" do
909 setup do
906 setup do
910 @manager_role = Role.find_by_name('Manager')
907 @manager_role = Role.find_by_name('Manager')
911 @developer_role = Role.find_by_name('Developer')
908 @developer_role = Role.find_by_name('Developer')
912
909
913 @project = Project.generate!
910 @project = Project.generate!
914 @manager = User.generate!
911 @manager = User.generate!
915 @developer = User.generate!
912 @developer = User.generate!
916 @boss = User.generate!
913 @boss = User.generate!
917 @guest = User.generate!
914 @guest = User.generate!
918 User.add_to_project(@manager, @project, @manager_role)
915 User.add_to_project(@manager, @project, @manager_role)
919 User.add_to_project(@developer, @project, @developer_role)
916 User.add_to_project(@developer, @project, @developer_role)
920 User.add_to_project(@boss, @project, [@manager_role, @developer_role])
917 User.add_to_project(@boss, @project, [@manager_role, @developer_role])
921
918
922 @issue1 = Issue.generate_for_project!(@project, :assigned_to_id => @manager.id)
919 @issue1 = Issue.generate_for_project!(@project, :assigned_to_id => @manager.id)
923 @issue2 = Issue.generate_for_project!(@project, :assigned_to_id => @developer.id)
920 @issue2 = Issue.generate_for_project!(@project, :assigned_to_id => @developer.id)
924 @issue3 = Issue.generate_for_project!(@project, :assigned_to_id => @boss.id)
921 @issue3 = Issue.generate_for_project!(@project, :assigned_to_id => @boss.id)
925 @issue4 = Issue.generate_for_project!(@project, :assigned_to_id => @guest.id)
922 @issue4 = Issue.generate_for_project!(@project, :assigned_to_id => @guest.id)
926 @issue5 = Issue.generate_for_project!(@project)
923 @issue5 = Issue.generate_for_project!(@project)
927 end
924 end
928
925
929 should "search assigned to for users with the Role" do
926 should "search assigned to for users with the Role" do
930 @query = Query.new(:name => '_', :project => @project)
927 @query = Query.new(:name => '_', :project => @project)
931 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
928 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
932
929
933 assert_query_result [@issue1, @issue3], @query
930 assert_query_result [@issue1, @issue3], @query
934 end
931 end
935
932
936 should "search assigned to for users with the Role on the issue project" do
933 should "search assigned to for users with the Role on the issue project" do
937 other_project = Project.generate!
934 other_project = Project.generate!
938 User.add_to_project(@developer, other_project, @manager_role)
935 User.add_to_project(@developer, other_project, @manager_role)
939
936
940 @query = Query.new(:name => '_', :project => @project)
937 @query = Query.new(:name => '_', :project => @project)
941 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
938 @query.add_filter('assigned_to_role', '=', [@manager_role.id.to_s])
942
939
943 assert_query_result [@issue1, @issue3], @query
940 assert_query_result [@issue1, @issue3], @query
944 end
941 end
945
942
946 should "return an empty set with empty role" do
943 should "return an empty set with empty role" do
947 @empty_role = Role.generate!
944 @empty_role = Role.generate!
948 @query = Query.new(:name => '_', :project => @project)
945 @query = Query.new(:name => '_', :project => @project)
949 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
946 @query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
950
947
951 assert_query_result [], @query
948 assert_query_result [], @query
952 end
949 end
953
950
954 should "search assigned to for users without the Role" do
951 should "search assigned to for users without the Role" do
955 @query = Query.new(:name => '_', :project => @project)
952 @query = Query.new(:name => '_', :project => @project)
956 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
953 @query.add_filter('assigned_to_role', '!', [@manager_role.id.to_s])
957
954
958 assert_query_result [@issue2, @issue4, @issue5], @query
955 assert_query_result [@issue2, @issue4, @issue5], @query
959 end
956 end
960
957
961 should "search assigned to for users not assigned to any Role (none)" do
958 should "search assigned to for users not assigned to any Role (none)" do
962 @query = Query.new(:name => '_', :project => @project)
959 @query = Query.new(:name => '_', :project => @project)
963 @query.add_filter('assigned_to_role', '!*', [''])
960 @query.add_filter('assigned_to_role', '!*', [''])
964
961
965 assert_query_result [@issue4, @issue5], @query
962 assert_query_result [@issue4, @issue5], @query
966 end
963 end
967
964
968 should "search assigned to for users assigned to any Role (all)" do
965 should "search assigned to for users assigned to any Role (all)" do
969 @query = Query.new(:name => '_', :project => @project)
966 @query = Query.new(:name => '_', :project => @project)
970 @query.add_filter('assigned_to_role', '*', [''])
967 @query.add_filter('assigned_to_role', '*', [''])
971
968
972 assert_query_result [@issue1, @issue2, @issue3], @query
969 assert_query_result [@issue1, @issue2, @issue3], @query
973 end
970 end
974
971
975 should "return issues with ! empty role" do
972 should "return issues with ! empty role" do
976 @empty_role = Role.generate!
973 @empty_role = Role.generate!
977 @query = Query.new(:name => '_', :project => @project)
974 @query = Query.new(:name => '_', :project => @project)
978 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
975 @query.add_filter('assigned_to_role', '!', [@empty_role.id.to_s])
979
976
980 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
977 assert_query_result [@issue1, @issue2, @issue3, @issue4, @issue5], @query
981 end
978 end
982 end
979 end
983 end
980 end
984
981
985 end
982 end
General Comments 0
You need to be logged in to leave comments. Login now