comparison test/functional/issues_controller_test.rb @ 1115:433d4f72a19b redmine-2.2

Update to Redmine SVN revision 11137 on 2.2-stable branch
author Chris Cannam
date Mon, 07 Jan 2013 12:01:42 +0000
parents 5f33065ddc4b
children 3e4c3460b6ca
comparison
equal deleted inserted replaced
929:5f33065ddc4b 1115:433d4f72a19b
1 # Redmine - project management software 1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 # 3 #
4 # This program is free software; you can redistribute it and/or 4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License 5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2 6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version. 7 # of the License, or (at your option) any later version.
39 :custom_fields_projects, 39 :custom_fields_projects,
40 :custom_fields_trackers, 40 :custom_fields_trackers,
41 :time_entries, 41 :time_entries,
42 :journals, 42 :journals,
43 :journal_details, 43 :journal_details,
44 :queries 44 :queries,
45 :repositories,
46 :changesets
45 47
46 include Redmine::I18n 48 include Redmine::I18n
47 49
48 def setup 50 def setup
49 @controller = IssuesController.new 51 @controller = IssuesController.new
51 @response = ActionController::TestResponse.new 53 @response = ActionController::TestResponse.new
52 User.current = nil 54 User.current = nil
53 end 55 end
54 56
55 def test_index 57 def test_index
56 Setting.default_language = 'en' 58 with_settings :default_language => "en" do
57 59 get :index
60 assert_response :success
61 assert_template 'index'
62 assert_not_nil assigns(:issues)
63 assert_nil assigns(:project)
64
65 # links to visible issues
66 assert_select 'a[href=/issues/1]', :text => /Can't print recipes/
67 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
68 # private projects hidden
69 assert_select 'a[href=/issues/6]', 0
70 assert_select 'a[href=/issues/4]', 0
71 # project column
72 assert_select 'th', :text => /Project/
73 end
74 end
75
76 def test_index_should_not_list_issues_when_module_disabled
77 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
58 get :index 78 get :index
59 assert_response :success 79 assert_response :success
60 assert_template 'index' 80 assert_template 'index'
61 assert_not_nil assigns(:issues) 81 assert_not_nil assigns(:issues)
62 assert_nil assigns(:project) 82 assert_nil assigns(:project)
63 assert_tag :tag => 'a', :content => /Can't print recipes/ 83
64 assert_tag :tag => 'a', :content => /Subproject issue/ 84 assert_select 'a[href=/issues/1]', 0
65 # private projects hidden 85 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
66 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
67 assert_no_tag :tag => 'a', :content => /Issue on project 2/
68 # project column
69 assert_tag :tag => 'th', :content => /Project/
70 end
71
72 def test_index_should_not_list_issues_when_module_disabled
73 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
74 get :index
75 assert_response :success
76 assert_template 'index'
77 assert_not_nil assigns(:issues)
78 assert_nil assigns(:project)
79 assert_no_tag :tag => 'a', :content => /Can't print recipes/
80 assert_tag :tag => 'a', :content => /Subproject issue/
81 end 86 end
82 87
83 def test_index_should_list_visible_issues_only 88 def test_index_should_list_visible_issues_only
84 get :index, :per_page => 100 89 get :index, :per_page => 100
85 assert_response :success 90 assert_response :success
91 Setting.display_subprojects_issues = 0 96 Setting.display_subprojects_issues = 0
92 get :index, :project_id => 1 97 get :index, :project_id => 1
93 assert_response :success 98 assert_response :success
94 assert_template 'index' 99 assert_template 'index'
95 assert_not_nil assigns(:issues) 100 assert_not_nil assigns(:issues)
96 assert_tag :tag => 'a', :content => /Can't print recipes/ 101
97 assert_no_tag :tag => 'a', :content => /Subproject issue/ 102 assert_select 'a[href=/issues/1]', :text => /Can't print recipes/
103 assert_select 'a[href=/issues/5]', 0
98 end 104 end
99 105
100 def test_index_with_project_and_subprojects 106 def test_index_with_project_and_subprojects
101 Setting.display_subprojects_issues = 1 107 Setting.display_subprojects_issues = 1
102 get :index, :project_id => 1 108 get :index, :project_id => 1
103 assert_response :success 109 assert_response :success
104 assert_template 'index' 110 assert_template 'index'
105 assert_not_nil assigns(:issues) 111 assert_not_nil assigns(:issues)
106 assert_tag :tag => 'a', :content => /Can't print recipes/ 112
107 assert_tag :tag => 'a', :content => /Subproject issue/ 113 assert_select 'a[href=/issues/1]', :text => /Can't print recipes/
108 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/ 114 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
109 end 115 assert_select 'a[href=/issues/6]', 0
110 116 end
111 def test_index_with_project_and_subprojects_should_show_private_subprojects 117
118 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
112 @request.session[:user_id] = 2 119 @request.session[:user_id] = 2
113 Setting.display_subprojects_issues = 1 120 Setting.display_subprojects_issues = 1
114 get :index, :project_id => 1 121 get :index, :project_id => 1
115 assert_response :success 122 assert_response :success
116 assert_template 'index' 123 assert_template 'index'
117 assert_not_nil assigns(:issues) 124 assert_not_nil assigns(:issues)
118 assert_tag :tag => 'a', :content => /Can't print recipes/ 125
119 assert_tag :tag => 'a', :content => /Subproject issue/ 126 assert_select 'a[href=/issues/1]', :text => /Can't print recipes/
120 assert_tag :tag => 'a', :content => /Issue of a private subproject/ 127 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
128 assert_select 'a[href=/issues/6]', :text => /Issue of a private subproject/
121 end 129 end
122 130
123 def test_index_with_project_and_default_filter 131 def test_index_with_project_and_default_filter
124 get :index, :project_id => 1, :set_filter => 1 132 get :index, :project_id => 1, :set_filter => 1
125 assert_response :success 133 assert_response :success
226 assert_not_nil query 234 assert_not_nil query
227 # no filter 235 # no filter
228 assert_equal({}, query.filters) 236 assert_equal({}, query.filters)
229 end 237 end
230 238
239 def test_index_with_project_custom_field_filter
240 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
241 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
242 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
243 filter_name = "project.cf_#{field.id}"
244 @request.session[:user_id] = 1
245
246 get :index, :set_filter => 1,
247 :f => [filter_name],
248 :op => {filter_name => '='},
249 :v => {filter_name => ['Foo']}
250 assert_response :success
251 assert_template 'index'
252 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
253 end
254
231 def test_index_with_query 255 def test_index_with_query
232 get :index, :project_id => 1, :query_id => 5 256 get :index, :project_id => 1, :query_id => 5
233 assert_response :success 257 assert_response :success
234 assert_template 'index' 258 assert_template 'index'
235 assert_not_nil assigns(:issues) 259 assert_not_nil assigns(:issues)
250 assert_template 'index' 274 assert_template 'index'
251 assert_not_nil assigns(:issues) 275 assert_not_nil assigns(:issues)
252 assert_not_nil assigns(:issue_count_by_group) 276 assert_not_nil assigns(:issue_count_by_group)
253 end 277 end
254 278
279 def test_index_with_query_grouped_by_user_custom_field
280 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
281 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
282 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
283 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
284 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
285
286 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
287 assert_response :success
288
289 assert_select 'tr.group', 3
290 assert_select 'tr.group' do
291 assert_select 'a', :text => 'John Smith'
292 assert_select 'span.count', :text => '1'
293 end
294 assert_select 'tr.group' do
295 assert_select 'a', :text => 'Dave Lopper'
296 assert_select 'span.count', :text => '2'
297 end
298 end
299
300 def test_index_with_query_grouped_by_tracker
301 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
302
303 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc'
304 assert_response :success
305
306 trackers = assigns(:issues).map(&:tracker).uniq
307 assert_equal [1, 2, 3], trackers.map(&:id)
308 end
309
310 def test_index_with_query_grouped_by_tracker_in_reverse_order
311 3.times {|i| Issue.generate!(:tracker_id => (i + 1))}
312
313 get :index, :set_filter => 1, :group_by => 'tracker', :sort => 'id:desc,tracker:desc'
314 assert_response :success
315
316 trackers = assigns(:issues).map(&:tracker).uniq
317 assert_equal [3, 2, 1], trackers.map(&:id)
318 end
319
255 def test_index_with_query_id_and_project_id_should_set_session_query 320 def test_index_with_query_id_and_project_id_should_set_session_query
256 get :index, :project_id => 1, :query_id => 4 321 get :index, :project_id => 1, :query_id => 4
257 assert_response :success 322 assert_response :success
258 assert_kind_of Hash, session[:query] 323 assert_kind_of Hash, session[:query]
259 assert_equal 4, session[:query][:id] 324 assert_equal 4, session[:query][:id]
260 assert_equal 1, session[:query][:project_id] 325 assert_equal 1, session[:query][:project_id]
326 end
327
328 def test_index_with_invalid_query_id_should_respond_404
329 get :index, :project_id => 1, :query_id => 999
330 assert_response 404
261 end 331 end
262 332
263 def test_index_with_cross_project_query_in_session_should_show_project_issues 333 def test_index_with_cross_project_query_in_session_should_show_project_issues
264 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil) 334 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
265 @request.session[:query] = {:id => q.id, :project_id => 1} 335 @request.session[:query] = {:id => q.id, :project_id => 1}
296 366
297 get :index, :query_id => q.id 367 get :index, :query_id => q.id
298 assert_response :success 368 assert_response :success
299 end 369 end
300 370
371 def test_index_should_omit_page_param_in_export_links
372 get :index, :page => 2
373 assert_response :success
374 assert_select 'a.atom[href=/issues.atom]'
375 assert_select 'a.csv[href=/issues.csv]'
376 assert_select 'a.pdf[href=/issues.pdf]'
377 assert_select 'form#csv-export-form[action=/issues.csv]'
378 end
379
301 def test_index_csv 380 def test_index_csv
302 get :index, :format => 'csv' 381 get :index, :format => 'csv'
303 assert_response :success 382 assert_response :success
304 assert_not_nil assigns(:issues) 383 assert_not_nil assigns(:issues)
305 assert_equal 'text/csv', @response.content_type 384 assert_equal 'text/csv; header=present', @response.content_type
306 assert @response.body.starts_with?("#,") 385 assert @response.body.starts_with?("#,")
307 lines = @response.body.chomp.split("\n") 386 lines = @response.body.chomp.split("\n")
308 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size 387 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
309 end 388 end
310 389
311 def test_index_csv_with_project 390 def test_index_csv_with_project
312 get :index, :project_id => 1, :format => 'csv' 391 get :index, :project_id => 1, :format => 'csv'
313 assert_response :success 392 assert_response :success
314 assert_not_nil assigns(:issues) 393 assert_not_nil assigns(:issues)
315 assert_equal 'text/csv', @response.content_type 394 assert_equal 'text/csv; header=present', @response.content_type
316 end 395 end
317 396
318 def test_index_csv_with_description 397 def test_index_csv_with_description
319 get :index, :format => 'csv', :description => '1' 398 get :index, :format => 'csv', :description => '1'
320 assert_response :success 399 assert_response :success
321 assert_not_nil assigns(:issues) 400 assert_not_nil assigns(:issues)
322 assert_equal 'text/csv', @response.content_type 401 assert_equal 'text/csv; header=present', @response.content_type
323 assert @response.body.starts_with?("#,") 402 assert @response.body.starts_with?("#,")
324 lines = @response.body.chomp.split("\n") 403 lines = @response.body.chomp.split("\n")
325 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size 404 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
326 end 405 end
327 406
407 def test_index_csv_with_spent_time_column
408 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
409 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
410
411 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
412 assert_response :success
413 assert_equal 'text/csv; header=present', @response.content_type
414 lines = @response.body.chomp.split("\n")
415 assert_include "#{issue.id},#{issue.subject},7.33", lines
416 end
417
328 def test_index_csv_with_all_columns 418 def test_index_csv_with_all_columns
329 get :index, :format => 'csv', :columns => 'all' 419 get :index, :format => 'csv', :columns => 'all'
330 assert_response :success 420 assert_response :success
331 assert_not_nil assigns(:issues) 421 assert_not_nil assigns(:issues)
332 assert_equal 'text/csv', @response.content_type 422 assert_equal 'text/csv; header=present', @response.content_type
333 assert @response.body.starts_with?("#,") 423 assert @response.body.starts_with?("#,")
334 lines = @response.body.chomp.split("\n") 424 lines = @response.body.chomp.split("\n")
335 assert_equal assigns(:query).available_columns.size + 1, lines[0].split(',').size 425 assert_equal assigns(:query).available_inline_columns.size + 1, lines[0].split(',').size
426 end
427
428 def test_index_csv_with_multi_column_field
429 CustomField.find(1).update_attribute :multiple, true
430 issue = Issue.find(1)
431 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
432 issue.save!
433
434 get :index, :format => 'csv', :columns => 'all'
435 assert_response :success
436 lines = @response.body.chomp.split("\n")
437 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
336 end 438 end
337 439
338 def test_index_csv_big_5 440 def test_index_csv_big_5
339 with_settings :default_language => "zh-TW" do 441 with_settings :default_language => "zh-TW" do
340 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88" 442 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
341 str_big5 = "\xa4@\xa4\xeb" 443 str_big5 = "\xa4@\xa4\xeb"
342 if str_utf8.respond_to?(:force_encoding) 444 if str_utf8.respond_to?(:force_encoding)
343 str_utf8.force_encoding('UTF-8') 445 str_utf8.force_encoding('UTF-8')
344 str_big5.force_encoding('Big5') 446 str_big5.force_encoding('Big5')
345 end 447 end
346 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, 448 issue = Issue.generate!(:subject => str_utf8)
347 :status_id => 1, :priority => IssuePriority.all.first,
348 :subject => str_utf8)
349 assert issue.save
350 449
351 get :index, :project_id => 1, 450 get :index, :project_id => 1,
352 :f => ['subject'], 451 :f => ['subject'],
353 :op => '=', :values => [str_utf8], 452 :op => '=', :values => [str_utf8],
354 :format => 'csv' 453 :format => 'csv'
355 assert_equal 'text/csv', @response.content_type 454 assert_equal 'text/csv; header=present', @response.content_type
356 lines = @response.body.chomp.split("\n") 455 lines = @response.body.chomp.split("\n")
357 s1 = "\xaa\xac\xbaA" 456 s1 = "\xaa\xac\xbaA"
358 if str_utf8.respond_to?(:force_encoding) 457 if str_utf8.respond_to?(:force_encoding)
359 s1.force_encoding('Big5') 458 s1.force_encoding('Big5')
360 end 459 end
367 with_settings :default_language => "zh-TW" do 466 with_settings :default_language => "zh-TW" do
368 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85" 467 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
369 if str_utf8.respond_to?(:force_encoding) 468 if str_utf8.respond_to?(:force_encoding)
370 str_utf8.force_encoding('UTF-8') 469 str_utf8.force_encoding('UTF-8')
371 end 470 end
372 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, 471 issue = Issue.generate!(:subject => str_utf8)
373 :status_id => 1, :priority => IssuePriority.all.first,
374 :subject => str_utf8)
375 assert issue.save
376 472
377 get :index, :project_id => 1, 473 get :index, :project_id => 1,
378 :f => ['subject'], 474 :f => ['subject'],
379 :op => '=', :values => [str_utf8], 475 :op => '=', :values => [str_utf8],
380 :c => ['status', 'subject'], 476 :c => ['status', 'subject'],
381 :format => 'csv', 477 :format => 'csv',
382 :set_filter => 1 478 :set_filter => 1
383 assert_equal 'text/csv', @response.content_type 479 assert_equal 'text/csv; header=present', @response.content_type
384 lines = @response.body.chomp.split("\n") 480 lines = @response.body.chomp.split("\n")
385 s1 = "\xaa\xac\xbaA" # status 481 s1 = "\xaa\xac\xbaA" # status
386 if str_utf8.respond_to?(:force_encoding) 482 if str_utf8.respond_to?(:force_encoding)
387 s1.force_encoding('Big5') 483 s1.force_encoding('Big5')
388 end 484 end
401 end 497 end
402 498
403 def test_index_csv_tw 499 def test_index_csv_tw
404 with_settings :default_language => "zh-TW" do 500 with_settings :default_language => "zh-TW" do
405 str1 = "test_index_csv_tw" 501 str1 = "test_index_csv_tw"
406 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, 502 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
407 :status_id => 1, :priority => IssuePriority.all.first,
408 :subject => str1, :estimated_hours => '1234.5')
409 assert issue.save
410 assert_equal 1234.5, issue.estimated_hours
411 503
412 get :index, :project_id => 1, 504 get :index, :project_id => 1,
413 :f => ['subject'], 505 :f => ['subject'],
414 :op => '=', :values => [str1], 506 :op => '=', :values => [str1],
415 :c => ['estimated_hours', 'subject'], 507 :c => ['estimated_hours', 'subject'],
416 :format => 'csv', 508 :format => 'csv',
417 :set_filter => 1 509 :set_filter => 1
418 assert_equal 'text/csv', @response.content_type 510 assert_equal 'text/csv; header=present', @response.content_type
419 lines = @response.body.chomp.split("\n") 511 lines = @response.body.chomp.split("\n")
420 assert_equal "#{issue.id},1234.5,#{str1}", lines[1] 512 assert_equal "#{issue.id},1234.50,#{str1}", lines[1]
421
422 str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
423 if str_tw.respond_to?(:force_encoding)
424 str_tw.force_encoding('UTF-8')
425 end
426 assert_equal str_tw, l(:general_lang_name)
427 assert_equal ',', l(:general_csv_separator)
428 assert_equal '.', l(:general_csv_decimal_separator)
429 end 513 end
430 end 514 end
431 515
432 def test_index_csv_fr 516 def test_index_csv_fr
433 with_settings :default_language => "fr" do 517 with_settings :default_language => "fr" do
434 str1 = "test_index_csv_fr" 518 str1 = "test_index_csv_fr"
435 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, 519 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
436 :status_id => 1, :priority => IssuePriority.all.first,
437 :subject => str1, :estimated_hours => '1234.5')
438 assert issue.save
439 assert_equal 1234.5, issue.estimated_hours
440 520
441 get :index, :project_id => 1, 521 get :index, :project_id => 1,
442 :f => ['subject'], 522 :f => ['subject'],
443 :op => '=', :values => [str1], 523 :op => '=', :values => [str1],
444 :c => ['estimated_hours', 'subject'], 524 :c => ['estimated_hours', 'subject'],
445 :format => 'csv', 525 :format => 'csv',
446 :set_filter => 1 526 :set_filter => 1
447 assert_equal 'text/csv', @response.content_type 527 assert_equal 'text/csv; header=present', @response.content_type
448 lines = @response.body.chomp.split("\n") 528 lines = @response.body.chomp.split("\n")
449 assert_equal "#{issue.id};1234,5;#{str1}", lines[1] 529 assert_equal "#{issue.id};1234,50;#{str1}", lines[1]
450
451 str_fr = "Fran\xc3\xa7ais"
452 if str_fr.respond_to?(:force_encoding)
453 str_fr.force_encoding('UTF-8')
454 end
455 assert_equal str_fr, l(:general_lang_name)
456 assert_equal ';', l(:general_csv_separator)
457 assert_equal ',', l(:general_csv_decimal_separator)
458 end 530 end
459 end 531 end
460 532
461 def test_index_pdf 533 def test_index_pdf
462 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang| 534 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
499 assert_not_nil assigns(:issues) 571 assert_not_nil assigns(:issues)
500 assert_not_nil assigns(:issue_count_by_group) 572 assert_not_nil assigns(:issue_count_by_group)
501 assert_equal 'application/pdf', @response.content_type 573 assert_equal 'application/pdf', @response.content_type
502 end 574 end
503 575
576 def test_index_atom
577 get :index, :project_id => 'ecookbook', :format => 'atom'
578 assert_response :success
579 assert_template 'common/feed'
580 assert_equal 'application/atom+xml', response.content_type
581
582 assert_select 'feed' do
583 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
584 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
585 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
586 end
587 end
588
504 def test_index_sort 589 def test_index_sort
505 get :index, :sort => 'tracker,id:desc' 590 get :index, :sort => 'tracker,id:desc'
506 assert_response :success 591 assert_response :success
507 592
508 sort_params = @request.session['issues_index_sort'] 593 sort_params = @request.session['issues_index_sort']
555 640
556 def test_index_group_by_author 641 def test_index_group_by_author
557 get :index, :group_by => 'author', :sort => 'priority' 642 get :index, :group_by => 'author', :sort => 'priority'
558 assert_response :success 643 assert_response :success
559 end 644 end
645
646 def test_index_sort_by_spent_hours
647 get :index, :sort => 'spent_hours:desc'
648 assert_response :success
649 hours = assigns(:issues).collect(&:spent_hours)
650 assert_equal hours.sort.reverse, hours
651 end
652
653 def test_index_sort_by_user_custom_field
654 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
655 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
656 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
657 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
658 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
659
660 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
661 assert_response :success
662
663 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
664 end
560 665
561 def test_index_with_columns 666 def test_index_with_columns
562 columns = ['tracker', 'subject', 'assigned_to'] 667 columns = ['tracker', 'subject', 'assigned_to']
563 get :index, :set_filter => 1, :c => columns 668 get :index, :set_filter => 1, :c => columns
564 assert_response :success 669 assert_response :success
572 assert_kind_of Hash, session[:query] 677 assert_kind_of Hash, session[:query]
573 assert_kind_of Array, session[:query][:column_names] 678 assert_kind_of Array, session[:query][:column_names]
574 assert_equal columns, session[:query][:column_names].map(&:to_s) 679 assert_equal columns, session[:query][:column_names].map(&:to_s)
575 680
576 # ensure only these columns are kept in the selected columns list 681 # ensure only these columns are kept in the selected columns list
577 assert_tag :tag => 'select', :attributes => { :id => 'selected_columns' }, 682 assert_select 'select#selected_columns option' do
578 :children => { :count => 3 } 683 assert_select 'option', 3
579 assert_no_tag :tag => 'option', :attributes => { :value => 'project' }, 684 assert_select 'option[value=tracker]'
580 :parent => { :tag => 'select', :attributes => { :id => "selected_columns" } } 685 assert_select 'option[value=project]', 0
686 end
581 end 687 end
582 688
583 def test_index_without_project_should_implicitly_add_project_column_to_default_columns 689 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
584 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to'] 690 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
585 get :index, :set_filter => 1 691 get :index, :set_filter => 1
609 # query should use specified columns 715 # query should use specified columns
610 query = assigns(:query) 716 query = assigns(:query)
611 assert_kind_of Query, query 717 assert_kind_of Query, query
612 assert_equal columns, query.column_names.map(&:to_s) 718 assert_equal columns, query.column_names.map(&:to_s)
613 719
614 assert_tag :td, 720 assert_select 'table.issues td.cf_2.string'
615 :attributes => {:class => 'cf_2 string'}, 721 end
616 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}} 722
723 def test_index_with_multi_custom_field_column
724 field = CustomField.find(1)
725 field.update_attribute :multiple, true
726 issue = Issue.find(1)
727 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
728 issue.save!
729
730 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
731 assert_response :success
732
733 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
734 end
735
736 def test_index_with_multi_user_custom_field_column
737 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
738 :tracker_ids => [1], :is_for_all => true)
739 issue = Issue.find(1)
740 issue.custom_field_values = {field.id => ['2', '3']}
741 issue.save!
742
743 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
744 assert_response :success
745
746 assert_select "table.issues td.cf_#{field.id}" do
747 assert_select 'a', 2
748 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
749 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
750 end
617 end 751 end
618 752
619 def test_index_with_date_column 753 def test_index_with_date_column
620 Issue.find(1).update_attribute :start_date, '1987-08-24'
621
622 with_settings :date_format => '%d/%m/%Y' do 754 with_settings :date_format => '%d/%m/%Y' do
755 Issue.find(1).update_attribute :start_date, '1987-08-24'
756
623 get :index, :set_filter => 1, :c => %w(start_date) 757 get :index, :set_filter => 1, :c => %w(start_date)
624 assert_tag 'td', :attributes => {:class => /start_date/}, :content => '24/08/1987' 758
625 end 759 assert_select "table.issues td.start_date", :text => '24/08/1987'
626 end 760 end
627 761 end
628 def test_index_with_done_ratio 762
763 def test_index_with_done_ratio_column
629 Issue.find(1).update_attribute :done_ratio, 40 764 Issue.find(1).update_attribute :done_ratio, 40
630 765
631 get :index, :set_filter => 1, :c => %w(done_ratio) 766 get :index, :set_filter => 1, :c => %w(done_ratio)
632 assert_tag 'td', :attributes => {:class => /done_ratio/}, 767
633 :child => {:tag => 'table', :attributes => {:class => 'progress'}, 768 assert_select 'table.issues td.done_ratio' do
634 :descendant => {:tag => 'td', :attributes => {:class => 'closed', :style => 'width: 40%;'}} 769 assert_select 'table.progress' do
635 } 770 assert_select 'td.closed[style=?]', 'width: 40%;'
636 end 771 end
637 772 end
638 def test_index_with_fixed_version 773 end
774
775 def test_index_with_spent_hours_column
776 get :index, :set_filter => 1, :c => %w(subject spent_hours)
777
778 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
779 end
780
781 def test_index_should_not_show_spent_hours_column_without_permission
782 Role.anonymous.remove_permission! :view_time_entries
783 get :index, :set_filter => 1, :c => %w(subject spent_hours)
784
785 assert_select 'td.spent_hours', 0
786 end
787
788 def test_index_with_fixed_version_column
639 get :index, :set_filter => 1, :c => %w(fixed_version) 789 get :index, :set_filter => 1, :c => %w(fixed_version)
640 assert_tag 'td', :attributes => {:class => /fixed_version/}, 790
641 :child => {:tag => 'a', :content => '1.0', :attributes => {:href => '/versions/2'}} 791 assert_select 'table.issues td.fixed_version' do
792 assert_select 'a[href=?]', '/versions/2', :text => '1.0'
793 end
794 end
795
796 def test_index_with_relations_column
797 IssueRelation.delete_all
798 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
799 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
800 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
801 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
802
803 get :index, :set_filter => 1, :c => %w(subject relations)
804 assert_response :success
805 assert_select "tr#issue-1 td.relations" do
806 assert_select "span", 3
807 assert_select "span", :text => "Related to #7"
808 assert_select "span", :text => "Related to #8"
809 assert_select "span", :text => "Blocks #11"
810 end
811 assert_select "tr#issue-2 td.relations" do
812 assert_select "span", 1
813 assert_select "span", :text => "Blocked by #12"
814 end
815 assert_select "tr#issue-3 td.relations" do
816 assert_select "span", 0
817 end
818
819 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
820 assert_response :success
821 assert_equal 'text/csv; header=present', response.content_type
822 lines = response.body.chomp.split("\n")
823 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
824 assert_include '2,Blocked by #12', lines
825 assert_include '3,""', lines
826
827 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
828 assert_response :success
829 assert_equal 'application/pdf', response.content_type
830 end
831
832 def test_index_with_description_column
833 get :index, :set_filter => 1, :c => %w(subject description)
834
835 assert_select 'table.issues thead th', 3 # columns: chekbox + id + subject
836 assert_select 'td.description[colspan=3]', :text => 'Unable to print recipes'
837
838 get :index, :set_filter => 1, :c => %w(subject description), :format => 'pdf'
839 assert_response :success
840 assert_equal 'application/pdf', response.content_type
642 end 841 end
643 842
644 def test_index_send_html_if_query_is_invalid 843 def test_index_send_html_if_query_is_invalid
645 get :index, :f => ['start_date'], :op => {:start_date => '='} 844 get :index, :f => ['start_date'], :op => {:start_date => '='}
646 assert_equal 'text/html', @response.content_type 845 assert_equal 'text/html', @response.content_type
655 854
656 def test_show_by_anonymous 855 def test_show_by_anonymous
657 get :show, :id => 1 856 get :show, :id => 1
658 assert_response :success 857 assert_response :success
659 assert_template 'show' 858 assert_template 'show'
660 assert_not_nil assigns(:issue)
661 assert_equal Issue.find(1), assigns(:issue) 859 assert_equal Issue.find(1), assigns(:issue)
662 860
861 assert_select 'div.issue div.description', :text => /Unable to print recipes/
862
663 # anonymous role is allowed to add a note 863 # anonymous role is allowed to add a note
664 assert_tag :tag => 'form', 864 assert_select 'form#issue-form' do
665 :descendant => { :tag => 'fieldset', 865 assert_select 'fieldset' do
666 :child => { :tag => 'legend', 866 assert_select 'legend', :text => 'Notes'
667 :content => /Notes/ } } 867 assert_select 'textarea[name=?]', 'issue[notes]'
668 assert_tag :tag => 'title', 868 end
669 :content => "Bug #1: Can't print recipes - eCookbook - Redmine" 869 end
870
871 assert_select 'title', :text => "Bug #1: Can't print recipes - eCookbook - Redmine"
670 end 872 end
671 873
672 def test_show_by_manager 874 def test_show_by_manager
673 @request.session[:user_id] = 2 875 @request.session[:user_id] = 2
674 get :show, :id => 1 876 get :show, :id => 1
675 assert_response :success 877 assert_response :success
676 878
677 assert_tag :tag => 'a', 879 assert_select 'a', :text => /Quote/
678 :content => /Quote/ 880
679 881 assert_select 'form#issue-form' do
680 assert_tag :tag => 'form', 882 assert_select 'fieldset' do
681 :descendant => { :tag => 'fieldset', 883 assert_select 'legend', :text => 'Change properties'
682 :child => { :tag => 'legend', 884 assert_select 'input[name=?]', 'issue[subject]'
683 :content => /Change properties/ } }, 885 end
684 :descendant => { :tag => 'fieldset', 886 assert_select 'fieldset' do
685 :child => { :tag => 'legend', 887 assert_select 'legend', :text => 'Log time'
686 :content => /Log time/ } }, 888 assert_select 'input[name=?]', 'time_entry[hours]'
687 :descendant => { :tag => 'fieldset', 889 end
688 :child => { :tag => 'legend', 890 assert_select 'fieldset' do
689 :content => /Notes/ } } 891 assert_select 'legend', :text => 'Notes'
892 assert_select 'textarea[name=?]', 'issue[notes]'
893 end
894 end
895 end
896
897 def test_show_should_display_update_form
898 @request.session[:user_id] = 2
899 get :show, :id => 1
900 assert_response :success
901
902 assert_tag 'form', :attributes => {:id => 'issue-form'}
903 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
904 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
905 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
906 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
907 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
908 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
909 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
910 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
911 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
912 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
913 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
914 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
915 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
916 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
917 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
918 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
919 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
920 end
921
922 def test_show_should_display_update_form_with_minimal_permissions
923 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
924 WorkflowTransition.delete_all :role_id => 1
925
926 @request.session[:user_id] = 2
927 get :show, :id => 1
928 assert_response :success
929
930 assert_tag 'form', :attributes => {:id => 'issue-form'}
931 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
932 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
933 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
934 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
935 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
936 assert_no_tag 'select', :attributes => {:name => 'issue[status_id]'}
937 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
938 assert_no_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
939 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
940 assert_no_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
941 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
942 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
943 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
944 assert_no_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
945 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
946 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
947 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
948 end
949
950 def test_show_should_display_update_form_with_workflow_permissions
951 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
952
953 @request.session[:user_id] = 2
954 get :show, :id => 1
955 assert_response :success
956
957 assert_tag 'form', :attributes => {:id => 'issue-form'}
958 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
959 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
960 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
961 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
962 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
963 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
964 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
965 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
966 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
967 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
968 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
969 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
970 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
971 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
972 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
973 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
974 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
975 end
976
977 def test_show_should_not_display_update_form_without_permissions
978 Role.find(1).update_attribute :permissions, [:view_issues]
979
980 @request.session[:user_id] = 2
981 get :show, :id => 1
982 assert_response :success
983
984 assert_select 'form#issue-form', 0
690 end 985 end
691 986
692 def test_update_form_should_not_display_inactive_enumerations 987 def test_update_form_should_not_display_inactive_enumerations
988 assert !IssuePriority.find(15).active?
989
693 @request.session[:user_id] = 2 990 @request.session[:user_id] = 2
694 get :show, :id => 1 991 get :show, :id => 1
695 assert_response :success 992 assert_response :success
696 993
697 assert ! IssuePriority.find(15).active? 994 assert_select 'form#issue-form' do
698 assert_no_tag :option, :attributes => {:value => '15'}, 995 assert_select 'select[name=?]', 'issue[priority_id]' do
699 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} } 996 assert_select 'option[value=4]'
997 assert_select 'option[value=15]', 0
998 end
999 end
700 end 1000 end
701 1001
702 def test_update_form_should_allow_attachment_upload 1002 def test_update_form_should_allow_attachment_upload
703 @request.session[:user_id] = 2 1003 @request.session[:user_id] = 2
704 get :show, :id => 1 1004 get :show, :id => 1
705 1005
706 assert_tag :tag => 'form', 1006 assert_select 'form#issue-form[method=post][enctype=multipart/form-data]' do
707 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'}, 1007 assert_select 'input[type=file][name=?]', 'attachments[1][file]'
708 :descendant => { 1008 end
709 :tag => 'input',
710 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
711 }
712 end 1009 end
713 1010
714 def test_show_should_deny_anonymous_access_without_permission 1011 def test_show_should_deny_anonymous_access_without_permission
715 Role.anonymous.remove_permission!(:view_issues) 1012 Role.anonymous.remove_permission!(:view_issues)
716 get :show, :id => 1 1013 get :show, :id => 1
780 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates') 1077 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
781 1078
782 get :show, :id => 1 1079 get :show, :id => 1
783 assert_response :success 1080 assert_response :success
784 1081
785 assert_tag :div, :attributes => { :id => 'relations' }, 1082 assert_select 'div#relations' do
786 :descendant => { :tag => 'a', :content => /#2$/ } 1083 assert_select 'a', :text => /#2$/
787 assert_no_tag :div, :attributes => { :id => 'relations' }, 1084 assert_select 'a', :text => /#4$/, :count => 0
788 :descendant => { :tag => 'a', :content => /#4$/ } 1085 end
1086 end
1087
1088 def test_show_should_list_subtasks
1089 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1090
1091 get :show, :id => 1
1092 assert_response :success
1093
1094 assert_select 'div#issue_tree' do
1095 assert_select 'td.subject', :text => /Child Issue/
1096 end
1097 end
1098
1099 def test_show_should_list_parents
1100 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1101
1102 get :show, :id => issue.id
1103 assert_response :success
1104
1105 assert_select 'div.subject' do
1106 assert_select 'h3', 'Child Issue'
1107 assert_select 'a[href=/issues/1]'
1108 end
1109 end
1110
1111 def test_show_should_not_display_prev_next_links_without_query_in_session
1112 get :show, :id => 1
1113 assert_response :success
1114 assert_nil assigns(:prev_issue_id)
1115 assert_nil assigns(:next_issue_id)
1116
1117 assert_select 'div.next-prev-links', 0
1118 end
1119
1120 def test_show_should_display_prev_next_links_with_query_in_session
1121 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1122 @request.session['issues_index_sort'] = 'id'
1123
1124 with_settings :display_subprojects_issues => '0' do
1125 get :show, :id => 3
1126 end
1127
1128 assert_response :success
1129 # Previous and next issues for all projects
1130 assert_equal 2, assigns(:prev_issue_id)
1131 assert_equal 5, assigns(:next_issue_id)
1132
1133 count = Issue.open.visible.count
1134
1135 assert_select 'div.next-prev-links' do
1136 assert_select 'a[href=/issues/2]', :text => /Previous/
1137 assert_select 'a[href=/issues/5]', :text => /Next/
1138 assert_select 'span.position', :text => "3 of #{count}"
1139 end
1140 end
1141
1142 def test_show_should_display_prev_next_links_with_saved_query_in_session
1143 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1,
1144 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1145 :sort_criteria => [['id', 'asc']])
1146 @request.session[:query] = {:id => query.id, :project_id => nil}
1147
1148 get :show, :id => 11
1149
1150 assert_response :success
1151 assert_equal query, assigns(:query)
1152 # Previous and next issues for all projects
1153 assert_equal 8, assigns(:prev_issue_id)
1154 assert_equal 12, assigns(:next_issue_id)
1155
1156 assert_select 'div.next-prev-links' do
1157 assert_select 'a[href=/issues/8]', :text => /Previous/
1158 assert_select 'a[href=/issues/12]', :text => /Next/
1159 end
1160 end
1161
1162 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1163 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1164
1165 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1166 @request.session['issues_index_sort'] = assoc_sort
1167
1168 get :show, :id => 3
1169 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1170
1171 assert_select 'div.next-prev-links' do
1172 assert_select 'a', :text => /(Previous|Next)/
1173 end
1174 end
1175 end
1176
1177 def test_show_should_display_prev_next_links_with_project_query_in_session
1178 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1179 @request.session['issues_index_sort'] = 'id'
1180
1181 with_settings :display_subprojects_issues => '0' do
1182 get :show, :id => 3
1183 end
1184
1185 assert_response :success
1186 # Previous and next issues inside project
1187 assert_equal 2, assigns(:prev_issue_id)
1188 assert_equal 7, assigns(:next_issue_id)
1189
1190 assert_select 'div.next-prev-links' do
1191 assert_select 'a[href=/issues/2]', :text => /Previous/
1192 assert_select 'a[href=/issues/7]', :text => /Next/
1193 end
1194 end
1195
1196 def test_show_should_not_display_prev_link_for_first_issue
1197 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1198 @request.session['issues_index_sort'] = 'id'
1199
1200 with_settings :display_subprojects_issues => '0' do
1201 get :show, :id => 1
1202 end
1203
1204 assert_response :success
1205 assert_nil assigns(:prev_issue_id)
1206 assert_equal 2, assigns(:next_issue_id)
1207
1208 assert_select 'div.next-prev-links' do
1209 assert_select 'a', :text => /Previous/, :count => 0
1210 assert_select 'a[href=/issues/2]', :text => /Next/
1211 end
1212 end
1213
1214 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1215 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1216 @request.session['issues_index_sort'] = 'id'
1217
1218 get :show, :id => 1
1219
1220 assert_response :success
1221 assert_nil assigns(:prev_issue_id)
1222 assert_nil assigns(:next_issue_id)
1223
1224 assert_select 'a', :text => /Previous/, :count => 0
1225 assert_select 'a', :text => /Next/, :count => 0
1226 end
1227
1228 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1229 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1230 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1231 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1232 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1233 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1234
1235 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1, :filters => {},
1236 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1237 @request.session[:query] = {:id => query.id, :project_id => nil}
1238
1239 get :show, :id => 3
1240 assert_response :success
1241
1242 assert_equal 2, assigns(:prev_issue_id)
1243 assert_equal 1, assigns(:next_issue_id)
1244
1245 assert_select 'div.next-prev-links' do
1246 assert_select 'a[href=/issues/2]', :text => /Previous/
1247 assert_select 'a[href=/issues/1]', :text => /Next/
1248 end
1249 end
1250
1251 def test_show_should_display_link_to_the_assignee
1252 get :show, :id => 2
1253 assert_response :success
1254 assert_select '.assigned-to' do
1255 assert_select 'a[href=/users/3]'
1256 end
1257 end
1258
1259 def test_show_should_display_visible_changesets_from_other_projects
1260 project = Project.find(2)
1261 issue = project.issues.first
1262 issue.changeset_ids = [102]
1263 issue.save!
1264 # changesets from other projects should be displayed even if repository
1265 # is disabled on issue's project
1266 project.disable_module! :repository
1267
1268 @request.session[:user_id] = 2
1269 get :show, :id => issue.id
1270
1271 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1272 end
1273
1274 def test_show_should_display_watchers
1275 @request.session[:user_id] = 2
1276 Issue.find(1).add_watcher User.find(2)
1277
1278 get :show, :id => 1
1279 assert_select 'div#watchers ul' do
1280 assert_select 'li' do
1281 assert_select 'a[href=/users/2]'
1282 assert_select 'a img[alt=Delete]'
1283 end
1284 end
1285 end
1286
1287 def test_show_should_display_watchers_with_gravatars
1288 @request.session[:user_id] = 2
1289 Issue.find(1).add_watcher User.find(2)
1290
1291 with_settings :gravatar_enabled => '1' do
1292 get :show, :id => 1
1293 end
1294
1295 assert_select 'div#watchers ul' do
1296 assert_select 'li' do
1297 assert_select 'img.gravatar'
1298 assert_select 'a[href=/users/2]'
1299 assert_select 'a img[alt=Delete]'
1300 end
1301 end
1302 end
1303
1304 def test_show_with_thumbnails_enabled_should_display_thumbnails
1305 @request.session[:user_id] = 2
1306
1307 with_settings :thumbnails_enabled => '1' do
1308 get :show, :id => 14
1309 assert_response :success
1310 end
1311
1312 assert_select 'div.thumbnails' do
1313 assert_select 'a[href=/attachments/16/testfile.png]' do
1314 assert_select 'img[src=/attachments/thumbnail/16]'
1315 end
1316 end
1317 end
1318
1319 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1320 @request.session[:user_id] = 2
1321
1322 with_settings :thumbnails_enabled => '0' do
1323 get :show, :id => 14
1324 assert_response :success
1325 end
1326
1327 assert_select 'div.thumbnails', 0
1328 end
1329
1330 def test_show_with_multi_custom_field
1331 field = CustomField.find(1)
1332 field.update_attribute :multiple, true
1333 issue = Issue.find(1)
1334 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1335 issue.save!
1336
1337 get :show, :id => 1
1338 assert_response :success
1339
1340 assert_select 'td', :text => 'MySQL, Oracle'
1341 end
1342
1343 def test_show_with_multi_user_custom_field
1344 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1345 :tracker_ids => [1], :is_for_all => true)
1346 issue = Issue.find(1)
1347 issue.custom_field_values = {field.id => ['2', '3']}
1348 issue.save!
1349
1350 get :show, :id => 1
1351 assert_response :success
1352
1353 # TODO: should display links
1354 assert_select 'td', :text => 'Dave Lopper, John Smith'
1355 end
1356
1357 def test_show_should_display_private_notes_with_permission_only
1358 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1359 @request.session[:user_id] = 2
1360
1361 get :show, :id => 2
1362 assert_response :success
1363 assert_include journal, assigns(:journals)
1364
1365 Role.find(1).remove_permission! :view_private_notes
1366 get :show, :id => 2
1367 assert_response :success
1368 assert_not_include journal, assigns(:journals)
789 end 1369 end
790 1370
791 def test_show_atom 1371 def test_show_atom
792 get :show, :id => 2, :format => 'atom' 1372 get :show, :id => 2, :format => 'atom'
793 assert_response :success 1373 assert_response :success
802 assert_equal 'application/pdf', @response.content_type 1382 assert_equal 'application/pdf', @response.content_type
803 assert @response.body.starts_with?('%PDF') 1383 assert @response.body.starts_with?('%PDF')
804 assert_not_nil assigns(:issue) 1384 assert_not_nil assigns(:issue)
805 end 1385 end
806 1386
1387 def test_show_export_to_pdf_with_ancestors
1388 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1389
1390 get :show, :id => issue.id, :format => 'pdf'
1391 assert_response :success
1392 assert_equal 'application/pdf', @response.content_type
1393 assert @response.body.starts_with?('%PDF')
1394 end
1395
1396 def test_show_export_to_pdf_with_descendants
1397 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1398 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1399 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1400
1401 get :show, :id => 1, :format => 'pdf'
1402 assert_response :success
1403 assert_equal 'application/pdf', @response.content_type
1404 assert @response.body.starts_with?('%PDF')
1405 end
1406
1407 def test_show_export_to_pdf_with_journals
1408 get :show, :id => 1, :format => 'pdf'
1409 assert_response :success
1410 assert_equal 'application/pdf', @response.content_type
1411 assert @response.body.starts_with?('%PDF')
1412 end
1413
1414 def test_show_export_to_pdf_with_changesets
1415 Issue.find(3).changesets = Changeset.find_all_by_id(100, 101, 102)
1416
1417 get :show, :id => 3, :format => 'pdf'
1418 assert_response :success
1419 assert_equal 'application/pdf', @response.content_type
1420 assert @response.body.starts_with?('%PDF')
1421 end
1422
807 def test_get_new 1423 def test_get_new
808 @request.session[:user_id] = 2 1424 @request.session[:user_id] = 2
809 get :new, :project_id => 1, :tracker_id => 1 1425 get :new, :project_id => 1, :tracker_id => 1
810 assert_response :success 1426 assert_response :success
811 assert_template 'new' 1427 assert_template 'new'
812 1428
813 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]', 1429 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
814 :value => 'Default string' } 1430 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1431 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1432 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1433 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1434 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1435 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1436 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1437 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1438 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1439 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1440 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1441 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1442 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1443 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1444 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
815 1445
816 # Be sure we don't display inactive IssuePriorities 1446 # Be sure we don't display inactive IssuePriorities
817 assert ! IssuePriority.find(15).active? 1447 assert ! IssuePriority.find(15).active?
818 assert_no_tag :option, :attributes => {:value => '15'}, 1448 assert_no_tag :option, :attributes => {:value => '15'},
819 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} } 1449 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
820 end 1450 end
821 1451
1452 def test_get_new_with_minimal_permissions
1453 Role.find(1).update_attribute :permissions, [:add_issues]
1454 WorkflowTransition.delete_all :role_id => 1
1455
1456 @request.session[:user_id] = 2
1457 get :new, :project_id => 1, :tracker_id => 1
1458 assert_response :success
1459 assert_template 'new'
1460
1461 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
1462 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1463 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1464 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1465 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1466 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1467 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1468 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1469 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1470 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1471 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1472 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1473 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1474 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1475 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1476 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1477 end
1478
1479 def test_get_new_with_list_custom_field
1480 @request.session[:user_id] = 2
1481 get :new, :project_id => 1, :tracker_id => 1
1482 assert_response :success
1483 assert_template 'new'
1484
1485 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1486 assert_select 'option', 4
1487 assert_select 'option[value=MySQL]', :text => 'MySQL'
1488 end
1489 end
1490
1491 def test_get_new_with_multi_custom_field
1492 field = IssueCustomField.find(1)
1493 field.update_attribute :multiple, true
1494
1495 @request.session[:user_id] = 2
1496 get :new, :project_id => 1, :tracker_id => 1
1497 assert_response :success
1498 assert_template 'new'
1499
1500 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1501 assert_select 'option', 3
1502 assert_select 'option[value=MySQL]', :text => 'MySQL'
1503 end
1504 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1505 end
1506
1507 def test_get_new_with_multi_user_custom_field
1508 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1509 :tracker_ids => [1], :is_for_all => true)
1510
1511 @request.session[:user_id] = 2
1512 get :new, :project_id => 1, :tracker_id => 1
1513 assert_response :success
1514 assert_template 'new'
1515
1516 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1517 assert_select 'option', Project.find(1).users.count
1518 assert_select 'option[value=2]', :text => 'John Smith'
1519 end
1520 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1521 end
1522
1523 def test_get_new_with_date_custom_field
1524 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1525
1526 @request.session[:user_id] = 2
1527 get :new, :project_id => 1, :tracker_id => 1
1528 assert_response :success
1529
1530 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1531 end
1532
1533 def test_get_new_with_text_custom_field
1534 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1535
1536 @request.session[:user_id] = 2
1537 get :new, :project_id => 1, :tracker_id => 1
1538 assert_response :success
1539
1540 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1541 end
1542
822 def test_get_new_without_default_start_date_is_creation_date 1543 def test_get_new_without_default_start_date_is_creation_date
823 Setting.default_issue_start_date_to_creation_date = 0 1544 Setting.default_issue_start_date_to_creation_date = 0
824 1545
825 @request.session[:user_id] = 2 1546 @request.session[:user_id] = 2
826 get :new, :project_id => 1, :tracker_id => 1 1547 get :new, :project_id => 1, :tracker_id => 1
827 assert_response :success 1548 assert_response :success
828 assert_template 'new' 1549 assert_template 'new'
829 1550
830 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]', 1551 assert_select 'input[name=?]', 'issue[start_date]'
831 :value => nil } 1552 assert_select 'input[name=?][value]', 'issue[start_date]', 0
832 end 1553 end
833 1554
834 def test_get_new_with_default_start_date_is_creation_date 1555 def test_get_new_with_default_start_date_is_creation_date
835 Setting.default_issue_start_date_to_creation_date = 1 1556 Setting.default_issue_start_date_to_creation_date = 1
836 1557
837 @request.session[:user_id] = 2 1558 @request.session[:user_id] = 2
838 get :new, :project_id => 1, :tracker_id => 1 1559 get :new, :project_id => 1, :tracker_id => 1
839 assert_response :success 1560 assert_response :success
840 assert_template 'new' 1561 assert_template 'new'
841 1562
842 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]', 1563 assert_select 'input[name=?][value=?]', 'issue[start_date]', Date.today.to_s
843 :value => Date.today.to_s }
844 end 1564 end
845 1565
846 def test_get_new_form_should_allow_attachment_upload 1566 def test_get_new_form_should_allow_attachment_upload
847 @request.session[:user_id] = 2 1567 @request.session[:user_id] = 2
848 get :new, :project_id => 1, :tracker_id => 1 1568 get :new, :project_id => 1, :tracker_id => 1
849 1569
850 assert_tag :tag => 'form', 1570 assert_select 'form[id=issue-form][method=post][enctype=multipart/form-data]' do
851 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'}, 1571 assert_select 'input[name=?][type=file]', 'attachments[1][file]'
852 :descendant => { 1572 assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
853 :tag => 'input', 1573 end
854 :attributes => {:type => 'file', :name => 'attachments[1][file]'} 1574 end
855 } 1575
1576 def test_get_new_should_prefill_the_form_from_params
1577 @request.session[:user_id] = 2
1578 get :new, :project_id => 1,
1579 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1580
1581 issue = assigns(:issue)
1582 assert_equal 3, issue.tracker_id
1583 assert_equal 'Prefilled', issue.description
1584 assert_equal 'Custom field value', issue.custom_field_value(2)
1585
1586 assert_select 'select[name=?]', 'issue[tracker_id]' do
1587 assert_select 'option[value=3][selected=selected]'
1588 end
1589 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1590 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1591 end
1592
1593 def test_get_new_should_mark_required_fields
1594 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1595 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1596 WorkflowPermission.delete_all
1597 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1598 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1599 @request.session[:user_id] = 2
1600
1601 get :new, :project_id => 1
1602 assert_response :success
1603 assert_template 'new'
1604
1605 assert_select 'label[for=issue_start_date]' do
1606 assert_select 'span[class=required]', 0
1607 end
1608 assert_select 'label[for=issue_due_date]' do
1609 assert_select 'span[class=required]'
1610 end
1611 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1612 assert_select 'span[class=required]', 0
1613 end
1614 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1615 assert_select 'span[class=required]'
1616 end
1617 end
1618
1619 def test_get_new_should_not_display_readonly_fields
1620 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1621 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1622 WorkflowPermission.delete_all
1623 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1624 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1625 @request.session[:user_id] = 2
1626
1627 get :new, :project_id => 1
1628 assert_response :success
1629 assert_template 'new'
1630
1631 assert_select 'input[name=?]', 'issue[start_date]'
1632 assert_select 'input[name=?]', 'issue[due_date]', 0
1633 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1634 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
856 end 1635 end
857 1636
858 def test_get_new_without_tracker_id 1637 def test_get_new_without_tracker_id
859 @request.session[:user_id] = 2 1638 @request.session[:user_id] = 2
860 get :new, :project_id => 1 1639 get :new, :project_id => 1
890 :issue => {:tracker_id => 2, 1669 :issue => {:tracker_id => 2,
891 :subject => 'This is the test_new issue', 1670 :subject => 'This is the test_new issue',
892 :description => 'This is the description', 1671 :description => 'This is the description',
893 :priority_id => 5} 1672 :priority_id => 5}
894 assert_response :success 1673 assert_response :success
895 assert_template 'attributes' 1674 assert_template 'update_form'
1675 assert_template 'form'
1676 assert_equal 'text/javascript', response.content_type
896 1677
897 issue = assigns(:issue) 1678 issue = assigns(:issue)
898 assert_kind_of Issue, issue 1679 assert_kind_of Issue, issue
899 assert_equal 1, issue.project_id 1680 assert_equal 1, issue.project_id
900 assert_equal 2, issue.tracker_id 1681 assert_equal 2, issue.tracker_id
901 assert_equal 'This is the test_new issue', issue.subject 1682 assert_equal 'This is the test_new issue', issue.subject
1683 end
1684
1685 def test_update_new_form_should_propose_transitions_based_on_initial_status
1686 @request.session[:user_id] = 2
1687 WorkflowTransition.delete_all
1688 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1689 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1690 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1691
1692 xhr :post, :new, :project_id => 1,
1693 :issue => {:tracker_id => 1,
1694 :status_id => 5,
1695 :subject => 'This is an issue'}
1696
1697 assert_equal 5, assigns(:issue).status_id
1698 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
902 end 1699 end
903 1700
904 def test_post_create 1701 def test_post_create
905 @request.session[:user_id] = 2 1702 @request.session[:user_id] = 2
906 assert_difference 'Issue.count' do 1703 assert_difference 'Issue.count' do
1001 end 1798 end
1002 1799
1003 issue = Issue.first(:order => 'id DESC') 1800 issue = Issue.first(:order => 'id DESC')
1004 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3} 1801 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1005 assert_not_nil flash[:notice], "flash was not set" 1802 assert_not_nil flash[:notice], "flash was not set"
1006 assert flash[:notice].include?("<a href='/issues/#{issue.id}'>##{issue.id}</a>"), "issue link not found in flash: #{flash[:notice]}" 1803 assert_include %|<a href="/issues/#{issue.id}" title="This is first issue">##{issue.id}</a>|, flash[:notice], "issue link not found in the flash message"
1007 end 1804 end
1008 1805
1009 def test_post_create_without_custom_fields_param 1806 def test_post_create_without_custom_fields_param
1010 @request.session[:user_id] = 2 1807 @request.session[:user_id] = 2
1011 assert_difference 'Issue.count' do 1808 assert_difference 'Issue.count' do
1016 :priority_id => 5} 1813 :priority_id => 5}
1017 end 1814 end
1018 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id 1815 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1019 end 1816 end
1020 1817
1818 def test_post_create_with_multi_custom_field
1819 field = IssueCustomField.find_by_name('Database')
1820 field.update_attribute(:multiple, true)
1821
1822 @request.session[:user_id] = 2
1823 assert_difference 'Issue.count' do
1824 post :create, :project_id => 1,
1825 :issue => {:tracker_id => 1,
1826 :subject => 'This is the test_new issue',
1827 :description => 'This is the description',
1828 :priority_id => 5,
1829 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
1830 end
1831 assert_response 302
1832 issue = Issue.first(:order => 'id DESC')
1833 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
1834 end
1835
1836 def test_post_create_with_empty_multi_custom_field
1837 field = IssueCustomField.find_by_name('Database')
1838 field.update_attribute(:multiple, true)
1839
1840 @request.session[:user_id] = 2
1841 assert_difference 'Issue.count' do
1842 post :create, :project_id => 1,
1843 :issue => {:tracker_id => 1,
1844 :subject => 'This is the test_new issue',
1845 :description => 'This is the description',
1846 :priority_id => 5,
1847 :custom_field_values => {'1' => ['']}}
1848 end
1849 assert_response 302
1850 issue = Issue.first(:order => 'id DESC')
1851 assert_equal [''], issue.custom_field_value(1).sort
1852 end
1853
1854 def test_post_create_with_multi_user_custom_field
1855 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1856 :tracker_ids => [1], :is_for_all => true)
1857
1858 @request.session[:user_id] = 2
1859 assert_difference 'Issue.count' do
1860 post :create, :project_id => 1,
1861 :issue => {:tracker_id => 1,
1862 :subject => 'This is the test_new issue',
1863 :description => 'This is the description',
1864 :priority_id => 5,
1865 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
1866 end
1867 assert_response 302
1868 issue = Issue.first(:order => 'id DESC')
1869 assert_equal ['2', '3'], issue.custom_field_value(field).sort
1870 end
1871
1021 def test_post_create_with_required_custom_field_and_without_custom_fields_param 1872 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1022 field = IssueCustomField.find_by_name('Database') 1873 field = IssueCustomField.find_by_name('Database')
1023 field.update_attribute(:is_required, true) 1874 field.update_attribute(:is_required, true)
1024 1875
1025 @request.session[:user_id] = 2 1876 @request.session[:user_id] = 2
1026 post :create, :project_id => 1, 1877 assert_no_difference 'Issue.count' do
1027 :issue => {:tracker_id => 1, 1878 post :create, :project_id => 1,
1028 :subject => 'This is the test_new issue', 1879 :issue => {:tracker_id => 1,
1029 :description => 'This is the description', 1880 :subject => 'This is the test_new issue',
1030 :priority_id => 5} 1881 :description => 'This is the description',
1882 :priority_id => 5}
1883 end
1031 assert_response :success 1884 assert_response :success
1032 assert_template 'new' 1885 assert_template 'new'
1033 issue = assigns(:issue) 1886 issue = assigns(:issue)
1034 assert_not_nil issue 1887 assert_not_nil issue
1035 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values) 1888 assert_error_tag :content => /Database can&#x27;t be blank/
1889 end
1890
1891 def test_create_should_validate_required_fields
1892 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1893 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1894 WorkflowPermission.delete_all
1895 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1896 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1897 @request.session[:user_id] = 2
1898
1899 assert_no_difference 'Issue.count' do
1900 post :create, :project_id => 1, :issue => {
1901 :tracker_id => 2,
1902 :status_id => 1,
1903 :subject => 'Test',
1904 :start_date => '',
1905 :due_date => '',
1906 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
1907 }
1908 assert_response :success
1909 assert_template 'new'
1910 end
1911
1912 assert_error_tag :content => /Due date can&#x27;t be blank/i
1913 assert_error_tag :content => /Bar can&#x27;t be blank/i
1914 end
1915
1916 def test_create_should_ignore_readonly_fields
1917 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1918 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1919 WorkflowPermission.delete_all
1920 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1921 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1922 @request.session[:user_id] = 2
1923
1924 assert_difference 'Issue.count' do
1925 post :create, :project_id => 1, :issue => {
1926 :tracker_id => 2,
1927 :status_id => 1,
1928 :subject => 'Test',
1929 :start_date => '2012-07-14',
1930 :due_date => '2012-07-16',
1931 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
1932 }
1933 assert_response 302
1934 end
1935
1936 issue = Issue.first(:order => 'id DESC')
1937 assert_equal Date.parse('2012-07-14'), issue.start_date
1938 assert_nil issue.due_date
1939 assert_equal 'value1', issue.custom_field_value(cf1)
1940 assert_nil issue.custom_field_value(cf2)
1036 end 1941 end
1037 1942
1038 def test_post_create_with_watchers 1943 def test_post_create_with_watchers
1039 @request.session[:user_id] = 2 1944 @request.session[:user_id] = 2
1040 ActionMailer::Base.deliveries.clear 1945 ActionMailer::Base.deliveries.clear
1054 # Watchers added 1959 # Watchers added
1055 assert_equal [2, 3], issue.watcher_user_ids.sort 1960 assert_equal [2, 3], issue.watcher_user_ids.sort
1056 assert issue.watched_by?(User.find(3)) 1961 assert issue.watched_by?(User.find(3))
1057 # Watchers notified 1962 # Watchers notified
1058 mail = ActionMailer::Base.deliveries.last 1963 mail = ActionMailer::Base.deliveries.last
1059 assert_kind_of TMail::Mail, mail 1964 assert_not_nil mail
1060 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail) 1965 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1061 end 1966 end
1062 1967
1063 def test_post_create_subissue 1968 def test_post_create_subissue
1064 @request.session[:user_id] = 2 1969 @request.session[:user_id] = 2
1065 1970
1066 assert_difference 'Issue.count' do 1971 assert_difference 'Issue.count' do
1067 post :create, :project_id => 1, 1972 post :create, :project_id => 1,
1068 :issue => {:tracker_id => 1, 1973 :issue => {:tracker_id => 1,
1069 :subject => 'This is a child issue', 1974 :subject => 'This is a child issue',
1070 :parent_issue_id => 2} 1975 :parent_issue_id => '2'}
1071 end 1976 assert_response 302
1072 issue = Issue.find_by_subject('This is a child issue') 1977 end
1073 assert_not_nil issue 1978 issue = Issue.order('id DESC').first
1074 assert_equal Issue.find(2), issue.parent 1979 assert_equal Issue.find(2), issue.parent
1075 end 1980 end
1076 1981
1077 def test_post_create_subissue_with_non_numeric_parent_id 1982 def test_post_create_subissue_with_sharp_parent_id
1078 @request.session[:user_id] = 2 1983 @request.session[:user_id] = 2
1079 1984
1080 assert_difference 'Issue.count' do 1985 assert_difference 'Issue.count' do
1081 post :create, :project_id => 1, 1986 post :create, :project_id => 1,
1082 :issue => {:tracker_id => 1, 1987 :issue => {:tracker_id => 1,
1083 :subject => 'This is a child issue', 1988 :subject => 'This is a child issue',
1084 :parent_issue_id => 'ABC'} 1989 :parent_issue_id => '#2'}
1085 end 1990 assert_response 302
1086 issue = Issue.find_by_subject('This is a child issue') 1991 end
1087 assert_not_nil issue 1992 issue = Issue.order('id DESC').first
1088 assert_nil issue.parent 1993 assert_equal Issue.find(2), issue.parent
1994 end
1995
1996 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
1997 @request.session[:user_id] = 2
1998
1999 assert_no_difference 'Issue.count' do
2000 post :create, :project_id => 1,
2001 :issue => {:tracker_id => 1,
2002 :subject => 'This is a child issue',
2003 :parent_issue_id => '4'}
2004
2005 assert_response :success
2006 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2007 assert_error_tag :content => /Parent task is invalid/i
2008 end
2009 end
2010
2011 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2012 @request.session[:user_id] = 2
2013
2014 assert_no_difference 'Issue.count' do
2015 post :create, :project_id => 1,
2016 :issue => {:tracker_id => 1,
2017 :subject => 'This is a child issue',
2018 :parent_issue_id => '01ABC'}
2019
2020 assert_response :success
2021 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2022 assert_error_tag :content => /Parent task is invalid/i
2023 end
1089 end 2024 end
1090 2025
1091 def test_post_create_private 2026 def test_post_create_private
1092 @request.session[:user_id] = 2 2027 @request.session[:user_id] = 2
1093 2028
1146 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}} 2081 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
1147 assert_response :success 2082 assert_response :success
1148 assert_template 'new' 2083 assert_template 'new'
1149 2084
1150 assert_tag :textarea, :attributes => { :name => 'issue[description]' }, 2085 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
1151 :content => 'This is a description' 2086 :content => "\nThis is a description"
1152 assert_tag :select, :attributes => { :name => 'issue[priority_id]' }, 2087 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1153 :child => { :tag => 'option', :attributes => { :selected => 'selected', 2088 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1154 :value => '6' }, 2089 :value => '6' },
1155 :content => 'High' } 2090 :content => 'High' }
1156 # Custom fields 2091 # Custom fields
1160 :content => 'Oracle' } 2095 :content => 'Oracle' }
1161 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]', 2096 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
1162 :value => 'Value for field 2'} 2097 :value => 'Value for field 2'}
1163 end 2098 end
1164 2099
2100 def test_post_create_with_failure_should_preserve_watchers
2101 assert !User.find(8).member_of?(Project.find(1))
2102
2103 @request.session[:user_id] = 2
2104 post :create, :project_id => 1,
2105 :issue => {:tracker_id => 1,
2106 :watcher_user_ids => ['3', '8']}
2107 assert_response :success
2108 assert_template 'new'
2109
2110 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '2', :checked => nil}
2111 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '3', :checked => 'checked'}
2112 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '8', :checked => 'checked'}
2113 end
2114
1165 def test_post_create_should_ignore_non_safe_attributes 2115 def test_post_create_should_ignore_non_safe_attributes
1166 @request.session[:user_id] = 2 2116 @request.session[:user_id] = 2
1167 assert_nothing_raised do 2117 assert_nothing_raised do
1168 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" } 2118 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
1169 end 2119 end
1192 assert_equal 59, attachment.filesize 2142 assert_equal 59, attachment.filesize
1193 assert File.exists?(attachment.diskfile) 2143 assert File.exists?(attachment.diskfile)
1194 assert_equal 59, File.size(attachment.diskfile) 2144 assert_equal 59, File.size(attachment.diskfile)
1195 end 2145 end
1196 2146
2147 def test_post_create_with_failure_should_save_attachments
2148 set_tmp_attachments_directory
2149 @request.session[:user_id] = 2
2150
2151 assert_no_difference 'Issue.count' do
2152 assert_difference 'Attachment.count' do
2153 post :create, :project_id => 1,
2154 :issue => { :tracker_id => '1', :subject => '' },
2155 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2156 assert_response :success
2157 assert_template 'new'
2158 end
2159 end
2160
2161 attachment = Attachment.first(:order => 'id DESC')
2162 assert_equal 'testfile.txt', attachment.filename
2163 assert File.exists?(attachment.diskfile)
2164 assert_nil attachment.container
2165
2166 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2167 assert_tag 'span', :content => /testfile.txt/
2168 end
2169
2170 def test_post_create_with_failure_should_keep_saved_attachments
2171 set_tmp_attachments_directory
2172 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2173 @request.session[:user_id] = 2
2174
2175 assert_no_difference 'Issue.count' do
2176 assert_no_difference 'Attachment.count' do
2177 post :create, :project_id => 1,
2178 :issue => { :tracker_id => '1', :subject => '' },
2179 :attachments => {'p0' => {'token' => attachment.token}}
2180 assert_response :success
2181 assert_template 'new'
2182 end
2183 end
2184
2185 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2186 assert_tag 'span', :content => /testfile.txt/
2187 end
2188
2189 def test_post_create_should_attach_saved_attachments
2190 set_tmp_attachments_directory
2191 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2192 @request.session[:user_id] = 2
2193
2194 assert_difference 'Issue.count' do
2195 assert_no_difference 'Attachment.count' do
2196 post :create, :project_id => 1,
2197 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2198 :attachments => {'p0' => {'token' => attachment.token}}
2199 assert_response 302
2200 end
2201 end
2202
2203 issue = Issue.first(:order => 'id DESC')
2204 assert_equal 1, issue.attachments.count
2205
2206 attachment.reload
2207 assert_equal issue, attachment.container
2208 end
2209
1197 context "without workflow privilege" do 2210 context "without workflow privilege" do
1198 setup do 2211 setup do
1199 Workflow.delete_all(["role_id = ?", Role.anonymous.id]) 2212 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
1200 Role.anonymous.add_permission! :add_issues, :add_issue_notes 2213 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1201 end 2214 end
1202 2215
1203 context "#new" do 2216 context "#new" do
1204 should "propose default status only" do 2217 should "propose default status only" do
1235 end 2248 end
1236 2249
1237 context "#update" do 2250 context "#update" do
1238 should "ignore status change" do 2251 should "ignore status change" do
1239 assert_difference 'Journal.count' do 2252 assert_difference 'Journal.count' do
1240 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3} 2253 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
1241 end 2254 end
1242 assert_equal 1, Issue.find(1).status_id 2255 assert_equal 1, Issue.find(1).status_id
1243 end 2256 end
1244 2257
1245 should "ignore attributes changes" do 2258 should "ignore attributes changes" do
1246 assert_difference 'Journal.count' do 2259 assert_difference 'Journal.count' do
1247 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2} 2260 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
1248 end 2261 end
1249 issue = Issue.find(1) 2262 issue = Issue.find(1)
1250 assert_equal "Can't print recipes", issue.subject 2263 assert_equal "Can't print recipes", issue.subject
1251 assert_nil issue.assigned_to 2264 assert_nil issue.assigned_to
1252 end 2265 end
1253 end 2266 end
1254 end 2267 end
1255 2268
1256 context "with workflow privilege" do 2269 context "with workflow privilege" do
1257 setup do 2270 setup do
1258 Workflow.delete_all(["role_id = ?", Role.anonymous.id]) 2271 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
1259 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3) 2272 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1260 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4) 2273 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1261 Role.anonymous.add_permission! :add_issues, :add_issue_notes 2274 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1262 end 2275 end
1263 2276
1264 context "#update" do 2277 context "#update" do
1265 should "accept authorized status" do 2278 should "accept authorized status" do
1266 assert_difference 'Journal.count' do 2279 assert_difference 'Journal.count' do
1267 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3} 2280 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
1268 end 2281 end
1269 assert_equal 3, Issue.find(1).status_id 2282 assert_equal 3, Issue.find(1).status_id
1270 end 2283 end
1271 2284
1272 should "ignore unauthorized status" do 2285 should "ignore unauthorized status" do
1273 assert_difference 'Journal.count' do 2286 assert_difference 'Journal.count' do
1274 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2} 2287 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
1275 end 2288 end
1276 assert_equal 1, Issue.find(1).status_id 2289 assert_equal 1, Issue.find(1).status_id
1277 end 2290 end
1278 2291
1279 should "accept authorized attributes changes" do 2292 should "accept authorized attributes changes" do
1280 assert_difference 'Journal.count' do 2293 assert_difference 'Journal.count' do
1281 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2} 2294 put :update, :id => 1, :issue => {:assigned_to_id => 2, :notes => 'just trying'}
1282 end 2295 end
1283 issue = Issue.find(1) 2296 issue = Issue.find(1)
1284 assert_equal 2, issue.assigned_to_id 2297 assert_equal 2, issue.assigned_to_id
1285 end 2298 end
1286 2299
1287 should "ignore unauthorized attributes changes" do 2300 should "ignore unauthorized attributes changes" do
1288 assert_difference 'Journal.count' do 2301 assert_difference 'Journal.count' do
1289 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'} 2302 put :update, :id => 1, :issue => {:subject => 'changed', :notes => 'just trying'}
1290 end 2303 end
1291 issue = Issue.find(1) 2304 issue = Issue.find(1)
1292 assert_equal "Can't print recipes", issue.subject 2305 assert_equal "Can't print recipes", issue.subject
1293 end 2306 end
1294 end 2307 end
1298 Role.anonymous.add_permission! :add_issues, :edit_issues 2311 Role.anonymous.add_permission! :add_issues, :edit_issues
1299 end 2312 end
1300 2313
1301 should "accept authorized status" do 2314 should "accept authorized status" do
1302 assert_difference 'Journal.count' do 2315 assert_difference 'Journal.count' do
1303 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3} 2316 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
1304 end 2317 end
1305 assert_equal 3, Issue.find(1).status_id 2318 assert_equal 3, Issue.find(1).status_id
1306 end 2319 end
1307 2320
1308 should "ignore unauthorized status" do 2321 should "ignore unauthorized status" do
1309 assert_difference 'Journal.count' do 2322 assert_difference 'Journal.count' do
1310 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2} 2323 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
1311 end 2324 end
1312 assert_equal 1, Issue.find(1).status_id 2325 assert_equal 1, Issue.find(1).status_id
1313 end 2326 end
1314 2327
1315 should "accept authorized attributes changes" do 2328 should "accept authorized attributes changes" do
1316 assert_difference 'Journal.count' do 2329 assert_difference 'Journal.count' do
1317 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2} 2330 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
1318 end 2331 end
1319 issue = Issue.find(1) 2332 issue = Issue.find(1)
1320 assert_equal "changed", issue.subject 2333 assert_equal "changed", issue.subject
1321 assert_equal 2, issue.assigned_to_id 2334 assert_equal 2, issue.assigned_to_id
1322 end 2335 end
1323 end 2336 end
1324 end 2337 end
1325 2338
1326 def test_copy_issue 2339 def test_new_as_copy
1327 @request.session[:user_id] = 2 2340 @request.session[:user_id] = 2
1328 get :new, :project_id => 1, :copy_from => 1 2341 get :new, :project_id => 1, :copy_from => 1
2342
2343 assert_response :success
1329 assert_template 'new' 2344 assert_template 'new'
2345
1330 assert_not_nil assigns(:issue) 2346 assert_not_nil assigns(:issue)
1331 orig = Issue.find(1) 2347 orig = Issue.find(1)
2348 assert_equal 1, assigns(:issue).project_id
1332 assert_equal orig.subject, assigns(:issue).subject 2349 assert_equal orig.subject, assigns(:issue).subject
2350 assert assigns(:issue).copy?
2351
2352 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2353 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2354 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2355 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
2356 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2357 :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
2358 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2359 end
2360
2361 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2362 @request.session[:user_id] = 2
2363 issue = Issue.find(3)
2364 assert issue.attachments.count > 0
2365 get :new, :project_id => 1, :copy_from => 3
2366
2367 assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2368 end
2369
2370 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2371 @request.session[:user_id] = 2
2372 issue = Issue.find(3)
2373 issue.attachments.delete_all
2374 get :new, :project_id => 1, :copy_from => 3
2375
2376 assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2377 end
2378
2379 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2380 @request.session[:user_id] = 2
2381 issue = Issue.generate_with_descendants!
2382 get :new, :project_id => 1, :copy_from => issue.id
2383
2384 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value=1]'
2385 end
2386
2387 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2388 @request.session[:user_id] = 2
2389 get :new, :project_id => 1, :copy_from => 99999
2390 assert_response 404
2391 end
2392
2393 def test_create_as_copy_on_different_project
2394 @request.session[:user_id] = 2
2395 assert_difference 'Issue.count' do
2396 post :create, :project_id => 1, :copy_from => 1,
2397 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2398
2399 assert_not_nil assigns(:issue)
2400 assert assigns(:issue).copy?
2401 end
2402 issue = Issue.first(:order => 'id DESC')
2403 assert_redirected_to "/issues/#{issue.id}"
2404
2405 assert_equal 2, issue.project_id
2406 assert_equal 3, issue.tracker_id
2407 assert_equal 'Copy', issue.subject
2408 end
2409
2410 def test_create_as_copy_should_copy_attachments
2411 @request.session[:user_id] = 2
2412 issue = Issue.find(3)
2413 count = issue.attachments.count
2414 assert count > 0
2415
2416 assert_difference 'Issue.count' do
2417 assert_difference 'Attachment.count', count do
2418 assert_no_difference 'Journal.count' do
2419 post :create, :project_id => 1, :copy_from => 3,
2420 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2421 :copy_attachments => '1'
2422 end
2423 end
2424 end
2425 copy = Issue.first(:order => 'id DESC')
2426 assert_equal count, copy.attachments.count
2427 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2428 end
2429
2430 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2431 @request.session[:user_id] = 2
2432 issue = Issue.find(3)
2433 count = issue.attachments.count
2434 assert count > 0
2435
2436 assert_difference 'Issue.count' do
2437 assert_no_difference 'Attachment.count' do
2438 assert_no_difference 'Journal.count' do
2439 post :create, :project_id => 1, :copy_from => 3,
2440 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
2441 end
2442 end
2443 end
2444 copy = Issue.first(:order => 'id DESC')
2445 assert_equal 0, copy.attachments.count
2446 end
2447
2448 def test_create_as_copy_with_attachments_should_add_new_files
2449 @request.session[:user_id] = 2
2450 issue = Issue.find(3)
2451 count = issue.attachments.count
2452 assert count > 0
2453
2454 assert_difference 'Issue.count' do
2455 assert_difference 'Attachment.count', count + 1 do
2456 assert_no_difference 'Journal.count' do
2457 post :create, :project_id => 1, :copy_from => 3,
2458 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2459 :copy_attachments => '1',
2460 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2461 end
2462 end
2463 end
2464 copy = Issue.first(:order => 'id DESC')
2465 assert_equal count + 1, copy.attachments.count
2466 end
2467
2468 def test_create_as_copy_should_add_relation_with_copied_issue
2469 @request.session[:user_id] = 2
2470
2471 assert_difference 'Issue.count' do
2472 assert_difference 'IssueRelation.count' do
2473 post :create, :project_id => 1, :copy_from => 1,
2474 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2475 end
2476 end
2477 copy = Issue.first(:order => 'id DESC')
2478 assert_equal 1, copy.relations.size
2479 end
2480
2481 def test_create_as_copy_should_copy_subtasks
2482 @request.session[:user_id] = 2
2483 issue = Issue.generate_with_descendants!
2484 count = issue.descendants.count
2485
2486 assert_difference 'Issue.count', count+1 do
2487 assert_no_difference 'Journal.count' do
2488 post :create, :project_id => 1, :copy_from => issue.id,
2489 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'},
2490 :copy_subtasks => '1'
2491 end
2492 end
2493 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2494 assert_equal count, copy.descendants.count
2495 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
2496 end
2497
2498 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
2499 @request.session[:user_id] = 2
2500 issue = Issue.generate_with_descendants!
2501
2502 assert_difference 'Issue.count', 1 do
2503 assert_no_difference 'Journal.count' do
2504 post :create, :project_id => 1, :copy_from => 3,
2505 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'}
2506 end
2507 end
2508 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2509 assert_equal 0, copy.descendants.count
2510 end
2511
2512 def test_create_as_copy_with_failure
2513 @request.session[:user_id] = 2
2514 post :create, :project_id => 1, :copy_from => 1,
2515 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
2516
2517 assert_response :success
2518 assert_template 'new'
2519
2520 assert_not_nil assigns(:issue)
2521 assert assigns(:issue).copy?
2522
2523 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2524 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2525 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2526 :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
2527 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2528 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
2529 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2530 end
2531
2532 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
2533 @request.session[:user_id] = 2
2534 assert !User.find(2).member_of?(Project.find(4))
2535
2536 assert_difference 'Issue.count' do
2537 post :create, :project_id => 1, :copy_from => 1,
2538 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2539 end
2540 issue = Issue.first(:order => 'id DESC')
2541 assert_equal 1, issue.project_id
1333 end 2542 end
1334 2543
1335 def test_get_edit 2544 def test_get_edit
1336 @request.session[:user_id] = 2 2545 @request.session[:user_id] = 2
1337 get :edit, :id => 1 2546 get :edit, :id => 1
1389 :child => { :tag => 'option', 2598 :child => { :tag => 'option',
1390 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } } 2599 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
1391 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' } 2600 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
1392 end 2601 end
1393 2602
2603 def test_get_edit_with_multi_custom_field
2604 field = CustomField.find(1)
2605 field.update_attribute :multiple, true
2606 issue = Issue.find(1)
2607 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2608 issue.save!
2609
2610 @request.session[:user_id] = 2
2611 get :edit, :id => 1
2612 assert_response :success
2613 assert_template 'edit'
2614
2615 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
2616 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2617 :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
2618 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2619 :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
2620 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2621 :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
2622 end
2623
1394 def test_update_edit_form 2624 def test_update_edit_form
1395 @request.session[:user_id] = 2 2625 @request.session[:user_id] = 2
1396 xhr :post, :new, :project_id => 1, 2626 xhr :put, :new, :project_id => 1,
1397 :id => 1, 2627 :id => 1,
1398 :issue => {:tracker_id => 2, 2628 :issue => {:tracker_id => 2,
1399 :subject => 'This is the test_new issue', 2629 :subject => 'This is the test_new issue',
1400 :description => 'This is the description', 2630 :description => 'This is the description',
1401 :priority_id => 5} 2631 :priority_id => 5}
1402 assert_response :success 2632 assert_response :success
1403 assert_template 'attributes' 2633 assert_equal 'text/javascript', response.content_type
2634 assert_template 'update_form'
2635 assert_template 'form'
1404 2636
1405 issue = assigns(:issue) 2637 issue = assigns(:issue)
1406 assert_kind_of Issue, issue 2638 assert_kind_of Issue, issue
1407 assert_equal 1, issue.id 2639 assert_equal 1, issue.id
1408 assert_equal 1, issue.project_id 2640 assert_equal 1, issue.project_id
1409 assert_equal 2, issue.tracker_id 2641 assert_equal 2, issue.tracker_id
1410 assert_equal 'This is the test_new issue', issue.subject 2642 assert_equal 'This is the test_new issue', issue.subject
1411 end 2643 end
1412 2644
1413 def test_update_using_invalid_http_verbs 2645 def test_update_edit_form_should_keep_issue_author
1414 @request.session[:user_id] = 2 2646 @request.session[:user_id] = 3
1415 subject = 'Updated by an invalid http verb' 2647 xhr :put, :new, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
1416 2648 assert_response :success
1417 get :update, :id => 1, :issue => {:subject => subject} 2649 assert_equal 'text/javascript', response.content_type
1418 assert_not_equal subject, Issue.find(1).subject 2650
1419 2651 issue = assigns(:issue)
1420 post :update, :id => 1, :issue => {:subject => subject} 2652 assert_equal User.find(2), issue.author
1421 assert_not_equal subject, Issue.find(1).subject 2653 assert_equal 2, issue.author_id
1422 2654 assert_not_equal User.current, issue.author
1423 delete :update, :id => 1, :issue => {:subject => subject} 2655 end
1424 assert_not_equal subject, Issue.find(1).subject 2656
2657 def test_update_edit_form_should_propose_transitions_based_on_initial_status
2658 @request.session[:user_id] = 2
2659 WorkflowTransition.delete_all
2660 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2661 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2662 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2663
2664 xhr :put, :new, :project_id => 1,
2665 :id => 2,
2666 :issue => {:tracker_id => 2,
2667 :status_id => 5,
2668 :subject => 'This is an issue'}
2669
2670 assert_equal 5, assigns(:issue).status_id
2671 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
2672 end
2673
2674 def test_update_edit_form_with_project_change
2675 @request.session[:user_id] = 2
2676 xhr :put, :new, :project_id => 1,
2677 :id => 1,
2678 :issue => {:project_id => 2,
2679 :tracker_id => 2,
2680 :subject => 'This is the test_new issue',
2681 :description => 'This is the description',
2682 :priority_id => 5}
2683 assert_response :success
2684 assert_template 'form'
2685
2686 issue = assigns(:issue)
2687 assert_kind_of Issue, issue
2688 assert_equal 1, issue.id
2689 assert_equal 2, issue.project_id
2690 assert_equal 2, issue.tracker_id
2691 assert_equal 'This is the test_new issue', issue.subject
1425 end 2692 end
1426 2693
1427 def test_put_update_without_custom_fields_param 2694 def test_put_update_without_custom_fields_param
1428 @request.session[:user_id] = 2 2695 @request.session[:user_id] = 2
1429 ActionMailer::Base.deliveries.clear 2696 ActionMailer::Base.deliveries.clear
1446 assert_equal new_subject, issue.subject 2713 assert_equal new_subject, issue.subject
1447 # Make sure custom fields were not cleared 2714 # Make sure custom fields were not cleared
1448 assert_equal '125', issue.custom_value_for(2).value 2715 assert_equal '125', issue.custom_value_for(2).value
1449 2716
1450 mail = ActionMailer::Base.deliveries.last 2717 mail = ActionMailer::Base.deliveries.last
1451 assert_kind_of TMail::Mail, mail 2718 assert_not_nil mail
1452 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]") 2719 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
1453 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}") 2720 assert_mail_body_match "Subject changed from #{old_subject} to #{new_subject}", mail
2721 end
2722
2723 def test_put_update_with_project_change
2724 @request.session[:user_id] = 2
2725 ActionMailer::Base.deliveries.clear
2726
2727 assert_difference('Journal.count') do
2728 assert_difference('JournalDetail.count', 3) do
2729 put :update, :id => 1, :issue => {:project_id => '2',
2730 :tracker_id => '1', # no change
2731 :priority_id => '6',
2732 :category_id => '3'
2733 }
2734 end
2735 end
2736 assert_redirected_to :action => 'show', :id => '1'
2737 issue = Issue.find(1)
2738 assert_equal 2, issue.project_id
2739 assert_equal 1, issue.tracker_id
2740 assert_equal 6, issue.priority_id
2741 assert_equal 3, issue.category_id
2742
2743 mail = ActionMailer::Base.deliveries.last
2744 assert_not_nil mail
2745 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2746 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
2747 end
2748
2749 def test_put_update_with_tracker_change
2750 @request.session[:user_id] = 2
2751 ActionMailer::Base.deliveries.clear
2752
2753 assert_difference('Journal.count') do
2754 assert_difference('JournalDetail.count', 2) do
2755 put :update, :id => 1, :issue => {:project_id => '1',
2756 :tracker_id => '2',
2757 :priority_id => '6'
2758 }
2759 end
2760 end
2761 assert_redirected_to :action => 'show', :id => '1'
2762 issue = Issue.find(1)
2763 assert_equal 1, issue.project_id
2764 assert_equal 2, issue.tracker_id
2765 assert_equal 6, issue.priority_id
2766 assert_equal 1, issue.category_id
2767
2768 mail = ActionMailer::Base.deliveries.last
2769 assert_not_nil mail
2770 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2771 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
1454 end 2772 end
1455 2773
1456 def test_put_update_with_custom_field_change 2774 def test_put_update_with_custom_field_change
1457 @request.session[:user_id] = 2 2775 @request.session[:user_id] = 2
1458 issue = Issue.find(1) 2776 issue = Issue.find(1)
1470 assert_redirected_to :action => 'show', :id => '1' 2788 assert_redirected_to :action => 'show', :id => '1'
1471 issue.reload 2789 issue.reload
1472 assert_equal 'New custom value', issue.custom_value_for(2).value 2790 assert_equal 'New custom value', issue.custom_value_for(2).value
1473 2791
1474 mail = ActionMailer::Base.deliveries.last 2792 mail = ActionMailer::Base.deliveries.last
1475 assert_kind_of TMail::Mail, mail 2793 assert_not_nil mail
1476 assert mail.body.include?("Searchable field changed from 125 to New custom value") 2794 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
2795 end
2796
2797 def test_put_update_with_multi_custom_field_change
2798 field = CustomField.find(1)
2799 field.update_attribute :multiple, true
2800 issue = Issue.find(1)
2801 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2802 issue.save!
2803
2804 @request.session[:user_id] = 2
2805 assert_difference('Journal.count') do
2806 assert_difference('JournalDetail.count', 3) do
2807 put :update, :id => 1,
2808 :issue => {
2809 :subject => 'Custom field change',
2810 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
2811 }
2812 end
2813 end
2814 assert_redirected_to :action => 'show', :id => '1'
2815 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
1477 end 2816 end
1478 2817
1479 def test_put_update_with_status_and_assignee_change 2818 def test_put_update_with_status_and_assignee_change
1480 issue = Issue.find(1) 2819 issue = Issue.find(1)
1481 assert_equal 1, issue.status_id 2820 assert_equal 1, issue.status_id
1482 @request.session[:user_id] = 2 2821 @request.session[:user_id] = 2
1483 assert_difference('TimeEntry.count', 0) do 2822 assert_difference('TimeEntry.count', 0) do
1484 put :update, 2823 put :update,
1485 :id => 1, 2824 :id => 1,
1486 :issue => { :status_id => 2, :assigned_to_id => 3 }, 2825 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
1487 :notes => 'Assigned to dlopper',
1488 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first } 2826 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
1489 end 2827 end
1490 assert_redirected_to :action => 'show', :id => '1' 2828 assert_redirected_to :action => 'show', :id => '1'
1491 issue.reload 2829 issue.reload
1492 assert_equal 2, issue.status_id 2830 assert_equal 2, issue.status_id
1493 j = Journal.find(:first, :order => 'id DESC') 2831 j = Journal.find(:first, :order => 'id DESC')
1494 assert_equal 'Assigned to dlopper', j.notes 2832 assert_equal 'Assigned to dlopper', j.notes
1495 assert_equal 2, j.details.size 2833 assert_equal 2, j.details.size
1496 2834
1497 mail = ActionMailer::Base.deliveries.last 2835 mail = ActionMailer::Base.deliveries.last
1498 assert mail.body.include?("Status changed from New to Assigned") 2836 assert_mail_body_match "Status changed from New to Assigned", mail
1499 # subject should contain the new status 2837 # subject should contain the new status
1500 assert mail.subject.include?("(#{ IssueStatus.find(2).name })") 2838 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
1501 end 2839 end
1502 2840
1503 def test_put_update_with_note_only 2841 def test_put_update_with_note_only
1504 notes = 'Note added by IssuesControllerTest#test_update_with_note_only' 2842 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
1505 # anonymous user 2843 # anonymous user
1506 put :update, 2844 put :update,
1507 :id => 1, 2845 :id => 1,
1508 :notes => notes 2846 :issue => { :notes => notes }
1509 assert_redirected_to :action => 'show', :id => '1' 2847 assert_redirected_to :action => 'show', :id => '1'
1510 j = Journal.find(:first, :order => 'id DESC') 2848 j = Journal.find(:first, :order => 'id DESC')
1511 assert_equal notes, j.notes 2849 assert_equal notes, j.notes
1512 assert_equal 0, j.details.size 2850 assert_equal 0, j.details.size
1513 assert_equal User.anonymous, j.user 2851 assert_equal User.anonymous, j.user
1514 2852
1515 mail = ActionMailer::Base.deliveries.last 2853 mail = ActionMailer::Base.deliveries.last
1516 assert mail.body.include?(notes) 2854 assert_mail_body_match notes, mail
2855 end
2856
2857 def test_put_update_with_private_note_only
2858 notes = 'Private note'
2859 @request.session[:user_id] = 2
2860
2861 assert_difference 'Journal.count' do
2862 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
2863 assert_redirected_to :action => 'show', :id => '1'
2864 end
2865
2866 j = Journal.order('id DESC').first
2867 assert_equal notes, j.notes
2868 assert_equal true, j.private_notes
2869 end
2870
2871 def test_put_update_with_private_note_and_changes
2872 notes = 'Private note'
2873 @request.session[:user_id] = 2
2874
2875 assert_difference 'Journal.count', 2 do
2876 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
2877 assert_redirected_to :action => 'show', :id => '1'
2878 end
2879
2880 j = Journal.order('id DESC').first
2881 assert_equal notes, j.notes
2882 assert_equal true, j.private_notes
2883 assert_equal 0, j.details.count
2884
2885 j = Journal.order('id DESC').offset(1).first
2886 assert_nil j.notes
2887 assert_equal false, j.private_notes
2888 assert_equal 1, j.details.count
1517 end 2889 end
1518 2890
1519 def test_put_update_with_note_and_spent_time 2891 def test_put_update_with_note_and_spent_time
1520 @request.session[:user_id] = 2 2892 @request.session[:user_id] = 2
1521 spent_hours_before = Issue.find(1).spent_hours 2893 spent_hours_before = Issue.find(1).spent_hours
1522 assert_difference('TimeEntry.count') do 2894 assert_difference('TimeEntry.count') do
1523 put :update, 2895 put :update,
1524 :id => 1, 2896 :id => 1,
1525 :notes => '2.5 hours added', 2897 :issue => { :notes => '2.5 hours added' },
1526 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id } 2898 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
1527 end 2899 end
1528 assert_redirected_to :action => 'show', :id => '1' 2900 assert_redirected_to :action => 'show', :id => '1'
1529 2901
1530 issue = Issue.find(1) 2902 issue = Issue.find(1)
1547 Journal.delete_all 2919 Journal.delete_all
1548 2920
1549 # anonymous user 2921 # anonymous user
1550 assert_difference 'Attachment.count' do 2922 assert_difference 'Attachment.count' do
1551 put :update, :id => 1, 2923 put :update, :id => 1,
1552 :notes => '', 2924 :issue => {:notes => ''},
1553 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}} 2925 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1554 end 2926 end
1555 2927
1556 assert_redirected_to :action => 'show', :id => '1' 2928 assert_redirected_to :action => 'show', :id => '1'
1557 j = Issue.find(1).journals.find(:first, :order => 'id DESC') 2929 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
1569 assert_equal 59, attachment.filesize 2941 assert_equal 59, attachment.filesize
1570 assert File.exists?(attachment.diskfile) 2942 assert File.exists?(attachment.diskfile)
1571 assert_equal 59, File.size(attachment.diskfile) 2943 assert_equal 59, File.size(attachment.diskfile)
1572 2944
1573 mail = ActionMailer::Base.deliveries.last 2945 mail = ActionMailer::Base.deliveries.last
1574 assert mail.body.include?('testfile.txt') 2946 assert_mail_body_match 'testfile.txt', mail
2947 end
2948
2949 def test_put_update_with_failure_should_save_attachments
2950 set_tmp_attachments_directory
2951 @request.session[:user_id] = 2
2952
2953 assert_no_difference 'Journal.count' do
2954 assert_difference 'Attachment.count' do
2955 put :update, :id => 1,
2956 :issue => { :subject => '' },
2957 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2958 assert_response :success
2959 assert_template 'edit'
2960 end
2961 end
2962
2963 attachment = Attachment.first(:order => 'id DESC')
2964 assert_equal 'testfile.txt', attachment.filename
2965 assert File.exists?(attachment.diskfile)
2966 assert_nil attachment.container
2967
2968 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2969 assert_tag 'span', :content => /testfile.txt/
2970 end
2971
2972 def test_put_update_with_failure_should_keep_saved_attachments
2973 set_tmp_attachments_directory
2974 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2975 @request.session[:user_id] = 2
2976
2977 assert_no_difference 'Journal.count' do
2978 assert_no_difference 'Attachment.count' do
2979 put :update, :id => 1,
2980 :issue => { :subject => '' },
2981 :attachments => {'p0' => {'token' => attachment.token}}
2982 assert_response :success
2983 assert_template 'edit'
2984 end
2985 end
2986
2987 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2988 assert_tag 'span', :content => /testfile.txt/
2989 end
2990
2991 def test_put_update_should_attach_saved_attachments
2992 set_tmp_attachments_directory
2993 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2994 @request.session[:user_id] = 2
2995
2996 assert_difference 'Journal.count' do
2997 assert_difference 'JournalDetail.count' do
2998 assert_no_difference 'Attachment.count' do
2999 put :update, :id => 1,
3000 :issue => {:notes => 'Attachment added'},
3001 :attachments => {'p0' => {'token' => attachment.token}}
3002 assert_redirected_to '/issues/1'
3003 end
3004 end
3005 end
3006
3007 attachment.reload
3008 assert_equal Issue.find(1), attachment.container
3009
3010 journal = Journal.first(:order => 'id DESC')
3011 assert_equal 1, journal.details.size
3012 assert_equal 'testfile.txt', journal.details.first.value
1575 end 3013 end
1576 3014
1577 def test_put_update_with_attachment_that_fails_to_save 3015 def test_put_update_with_attachment_that_fails_to_save
1578 set_tmp_attachments_directory 3016 set_tmp_attachments_directory
1579 3017
1585 Attachment.any_instance.stubs(:create).returns(Attachment.new) 3023 Attachment.any_instance.stubs(:create).returns(Attachment.new)
1586 3024
1587 # anonymous user 3025 # anonymous user
1588 put :update, 3026 put :update,
1589 :id => 1, 3027 :id => 1,
1590 :notes => '', 3028 :issue => {:notes => ''},
1591 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}} 3029 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
1592 assert_redirected_to :action => 'show', :id => '1' 3030 assert_redirected_to :action => 'show', :id => '1'
1593 assert_equal '1 file(s) could not be saved.', flash[:warning] 3031 assert_equal '1 file(s) could not be saved.', flash[:warning]
1594 3032 end
1595 end if Object.const_defined?(:Mocha)
1596 3033
1597 def test_put_update_with_no_change 3034 def test_put_update_with_no_change
1598 issue = Issue.find(1) 3035 issue = Issue.find(1)
1599 issue.journals.clear 3036 issue.journals.clear
1600 ActionMailer::Base.deliveries.clear 3037 ActionMailer::Base.deliveries.clear
1601 3038
1602 put :update, 3039 put :update,
1603 :id => 1, 3040 :id => 1,
1604 :notes => '' 3041 :issue => {:notes => ''}
1605 assert_redirected_to :action => 'show', :id => '1' 3042 assert_redirected_to :action => 'show', :id => '1'
1606 3043
1607 issue.reload 3044 issue.reload
1608 assert issue.journals.empty? 3045 assert issue.journals.empty?
1609 # No email should be sent 3046 # No email should be sent
1629 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time' 3066 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1630 3067
1631 assert_no_difference('Journal.count') do 3068 assert_no_difference('Journal.count') do
1632 put :update, 3069 put :update,
1633 :id => 1, 3070 :id => 1,
1634 :notes => notes, 3071 :issue => {:notes => notes},
1635 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"} 3072 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
1636 end 3073 end
1637 assert_response :success 3074 assert_response :success
1638 assert_template 'edit' 3075 assert_template 'edit'
1639 3076
1640 assert_error_tag :descendant => {:content => /Activity can't be blank/} 3077 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
1641 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes 3078 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
1642 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" } 3079 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
1643 end 3080 end
1644 3081
1645 def test_put_update_with_invalid_spent_time_comments_only 3082 def test_put_update_with_invalid_spent_time_comments_only
1646 @request.session[:user_id] = 2 3083 @request.session[:user_id] = 2
1647 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time' 3084 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1648 3085
1649 assert_no_difference('Journal.count') do 3086 assert_no_difference('Journal.count') do
1650 put :update, 3087 put :update,
1651 :id => 1, 3088 :id => 1,
1652 :notes => notes, 3089 :issue => {:notes => notes},
1653 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""} 3090 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
1654 end 3091 end
1655 assert_response :success 3092 assert_response :success
1656 assert_template 'edit' 3093 assert_template 'edit'
1657 3094
1658 assert_error_tag :descendant => {:content => /Activity can't be blank/} 3095 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
1659 assert_error_tag :descendant => {:content => /Hours can't be blank/} 3096 assert_error_tag :descendant => {:content => /Hours can&#x27;t be blank/}
1660 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes 3097 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
1661 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" } 3098 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
1662 end 3099 end
1663 3100
1664 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject 3101 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
1665 issue = Issue.find(2) 3102 issue = Issue.find(2)
1711 @request.session[:user_id] = 2 3148 @request.session[:user_id] = 2
1712 get :bulk_edit, :ids => [1, 2] 3149 get :bulk_edit, :ids => [1, 2]
1713 assert_response :success 3150 assert_response :success
1714 assert_template 'bulk_edit' 3151 assert_template 'bulk_edit'
1715 3152
3153 assert_tag :select, :attributes => {:name => 'issue[project_id]'}
1716 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'} 3154 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1717 3155
1718 # Project specific custom field, date type 3156 # Project specific custom field, date type
1719 field = CustomField.find(9) 3157 field = CustomField.find(9)
1720 assert !field.is_for_all? 3158 assert !field.is_for_all?
1754 get :bulk_edit, :ids => [1, 2] 3192 get :bulk_edit, :ids => [1, 2]
1755 assert_response :success 3193 assert_response :success
1756 assert_template 'bulk_edit' 3194 assert_template 'bulk_edit'
1757 3195
1758 assert_tag :select, 3196 assert_tag :select,
1759 :attributes => {:name => "issue[custom_field_values][#{field.id}]"}, 3197 :attributes => {:name => "issue[custom_field_values][#{field.id}]", :class => 'user_cf'},
1760 :children => { 3198 :children => {
1761 :only => {:tag => 'option'}, 3199 :only => {:tag => 'option'},
1762 :count => Project.find(1).users.count + 1 3200 :count => Project.find(1).users.count + 2 # "no change" + "none" options
1763 } 3201 }
1764 end 3202 end
1765 3203
1766 def test_get_bulk_edit_with_version_custom_field 3204 def test_get_bulk_edit_with_version_custom_field
1767 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true) 3205 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
1773 3211
1774 assert_tag :select, 3212 assert_tag :select,
1775 :attributes => {:name => "issue[custom_field_values][#{field.id}]"}, 3213 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1776 :children => { 3214 :children => {
1777 :only => {:tag => 'option'}, 3215 :only => {:tag => 'option'},
1778 :count => Project.find(1).shared_versions.count + 1 3216 :count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
1779 } 3217 }
3218 end
3219
3220 def test_get_bulk_edit_with_multi_custom_field
3221 field = CustomField.find(1)
3222 field.update_attribute :multiple, true
3223
3224 @request.session[:user_id] = 2
3225 get :bulk_edit, :ids => [1, 2]
3226 assert_response :success
3227 assert_template 'bulk_edit'
3228
3229 assert_tag :select,
3230 :attributes => {:name => "issue[custom_field_values][1][]"},
3231 :children => {
3232 :only => {:tag => 'option'},
3233 :count => field.possible_values.size + 1 # "none" options
3234 }
3235 end
3236
3237 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3238 WorkflowTransition.delete_all
3239 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
3240 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
3241 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
3242 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3243 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3244 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3245 @request.session[:user_id] = 2
3246 get :bulk_edit, :ids => [1, 2]
3247
3248 assert_response :success
3249 statuses = assigns(:available_statuses)
3250 assert_not_nil statuses
3251 assert_equal [1, 3], statuses.map(&:id).sort
3252
3253 assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
3254 :children => {:count => 3} # 2 statuses + "no change" option
3255 end
3256
3257 def test_bulk_edit_should_propose_target_project_open_shared_versions
3258 @request.session[:user_id] = 2
3259 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3260 assert_response :success
3261 assert_template 'bulk_edit'
3262 assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
3263 assert_tag 'select',
3264 :attributes => {:name => 'issue[fixed_version_id]'},
3265 :descendant => {:tag => 'option', :content => '2.0'}
3266 end
3267
3268 def test_bulk_edit_should_propose_target_project_categories
3269 @request.session[:user_id] = 2
3270 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3271 assert_response :success
3272 assert_template 'bulk_edit'
3273 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3274 assert_tag 'select',
3275 :attributes => {:name => 'issue[category_id]'},
3276 :descendant => {:tag => 'option', :content => 'Recipes'}
1780 end 3277 end
1781 3278
1782 def test_bulk_update 3279 def test_bulk_update
1783 @request.session[:user_id] = 2 3280 @request.session[:user_id] = 2
1784 # update issues priority 3281 # update issues priority
1863 3360
1864 assert_response 302 3361 assert_response 302
1865 assert_equal 2, ActionMailer::Base.deliveries.size 3362 assert_equal 2, ActionMailer::Base.deliveries.size
1866 end 3363 end
1867 3364
3365 def test_bulk_update_project
3366 @request.session[:user_id] = 2
3367 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3368 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3369 # Issues moved to project 2
3370 assert_equal 2, Issue.find(1).project_id
3371 assert_equal 2, Issue.find(2).project_id
3372 # No tracker change
3373 assert_equal 1, Issue.find(1).tracker_id
3374 assert_equal 2, Issue.find(2).tracker_id
3375 end
3376
3377 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3378 @request.session[:user_id] = 2
3379 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3380 assert_redirected_to '/issues/1'
3381 end
3382
3383 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3384 @request.session[:user_id] = 2
3385 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3386 assert_redirected_to '/projects/onlinestore/issues'
3387 end
3388
3389 def test_bulk_update_tracker
3390 @request.session[:user_id] = 2
3391 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3392 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3393 assert_equal 2, Issue.find(1).tracker_id
3394 assert_equal 2, Issue.find(2).tracker_id
3395 end
3396
1868 def test_bulk_update_status 3397 def test_bulk_update_status
1869 @request.session[:user_id] = 2 3398 @request.session[:user_id] = 2
1870 # update issues priority 3399 # update issues priority
1871 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status', 3400 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
1872 :issue => {:priority_id => '', 3401 :issue => {:priority_id => '',
1874 :status_id => '5'} 3403 :status_id => '5'}
1875 3404
1876 assert_response 302 3405 assert_response 302
1877 issue = Issue.find(1) 3406 issue = Issue.find(1)
1878 assert issue.closed? 3407 assert issue.closed?
3408 end
3409
3410 def test_bulk_update_priority
3411 @request.session[:user_id] = 2
3412 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3413
3414 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3415 assert_equal 6, Issue.find(1).priority_id
3416 assert_equal 6, Issue.find(2).priority_id
3417 end
3418
3419 def test_bulk_update_with_notes
3420 @request.session[:user_id] = 2
3421 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
3422
3423 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3424 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
3425 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
1879 end 3426 end
1880 3427
1881 def test_bulk_update_parent_id 3428 def test_bulk_update_parent_id
1882 @request.session[:user_id] = 2 3429 @request.session[:user_id] = 2
1883 post :bulk_update, :ids => [1, 3], 3430 post :bulk_update, :ids => [1, 3],
1907 assert_equal 1, journal.details.size 3454 assert_equal 1, journal.details.size
1908 assert_equal '125', journal.details.first.old_value 3455 assert_equal '125', journal.details.first.old_value
1909 assert_equal '777', journal.details.first.value 3456 assert_equal '777', journal.details.first.value
1910 end 3457 end
1911 3458
3459 def test_bulk_update_custom_field_to_blank
3460 @request.session[:user_id] = 2
3461 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
3462 :issue => {:priority_id => '',
3463 :assigned_to_id => '',
3464 :custom_field_values => {'1' => '__none__'}}
3465 assert_response 302
3466 assert_equal '', Issue.find(1).custom_field_value(1)
3467 assert_equal '', Issue.find(3).custom_field_value(1)
3468 end
3469
3470 def test_bulk_update_multi_custom_field
3471 field = CustomField.find(1)
3472 field.update_attribute :multiple, true
3473
3474 @request.session[:user_id] = 2
3475 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
3476 :issue => {:priority_id => '',
3477 :assigned_to_id => '',
3478 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
3479
3480 assert_response 302
3481
3482 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
3483 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
3484 # the custom field is not associated with the issue tracker
3485 assert_nil Issue.find(2).custom_field_value(1)
3486 end
3487
3488 def test_bulk_update_multi_custom_field_to_blank
3489 field = CustomField.find(1)
3490 field.update_attribute :multiple, true
3491
3492 @request.session[:user_id] = 2
3493 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
3494 :issue => {:priority_id => '',
3495 :assigned_to_id => '',
3496 :custom_field_values => {'1' => ['__none__']}}
3497 assert_response 302
3498 assert_equal [''], Issue.find(1).custom_field_value(1)
3499 assert_equal [''], Issue.find(3).custom_field_value(1)
3500 end
3501
1912 def test_bulk_update_unassign 3502 def test_bulk_update_unassign
1913 assert_not_nil Issue.find(2).assigned_to 3503 assert_not_nil Issue.find(2).assigned_to
1914 @request.session[:user_id] = 2 3504 @request.session[:user_id] = 2
1915 # unassign issues 3505 # unassign issues
1916 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'} 3506 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1946 3536
1947 assert_response :redirect 3537 assert_response :redirect
1948 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier 3538 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1949 end 3539 end
1950 3540
3541 def test_bulk_update_with_failure_should_set_flash
3542 @request.session[:user_id] = 2
3543 Issue.update_all("subject = ''", "id = 2") # Make it invalid
3544 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3545
3546 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3547 assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
3548 end
3549
3550 def test_get_bulk_copy
3551 @request.session[:user_id] = 2
3552 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
3553 assert_response :success
3554 assert_template 'bulk_edit'
3555
3556 issues = assigns(:issues)
3557 assert_not_nil issues
3558 assert_equal [1, 2, 3], issues.map(&:id).sort
3559
3560 assert_select 'input[name=copy_attachments]'
3561 end
3562
3563 def test_bulk_copy_to_another_project
3564 @request.session[:user_id] = 2
3565 assert_difference 'Issue.count', 2 do
3566 assert_no_difference 'Project.find(1).issues.count' do
3567 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
3568 end
3569 end
3570 assert_redirected_to '/projects/ecookbook/issues'
3571
3572 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3573 copies.each do |copy|
3574 assert_equal 2, copy.project_id
3575 end
3576 end
3577
3578 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
3579 @request.session[:user_id] = 2
3580 issues = [
3581 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
3582 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
3583 ]
3584
3585 assert_difference 'Issue.count', issues.size do
3586 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
3587 :issue => {
3588 :project_id => '', :tracker_id => '', :assigned_to_id => '',
3589 :status_id => '', :start_date => '', :due_date => ''
3590 }
3591 end
3592
3593 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3594 issues.each do |orig|
3595 copy = copies.detect {|c| c.subject == orig.subject}
3596 assert_not_nil copy
3597 assert_equal orig.project_id, copy.project_id
3598 assert_equal orig.tracker_id, copy.tracker_id
3599 assert_equal orig.status_id, copy.status_id
3600 assert_equal orig.assigned_to_id, copy.assigned_to_id
3601 assert_equal orig.priority_id, copy.priority_id
3602 end
3603 end
3604
3605 def test_bulk_copy_should_allow_changing_the_issue_attributes
3606 # Fixes random test failure with Mysql
3607 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3608 # doesn't return the expected results
3609 Issue.delete_all("project_id=2")
3610
3611 @request.session[:user_id] = 2
3612 assert_difference 'Issue.count', 2 do
3613 assert_no_difference 'Project.find(1).issues.count' do
3614 post :bulk_update, :ids => [1, 2], :copy => '1',
3615 :issue => {
3616 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
3617 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
3618 }
3619 end
3620 end
3621
3622 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3623 assert_equal 2, copied_issues.size
3624 copied_issues.each do |issue|
3625 assert_equal 2, issue.project_id, "Project is incorrect"
3626 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
3627 assert_equal 1, issue.status_id, "Status is incorrect"
3628 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
3629 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
3630 end
3631 end
3632
3633 def test_bulk_copy_should_allow_adding_a_note
3634 @request.session[:user_id] = 2
3635 assert_difference 'Issue.count', 1 do
3636 post :bulk_update, :ids => [1], :copy => '1',
3637 :notes => 'Copying one issue',
3638 :issue => {
3639 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
3640 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
3641 }
3642 end
3643
3644 issue = Issue.first(:order => 'id DESC')
3645 assert_equal 1, issue.journals.size
3646 journal = issue.journals.first
3647 assert_equal 0, journal.details.size
3648 assert_equal 'Copying one issue', journal.notes
3649 end
3650
3651 def test_bulk_copy_should_allow_not_copying_the_attachments
3652 attachment_count = Issue.find(3).attachments.size
3653 assert attachment_count > 0
3654 @request.session[:user_id] = 2
3655
3656 assert_difference 'Issue.count', 1 do
3657 assert_no_difference 'Attachment.count' do
3658 post :bulk_update, :ids => [3], :copy => '1',
3659 :issue => {
3660 :project_id => ''
3661 }
3662 end
3663 end
3664 end
3665
3666 def test_bulk_copy_should_allow_copying_the_attachments
3667 attachment_count = Issue.find(3).attachments.size
3668 assert attachment_count > 0
3669 @request.session[:user_id] = 2
3670
3671 assert_difference 'Issue.count', 1 do
3672 assert_difference 'Attachment.count', attachment_count do
3673 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
3674 :issue => {
3675 :project_id => ''
3676 }
3677 end
3678 end
3679 end
3680
3681 def test_bulk_copy_should_add_relations_with_copied_issues
3682 @request.session[:user_id] = 2
3683
3684 assert_difference 'Issue.count', 2 do
3685 assert_difference 'IssueRelation.count', 2 do
3686 post :bulk_update, :ids => [1, 3], :copy => '1',
3687 :issue => {
3688 :project_id => '1'
3689 }
3690 end
3691 end
3692 end
3693
3694 def test_bulk_copy_should_allow_not_copying_the_subtasks
3695 issue = Issue.generate_with_descendants!
3696 @request.session[:user_id] = 2
3697
3698 assert_difference 'Issue.count', 1 do
3699 post :bulk_update, :ids => [issue.id], :copy => '1',
3700 :issue => {
3701 :project_id => ''
3702 }
3703 end
3704 end
3705
3706 def test_bulk_copy_should_allow_copying_the_subtasks
3707 issue = Issue.generate_with_descendants!
3708 count = issue.descendants.count
3709 @request.session[:user_id] = 2
3710
3711 assert_difference 'Issue.count', count+1 do
3712 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
3713 :issue => {
3714 :project_id => ''
3715 }
3716 end
3717 copy = Issue.where(:parent_id => nil).order("id DESC").first
3718 assert_equal count, copy.descendants.count
3719 end
3720
3721 def test_bulk_copy_should_not_copy_selected_subtasks_twice
3722 issue = Issue.generate_with_descendants!
3723 count = issue.descendants.count
3724 @request.session[:user_id] = 2
3725
3726 assert_difference 'Issue.count', count+1 do
3727 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
3728 :issue => {
3729 :project_id => ''
3730 }
3731 end
3732 copy = Issue.where(:parent_id => nil).order("id DESC").first
3733 assert_equal count, copy.descendants.count
3734 end
3735
3736 def test_bulk_copy_to_another_project_should_follow_when_needed
3737 @request.session[:user_id] = 2
3738 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
3739 issue = Issue.first(:order => 'id DESC')
3740 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
3741 end
3742
1951 def test_destroy_issue_with_no_time_entries 3743 def test_destroy_issue_with_no_time_entries
1952 assert_nil TimeEntry.find_by_issue_id(2) 3744 assert_nil TimeEntry.find_by_issue_id(2)
1953 @request.session[:user_id] = 2 3745 @request.session[:user_id] = 2
1954 post :destroy, :id => 2 3746
3747 assert_difference 'Issue.count', -1 do
3748 delete :destroy, :id => 2
3749 end
1955 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 3750 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1956 assert_nil Issue.find_by_id(2) 3751 assert_nil Issue.find_by_id(2)
1957 end 3752 end
1958 3753
1959 def test_destroy_issues_with_time_entries 3754 def test_destroy_issues_with_time_entries
1960 @request.session[:user_id] = 2 3755 @request.session[:user_id] = 2
1961 post :destroy, :ids => [1, 3] 3756
3757 assert_no_difference 'Issue.count' do
3758 delete :destroy, :ids => [1, 3]
3759 end
1962 assert_response :success 3760 assert_response :success
1963 assert_template 'destroy' 3761 assert_template 'destroy'
1964 assert_not_nil assigns(:hours) 3762 assert_not_nil assigns(:hours)
1965 assert Issue.find_by_id(1) && Issue.find_by_id(3) 3763 assert Issue.find_by_id(1) && Issue.find_by_id(3)
3764 assert_tag 'form',
3765 :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
1966 end 3766 end
1967 3767
1968 def test_destroy_issues_and_destroy_time_entries 3768 def test_destroy_issues_and_destroy_time_entries
1969 @request.session[:user_id] = 2 3769 @request.session[:user_id] = 2
1970 post :destroy, :ids => [1, 3], :todo => 'destroy' 3770
3771 assert_difference 'Issue.count', -2 do
3772 assert_difference 'TimeEntry.count', -3 do
3773 delete :destroy, :ids => [1, 3], :todo => 'destroy'
3774 end
3775 end
1971 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 3776 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1972 assert !(Issue.find_by_id(1) || Issue.find_by_id(3)) 3777 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1973 assert_nil TimeEntry.find_by_id([1, 2]) 3778 assert_nil TimeEntry.find_by_id([1, 2])
1974 end 3779 end
1975 3780
1976 def test_destroy_issues_and_assign_time_entries_to_project 3781 def test_destroy_issues_and_assign_time_entries_to_project
1977 @request.session[:user_id] = 2 3782 @request.session[:user_id] = 2
1978 post :destroy, :ids => [1, 3], :todo => 'nullify' 3783
3784 assert_difference 'Issue.count', -2 do
3785 assert_no_difference 'TimeEntry.count' do
3786 delete :destroy, :ids => [1, 3], :todo => 'nullify'
3787 end
3788 end
1979 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 3789 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1980 assert !(Issue.find_by_id(1) || Issue.find_by_id(3)) 3790 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1981 assert_nil TimeEntry.find(1).issue_id 3791 assert_nil TimeEntry.find(1).issue_id
1982 assert_nil TimeEntry.find(2).issue_id 3792 assert_nil TimeEntry.find(2).issue_id
1983 end 3793 end
1984 3794
1985 def test_destroy_issues_and_reassign_time_entries_to_another_issue 3795 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1986 @request.session[:user_id] = 2 3796 @request.session[:user_id] = 2
1987 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2 3797
3798 assert_difference 'Issue.count', -2 do
3799 assert_no_difference 'TimeEntry.count' do
3800 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
3801 end
3802 end
1988 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 3803 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1989 assert !(Issue.find_by_id(1) || Issue.find_by_id(3)) 3804 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1990 assert_equal 2, TimeEntry.find(1).issue_id 3805 assert_equal 2, TimeEntry.find(1).issue_id
1991 assert_equal 2, TimeEntry.find(2).issue_id 3806 assert_equal 2, TimeEntry.find(2).issue_id
1992 end 3807 end
1993 3808
1994 def test_destroy_issues_from_different_projects 3809 def test_destroy_issues_from_different_projects
1995 @request.session[:user_id] = 2 3810 @request.session[:user_id] = 2
1996 post :destroy, :ids => [1, 2, 6], :todo => 'destroy' 3811
3812 assert_difference 'Issue.count', -3 do
3813 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
3814 end
1997 assert_redirected_to :controller => 'issues', :action => 'index' 3815 assert_redirected_to :controller => 'issues', :action => 'index'
1998 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6)) 3816 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
1999 end 3817 end
2000 3818
2001 def test_destroy_parent_and_child_issues 3819 def test_destroy_parent_and_child_issues
2002 parent = Issue.generate!(:project_id => 1, :tracker_id => 1) 3820 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
2003 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id) 3821 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
2004 assert child.is_descendant_of?(parent.reload) 3822 assert child.is_descendant_of?(parent.reload)
2005 3823
2006 @request.session[:user_id] = 2 3824 @request.session[:user_id] = 2
2007 assert_difference 'Issue.count', -2 do 3825 assert_difference 'Issue.count', -2 do
2008 post :destroy, :ids => [parent.id, child.id], :todo => 'destroy' 3826 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
2009 end 3827 end
2010 assert_response 302 3828 assert_response 302
2011 end 3829 end
2012 3830
2013 def test_default_search_scope 3831 def test_default_search_scope