##// END OF EJS Templates
Fixed failing test in #3391. Quotes (") are html escaped....
Eric Davis -
r2670:68c7af6c914a
parent child
Show More
@@ -1,1089 +1,1089
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2008 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.dirname(__FILE__) + '/../test_helper'
19 19 require 'issues_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class IssuesController; def rescue_action(e) raise e end; end
23 23
24 24 class IssuesControllerTest < Test::Unit::TestCase
25 25 fixtures :projects,
26 26 :users,
27 27 :roles,
28 28 :members,
29 29 :member_roles,
30 30 :issues,
31 31 :issue_statuses,
32 32 :versions,
33 33 :trackers,
34 34 :projects_trackers,
35 35 :issue_categories,
36 36 :enabled_modules,
37 37 :enumerations,
38 38 :attachments,
39 39 :workflows,
40 40 :custom_fields,
41 41 :custom_values,
42 42 :custom_fields_trackers,
43 43 :time_entries,
44 44 :journals,
45 45 :journal_details
46 46
47 47 def setup
48 48 @controller = IssuesController.new
49 49 @request = ActionController::TestRequest.new
50 50 @response = ActionController::TestResponse.new
51 51 User.current = nil
52 52 end
53 53
54 54 def test_index_routing
55 55 assert_routing(
56 56 {:method => :get, :path => '/issues'},
57 57 :controller => 'issues', :action => 'index'
58 58 )
59 59 end
60 60
61 61 def test_index
62 62 Setting.default_language = 'en'
63 63
64 64 get :index
65 65 assert_response :success
66 66 assert_template 'index.rhtml'
67 67 assert_not_nil assigns(:issues)
68 68 assert_nil assigns(:project)
69 69 assert_tag :tag => 'a', :content => /Can't print recipes/
70 70 assert_tag :tag => 'a', :content => /Subproject issue/
71 71 # private projects hidden
72 72 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
73 73 assert_no_tag :tag => 'a', :content => /Issue on project 2/
74 74 # project column
75 75 assert_tag :tag => 'th', :content => /Project/
76 76 end
77 77
78 78 def test_index_should_not_list_issues_when_module_disabled
79 79 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
80 80 get :index
81 81 assert_response :success
82 82 assert_template 'index.rhtml'
83 83 assert_not_nil assigns(:issues)
84 84 assert_nil assigns(:project)
85 85 assert_no_tag :tag => 'a', :content => /Can't print recipes/
86 86 assert_tag :tag => 'a', :content => /Subproject issue/
87 87 end
88 88
89 89 def test_index_with_project_routing
90 90 assert_routing(
91 91 {:method => :get, :path => '/projects/23/issues'},
92 92 :controller => 'issues', :action => 'index', :project_id => '23'
93 93 )
94 94 end
95 95
96 96 def test_index_should_not_list_issues_when_module_disabled
97 97 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
98 98 get :index
99 99 assert_response :success
100 100 assert_template 'index.rhtml'
101 101 assert_not_nil assigns(:issues)
102 102 assert_nil assigns(:project)
103 103 assert_no_tag :tag => 'a', :content => /Can't print recipes/
104 104 assert_tag :tag => 'a', :content => /Subproject issue/
105 105 end
106 106
107 107 def test_index_with_project_routing
108 108 assert_routing(
109 109 {:method => :get, :path => 'projects/23/issues'},
110 110 :controller => 'issues', :action => 'index', :project_id => '23'
111 111 )
112 112 end
113 113
114 114 def test_index_with_project
115 115 Setting.display_subprojects_issues = 0
116 116 get :index, :project_id => 1
117 117 assert_response :success
118 118 assert_template 'index.rhtml'
119 119 assert_not_nil assigns(:issues)
120 120 assert_tag :tag => 'a', :content => /Can't print recipes/
121 121 assert_no_tag :tag => 'a', :content => /Subproject issue/
122 122 end
123 123
124 124 def test_index_with_project_and_subprojects
125 125 Setting.display_subprojects_issues = 1
126 126 get :index, :project_id => 1
127 127 assert_response :success
128 128 assert_template 'index.rhtml'
129 129 assert_not_nil assigns(:issues)
130 130 assert_tag :tag => 'a', :content => /Can't print recipes/
131 131 assert_tag :tag => 'a', :content => /Subproject issue/
132 132 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
133 133 end
134 134
135 135 def test_index_with_project_and_subprojects_should_show_private_subprojects
136 136 @request.session[:user_id] = 2
137 137 Setting.display_subprojects_issues = 1
138 138 get :index, :project_id => 1
139 139 assert_response :success
140 140 assert_template 'index.rhtml'
141 141 assert_not_nil assigns(:issues)
142 142 assert_tag :tag => 'a', :content => /Can't print recipes/
143 143 assert_tag :tag => 'a', :content => /Subproject issue/
144 144 assert_tag :tag => 'a', :content => /Issue of a private subproject/
145 145 end
146 146
147 147 def test_index_with_project_routing_formatted
148 148 assert_routing(
149 149 {:method => :get, :path => 'projects/23/issues.pdf'},
150 150 :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
151 151 )
152 152 assert_routing(
153 153 {:method => :get, :path => 'projects/23/issues.atom'},
154 154 :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
155 155 )
156 156 end
157 157
158 158 def test_index_with_project_and_filter
159 159 get :index, :project_id => 1, :set_filter => 1
160 160 assert_response :success
161 161 assert_template 'index.rhtml'
162 162 assert_not_nil assigns(:issues)
163 163 end
164 164
165 165 def test_index_with_query
166 166 get :index, :project_id => 1, :query_id => 5
167 167 assert_response :success
168 168 assert_template 'index.rhtml'
169 169 assert_not_nil assigns(:issues)
170 170 assert_nil assigns(:issue_count_by_group)
171 171 end
172 172
173 173 def test_index_with_grouped_query
174 174 get :index, :project_id => 1, :query_id => 6
175 175 assert_response :success
176 176 assert_template 'index.rhtml'
177 177 assert_not_nil assigns(:issues)
178 178 assert_not_nil assigns(:issue_count_by_group)
179 179 end
180 180
181 181 def test_index_csv_with_project
182 182 get :index, :format => 'csv'
183 183 assert_response :success
184 184 assert_not_nil assigns(:issues)
185 185 assert_equal 'text/csv', @response.content_type
186 186
187 187 get :index, :project_id => 1, :format => 'csv'
188 188 assert_response :success
189 189 assert_not_nil assigns(:issues)
190 190 assert_equal 'text/csv', @response.content_type
191 191 end
192 192
193 193 def test_index_formatted
194 194 assert_routing(
195 195 {:method => :get, :path => 'issues.pdf'},
196 196 :controller => 'issues', :action => 'index', :format => 'pdf'
197 197 )
198 198 assert_routing(
199 199 {:method => :get, :path => 'issues.atom'},
200 200 :controller => 'issues', :action => 'index', :format => 'atom'
201 201 )
202 202 end
203 203
204 204 def test_index_pdf
205 205 get :index, :format => 'pdf'
206 206 assert_response :success
207 207 assert_not_nil assigns(:issues)
208 208 assert_equal 'application/pdf', @response.content_type
209 209
210 210 get :index, :project_id => 1, :format => 'pdf'
211 211 assert_response :success
212 212 assert_not_nil assigns(:issues)
213 213 assert_equal 'application/pdf', @response.content_type
214 214
215 215 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
216 216 assert_response :success
217 217 assert_not_nil assigns(:issues)
218 218 assert_equal 'application/pdf', @response.content_type
219 219 end
220 220
221 221 def test_index_sort
222 222 get :index, :sort => 'tracker,id:desc'
223 223 assert_response :success
224 224
225 225 sort_params = @request.session['issues_index_sort']
226 226 assert sort_params.is_a?(String)
227 227 assert_equal 'tracker,id:desc', sort_params
228 228
229 229 issues = assigns(:issues)
230 230 assert_not_nil issues
231 231 assert !issues.empty?
232 232 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
233 233 end
234 234
235 235 def test_gantt
236 236 get :gantt, :project_id => 1
237 237 assert_response :success
238 238 assert_template 'gantt.rhtml'
239 239 assert_not_nil assigns(:gantt)
240 240 events = assigns(:gantt).events
241 241 assert_not_nil events
242 242 # Issue with start and due dates
243 243 i = Issue.find(1)
244 244 assert_not_nil i.due_date
245 245 assert events.include?(Issue.find(1))
246 246 # Issue with without due date but targeted to a version with date
247 247 i = Issue.find(2)
248 248 assert_nil i.due_date
249 249 assert events.include?(i)
250 250 end
251 251
252 252 def test_cross_project_gantt
253 253 get :gantt
254 254 assert_response :success
255 255 assert_template 'gantt.rhtml'
256 256 assert_not_nil assigns(:gantt)
257 257 events = assigns(:gantt).events
258 258 assert_not_nil events
259 259 end
260 260
261 261 def test_gantt_export_to_pdf
262 262 get :gantt, :project_id => 1, :format => 'pdf'
263 263 assert_response :success
264 264 assert_equal 'application/pdf', @response.content_type
265 265 assert @response.body.starts_with?('%PDF')
266 266 assert_not_nil assigns(:gantt)
267 267 end
268 268
269 269 def test_cross_project_gantt_export_to_pdf
270 270 get :gantt, :format => 'pdf'
271 271 assert_response :success
272 272 assert_equal 'application/pdf', @response.content_type
273 273 assert @response.body.starts_with?('%PDF')
274 274 assert_not_nil assigns(:gantt)
275 275 end
276 276
277 277 if Object.const_defined?(:Magick)
278 278 def test_gantt_image
279 279 get :gantt, :project_id => 1, :format => 'png'
280 280 assert_response :success
281 281 assert_equal 'image/png', @response.content_type
282 282 end
283 283 else
284 284 puts "RMagick not installed. Skipping tests !!!"
285 285 end
286 286
287 287 def test_calendar
288 288 get :calendar, :project_id => 1
289 289 assert_response :success
290 290 assert_template 'calendar'
291 291 assert_not_nil assigns(:calendar)
292 292 end
293 293
294 294 def test_cross_project_calendar
295 295 get :calendar
296 296 assert_response :success
297 297 assert_template 'calendar'
298 298 assert_not_nil assigns(:calendar)
299 299 end
300 300
301 301 def test_changes
302 302 get :changes, :project_id => 1
303 303 assert_response :success
304 304 assert_not_nil assigns(:journals)
305 305 assert_equal 'application/atom+xml', @response.content_type
306 306 end
307 307
308 308 def test_show_routing
309 309 assert_routing(
310 310 {:method => :get, :path => '/issues/64'},
311 311 :controller => 'issues', :action => 'show', :id => '64'
312 312 )
313 313 end
314 314
315 315 def test_show_routing_formatted
316 316 assert_routing(
317 317 {:method => :get, :path => '/issues/2332.pdf'},
318 318 :controller => 'issues', :action => 'show', :id => '2332', :format => 'pdf'
319 319 )
320 320 assert_routing(
321 321 {:method => :get, :path => '/issues/23123.atom'},
322 322 :controller => 'issues', :action => 'show', :id => '23123', :format => 'atom'
323 323 )
324 324 end
325 325
326 326 def test_show_by_anonymous
327 327 get :show, :id => 1
328 328 assert_response :success
329 329 assert_template 'show.rhtml'
330 330 assert_not_nil assigns(:issue)
331 331 assert_equal Issue.find(1), assigns(:issue)
332 332
333 333 # anonymous role is allowed to add a note
334 334 assert_tag :tag => 'form',
335 335 :descendant => { :tag => 'fieldset',
336 336 :child => { :tag => 'legend',
337 337 :content => /Notes/ } }
338 338 end
339 339
340 340 def test_show_by_manager
341 341 @request.session[:user_id] = 2
342 342 get :show, :id => 1
343 343 assert_response :success
344 344
345 345 assert_tag :tag => 'form',
346 346 :descendant => { :tag => 'fieldset',
347 347 :child => { :tag => 'legend',
348 348 :content => /Change properties/ } },
349 349 :descendant => { :tag => 'fieldset',
350 350 :child => { :tag => 'legend',
351 351 :content => /Log time/ } },
352 352 :descendant => { :tag => 'fieldset',
353 353 :child => { :tag => 'legend',
354 354 :content => /Notes/ } }
355 355 end
356 356
357 357 def test_show_should_not_disclose_relations_to_invisible_issues
358 358 Setting.cross_project_issue_relations = '1'
359 359 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
360 360 # Relation to a private project issue
361 361 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
362 362
363 363 get :show, :id => 1
364 364 assert_response :success
365 365
366 366 assert_tag :div, :attributes => { :id => 'relations' },
367 367 :descendant => { :tag => 'a', :content => /#2$/ }
368 368 assert_no_tag :div, :attributes => { :id => 'relations' },
369 369 :descendant => { :tag => 'a', :content => /#4$/ }
370 370 end
371 371
372 372 def test_show_atom
373 373 get :show, :id => 2, :format => 'atom'
374 374 assert_response :success
375 375 assert_template 'changes.rxml'
376 376 # Inline image
377 assert @response.body.include?("&lt;img src=\"http://test.host/attachments/download/10\" alt=\"\" /&gt;")
377 assert @response.body.include?("&lt;img src=&quot;http://test.host/attachments/download/10&quot; alt=&quot;&quot; /&gt;")
378 378 end
379 379
380 380 def test_new_routing
381 381 assert_routing(
382 382 {:method => :get, :path => '/projects/1/issues/new'},
383 383 :controller => 'issues', :action => 'new', :project_id => '1'
384 384 )
385 385 assert_recognizes(
386 386 {:controller => 'issues', :action => 'new', :project_id => '1'},
387 387 {:method => :post, :path => '/projects/1/issues'}
388 388 )
389 389 end
390 390
391 391 def test_show_export_to_pdf
392 392 get :show, :id => 3, :format => 'pdf'
393 393 assert_response :success
394 394 assert_equal 'application/pdf', @response.content_type
395 395 assert @response.body.starts_with?('%PDF')
396 396 assert_not_nil assigns(:issue)
397 397 end
398 398
399 399 def test_get_new
400 400 @request.session[:user_id] = 2
401 401 get :new, :project_id => 1, :tracker_id => 1
402 402 assert_response :success
403 403 assert_template 'new'
404 404
405 405 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
406 406 :value => 'Default string' }
407 407 end
408 408
409 409 def test_get_new_without_tracker_id
410 410 @request.session[:user_id] = 2
411 411 get :new, :project_id => 1
412 412 assert_response :success
413 413 assert_template 'new'
414 414
415 415 issue = assigns(:issue)
416 416 assert_not_nil issue
417 417 assert_equal Project.find(1).trackers.first, issue.tracker
418 418 end
419 419
420 420 def test_get_new_with_no_default_status_should_display_an_error
421 421 @request.session[:user_id] = 2
422 422 IssueStatus.delete_all
423 423
424 424 get :new, :project_id => 1
425 425 assert_response 500
426 426 assert_not_nil flash[:error]
427 427 assert_tag :tag => 'div', :attributes => { :class => /error/ },
428 428 :content => /No default issue/
429 429 end
430 430
431 431 def test_get_new_with_no_tracker_should_display_an_error
432 432 @request.session[:user_id] = 2
433 433 Tracker.delete_all
434 434
435 435 get :new, :project_id => 1
436 436 assert_response 500
437 437 assert_not_nil flash[:error]
438 438 assert_tag :tag => 'div', :attributes => { :class => /error/ },
439 439 :content => /No tracker/
440 440 end
441 441
442 442 def test_update_new_form
443 443 @request.session[:user_id] = 2
444 444 xhr :post, :new, :project_id => 1,
445 445 :issue => {:tracker_id => 2,
446 446 :subject => 'This is the test_new issue',
447 447 :description => 'This is the description',
448 448 :priority_id => 5}
449 449 assert_response :success
450 450 assert_template 'new'
451 451 end
452 452
453 453 def test_post_new
454 454 @request.session[:user_id] = 2
455 455 post :new, :project_id => 1,
456 456 :issue => {:tracker_id => 3,
457 457 :subject => 'This is the test_new issue',
458 458 :description => 'This is the description',
459 459 :priority_id => 5,
460 460 :estimated_hours => '',
461 461 :custom_field_values => {'2' => 'Value for field 2'}}
462 462 assert_redirected_to :action => 'show'
463 463
464 464 issue = Issue.find_by_subject('This is the test_new issue')
465 465 assert_not_nil issue
466 466 assert_equal 2, issue.author_id
467 467 assert_equal 3, issue.tracker_id
468 468 assert_nil issue.estimated_hours
469 469 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
470 470 assert_not_nil v
471 471 assert_equal 'Value for field 2', v.value
472 472 end
473 473
474 474 def test_post_new_and_continue
475 475 @request.session[:user_id] = 2
476 476 post :new, :project_id => 1,
477 477 :issue => {:tracker_id => 3,
478 478 :subject => 'This is first issue',
479 479 :priority_id => 5},
480 480 :continue => ''
481 481 assert_redirected_to :controller => 'issues', :action => 'new', :tracker_id => 3
482 482 end
483 483
484 484 def test_post_new_without_custom_fields_param
485 485 @request.session[:user_id] = 2
486 486 post :new, :project_id => 1,
487 487 :issue => {:tracker_id => 1,
488 488 :subject => 'This is the test_new issue',
489 489 :description => 'This is the description',
490 490 :priority_id => 5}
491 491 assert_redirected_to :action => 'show'
492 492 end
493 493
494 494 def test_post_new_with_required_custom_field_and_without_custom_fields_param
495 495 field = IssueCustomField.find_by_name('Database')
496 496 field.update_attribute(:is_required, true)
497 497
498 498 @request.session[:user_id] = 2
499 499 post :new, :project_id => 1,
500 500 :issue => {:tracker_id => 1,
501 501 :subject => 'This is the test_new issue',
502 502 :description => 'This is the description',
503 503 :priority_id => 5}
504 504 assert_response :success
505 505 assert_template 'new'
506 506 issue = assigns(:issue)
507 507 assert_not_nil issue
508 508 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
509 509 end
510 510
511 511 def test_post_new_with_watchers
512 512 @request.session[:user_id] = 2
513 513 ActionMailer::Base.deliveries.clear
514 514
515 515 assert_difference 'Watcher.count', 2 do
516 516 post :new, :project_id => 1,
517 517 :issue => {:tracker_id => 1,
518 518 :subject => 'This is a new issue with watchers',
519 519 :description => 'This is the description',
520 520 :priority_id => 5,
521 521 :watcher_user_ids => ['2', '3']}
522 522 end
523 523 issue = Issue.find_by_subject('This is a new issue with watchers')
524 524 assert_not_nil issue
525 525 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
526 526
527 527 # Watchers added
528 528 assert_equal [2, 3], issue.watcher_user_ids.sort
529 529 assert issue.watched_by?(User.find(3))
530 530 # Watchers notified
531 531 mail = ActionMailer::Base.deliveries.last
532 532 assert_kind_of TMail::Mail, mail
533 533 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
534 534 end
535 535
536 536 def test_post_new_should_send_a_notification
537 537 ActionMailer::Base.deliveries.clear
538 538 @request.session[:user_id] = 2
539 539 post :new, :project_id => 1,
540 540 :issue => {:tracker_id => 3,
541 541 :subject => 'This is the test_new issue',
542 542 :description => 'This is the description',
543 543 :priority_id => 5,
544 544 :estimated_hours => '',
545 545 :custom_field_values => {'2' => 'Value for field 2'}}
546 546 assert_redirected_to :action => 'show'
547 547
548 548 assert_equal 1, ActionMailer::Base.deliveries.size
549 549 end
550 550
551 551 def test_post_should_preserve_fields_values_on_validation_failure
552 552 @request.session[:user_id] = 2
553 553 post :new, :project_id => 1,
554 554 :issue => {:tracker_id => 1,
555 555 # empty subject
556 556 :subject => '',
557 557 :description => 'This is a description',
558 558 :priority_id => 6,
559 559 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
560 560 assert_response :success
561 561 assert_template 'new'
562 562
563 563 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
564 564 :content => 'This is a description'
565 565 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
566 566 :child => { :tag => 'option', :attributes => { :selected => 'selected',
567 567 :value => '6' },
568 568 :content => 'High' }
569 569 # Custom fields
570 570 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
571 571 :child => { :tag => 'option', :attributes => { :selected => 'selected',
572 572 :value => 'Oracle' },
573 573 :content => 'Oracle' }
574 574 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
575 575 :value => 'Value for field 2'}
576 576 end
577 577
578 578 def test_copy_routing
579 579 assert_routing(
580 580 {:method => :get, :path => '/projects/world_domination/issues/567/copy'},
581 581 :controller => 'issues', :action => 'new', :project_id => 'world_domination', :copy_from => '567'
582 582 )
583 583 end
584 584
585 585 def test_copy_issue
586 586 @request.session[:user_id] = 2
587 587 get :new, :project_id => 1, :copy_from => 1
588 588 assert_template 'new'
589 589 assert_not_nil assigns(:issue)
590 590 orig = Issue.find(1)
591 591 assert_equal orig.subject, assigns(:issue).subject
592 592 end
593 593
594 594 def test_edit_routing
595 595 assert_routing(
596 596 {:method => :get, :path => '/issues/1/edit'},
597 597 :controller => 'issues', :action => 'edit', :id => '1'
598 598 )
599 599 assert_recognizes( #TODO: use a PUT on the issue URI isntead, need to adjust form
600 600 {:controller => 'issues', :action => 'edit', :id => '1'},
601 601 {:method => :post, :path => '/issues/1/edit'}
602 602 )
603 603 end
604 604
605 605 def test_get_edit
606 606 @request.session[:user_id] = 2
607 607 get :edit, :id => 1
608 608 assert_response :success
609 609 assert_template 'edit'
610 610 assert_not_nil assigns(:issue)
611 611 assert_equal Issue.find(1), assigns(:issue)
612 612 end
613 613
614 614 def test_get_edit_with_params
615 615 @request.session[:user_id] = 2
616 616 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }
617 617 assert_response :success
618 618 assert_template 'edit'
619 619
620 620 issue = assigns(:issue)
621 621 assert_not_nil issue
622 622
623 623 assert_equal 5, issue.status_id
624 624 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
625 625 :child => { :tag => 'option',
626 626 :content => 'Closed',
627 627 :attributes => { :selected => 'selected' } }
628 628
629 629 assert_equal 7, issue.priority_id
630 630 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
631 631 :child => { :tag => 'option',
632 632 :content => 'Urgent',
633 633 :attributes => { :selected => 'selected' } }
634 634 end
635 635
636 636 def test_reply_routing
637 637 assert_routing(
638 638 {:method => :post, :path => '/issues/1/quoted'},
639 639 :controller => 'issues', :action => 'reply', :id => '1'
640 640 )
641 641 end
642 642
643 643 def test_reply_to_issue
644 644 @request.session[:user_id] = 2
645 645 get :reply, :id => 1
646 646 assert_response :success
647 647 assert_select_rjs :show, "update"
648 648 end
649 649
650 650 def test_reply_to_note
651 651 @request.session[:user_id] = 2
652 652 get :reply, :id => 1, :journal_id => 2
653 653 assert_response :success
654 654 assert_select_rjs :show, "update"
655 655 end
656 656
657 657 def test_post_edit_without_custom_fields_param
658 658 @request.session[:user_id] = 2
659 659 ActionMailer::Base.deliveries.clear
660 660
661 661 issue = Issue.find(1)
662 662 assert_equal '125', issue.custom_value_for(2).value
663 663 old_subject = issue.subject
664 664 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
665 665
666 666 assert_difference('Journal.count') do
667 667 assert_difference('JournalDetail.count', 2) do
668 668 post :edit, :id => 1, :issue => {:subject => new_subject,
669 669 :priority_id => '6',
670 670 :category_id => '1' # no change
671 671 }
672 672 end
673 673 end
674 674 assert_redirected_to :action => 'show', :id => '1'
675 675 issue.reload
676 676 assert_equal new_subject, issue.subject
677 677 # Make sure custom fields were not cleared
678 678 assert_equal '125', issue.custom_value_for(2).value
679 679
680 680 mail = ActionMailer::Base.deliveries.last
681 681 assert_kind_of TMail::Mail, mail
682 682 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
683 683 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
684 684 end
685 685
686 686 def test_post_edit_with_custom_field_change
687 687 @request.session[:user_id] = 2
688 688 issue = Issue.find(1)
689 689 assert_equal '125', issue.custom_value_for(2).value
690 690
691 691 assert_difference('Journal.count') do
692 692 assert_difference('JournalDetail.count', 3) do
693 693 post :edit, :id => 1, :issue => {:subject => 'Custom field change',
694 694 :priority_id => '6',
695 695 :category_id => '1', # no change
696 696 :custom_field_values => { '2' => 'New custom value' }
697 697 }
698 698 end
699 699 end
700 700 assert_redirected_to :action => 'show', :id => '1'
701 701 issue.reload
702 702 assert_equal 'New custom value', issue.custom_value_for(2).value
703 703
704 704 mail = ActionMailer::Base.deliveries.last
705 705 assert_kind_of TMail::Mail, mail
706 706 assert mail.body.include?("Searchable field changed from 125 to New custom value")
707 707 end
708 708
709 709 def test_post_edit_with_status_and_assignee_change
710 710 issue = Issue.find(1)
711 711 assert_equal 1, issue.status_id
712 712 @request.session[:user_id] = 2
713 713 assert_difference('TimeEntry.count', 0) do
714 714 post :edit,
715 715 :id => 1,
716 716 :issue => { :status_id => 2, :assigned_to_id => 3 },
717 717 :notes => 'Assigned to dlopper',
718 718 :time_entry => { :hours => '', :comments => '', :activity_id => Enumeration.activities.first }
719 719 end
720 720 assert_redirected_to :action => 'show', :id => '1'
721 721 issue.reload
722 722 assert_equal 2, issue.status_id
723 723 j = issue.journals.find(:first, :order => 'id DESC')
724 724 assert_equal 'Assigned to dlopper', j.notes
725 725 assert_equal 2, j.details.size
726 726
727 727 mail = ActionMailer::Base.deliveries.last
728 728 assert mail.body.include?("Status changed from New to Assigned")
729 729 # subject should contain the new status
730 730 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
731 731 end
732 732
733 733 def test_post_edit_with_note_only
734 734 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
735 735 # anonymous user
736 736 post :edit,
737 737 :id => 1,
738 738 :notes => notes
739 739 assert_redirected_to :action => 'show', :id => '1'
740 740 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
741 741 assert_equal notes, j.notes
742 742 assert_equal 0, j.details.size
743 743 assert_equal User.anonymous, j.user
744 744
745 745 mail = ActionMailer::Base.deliveries.last
746 746 assert mail.body.include?(notes)
747 747 end
748 748
749 749 def test_post_edit_with_note_and_spent_time
750 750 @request.session[:user_id] = 2
751 751 spent_hours_before = Issue.find(1).spent_hours
752 752 assert_difference('TimeEntry.count') do
753 753 post :edit,
754 754 :id => 1,
755 755 :notes => '2.5 hours added',
756 756 :time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.activities.first }
757 757 end
758 758 assert_redirected_to :action => 'show', :id => '1'
759 759
760 760 issue = Issue.find(1)
761 761
762 762 j = issue.journals.find(:first, :order => 'id DESC')
763 763 assert_equal '2.5 hours added', j.notes
764 764 assert_equal 0, j.details.size
765 765
766 766 t = issue.time_entries.find(:first, :order => 'id DESC')
767 767 assert_not_nil t
768 768 assert_equal 2.5, t.hours
769 769 assert_equal spent_hours_before + 2.5, issue.spent_hours
770 770 end
771 771
772 772 def test_post_edit_with_attachment_only
773 773 set_tmp_attachments_directory
774 774
775 775 # Delete all fixtured journals, a race condition can occur causing the wrong
776 776 # journal to get fetched in the next find.
777 777 Journal.delete_all
778 778
779 779 # anonymous user
780 780 post :edit,
781 781 :id => 1,
782 782 :notes => '',
783 783 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
784 784 assert_redirected_to :action => 'show', :id => '1'
785 785 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
786 786 assert j.notes.blank?
787 787 assert_equal 1, j.details.size
788 788 assert_equal 'testfile.txt', j.details.first.value
789 789 assert_equal User.anonymous, j.user
790 790
791 791 mail = ActionMailer::Base.deliveries.last
792 792 assert mail.body.include?('testfile.txt')
793 793 end
794 794
795 795 def test_post_edit_with_no_change
796 796 issue = Issue.find(1)
797 797 issue.journals.clear
798 798 ActionMailer::Base.deliveries.clear
799 799
800 800 post :edit,
801 801 :id => 1,
802 802 :notes => ''
803 803 assert_redirected_to :action => 'show', :id => '1'
804 804
805 805 issue.reload
806 806 assert issue.journals.empty?
807 807 # No email should be sent
808 808 assert ActionMailer::Base.deliveries.empty?
809 809 end
810 810
811 811 def test_post_edit_should_send_a_notification
812 812 @request.session[:user_id] = 2
813 813 ActionMailer::Base.deliveries.clear
814 814 issue = Issue.find(1)
815 815 old_subject = issue.subject
816 816 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
817 817
818 818 post :edit, :id => 1, :issue => {:subject => new_subject,
819 819 :priority_id => '6',
820 820 :category_id => '1' # no change
821 821 }
822 822 assert_equal 1, ActionMailer::Base.deliveries.size
823 823 end
824 824
825 825 def test_post_edit_with_invalid_spent_time
826 826 @request.session[:user_id] = 2
827 827 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
828 828
829 829 assert_no_difference('Journal.count') do
830 830 post :edit,
831 831 :id => 1,
832 832 :notes => notes,
833 833 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
834 834 end
835 835 assert_response :success
836 836 assert_template 'edit'
837 837
838 838 assert_tag :textarea, :attributes => { :name => 'notes' },
839 839 :content => notes
840 840 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
841 841 end
842 842
843 843 def test_get_bulk_edit
844 844 @request.session[:user_id] = 2
845 845 get :bulk_edit, :ids => [1, 2]
846 846 assert_response :success
847 847 assert_template 'bulk_edit'
848 848 end
849 849
850 850 def test_bulk_edit
851 851 @request.session[:user_id] = 2
852 852 # update issues priority
853 853 post :bulk_edit, :ids => [1, 2], :priority_id => 7,
854 854 :assigned_to_id => '',
855 855 :custom_field_values => {'2' => ''},
856 856 :notes => 'Bulk editing'
857 857 assert_response 302
858 858 # check that the issues were updated
859 859 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
860 860
861 861 issue = Issue.find(1)
862 862 journal = issue.journals.find(:first, :order => 'created_on DESC')
863 863 assert_equal '125', issue.custom_value_for(2).value
864 864 assert_equal 'Bulk editing', journal.notes
865 865 assert_equal 1, journal.details.size
866 866 end
867 867
868 868 def test_bullk_edit_should_send_a_notification
869 869 @request.session[:user_id] = 2
870 870 ActionMailer::Base.deliveries.clear
871 871 post(:bulk_edit,
872 872 {
873 873 :ids => [1, 2],
874 874 :priority_id => 7,
875 875 :assigned_to_id => '',
876 876 :custom_field_values => {'2' => ''},
877 877 :notes => 'Bulk editing'
878 878 })
879 879
880 880 assert_response 302
881 881 assert_equal 2, ActionMailer::Base.deliveries.size
882 882 end
883 883
884 884 def test_bulk_edit_status
885 885 @request.session[:user_id] = 2
886 886 # update issues priority
887 887 post :bulk_edit, :ids => [1, 2], :priority_id => '',
888 888 :assigned_to_id => '',
889 889 :status_id => '5',
890 890 :notes => 'Bulk editing status'
891 891 assert_response 302
892 892 issue = Issue.find(1)
893 893 assert issue.closed?
894 894 end
895 895
896 896 def test_bulk_edit_custom_field
897 897 @request.session[:user_id] = 2
898 898 # update issues priority
899 899 post :bulk_edit, :ids => [1, 2], :priority_id => '',
900 900 :assigned_to_id => '',
901 901 :custom_field_values => {'2' => '777'},
902 902 :notes => 'Bulk editing custom field'
903 903 assert_response 302
904 904
905 905 issue = Issue.find(1)
906 906 journal = issue.journals.find(:first, :order => 'created_on DESC')
907 907 assert_equal '777', issue.custom_value_for(2).value
908 908 assert_equal 1, journal.details.size
909 909 assert_equal '125', journal.details.first.old_value
910 910 assert_equal '777', journal.details.first.value
911 911 end
912 912
913 913 def test_bulk_unassign
914 914 assert_not_nil Issue.find(2).assigned_to
915 915 @request.session[:user_id] = 2
916 916 # unassign issues
917 917 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk unassigning', :assigned_to_id => 'none'
918 918 assert_response 302
919 919 # check that the issues were updated
920 920 assert_nil Issue.find(2).assigned_to
921 921 end
922 922
923 923 def test_move_routing
924 924 assert_routing(
925 925 {:method => :get, :path => '/issues/1/move'},
926 926 :controller => 'issues', :action => 'move', :id => '1'
927 927 )
928 928 assert_recognizes(
929 929 {:controller => 'issues', :action => 'move', :id => '1'},
930 930 {:method => :post, :path => '/issues/1/move'}
931 931 )
932 932 end
933 933
934 934 def test_move_one_issue_to_another_project
935 935 @request.session[:user_id] = 2
936 936 post :move, :id => 1, :new_project_id => 2
937 937 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
938 938 assert_equal 2, Issue.find(1).project_id
939 939 end
940 940
941 941 def test_bulk_move_to_another_project
942 942 @request.session[:user_id] = 2
943 943 post :move, :ids => [1, 2], :new_project_id => 2
944 944 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
945 945 # Issues moved to project 2
946 946 assert_equal 2, Issue.find(1).project_id
947 947 assert_equal 2, Issue.find(2).project_id
948 948 # No tracker change
949 949 assert_equal 1, Issue.find(1).tracker_id
950 950 assert_equal 2, Issue.find(2).tracker_id
951 951 end
952 952
953 953 def test_bulk_move_to_another_tracker
954 954 @request.session[:user_id] = 2
955 955 post :move, :ids => [1, 2], :new_tracker_id => 2
956 956 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
957 957 assert_equal 2, Issue.find(1).tracker_id
958 958 assert_equal 2, Issue.find(2).tracker_id
959 959 end
960 960
961 961 def test_bulk_copy_to_another_project
962 962 @request.session[:user_id] = 2
963 963 assert_difference 'Issue.count', 2 do
964 964 assert_no_difference 'Project.find(1).issues.count' do
965 965 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
966 966 end
967 967 end
968 968 assert_redirected_to 'projects/ecookbook/issues'
969 969 end
970 970
971 971 def test_context_menu_one_issue
972 972 @request.session[:user_id] = 2
973 973 get :context_menu, :ids => [1]
974 974 assert_response :success
975 975 assert_template 'context_menu'
976 976 assert_tag :tag => 'a', :content => 'Edit',
977 977 :attributes => { :href => '/issues/1/edit',
978 978 :class => 'icon-edit' }
979 979 assert_tag :tag => 'a', :content => 'Closed',
980 980 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
981 981 :class => '' }
982 982 assert_tag :tag => 'a', :content => 'Immediate',
983 983 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;priority_id=8',
984 984 :class => '' }
985 985 assert_tag :tag => 'a', :content => 'Dave Lopper',
986 986 :attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&amp;ids%5B%5D=1',
987 987 :class => '' }
988 988 assert_tag :tag => 'a', :content => 'Copy',
989 989 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
990 990 :class => 'icon-copy' }
991 991 assert_tag :tag => 'a', :content => 'Move',
992 992 :attributes => { :href => '/issues/move?ids%5B%5D=1',
993 993 :class => 'icon-move' }
994 994 assert_tag :tag => 'a', :content => 'Delete',
995 995 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
996 996 :class => 'icon-del' }
997 997 end
998 998
999 999 def test_context_menu_one_issue_by_anonymous
1000 1000 get :context_menu, :ids => [1]
1001 1001 assert_response :success
1002 1002 assert_template 'context_menu'
1003 1003 assert_tag :tag => 'a', :content => 'Delete',
1004 1004 :attributes => { :href => '#',
1005 1005 :class => 'icon-del disabled' }
1006 1006 end
1007 1007
1008 1008 def test_context_menu_multiple_issues_of_same_project
1009 1009 @request.session[:user_id] = 2
1010 1010 get :context_menu, :ids => [1, 2]
1011 1011 assert_response :success
1012 1012 assert_template 'context_menu'
1013 1013 assert_tag :tag => 'a', :content => 'Edit',
1014 1014 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
1015 1015 :class => 'icon-edit' }
1016 1016 assert_tag :tag => 'a', :content => 'Immediate',
1017 1017 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;priority_id=8',
1018 1018 :class => '' }
1019 1019 assert_tag :tag => 'a', :content => 'Dave Lopper',
1020 1020 :attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
1021 1021 :class => '' }
1022 1022 assert_tag :tag => 'a', :content => 'Move',
1023 1023 :attributes => { :href => '/issues/move?ids%5B%5D=1&amp;ids%5B%5D=2',
1024 1024 :class => 'icon-move' }
1025 1025 assert_tag :tag => 'a', :content => 'Delete',
1026 1026 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
1027 1027 :class => 'icon-del' }
1028 1028 end
1029 1029
1030 1030 def test_context_menu_multiple_issues_of_different_project
1031 1031 @request.session[:user_id] = 2
1032 1032 get :context_menu, :ids => [1, 2, 4]
1033 1033 assert_response :success
1034 1034 assert_template 'context_menu'
1035 1035 assert_tag :tag => 'a', :content => 'Delete',
1036 1036 :attributes => { :href => '#',
1037 1037 :class => 'icon-del disabled' }
1038 1038 end
1039 1039
1040 1040 def test_destroy_routing
1041 1041 assert_recognizes( #TODO: use DELETE on issue URI (need to change forms)
1042 1042 {:controller => 'issues', :action => 'destroy', :id => '1'},
1043 1043 {:method => :post, :path => '/issues/1/destroy'}
1044 1044 )
1045 1045 end
1046 1046
1047 1047 def test_destroy_issue_with_no_time_entries
1048 1048 assert_nil TimeEntry.find_by_issue_id(2)
1049 1049 @request.session[:user_id] = 2
1050 1050 post :destroy, :id => 2
1051 1051 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1052 1052 assert_nil Issue.find_by_id(2)
1053 1053 end
1054 1054
1055 1055 def test_destroy_issues_with_time_entries
1056 1056 @request.session[:user_id] = 2
1057 1057 post :destroy, :ids => [1, 3]
1058 1058 assert_response :success
1059 1059 assert_template 'destroy'
1060 1060 assert_not_nil assigns(:hours)
1061 1061 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1062 1062 end
1063 1063
1064 1064 def test_destroy_issues_and_destroy_time_entries
1065 1065 @request.session[:user_id] = 2
1066 1066 post :destroy, :ids => [1, 3], :todo => 'destroy'
1067 1067 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1068 1068 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1069 1069 assert_nil TimeEntry.find_by_id([1, 2])
1070 1070 end
1071 1071
1072 1072 def test_destroy_issues_and_assign_time_entries_to_project
1073 1073 @request.session[:user_id] = 2
1074 1074 post :destroy, :ids => [1, 3], :todo => 'nullify'
1075 1075 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1076 1076 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1077 1077 assert_nil TimeEntry.find(1).issue_id
1078 1078 assert_nil TimeEntry.find(2).issue_id
1079 1079 end
1080 1080
1081 1081 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1082 1082 @request.session[:user_id] = 2
1083 1083 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1084 1084 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1085 1085 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1086 1086 assert_equal 2, TimeEntry.find(1).issue_id
1087 1087 assert_equal 2, TimeEntry.find(2).issue_id
1088 1088 end
1089 1089 end
General Comments 0
You need to be logged in to leave comments. Login now