##// END OF EJS Templates
Fixed that grouping issue by key/value custom field does not work (#22178)....
Jean-Philippe Lang -
r14842:e0ae0f287a5f
parent child
Show More
@@ -1,74 +1,80
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class CustomFieldEnumeration < ActiveRecord::Base
19 19 belongs_to :custom_field
20 20 attr_accessible :name, :active, :position
21 21
22 22 validates_presence_of :name, :position, :custom_field_id
23 23 validates_length_of :name, :maximum => 60
24 24 validates_numericality_of :position, :only_integer => true
25 25 before_create :set_position
26 26
27 27 scope :active, lambda { where(:active => true) }
28 28
29 29 def to_s
30 30 name.to_s
31 31 end
32 32
33 33 def objects_count
34 34 custom_values.count
35 35 end
36 36
37 37 def in_use?
38 38 objects_count > 0
39 39 end
40 40
41 41 alias :destroy_without_reassign :destroy
42 42 def destroy(reassign_to=nil)
43 43 if reassign_to
44 44 custom_values.update_all(:value => reassign_to.id.to_s)
45 45 end
46 46 destroy_without_reassign
47 47 end
48 48
49 49 def custom_values
50 50 custom_field.custom_values.where(:value => id.to_s)
51 51 end
52 52
53 53 def self.update_each(custom_field, attributes)
54 54 return unless attributes.is_a?(Hash)
55 55 transaction do
56 56 attributes.each do |enumeration_id, enumeration_attributes|
57 57 enumeration = custom_field.enumerations.find_by_id(enumeration_id)
58 58 if enumeration
59 59 enumeration.attributes = enumeration_attributes
60 60 unless enumeration.save
61 61 raise ActiveRecord::Rollback
62 62 end
63 63 end
64 64 end
65 65 end
66 66 end
67 67
68 def self.fields_for_order_statement(table=nil)
69 table ||= table_name
70 columns = ['position']
71 columns.uniq.map {|field| "#{table}.#{field}"}
72 end
73
68 74 private
69 75
70 76 def set_position
71 77 max = self.class.where(:custom_field_id => custom_field_id).maximum(:position) || 0
72 78 self.position = max + 1
73 79 end
74 80 end
@@ -1,4494 +1,4520
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class IssuesControllerTest < ActionController::TestCase
21 21 fixtures :projects,
22 22 :users, :email_addresses,
23 23 :roles,
24 24 :members,
25 25 :member_roles,
26 26 :issues,
27 27 :issue_statuses,
28 28 :issue_relations,
29 29 :versions,
30 30 :trackers,
31 31 :projects_trackers,
32 32 :issue_categories,
33 33 :enabled_modules,
34 34 :enumerations,
35 35 :attachments,
36 36 :workflows,
37 37 :custom_fields,
38 38 :custom_values,
39 39 :custom_fields_projects,
40 40 :custom_fields_trackers,
41 41 :time_entries,
42 42 :journals,
43 43 :journal_details,
44 44 :queries,
45 45 :repositories,
46 46 :changesets
47 47
48 48 include Redmine::I18n
49 49
50 50 def setup
51 51 User.current = nil
52 52 end
53 53
54 54 def test_index
55 55 with_settings :default_language => "en" do
56 56 get :index
57 57 assert_response :success
58 58 assert_template 'index'
59 59 assert_not_nil assigns(:issues)
60 60 assert_nil assigns(:project)
61 61
62 62 # links to visible issues
63 63 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
64 64 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
65 65 # private projects hidden
66 66 assert_select 'a[href="/issues/6"]', 0
67 67 assert_select 'a[href="/issues/4"]', 0
68 68 # project column
69 69 assert_select 'th', :text => /Project/
70 70 end
71 71 end
72 72
73 73 def test_index_should_not_list_issues_when_module_disabled
74 74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
75 75 get :index
76 76 assert_response :success
77 77 assert_template 'index'
78 78 assert_not_nil assigns(:issues)
79 79 assert_nil assigns(:project)
80 80
81 81 assert_select 'a[href="/issues/1"]', 0
82 82 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
83 83 end
84 84
85 85 def test_index_should_list_visible_issues_only
86 86 get :index, :per_page => 100
87 87 assert_response :success
88 88 assert_not_nil assigns(:issues)
89 89 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
90 90 end
91 91
92 92 def test_index_with_project
93 93 Setting.display_subprojects_issues = 0
94 94 get :index, :project_id => 1
95 95 assert_response :success
96 96 assert_template 'index'
97 97 assert_not_nil assigns(:issues)
98 98
99 99 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
100 100 assert_select 'a[href="/issues/5"]', 0
101 101 end
102 102
103 103 def test_index_with_project_and_subprojects
104 104 Setting.display_subprojects_issues = 1
105 105 get :index, :project_id => 1
106 106 assert_response :success
107 107 assert_template 'index'
108 108 assert_not_nil assigns(:issues)
109 109
110 110 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
111 111 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
112 112 assert_select 'a[href="/issues/6"]', 0
113 113 end
114 114
115 115 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
116 116 @request.session[:user_id] = 2
117 117 Setting.display_subprojects_issues = 1
118 118 get :index, :project_id => 1
119 119 assert_response :success
120 120 assert_template 'index'
121 121 assert_not_nil assigns(:issues)
122 122
123 123 assert_select 'a[href="/issues/1"]', :text => /Cannot print recipes/
124 124 assert_select 'a[href="/issues/5"]', :text => /Subproject issue/
125 125 assert_select 'a[href="/issues/6"]', :text => /Issue of a private subproject/
126 126 end
127 127
128 128 def test_index_with_project_and_default_filter
129 129 get :index, :project_id => 1, :set_filter => 1
130 130 assert_response :success
131 131 assert_template 'index'
132 132 assert_not_nil assigns(:issues)
133 133
134 134 query = assigns(:query)
135 135 assert_not_nil query
136 136 # default filter
137 137 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
138 138 end
139 139
140 140 def test_index_with_project_and_filter
141 141 get :index, :project_id => 1, :set_filter => 1,
142 142 :f => ['tracker_id'],
143 143 :op => {'tracker_id' => '='},
144 144 :v => {'tracker_id' => ['1']}
145 145 assert_response :success
146 146 assert_template 'index'
147 147 assert_not_nil assigns(:issues)
148 148
149 149 query = assigns(:query)
150 150 assert_not_nil query
151 151 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
152 152 end
153 153
154 154 def test_index_with_short_filters
155 155 to_test = {
156 156 'status_id' => {
157 157 'o' => { :op => 'o', :values => [''] },
158 158 'c' => { :op => 'c', :values => [''] },
159 159 '7' => { :op => '=', :values => ['7'] },
160 160 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
161 161 '=7' => { :op => '=', :values => ['7'] },
162 162 '!3' => { :op => '!', :values => ['3'] },
163 163 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
164 164 'subject' => {
165 165 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
166 166 'o' => { :op => '=', :values => ['o'] },
167 167 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
168 168 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
169 169 'tracker_id' => {
170 170 '3' => { :op => '=', :values => ['3'] },
171 171 '=3' => { :op => '=', :values => ['3'] }},
172 172 'start_date' => {
173 173 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
174 174 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
175 175 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
176 176 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
177 177 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
178 178 '<t+2' => { :op => '<t+', :values => ['2'] },
179 179 '>t+2' => { :op => '>t+', :values => ['2'] },
180 180 't+2' => { :op => 't+', :values => ['2'] },
181 181 't' => { :op => 't', :values => [''] },
182 182 'w' => { :op => 'w', :values => [''] },
183 183 '>t-2' => { :op => '>t-', :values => ['2'] },
184 184 '<t-2' => { :op => '<t-', :values => ['2'] },
185 185 't-2' => { :op => 't-', :values => ['2'] }},
186 186 'created_on' => {
187 187 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
188 188 '<t-2' => { :op => '<t-', :values => ['2'] },
189 189 '>t-2' => { :op => '>t-', :values => ['2'] },
190 190 't-2' => { :op => 't-', :values => ['2'] }},
191 191 'cf_1' => {
192 192 'c' => { :op => '=', :values => ['c'] },
193 193 '!c' => { :op => '!', :values => ['c'] },
194 194 '!*' => { :op => '!*', :values => [''] },
195 195 '*' => { :op => '*', :values => [''] }},
196 196 'estimated_hours' => {
197 197 '=13.4' => { :op => '=', :values => ['13.4'] },
198 198 '>=45' => { :op => '>=', :values => ['45'] },
199 199 '<=125' => { :op => '<=', :values => ['125'] },
200 200 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
201 201 '!*' => { :op => '!*', :values => [''] },
202 202 '*' => { :op => '*', :values => [''] }}
203 203 }
204 204
205 205 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
206 206
207 207 to_test.each do |field, expression_and_expected|
208 208 expression_and_expected.each do |filter_expression, expected|
209 209
210 210 get :index, :set_filter => 1, field => filter_expression
211 211
212 212 assert_response :success
213 213 assert_template 'index'
214 214 assert_not_nil assigns(:issues)
215 215
216 216 query = assigns(:query)
217 217 assert_not_nil query
218 218 assert query.has_filter?(field)
219 219 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
220 220 end
221 221 end
222 222 end
223 223
224 224 def test_index_with_project_and_empty_filters
225 225 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
226 226 assert_response :success
227 227 assert_template 'index'
228 228 assert_not_nil assigns(:issues)
229 229
230 230 query = assigns(:query)
231 231 assert_not_nil query
232 232 # no filter
233 233 assert_equal({}, query.filters)
234 234 end
235 235
236 236 def test_index_with_project_custom_field_filter
237 237 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
238 238 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
239 239 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
240 240 filter_name = "project.cf_#{field.id}"
241 241 @request.session[:user_id] = 1
242 242
243 243 get :index, :set_filter => 1,
244 244 :f => [filter_name],
245 245 :op => {filter_name => '='},
246 246 :v => {filter_name => ['Foo']}
247 247 assert_response :success
248 248 assert_template 'index'
249 249 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
250 250 end
251 251
252 252 def test_index_with_query
253 253 get :index, :project_id => 1, :query_id => 5
254 254 assert_response :success
255 255 assert_template 'index'
256 256 assert_not_nil assigns(:issues)
257 257 assert_nil assigns(:issue_count_by_group)
258 258 end
259 259
260 260 def test_index_with_query_grouped_by_tracker
261 261 get :index, :project_id => 1, :query_id => 6
262 262 assert_response :success
263 263 assert_template 'index'
264 264 assert_not_nil assigns(:issues)
265 265 assert_not_nil assigns(:issue_count_by_group)
266 266 end
267 267
268 268 def test_index_with_query_grouped_and_sorted_by_category
269 269 get :index, :project_id => 1, :set_filter => 1, :group_by => "category", :sort => "category"
270 270 assert_response :success
271 271 assert_template 'index'
272 272 assert_not_nil assigns(:issues)
273 273 assert_not_nil assigns(:issue_count_by_group)
274 274 end
275 275
276 276 def test_index_with_query_grouped_by_list_custom_field
277 277 get :index, :project_id => 1, :query_id => 9
278 278 assert_response :success
279 279 assert_template 'index'
280 280 assert_not_nil assigns(:issues)
281 281 assert_not_nil assigns(:issue_count_by_group)
282 282 end
283 283
284 def test_index_with_query_grouped_by_key_value_custom_field
285 cf = IssueCustomField.create!(:name => 'Key', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'enumeration')
286 cf.enumerations << valueb = CustomFieldEnumeration.new(:name => 'Value B', :position => 1)
287 cf.enumerations << valuea = CustomFieldEnumeration.new(:name => 'Value A', :position => 2)
288 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => valueb.id)
289 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => valueb.id)
290 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => valuea.id)
291 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
292
293 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
294 assert_response :success
295 assert_template 'index'
296 assert_not_nil assigns(:issues)
297 assert_not_nil assigns(:issue_count_by_group)
298
299 assert_select 'tr.group', 3
300 assert_select 'tr.group' do
301 assert_select 'span.name', :text => 'Value B'
302 assert_select 'span.count', :text => '2'
303 end
304 assert_select 'tr.group' do
305 assert_select 'span.name', :text => 'Value A'
306 assert_select 'span.count', :text => '1'
307 end
308 end
309
284 310 def test_index_with_query_grouped_by_user_custom_field
285 311 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
286 312 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
287 313 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
288 314 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
289 315 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
290 316
291 317 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
292 318 assert_response :success
293 319
294 320 assert_select 'tr.group', 3
295 321 assert_select 'tr.group' do
296 322 assert_select 'a', :text => 'John Smith'
297 323 assert_select 'span.count', :text => '1'
298 324 end
299 325 assert_select 'tr.group' do
300 326 assert_select 'a', :text => 'Dave Lopper'
301 327 assert_select 'span.count', :text => '2'
302 328 end
303 329 end
304 330
305 331 def test_index_grouped_by_boolean_custom_field_should_distinguish_blank_and_false_values
306 332 cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool')
307 333 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '1')
308 334 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
309 335 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '')
310 336
311 337 with_settings :default_language => 'en' do
312 338 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
313 339 assert_response :success
314 340 end
315 341
316 342 assert_select 'tr.group', 3
317 343 assert_select 'tr.group', :text => /Yes/
318 344 assert_select 'tr.group', :text => /No/
319 345 assert_select 'tr.group', :text => /blank/
320 346 end
321 347
322 348 def test_index_grouped_by_boolean_custom_field_with_false_group_in_first_position_should_show_the_group
323 349 cf = IssueCustomField.create!(:name => 'Bool', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'bool', :is_filter => true)
324 350 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '0')
325 351 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '0')
326 352
327 353 with_settings :default_language => 'en' do
328 354 get :index, :project_id => 1, :set_filter => 1, "cf_#{cf.id}" => "*", :group_by => "cf_#{cf.id}"
329 355 assert_response :success
330 356 assert_equal [1, 2], assigns(:issues).map(&:id).sort
331 357 end
332 358
333 359 assert_select 'tr.group', 1
334 360 assert_select 'tr.group', :text => /No/
335 361 end
336 362
337 363 def test_index_with_query_grouped_by_tracker_in_normal_order
338 364 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
339 365
340 366 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
341 367 assert_response :success
342 368
343 369 trackers = assigns(:issues).map(&:tracker).uniq
344 370 assert_equal [1, 2, 3], trackers.map(&:id)
345 371 end
346 372
347 373 def test_index_with_query_grouped_by_tracker_in_reverse_order
348 374 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
349 375
350 376 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
351 377 assert_response :success
352 378
353 379 trackers = assigns(:issues).map(&:tracker).uniq
354 380 assert_equal [3, 2, 1], trackers.map(&:id)
355 381 end
356 382
357 383 def test_index_with_query_id_and_project_id_should_set_session_query
358 384 get :index, :project_id => 1, :query_id => 4
359 385 assert_response :success
360 386 assert_kind_of Hash, session[:query]
361 387 assert_equal 4, session[:query][:id]
362 388 assert_equal 1, session[:query][:project_id]
363 389 end
364 390
365 391 def test_index_with_invalid_query_id_should_respond_404
366 392 get :index, :project_id => 1, :query_id => 999
367 393 assert_response 404
368 394 end
369 395
370 396 def test_index_with_cross_project_query_in_session_should_show_project_issues
371 397 q = IssueQuery.create!(:name => "test", :user_id => 2, :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
372 398 @request.session[:query] = {:id => q.id, :project_id => 1}
373 399
374 400 with_settings :display_subprojects_issues => '0' do
375 401 get :index, :project_id => 1
376 402 end
377 403 assert_response :success
378 404 assert_not_nil assigns(:query)
379 405 assert_equal q.id, assigns(:query).id
380 406 assert_equal 1, assigns(:query).project_id
381 407 assert_equal [1], assigns(:issues).map(&:project_id).uniq
382 408 end
383 409
384 410 def test_private_query_should_not_be_available_to_other_users
385 411 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
386 412 @request.session[:user_id] = 3
387 413
388 414 get :index, :query_id => q.id
389 415 assert_response 403
390 416 end
391 417
392 418 def test_private_query_should_be_available_to_its_user
393 419 q = IssueQuery.create!(:name => "private", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PRIVATE, :project => nil)
394 420 @request.session[:user_id] = 2
395 421
396 422 get :index, :query_id => q.id
397 423 assert_response :success
398 424 end
399 425
400 426 def test_public_query_should_be_available_to_other_users
401 427 q = IssueQuery.create!(:name => "public", :user => User.find(2), :visibility => IssueQuery::VISIBILITY_PUBLIC, :project => nil)
402 428 @request.session[:user_id] = 3
403 429
404 430 get :index, :query_id => q.id
405 431 assert_response :success
406 432 end
407 433
408 434 def test_index_should_omit_page_param_in_export_links
409 435 get :index, :page => 2
410 436 assert_response :success
411 437 assert_select 'a.atom[href="/issues.atom"]'
412 438 assert_select 'a.csv[href="/issues.csv"]'
413 439 assert_select 'a.pdf[href="/issues.pdf"]'
414 440 assert_select 'form#csv-export-form[action="/issues.csv"]'
415 441 end
416 442
417 443 def test_index_should_not_warn_when_not_exceeding_export_limit
418 444 with_settings :issues_export_limit => 200 do
419 445 get :index
420 446 assert_select '#csv-export-options p.icon-warning', 0
421 447 end
422 448 end
423 449
424 450 def test_index_should_warn_when_exceeding_export_limit
425 451 with_settings :issues_export_limit => 2 do
426 452 get :index
427 453 assert_select '#csv-export-options p.icon-warning', :text => %r{limit: 2}
428 454 end
429 455 end
430 456
431 457 def test_index_should_include_query_params_as_hidden_fields_in_csv_export_form
432 458 get :index, :project_id => 1, :set_filter => "1", :tracker_id => "2", :sort => 'status', :c => ["status", "priority"]
433 459
434 460 assert_select '#csv-export-form[action=?]', '/projects/ecookbook/issues.csv'
435 461 assert_select '#csv-export-form[method=?]', 'get'
436 462
437 463 assert_select '#csv-export-form' do
438 464 assert_select 'input[name=?][value=?]', 'set_filter', '1'
439 465
440 466 assert_select 'input[name=?][value=?]', 'f[]', 'tracker_id'
441 467 assert_select 'input[name=?][value=?]', 'op[tracker_id]', '='
442 468 assert_select 'input[name=?][value=?]', 'v[tracker_id][]', '2'
443 469
444 470 assert_select 'input[name=?][value=?]', 'c[]', 'status'
445 471 assert_select 'input[name=?][value=?]', 'c[]', 'priority'
446 472
447 473 assert_select 'input[name=?][value=?]', 'sort', 'status'
448 474 end
449 475 end
450 476
451 477 def test_index_csv
452 478 get :index, :format => 'csv'
453 479 assert_response :success
454 480 assert_not_nil assigns(:issues)
455 481 assert_equal 'text/csv; header=present', @response.content_type
456 482 assert @response.body.starts_with?("#,")
457 483 lines = @response.body.chomp.split("\n")
458 484 assert_equal assigns(:query).columns.size, lines[0].split(',').size
459 485 end
460 486
461 487 def test_index_csv_with_project
462 488 get :index, :project_id => 1, :format => 'csv'
463 489 assert_response :success
464 490 assert_not_nil assigns(:issues)
465 491 assert_equal 'text/csv; header=present', @response.content_type
466 492 end
467 493
468 494 def test_index_csv_with_description
469 495 Issue.generate!(:description => 'test_index_csv_with_description')
470 496
471 497 with_settings :default_language => 'en' do
472 498 get :index, :format => 'csv', :csv => {:description => '1'}
473 499 assert_response :success
474 500 assert_not_nil assigns(:issues)
475 501 end
476 502
477 503 assert_equal 'text/csv; header=present', response.content_type
478 504 headers = response.body.chomp.split("\n").first.split(',')
479 505 assert_include 'Description', headers
480 506 assert_include 'test_index_csv_with_description', response.body
481 507 end
482 508
483 509 def test_index_csv_with_spent_time_column
484 510 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
485 511 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
486 512
487 513 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
488 514 assert_response :success
489 515 assert_equal 'text/csv; header=present', @response.content_type
490 516 lines = @response.body.chomp.split("\n")
491 517 assert_include "#{issue.id},#{issue.subject},7.33", lines
492 518 end
493 519
494 520 def test_index_csv_with_all_columns
495 521 get :index, :format => 'csv', :csv => {:columns => 'all'}
496 522 assert_response :success
497 523 assert_not_nil assigns(:issues)
498 524 assert_equal 'text/csv; header=present', @response.content_type
499 525 assert_match /\A#,/, response.body
500 526 lines = response.body.chomp.split("\n")
501 527 assert_equal assigns(:query).available_inline_columns.size, lines[0].split(',').size
502 528 end
503 529
504 530 def test_index_csv_with_multi_column_field
505 531 CustomField.find(1).update_attribute :multiple, true
506 532 issue = Issue.find(1)
507 533 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
508 534 issue.save!
509 535
510 536 get :index, :format => 'csv', :csv => {:columns => 'all'}
511 537 assert_response :success
512 538 lines = @response.body.chomp.split("\n")
513 539 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
514 540 end
515 541
516 542 def test_index_csv_should_format_float_custom_fields_with_csv_decimal_separator
517 543 field = IssueCustomField.create!(:name => 'Float', :is_for_all => true, :tracker_ids => [1], :field_format => 'float')
518 544 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id => '185.6'})
519 545
520 546 with_settings :default_language => 'fr' do
521 547 get :index, :format => 'csv', :csv => {:columns => 'all'}
522 548 assert_response :success
523 549 issue_line = response.body.chomp.split("\n").map {|line| line.split(';')}.detect {|line| line[0]==issue.id.to_s}
524 550 assert_include '185,60', issue_line
525 551 end
526 552
527 553 with_settings :default_language => 'en' do
528 554 get :index, :format => 'csv', :csv => {:columns => 'all'}
529 555 assert_response :success
530 556 issue_line = response.body.chomp.split("\n").map {|line| line.split(',')}.detect {|line| line[0]==issue.id.to_s}
531 557 assert_include '185.60', issue_line
532 558 end
533 559 end
534 560
535 561 def test_index_csv_should_fill_parent_column_with_parent_id
536 562 Issue.delete_all
537 563 parent = Issue.generate!
538 564 child = Issue.generate!(:parent_issue_id => parent.id)
539 565
540 566 with_settings :default_language => 'en' do
541 567 get :index, :format => 'csv', :c => %w(parent)
542 568 end
543 569 lines = response.body.split("\n")
544 570 assert_include "#{child.id},#{parent.id}", lines
545 571 end
546 572
547 573 def test_index_csv_big_5
548 574 with_settings :default_language => "zh-TW" do
549 575 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88".force_encoding('UTF-8')
550 576 str_big5 = "\xa4@\xa4\xeb".force_encoding('Big5')
551 577 issue = Issue.generate!(:subject => str_utf8)
552 578
553 579 get :index, :project_id => 1,
554 580 :f => ['subject'],
555 581 :op => '=', :values => [str_utf8],
556 582 :format => 'csv'
557 583 assert_equal 'text/csv; header=present', @response.content_type
558 584 lines = @response.body.chomp.split("\n")
559 585 header = lines[0]
560 586 status = "\xaa\xac\xbaA".force_encoding('Big5')
561 587 assert_include status, header
562 588 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
563 589 assert_include str_big5, issue_line
564 590 end
565 591 end
566 592
567 593 def test_index_csv_cannot_convert_should_be_replaced_big_5
568 594 with_settings :default_language => "zh-TW" do
569 595 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85".force_encoding('UTF-8')
570 596 issue = Issue.generate!(:subject => str_utf8)
571 597
572 598 get :index, :project_id => 1,
573 599 :f => ['subject'],
574 600 :op => '=', :values => [str_utf8],
575 601 :c => ['status', 'subject'],
576 602 :format => 'csv',
577 603 :set_filter => 1
578 604 assert_equal 'text/csv; header=present', @response.content_type
579 605 lines = @response.body.chomp.split("\n")
580 606 header = lines[0]
581 607 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
582 608 s1 = "\xaa\xac\xbaA".force_encoding('Big5') # status
583 609 assert header.include?(s1)
584 610 s2 = issue_line.split(",")[2]
585 611 s3 = "\xa5H?".force_encoding('Big5') # subject
586 612 assert_equal s3, s2
587 613 end
588 614 end
589 615
590 616 def test_index_csv_tw
591 617 with_settings :default_language => "zh-TW" do
592 618 str1 = "test_index_csv_tw"
593 619 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
594 620
595 621 get :index, :project_id => 1,
596 622 :f => ['subject'],
597 623 :op => '=', :values => [str1],
598 624 :c => ['estimated_hours', 'subject'],
599 625 :format => 'csv',
600 626 :set_filter => 1
601 627 assert_equal 'text/csv; header=present', @response.content_type
602 628 lines = @response.body.chomp.split("\n")
603 629 assert_include "#{issue.id},1234.50,#{str1}", lines
604 630 end
605 631 end
606 632
607 633 def test_index_csv_fr
608 634 with_settings :default_language => "fr" do
609 635 str1 = "test_index_csv_fr"
610 636 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
611 637
612 638 get :index, :project_id => 1,
613 639 :f => ['subject'],
614 640 :op => '=', :values => [str1],
615 641 :c => ['estimated_hours', 'subject'],
616 642 :format => 'csv',
617 643 :set_filter => 1
618 644 assert_equal 'text/csv; header=present', @response.content_type
619 645 lines = @response.body.chomp.split("\n")
620 646 assert_include "#{issue.id};1234,50;#{str1}", lines
621 647 end
622 648 end
623 649
624 650 def test_index_pdf
625 651 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
626 652 with_settings :default_language => lang do
627 653
628 654 get :index
629 655 assert_response :success
630 656 assert_template 'index'
631 657
632 658 get :index, :format => 'pdf'
633 659 assert_response :success
634 660 assert_not_nil assigns(:issues)
635 661 assert_equal 'application/pdf', @response.content_type
636 662
637 663 get :index, :project_id => 1, :format => 'pdf'
638 664 assert_response :success
639 665 assert_not_nil assigns(:issues)
640 666 assert_equal 'application/pdf', @response.content_type
641 667
642 668 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
643 669 assert_response :success
644 670 assert_not_nil assigns(:issues)
645 671 assert_equal 'application/pdf', @response.content_type
646 672 end
647 673 end
648 674 end
649 675
650 676 def test_index_pdf_with_query_grouped_by_list_custom_field
651 677 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
652 678 assert_response :success
653 679 assert_not_nil assigns(:issues)
654 680 assert_not_nil assigns(:issue_count_by_group)
655 681 assert_equal 'application/pdf', @response.content_type
656 682 end
657 683
658 684 def test_index_atom
659 685 get :index, :project_id => 'ecookbook', :format => 'atom'
660 686 assert_response :success
661 687 assert_template 'common/feed'
662 688 assert_equal 'application/atom+xml', response.content_type
663 689
664 690 assert_select 'feed' do
665 691 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
666 692 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
667 693 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
668 694 end
669 695 end
670 696
671 697 def test_index_sort
672 698 get :index, :sort => 'tracker,id:desc'
673 699 assert_response :success
674 700
675 701 sort_params = @request.session['issues_index_sort']
676 702 assert sort_params.is_a?(String)
677 703 assert_equal 'tracker,id:desc', sort_params
678 704
679 705 issues = assigns(:issues)
680 706 assert_not_nil issues
681 707 assert !issues.empty?
682 708 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
683 709 assert_select 'table.issues.sort-by-tracker.sort-asc'
684 710 end
685 711
686 712 def test_index_sort_by_field_not_included_in_columns
687 713 Setting.issue_list_default_columns = %w(subject author)
688 714 get :index, :sort => 'tracker'
689 715 end
690 716
691 717 def test_index_sort_by_assigned_to
692 718 get :index, :sort => 'assigned_to'
693 719 assert_response :success
694 720 assignees = assigns(:issues).collect(&:assigned_to).compact
695 721 assert_equal assignees.sort, assignees
696 722 assert_select 'table.issues.sort-by-assigned-to.sort-asc'
697 723 end
698 724
699 725 def test_index_sort_by_assigned_to_desc
700 726 get :index, :sort => 'assigned_to:desc'
701 727 assert_response :success
702 728 assignees = assigns(:issues).collect(&:assigned_to).compact
703 729 assert_equal assignees.sort.reverse, assignees
704 730 assert_select 'table.issues.sort-by-assigned-to.sort-desc'
705 731 end
706 732
707 733 def test_index_group_by_assigned_to
708 734 get :index, :group_by => 'assigned_to', :sort => 'priority'
709 735 assert_response :success
710 736 end
711 737
712 738 def test_index_sort_by_author
713 739 get :index, :sort => 'author'
714 740 assert_response :success
715 741 authors = assigns(:issues).collect(&:author)
716 742 assert_equal authors.sort, authors
717 743 end
718 744
719 745 def test_index_sort_by_author_desc
720 746 get :index, :sort => 'author:desc'
721 747 assert_response :success
722 748 authors = assigns(:issues).collect(&:author)
723 749 assert_equal authors.sort.reverse, authors
724 750 end
725 751
726 752 def test_index_group_by_author
727 753 get :index, :group_by => 'author', :sort => 'priority'
728 754 assert_response :success
729 755 end
730 756
731 757 def test_index_sort_by_spent_hours
732 758 get :index, :sort => 'spent_hours:desc'
733 759 assert_response :success
734 760 hours = assigns(:issues).collect(&:spent_hours)
735 761 assert_equal hours.sort.reverse, hours
736 762 end
737 763
738 764 def test_index_sort_by_total_spent_hours
739 765 get :index, :sort => 'total_spent_hours:desc'
740 766 assert_response :success
741 767 hours = assigns(:issues).collect(&:total_spent_hours)
742 768 assert_equal hours.sort.reverse, hours
743 769 end
744 770
745 771 def test_index_sort_by_total_estimated_hours
746 772 get :index, :sort => 'total_estimated_hours:desc'
747 773 assert_response :success
748 774 hours = assigns(:issues).collect(&:total_estimated_hours)
749 775 assert_equal hours.sort.reverse, hours
750 776 end
751 777
752 778 def test_index_sort_by_user_custom_field
753 779 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
754 780 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
755 781 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
756 782 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
757 783 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
758 784
759 785 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
760 786 assert_response :success
761 787
762 788 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
763 789 end
764 790
765 791 def test_index_with_columns
766 792 columns = ['tracker', 'subject', 'assigned_to']
767 793 get :index, :set_filter => 1, :c => columns
768 794 assert_response :success
769 795
770 796 # query should use specified columns
771 797 query = assigns(:query)
772 798 assert_kind_of IssueQuery, query
773 799 assert_equal columns, query.column_names.map(&:to_s)
774 800
775 801 # columns should be stored in session
776 802 assert_kind_of Hash, session[:query]
777 803 assert_kind_of Array, session[:query][:column_names]
778 804 assert_equal columns, session[:query][:column_names].map(&:to_s)
779 805
780 806 # ensure only these columns are kept in the selected columns list
781 807 assert_select 'select#selected_columns option' do
782 808 assert_select 'option', 3
783 809 assert_select 'option[value=tracker]'
784 810 assert_select 'option[value=project]', 0
785 811 end
786 812 end
787 813
788 814 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
789 815 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
790 816 get :index, :set_filter => 1
791 817
792 818 # query should use specified columns
793 819 query = assigns(:query)
794 820 assert_kind_of IssueQuery, query
795 821 assert_equal [:id, :project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
796 822 end
797 823
798 824 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
799 825 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
800 826 columns = ['id', 'tracker', 'subject', 'assigned_to']
801 827 get :index, :set_filter => 1, :c => columns
802 828
803 829 # query should use specified columns
804 830 query = assigns(:query)
805 831 assert_kind_of IssueQuery, query
806 832 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
807 833 end
808 834
809 835 def test_index_with_default_columns_should_respect_default_columns_order
810 836 columns = ['assigned_to', 'subject', 'status', 'tracker']
811 837 with_settings :issue_list_default_columns => columns do
812 838 get :index, :project_id => 1, :set_filter => 1
813 839
814 840 query = assigns(:query)
815 841 assert_equal (['id'] + columns).map(&:to_sym), query.columns.map(&:name)
816 842 end
817 843 end
818 844
819 845 def test_index_with_custom_field_column
820 846 columns = %w(tracker subject cf_2)
821 847 get :index, :set_filter => 1, :c => columns
822 848 assert_response :success
823 849
824 850 # query should use specified columns
825 851 query = assigns(:query)
826 852 assert_kind_of IssueQuery, query
827 853 assert_equal columns, query.column_names.map(&:to_s)
828 854
829 855 assert_select 'table.issues td.cf_2.string'
830 856 end
831 857
832 858 def test_index_with_multi_custom_field_column
833 859 field = CustomField.find(1)
834 860 field.update_attribute :multiple, true
835 861 issue = Issue.find(1)
836 862 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
837 863 issue.save!
838 864
839 865 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
840 866 assert_response :success
841 867
842 868 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
843 869 end
844 870
845 871 def test_index_with_multi_user_custom_field_column
846 872 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
847 873 :tracker_ids => [1], :is_for_all => true)
848 874 issue = Issue.find(1)
849 875 issue.custom_field_values = {field.id => ['2', '3']}
850 876 issue.save!
851 877
852 878 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
853 879 assert_response :success
854 880
855 881 assert_select "table.issues td.cf_#{field.id}" do
856 882 assert_select 'a', 2
857 883 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
858 884 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
859 885 end
860 886 end
861 887
862 888 def test_index_with_date_column
863 889 with_settings :date_format => '%d/%m/%Y' do
864 890 Issue.find(1).update_attribute :start_date, '1987-08-24'
865 891 get :index, :set_filter => 1, :c => %w(start_date)
866 892 assert_select "table.issues td.start_date", :text => '24/08/1987'
867 893 end
868 894 end
869 895
870 896 def test_index_with_done_ratio_column
871 897 Issue.find(1).update_attribute :done_ratio, 40
872 898 get :index, :set_filter => 1, :c => %w(done_ratio)
873 899 assert_select 'table.issues td.done_ratio' do
874 900 assert_select 'table.progress' do
875 901 assert_select 'td.closed[style=?]', 'width: 40%;'
876 902 end
877 903 end
878 904 end
879 905
880 906 def test_index_with_spent_hours_column
881 907 Issue.expects(:load_visible_spent_hours).once
882 908 get :index, :set_filter => 1, :c => %w(subject spent_hours)
883 909 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
884 910 end
885 911
886 912 def test_index_with_total_spent_hours_column
887 913 Issue.expects(:load_visible_total_spent_hours).once
888 914 get :index, :set_filter => 1, :c => %w(subject total_spent_hours)
889 915 assert_select 'table.issues tr#issue-3 td.total_spent_hours', :text => '1.00'
890 916 end
891 917
892 918 def test_index_with_total_estimated_hours_column
893 919 get :index, :set_filter => 1, :c => %w(subject total_estimated_hours)
894 920 assert_select 'table.issues td.total_estimated_hours'
895 921 end
896 922
897 923 def test_index_should_not_show_spent_hours_column_without_permission
898 924 Role.anonymous.remove_permission! :view_time_entries
899 925 get :index, :set_filter => 1, :c => %w(subject spent_hours)
900 926 assert_select 'td.spent_hours', 0
901 927 end
902 928
903 929 def test_index_with_fixed_version_column
904 930 get :index, :set_filter => 1, :c => %w(fixed_version)
905 931 assert_select 'table.issues td.fixed_version' do
906 932 assert_select 'a[href=?]', '/versions/2', :text => 'eCookbook - 1.0'
907 933 end
908 934 end
909 935
910 936 def test_index_with_relations_column
911 937 IssueRelation.delete_all
912 938 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
913 939 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
914 940 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
915 941 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
916 942
917 943 get :index, :set_filter => 1, :c => %w(subject relations)
918 944 assert_response :success
919 945 assert_select "tr#issue-1 td.relations" do
920 946 assert_select "span", 3
921 947 assert_select "span", :text => "Related to #7"
922 948 assert_select "span", :text => "Related to #8"
923 949 assert_select "span", :text => "Blocks #11"
924 950 end
925 951 assert_select "tr#issue-2 td.relations" do
926 952 assert_select "span", 1
927 953 assert_select "span", :text => "Blocked by #12"
928 954 end
929 955 assert_select "tr#issue-3 td.relations" do
930 956 assert_select "span", 0
931 957 end
932 958
933 959 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
934 960 assert_response :success
935 961 assert_equal 'text/csv; header=present', response.content_type
936 962 lines = response.body.chomp.split("\n")
937 963 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
938 964 assert_include '2,Blocked by #12', lines
939 965 assert_include '3,""', lines
940 966
941 967 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
942 968 assert_response :success
943 969 assert_equal 'application/pdf', response.content_type
944 970 end
945 971
946 972 def test_index_with_description_column
947 973 get :index, :set_filter => 1, :c => %w(subject description)
948 974
949 975 assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
950 976 assert_select 'td.description[colspan="3"]', :text => 'Unable to print recipes'
951 977
952 978 get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
953 979 assert_response :success
954 980 assert_equal 'application/pdf', response.content_type
955 981 end
956 982
957 983 def test_index_with_parent_column
958 984 Issue.delete_all
959 985 parent = Issue.generate!
960 986 child = Issue.generate!(:parent_issue_id => parent.id)
961 987
962 988 get :index, :c => %w(parent)
963 989
964 990 assert_select 'td.parent', :text => "#{parent.tracker} ##{parent.id}"
965 991 assert_select 'td.parent a[title=?]', parent.subject
966 992 end
967 993
968 994 def test_index_with_estimated_hours_total
969 995 Issue.delete_all
970 996 Issue.generate!(:estimated_hours => 5.5)
971 997 Issue.generate!(:estimated_hours => 1.1)
972 998
973 999 get :index, :t => %w(estimated_hours)
974 1000 assert_response :success
975 1001 assert_select '.query-totals'
976 1002 assert_select '.total-for-estimated-hours span.value', :text => '6.60'
977 1003 assert_select 'input[type=checkbox][name=?][value=estimated_hours][checked=checked]', 't[]'
978 1004 end
979 1005
980 1006 def test_index_with_grouped_query_and_estimated_hours_total
981 1007 Issue.delete_all
982 1008 Issue.generate!(:estimated_hours => 5.5, :category_id => 1)
983 1009 Issue.generate!(:estimated_hours => 2.3, :category_id => 1)
984 1010 Issue.generate!(:estimated_hours => 1.1, :category_id => 2)
985 1011 Issue.generate!(:estimated_hours => 4.6)
986 1012
987 1013 get :index, :t => %w(estimated_hours), :group_by => 'category'
988 1014 assert_response :success
989 1015 assert_select '.query-totals'
990 1016 assert_select '.query-totals .total-for-estimated-hours span.value', :text => '13.50'
991 1017 assert_select 'tr.group', :text => /Printing/ do
992 1018 assert_select '.total-for-estimated-hours span.value', :text => '7.80'
993 1019 end
994 1020 assert_select 'tr.group', :text => /Recipes/ do
995 1021 assert_select '.total-for-estimated-hours span.value', :text => '1.10'
996 1022 end
997 1023 assert_select 'tr.group', :text => /blank/ do
998 1024 assert_select '.total-for-estimated-hours span.value', :text => '4.60'
999 1025 end
1000 1026 end
1001 1027
1002 1028 def test_index_with_int_custom_field_total
1003 1029 field = IssueCustomField.generate!(:field_format => 'int', :is_for_all => true)
1004 1030 CustomValue.create!(:customized => Issue.find(1), :custom_field => field, :value => '2')
1005 1031 CustomValue.create!(:customized => Issue.find(2), :custom_field => field, :value => '7')
1006 1032
1007 1033 get :index, :t => ["cf_#{field.id}"]
1008 1034 assert_response :success
1009 1035 assert_select '.query-totals'
1010 1036 assert_select ".total-for-cf-#{field.id} span.value", :text => '9'
1011 1037 end
1012 1038
1013 1039 def test_index_totals_should_default_to_settings
1014 1040 with_settings :issue_list_default_totals => ['estimated_hours'] do
1015 1041 get :index
1016 1042 assert_response :success
1017 1043 assert_select '.total-for-estimated-hours span.value'
1018 1044 assert_select '.query-totals>span', 1
1019 1045 end
1020 1046 end
1021 1047
1022 1048 def test_index_send_html_if_query_is_invalid
1023 1049 get :index, :f => ['start_date'], :op => {:start_date => '='}
1024 1050 assert_equal 'text/html', @response.content_type
1025 1051 assert_template 'index'
1026 1052 end
1027 1053
1028 1054 def test_index_send_nothing_if_query_is_invalid
1029 1055 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
1030 1056 assert_equal 'text/csv', @response.content_type
1031 1057 assert @response.body.blank?
1032 1058 end
1033 1059
1034 1060 def test_show_by_anonymous
1035 1061 get :show, :id => 1
1036 1062 assert_response :success
1037 1063 assert_template 'show'
1038 1064 assert_equal Issue.find(1), assigns(:issue)
1039 1065 assert_select 'div.issue div.description', :text => /Unable to print recipes/
1040 1066 # anonymous role is allowed to add a note
1041 1067 assert_select 'form#issue-form' do
1042 1068 assert_select 'fieldset' do
1043 1069 assert_select 'legend', :text => 'Notes'
1044 1070 assert_select 'textarea[name=?]', 'issue[notes]'
1045 1071 end
1046 1072 end
1047 1073 assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
1048 1074 end
1049 1075
1050 1076 def test_show_by_manager
1051 1077 @request.session[:user_id] = 2
1052 1078 get :show, :id => 1
1053 1079 assert_response :success
1054 1080 assert_select 'a', :text => /Quote/
1055 1081 assert_select 'form#issue-form' do
1056 1082 assert_select 'fieldset' do
1057 1083 assert_select 'legend', :text => 'Change properties'
1058 1084 assert_select 'input[name=?]', 'issue[subject]'
1059 1085 end
1060 1086 assert_select 'fieldset' do
1061 1087 assert_select 'legend', :text => 'Log time'
1062 1088 assert_select 'input[name=?]', 'time_entry[hours]'
1063 1089 end
1064 1090 assert_select 'fieldset' do
1065 1091 assert_select 'legend', :text => 'Notes'
1066 1092 assert_select 'textarea[name=?]', 'issue[notes]'
1067 1093 end
1068 1094 end
1069 1095 end
1070 1096
1071 1097 def test_show_should_display_update_form
1072 1098 @request.session[:user_id] = 2
1073 1099 get :show, :id => 1
1074 1100 assert_response :success
1075 1101
1076 1102 assert_select 'form#issue-form' do
1077 1103 assert_select 'input[name=?]', 'issue[is_private]'
1078 1104 assert_select 'select[name=?]', 'issue[project_id]'
1079 1105 assert_select 'select[name=?]', 'issue[tracker_id]'
1080 1106 assert_select 'input[name=?]', 'issue[subject]'
1081 1107 assert_select 'textarea[name=?]', 'issue[description]'
1082 1108 assert_select 'select[name=?]', 'issue[status_id]'
1083 1109 assert_select 'select[name=?]', 'issue[priority_id]'
1084 1110 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1085 1111 assert_select 'select[name=?]', 'issue[category_id]'
1086 1112 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1087 1113 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1088 1114 assert_select 'input[name=?]', 'issue[start_date]'
1089 1115 assert_select 'input[name=?]', 'issue[due_date]'
1090 1116 assert_select 'select[name=?]', 'issue[done_ratio]'
1091 1117 assert_select 'input[name=?]', 'issue[custom_field_values][2]'
1092 1118 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1093 1119 assert_select 'textarea[name=?]', 'issue[notes]'
1094 1120 end
1095 1121 end
1096 1122
1097 1123 def test_show_should_display_update_form_with_minimal_permissions
1098 1124 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
1099 1125 WorkflowTransition.delete_all :role_id => 1
1100 1126
1101 1127 @request.session[:user_id] = 2
1102 1128 get :show, :id => 1
1103 1129 assert_response :success
1104 1130
1105 1131 assert_select 'form#issue-form' do
1106 1132 assert_select 'input[name=?]', 'issue[is_private]', 0
1107 1133 assert_select 'select[name=?]', 'issue[project_id]', 0
1108 1134 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1109 1135 assert_select 'input[name=?]', 'issue[subject]', 0
1110 1136 assert_select 'textarea[name=?]', 'issue[description]', 0
1111 1137 assert_select 'select[name=?]', 'issue[status_id]', 0
1112 1138 assert_select 'select[name=?]', 'issue[priority_id]', 0
1113 1139 assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
1114 1140 assert_select 'select[name=?]', 'issue[category_id]', 0
1115 1141 assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
1116 1142 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1117 1143 assert_select 'input[name=?]', 'issue[start_date]', 0
1118 1144 assert_select 'input[name=?]', 'issue[due_date]', 0
1119 1145 assert_select 'select[name=?]', 'issue[done_ratio]', 0
1120 1146 assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
1121 1147 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1122 1148 assert_select 'textarea[name=?]', 'issue[notes]'
1123 1149 end
1124 1150 end
1125 1151
1126 1152 def test_show_should_not_display_update_form_without_permissions
1127 1153 Role.find(1).update_attribute :permissions, [:view_issues]
1128 1154
1129 1155 @request.session[:user_id] = 2
1130 1156 get :show, :id => 1
1131 1157 assert_response :success
1132 1158
1133 1159 assert_select 'form#issue-form', 0
1134 1160 end
1135 1161
1136 1162 def test_update_form_should_not_display_inactive_enumerations
1137 1163 assert !IssuePriority.find(15).active?
1138 1164
1139 1165 @request.session[:user_id] = 2
1140 1166 get :show, :id => 1
1141 1167 assert_response :success
1142 1168
1143 1169 assert_select 'form#issue-form' do
1144 1170 assert_select 'select[name=?]', 'issue[priority_id]' do
1145 1171 assert_select 'option[value="4"]'
1146 1172 assert_select 'option[value="15"]', 0
1147 1173 end
1148 1174 end
1149 1175 end
1150 1176
1151 1177 def test_update_form_should_allow_attachment_upload
1152 1178 @request.session[:user_id] = 2
1153 1179 get :show, :id => 1
1154 1180
1155 1181 assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
1156 1182 assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
1157 1183 end
1158 1184 end
1159 1185
1160 1186 def test_show_should_deny_anonymous_access_without_permission
1161 1187 Role.anonymous.remove_permission!(:view_issues)
1162 1188 get :show, :id => 1
1163 1189 assert_response :redirect
1164 1190 end
1165 1191
1166 1192 def test_show_should_deny_anonymous_access_to_private_issue
1167 1193 Issue.where(:id => 1).update_all(["is_private = ?", true])
1168 1194 get :show, :id => 1
1169 1195 assert_response :redirect
1170 1196 end
1171 1197
1172 1198 def test_show_should_deny_non_member_access_without_permission
1173 1199 Role.non_member.remove_permission!(:view_issues)
1174 1200 @request.session[:user_id] = 9
1175 1201 get :show, :id => 1
1176 1202 assert_response 403
1177 1203 end
1178 1204
1179 1205 def test_show_should_deny_non_member_access_to_private_issue
1180 1206 Issue.where(:id => 1).update_all(["is_private = ?", true])
1181 1207 @request.session[:user_id] = 9
1182 1208 get :show, :id => 1
1183 1209 assert_response 403
1184 1210 end
1185 1211
1186 1212 def test_show_should_deny_member_access_without_permission
1187 1213 Role.find(1).remove_permission!(:view_issues)
1188 1214 @request.session[:user_id] = 2
1189 1215 get :show, :id => 1
1190 1216 assert_response 403
1191 1217 end
1192 1218
1193 1219 def test_show_should_deny_member_access_to_private_issue_without_permission
1194 1220 Issue.where(:id => 1).update_all(["is_private = ?", true])
1195 1221 @request.session[:user_id] = 3
1196 1222 get :show, :id => 1
1197 1223 assert_response 403
1198 1224 end
1199 1225
1200 1226 def test_show_should_allow_author_access_to_private_issue
1201 1227 Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
1202 1228 @request.session[:user_id] = 3
1203 1229 get :show, :id => 1
1204 1230 assert_response :success
1205 1231 end
1206 1232
1207 1233 def test_show_should_allow_assignee_access_to_private_issue
1208 1234 Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
1209 1235 @request.session[:user_id] = 3
1210 1236 get :show, :id => 1
1211 1237 assert_response :success
1212 1238 end
1213 1239
1214 1240 def test_show_should_allow_member_access_to_private_issue_with_permission
1215 1241 Issue.where(:id => 1).update_all(["is_private = ?", true])
1216 1242 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1217 1243 @request.session[:user_id] = 3
1218 1244 get :show, :id => 1
1219 1245 assert_response :success
1220 1246 end
1221 1247
1222 1248 def test_show_should_not_disclose_relations_to_invisible_issues
1223 1249 Setting.cross_project_issue_relations = '1'
1224 1250 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1225 1251 # Relation to a private project issue
1226 1252 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1227 1253
1228 1254 get :show, :id => 1
1229 1255 assert_response :success
1230 1256
1231 1257 assert_select 'div#relations' do
1232 1258 assert_select 'a', :text => /#2$/
1233 1259 assert_select 'a', :text => /#4$/, :count => 0
1234 1260 end
1235 1261 end
1236 1262
1237 1263 def test_show_should_list_subtasks
1238 1264 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1239 1265
1240 1266 get :show, :id => 1
1241 1267 assert_response :success
1242 1268
1243 1269 assert_select 'div#issue_tree' do
1244 1270 assert_select 'td.subject', :text => /Child Issue/
1245 1271 end
1246 1272 end
1247 1273
1248 1274 def test_show_should_list_parents
1249 1275 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1250 1276
1251 1277 get :show, :id => issue.id
1252 1278 assert_response :success
1253 1279
1254 1280 assert_select 'div.subject' do
1255 1281 assert_select 'h3', 'Child Issue'
1256 1282 assert_select 'a[href="/issues/1"]'
1257 1283 end
1258 1284 end
1259 1285
1260 1286 def test_show_should_not_display_prev_next_links_without_query_in_session
1261 1287 get :show, :id => 1
1262 1288 assert_response :success
1263 1289 assert_nil assigns(:prev_issue_id)
1264 1290 assert_nil assigns(:next_issue_id)
1265 1291
1266 1292 assert_select 'div.next-prev-links', 0
1267 1293 end
1268 1294
1269 1295 def test_show_should_display_prev_next_links_with_query_in_session
1270 1296 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1271 1297 @request.session['issues_index_sort'] = 'id'
1272 1298
1273 1299 with_settings :display_subprojects_issues => '0' do
1274 1300 get :show, :id => 3
1275 1301 end
1276 1302
1277 1303 assert_response :success
1278 1304 # Previous and next issues for all projects
1279 1305 assert_equal 2, assigns(:prev_issue_id)
1280 1306 assert_equal 5, assigns(:next_issue_id)
1281 1307
1282 1308 count = Issue.open.visible.count
1283 1309
1284 1310 assert_select 'div.next-prev-links' do
1285 1311 assert_select 'a[href="/issues/2"]', :text => /Previous/
1286 1312 assert_select 'a[href="/issues/5"]', :text => /Next/
1287 1313 assert_select 'span.position', :text => "3 of #{count}"
1288 1314 end
1289 1315 end
1290 1316
1291 1317 def test_show_should_display_prev_next_links_with_saved_query_in_session
1292 1318 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
1293 1319 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1294 1320 :sort_criteria => [['id', 'asc']])
1295 1321 @request.session[:query] = {:id => query.id, :project_id => nil}
1296 1322
1297 1323 get :show, :id => 11
1298 1324
1299 1325 assert_response :success
1300 1326 assert_equal query, assigns(:query)
1301 1327 # Previous and next issues for all projects
1302 1328 assert_equal 8, assigns(:prev_issue_id)
1303 1329 assert_equal 12, assigns(:next_issue_id)
1304 1330
1305 1331 assert_select 'div.next-prev-links' do
1306 1332 assert_select 'a[href="/issues/8"]', :text => /Previous/
1307 1333 assert_select 'a[href="/issues/12"]', :text => /Next/
1308 1334 end
1309 1335 end
1310 1336
1311 1337 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1312 1338 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1313 1339
1314 1340 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1315 1341 @request.session['issues_index_sort'] = assoc_sort
1316 1342
1317 1343 get :show, :id => 3
1318 1344 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1319 1345
1320 1346 assert_select 'div.next-prev-links' do
1321 1347 assert_select 'a', :text => /(Previous|Next)/
1322 1348 end
1323 1349 end
1324 1350 end
1325 1351
1326 1352 def test_show_should_display_prev_next_links_with_project_query_in_session
1327 1353 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1328 1354 @request.session['issues_index_sort'] = 'id'
1329 1355
1330 1356 with_settings :display_subprojects_issues => '0' do
1331 1357 get :show, :id => 3
1332 1358 end
1333 1359
1334 1360 assert_response :success
1335 1361 # Previous and next issues inside project
1336 1362 assert_equal 2, assigns(:prev_issue_id)
1337 1363 assert_equal 7, assigns(:next_issue_id)
1338 1364
1339 1365 assert_select 'div.next-prev-links' do
1340 1366 assert_select 'a[href="/issues/2"]', :text => /Previous/
1341 1367 assert_select 'a[href="/issues/7"]', :text => /Next/
1342 1368 end
1343 1369 end
1344 1370
1345 1371 def test_show_should_not_display_prev_link_for_first_issue
1346 1372 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1347 1373 @request.session['issues_index_sort'] = 'id'
1348 1374
1349 1375 with_settings :display_subprojects_issues => '0' do
1350 1376 get :show, :id => 1
1351 1377 end
1352 1378
1353 1379 assert_response :success
1354 1380 assert_nil assigns(:prev_issue_id)
1355 1381 assert_equal 2, assigns(:next_issue_id)
1356 1382
1357 1383 assert_select 'div.next-prev-links' do
1358 1384 assert_select 'a', :text => /Previous/, :count => 0
1359 1385 assert_select 'a[href="/issues/2"]', :text => /Next/
1360 1386 end
1361 1387 end
1362 1388
1363 1389 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1364 1390 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1365 1391 @request.session['issues_index_sort'] = 'id'
1366 1392
1367 1393 get :show, :id => 1
1368 1394
1369 1395 assert_response :success
1370 1396 assert_nil assigns(:prev_issue_id)
1371 1397 assert_nil assigns(:next_issue_id)
1372 1398
1373 1399 assert_select 'a', :text => /Previous/, :count => 0
1374 1400 assert_select 'a', :text => /Next/, :count => 0
1375 1401 end
1376 1402
1377 1403 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1378 1404 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1379 1405 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1380 1406 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1381 1407 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1382 1408 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1383 1409
1384 1410 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
1385 1411 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1386 1412 @request.session[:query] = {:id => query.id, :project_id => nil}
1387 1413
1388 1414 get :show, :id => 3
1389 1415 assert_response :success
1390 1416
1391 1417 assert_equal 2, assigns(:prev_issue_id)
1392 1418 assert_equal 1, assigns(:next_issue_id)
1393 1419
1394 1420 assert_select 'div.next-prev-links' do
1395 1421 assert_select 'a[href="/issues/2"]', :text => /Previous/
1396 1422 assert_select 'a[href="/issues/1"]', :text => /Next/
1397 1423 end
1398 1424 end
1399 1425
1400 1426 def test_show_should_display_category_field_if_categories_are_defined
1401 1427 Issue.update_all :category_id => nil
1402 1428
1403 1429 get :show, :id => 1
1404 1430 assert_response :success
1405 1431 assert_select '.attributes .category'
1406 1432 end
1407 1433
1408 1434 def test_show_should_not_display_category_field_if_no_categories_are_defined
1409 1435 Project.find(1).issue_categories.delete_all
1410 1436
1411 1437 get :show, :id => 1
1412 1438 assert_response :success
1413 1439 assert_select 'table.attributes .category', 0
1414 1440 end
1415 1441
1416 1442 def test_show_should_display_link_to_the_assignee
1417 1443 get :show, :id => 2
1418 1444 assert_response :success
1419 1445 assert_select '.assigned-to' do
1420 1446 assert_select 'a[href="/users/3"]'
1421 1447 end
1422 1448 end
1423 1449
1424 1450 def test_show_should_display_visible_changesets_from_other_projects
1425 1451 project = Project.find(2)
1426 1452 issue = project.issues.first
1427 1453 issue.changeset_ids = [102]
1428 1454 issue.save!
1429 1455 # changesets from other projects should be displayed even if repository
1430 1456 # is disabled on issue's project
1431 1457 project.disable_module! :repository
1432 1458
1433 1459 @request.session[:user_id] = 2
1434 1460 get :show, :id => issue.id
1435 1461
1436 1462 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1437 1463 end
1438 1464
1439 1465 def test_show_should_display_watchers
1440 1466 @request.session[:user_id] = 2
1441 1467 Issue.find(1).add_watcher User.find(2)
1442 1468
1443 1469 get :show, :id => 1
1444 1470 assert_select 'div#watchers ul' do
1445 1471 assert_select 'li' do
1446 1472 assert_select 'a[href="/users/2"]'
1447 1473 assert_select 'a[class*=delete]'
1448 1474 end
1449 1475 end
1450 1476 end
1451 1477
1452 1478 def test_show_should_display_watchers_with_gravatars
1453 1479 @request.session[:user_id] = 2
1454 1480 Issue.find(1).add_watcher User.find(2)
1455 1481
1456 1482 with_settings :gravatar_enabled => '1' do
1457 1483 get :show, :id => 1
1458 1484 end
1459 1485
1460 1486 assert_select 'div#watchers ul' do
1461 1487 assert_select 'li' do
1462 1488 assert_select 'img.gravatar'
1463 1489 assert_select 'a[href="/users/2"]'
1464 1490 assert_select 'a[class*=delete]'
1465 1491 end
1466 1492 end
1467 1493 end
1468 1494
1469 1495 def test_show_with_thumbnails_enabled_should_display_thumbnails
1470 1496 @request.session[:user_id] = 2
1471 1497
1472 1498 with_settings :thumbnails_enabled => '1' do
1473 1499 get :show, :id => 14
1474 1500 assert_response :success
1475 1501 end
1476 1502
1477 1503 assert_select 'div.thumbnails' do
1478 1504 assert_select 'a[href="/attachments/16/testfile.png"]' do
1479 1505 assert_select 'img[src="/attachments/thumbnail/16"]'
1480 1506 end
1481 1507 end
1482 1508 end
1483 1509
1484 1510 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1485 1511 @request.session[:user_id] = 2
1486 1512
1487 1513 with_settings :thumbnails_enabled => '0' do
1488 1514 get :show, :id => 14
1489 1515 assert_response :success
1490 1516 end
1491 1517
1492 1518 assert_select 'div.thumbnails', 0
1493 1519 end
1494 1520
1495 1521 def test_show_with_multi_custom_field
1496 1522 field = CustomField.find(1)
1497 1523 field.update_attribute :multiple, true
1498 1524 issue = Issue.find(1)
1499 1525 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1500 1526 issue.save!
1501 1527
1502 1528 get :show, :id => 1
1503 1529 assert_response :success
1504 1530
1505 1531 assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
1506 1532 end
1507 1533
1508 1534 def test_show_with_multi_user_custom_field
1509 1535 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1510 1536 :tracker_ids => [1], :is_for_all => true)
1511 1537 issue = Issue.find(1)
1512 1538 issue.custom_field_values = {field.id => ['2', '3']}
1513 1539 issue.save!
1514 1540
1515 1541 get :show, :id => 1
1516 1542 assert_response :success
1517 1543
1518 1544 assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
1519 1545 assert_select 'a', :text => 'Dave Lopper'
1520 1546 assert_select 'a', :text => 'John Smith'
1521 1547 end
1522 1548 end
1523 1549
1524 1550 def test_show_should_display_private_notes_with_permission_only
1525 1551 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1526 1552 @request.session[:user_id] = 2
1527 1553
1528 1554 get :show, :id => 2
1529 1555 assert_response :success
1530 1556 assert_include journal, assigns(:journals)
1531 1557
1532 1558 Role.find(1).remove_permission! :view_private_notes
1533 1559 get :show, :id => 2
1534 1560 assert_response :success
1535 1561 assert_not_include journal, assigns(:journals)
1536 1562 end
1537 1563
1538 1564 def test_show_atom
1539 1565 get :show, :id => 2, :format => 'atom'
1540 1566 assert_response :success
1541 1567 assert_template 'journals/index'
1542 1568 # Inline image
1543 1569 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1544 1570 end
1545 1571
1546 1572 def test_show_export_to_pdf
1547 1573 issue = Issue.find(3)
1548 1574 assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
1549 1575 get :show, :id => 3, :format => 'pdf'
1550 1576 assert_response :success
1551 1577 assert_equal 'application/pdf', @response.content_type
1552 1578 assert @response.body.starts_with?('%PDF')
1553 1579 assert_not_nil assigns(:issue)
1554 1580 end
1555 1581
1556 1582 def test_export_to_pdf_with_utf8_u_fffd
1557 1583 # U+FFFD
1558 1584 s = "\xef\xbf\xbd"
1559 1585 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
1560 1586 issue = Issue.generate!(:subject => s)
1561 1587 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
1562 1588 with_settings :default_language => lang do
1563 1589 get :show, :id => issue.id, :format => 'pdf'
1564 1590 assert_response :success
1565 1591 assert_equal 'application/pdf', @response.content_type
1566 1592 assert @response.body.starts_with?('%PDF')
1567 1593 assert_not_nil assigns(:issue)
1568 1594 end
1569 1595 end
1570 1596 end
1571 1597
1572 1598 def test_show_export_to_pdf_with_ancestors
1573 1599 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1574 1600
1575 1601 get :show, :id => issue.id, :format => 'pdf'
1576 1602 assert_response :success
1577 1603 assert_equal 'application/pdf', @response.content_type
1578 1604 assert @response.body.starts_with?('%PDF')
1579 1605 end
1580 1606
1581 1607 def test_show_export_to_pdf_with_descendants
1582 1608 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1583 1609 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1584 1610 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1585 1611
1586 1612 get :show, :id => 1, :format => 'pdf'
1587 1613 assert_response :success
1588 1614 assert_equal 'application/pdf', @response.content_type
1589 1615 assert @response.body.starts_with?('%PDF')
1590 1616 end
1591 1617
1592 1618 def test_show_export_to_pdf_with_journals
1593 1619 get :show, :id => 1, :format => 'pdf'
1594 1620 assert_response :success
1595 1621 assert_equal 'application/pdf', @response.content_type
1596 1622 assert @response.body.starts_with?('%PDF')
1597 1623 end
1598 1624
1599 1625 def test_show_export_to_pdf_with_changesets
1600 1626 [[100], [100, 101], [100, 101, 102]].each do |cs|
1601 1627 issue1 = Issue.find(3)
1602 1628 issue1.changesets = Changeset.find(cs)
1603 1629 issue1.save!
1604 1630 issue = Issue.find(3)
1605 1631 assert_equal issue.changesets.count, cs.size
1606 1632 get :show, :id => 3, :format => 'pdf'
1607 1633 assert_response :success
1608 1634 assert_equal 'application/pdf', @response.content_type
1609 1635 assert @response.body.starts_with?('%PDF')
1610 1636 end
1611 1637 end
1612 1638
1613 1639 def test_show_invalid_should_respond_with_404
1614 1640 get :show, :id => 999
1615 1641 assert_response 404
1616 1642 end
1617 1643
1618 1644 def test_get_new
1619 1645 @request.session[:user_id] = 2
1620 1646 get :new, :project_id => 1, :tracker_id => 1
1621 1647 assert_response :success
1622 1648 assert_template 'new'
1623 1649
1624 1650 assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
1625 1651 assert_select 'form#issue-form' do
1626 1652 assert_select 'input[name=?]', 'issue[is_private]'
1627 1653 assert_select 'select[name=?]', 'issue[project_id]', 0
1628 1654 assert_select 'select[name=?]', 'issue[tracker_id]'
1629 1655 assert_select 'input[name=?]', 'issue[subject]'
1630 1656 assert_select 'textarea[name=?]', 'issue[description]'
1631 1657 assert_select 'select[name=?]', 'issue[status_id]'
1632 1658 assert_select 'select[name=?]', 'issue[priority_id]'
1633 1659 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1634 1660 assert_select 'select[name=?]', 'issue[category_id]'
1635 1661 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1636 1662 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1637 1663 assert_select 'input[name=?]', 'issue[start_date]'
1638 1664 assert_select 'input[name=?]', 'issue[due_date]'
1639 1665 assert_select 'select[name=?]', 'issue[done_ratio]'
1640 1666 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1641 1667 assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
1642 1668 end
1643 1669
1644 1670 # Be sure we don't display inactive IssuePriorities
1645 1671 assert ! IssuePriority.find(15).active?
1646 1672 assert_select 'select[name=?]', 'issue[priority_id]' do
1647 1673 assert_select 'option[value="15"]', 0
1648 1674 end
1649 1675 end
1650 1676
1651 1677 def test_get_new_with_minimal_permissions
1652 1678 Role.find(1).update_attribute :permissions, [:add_issues]
1653 1679 WorkflowTransition.delete_all :role_id => 1
1654 1680
1655 1681 @request.session[:user_id] = 2
1656 1682 get :new, :project_id => 1, :tracker_id => 1
1657 1683 assert_response :success
1658 1684 assert_template 'new'
1659 1685
1660 1686 assert_select 'form#issue-form' do
1661 1687 assert_select 'input[name=?]', 'issue[is_private]', 0
1662 1688 assert_select 'select[name=?]', 'issue[project_id]', 0
1663 1689 assert_select 'select[name=?]', 'issue[tracker_id]'
1664 1690 assert_select 'input[name=?]', 'issue[subject]'
1665 1691 assert_select 'textarea[name=?]', 'issue[description]'
1666 1692 assert_select 'select[name=?]', 'issue[status_id]'
1667 1693 assert_select 'select[name=?]', 'issue[priority_id]'
1668 1694 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1669 1695 assert_select 'select[name=?]', 'issue[category_id]'
1670 1696 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1671 1697 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1672 1698 assert_select 'input[name=?]', 'issue[start_date]'
1673 1699 assert_select 'input[name=?]', 'issue[due_date]'
1674 1700 assert_select 'select[name=?]', 'issue[done_ratio]'
1675 1701 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1676 1702 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1677 1703 end
1678 1704 end
1679 1705
1680 1706 def test_new_without_project_id
1681 1707 @request.session[:user_id] = 2
1682 1708 get :new
1683 1709 assert_response :success
1684 1710 assert_template 'new'
1685 1711
1686 1712 assert_select 'form#issue-form[action=?]', '/issues'
1687 1713 assert_select 'form#issue-form' do
1688 1714 assert_select 'select[name=?]', 'issue[project_id]'
1689 1715 end
1690 1716
1691 1717 assert_nil assigns(:project)
1692 1718 assert_not_nil assigns(:issue)
1693 1719 end
1694 1720
1695 1721 def test_new_should_select_default_status
1696 1722 @request.session[:user_id] = 2
1697 1723
1698 1724 get :new, :project_id => 1
1699 1725 assert_response :success
1700 1726 assert_template 'new'
1701 1727 assert_select 'select[name=?]', 'issue[status_id]' do
1702 1728 assert_select 'option[value="1"][selected=selected]'
1703 1729 end
1704 1730 assert_select 'input[name=was_default_status][value="1"]'
1705 1731 end
1706 1732
1707 1733 def test_new_should_propose_allowed_statuses
1708 1734 WorkflowTransition.delete_all
1709 1735 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
1710 1736 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
1711 1737 @request.session[:user_id] = 2
1712 1738
1713 1739 get :new, :project_id => 1
1714 1740 assert_response :success
1715 1741 assert_select 'select[name=?]', 'issue[status_id]' do
1716 1742 assert_select 'option[value="1"]'
1717 1743 assert_select 'option[value="3"]'
1718 1744 assert_select 'option', 2
1719 1745 assert_select 'option[value="1"][selected=selected]'
1720 1746 end
1721 1747 end
1722 1748
1723 1749 def test_new_should_propose_allowed_statuses_without_default_status_allowed
1724 1750 WorkflowTransition.delete_all
1725 1751 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
1726 1752 assert_equal 1, Tracker.find(1).default_status_id
1727 1753 @request.session[:user_id] = 2
1728 1754
1729 1755 get :new, :project_id => 1
1730 1756 assert_response :success
1731 1757 assert_select 'select[name=?]', 'issue[status_id]' do
1732 1758 assert_select 'option[value="2"]'
1733 1759 assert_select 'option', 1
1734 1760 assert_select 'option[value="2"][selected=selected]'
1735 1761 end
1736 1762 end
1737 1763
1738 1764 def test_new_should_preselect_default_version
1739 1765 version = Version.generate!(:project_id => 1)
1740 1766 Project.find(1).update_attribute :default_version_id, version.id
1741 1767 @request.session[:user_id] = 2
1742 1768
1743 1769 get :new, :project_id => 1
1744 1770 assert_response :success
1745 1771 assert_equal version, assigns(:issue).fixed_version
1746 1772 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
1747 1773 assert_select 'option[value=?][selected=selected]', version.id.to_s
1748 1774 end
1749 1775 end
1750 1776
1751 1777 def test_get_new_with_list_custom_field
1752 1778 @request.session[:user_id] = 2
1753 1779 get :new, :project_id => 1, :tracker_id => 1
1754 1780 assert_response :success
1755 1781 assert_template 'new'
1756 1782
1757 1783 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1758 1784 assert_select 'option', 4
1759 1785 assert_select 'option[value=MySQL]', :text => 'MySQL'
1760 1786 end
1761 1787 end
1762 1788
1763 1789 def test_get_new_with_multi_custom_field
1764 1790 field = IssueCustomField.find(1)
1765 1791 field.update_attribute :multiple, true
1766 1792
1767 1793 @request.session[:user_id] = 2
1768 1794 get :new, :project_id => 1, :tracker_id => 1
1769 1795 assert_response :success
1770 1796 assert_template 'new'
1771 1797
1772 1798 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1773 1799 assert_select 'option', 3
1774 1800 assert_select 'option[value=MySQL]', :text => 'MySQL'
1775 1801 end
1776 1802 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1777 1803 end
1778 1804
1779 1805 def test_get_new_with_multi_user_custom_field
1780 1806 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1781 1807 :tracker_ids => [1], :is_for_all => true)
1782 1808
1783 1809 @request.session[:user_id] = 2
1784 1810 get :new, :project_id => 1, :tracker_id => 1
1785 1811 assert_response :success
1786 1812 assert_template 'new'
1787 1813
1788 1814 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1789 1815 assert_select 'option', Project.find(1).users.count
1790 1816 assert_select 'option[value="2"]', :text => 'John Smith'
1791 1817 end
1792 1818 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1793 1819 end
1794 1820
1795 1821 def test_get_new_with_date_custom_field
1796 1822 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1797 1823
1798 1824 @request.session[:user_id] = 2
1799 1825 get :new, :project_id => 1, :tracker_id => 1
1800 1826 assert_response :success
1801 1827
1802 1828 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1803 1829 end
1804 1830
1805 1831 def test_get_new_with_text_custom_field
1806 1832 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1807 1833
1808 1834 @request.session[:user_id] = 2
1809 1835 get :new, :project_id => 1, :tracker_id => 1
1810 1836 assert_response :success
1811 1837
1812 1838 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1813 1839 end
1814 1840
1815 1841 def test_get_new_without_default_start_date_is_creation_date
1816 1842 with_settings :default_issue_start_date_to_creation_date => 0 do
1817 1843 @request.session[:user_id] = 2
1818 1844 get :new, :project_id => 1, :tracker_id => 1
1819 1845 assert_response :success
1820 1846 assert_template 'new'
1821 1847 assert_select 'input[name=?]', 'issue[start_date]'
1822 1848 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1823 1849 end
1824 1850 end
1825 1851
1826 1852 def test_get_new_with_default_start_date_is_creation_date
1827 1853 with_settings :default_issue_start_date_to_creation_date => 1 do
1828 1854 @request.session[:user_id] = 2
1829 1855 get :new, :project_id => 1, :tracker_id => 1
1830 1856 assert_response :success
1831 1857 assert_template 'new'
1832 1858 assert_select 'input[name=?][value=?]', 'issue[start_date]',
1833 1859 Date.today.to_s
1834 1860 end
1835 1861 end
1836 1862
1837 1863 def test_get_new_form_should_allow_attachment_upload
1838 1864 @request.session[:user_id] = 2
1839 1865 get :new, :project_id => 1, :tracker_id => 1
1840 1866
1841 1867 assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
1842 1868 assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
1843 1869 end
1844 1870 end
1845 1871
1846 1872 def test_get_new_should_prefill_the_form_from_params
1847 1873 @request.session[:user_id] = 2
1848 1874 get :new, :project_id => 1,
1849 1875 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1850 1876
1851 1877 issue = assigns(:issue)
1852 1878 assert_equal 3, issue.tracker_id
1853 1879 assert_equal 'Prefilled', issue.description
1854 1880 assert_equal 'Custom field value', issue.custom_field_value(2)
1855 1881
1856 1882 assert_select 'select[name=?]', 'issue[tracker_id]' do
1857 1883 assert_select 'option[value="3"][selected=selected]'
1858 1884 end
1859 1885 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1860 1886 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1861 1887 end
1862 1888
1863 1889 def test_get_new_should_mark_required_fields
1864 1890 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1865 1891 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1866 1892 WorkflowPermission.delete_all
1867 1893 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1868 1894 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1869 1895 @request.session[:user_id] = 2
1870 1896
1871 1897 get :new, :project_id => 1
1872 1898 assert_response :success
1873 1899 assert_template 'new'
1874 1900
1875 1901 assert_select 'label[for=issue_start_date]' do
1876 1902 assert_select 'span[class=required]', 0
1877 1903 end
1878 1904 assert_select 'label[for=issue_due_date]' do
1879 1905 assert_select 'span[class=required]'
1880 1906 end
1881 1907 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1882 1908 assert_select 'span[class=required]', 0
1883 1909 end
1884 1910 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1885 1911 assert_select 'span[class=required]'
1886 1912 end
1887 1913 end
1888 1914
1889 1915 def test_get_new_should_not_display_readonly_fields
1890 1916 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1891 1917 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1892 1918 WorkflowPermission.delete_all
1893 1919 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1894 1920 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1895 1921 @request.session[:user_id] = 2
1896 1922
1897 1923 get :new, :project_id => 1
1898 1924 assert_response :success
1899 1925 assert_template 'new'
1900 1926
1901 1927 assert_select 'input[name=?]', 'issue[start_date]'
1902 1928 assert_select 'input[name=?]', 'issue[due_date]', 0
1903 1929 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1904 1930 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1905 1931 end
1906 1932
1907 1933 def test_new_with_tracker_set_as_readonly_should_accept_status
1908 1934 WorkflowPermission.delete_all
1909 1935 [1, 2].each do |status_id|
1910 1936 WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
1911 1937 end
1912 1938 @request.session[:user_id] = 2
1913 1939
1914 1940 get :new, :project_id => 1, :issue => {:status_id => 2}
1915 1941 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1916 1942 assert_equal 2, assigns(:issue).status_id
1917 1943 end
1918 1944
1919 1945 def test_get_new_without_tracker_id
1920 1946 @request.session[:user_id] = 2
1921 1947 get :new, :project_id => 1
1922 1948 assert_response :success
1923 1949 assert_template 'new'
1924 1950
1925 1951 issue = assigns(:issue)
1926 1952 assert_not_nil issue
1927 1953 assert_equal Project.find(1).trackers.first, issue.tracker
1928 1954 end
1929 1955
1930 1956 def test_get_new_with_no_default_status_should_display_an_error
1931 1957 @request.session[:user_id] = 2
1932 1958 IssueStatus.delete_all
1933 1959
1934 1960 get :new, :project_id => 1
1935 1961 assert_response 500
1936 1962 assert_select_error /No default issue/
1937 1963 end
1938 1964
1939 1965 def test_get_new_with_no_tracker_should_display_an_error
1940 1966 @request.session[:user_id] = 2
1941 1967 Tracker.delete_all
1942 1968
1943 1969 get :new, :project_id => 1
1944 1970 assert_response 500
1945 1971 assert_select_error /No tracker/
1946 1972 end
1947 1973
1948 1974 def test_new_with_invalid_project_id
1949 1975 @request.session[:user_id] = 1
1950 1976 get :new, :project_id => 'invalid'
1951 1977 assert_response 404
1952 1978 end
1953 1979
1954 1980 def test_update_form_for_new_issue
1955 1981 @request.session[:user_id] = 2
1956 1982 xhr :post, :new, :project_id => 1,
1957 1983 :issue => {:tracker_id => 2,
1958 1984 :subject => 'This is the test_new issue',
1959 1985 :description => 'This is the description',
1960 1986 :priority_id => 5}
1961 1987 assert_response :success
1962 1988 assert_template 'new'
1963 1989 assert_template :partial => '_form'
1964 1990 assert_equal 'text/javascript', response.content_type
1965 1991
1966 1992 issue = assigns(:issue)
1967 1993 assert_kind_of Issue, issue
1968 1994 assert_equal 1, issue.project_id
1969 1995 assert_equal 2, issue.tracker_id
1970 1996 assert_equal 'This is the test_new issue', issue.subject
1971 1997 end
1972 1998
1973 1999 def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
1974 2000 @request.session[:user_id] = 2
1975 2001 WorkflowTransition.delete_all
1976 2002 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
1977 2003 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
1978 2004 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1979 2005
1980 2006 xhr :post, :new, :project_id => 1,
1981 2007 :issue => {:tracker_id => 1,
1982 2008 :status_id => 5,
1983 2009 :subject => 'This is an issue'}
1984 2010
1985 2011 assert_equal 5, assigns(:issue).status_id
1986 2012 assert_equal [2,5], assigns(:allowed_statuses).map(&:id).sort
1987 2013 end
1988 2014
1989 2015 def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
1990 2016 @request.session[:user_id] = 2
1991 2017 tracker = Tracker.find(2)
1992 2018 tracker.update! :default_status_id => 2
1993 2019 tracker.generate_transitions! 2, 1, :clear => true
1994 2020
1995 2021 xhr :post, :new, :project_id => 1,
1996 2022 :issue => {:tracker_id => 2,
1997 2023 :status_id => 1},
1998 2024 :was_default_status => 1
1999 2025
2000 2026 assert_equal 2, assigns(:issue).status_id
2001 2027 end
2002 2028
2003 2029 def test_update_form_for_new_issue_should_ignore_version_when_changing_project
2004 2030 version = Version.generate!(:project_id => 1)
2005 2031 Project.find(1).update_attribute :default_version_id, version.id
2006 2032 @request.session[:user_id] = 2
2007 2033
2008 2034 xhr :post, :new, :issue => {:project_id => 1,
2009 2035 :fixed_version_id => ''},
2010 2036 :form_update_triggered_by => 'issue_project_id'
2011 2037 assert_response :success
2012 2038 assert_template 'new'
2013 2039
2014 2040 issue = assigns(:issue)
2015 2041 assert_equal 1, issue.project_id
2016 2042 assert_equal version, issue.fixed_version
2017 2043 end
2018 2044
2019 2045 def test_post_create
2020 2046 @request.session[:user_id] = 2
2021 2047 assert_difference 'Issue.count' do
2022 2048 assert_no_difference 'Journal.count' do
2023 2049 post :create, :project_id => 1,
2024 2050 :issue => {:tracker_id => 3,
2025 2051 :status_id => 2,
2026 2052 :subject => 'This is the test_new issue',
2027 2053 :description => 'This is the description',
2028 2054 :priority_id => 5,
2029 2055 :start_date => '2010-11-07',
2030 2056 :estimated_hours => '',
2031 2057 :custom_field_values => {'2' => 'Value for field 2'}}
2032 2058 end
2033 2059 end
2034 2060 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2035 2061
2036 2062 issue = Issue.find_by_subject('This is the test_new issue')
2037 2063 assert_not_nil issue
2038 2064 assert_equal 2, issue.author_id
2039 2065 assert_equal 3, issue.tracker_id
2040 2066 assert_equal 2, issue.status_id
2041 2067 assert_equal Date.parse('2010-11-07'), issue.start_date
2042 2068 assert_nil issue.estimated_hours
2043 2069 v = issue.custom_values.where(:custom_field_id => 2).first
2044 2070 assert_not_nil v
2045 2071 assert_equal 'Value for field 2', v.value
2046 2072 end
2047 2073
2048 2074 def test_post_new_with_group_assignment
2049 2075 group = Group.find(11)
2050 2076 project = Project.find(1)
2051 2077 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2052 2078
2053 2079 with_settings :issue_group_assignment => '1' do
2054 2080 @request.session[:user_id] = 2
2055 2081 assert_difference 'Issue.count' do
2056 2082 post :create, :project_id => project.id,
2057 2083 :issue => {:tracker_id => 3,
2058 2084 :status_id => 1,
2059 2085 :subject => 'This is the test_new_with_group_assignment issue',
2060 2086 :assigned_to_id => group.id}
2061 2087 end
2062 2088 end
2063 2089 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2064 2090
2065 2091 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
2066 2092 assert_not_nil issue
2067 2093 assert_equal group, issue.assigned_to
2068 2094 end
2069 2095
2070 2096 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
2071 2097 with_settings :default_issue_start_date_to_creation_date => 0 do
2072 2098 @request.session[:user_id] = 2
2073 2099 assert_difference 'Issue.count' do
2074 2100 post :create, :project_id => 1,
2075 2101 :issue => {:tracker_id => 3,
2076 2102 :status_id => 2,
2077 2103 :subject => 'This is the test_new issue',
2078 2104 :description => 'This is the description',
2079 2105 :priority_id => 5,
2080 2106 :estimated_hours => '',
2081 2107 :custom_field_values => {'2' => 'Value for field 2'}}
2082 2108 end
2083 2109 assert_redirected_to :controller => 'issues', :action => 'show',
2084 2110 :id => Issue.last.id
2085 2111 issue = Issue.find_by_subject('This is the test_new issue')
2086 2112 assert_not_nil issue
2087 2113 assert_nil issue.start_date
2088 2114 end
2089 2115 end
2090 2116
2091 2117 def test_post_create_without_start_date_and_default_start_date_is_creation_date
2092 2118 with_settings :default_issue_start_date_to_creation_date => 1 do
2093 2119 @request.session[:user_id] = 2
2094 2120 assert_difference 'Issue.count' do
2095 2121 post :create, :project_id => 1,
2096 2122 :issue => {:tracker_id => 3,
2097 2123 :status_id => 2,
2098 2124 :subject => 'This is the test_new issue',
2099 2125 :description => 'This is the description',
2100 2126 :priority_id => 5,
2101 2127 :estimated_hours => '',
2102 2128 :custom_field_values => {'2' => 'Value for field 2'}}
2103 2129 end
2104 2130 assert_redirected_to :controller => 'issues', :action => 'show',
2105 2131 :id => Issue.last.id
2106 2132 issue = Issue.find_by_subject('This is the test_new issue')
2107 2133 assert_not_nil issue
2108 2134 assert_equal Date.today, issue.start_date
2109 2135 end
2110 2136 end
2111 2137
2112 2138 def test_post_create_and_continue
2113 2139 @request.session[:user_id] = 2
2114 2140 assert_difference 'Issue.count' do
2115 2141 post :create, :project_id => 1,
2116 2142 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
2117 2143 :continue => ''
2118 2144 end
2119 2145
2120 2146 issue = Issue.order('id DESC').first
2121 2147 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
2122 2148 assert_not_nil flash[:notice], "flash was not set"
2123 2149 assert_select_in flash[:notice],
2124 2150 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
2125 2151 end
2126 2152
2127 2153 def test_post_create_without_custom_fields_param
2128 2154 @request.session[:user_id] = 2
2129 2155 assert_difference 'Issue.count' do
2130 2156 post :create, :project_id => 1,
2131 2157 :issue => {:tracker_id => 1,
2132 2158 :subject => 'This is the test_new issue',
2133 2159 :description => 'This is the description',
2134 2160 :priority_id => 5}
2135 2161 end
2136 2162 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2137 2163 end
2138 2164
2139 2165 def test_post_create_with_multi_custom_field
2140 2166 field = IssueCustomField.find_by_name('Database')
2141 2167 field.update_attribute(:multiple, true)
2142 2168
2143 2169 @request.session[:user_id] = 2
2144 2170 assert_difference 'Issue.count' do
2145 2171 post :create, :project_id => 1,
2146 2172 :issue => {:tracker_id => 1,
2147 2173 :subject => 'This is the test_new issue',
2148 2174 :description => 'This is the description',
2149 2175 :priority_id => 5,
2150 2176 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
2151 2177 end
2152 2178 assert_response 302
2153 2179 issue = Issue.order('id DESC').first
2154 2180 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
2155 2181 end
2156 2182
2157 2183 def test_post_create_with_empty_multi_custom_field
2158 2184 field = IssueCustomField.find_by_name('Database')
2159 2185 field.update_attribute(:multiple, true)
2160 2186
2161 2187 @request.session[:user_id] = 2
2162 2188 assert_difference 'Issue.count' do
2163 2189 post :create, :project_id => 1,
2164 2190 :issue => {:tracker_id => 1,
2165 2191 :subject => 'This is the test_new issue',
2166 2192 :description => 'This is the description',
2167 2193 :priority_id => 5,
2168 2194 :custom_field_values => {'1' => ['']}}
2169 2195 end
2170 2196 assert_response 302
2171 2197 issue = Issue.order('id DESC').first
2172 2198 assert_equal [''], issue.custom_field_value(1).sort
2173 2199 end
2174 2200
2175 2201 def test_post_create_with_multi_user_custom_field
2176 2202 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
2177 2203 :tracker_ids => [1], :is_for_all => true)
2178 2204
2179 2205 @request.session[:user_id] = 2
2180 2206 assert_difference 'Issue.count' do
2181 2207 post :create, :project_id => 1,
2182 2208 :issue => {:tracker_id => 1,
2183 2209 :subject => 'This is the test_new issue',
2184 2210 :description => 'This is the description',
2185 2211 :priority_id => 5,
2186 2212 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
2187 2213 end
2188 2214 assert_response 302
2189 2215 issue = Issue.order('id DESC').first
2190 2216 assert_equal ['2', '3'], issue.custom_field_value(field).sort
2191 2217 end
2192 2218
2193 2219 def test_post_create_with_required_custom_field_and_without_custom_fields_param
2194 2220 field = IssueCustomField.find_by_name('Database')
2195 2221 field.update_attribute(:is_required, true)
2196 2222
2197 2223 @request.session[:user_id] = 2
2198 2224 assert_no_difference 'Issue.count' do
2199 2225 post :create, :project_id => 1,
2200 2226 :issue => {:tracker_id => 1,
2201 2227 :subject => 'This is the test_new issue',
2202 2228 :description => 'This is the description',
2203 2229 :priority_id => 5}
2204 2230 end
2205 2231 assert_response :success
2206 2232 assert_template 'new'
2207 2233 issue = assigns(:issue)
2208 2234 assert_not_nil issue
2209 2235 assert_select_error /Database cannot be blank/
2210 2236 end
2211 2237
2212 2238 def test_create_should_validate_required_fields
2213 2239 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2214 2240 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2215 2241 WorkflowPermission.delete_all
2216 2242 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
2217 2243 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2218 2244 @request.session[:user_id] = 2
2219 2245
2220 2246 assert_no_difference 'Issue.count' do
2221 2247 post :create, :project_id => 1, :issue => {
2222 2248 :tracker_id => 2,
2223 2249 :status_id => 1,
2224 2250 :subject => 'Test',
2225 2251 :start_date => '',
2226 2252 :due_date => '',
2227 2253 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
2228 2254 }
2229 2255 assert_response :success
2230 2256 assert_template 'new'
2231 2257 end
2232 2258
2233 2259 assert_select_error /Due date cannot be blank/i
2234 2260 assert_select_error /Bar cannot be blank/i
2235 2261 end
2236 2262
2237 2263 def test_create_should_validate_required_list_fields
2238 2264 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
2239 2265 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
2240 2266 WorkflowPermission.delete_all
2241 2267 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
2242 2268 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2243 2269 @request.session[:user_id] = 2
2244 2270
2245 2271 assert_no_difference 'Issue.count' do
2246 2272 post :create, :project_id => 1, :issue => {
2247 2273 :tracker_id => 2,
2248 2274 :status_id => 1,
2249 2275 :subject => 'Test',
2250 2276 :start_date => '',
2251 2277 :due_date => '',
2252 2278 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ['']}
2253 2279 }
2254 2280 assert_response :success
2255 2281 assert_template 'new'
2256 2282 end
2257 2283
2258 2284 assert_select_error /Foo cannot be blank/i
2259 2285 assert_select_error /Bar cannot be blank/i
2260 2286 end
2261 2287
2262 2288 def test_create_should_ignore_readonly_fields
2263 2289 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2264 2290 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2265 2291 WorkflowPermission.delete_all
2266 2292 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
2267 2293 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
2268 2294 @request.session[:user_id] = 2
2269 2295
2270 2296 assert_difference 'Issue.count' do
2271 2297 post :create, :project_id => 1, :issue => {
2272 2298 :tracker_id => 2,
2273 2299 :status_id => 1,
2274 2300 :subject => 'Test',
2275 2301 :start_date => '2012-07-14',
2276 2302 :due_date => '2012-07-16',
2277 2303 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
2278 2304 }
2279 2305 assert_response 302
2280 2306 end
2281 2307
2282 2308 issue = Issue.order('id DESC').first
2283 2309 assert_equal Date.parse('2012-07-14'), issue.start_date
2284 2310 assert_nil issue.due_date
2285 2311 assert_equal 'value1', issue.custom_field_value(cf1)
2286 2312 assert_nil issue.custom_field_value(cf2)
2287 2313 end
2288 2314
2289 2315 def test_post_create_with_watchers
2290 2316 @request.session[:user_id] = 2
2291 2317 ActionMailer::Base.deliveries.clear
2292 2318
2293 2319 with_settings :notified_events => %w(issue_added) do
2294 2320 assert_difference 'Watcher.count', 2 do
2295 2321 post :create, :project_id => 1,
2296 2322 :issue => {:tracker_id => 1,
2297 2323 :subject => 'This is a new issue with watchers',
2298 2324 :description => 'This is the description',
2299 2325 :priority_id => 5,
2300 2326 :watcher_user_ids => ['2', '3']}
2301 2327 end
2302 2328 end
2303 2329 issue = Issue.find_by_subject('This is a new issue with watchers')
2304 2330 assert_not_nil issue
2305 2331 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
2306 2332
2307 2333 # Watchers added
2308 2334 assert_equal [2, 3], issue.watcher_user_ids.sort
2309 2335 assert issue.watched_by?(User.find(3))
2310 2336 # Watchers notified
2311 2337 mail = ActionMailer::Base.deliveries.last
2312 2338 assert_not_nil mail
2313 2339 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
2314 2340 end
2315 2341
2316 2342 def test_post_create_subissue
2317 2343 @request.session[:user_id] = 2
2318 2344
2319 2345 assert_difference 'Issue.count' do
2320 2346 post :create, :project_id => 1,
2321 2347 :issue => {:tracker_id => 1,
2322 2348 :subject => 'This is a child issue',
2323 2349 :parent_issue_id => '2'}
2324 2350 assert_response 302
2325 2351 end
2326 2352 issue = Issue.order('id DESC').first
2327 2353 assert_equal Issue.find(2), issue.parent
2328 2354 end
2329 2355
2330 2356 def test_post_create_subissue_with_sharp_parent_id
2331 2357 @request.session[:user_id] = 2
2332 2358
2333 2359 assert_difference 'Issue.count' do
2334 2360 post :create, :project_id => 1,
2335 2361 :issue => {:tracker_id => 1,
2336 2362 :subject => 'This is a child issue',
2337 2363 :parent_issue_id => '#2'}
2338 2364 assert_response 302
2339 2365 end
2340 2366 issue = Issue.order('id DESC').first
2341 2367 assert_equal Issue.find(2), issue.parent
2342 2368 end
2343 2369
2344 2370 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
2345 2371 @request.session[:user_id] = 2
2346 2372
2347 2373 assert_no_difference 'Issue.count' do
2348 2374 post :create, :project_id => 1,
2349 2375 :issue => {:tracker_id => 1,
2350 2376 :subject => 'This is a child issue',
2351 2377 :parent_issue_id => '4'}
2352 2378
2353 2379 assert_response :success
2354 2380 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2355 2381 assert_select_error /Parent task is invalid/i
2356 2382 end
2357 2383 end
2358 2384
2359 2385 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2360 2386 @request.session[:user_id] = 2
2361 2387
2362 2388 assert_no_difference 'Issue.count' do
2363 2389 post :create, :project_id => 1,
2364 2390 :issue => {:tracker_id => 1,
2365 2391 :subject => 'This is a child issue',
2366 2392 :parent_issue_id => '01ABC'}
2367 2393
2368 2394 assert_response :success
2369 2395 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2370 2396 assert_select_error /Parent task is invalid/i
2371 2397 end
2372 2398 end
2373 2399
2374 2400 def test_post_create_private
2375 2401 @request.session[:user_id] = 2
2376 2402
2377 2403 assert_difference 'Issue.count' do
2378 2404 post :create, :project_id => 1,
2379 2405 :issue => {:tracker_id => 1,
2380 2406 :subject => 'This is a private issue',
2381 2407 :is_private => '1'}
2382 2408 end
2383 2409 issue = Issue.order('id DESC').first
2384 2410 assert issue.is_private?
2385 2411 end
2386 2412
2387 2413 def test_post_create_private_with_set_own_issues_private_permission
2388 2414 role = Role.find(1)
2389 2415 role.remove_permission! :set_issues_private
2390 2416 role.add_permission! :set_own_issues_private
2391 2417
2392 2418 @request.session[:user_id] = 2
2393 2419
2394 2420 assert_difference 'Issue.count' do
2395 2421 post :create, :project_id => 1,
2396 2422 :issue => {:tracker_id => 1,
2397 2423 :subject => 'This is a private issue',
2398 2424 :is_private => '1'}
2399 2425 end
2400 2426 issue = Issue.order('id DESC').first
2401 2427 assert issue.is_private?
2402 2428 end
2403 2429
2404 2430 def test_create_without_project_id
2405 2431 @request.session[:user_id] = 2
2406 2432
2407 2433 assert_difference 'Issue.count' do
2408 2434 post :create,
2409 2435 :issue => {:project_id => 3,
2410 2436 :tracker_id => 2,
2411 2437 :subject => 'Foo'}
2412 2438 assert_response 302
2413 2439 end
2414 2440 issue = Issue.order('id DESC').first
2415 2441 assert_equal 3, issue.project_id
2416 2442 assert_equal 2, issue.tracker_id
2417 2443 end
2418 2444
2419 2445 def test_create_without_project_id_and_continue_should_redirect_without_project_id
2420 2446 @request.session[:user_id] = 2
2421 2447
2422 2448 assert_difference 'Issue.count' do
2423 2449 post :create,
2424 2450 :issue => {:project_id => 3,
2425 2451 :tracker_id => 2,
2426 2452 :subject => 'Foo'},
2427 2453 :continue => '1'
2428 2454 assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
2429 2455 end
2430 2456 end
2431 2457
2432 2458 def test_create_without_project_id_should_be_denied_without_permission
2433 2459 Role.non_member.remove_permission! :add_issues
2434 2460 Role.anonymous.remove_permission! :add_issues
2435 2461 @request.session[:user_id] = 2
2436 2462
2437 2463 assert_no_difference 'Issue.count' do
2438 2464 post :create,
2439 2465 :issue => {:project_id => 3,
2440 2466 :tracker_id => 2,
2441 2467 :subject => 'Foo'}
2442 2468 assert_response 422
2443 2469 end
2444 2470 end
2445 2471
2446 2472 def test_create_without_project_id_with_failure
2447 2473 @request.session[:user_id] = 2
2448 2474
2449 2475 post :create,
2450 2476 :issue => {:project_id => 3,
2451 2477 :tracker_id => 2,
2452 2478 :subject => ''}
2453 2479 assert_response :success
2454 2480 assert_nil assigns(:project)
2455 2481 end
2456 2482
2457 2483 def test_post_create_should_send_a_notification
2458 2484 ActionMailer::Base.deliveries.clear
2459 2485 @request.session[:user_id] = 2
2460 2486 with_settings :notified_events => %w(issue_added) do
2461 2487 assert_difference 'Issue.count' do
2462 2488 post :create, :project_id => 1,
2463 2489 :issue => {:tracker_id => 3,
2464 2490 :subject => 'This is the test_new issue',
2465 2491 :description => 'This is the description',
2466 2492 :priority_id => 5,
2467 2493 :estimated_hours => '',
2468 2494 :custom_field_values => {'2' => 'Value for field 2'}}
2469 2495 end
2470 2496 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2471 2497
2472 2498 assert_equal 1, ActionMailer::Base.deliveries.size
2473 2499 end
2474 2500 end
2475 2501
2476 2502 def test_post_create_should_preserve_fields_values_on_validation_failure
2477 2503 @request.session[:user_id] = 2
2478 2504 post :create, :project_id => 1,
2479 2505 :issue => {:tracker_id => 1,
2480 2506 # empty subject
2481 2507 :subject => '',
2482 2508 :description => 'This is a description',
2483 2509 :priority_id => 6,
2484 2510 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2485 2511 assert_response :success
2486 2512 assert_template 'new'
2487 2513
2488 2514 assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
2489 2515 assert_select 'select[name=?]', 'issue[priority_id]' do
2490 2516 assert_select 'option[value="6"][selected=selected]', :text => 'High'
2491 2517 end
2492 2518 # Custom fields
2493 2519 assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
2494 2520 assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
2495 2521 end
2496 2522 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
2497 2523 end
2498 2524
2499 2525 def test_post_create_with_failure_should_preserve_watchers
2500 2526 assert !User.find(8).member_of?(Project.find(1))
2501 2527
2502 2528 @request.session[:user_id] = 2
2503 2529 post :create, :project_id => 1,
2504 2530 :issue => {:tracker_id => 1,
2505 2531 :watcher_user_ids => ['3', '8']}
2506 2532 assert_response :success
2507 2533 assert_template 'new'
2508 2534
2509 2535 assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
2510 2536 assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
2511 2537 assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
2512 2538 end
2513 2539
2514 2540 def test_post_create_should_ignore_non_safe_attributes
2515 2541 @request.session[:user_id] = 2
2516 2542 assert_nothing_raised do
2517 2543 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2518 2544 end
2519 2545 end
2520 2546
2521 2547 def test_post_create_with_attachment
2522 2548 set_tmp_attachments_directory
2523 2549 @request.session[:user_id] = 2
2524 2550
2525 2551 assert_difference 'Issue.count' do
2526 2552 assert_difference 'Attachment.count' do
2527 2553 assert_no_difference 'Journal.count' do
2528 2554 post :create, :project_id => 1,
2529 2555 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2530 2556 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2531 2557 end
2532 2558 end
2533 2559 end
2534 2560
2535 2561 issue = Issue.order('id DESC').first
2536 2562 attachment = Attachment.order('id DESC').first
2537 2563
2538 2564 assert_equal issue, attachment.container
2539 2565 assert_equal 2, attachment.author_id
2540 2566 assert_equal 'testfile.txt', attachment.filename
2541 2567 assert_equal 'text/plain', attachment.content_type
2542 2568 assert_equal 'test file', attachment.description
2543 2569 assert_equal 59, attachment.filesize
2544 2570 assert File.exists?(attachment.diskfile)
2545 2571 assert_equal 59, File.size(attachment.diskfile)
2546 2572 end
2547 2573
2548 2574 def test_post_create_with_attachment_should_notify_with_attachments
2549 2575 ActionMailer::Base.deliveries.clear
2550 2576 set_tmp_attachments_directory
2551 2577 @request.session[:user_id] = 2
2552 2578
2553 2579 with_settings :host_name => 'mydomain.foo', :protocol => 'http', :notified_events => %w(issue_added) do
2554 2580 assert_difference 'Issue.count' do
2555 2581 post :create, :project_id => 1,
2556 2582 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2557 2583 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2558 2584 end
2559 2585 end
2560 2586
2561 2587 assert_not_nil ActionMailer::Base.deliveries.last
2562 2588 assert_select_email do
2563 2589 assert_select 'a[href^=?]', 'http://mydomain.foo/attachments/download', 'testfile.txt'
2564 2590 end
2565 2591 end
2566 2592
2567 2593 def test_post_create_with_failure_should_save_attachments
2568 2594 set_tmp_attachments_directory
2569 2595 @request.session[:user_id] = 2
2570 2596
2571 2597 assert_no_difference 'Issue.count' do
2572 2598 assert_difference 'Attachment.count' do
2573 2599 post :create, :project_id => 1,
2574 2600 :issue => { :tracker_id => '1', :subject => '' },
2575 2601 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2576 2602 assert_response :success
2577 2603 assert_template 'new'
2578 2604 end
2579 2605 end
2580 2606
2581 2607 attachment = Attachment.order('id DESC').first
2582 2608 assert_equal 'testfile.txt', attachment.filename
2583 2609 assert File.exists?(attachment.diskfile)
2584 2610 assert_nil attachment.container
2585 2611
2586 2612 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2587 2613 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2588 2614 end
2589 2615
2590 2616 def test_post_create_with_failure_should_keep_saved_attachments
2591 2617 set_tmp_attachments_directory
2592 2618 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2593 2619 @request.session[:user_id] = 2
2594 2620
2595 2621 assert_no_difference 'Issue.count' do
2596 2622 assert_no_difference 'Attachment.count' do
2597 2623 post :create, :project_id => 1,
2598 2624 :issue => { :tracker_id => '1', :subject => '' },
2599 2625 :attachments => {'p0' => {'token' => attachment.token}}
2600 2626 assert_response :success
2601 2627 assert_template 'new'
2602 2628 end
2603 2629 end
2604 2630
2605 2631 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2606 2632 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2607 2633 end
2608 2634
2609 2635 def test_post_create_should_attach_saved_attachments
2610 2636 set_tmp_attachments_directory
2611 2637 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2612 2638 @request.session[:user_id] = 2
2613 2639
2614 2640 assert_difference 'Issue.count' do
2615 2641 assert_no_difference 'Attachment.count' do
2616 2642 post :create, :project_id => 1,
2617 2643 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2618 2644 :attachments => {'p0' => {'token' => attachment.token}}
2619 2645 assert_response 302
2620 2646 end
2621 2647 end
2622 2648
2623 2649 issue = Issue.order('id DESC').first
2624 2650 assert_equal 1, issue.attachments.count
2625 2651
2626 2652 attachment.reload
2627 2653 assert_equal issue, attachment.container
2628 2654 end
2629 2655
2630 2656 def setup_without_workflow_privilege
2631 2657 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2632 2658 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2633 2659 end
2634 2660 private :setup_without_workflow_privilege
2635 2661
2636 2662 test "without workflow privilege #new should propose default status only" do
2637 2663 setup_without_workflow_privilege
2638 2664 get :new, :project_id => 1
2639 2665 assert_response :success
2640 2666 assert_template 'new'
2641 2667
2642 2668 issue = assigns(:issue)
2643 2669 assert_not_nil issue.default_status
2644 2670
2645 2671 assert_select 'select[name=?]', 'issue[status_id]' do
2646 2672 assert_select 'option', 1
2647 2673 assert_select 'option[value=?]', issue.default_status.id.to_s
2648 2674 end
2649 2675 end
2650 2676
2651 2677 test "without workflow privilege #create should accept default status" do
2652 2678 setup_without_workflow_privilege
2653 2679 assert_difference 'Issue.count' do
2654 2680 post :create, :project_id => 1,
2655 2681 :issue => {:tracker_id => 1,
2656 2682 :subject => 'This is an issue',
2657 2683 :status_id => 1}
2658 2684 end
2659 2685 issue = Issue.order('id').last
2660 2686 assert_not_nil issue.default_status
2661 2687 assert_equal issue.default_status, issue.status
2662 2688 end
2663 2689
2664 2690 test "without workflow privilege #create should ignore unauthorized status" do
2665 2691 setup_without_workflow_privilege
2666 2692 assert_difference 'Issue.count' do
2667 2693 post :create, :project_id => 1,
2668 2694 :issue => {:tracker_id => 1,
2669 2695 :subject => 'This is an issue',
2670 2696 :status_id => 3}
2671 2697 end
2672 2698 issue = Issue.order('id').last
2673 2699 assert_not_nil issue.default_status
2674 2700 assert_equal issue.default_status, issue.status
2675 2701 end
2676 2702
2677 2703 test "without workflow privilege #update should ignore status change" do
2678 2704 setup_without_workflow_privilege
2679 2705 assert_difference 'Journal.count' do
2680 2706 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2681 2707 end
2682 2708 assert_equal 1, Issue.find(1).status_id
2683 2709 end
2684 2710
2685 2711 test "without workflow privilege #update ignore attributes changes" do
2686 2712 setup_without_workflow_privilege
2687 2713 assert_difference 'Journal.count' do
2688 2714 put :update, :id => 1,
2689 2715 :issue => {:subject => 'changed', :assigned_to_id => 2,
2690 2716 :notes => 'just trying'}
2691 2717 end
2692 2718 issue = Issue.find(1)
2693 2719 assert_equal "Cannot print recipes", issue.subject
2694 2720 assert_nil issue.assigned_to
2695 2721 end
2696 2722
2697 2723 def setup_with_workflow_privilege
2698 2724 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2699 2725 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2700 2726 :old_status_id => 1, :new_status_id => 3)
2701 2727 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2702 2728 :old_status_id => 1, :new_status_id => 4)
2703 2729 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2704 2730 end
2705 2731 private :setup_with_workflow_privilege
2706 2732
2707 2733 def setup_with_workflow_privilege_and_edit_issues_permission
2708 2734 setup_with_workflow_privilege
2709 2735 Role.anonymous.add_permission! :add_issues, :edit_issues
2710 2736 end
2711 2737 private :setup_with_workflow_privilege_and_edit_issues_permission
2712 2738
2713 2739 test "with workflow privilege and :edit_issues permission should accept authorized status" do
2714 2740 setup_with_workflow_privilege_and_edit_issues_permission
2715 2741 assert_difference 'Journal.count' do
2716 2742 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2717 2743 end
2718 2744 assert_equal 3, Issue.find(1).status_id
2719 2745 end
2720 2746
2721 2747 test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
2722 2748 setup_with_workflow_privilege_and_edit_issues_permission
2723 2749 assert_difference 'Journal.count' do
2724 2750 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2725 2751 end
2726 2752 assert_equal 1, Issue.find(1).status_id
2727 2753 end
2728 2754
2729 2755 test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
2730 2756 setup_with_workflow_privilege_and_edit_issues_permission
2731 2757 assert_difference 'Journal.count' do
2732 2758 put :update, :id => 1,
2733 2759 :issue => {:subject => 'changed', :assigned_to_id => 2,
2734 2760 :notes => 'just trying'}
2735 2761 end
2736 2762 issue = Issue.find(1)
2737 2763 assert_equal "changed", issue.subject
2738 2764 assert_equal 2, issue.assigned_to_id
2739 2765 end
2740 2766
2741 2767 def test_new_as_copy
2742 2768 @request.session[:user_id] = 2
2743 2769 get :new, :project_id => 1, :copy_from => 1
2744 2770
2745 2771 assert_response :success
2746 2772 assert_template 'new'
2747 2773
2748 2774 assert_not_nil assigns(:issue)
2749 2775 orig = Issue.find(1)
2750 2776 assert_equal 1, assigns(:issue).project_id
2751 2777 assert_equal orig.subject, assigns(:issue).subject
2752 2778 assert assigns(:issue).copy?
2753 2779
2754 2780 assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
2755 2781 assert_select 'select[name=?]', 'issue[project_id]' do
2756 2782 assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
2757 2783 assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
2758 2784 end
2759 2785 assert_select 'input[name=copy_from][value="1"]'
2760 2786 end
2761 2787
2762 2788 # "New issue" menu item should not link to copy
2763 2789 assert_select '#main-menu a.new-issue[href="/projects/ecookbook/issues/new"]'
2764 2790 end
2765 2791
2766 2792 def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
2767 2793 user = setup_user_with_copy_but_not_add_permission
2768 2794
2769 2795 @request.session[:user_id] = user.id
2770 2796 get :new, :project_id => 1, :copy_from => 1
2771 2797
2772 2798 assert_response :success
2773 2799 assert_template 'new'
2774 2800 assert_select 'select[name=?]', 'issue[project_id]' do
2775 2801 assert_select 'option[value="1"]', 0
2776 2802 assert_select 'option[value="2"]', :text => 'OnlineStore'
2777 2803 end
2778 2804 end
2779 2805
2780 2806 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2781 2807 @request.session[:user_id] = 2
2782 2808 issue = Issue.find(3)
2783 2809 assert issue.attachments.count > 0
2784 2810 get :new, :project_id => 1, :copy_from => 3
2785 2811
2786 2812 assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
2787 2813 end
2788 2814
2789 2815 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2790 2816 @request.session[:user_id] = 2
2791 2817 issue = Issue.find(3)
2792 2818 issue.attachments.delete_all
2793 2819 get :new, :project_id => 1, :copy_from => 3
2794 2820
2795 2821 assert_select 'input[name=copy_attachments]', 0
2796 2822 end
2797 2823
2798 2824 def test_new_as_copy_should_preserve_parent_id
2799 2825 @request.session[:user_id] = 2
2800 2826 issue = Issue.generate!(:parent_issue_id => 2)
2801 2827 get :new, :project_id => 1, :copy_from => issue.id
2802 2828
2803 2829 assert_select 'input[name=?][value="2"]', 'issue[parent_issue_id]'
2804 2830 end
2805 2831
2806 2832 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2807 2833 @request.session[:user_id] = 2
2808 2834 issue = Issue.generate_with_descendants!
2809 2835 get :new, :project_id => 1, :copy_from => issue.id
2810 2836
2811 2837 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
2812 2838 end
2813 2839
2814 2840 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2815 2841 @request.session[:user_id] = 2
2816 2842 get :new, :project_id => 1, :copy_from => 99999
2817 2843 assert_response 404
2818 2844 end
2819 2845
2820 2846 def test_create_as_copy_on_different_project
2821 2847 @request.session[:user_id] = 2
2822 2848 assert_difference 'Issue.count' do
2823 2849 post :create, :project_id => 1, :copy_from => 1,
2824 2850 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2825 2851
2826 2852 assert_not_nil assigns(:issue)
2827 2853 assert assigns(:issue).copy?
2828 2854 end
2829 2855 issue = Issue.order('id DESC').first
2830 2856 assert_redirected_to "/issues/#{issue.id}"
2831 2857
2832 2858 assert_equal 2, issue.project_id
2833 2859 assert_equal 3, issue.tracker_id
2834 2860 assert_equal 'Copy', issue.subject
2835 2861 end
2836 2862
2837 2863 def test_create_as_copy_should_allow_status_to_be_set_to_default
2838 2864 copied = Issue.generate! :status_id => 2
2839 2865 assert_equal 2, copied.reload.status_id
2840 2866
2841 2867 @request.session[:user_id] = 2
2842 2868 assert_difference 'Issue.count' do
2843 2869 post :create, :project_id => 1, :copy_from => copied.id,
2844 2870 :issue => {:project_id => '1', :tracker_id => '1', :status_id => '1'},
2845 2871 :was_default_status => '1'
2846 2872 end
2847 2873 issue = Issue.order('id DESC').first
2848 2874 assert_equal 1, issue.status_id
2849 2875 end
2850 2876
2851 2877 def test_create_as_copy_should_copy_attachments
2852 2878 @request.session[:user_id] = 2
2853 2879 issue = Issue.find(3)
2854 2880 count = issue.attachments.count
2855 2881 assert count > 0
2856 2882 assert_difference 'Issue.count' do
2857 2883 assert_difference 'Attachment.count', count do
2858 2884 post :create, :project_id => 1, :copy_from => 3,
2859 2885 :issue => {:project_id => '1', :tracker_id => '3',
2860 2886 :status_id => '1', :subject => 'Copy with attachments'},
2861 2887 :copy_attachments => '1'
2862 2888 end
2863 2889 end
2864 2890 copy = Issue.order('id DESC').first
2865 2891 assert_equal count, copy.attachments.count
2866 2892 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2867 2893 end
2868 2894
2869 2895 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2870 2896 @request.session[:user_id] = 2
2871 2897 issue = Issue.find(3)
2872 2898 count = issue.attachments.count
2873 2899 assert count > 0
2874 2900 assert_difference 'Issue.count' do
2875 2901 assert_no_difference 'Attachment.count' do
2876 2902 post :create, :project_id => 1, :copy_from => 3,
2877 2903 :issue => {:project_id => '1', :tracker_id => '3',
2878 2904 :status_id => '1', :subject => 'Copy with attachments'}
2879 2905 end
2880 2906 end
2881 2907 copy = Issue.order('id DESC').first
2882 2908 assert_equal 0, copy.attachments.count
2883 2909 end
2884 2910
2885 2911 def test_create_as_copy_with_attachments_should_also_add_new_files
2886 2912 @request.session[:user_id] = 2
2887 2913 issue = Issue.find(3)
2888 2914 count = issue.attachments.count
2889 2915 assert count > 0
2890 2916 assert_difference 'Issue.count' do
2891 2917 assert_difference 'Attachment.count', count + 1 do
2892 2918 post :create, :project_id => 1, :copy_from => 3,
2893 2919 :issue => {:project_id => '1', :tracker_id => '3',
2894 2920 :status_id => '1', :subject => 'Copy with attachments'},
2895 2921 :copy_attachments => '1',
2896 2922 :attachments => {'1' =>
2897 2923 {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
2898 2924 'description' => 'test file'}}
2899 2925 end
2900 2926 end
2901 2927 copy = Issue.order('id DESC').first
2902 2928 assert_equal count + 1, copy.attachments.count
2903 2929 end
2904 2930
2905 2931 def test_create_as_copy_should_add_relation_with_copied_issue
2906 2932 @request.session[:user_id] = 2
2907 2933 assert_difference 'Issue.count' do
2908 2934 assert_difference 'IssueRelation.count' do
2909 2935 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2910 2936 :issue => {:project_id => '1', :tracker_id => '3',
2911 2937 :status_id => '1', :subject => 'Copy'}
2912 2938 end
2913 2939 end
2914 2940 copy = Issue.order('id DESC').first
2915 2941 assert_equal 1, copy.relations.size
2916 2942 end
2917 2943
2918 2944 def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
2919 2945 @request.session[:user_id] = 2
2920 2946 assert_difference 'Issue.count' do
2921 2947 assert_no_difference 'IssueRelation.count' do
2922 2948 post :create, :project_id => 1, :copy_from => 1,
2923 2949 :issue => {:subject => 'Copy'}
2924 2950 end
2925 2951 end
2926 2952 end
2927 2953
2928 2954 def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
2929 2955 with_settings :link_copied_issue => 'yes' do
2930 2956 @request.session[:user_id] = 2
2931 2957 assert_difference 'Issue.count' do
2932 2958 assert_difference 'IssueRelation.count' do
2933 2959 post :create, :project_id => 1, :copy_from => 1,
2934 2960 :issue => {:subject => 'Copy'}
2935 2961 end
2936 2962 end
2937 2963 end
2938 2964 end
2939 2965
2940 2966 def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
2941 2967 with_settings :link_copied_issue => 'no' do
2942 2968 @request.session[:user_id] = 2
2943 2969 assert_difference 'Issue.count' do
2944 2970 assert_no_difference 'IssueRelation.count' do
2945 2971 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2946 2972 :issue => {:subject => 'Copy'}
2947 2973 end
2948 2974 end
2949 2975 end
2950 2976 end
2951 2977
2952 2978 def test_create_as_copy_should_copy_subtasks
2953 2979 @request.session[:user_id] = 2
2954 2980 issue = Issue.generate_with_descendants!
2955 2981 count = issue.descendants.count
2956 2982 assert_difference 'Issue.count', count + 1 do
2957 2983 post :create, :project_id => 1, :copy_from => issue.id,
2958 2984 :issue => {:project_id => '1', :tracker_id => '3',
2959 2985 :status_id => '1', :subject => 'Copy with subtasks'},
2960 2986 :copy_subtasks => '1'
2961 2987 end
2962 2988 copy = Issue.where(:parent_id => nil).order('id DESC').first
2963 2989 assert_equal count, copy.descendants.count
2964 2990 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
2965 2991 end
2966 2992
2967 2993 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
2968 2994 @request.session[:user_id] = 2
2969 2995 issue = Issue.generate_with_descendants!
2970 2996 assert_difference 'Issue.count', 1 do
2971 2997 post :create, :project_id => 1, :copy_from => 3,
2972 2998 :issue => {:project_id => '1', :tracker_id => '3',
2973 2999 :status_id => '1', :subject => 'Copy with subtasks'}
2974 3000 end
2975 3001 copy = Issue.where(:parent_id => nil).order('id DESC').first
2976 3002 assert_equal 0, copy.descendants.count
2977 3003 end
2978 3004
2979 3005 def test_create_as_copy_with_failure
2980 3006 @request.session[:user_id] = 2
2981 3007 post :create, :project_id => 1, :copy_from => 1,
2982 3008 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
2983 3009
2984 3010 assert_response :success
2985 3011 assert_template 'new'
2986 3012
2987 3013 assert_not_nil assigns(:issue)
2988 3014 assert assigns(:issue).copy?
2989 3015
2990 3016 assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
2991 3017 assert_select 'select[name=?]', 'issue[project_id]' do
2992 3018 assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
2993 3019 assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
2994 3020 end
2995 3021 assert_select 'input[name=copy_from][value="1"]'
2996 3022 end
2997 3023 end
2998 3024
2999 3025 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
3000 3026 @request.session[:user_id] = 2
3001 3027 assert !User.find(2).member_of?(Project.find(4))
3002 3028
3003 3029 assert_difference 'Issue.count' do
3004 3030 post :create, :project_id => 1, :copy_from => 1,
3005 3031 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
3006 3032 end
3007 3033 issue = Issue.order('id DESC').first
3008 3034 assert_equal 1, issue.project_id
3009 3035 end
3010 3036
3011 3037 def test_get_edit
3012 3038 @request.session[:user_id] = 2
3013 3039 get :edit, :id => 1
3014 3040 assert_response :success
3015 3041 assert_template 'edit'
3016 3042 assert_not_nil assigns(:issue)
3017 3043 assert_equal Issue.find(1), assigns(:issue)
3018 3044
3019 3045 # Be sure we don't display inactive IssuePriorities
3020 3046 assert ! IssuePriority.find(15).active?
3021 3047 assert_select 'select[name=?]', 'issue[priority_id]' do
3022 3048 assert_select 'option[value="15"]', 0
3023 3049 end
3024 3050 end
3025 3051
3026 3052 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
3027 3053 @request.session[:user_id] = 2
3028 3054 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
3029 3055
3030 3056 get :edit, :id => 1
3031 3057 assert_select 'input[name=?]', 'time_entry[hours]'
3032 3058 end
3033 3059
3034 3060 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
3035 3061 @request.session[:user_id] = 2
3036 3062 Role.find_by_name('Manager').remove_permission! :log_time
3037 3063
3038 3064 get :edit, :id => 1
3039 3065 assert_select 'input[name=?]', 'time_entry[hours]', 0
3040 3066 end
3041 3067
3042 3068 def test_get_edit_with_params
3043 3069 @request.session[:user_id] = 2
3044 3070 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
3045 3071 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
3046 3072 assert_response :success
3047 3073 assert_template 'edit'
3048 3074
3049 3075 issue = assigns(:issue)
3050 3076 assert_not_nil issue
3051 3077
3052 3078 assert_equal 5, issue.status_id
3053 3079 assert_select 'select[name=?]', 'issue[status_id]' do
3054 3080 assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
3055 3081 end
3056 3082
3057 3083 assert_equal 7, issue.priority_id
3058 3084 assert_select 'select[name=?]', 'issue[priority_id]' do
3059 3085 assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
3060 3086 end
3061 3087
3062 3088 assert_select 'input[name=?][value="2.5"]', 'time_entry[hours]'
3063 3089 assert_select 'select[name=?]', 'time_entry[activity_id]' do
3064 3090 assert_select 'option[value="10"][selected=selected]', :text => 'Development'
3065 3091 end
3066 3092 assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
3067 3093 end
3068 3094
3069 3095 def test_get_edit_with_multi_custom_field
3070 3096 field = CustomField.find(1)
3071 3097 field.update_attribute :multiple, true
3072 3098 issue = Issue.find(1)
3073 3099 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3074 3100 issue.save!
3075 3101
3076 3102 @request.session[:user_id] = 2
3077 3103 get :edit, :id => 1
3078 3104 assert_response :success
3079 3105 assert_template 'edit'
3080 3106
3081 3107 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
3082 3108 assert_select 'option', 3
3083 3109 assert_select 'option[value=MySQL][selected=selected]'
3084 3110 assert_select 'option[value=Oracle][selected=selected]'
3085 3111 assert_select 'option[value=PostgreSQL]:not([selected])'
3086 3112 end
3087 3113 end
3088 3114
3089 3115 def test_update_form_for_existing_issue
3090 3116 @request.session[:user_id] = 2
3091 3117 xhr :patch, :edit, :id => 1,
3092 3118 :issue => {:tracker_id => 2,
3093 3119 :subject => 'This is the test_new issue',
3094 3120 :description => 'This is the description',
3095 3121 :priority_id => 5}
3096 3122 assert_response :success
3097 3123 assert_equal 'text/javascript', response.content_type
3098 3124 assert_template 'edit'
3099 3125 assert_template :partial => '_form'
3100 3126
3101 3127 issue = assigns(:issue)
3102 3128 assert_kind_of Issue, issue
3103 3129 assert_equal 1, issue.id
3104 3130 assert_equal 1, issue.project_id
3105 3131 assert_equal 2, issue.tracker_id
3106 3132 assert_equal 'This is the test_new issue', issue.subject
3107 3133 end
3108 3134
3109 3135 def test_update_form_for_existing_issue_should_keep_issue_author
3110 3136 @request.session[:user_id] = 3
3111 3137 xhr :patch, :edit, :id => 1, :issue => {:subject => 'Changed'}
3112 3138 assert_response :success
3113 3139 assert_equal 'text/javascript', response.content_type
3114 3140
3115 3141 issue = assigns(:issue)
3116 3142 assert_equal User.find(2), issue.author
3117 3143 assert_equal 2, issue.author_id
3118 3144 assert_not_equal User.current, issue.author
3119 3145 end
3120 3146
3121 3147 def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
3122 3148 @request.session[:user_id] = 2
3123 3149 WorkflowTransition.delete_all
3124 3150 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3125 3151 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3126 3152 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
3127 3153
3128 3154 xhr :patch, :edit, :id => 2,
3129 3155 :issue => {:tracker_id => 2,
3130 3156 :status_id => 5,
3131 3157 :subject => 'This is an issue'}
3132 3158
3133 3159 assert_equal 5, assigns(:issue).status_id
3134 3160 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
3135 3161 end
3136 3162
3137 3163 def test_update_form_for_existing_issue_with_project_change
3138 3164 @request.session[:user_id] = 2
3139 3165 xhr :patch, :edit, :id => 1,
3140 3166 :issue => {:project_id => 2,
3141 3167 :tracker_id => 2,
3142 3168 :subject => 'This is the test_new issue',
3143 3169 :description => 'This is the description',
3144 3170 :priority_id => 5}
3145 3171 assert_response :success
3146 3172 assert_template :partial => '_form'
3147 3173
3148 3174 issue = assigns(:issue)
3149 3175 assert_kind_of Issue, issue
3150 3176 assert_equal 1, issue.id
3151 3177 assert_equal 2, issue.project_id
3152 3178 assert_equal 2, issue.tracker_id
3153 3179 assert_equal 'This is the test_new issue', issue.subject
3154 3180 end
3155 3181
3156 3182 def test_update_form_should_keep_category_with_same_when_changing_project
3157 3183 source = Project.generate!
3158 3184 target = Project.generate!
3159 3185 source_category = IssueCategory.create!(:name => 'Foo', :project => source)
3160 3186 target_category = IssueCategory.create!(:name => 'Foo', :project => target)
3161 3187 issue = Issue.generate!(:project => source, :category => source_category)
3162 3188
3163 3189 @request.session[:user_id] = 1
3164 3190 patch :edit, :id => issue.id,
3165 3191 :issue => {:project_id => target.id, :category_id => source_category.id}
3166 3192 assert_response :success
3167 3193
3168 3194 issue = assigns(:issue)
3169 3195 assert_equal target_category, issue.category
3170 3196 end
3171 3197
3172 3198 def test_update_form_should_propose_default_status_for_existing_issue
3173 3199 @request.session[:user_id] = 2
3174 3200 WorkflowTransition.delete_all
3175 3201 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3176 3202
3177 3203 xhr :patch, :edit, :id => 2
3178 3204 assert_response :success
3179 3205 assert_equal [2,3], assigns(:allowed_statuses).map(&:id).sort
3180 3206 end
3181 3207
3182 3208 def test_put_update_without_custom_fields_param
3183 3209 @request.session[:user_id] = 2
3184 3210
3185 3211 issue = Issue.find(1)
3186 3212 assert_equal '125', issue.custom_value_for(2).value
3187 3213
3188 3214 assert_difference('Journal.count') do
3189 3215 assert_difference('JournalDetail.count') do
3190 3216 put :update, :id => 1, :issue => {:subject => 'New subject'}
3191 3217 end
3192 3218 end
3193 3219 assert_redirected_to :action => 'show', :id => '1'
3194 3220 issue.reload
3195 3221 assert_equal 'New subject', issue.subject
3196 3222 # Make sure custom fields were not cleared
3197 3223 assert_equal '125', issue.custom_value_for(2).value
3198 3224 end
3199 3225
3200 3226 def test_put_update_with_project_change
3201 3227 @request.session[:user_id] = 2
3202 3228 ActionMailer::Base.deliveries.clear
3203 3229
3204 3230 with_settings :notified_events => %w(issue_updated) do
3205 3231 assert_difference('Journal.count') do
3206 3232 assert_difference('JournalDetail.count', 3) do
3207 3233 put :update, :id => 1, :issue => {:project_id => '2',
3208 3234 :tracker_id => '1', # no change
3209 3235 :priority_id => '6',
3210 3236 :category_id => '3'
3211 3237 }
3212 3238 end
3213 3239 end
3214 3240 end
3215 3241 assert_redirected_to :action => 'show', :id => '1'
3216 3242 issue = Issue.find(1)
3217 3243 assert_equal 2, issue.project_id
3218 3244 assert_equal 1, issue.tracker_id
3219 3245 assert_equal 6, issue.priority_id
3220 3246 assert_equal 3, issue.category_id
3221 3247
3222 3248 mail = ActionMailer::Base.deliveries.last
3223 3249 assert_not_nil mail
3224 3250 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3225 3251 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
3226 3252 end
3227 3253
3228 3254 def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
3229 3255 target = Project.generate!(:tracker_ids => [])
3230 3256 assert target.trackers.empty?
3231 3257 issue = Issue.generate!
3232 3258 @request.session[:user_id] = 1
3233 3259
3234 3260 put :update, :id => issue.id, :issue => {:project_id => target.id}
3235 3261 assert_response 302
3236 3262 end
3237 3263
3238 3264 def test_put_update_with_tracker_change
3239 3265 @request.session[:user_id] = 2
3240 3266 ActionMailer::Base.deliveries.clear
3241 3267
3242 3268 with_settings :notified_events => %w(issue_updated) do
3243 3269 assert_difference('Journal.count') do
3244 3270 assert_difference('JournalDetail.count', 2) do
3245 3271 put :update, :id => 1, :issue => {:project_id => '1',
3246 3272 :tracker_id => '2',
3247 3273 :priority_id => '6'
3248 3274 }
3249 3275 end
3250 3276 end
3251 3277 end
3252 3278 assert_redirected_to :action => 'show', :id => '1'
3253 3279 issue = Issue.find(1)
3254 3280 assert_equal 1, issue.project_id
3255 3281 assert_equal 2, issue.tracker_id
3256 3282 assert_equal 6, issue.priority_id
3257 3283 assert_equal 1, issue.category_id
3258 3284
3259 3285 mail = ActionMailer::Base.deliveries.last
3260 3286 assert_not_nil mail
3261 3287 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3262 3288 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
3263 3289 end
3264 3290
3265 3291 def test_put_update_with_custom_field_change
3266 3292 @request.session[:user_id] = 2
3267 3293 issue = Issue.find(1)
3268 3294 assert_equal '125', issue.custom_value_for(2).value
3269 3295
3270 3296 with_settings :notified_events => %w(issue_updated) do
3271 3297 assert_difference('Journal.count') do
3272 3298 assert_difference('JournalDetail.count', 3) do
3273 3299 put :update, :id => 1, :issue => {:subject => 'Custom field change',
3274 3300 :priority_id => '6',
3275 3301 :category_id => '1', # no change
3276 3302 :custom_field_values => { '2' => 'New custom value' }
3277 3303 }
3278 3304 end
3279 3305 end
3280 3306 end
3281 3307 assert_redirected_to :action => 'show', :id => '1'
3282 3308 issue.reload
3283 3309 assert_equal 'New custom value', issue.custom_value_for(2).value
3284 3310
3285 3311 mail = ActionMailer::Base.deliveries.last
3286 3312 assert_not_nil mail
3287 3313 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
3288 3314 end
3289 3315
3290 3316 def test_put_update_with_multi_custom_field_change
3291 3317 field = CustomField.find(1)
3292 3318 field.update_attribute :multiple, true
3293 3319 issue = Issue.find(1)
3294 3320 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3295 3321 issue.save!
3296 3322
3297 3323 @request.session[:user_id] = 2
3298 3324 assert_difference('Journal.count') do
3299 3325 assert_difference('JournalDetail.count', 3) do
3300 3326 put :update, :id => 1,
3301 3327 :issue => {
3302 3328 :subject => 'Custom field change',
3303 3329 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
3304 3330 }
3305 3331 end
3306 3332 end
3307 3333 assert_redirected_to :action => 'show', :id => '1'
3308 3334 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
3309 3335 end
3310 3336
3311 3337 def test_put_update_with_status_and_assignee_change
3312 3338 issue = Issue.find(1)
3313 3339 assert_equal 1, issue.status_id
3314 3340 @request.session[:user_id] = 2
3315 3341
3316 3342 with_settings :notified_events => %w(issue_updated) do
3317 3343 assert_difference('TimeEntry.count', 0) do
3318 3344 put :update,
3319 3345 :id => 1,
3320 3346 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
3321 3347 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
3322 3348 end
3323 3349 end
3324 3350 assert_redirected_to :action => 'show', :id => '1'
3325 3351 issue.reload
3326 3352 assert_equal 2, issue.status_id
3327 3353 j = Journal.order('id DESC').first
3328 3354 assert_equal 'Assigned to dlopper', j.notes
3329 3355 assert_equal 2, j.details.size
3330 3356
3331 3357 mail = ActionMailer::Base.deliveries.last
3332 3358 assert_mail_body_match "Status changed from New to Assigned", mail
3333 3359 # subject should contain the new status
3334 3360 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
3335 3361 end
3336 3362
3337 3363 def test_put_update_with_note_only
3338 3364 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
3339 3365
3340 3366 with_settings :notified_events => %w(issue_updated) do
3341 3367 # anonymous user
3342 3368 put :update,
3343 3369 :id => 1,
3344 3370 :issue => { :notes => notes }
3345 3371 end
3346 3372 assert_redirected_to :action => 'show', :id => '1'
3347 3373 j = Journal.order('id DESC').first
3348 3374 assert_equal notes, j.notes
3349 3375 assert_equal 0, j.details.size
3350 3376 assert_equal User.anonymous, j.user
3351 3377
3352 3378 mail = ActionMailer::Base.deliveries.last
3353 3379 assert_mail_body_match notes, mail
3354 3380 end
3355 3381
3356 3382 def test_put_update_with_private_note_only
3357 3383 notes = 'Private note'
3358 3384 @request.session[:user_id] = 2
3359 3385
3360 3386 assert_difference 'Journal.count' do
3361 3387 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
3362 3388 assert_redirected_to :action => 'show', :id => '1'
3363 3389 end
3364 3390
3365 3391 j = Journal.order('id DESC').first
3366 3392 assert_equal notes, j.notes
3367 3393 assert_equal true, j.private_notes
3368 3394 end
3369 3395
3370 3396 def test_put_update_with_private_note_and_changes
3371 3397 notes = 'Private note'
3372 3398 @request.session[:user_id] = 2
3373 3399
3374 3400 assert_difference 'Journal.count', 2 do
3375 3401 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
3376 3402 assert_redirected_to :action => 'show', :id => '1'
3377 3403 end
3378 3404
3379 3405 j = Journal.order('id DESC').first
3380 3406 assert_equal notes, j.notes
3381 3407 assert_equal true, j.private_notes
3382 3408 assert_equal 0, j.details.count
3383 3409
3384 3410 j = Journal.order('id DESC').offset(1).first
3385 3411 assert_nil j.notes
3386 3412 assert_equal false, j.private_notes
3387 3413 assert_equal 1, j.details.count
3388 3414 end
3389 3415
3390 3416 def test_put_update_with_note_and_spent_time
3391 3417 @request.session[:user_id] = 2
3392 3418 spent_hours_before = Issue.find(1).spent_hours
3393 3419 assert_difference('TimeEntry.count') do
3394 3420 put :update,
3395 3421 :id => 1,
3396 3422 :issue => { :notes => '2.5 hours added' },
3397 3423 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
3398 3424 end
3399 3425 assert_redirected_to :action => 'show', :id => '1'
3400 3426
3401 3427 issue = Issue.find(1)
3402 3428
3403 3429 j = Journal.order('id DESC').first
3404 3430 assert_equal '2.5 hours added', j.notes
3405 3431 assert_equal 0, j.details.size
3406 3432
3407 3433 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
3408 3434 assert_not_nil t
3409 3435 assert_equal 2.5, t.hours
3410 3436 assert_equal spent_hours_before + 2.5, issue.spent_hours
3411 3437 end
3412 3438
3413 3439 def test_put_update_should_preserve_parent_issue_even_if_not_visible
3414 3440 parent = Issue.generate!(:project_id => 1, :is_private => true)
3415 3441 issue = Issue.generate!(:parent_issue_id => parent.id)
3416 3442 assert !parent.visible?(User.find(3))
3417 3443 @request.session[:user_id] = 3
3418 3444
3419 3445 get :edit, :id => issue.id
3420 3446 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
3421 3447
3422 3448 put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
3423 3449 assert_response 302
3424 3450 assert_equal parent, issue.parent
3425 3451 end
3426 3452
3427 3453 def test_put_update_with_attachment_only
3428 3454 set_tmp_attachments_directory
3429 3455
3430 3456 # Delete all fixtured journals, a race condition can occur causing the wrong
3431 3457 # journal to get fetched in the next find.
3432 3458 Journal.delete_all
3433 3459
3434 3460 with_settings :notified_events => %w(issue_updated) do
3435 3461 # anonymous user
3436 3462 assert_difference 'Attachment.count' do
3437 3463 put :update, :id => 1,
3438 3464 :issue => {:notes => ''},
3439 3465 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3440 3466 end
3441 3467 end
3442 3468
3443 3469 assert_redirected_to :action => 'show', :id => '1'
3444 3470 j = Issue.find(1).journals.reorder('id DESC').first
3445 3471 assert j.notes.blank?
3446 3472 assert_equal 1, j.details.size
3447 3473 assert_equal 'testfile.txt', j.details.first.value
3448 3474 assert_equal User.anonymous, j.user
3449 3475
3450 3476 attachment = Attachment.order('id DESC').first
3451 3477 assert_equal Issue.find(1), attachment.container
3452 3478 assert_equal User.anonymous, attachment.author
3453 3479 assert_equal 'testfile.txt', attachment.filename
3454 3480 assert_equal 'text/plain', attachment.content_type
3455 3481 assert_equal 'test file', attachment.description
3456 3482 assert_equal 59, attachment.filesize
3457 3483 assert File.exists?(attachment.diskfile)
3458 3484 assert_equal 59, File.size(attachment.diskfile)
3459 3485
3460 3486 mail = ActionMailer::Base.deliveries.last
3461 3487 assert_mail_body_match 'testfile.txt', mail
3462 3488 end
3463 3489
3464 3490 def test_put_update_with_failure_should_save_attachments
3465 3491 set_tmp_attachments_directory
3466 3492 @request.session[:user_id] = 2
3467 3493
3468 3494 assert_no_difference 'Journal.count' do
3469 3495 assert_difference 'Attachment.count' do
3470 3496 put :update, :id => 1,
3471 3497 :issue => { :subject => '' },
3472 3498 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3473 3499 assert_response :success
3474 3500 assert_template 'edit'
3475 3501 end
3476 3502 end
3477 3503
3478 3504 attachment = Attachment.order('id DESC').first
3479 3505 assert_equal 'testfile.txt', attachment.filename
3480 3506 assert File.exists?(attachment.diskfile)
3481 3507 assert_nil attachment.container
3482 3508
3483 3509 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3484 3510 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3485 3511 end
3486 3512
3487 3513 def test_put_update_with_failure_should_keep_saved_attachments
3488 3514 set_tmp_attachments_directory
3489 3515 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3490 3516 @request.session[:user_id] = 2
3491 3517
3492 3518 assert_no_difference 'Journal.count' do
3493 3519 assert_no_difference 'Attachment.count' do
3494 3520 put :update, :id => 1,
3495 3521 :issue => { :subject => '' },
3496 3522 :attachments => {'p0' => {'token' => attachment.token}}
3497 3523 assert_response :success
3498 3524 assert_template 'edit'
3499 3525 end
3500 3526 end
3501 3527
3502 3528 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3503 3529 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3504 3530 end
3505 3531
3506 3532 def test_put_update_should_attach_saved_attachments
3507 3533 set_tmp_attachments_directory
3508 3534 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3509 3535 @request.session[:user_id] = 2
3510 3536
3511 3537 assert_difference 'Journal.count' do
3512 3538 assert_difference 'JournalDetail.count' do
3513 3539 assert_no_difference 'Attachment.count' do
3514 3540 put :update, :id => 1,
3515 3541 :issue => {:notes => 'Attachment added'},
3516 3542 :attachments => {'p0' => {'token' => attachment.token}}
3517 3543 assert_redirected_to '/issues/1'
3518 3544 end
3519 3545 end
3520 3546 end
3521 3547
3522 3548 attachment.reload
3523 3549 assert_equal Issue.find(1), attachment.container
3524 3550
3525 3551 journal = Journal.order('id DESC').first
3526 3552 assert_equal 1, journal.details.size
3527 3553 assert_equal 'testfile.txt', journal.details.first.value
3528 3554 end
3529 3555
3530 3556 def test_put_update_with_attachment_that_fails_to_save
3531 3557 set_tmp_attachments_directory
3532 3558
3533 3559 # anonymous user
3534 3560 with_settings :attachment_max_size => 0 do
3535 3561 put :update,
3536 3562 :id => 1,
3537 3563 :issue => {:notes => ''},
3538 3564 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3539 3565 assert_redirected_to :action => 'show', :id => '1'
3540 3566 assert_equal '1 file(s) could not be saved.', flash[:warning]
3541 3567 end
3542 3568 end
3543 3569
3544 3570 def test_put_update_with_no_change
3545 3571 issue = Issue.find(1)
3546 3572 issue.journals.clear
3547 3573 ActionMailer::Base.deliveries.clear
3548 3574
3549 3575 put :update,
3550 3576 :id => 1,
3551 3577 :issue => {:notes => ''}
3552 3578 assert_redirected_to :action => 'show', :id => '1'
3553 3579
3554 3580 issue.reload
3555 3581 assert issue.journals.empty?
3556 3582 # No email should be sent
3557 3583 assert ActionMailer::Base.deliveries.empty?
3558 3584 end
3559 3585
3560 3586 def test_put_update_should_send_a_notification
3561 3587 @request.session[:user_id] = 2
3562 3588 ActionMailer::Base.deliveries.clear
3563 3589 issue = Issue.find(1)
3564 3590 old_subject = issue.subject
3565 3591 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3566 3592
3567 3593 with_settings :notified_events => %w(issue_updated) do
3568 3594 put :update, :id => 1, :issue => {:subject => new_subject,
3569 3595 :priority_id => '6',
3570 3596 :category_id => '1' # no change
3571 3597 }
3572 3598 assert_equal 1, ActionMailer::Base.deliveries.size
3573 3599 end
3574 3600 end
3575 3601
3576 3602 def test_put_update_with_invalid_spent_time_hours_only
3577 3603 @request.session[:user_id] = 2
3578 3604 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3579 3605
3580 3606 assert_no_difference('Journal.count') do
3581 3607 put :update,
3582 3608 :id => 1,
3583 3609 :issue => {:notes => notes},
3584 3610 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3585 3611 end
3586 3612 assert_response :success
3587 3613 assert_template 'edit'
3588 3614
3589 3615 assert_select_error /Activity cannot be blank/
3590 3616 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3591 3617 assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
3592 3618 end
3593 3619
3594 3620 def test_put_update_with_invalid_spent_time_comments_only
3595 3621 @request.session[:user_id] = 2
3596 3622 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3597 3623
3598 3624 assert_no_difference('Journal.count') do
3599 3625 put :update,
3600 3626 :id => 1,
3601 3627 :issue => {:notes => notes},
3602 3628 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3603 3629 end
3604 3630 assert_response :success
3605 3631 assert_template 'edit'
3606 3632
3607 3633 assert_select_error /Activity cannot be blank/
3608 3634 assert_select_error /Hours cannot be blank/
3609 3635 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3610 3636 assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
3611 3637 end
3612 3638
3613 3639 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3614 3640 issue = Issue.find(2)
3615 3641 @request.session[:user_id] = 2
3616 3642
3617 3643 put :update,
3618 3644 :id => issue.id,
3619 3645 :issue => {
3620 3646 :fixed_version_id => 4
3621 3647 }
3622 3648
3623 3649 assert_response :redirect
3624 3650 issue.reload
3625 3651 assert_equal 4, issue.fixed_version_id
3626 3652 assert_not_equal issue.project_id, issue.fixed_version.project_id
3627 3653 end
3628 3654
3629 3655 def test_put_update_should_redirect_back_using_the_back_url_parameter
3630 3656 issue = Issue.find(2)
3631 3657 @request.session[:user_id] = 2
3632 3658
3633 3659 put :update,
3634 3660 :id => issue.id,
3635 3661 :issue => {
3636 3662 :fixed_version_id => 4
3637 3663 },
3638 3664 :back_url => '/issues'
3639 3665
3640 3666 assert_response :redirect
3641 3667 assert_redirected_to '/issues'
3642 3668 end
3643 3669
3644 3670 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3645 3671 issue = Issue.find(2)
3646 3672 @request.session[:user_id] = 2
3647 3673
3648 3674 put :update,
3649 3675 :id => issue.id,
3650 3676 :issue => {
3651 3677 :fixed_version_id => 4
3652 3678 },
3653 3679 :back_url => 'http://google.com'
3654 3680
3655 3681 assert_response :redirect
3656 3682 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3657 3683 end
3658 3684
3659 3685 def test_get_bulk_edit
3660 3686 @request.session[:user_id] = 2
3661 3687 get :bulk_edit, :ids => [1, 3]
3662 3688 assert_response :success
3663 3689 assert_template 'bulk_edit'
3664 3690
3665 3691 assert_select 'ul#bulk-selection' do
3666 3692 assert_select 'li', 2
3667 3693 assert_select 'li a', :text => 'Bug #1'
3668 3694 end
3669 3695
3670 3696 assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
3671 3697 assert_select 'input[name=?]', 'ids[]', 2
3672 3698 assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
3673 3699
3674 3700 assert_select 'select[name=?]', 'issue[project_id]'
3675 3701 assert_select 'input[name=?]', 'issue[parent_issue_id]'
3676 3702
3677 3703 # Project specific custom field, date type
3678 3704 field = CustomField.find(9)
3679 3705 assert !field.is_for_all?
3680 3706 assert_equal 'date', field.field_format
3681 3707 assert_select 'input[name=?]', 'issue[custom_field_values][9]'
3682 3708
3683 3709 # System wide custom field
3684 3710 assert CustomField.find(1).is_for_all?
3685 3711 assert_select 'select[name=?]', 'issue[custom_field_values][1]'
3686 3712
3687 3713 # Be sure we don't display inactive IssuePriorities
3688 3714 assert ! IssuePriority.find(15).active?
3689 3715 assert_select 'select[name=?]', 'issue[priority_id]' do
3690 3716 assert_select 'option[value="15"]', 0
3691 3717 end
3692 3718 end
3693 3719 end
3694 3720
3695 3721 def test_get_bulk_edit_on_different_projects
3696 3722 @request.session[:user_id] = 2
3697 3723 get :bulk_edit, :ids => [1, 2, 6]
3698 3724 assert_response :success
3699 3725 assert_template 'bulk_edit'
3700 3726
3701 3727 # Can not set issues from different projects as children of an issue
3702 3728 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
3703 3729
3704 3730 # Project specific custom field, date type
3705 3731 field = CustomField.find(9)
3706 3732 assert !field.is_for_all?
3707 3733 assert !field.project_ids.include?(Issue.find(6).project_id)
3708 3734 assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
3709 3735 end
3710 3736
3711 3737 def test_get_bulk_edit_with_user_custom_field
3712 3738 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
3713 3739
3714 3740 @request.session[:user_id] = 2
3715 3741 get :bulk_edit, :ids => [1, 2]
3716 3742 assert_response :success
3717 3743 assert_template 'bulk_edit'
3718 3744
3719 3745 assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3720 3746 assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
3721 3747 end
3722 3748 end
3723 3749
3724 3750 def test_get_bulk_edit_with_version_custom_field
3725 3751 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
3726 3752
3727 3753 @request.session[:user_id] = 2
3728 3754 get :bulk_edit, :ids => [1, 2]
3729 3755 assert_response :success
3730 3756 assert_template 'bulk_edit'
3731 3757
3732 3758 assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3733 3759 assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3734 3760 end
3735 3761 end
3736 3762
3737 3763 def test_get_bulk_edit_with_multi_custom_field
3738 3764 field = CustomField.find(1)
3739 3765 field.update_attribute :multiple, true
3740 3766
3741 3767 @request.session[:user_id] = 2
3742 3768 get :bulk_edit, :ids => [1, 3]
3743 3769 assert_response :success
3744 3770 assert_template 'bulk_edit'
3745 3771
3746 3772 assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
3747 3773 assert_select 'option', field.possible_values.size + 1 # "none" options
3748 3774 end
3749 3775 end
3750 3776
3751 3777 def test_bulk_edit_should_propose_to_clear_text_custom_fields
3752 3778 @request.session[:user_id] = 2
3753 3779 get :bulk_edit, :ids => [1, 3]
3754 3780 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
3755 3781 end
3756 3782
3757 3783 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3758 3784 WorkflowTransition.delete_all
3759 3785 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3760 3786 :old_status_id => 1, :new_status_id => 1)
3761 3787 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3762 3788 :old_status_id => 1, :new_status_id => 3)
3763 3789 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3764 3790 :old_status_id => 1, :new_status_id => 4)
3765 3791 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3766 3792 :old_status_id => 2, :new_status_id => 1)
3767 3793 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3768 3794 :old_status_id => 2, :new_status_id => 3)
3769 3795 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3770 3796 :old_status_id => 2, :new_status_id => 5)
3771 3797 @request.session[:user_id] = 2
3772 3798 get :bulk_edit, :ids => [1, 2]
3773 3799
3774 3800 assert_response :success
3775 3801 statuses = assigns(:available_statuses)
3776 3802 assert_not_nil statuses
3777 3803 assert_equal [1, 3], statuses.map(&:id).sort
3778 3804
3779 3805 assert_select 'select[name=?]', 'issue[status_id]' do
3780 3806 assert_select 'option', 3 # 2 statuses + "no change" option
3781 3807 end
3782 3808 end
3783 3809
3784 3810 def test_bulk_edit_should_propose_target_project_open_shared_versions
3785 3811 @request.session[:user_id] = 2
3786 3812 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3787 3813 assert_response :success
3788 3814 assert_template 'bulk_edit'
3789 3815 assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort
3790 3816
3791 3817 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
3792 3818 assert_select 'option', :text => '2.0'
3793 3819 end
3794 3820 end
3795 3821
3796 3822 def test_bulk_edit_should_propose_target_project_categories
3797 3823 @request.session[:user_id] = 2
3798 3824 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3799 3825 assert_response :success
3800 3826 assert_template 'bulk_edit'
3801 3827 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3802 3828
3803 3829 assert_select 'select[name=?]', 'issue[category_id]' do
3804 3830 assert_select 'option', :text => 'Recipes'
3805 3831 end
3806 3832 end
3807 3833
3808 3834 def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
3809 3835 IssueCustomField.delete_all
3810 3836 field = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
3811 3837 IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
3812 3838 @request.session[:user_id] = 2
3813 3839
3814 3840 issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
3815 3841 get :bulk_edit, :ids => issue_ids
3816 3842 assert_equal [field], assigns(:custom_fields)
3817 3843 end
3818 3844
3819 3845 def test_bulk_update
3820 3846 @request.session[:user_id] = 2
3821 3847 # update issues priority
3822 3848 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3823 3849 :issue => {:priority_id => 7,
3824 3850 :assigned_to_id => '',
3825 3851 :custom_field_values => {'2' => ''}}
3826 3852
3827 3853 assert_response 302
3828 3854 # check that the issues were updated
3829 3855 assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
3830 3856
3831 3857 issue = Issue.find(1)
3832 3858 journal = issue.journals.reorder('created_on DESC').first
3833 3859 assert_equal '125', issue.custom_value_for(2).value
3834 3860 assert_equal 'Bulk editing', journal.notes
3835 3861 assert_equal 1, journal.details.size
3836 3862 end
3837 3863
3838 3864 def test_bulk_update_with_group_assignee
3839 3865 group = Group.find(11)
3840 3866 project = Project.find(1)
3841 3867 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3842 3868
3843 3869 @request.session[:user_id] = 2
3844 3870 # update issues assignee
3845 3871 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3846 3872 :issue => {:priority_id => '',
3847 3873 :assigned_to_id => group.id,
3848 3874 :custom_field_values => {'2' => ''}}
3849 3875
3850 3876 assert_response 302
3851 3877 assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
3852 3878 end
3853 3879
3854 3880 def test_bulk_update_on_different_projects
3855 3881 @request.session[:user_id] = 2
3856 3882 # update issues priority
3857 3883 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3858 3884 :issue => {:priority_id => 7,
3859 3885 :assigned_to_id => '',
3860 3886 :custom_field_values => {'2' => ''}}
3861 3887
3862 3888 assert_response 302
3863 3889 # check that the issues were updated
3864 3890 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3865 3891
3866 3892 issue = Issue.find(1)
3867 3893 journal = issue.journals.reorder('created_on DESC').first
3868 3894 assert_equal '125', issue.custom_value_for(2).value
3869 3895 assert_equal 'Bulk editing', journal.notes
3870 3896 assert_equal 1, journal.details.size
3871 3897 end
3872 3898
3873 3899 def test_bulk_update_on_different_projects_without_rights
3874 3900 @request.session[:user_id] = 3
3875 3901 user = User.find(3)
3876 3902 action = { :controller => "issues", :action => "bulk_update" }
3877 3903 assert user.allowed_to?(action, Issue.find(1).project)
3878 3904 assert ! user.allowed_to?(action, Issue.find(6).project)
3879 3905 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3880 3906 :issue => {:priority_id => 7,
3881 3907 :assigned_to_id => '',
3882 3908 :custom_field_values => {'2' => ''}}
3883 3909 assert_response 403
3884 3910 assert_not_equal "Bulk should fail", Journal.last.notes
3885 3911 end
3886 3912
3887 3913 def test_bullk_update_should_send_a_notification
3888 3914 @request.session[:user_id] = 2
3889 3915 ActionMailer::Base.deliveries.clear
3890 3916 with_settings :notified_events => %w(issue_updated) do
3891 3917 post(:bulk_update,
3892 3918 {
3893 3919 :ids => [1, 2],
3894 3920 :notes => 'Bulk editing',
3895 3921 :issue => {
3896 3922 :priority_id => 7,
3897 3923 :assigned_to_id => '',
3898 3924 :custom_field_values => {'2' => ''}
3899 3925 }
3900 3926 })
3901 3927 assert_response 302
3902 3928 assert_equal 2, ActionMailer::Base.deliveries.size
3903 3929 end
3904 3930 end
3905 3931
3906 3932 def test_bulk_update_project
3907 3933 @request.session[:user_id] = 2
3908 3934 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3909 3935 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3910 3936 # Issues moved to project 2
3911 3937 assert_equal 2, Issue.find(1).project_id
3912 3938 assert_equal 2, Issue.find(2).project_id
3913 3939 # No tracker change
3914 3940 assert_equal 1, Issue.find(1).tracker_id
3915 3941 assert_equal 2, Issue.find(2).tracker_id
3916 3942 end
3917 3943
3918 3944 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3919 3945 @request.session[:user_id] = 2
3920 3946 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3921 3947 assert_redirected_to '/issues/1'
3922 3948 end
3923 3949
3924 3950 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3925 3951 @request.session[:user_id] = 2
3926 3952 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3927 3953 assert_redirected_to '/projects/onlinestore/issues'
3928 3954 end
3929 3955
3930 3956 def test_bulk_update_tracker
3931 3957 @request.session[:user_id] = 2
3932 3958 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3933 3959 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3934 3960 assert_equal 2, Issue.find(1).tracker_id
3935 3961 assert_equal 2, Issue.find(2).tracker_id
3936 3962 end
3937 3963
3938 3964 def test_bulk_update_status
3939 3965 @request.session[:user_id] = 2
3940 3966 # update issues priority
3941 3967 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
3942 3968 :issue => {:priority_id => '',
3943 3969 :assigned_to_id => '',
3944 3970 :status_id => '5'}
3945 3971
3946 3972 assert_response 302
3947 3973 issue = Issue.find(1)
3948 3974 assert issue.closed?
3949 3975 end
3950 3976
3951 3977 def test_bulk_update_priority
3952 3978 @request.session[:user_id] = 2
3953 3979 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3954 3980
3955 3981 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3956 3982 assert_equal 6, Issue.find(1).priority_id
3957 3983 assert_equal 6, Issue.find(2).priority_id
3958 3984 end
3959 3985
3960 3986 def test_bulk_update_with_notes
3961 3987 @request.session[:user_id] = 2
3962 3988 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
3963 3989
3964 3990 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3965 3991 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
3966 3992 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
3967 3993 end
3968 3994
3969 3995 def test_bulk_update_parent_id
3970 3996 IssueRelation.delete_all
3971 3997 @request.session[:user_id] = 2
3972 3998 post :bulk_update, :ids => [1, 3],
3973 3999 :notes => 'Bulk editing parent',
3974 4000 :issue => {:priority_id => '', :assigned_to_id => '',
3975 4001 :status_id => '', :parent_issue_id => '2'}
3976 4002 assert_response 302
3977 4003 parent = Issue.find(2)
3978 4004 assert_equal parent.id, Issue.find(1).parent_id
3979 4005 assert_equal parent.id, Issue.find(3).parent_id
3980 4006 assert_equal [1, 3], parent.children.collect(&:id).sort
3981 4007 end
3982 4008
3983 4009 def test_bulk_update_custom_field
3984 4010 @request.session[:user_id] = 2
3985 4011 # update issues priority
3986 4012 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
3987 4013 :issue => {:priority_id => '',
3988 4014 :assigned_to_id => '',
3989 4015 :custom_field_values => {'2' => '777'}}
3990 4016
3991 4017 assert_response 302
3992 4018
3993 4019 issue = Issue.find(1)
3994 4020 journal = issue.journals.reorder('created_on DESC').first
3995 4021 assert_equal '777', issue.custom_value_for(2).value
3996 4022 assert_equal 1, journal.details.size
3997 4023 assert_equal '125', journal.details.first.old_value
3998 4024 assert_equal '777', journal.details.first.value
3999 4025 end
4000 4026
4001 4027 def test_bulk_update_custom_field_to_blank
4002 4028 @request.session[:user_id] = 2
4003 4029 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
4004 4030 :issue => {:priority_id => '',
4005 4031 :assigned_to_id => '',
4006 4032 :custom_field_values => {'1' => '__none__'}}
4007 4033 assert_response 302
4008 4034 assert_equal '', Issue.find(1).custom_field_value(1)
4009 4035 assert_equal '', Issue.find(3).custom_field_value(1)
4010 4036 end
4011 4037
4012 4038 def test_bulk_update_multi_custom_field
4013 4039 field = CustomField.find(1)
4014 4040 field.update_attribute :multiple, true
4015 4041
4016 4042 @request.session[:user_id] = 2
4017 4043 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
4018 4044 :issue => {:priority_id => '',
4019 4045 :assigned_to_id => '',
4020 4046 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
4021 4047
4022 4048 assert_response 302
4023 4049
4024 4050 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
4025 4051 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
4026 4052 # the custom field is not associated with the issue tracker
4027 4053 assert_nil Issue.find(2).custom_field_value(1)
4028 4054 end
4029 4055
4030 4056 def test_bulk_update_multi_custom_field_to_blank
4031 4057 field = CustomField.find(1)
4032 4058 field.update_attribute :multiple, true
4033 4059
4034 4060 @request.session[:user_id] = 2
4035 4061 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
4036 4062 :issue => {:priority_id => '',
4037 4063 :assigned_to_id => '',
4038 4064 :custom_field_values => {'1' => ['__none__']}}
4039 4065 assert_response 302
4040 4066 assert_equal [''], Issue.find(1).custom_field_value(1)
4041 4067 assert_equal [''], Issue.find(3).custom_field_value(1)
4042 4068 end
4043 4069
4044 4070 def test_bulk_update_unassign
4045 4071 assert_not_nil Issue.find(2).assigned_to
4046 4072 @request.session[:user_id] = 2
4047 4073 # unassign issues
4048 4074 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
4049 4075 assert_response 302
4050 4076 # check that the issues were updated
4051 4077 assert_nil Issue.find(2).assigned_to
4052 4078 end
4053 4079
4054 4080 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
4055 4081 @request.session[:user_id] = 2
4056 4082
4057 4083 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
4058 4084
4059 4085 assert_response :redirect
4060 4086 issues = Issue.find([1,2])
4061 4087 issues.each do |issue|
4062 4088 assert_equal 4, issue.fixed_version_id
4063 4089 assert_not_equal issue.project_id, issue.fixed_version.project_id
4064 4090 end
4065 4091 end
4066 4092
4067 4093 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
4068 4094 @request.session[:user_id] = 2
4069 4095 post :bulk_update, :ids => [1,2], :back_url => '/issues'
4070 4096
4071 4097 assert_response :redirect
4072 4098 assert_redirected_to '/issues'
4073 4099 end
4074 4100
4075 4101 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
4076 4102 @request.session[:user_id] = 2
4077 4103 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
4078 4104
4079 4105 assert_response :redirect
4080 4106 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
4081 4107 end
4082 4108
4083 4109 def test_bulk_update_with_all_failures_should_show_errors
4084 4110 @request.session[:user_id] = 2
4085 4111 post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
4086 4112
4087 4113 assert_response :success
4088 4114 assert_template 'bulk_edit'
4089 4115 assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
4090 4116 assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
4091 4117
4092 4118 assert_equal [1, 2], assigns[:issues].map(&:id)
4093 4119 end
4094 4120
4095 4121 def test_bulk_update_with_some_failures_should_show_errors
4096 4122 issue1 = Issue.generate!(:start_date => '2013-05-12')
4097 4123 issue2 = Issue.generate!(:start_date => '2013-05-15')
4098 4124 issue3 = Issue.generate!
4099 4125 @request.session[:user_id] = 2
4100 4126 post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id],
4101 4127 :issue => {:due_date => '2013-05-01'}
4102 4128 assert_response :success
4103 4129 assert_template 'bulk_edit'
4104 4130 assert_select '#errorExplanation span',
4105 4131 :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
4106 4132 assert_select '#errorExplanation ul li',
4107 4133 :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
4108 4134 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
4109 4135 end
4110 4136
4111 4137 def test_bulk_update_with_failure_should_preserved_form_values
4112 4138 @request.session[:user_id] = 2
4113 4139 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
4114 4140
4115 4141 assert_response :success
4116 4142 assert_template 'bulk_edit'
4117 4143 assert_select 'select[name=?]', 'issue[tracker_id]' do
4118 4144 assert_select 'option[value="2"][selected=selected]'
4119 4145 end
4120 4146 assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
4121 4147 end
4122 4148
4123 4149 def test_get_bulk_copy
4124 4150 @request.session[:user_id] = 2
4125 4151 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4126 4152 assert_response :success
4127 4153 assert_template 'bulk_edit'
4128 4154
4129 4155 issues = assigns(:issues)
4130 4156 assert_not_nil issues
4131 4157 assert_equal [1, 2, 3], issues.map(&:id).sort
4132 4158
4133 4159 assert_select 'select[name=?]', 'issue[project_id]' do
4134 4160 assert_select 'option[value=""]'
4135 4161 end
4136 4162 assert_select 'input[name=copy_attachments]'
4137 4163 end
4138 4164
4139 4165 def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
4140 4166 user = setup_user_with_copy_but_not_add_permission
4141 4167 @request.session[:user_id] = user.id
4142 4168
4143 4169 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4144 4170 assert_response :success
4145 4171 assert_template 'bulk_edit'
4146 4172
4147 4173 assert_select 'select[name=?]', 'issue[project_id]' do
4148 4174 assert_select 'option[value=""]', 0
4149 4175 assert_select 'option[value="2"]'
4150 4176 end
4151 4177 end
4152 4178
4153 4179 def test_bulk_copy_to_another_project
4154 4180 @request.session[:user_id] = 2
4155 4181 assert_difference 'Issue.count', 2 do
4156 4182 assert_no_difference 'Project.find(1).issues.count' do
4157 4183 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
4158 4184 end
4159 4185 end
4160 4186 assert_redirected_to '/projects/ecookbook/issues'
4161 4187
4162 4188 copies = Issue.order('id DESC').limit(issues.size)
4163 4189 copies.each do |copy|
4164 4190 assert_equal 2, copy.project_id
4165 4191 end
4166 4192 end
4167 4193
4168 4194 def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
4169 4195 user = setup_user_with_copy_but_not_add_permission
4170 4196 @request.session[:user_id] = user.id
4171 4197
4172 4198 assert_difference 'Issue.count', 3 do
4173 4199 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '2'}, :copy => '1'
4174 4200 assert_response 302
4175 4201 end
4176 4202 end
4177 4203
4178 4204 def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
4179 4205 user = setup_user_with_copy_but_not_add_permission
4180 4206 @request.session[:user_id] = user.id
4181 4207
4182 4208 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => ''}, :copy => '1'
4183 4209 assert_response 403
4184 4210 end
4185 4211
4186 4212 def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
4187 4213 user = setup_user_with_copy_but_not_add_permission
4188 4214 @request.session[:user_id] = user.id
4189 4215
4190 4216 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '1'}, :copy => '1'
4191 4217 assert_response 403
4192 4218 end
4193 4219
4194 4220 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
4195 4221 @request.session[:user_id] = 2
4196 4222 issues = [
4197 4223 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
4198 4224 :priority_id => 2, :subject => 'issue 1', :author_id => 1,
4199 4225 :assigned_to_id => nil),
4200 4226 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
4201 4227 :priority_id => 1, :subject => 'issue 2', :author_id => 2,
4202 4228 :assigned_to_id => 3)
4203 4229 ]
4204 4230 assert_difference 'Issue.count', issues.size do
4205 4231 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
4206 4232 :issue => {
4207 4233 :project_id => '', :tracker_id => '', :assigned_to_id => '',
4208 4234 :status_id => '', :start_date => '', :due_date => ''
4209 4235 }
4210 4236 end
4211 4237
4212 4238 copies = Issue.order('id DESC').limit(issues.size)
4213 4239 issues.each do |orig|
4214 4240 copy = copies.detect {|c| c.subject == orig.subject}
4215 4241 assert_not_nil copy
4216 4242 assert_equal orig.project_id, copy.project_id
4217 4243 assert_equal orig.tracker_id, copy.tracker_id
4218 4244 assert_equal orig.status_id, copy.status_id
4219 4245 assert_equal orig.assigned_to_id, copy.assigned_to_id
4220 4246 assert_equal orig.priority_id, copy.priority_id
4221 4247 end
4222 4248 end
4223 4249
4224 4250 def test_bulk_copy_should_allow_changing_the_issue_attributes
4225 4251 # Fixes random test failure with Mysql
4226 4252 # where Issue.where(:project_id => 2).limit(2).order('id desc')
4227 4253 # doesn't return the expected results
4228 4254 Issue.delete_all("project_id=2")
4229 4255
4230 4256 @request.session[:user_id] = 2
4231 4257 assert_difference 'Issue.count', 2 do
4232 4258 assert_no_difference 'Project.find(1).issues.count' do
4233 4259 post :bulk_update, :ids => [1, 2], :copy => '1',
4234 4260 :issue => {
4235 4261 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
4236 4262 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
4237 4263 }
4238 4264 end
4239 4265 end
4240 4266
4241 4267 copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
4242 4268 assert_equal 2, copied_issues.size
4243 4269 copied_issues.each do |issue|
4244 4270 assert_equal 2, issue.project_id, "Project is incorrect"
4245 4271 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
4246 4272 assert_equal 1, issue.status_id, "Status is incorrect"
4247 4273 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
4248 4274 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
4249 4275 end
4250 4276 end
4251 4277
4252 4278 def test_bulk_copy_should_allow_adding_a_note
4253 4279 @request.session[:user_id] = 2
4254 4280 assert_difference 'Issue.count', 1 do
4255 4281 post :bulk_update, :ids => [1], :copy => '1',
4256 4282 :notes => 'Copying one issue',
4257 4283 :issue => {
4258 4284 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
4259 4285 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
4260 4286 }
4261 4287 end
4262 4288 issue = Issue.order('id DESC').first
4263 4289 assert_equal 1, issue.journals.size
4264 4290 journal = issue.journals.first
4265 4291 assert_equal 'Copying one issue', journal.notes
4266 4292 end
4267 4293
4268 4294 def test_bulk_copy_should_allow_not_copying_the_attachments
4269 4295 attachment_count = Issue.find(3).attachments.size
4270 4296 assert attachment_count > 0
4271 4297 @request.session[:user_id] = 2
4272 4298
4273 4299 assert_difference 'Issue.count', 1 do
4274 4300 assert_no_difference 'Attachment.count' do
4275 4301 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '0',
4276 4302 :issue => {
4277 4303 :project_id => ''
4278 4304 }
4279 4305 end
4280 4306 end
4281 4307 end
4282 4308
4283 4309 def test_bulk_copy_should_allow_copying_the_attachments
4284 4310 attachment_count = Issue.find(3).attachments.size
4285 4311 assert attachment_count > 0
4286 4312 @request.session[:user_id] = 2
4287 4313
4288 4314 assert_difference 'Issue.count', 1 do
4289 4315 assert_difference 'Attachment.count', attachment_count do
4290 4316 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
4291 4317 :issue => {
4292 4318 :project_id => ''
4293 4319 }
4294 4320 end
4295 4321 end
4296 4322 end
4297 4323
4298 4324 def test_bulk_copy_should_add_relations_with_copied_issues
4299 4325 @request.session[:user_id] = 2
4300 4326
4301 4327 assert_difference 'Issue.count', 2 do
4302 4328 assert_difference 'IssueRelation.count', 2 do
4303 4329 post :bulk_update, :ids => [1, 3], :copy => '1', :link_copy => '1',
4304 4330 :issue => {
4305 4331 :project_id => '1'
4306 4332 }
4307 4333 end
4308 4334 end
4309 4335 end
4310 4336
4311 4337 def test_bulk_copy_should_allow_not_copying_the_subtasks
4312 4338 issue = Issue.generate_with_descendants!
4313 4339 @request.session[:user_id] = 2
4314 4340
4315 4341 assert_difference 'Issue.count', 1 do
4316 4342 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '0',
4317 4343 :issue => {
4318 4344 :project_id => ''
4319 4345 }
4320 4346 end
4321 4347 end
4322 4348
4323 4349 def test_bulk_copy_should_allow_copying_the_subtasks
4324 4350 issue = Issue.generate_with_descendants!
4325 4351 count = issue.descendants.count
4326 4352 @request.session[:user_id] = 2
4327 4353
4328 4354 assert_difference 'Issue.count', count+1 do
4329 4355 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
4330 4356 :issue => {
4331 4357 :project_id => ''
4332 4358 }
4333 4359 end
4334 4360 copy = Issue.where(:parent_id => nil).order("id DESC").first
4335 4361 assert_equal count, copy.descendants.count
4336 4362 end
4337 4363
4338 4364 def test_bulk_copy_should_not_copy_selected_subtasks_twice
4339 4365 issue = Issue.generate_with_descendants!
4340 4366 count = issue.descendants.count
4341 4367 @request.session[:user_id] = 2
4342 4368
4343 4369 assert_difference 'Issue.count', count+1 do
4344 4370 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
4345 4371 :issue => {
4346 4372 :project_id => ''
4347 4373 }
4348 4374 end
4349 4375 copy = Issue.where(:parent_id => nil).order("id DESC").first
4350 4376 assert_equal count, copy.descendants.count
4351 4377 end
4352 4378
4353 4379 def test_bulk_copy_to_another_project_should_follow_when_needed
4354 4380 @request.session[:user_id] = 2
4355 4381 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
4356 4382 issue = Issue.order('id DESC').first
4357 4383 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
4358 4384 end
4359 4385
4360 4386 def test_bulk_copy_with_all_failures_should_display_errors
4361 4387 @request.session[:user_id] = 2
4362 4388 post :bulk_update, :ids => [1, 2], :copy => '1', :issue => {:start_date => 'foo'}
4363 4389
4364 4390 assert_response :success
4365 4391 end
4366 4392
4367 4393 def test_destroy_issue_with_no_time_entries
4368 4394 assert_nil TimeEntry.find_by_issue_id(2)
4369 4395 @request.session[:user_id] = 2
4370 4396
4371 4397 assert_difference 'Issue.count', -1 do
4372 4398 delete :destroy, :id => 2
4373 4399 end
4374 4400 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4375 4401 assert_nil Issue.find_by_id(2)
4376 4402 end
4377 4403
4378 4404 def test_destroy_issues_with_time_entries
4379 4405 @request.session[:user_id] = 2
4380 4406
4381 4407 assert_no_difference 'Issue.count' do
4382 4408 delete :destroy, :ids => [1, 3]
4383 4409 end
4384 4410 assert_response :success
4385 4411 assert_template 'destroy'
4386 4412 assert_not_nil assigns(:hours)
4387 4413 assert Issue.find_by_id(1) && Issue.find_by_id(3)
4388 4414
4389 4415 assert_select 'form' do
4390 4416 assert_select 'input[name=_method][value=delete]'
4391 4417 end
4392 4418 end
4393 4419
4394 4420 def test_destroy_issues_and_destroy_time_entries
4395 4421 @request.session[:user_id] = 2
4396 4422
4397 4423 assert_difference 'Issue.count', -2 do
4398 4424 assert_difference 'TimeEntry.count', -3 do
4399 4425 delete :destroy, :ids => [1, 3], :todo => 'destroy'
4400 4426 end
4401 4427 end
4402 4428 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4403 4429 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4404 4430 assert_nil TimeEntry.find_by_id([1, 2])
4405 4431 end
4406 4432
4407 4433 def test_destroy_issues_and_assign_time_entries_to_project
4408 4434 @request.session[:user_id] = 2
4409 4435
4410 4436 assert_difference 'Issue.count', -2 do
4411 4437 assert_no_difference 'TimeEntry.count' do
4412 4438 delete :destroy, :ids => [1, 3], :todo => 'nullify'
4413 4439 end
4414 4440 end
4415 4441 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4416 4442 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4417 4443 assert_nil TimeEntry.find(1).issue_id
4418 4444 assert_nil TimeEntry.find(2).issue_id
4419 4445 end
4420 4446
4421 4447 def test_destroy_issues_and_reassign_time_entries_to_another_issue
4422 4448 @request.session[:user_id] = 2
4423 4449
4424 4450 assert_difference 'Issue.count', -2 do
4425 4451 assert_no_difference 'TimeEntry.count' do
4426 4452 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
4427 4453 end
4428 4454 end
4429 4455 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4430 4456 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4431 4457 assert_equal 2, TimeEntry.find(1).issue_id
4432 4458 assert_equal 2, TimeEntry.find(2).issue_id
4433 4459 end
4434 4460
4435 4461 def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
4436 4462 @request.session[:user_id] = 2
4437 4463
4438 4464 assert_no_difference 'Issue.count' do
4439 4465 assert_no_difference 'TimeEntry.count' do
4440 4466 # try to reassign time to an issue of another project
4441 4467 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 4
4442 4468 end
4443 4469 end
4444 4470 assert_response :success
4445 4471 assert_template 'destroy'
4446 4472 end
4447 4473
4448 4474 def test_destroy_issues_from_different_projects
4449 4475 @request.session[:user_id] = 2
4450 4476
4451 4477 assert_difference 'Issue.count', -3 do
4452 4478 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
4453 4479 end
4454 4480 assert_redirected_to :controller => 'issues', :action => 'index'
4455 4481 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
4456 4482 end
4457 4483
4458 4484 def test_destroy_parent_and_child_issues
4459 4485 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
4460 4486 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
4461 4487 assert child.is_descendant_of?(parent.reload)
4462 4488
4463 4489 @request.session[:user_id] = 2
4464 4490 assert_difference 'Issue.count', -2 do
4465 4491 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
4466 4492 end
4467 4493 assert_response 302
4468 4494 end
4469 4495
4470 4496 def test_destroy_invalid_should_respond_with_404
4471 4497 @request.session[:user_id] = 2
4472 4498 assert_no_difference 'Issue.count' do
4473 4499 delete :destroy, :id => 999
4474 4500 end
4475 4501 assert_response 404
4476 4502 end
4477 4503
4478 4504 def test_default_search_scope
4479 4505 get :index
4480 4506
4481 4507 assert_select 'div#quick-search form' do
4482 4508 assert_select 'input[name=issues][value="1"][type=hidden]'
4483 4509 end
4484 4510 end
4485 4511
4486 4512 def setup_user_with_copy_but_not_add_permission
4487 4513 Role.all.each {|r| r.remove_permission! :add_issues}
4488 4514 Role.find_by_name('Manager').add_permission! :add_issues
4489 4515 user = User.generate!
4490 4516 User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
4491 4517 User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
4492 4518 user
4493 4519 end
4494 4520 end
General Comments 0
You need to be logged in to leave comments. Login now