annotate test/functional/issues_controller_test.rb @ 8:0c83d98252d9 yuya

* Add custom repo prefix and proper auth realm, remove auth cache (seems like an unwise feature), pass DB handle around, various other bits of tidying
author Chris Cannam
date Thu, 12 Aug 2010 15:31:37 +0100
parents 513646585e45
children 1d32c0a0efbf
rev   line source
Chris@0 1 # Redmine - project management software
Chris@0 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 require File.dirname(__FILE__) + '/../test_helper'
Chris@0 19 require 'issues_controller'
Chris@0 20
Chris@0 21 # Re-raise errors caught by the controller.
Chris@0 22 class IssuesController; def rescue_action(e) raise e end; end
Chris@0 23
Chris@0 24 class IssuesControllerTest < ActionController::TestCase
Chris@0 25 fixtures :projects,
Chris@0 26 :users,
Chris@0 27 :roles,
Chris@0 28 :members,
Chris@0 29 :member_roles,
Chris@0 30 :issues,
Chris@0 31 :issue_statuses,
Chris@0 32 :versions,
Chris@0 33 :trackers,
Chris@0 34 :projects_trackers,
Chris@0 35 :issue_categories,
Chris@0 36 :enabled_modules,
Chris@0 37 :enumerations,
Chris@0 38 :attachments,
Chris@0 39 :workflows,
Chris@0 40 :custom_fields,
Chris@0 41 :custom_values,
Chris@0 42 :custom_fields_projects,
Chris@0 43 :custom_fields_trackers,
Chris@0 44 :time_entries,
Chris@0 45 :journals,
Chris@0 46 :journal_details,
Chris@0 47 :queries
Chris@0 48
Chris@0 49 def setup
Chris@0 50 @controller = IssuesController.new
Chris@0 51 @request = ActionController::TestRequest.new
Chris@0 52 @response = ActionController::TestResponse.new
Chris@0 53 User.current = nil
Chris@0 54 end
Chris@0 55
Chris@0 56 def test_index
Chris@0 57 Setting.default_language = 'en'
Chris@0 58
Chris@0 59 get :index
Chris@0 60 assert_response :success
Chris@0 61 assert_template 'index.rhtml'
Chris@0 62 assert_not_nil assigns(:issues)
Chris@0 63 assert_nil assigns(:project)
Chris@0 64 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 65 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 66 # private projects hidden
Chris@0 67 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
Chris@0 68 assert_no_tag :tag => 'a', :content => /Issue on project 2/
Chris@0 69 # project column
Chris@0 70 assert_tag :tag => 'th', :content => /Project/
Chris@0 71 end
Chris@0 72
Chris@0 73 def test_index_should_not_list_issues_when_module_disabled
Chris@0 74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
Chris@0 75 get :index
Chris@0 76 assert_response :success
Chris@0 77 assert_template 'index.rhtml'
Chris@0 78 assert_not_nil assigns(:issues)
Chris@0 79 assert_nil assigns(:project)
Chris@0 80 assert_no_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 81 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 82 end
Chris@0 83
Chris@0 84 def test_index_should_not_list_issues_when_module_disabled
Chris@0 85 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
Chris@0 86 get :index
Chris@0 87 assert_response :success
Chris@0 88 assert_template 'index.rhtml'
Chris@0 89 assert_not_nil assigns(:issues)
Chris@0 90 assert_nil assigns(:project)
Chris@0 91 assert_no_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 92 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 93 end
Chris@0 94
Chris@0 95 def test_index_with_project
Chris@0 96 Setting.display_subprojects_issues = 0
Chris@0 97 get :index, :project_id => 1
Chris@0 98 assert_response :success
Chris@0 99 assert_template 'index.rhtml'
Chris@0 100 assert_not_nil assigns(:issues)
Chris@0 101 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 102 assert_no_tag :tag => 'a', :content => /Subproject issue/
Chris@0 103 end
Chris@0 104
Chris@0 105 def test_index_with_project_and_subprojects
Chris@0 106 Setting.display_subprojects_issues = 1
Chris@0 107 get :index, :project_id => 1
Chris@0 108 assert_response :success
Chris@0 109 assert_template 'index.rhtml'
Chris@0 110 assert_not_nil assigns(:issues)
Chris@0 111 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 112 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 113 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
Chris@0 114 end
Chris@0 115
Chris@0 116 def test_index_with_project_and_subprojects_should_show_private_subprojects
Chris@0 117 @request.session[:user_id] = 2
Chris@0 118 Setting.display_subprojects_issues = 1
Chris@0 119 get :index, :project_id => 1
Chris@0 120 assert_response :success
Chris@0 121 assert_template 'index.rhtml'
Chris@0 122 assert_not_nil assigns(:issues)
Chris@0 123 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 124 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 125 assert_tag :tag => 'a', :content => /Issue of a private subproject/
Chris@0 126 end
Chris@0 127
Chris@0 128 def test_index_with_project_and_filter
Chris@0 129 get :index, :project_id => 1, :set_filter => 1
Chris@0 130 assert_response :success
Chris@0 131 assert_template 'index.rhtml'
Chris@0 132 assert_not_nil assigns(:issues)
Chris@0 133 end
Chris@0 134
Chris@0 135 def test_index_with_query
Chris@0 136 get :index, :project_id => 1, :query_id => 5
Chris@0 137 assert_response :success
Chris@0 138 assert_template 'index.rhtml'
Chris@0 139 assert_not_nil assigns(:issues)
Chris@0 140 assert_nil assigns(:issue_count_by_group)
Chris@0 141 end
Chris@0 142
Chris@0 143 def test_index_with_query_grouped_by_tracker
Chris@0 144 get :index, :project_id => 1, :query_id => 6
Chris@0 145 assert_response :success
Chris@0 146 assert_template 'index.rhtml'
Chris@0 147 assert_not_nil assigns(:issues)
Chris@0 148 assert_not_nil assigns(:issue_count_by_group)
Chris@0 149 end
Chris@0 150
Chris@0 151 def test_index_with_query_grouped_by_list_custom_field
Chris@0 152 get :index, :project_id => 1, :query_id => 9
Chris@0 153 assert_response :success
Chris@0 154 assert_template 'index.rhtml'
Chris@0 155 assert_not_nil assigns(:issues)
Chris@0 156 assert_not_nil assigns(:issue_count_by_group)
Chris@0 157 end
Chris@0 158
Chris@0 159 def test_index_sort_by_field_not_included_in_columns
Chris@0 160 Setting.issue_list_default_columns = %w(subject author)
Chris@0 161 get :index, :sort => 'tracker'
Chris@0 162 end
Chris@0 163
Chris@0 164 def test_index_csv_with_project
Chris@0 165 Setting.default_language = 'en'
Chris@0 166
Chris@0 167 get :index, :format => 'csv'
Chris@0 168 assert_response :success
Chris@0 169 assert_not_nil assigns(:issues)
Chris@0 170 assert_equal 'text/csv', @response.content_type
Chris@0 171 assert @response.body.starts_with?("#,")
Chris@0 172
Chris@0 173 get :index, :project_id => 1, :format => 'csv'
Chris@0 174 assert_response :success
Chris@0 175 assert_not_nil assigns(:issues)
Chris@0 176 assert_equal 'text/csv', @response.content_type
Chris@0 177 end
Chris@0 178
Chris@0 179 def test_index_pdf
Chris@0 180 get :index, :format => 'pdf'
Chris@0 181 assert_response :success
Chris@0 182 assert_not_nil assigns(:issues)
Chris@0 183 assert_equal 'application/pdf', @response.content_type
Chris@0 184
Chris@0 185 get :index, :project_id => 1, :format => 'pdf'
Chris@0 186 assert_response :success
Chris@0 187 assert_not_nil assigns(:issues)
Chris@0 188 assert_equal 'application/pdf', @response.content_type
Chris@0 189
Chris@0 190 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
Chris@0 191 assert_response :success
Chris@0 192 assert_not_nil assigns(:issues)
Chris@0 193 assert_equal 'application/pdf', @response.content_type
Chris@0 194 end
Chris@0 195
Chris@0 196 def test_index_pdf_with_query_grouped_by_list_custom_field
Chris@0 197 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
Chris@0 198 assert_response :success
Chris@0 199 assert_not_nil assigns(:issues)
Chris@0 200 assert_not_nil assigns(:issue_count_by_group)
Chris@0 201 assert_equal 'application/pdf', @response.content_type
Chris@0 202 end
Chris@0 203
Chris@0 204 def test_index_sort
Chris@0 205 get :index, :sort => 'tracker,id:desc'
Chris@0 206 assert_response :success
Chris@0 207
Chris@0 208 sort_params = @request.session['issues_index_sort']
Chris@0 209 assert sort_params.is_a?(String)
Chris@0 210 assert_equal 'tracker,id:desc', sort_params
Chris@0 211
Chris@0 212 issues = assigns(:issues)
Chris@0 213 assert_not_nil issues
Chris@0 214 assert !issues.empty?
Chris@0 215 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
Chris@0 216 end
Chris@0 217
Chris@0 218 def test_index_with_columns
Chris@0 219 columns = ['tracker', 'subject', 'assigned_to']
Chris@0 220 get :index, :set_filter => 1, :query => { 'column_names' => columns}
Chris@0 221 assert_response :success
Chris@0 222
Chris@0 223 # query should use specified columns
Chris@0 224 query = assigns(:query)
Chris@0 225 assert_kind_of Query, query
Chris@0 226 assert_equal columns, query.column_names.map(&:to_s)
Chris@0 227
Chris@0 228 # columns should be stored in session
Chris@0 229 assert_kind_of Hash, session[:query]
Chris@0 230 assert_kind_of Array, session[:query][:column_names]
Chris@0 231 assert_equal columns, session[:query][:column_names].map(&:to_s)
Chris@0 232 end
Chris@0 233
Chris@0 234 def test_changes
Chris@0 235 get :changes, :project_id => 1
Chris@0 236 assert_response :success
Chris@0 237 assert_not_nil assigns(:journals)
Chris@0 238 assert_equal 'application/atom+xml', @response.content_type
Chris@0 239 end
Chris@0 240
Chris@0 241 def test_show_by_anonymous
Chris@0 242 get :show, :id => 1
Chris@0 243 assert_response :success
Chris@0 244 assert_template 'show.rhtml'
Chris@0 245 assert_not_nil assigns(:issue)
Chris@0 246 assert_equal Issue.find(1), assigns(:issue)
Chris@0 247
Chris@0 248 # anonymous role is allowed to add a note
Chris@0 249 assert_tag :tag => 'form',
Chris@0 250 :descendant => { :tag => 'fieldset',
Chris@0 251 :child => { :tag => 'legend',
Chris@0 252 :content => /Notes/ } }
Chris@0 253 end
Chris@0 254
Chris@0 255 def test_show_by_manager
Chris@0 256 @request.session[:user_id] = 2
Chris@0 257 get :show, :id => 1
Chris@0 258 assert_response :success
Chris@0 259
Chris@0 260 assert_tag :tag => 'form',
Chris@0 261 :descendant => { :tag => 'fieldset',
Chris@0 262 :child => { :tag => 'legend',
Chris@0 263 :content => /Change properties/ } },
Chris@0 264 :descendant => { :tag => 'fieldset',
Chris@0 265 :child => { :tag => 'legend',
Chris@0 266 :content => /Log time/ } },
Chris@0 267 :descendant => { :tag => 'fieldset',
Chris@0 268 :child => { :tag => 'legend',
Chris@0 269 :content => /Notes/ } }
Chris@0 270 end
Chris@0 271
Chris@0 272 def test_show_should_deny_anonymous_access_without_permission
Chris@0 273 Role.anonymous.remove_permission!(:view_issues)
Chris@0 274 get :show, :id => 1
Chris@0 275 assert_response :redirect
Chris@0 276 end
Chris@0 277
Chris@0 278 def test_show_should_deny_non_member_access_without_permission
Chris@0 279 Role.non_member.remove_permission!(:view_issues)
Chris@0 280 @request.session[:user_id] = 9
Chris@0 281 get :show, :id => 1
Chris@0 282 assert_response 403
Chris@0 283 end
Chris@0 284
Chris@0 285 def test_show_should_deny_member_access_without_permission
Chris@0 286 Role.find(1).remove_permission!(:view_issues)
Chris@0 287 @request.session[:user_id] = 2
Chris@0 288 get :show, :id => 1
Chris@0 289 assert_response 403
Chris@0 290 end
Chris@0 291
Chris@0 292 def test_show_should_not_disclose_relations_to_invisible_issues
Chris@0 293 Setting.cross_project_issue_relations = '1'
Chris@0 294 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
Chris@0 295 # Relation to a private project issue
Chris@0 296 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
Chris@0 297
Chris@0 298 get :show, :id => 1
Chris@0 299 assert_response :success
Chris@0 300
Chris@0 301 assert_tag :div, :attributes => { :id => 'relations' },
Chris@0 302 :descendant => { :tag => 'a', :content => /#2$/ }
Chris@0 303 assert_no_tag :div, :attributes => { :id => 'relations' },
Chris@0 304 :descendant => { :tag => 'a', :content => /#4$/ }
Chris@0 305 end
Chris@0 306
Chris@0 307 def test_show_atom
Chris@0 308 get :show, :id => 2, :format => 'atom'
Chris@0 309 assert_response :success
Chris@0 310 assert_template 'changes.rxml'
Chris@0 311 # Inline image
Chris@0 312 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
Chris@0 313 end
Chris@0 314
Chris@0 315 def test_show_export_to_pdf
Chris@0 316 get :show, :id => 3, :format => 'pdf'
Chris@0 317 assert_response :success
Chris@0 318 assert_equal 'application/pdf', @response.content_type
Chris@0 319 assert @response.body.starts_with?('%PDF')
Chris@0 320 assert_not_nil assigns(:issue)
Chris@0 321 end
Chris@0 322
Chris@0 323 def test_get_new
Chris@0 324 @request.session[:user_id] = 2
Chris@0 325 get :new, :project_id => 1, :tracker_id => 1
Chris@0 326 assert_response :success
Chris@0 327 assert_template 'new'
Chris@0 328
Chris@0 329 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
Chris@0 330 :value => 'Default string' }
Chris@0 331 end
Chris@0 332
Chris@0 333 def test_get_new_without_tracker_id
Chris@0 334 @request.session[:user_id] = 2
Chris@0 335 get :new, :project_id => 1
Chris@0 336 assert_response :success
Chris@0 337 assert_template 'new'
Chris@0 338
Chris@0 339 issue = assigns(:issue)
Chris@0 340 assert_not_nil issue
Chris@0 341 assert_equal Project.find(1).trackers.first, issue.tracker
Chris@0 342 end
Chris@0 343
Chris@0 344 def test_get_new_with_no_default_status_should_display_an_error
Chris@0 345 @request.session[:user_id] = 2
Chris@0 346 IssueStatus.delete_all
Chris@0 347
Chris@0 348 get :new, :project_id => 1
Chris@0 349 assert_response 500
Chris@0 350 assert_not_nil flash[:error]
Chris@0 351 assert_tag :tag => 'div', :attributes => { :class => /error/ },
Chris@0 352 :content => /No default issue/
Chris@0 353 end
Chris@0 354
Chris@0 355 def test_get_new_with_no_tracker_should_display_an_error
Chris@0 356 @request.session[:user_id] = 2
Chris@0 357 Tracker.delete_all
Chris@0 358
Chris@0 359 get :new, :project_id => 1
Chris@0 360 assert_response 500
Chris@0 361 assert_not_nil flash[:error]
Chris@0 362 assert_tag :tag => 'div', :attributes => { :class => /error/ },
Chris@0 363 :content => /No tracker/
Chris@0 364 end
Chris@0 365
Chris@0 366 def test_update_new_form
Chris@0 367 @request.session[:user_id] = 2
Chris@0 368 xhr :post, :update_form, :project_id => 1,
Chris@0 369 :issue => {:tracker_id => 2,
Chris@0 370 :subject => 'This is the test_new issue',
Chris@0 371 :description => 'This is the description',
Chris@0 372 :priority_id => 5}
Chris@0 373 assert_response :success
Chris@0 374 assert_template 'attributes'
Chris@0 375
Chris@0 376 issue = assigns(:issue)
Chris@0 377 assert_kind_of Issue, issue
Chris@0 378 assert_equal 1, issue.project_id
Chris@0 379 assert_equal 2, issue.tracker_id
Chris@0 380 assert_equal 'This is the test_new issue', issue.subject
Chris@0 381 end
Chris@0 382
Chris@0 383 def test_post_create
Chris@0 384 @request.session[:user_id] = 2
Chris@0 385 assert_difference 'Issue.count' do
Chris@0 386 post :create, :project_id => 1,
Chris@0 387 :issue => {:tracker_id => 3,
Chris@0 388 :status_id => 2,
Chris@0 389 :subject => 'This is the test_new issue',
Chris@0 390 :description => 'This is the description',
Chris@0 391 :priority_id => 5,
Chris@0 392 :estimated_hours => '',
Chris@0 393 :custom_field_values => {'2' => 'Value for field 2'}}
Chris@0 394 end
Chris@0 395 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@0 396
Chris@0 397 issue = Issue.find_by_subject('This is the test_new issue')
Chris@0 398 assert_not_nil issue
Chris@0 399 assert_equal 2, issue.author_id
Chris@0 400 assert_equal 3, issue.tracker_id
Chris@0 401 assert_equal 2, issue.status_id
Chris@0 402 assert_nil issue.estimated_hours
Chris@0 403 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
Chris@0 404 assert_not_nil v
Chris@0 405 assert_equal 'Value for field 2', v.value
Chris@0 406 end
Chris@0 407
Chris@0 408 def test_post_create_and_continue
Chris@0 409 @request.session[:user_id] = 2
Chris@0 410 post :create, :project_id => 1,
Chris@0 411 :issue => {:tracker_id => 3,
Chris@0 412 :subject => 'This is first issue',
Chris@0 413 :priority_id => 5},
Chris@0 414 :continue => ''
Chris@0 415 assert_redirected_to :controller => 'issues', :action => 'new', :issue => {:tracker_id => 3}
Chris@0 416 end
Chris@0 417
Chris@0 418 def test_post_create_without_custom_fields_param
Chris@0 419 @request.session[:user_id] = 2
Chris@0 420 assert_difference 'Issue.count' do
Chris@0 421 post :create, :project_id => 1,
Chris@0 422 :issue => {:tracker_id => 1,
Chris@0 423 :subject => 'This is the test_new issue',
Chris@0 424 :description => 'This is the description',
Chris@0 425 :priority_id => 5}
Chris@0 426 end
Chris@0 427 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@0 428 end
Chris@0 429
Chris@0 430 def test_post_create_with_required_custom_field_and_without_custom_fields_param
Chris@0 431 field = IssueCustomField.find_by_name('Database')
Chris@0 432 field.update_attribute(:is_required, true)
Chris@0 433
Chris@0 434 @request.session[:user_id] = 2
Chris@0 435 post :create, :project_id => 1,
Chris@0 436 :issue => {:tracker_id => 1,
Chris@0 437 :subject => 'This is the test_new issue',
Chris@0 438 :description => 'This is the description',
Chris@0 439 :priority_id => 5}
Chris@0 440 assert_response :success
Chris@0 441 assert_template 'new'
Chris@0 442 issue = assigns(:issue)
Chris@0 443 assert_not_nil issue
Chris@0 444 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
Chris@0 445 end
Chris@0 446
Chris@0 447 def test_post_create_with_watchers
Chris@0 448 @request.session[:user_id] = 2
Chris@0 449 ActionMailer::Base.deliveries.clear
Chris@0 450
Chris@0 451 assert_difference 'Watcher.count', 2 do
Chris@0 452 post :create, :project_id => 1,
Chris@0 453 :issue => {:tracker_id => 1,
Chris@0 454 :subject => 'This is a new issue with watchers',
Chris@0 455 :description => 'This is the description',
Chris@0 456 :priority_id => 5,
Chris@0 457 :watcher_user_ids => ['2', '3']}
Chris@0 458 end
Chris@0 459 issue = Issue.find_by_subject('This is a new issue with watchers')
Chris@0 460 assert_not_nil issue
Chris@0 461 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
Chris@0 462
Chris@0 463 # Watchers added
Chris@0 464 assert_equal [2, 3], issue.watcher_user_ids.sort
Chris@0 465 assert issue.watched_by?(User.find(3))
Chris@0 466 # Watchers notified
Chris@0 467 mail = ActionMailer::Base.deliveries.last
Chris@0 468 assert_kind_of TMail::Mail, mail
Chris@0 469 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
Chris@0 470 end
Chris@0 471
Chris@0 472 def test_post_create_subissue
Chris@0 473 @request.session[:user_id] = 2
Chris@0 474
Chris@0 475 assert_difference 'Issue.count' do
Chris@0 476 post :create, :project_id => 1,
Chris@0 477 :issue => {:tracker_id => 1,
Chris@0 478 :subject => 'This is a child issue',
Chris@0 479 :parent_issue_id => 2}
Chris@0 480 end
Chris@0 481 issue = Issue.find_by_subject('This is a child issue')
Chris@0 482 assert_not_nil issue
Chris@0 483 assert_equal Issue.find(2), issue.parent
Chris@0 484 end
Chris@0 485
Chris@0 486 def test_post_create_should_send_a_notification
Chris@0 487 ActionMailer::Base.deliveries.clear
Chris@0 488 @request.session[:user_id] = 2
Chris@0 489 assert_difference 'Issue.count' do
Chris@0 490 post :create, :project_id => 1,
Chris@0 491 :issue => {:tracker_id => 3,
Chris@0 492 :subject => 'This is the test_new issue',
Chris@0 493 :description => 'This is the description',
Chris@0 494 :priority_id => 5,
Chris@0 495 :estimated_hours => '',
Chris@0 496 :custom_field_values => {'2' => 'Value for field 2'}}
Chris@0 497 end
Chris@0 498 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@0 499
Chris@0 500 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 501 end
Chris@0 502
Chris@0 503 def test_post_create_should_preserve_fields_values_on_validation_failure
Chris@0 504 @request.session[:user_id] = 2
Chris@0 505 post :create, :project_id => 1,
Chris@0 506 :issue => {:tracker_id => 1,
Chris@0 507 # empty subject
Chris@0 508 :subject => '',
Chris@0 509 :description => 'This is a description',
Chris@0 510 :priority_id => 6,
Chris@0 511 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
Chris@0 512 assert_response :success
Chris@0 513 assert_template 'new'
Chris@0 514
Chris@0 515 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
Chris@0 516 :content => 'This is a description'
Chris@0 517 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
Chris@0 518 :child => { :tag => 'option', :attributes => { :selected => 'selected',
Chris@0 519 :value => '6' },
Chris@0 520 :content => 'High' }
Chris@0 521 # Custom fields
Chris@0 522 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
Chris@0 523 :child => { :tag => 'option', :attributes => { :selected => 'selected',
Chris@0 524 :value => 'Oracle' },
Chris@0 525 :content => 'Oracle' }
Chris@0 526 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
Chris@0 527 :value => 'Value for field 2'}
Chris@0 528 end
Chris@0 529
Chris@0 530 def test_post_create_should_ignore_non_safe_attributes
Chris@0 531 @request.session[:user_id] = 2
Chris@0 532 assert_nothing_raised do
Chris@0 533 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
Chris@0 534 end
Chris@0 535 end
Chris@0 536
Chris@0 537 context "without workflow privilege" do
Chris@0 538 setup do
Chris@0 539 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
Chris@0 540 Role.anonymous.add_permission! :add_issues
Chris@0 541 end
Chris@0 542
Chris@0 543 context "#new" do
Chris@0 544 should "propose default status only" do
Chris@0 545 get :new, :project_id => 1
Chris@0 546 assert_response :success
Chris@0 547 assert_template 'new'
Chris@0 548 assert_tag :tag => 'select',
Chris@0 549 :attributes => {:name => 'issue[status_id]'},
Chris@0 550 :children => {:count => 1},
Chris@0 551 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
Chris@0 552 end
Chris@0 553
Chris@0 554 should "accept default status" do
Chris@0 555 assert_difference 'Issue.count' do
Chris@0 556 post :create, :project_id => 1,
Chris@0 557 :issue => {:tracker_id => 1,
Chris@0 558 :subject => 'This is an issue',
Chris@0 559 :status_id => 1}
Chris@0 560 end
Chris@0 561 issue = Issue.last(:order => 'id')
Chris@0 562 assert_equal IssueStatus.default, issue.status
Chris@0 563 end
Chris@0 564
Chris@0 565 should "ignore unauthorized status" do
Chris@0 566 assert_difference 'Issue.count' do
Chris@0 567 post :create, :project_id => 1,
Chris@0 568 :issue => {:tracker_id => 1,
Chris@0 569 :subject => 'This is an issue',
Chris@0 570 :status_id => 3}
Chris@0 571 end
Chris@0 572 issue = Issue.last(:order => 'id')
Chris@0 573 assert_equal IssueStatus.default, issue.status
Chris@0 574 end
Chris@0 575 end
Chris@0 576 end
Chris@0 577
Chris@0 578 def test_copy_issue
Chris@0 579 @request.session[:user_id] = 2
Chris@0 580 get :new, :project_id => 1, :copy_from => 1
Chris@0 581 assert_template 'new'
Chris@0 582 assert_not_nil assigns(:issue)
Chris@0 583 orig = Issue.find(1)
Chris@0 584 assert_equal orig.subject, assigns(:issue).subject
Chris@0 585 end
Chris@0 586
Chris@0 587 def test_get_edit
Chris@0 588 @request.session[:user_id] = 2
Chris@0 589 get :edit, :id => 1
Chris@0 590 assert_response :success
Chris@0 591 assert_template 'edit'
Chris@0 592 assert_not_nil assigns(:issue)
Chris@0 593 assert_equal Issue.find(1), assigns(:issue)
Chris@0 594 end
Chris@0 595
Chris@0 596 def test_get_edit_with_params
Chris@0 597 @request.session[:user_id] = 2
Chris@0 598 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }
Chris@0 599 assert_response :success
Chris@0 600 assert_template 'edit'
Chris@0 601
Chris@0 602 issue = assigns(:issue)
Chris@0 603 assert_not_nil issue
Chris@0 604
Chris@0 605 assert_equal 5, issue.status_id
Chris@0 606 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
Chris@0 607 :child => { :tag => 'option',
Chris@0 608 :content => 'Closed',
Chris@0 609 :attributes => { :selected => 'selected' } }
Chris@0 610
Chris@0 611 assert_equal 7, issue.priority_id
Chris@0 612 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
Chris@0 613 :child => { :tag => 'option',
Chris@0 614 :content => 'Urgent',
Chris@0 615 :attributes => { :selected => 'selected' } }
Chris@0 616 end
Chris@0 617
Chris@0 618 def test_update_edit_form
Chris@0 619 @request.session[:user_id] = 2
Chris@0 620 xhr :post, :update_form, :project_id => 1,
Chris@0 621 :id => 1,
Chris@0 622 :issue => {:tracker_id => 2,
Chris@0 623 :subject => 'This is the test_new issue',
Chris@0 624 :description => 'This is the description',
Chris@0 625 :priority_id => 5}
Chris@0 626 assert_response :success
Chris@0 627 assert_template 'attributes'
Chris@0 628
Chris@0 629 issue = assigns(:issue)
Chris@0 630 assert_kind_of Issue, issue
Chris@0 631 assert_equal 1, issue.id
Chris@0 632 assert_equal 1, issue.project_id
Chris@0 633 assert_equal 2, issue.tracker_id
Chris@0 634 assert_equal 'This is the test_new issue', issue.subject
Chris@0 635 end
Chris@0 636
Chris@0 637 def test_reply_to_issue
Chris@0 638 @request.session[:user_id] = 2
Chris@0 639 get :reply, :id => 1
Chris@0 640 assert_response :success
Chris@0 641 assert_select_rjs :show, "update"
Chris@0 642 end
Chris@0 643
Chris@0 644 def test_reply_to_note
Chris@0 645 @request.session[:user_id] = 2
Chris@0 646 get :reply, :id => 1, :journal_id => 2
Chris@0 647 assert_response :success
Chris@0 648 assert_select_rjs :show, "update"
Chris@0 649 end
Chris@0 650
Chris@0 651 def test_update_using_invalid_http_verbs
Chris@0 652 @request.session[:user_id] = 2
Chris@0 653 subject = 'Updated by an invalid http verb'
Chris@0 654
Chris@0 655 get :update, :id => 1, :issue => {:subject => subject}
Chris@0 656 assert_not_equal subject, Issue.find(1).subject
Chris@0 657
Chris@0 658 post :update, :id => 1, :issue => {:subject => subject}
Chris@0 659 assert_not_equal subject, Issue.find(1).subject
Chris@0 660
Chris@0 661 delete :update, :id => 1, :issue => {:subject => subject}
Chris@0 662 assert_not_equal subject, Issue.find(1).subject
Chris@0 663 end
Chris@0 664
Chris@0 665 def test_put_update_without_custom_fields_param
Chris@0 666 @request.session[:user_id] = 2
Chris@0 667 ActionMailer::Base.deliveries.clear
Chris@0 668
Chris@0 669 issue = Issue.find(1)
Chris@0 670 assert_equal '125', issue.custom_value_for(2).value
Chris@0 671 old_subject = issue.subject
Chris@0 672 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
Chris@0 673
Chris@0 674 assert_difference('Journal.count') do
Chris@0 675 assert_difference('JournalDetail.count', 2) do
Chris@0 676 put :update, :id => 1, :issue => {:subject => new_subject,
Chris@0 677 :priority_id => '6',
Chris@0 678 :category_id => '1' # no change
Chris@0 679 }
Chris@0 680 end
Chris@0 681 end
Chris@0 682 assert_redirected_to :action => 'show', :id => '1'
Chris@0 683 issue.reload
Chris@0 684 assert_equal new_subject, issue.subject
Chris@0 685 # Make sure custom fields were not cleared
Chris@0 686 assert_equal '125', issue.custom_value_for(2).value
Chris@0 687
Chris@0 688 mail = ActionMailer::Base.deliveries.last
Chris@0 689 assert_kind_of TMail::Mail, mail
Chris@0 690 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
Chris@0 691 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
Chris@0 692 end
Chris@0 693
Chris@0 694 def test_put_update_with_custom_field_change
Chris@0 695 @request.session[:user_id] = 2
Chris@0 696 issue = Issue.find(1)
Chris@0 697 assert_equal '125', issue.custom_value_for(2).value
Chris@0 698
Chris@0 699 assert_difference('Journal.count') do
Chris@0 700 assert_difference('JournalDetail.count', 3) do
Chris@0 701 put :update, :id => 1, :issue => {:subject => 'Custom field change',
Chris@0 702 :priority_id => '6',
Chris@0 703 :category_id => '1', # no change
Chris@0 704 :custom_field_values => { '2' => 'New custom value' }
Chris@0 705 }
Chris@0 706 end
Chris@0 707 end
Chris@0 708 assert_redirected_to :action => 'show', :id => '1'
Chris@0 709 issue.reload
Chris@0 710 assert_equal 'New custom value', issue.custom_value_for(2).value
Chris@0 711
Chris@0 712 mail = ActionMailer::Base.deliveries.last
Chris@0 713 assert_kind_of TMail::Mail, mail
Chris@0 714 assert mail.body.include?("Searchable field changed from 125 to New custom value")
Chris@0 715 end
Chris@0 716
Chris@0 717 def test_put_update_with_status_and_assignee_change
Chris@0 718 issue = Issue.find(1)
Chris@0 719 assert_equal 1, issue.status_id
Chris@0 720 @request.session[:user_id] = 2
Chris@0 721 assert_difference('TimeEntry.count', 0) do
Chris@0 722 put :update,
Chris@0 723 :id => 1,
Chris@0 724 :issue => { :status_id => 2, :assigned_to_id => 3 },
Chris@0 725 :notes => 'Assigned to dlopper',
Chris@0 726 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
Chris@0 727 end
Chris@0 728 assert_redirected_to :action => 'show', :id => '1'
Chris@0 729 issue.reload
Chris@0 730 assert_equal 2, issue.status_id
Chris@0 731 j = Journal.find(:first, :order => 'id DESC')
Chris@0 732 assert_equal 'Assigned to dlopper', j.notes
Chris@0 733 assert_equal 2, j.details.size
Chris@0 734
Chris@0 735 mail = ActionMailer::Base.deliveries.last
Chris@0 736 assert mail.body.include?("Status changed from New to Assigned")
Chris@0 737 # subject should contain the new status
Chris@0 738 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
Chris@0 739 end
Chris@0 740
Chris@0 741 def test_put_update_with_note_only
Chris@0 742 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
Chris@0 743 # anonymous user
Chris@0 744 put :update,
Chris@0 745 :id => 1,
Chris@0 746 :notes => notes
Chris@0 747 assert_redirected_to :action => 'show', :id => '1'
Chris@0 748 j = Journal.find(:first, :order => 'id DESC')
Chris@0 749 assert_equal notes, j.notes
Chris@0 750 assert_equal 0, j.details.size
Chris@0 751 assert_equal User.anonymous, j.user
Chris@0 752
Chris@0 753 mail = ActionMailer::Base.deliveries.last
Chris@0 754 assert mail.body.include?(notes)
Chris@0 755 end
Chris@0 756
Chris@0 757 def test_put_update_with_note_and_spent_time
Chris@0 758 @request.session[:user_id] = 2
Chris@0 759 spent_hours_before = Issue.find(1).spent_hours
Chris@0 760 assert_difference('TimeEntry.count') do
Chris@0 761 put :update,
Chris@0 762 :id => 1,
Chris@0 763 :notes => '2.5 hours added',
Chris@0 764 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
Chris@0 765 end
Chris@0 766 assert_redirected_to :action => 'show', :id => '1'
Chris@0 767
Chris@0 768 issue = Issue.find(1)
Chris@0 769
Chris@0 770 j = Journal.find(:first, :order => 'id DESC')
Chris@0 771 assert_equal '2.5 hours added', j.notes
Chris@0 772 assert_equal 0, j.details.size
Chris@0 773
Chris@0 774 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
Chris@0 775 assert_not_nil t
Chris@0 776 assert_equal 2.5, t.hours
Chris@0 777 assert_equal spent_hours_before + 2.5, issue.spent_hours
Chris@0 778 end
Chris@0 779
Chris@0 780 def test_put_update_with_attachment_only
Chris@0 781 set_tmp_attachments_directory
Chris@0 782
Chris@0 783 # Delete all fixtured journals, a race condition can occur causing the wrong
Chris@0 784 # journal to get fetched in the next find.
Chris@0 785 Journal.delete_all
Chris@0 786
Chris@0 787 # anonymous user
Chris@0 788 put :update,
Chris@0 789 :id => 1,
Chris@0 790 :notes => '',
Chris@0 791 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
Chris@0 792 assert_redirected_to :action => 'show', :id => '1'
Chris@0 793 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
Chris@0 794 assert j.notes.blank?
Chris@0 795 assert_equal 1, j.details.size
Chris@0 796 assert_equal 'testfile.txt', j.details.first.value
Chris@0 797 assert_equal User.anonymous, j.user
Chris@0 798
Chris@0 799 mail = ActionMailer::Base.deliveries.last
Chris@0 800 assert mail.body.include?('testfile.txt')
Chris@0 801 end
Chris@0 802
Chris@0 803 def test_put_update_with_attachment_that_fails_to_save
Chris@0 804 set_tmp_attachments_directory
Chris@0 805
Chris@0 806 # Delete all fixtured journals, a race condition can occur causing the wrong
Chris@0 807 # journal to get fetched in the next find.
Chris@0 808 Journal.delete_all
Chris@0 809
Chris@0 810 # Mock out the unsaved attachment
Chris@0 811 Attachment.any_instance.stubs(:create).returns(Attachment.new)
Chris@0 812
Chris@0 813 # anonymous user
Chris@0 814 put :update,
Chris@0 815 :id => 1,
Chris@0 816 :notes => '',
Chris@0 817 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
Chris@0 818 assert_redirected_to :action => 'show', :id => '1'
Chris@0 819 assert_equal '1 file(s) could not be saved.', flash[:warning]
Chris@0 820
Chris@0 821 end if Object.const_defined?(:Mocha)
Chris@0 822
Chris@0 823 def test_put_update_with_no_change
Chris@0 824 issue = Issue.find(1)
Chris@0 825 issue.journals.clear
Chris@0 826 ActionMailer::Base.deliveries.clear
Chris@0 827
Chris@0 828 put :update,
Chris@0 829 :id => 1,
Chris@0 830 :notes => ''
Chris@0 831 assert_redirected_to :action => 'show', :id => '1'
Chris@0 832
Chris@0 833 issue.reload
Chris@0 834 assert issue.journals.empty?
Chris@0 835 # No email should be sent
Chris@0 836 assert ActionMailer::Base.deliveries.empty?
Chris@0 837 end
Chris@0 838
Chris@0 839 def test_put_update_should_send_a_notification
Chris@0 840 @request.session[:user_id] = 2
Chris@0 841 ActionMailer::Base.deliveries.clear
Chris@0 842 issue = Issue.find(1)
Chris@0 843 old_subject = issue.subject
Chris@0 844 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
Chris@0 845
Chris@0 846 put :update, :id => 1, :issue => {:subject => new_subject,
Chris@0 847 :priority_id => '6',
Chris@0 848 :category_id => '1' # no change
Chris@0 849 }
Chris@0 850 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 851 end
Chris@0 852
Chris@0 853 def test_put_update_with_invalid_spent_time
Chris@0 854 @request.session[:user_id] = 2
Chris@0 855 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
Chris@0 856
Chris@0 857 assert_no_difference('Journal.count') do
Chris@0 858 put :update,
Chris@0 859 :id => 1,
Chris@0 860 :notes => notes,
Chris@0 861 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
Chris@0 862 end
Chris@0 863 assert_response :success
Chris@0 864 assert_template 'edit'
Chris@0 865
Chris@0 866 assert_tag :textarea, :attributes => { :name => 'notes' },
Chris@0 867 :content => notes
Chris@0 868 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
Chris@0 869 end
Chris@0 870
Chris@0 871 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
Chris@0 872 issue = Issue.find(2)
Chris@0 873 @request.session[:user_id] = 2
Chris@0 874
Chris@0 875 put :update,
Chris@0 876 :id => issue.id,
Chris@0 877 :issue => {
Chris@0 878 :fixed_version_id => 4
Chris@0 879 }
Chris@0 880
Chris@0 881 assert_response :redirect
Chris@0 882 issue.reload
Chris@0 883 assert_equal 4, issue.fixed_version_id
Chris@0 884 assert_not_equal issue.project_id, issue.fixed_version.project_id
Chris@0 885 end
Chris@0 886
Chris@0 887 def test_put_update_should_redirect_back_using_the_back_url_parameter
Chris@0 888 issue = Issue.find(2)
Chris@0 889 @request.session[:user_id] = 2
Chris@0 890
Chris@0 891 put :update,
Chris@0 892 :id => issue.id,
Chris@0 893 :issue => {
Chris@0 894 :fixed_version_id => 4
Chris@0 895 },
Chris@0 896 :back_url => '/issues'
Chris@0 897
Chris@0 898 assert_response :redirect
Chris@0 899 assert_redirected_to '/issues'
Chris@0 900 end
Chris@0 901
Chris@0 902 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
Chris@0 903 issue = Issue.find(2)
Chris@0 904 @request.session[:user_id] = 2
Chris@0 905
Chris@0 906 put :update,
Chris@0 907 :id => issue.id,
Chris@0 908 :issue => {
Chris@0 909 :fixed_version_id => 4
Chris@0 910 },
Chris@0 911 :back_url => 'http://google.com'
Chris@0 912
Chris@0 913 assert_response :redirect
Chris@0 914 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
Chris@0 915 end
Chris@0 916
Chris@0 917 def test_get_bulk_edit
Chris@0 918 @request.session[:user_id] = 2
Chris@0 919 get :bulk_edit, :ids => [1, 2]
Chris@0 920 assert_response :success
Chris@0 921 assert_template 'bulk_edit'
Chris@0 922
Chris@0 923 # Project specific custom field, date type
Chris@0 924 field = CustomField.find(9)
Chris@0 925 assert !field.is_for_all?
Chris@0 926 assert_equal 'date', field.field_format
Chris@0 927 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
Chris@0 928
Chris@0 929 # System wide custom field
Chris@0 930 assert CustomField.find(1).is_for_all?
Chris@0 931 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
Chris@0 932 end
Chris@0 933
Chris@0 934 def test_bulk_edit
Chris@0 935 @request.session[:user_id] = 2
Chris@0 936 # update issues priority
Chris@0 937 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing',
Chris@0 938 :issue => {:priority_id => 7,
Chris@0 939 :assigned_to_id => '',
Chris@0 940 :custom_field_values => {'2' => ''}}
Chris@0 941
Chris@0 942 assert_response 302
Chris@0 943 # check that the issues were updated
Chris@0 944 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
Chris@0 945
Chris@0 946 issue = Issue.find(1)
Chris@0 947 journal = issue.journals.find(:first, :order => 'created_on DESC')
Chris@0 948 assert_equal '125', issue.custom_value_for(2).value
Chris@0 949 assert_equal 'Bulk editing', journal.notes
Chris@0 950 assert_equal 1, journal.details.size
Chris@0 951 end
Chris@0 952
Chris@0 953 def test_bullk_edit_should_send_a_notification
Chris@0 954 @request.session[:user_id] = 2
Chris@0 955 ActionMailer::Base.deliveries.clear
Chris@0 956 post(:bulk_edit,
Chris@0 957 {
Chris@0 958 :ids => [1, 2],
Chris@0 959 :notes => 'Bulk editing',
Chris@0 960 :issue => {
Chris@0 961 :priority_id => 7,
Chris@0 962 :assigned_to_id => '',
Chris@0 963 :custom_field_values => {'2' => ''}
Chris@0 964 }
Chris@0 965 })
Chris@0 966
Chris@0 967 assert_response 302
Chris@0 968 assert_equal 2, ActionMailer::Base.deliveries.size
Chris@0 969 end
Chris@0 970
Chris@0 971 def test_bulk_edit_status
Chris@0 972 @request.session[:user_id] = 2
Chris@0 973 # update issues priority
Chris@0 974 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing status',
Chris@0 975 :issue => {:priority_id => '',
Chris@0 976 :assigned_to_id => '',
Chris@0 977 :status_id => '5'}
Chris@0 978
Chris@0 979 assert_response 302
Chris@0 980 issue = Issue.find(1)
Chris@0 981 assert issue.closed?
Chris@0 982 end
Chris@0 983
Chris@0 984 def test_bulk_edit_custom_field
Chris@0 985 @request.session[:user_id] = 2
Chris@0 986 # update issues priority
Chris@0 987 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing custom field',
Chris@0 988 :issue => {:priority_id => '',
Chris@0 989 :assigned_to_id => '',
Chris@0 990 :custom_field_values => {'2' => '777'}}
Chris@0 991
Chris@0 992 assert_response 302
Chris@0 993
Chris@0 994 issue = Issue.find(1)
Chris@0 995 journal = issue.journals.find(:first, :order => 'created_on DESC')
Chris@0 996 assert_equal '777', issue.custom_value_for(2).value
Chris@0 997 assert_equal 1, journal.details.size
Chris@0 998 assert_equal '125', journal.details.first.old_value
Chris@0 999 assert_equal '777', journal.details.first.value
Chris@0 1000 end
Chris@0 1001
Chris@0 1002 def test_bulk_unassign
Chris@0 1003 assert_not_nil Issue.find(2).assigned_to
Chris@0 1004 @request.session[:user_id] = 2
Chris@0 1005 # unassign issues
Chris@0 1006 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
Chris@0 1007 assert_response 302
Chris@0 1008 # check that the issues were updated
Chris@0 1009 assert_nil Issue.find(2).assigned_to
Chris@0 1010 end
Chris@0 1011
Chris@0 1012 def test_post_bulk_edit_should_allow_fixed_version_to_be_set_to_a_subproject
Chris@0 1013 @request.session[:user_id] = 2
Chris@0 1014
Chris@0 1015 post :bulk_edit, :ids => [1,2], :issue => {:fixed_version_id => 4}
Chris@0 1016
Chris@0 1017 assert_response :redirect
Chris@0 1018 issues = Issue.find([1,2])
Chris@0 1019 issues.each do |issue|
Chris@0 1020 assert_equal 4, issue.fixed_version_id
Chris@0 1021 assert_not_equal issue.project_id, issue.fixed_version.project_id
Chris@0 1022 end
Chris@0 1023 end
Chris@0 1024
Chris@0 1025 def test_post_bulk_edit_should_redirect_back_using_the_back_url_parameter
Chris@0 1026 @request.session[:user_id] = 2
Chris@0 1027 post :bulk_edit, :ids => [1,2], :back_url => '/issues'
Chris@0 1028
Chris@0 1029 assert_response :redirect
Chris@0 1030 assert_redirected_to '/issues'
Chris@0 1031 end
Chris@0 1032
Chris@0 1033 def test_post_bulk_edit_should_not_redirect_back_using_the_back_url_parameter_off_the_host
Chris@0 1034 @request.session[:user_id] = 2
Chris@0 1035 post :bulk_edit, :ids => [1,2], :back_url => 'http://google.com'
Chris@0 1036
Chris@0 1037 assert_response :redirect
Chris@0 1038 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
Chris@0 1039 end
Chris@0 1040
Chris@0 1041 def test_move_one_issue_to_another_project
Chris@0 1042 @request.session[:user_id] = 2
Chris@0 1043 post :move, :id => 1, :new_project_id => 2, :tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
Chris@0 1044 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1045 assert_equal 2, Issue.find(1).project_id
Chris@0 1046 end
Chris@0 1047
Chris@0 1048 def test_move_one_issue_to_another_project_should_follow_when_needed
Chris@0 1049 @request.session[:user_id] = 2
Chris@0 1050 post :move, :id => 1, :new_project_id => 2, :follow => '1'
Chris@0 1051 assert_redirected_to '/issues/1'
Chris@0 1052 end
Chris@0 1053
Chris@0 1054 def test_bulk_move_to_another_project
Chris@0 1055 @request.session[:user_id] = 2
Chris@0 1056 post :move, :ids => [1, 2], :new_project_id => 2
Chris@0 1057 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1058 # Issues moved to project 2
Chris@0 1059 assert_equal 2, Issue.find(1).project_id
Chris@0 1060 assert_equal 2, Issue.find(2).project_id
Chris@0 1061 # No tracker change
Chris@0 1062 assert_equal 1, Issue.find(1).tracker_id
Chris@0 1063 assert_equal 2, Issue.find(2).tracker_id
Chris@0 1064 end
Chris@0 1065
Chris@0 1066 def test_bulk_move_to_another_tracker
Chris@0 1067 @request.session[:user_id] = 2
Chris@0 1068 post :move, :ids => [1, 2], :new_tracker_id => 2
Chris@0 1069 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1070 assert_equal 2, Issue.find(1).tracker_id
Chris@0 1071 assert_equal 2, Issue.find(2).tracker_id
Chris@0 1072 end
Chris@0 1073
Chris@0 1074 def test_bulk_copy_to_another_project
Chris@0 1075 @request.session[:user_id] = 2
Chris@0 1076 assert_difference 'Issue.count', 2 do
Chris@0 1077 assert_no_difference 'Project.find(1).issues.count' do
Chris@0 1078 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
Chris@0 1079 end
Chris@0 1080 end
Chris@0 1081 assert_redirected_to 'projects/ecookbook/issues'
Chris@0 1082 end
Chris@0 1083
Chris@0 1084 context "#move via bulk copy" do
Chris@0 1085 should "allow not changing the issue's attributes" do
Chris@0 1086 @request.session[:user_id] = 2
Chris@0 1087 issue_before_move = Issue.find(1)
Chris@0 1088 assert_difference 'Issue.count', 1 do
Chris@0 1089 assert_no_difference 'Project.find(1).issues.count' do
Chris@0 1090 post :move, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
Chris@0 1091 end
Chris@0 1092 end
Chris@0 1093 issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
Chris@0 1094 assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
Chris@0 1095 assert_equal issue_before_move.status_id, issue_after_move.status_id
Chris@0 1096 assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
Chris@0 1097 end
Chris@0 1098
Chris@0 1099 should "allow changing the issue's attributes" do
Chris@0 1100 # Fixes random test failure with Mysql
Chris@0 1101 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2}) doesn't return the expected results
Chris@0 1102 Issue.delete_all("project_id=2")
Chris@0 1103
Chris@0 1104 @request.session[:user_id] = 2
Chris@0 1105 assert_difference 'Issue.count', 2 do
Chris@0 1106 assert_no_difference 'Project.find(1).issues.count' do
Chris@0 1107 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => 4, :status_id => 3, :start_date => '2009-12-01', :due_date => '2009-12-31'
Chris@0 1108 end
Chris@0 1109 end
Chris@0 1110
Chris@0 1111 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
Chris@0 1112 assert_equal 2, copied_issues.size
Chris@0 1113 copied_issues.each do |issue|
Chris@0 1114 assert_equal 2, issue.project_id, "Project is incorrect"
Chris@0 1115 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
Chris@0 1116 assert_equal 3, issue.status_id, "Status is incorrect"
Chris@0 1117 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
Chris@0 1118 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
Chris@0 1119 end
Chris@0 1120 end
Chris@0 1121 end
Chris@0 1122
Chris@0 1123 def test_copy_to_another_project_should_follow_when_needed
Chris@0 1124 @request.session[:user_id] = 2
Chris@0 1125 post :move, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :follow => '1'
Chris@0 1126 issue = Issue.first(:order => 'id DESC')
Chris@0 1127 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
Chris@0 1128 end
Chris@0 1129
Chris@0 1130 def test_context_menu_one_issue
Chris@0 1131 @request.session[:user_id] = 2
Chris@0 1132 get :context_menu, :ids => [1]
Chris@0 1133 assert_response :success
Chris@0 1134 assert_template 'context_menu'
Chris@0 1135 assert_tag :tag => 'a', :content => 'Edit',
Chris@0 1136 :attributes => { :href => '/issues/1/edit',
Chris@0 1137 :class => 'icon-edit' }
Chris@0 1138 assert_tag :tag => 'a', :content => 'Closed',
Chris@0 1139 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
Chris@0 1140 :class => '' }
Chris@0 1141 assert_tag :tag => 'a', :content => 'Immediate',
Chris@0 1142 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
Chris@0 1143 :class => '' }
Chris@0 1144 # Versions
Chris@0 1145 assert_tag :tag => 'a', :content => '2.0',
Chris@0 1146 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
Chris@0 1147 :class => '' }
Chris@0 1148 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
Chris@0 1149 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
Chris@0 1150 :class => '' }
Chris@0 1151
Chris@0 1152 assert_tag :tag => 'a', :content => 'Dave Lopper',
Chris@0 1153 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
Chris@0 1154 :class => '' }
Chris@0 1155 assert_tag :tag => 'a', :content => 'Duplicate',
Chris@0 1156 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
Chris@0 1157 :class => 'icon-duplicate' }
Chris@0 1158 assert_tag :tag => 'a', :content => 'Copy',
Chris@0 1159 :attributes => { :href => '/issues/move?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
Chris@0 1160 :class => 'icon-copy' }
Chris@0 1161 assert_tag :tag => 'a', :content => 'Move',
Chris@0 1162 :attributes => { :href => '/issues/move?ids%5B%5D=1',
Chris@0 1163 :class => 'icon-move' }
Chris@0 1164 assert_tag :tag => 'a', :content => 'Delete',
Chris@0 1165 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
Chris@0 1166 :class => 'icon-del' }
Chris@0 1167 end
Chris@0 1168
Chris@0 1169 def test_context_menu_one_issue_by_anonymous
Chris@0 1170 get :context_menu, :ids => [1]
Chris@0 1171 assert_response :success
Chris@0 1172 assert_template 'context_menu'
Chris@0 1173 assert_tag :tag => 'a', :content => 'Delete',
Chris@0 1174 :attributes => { :href => '#',
Chris@0 1175 :class => 'icon-del disabled' }
Chris@0 1176 end
Chris@0 1177
Chris@0 1178 def test_context_menu_multiple_issues_of_same_project
Chris@0 1179 @request.session[:user_id] = 2
Chris@0 1180 get :context_menu, :ids => [1, 2]
Chris@0 1181 assert_response :success
Chris@0 1182 assert_template 'context_menu'
Chris@0 1183 assert_tag :tag => 'a', :content => 'Edit',
Chris@0 1184 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
Chris@0 1185 :class => 'icon-edit' }
Chris@0 1186 assert_tag :tag => 'a', :content => 'Immediate',
Chris@0 1187 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bpriority_id%5D=8',
Chris@0 1188 :class => '' }
Chris@0 1189 assert_tag :tag => 'a', :content => 'Dave Lopper',
Chris@0 1190 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bassigned_to_id%5D=3',
Chris@0 1191 :class => '' }
Chris@0 1192 assert_tag :tag => 'a', :content => 'Copy',
Chris@0 1193 :attributes => { :href => '/issues/move?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
Chris@0 1194 :class => 'icon-copy' }
Chris@0 1195 assert_tag :tag => 'a', :content => 'Move',
Chris@0 1196 :attributes => { :href => '/issues/move?ids%5B%5D=1&amp;ids%5B%5D=2',
Chris@0 1197 :class => 'icon-move' }
Chris@0 1198 assert_tag :tag => 'a', :content => 'Delete',
Chris@0 1199 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
Chris@0 1200 :class => 'icon-del' }
Chris@0 1201 end
Chris@0 1202
Chris@0 1203 def test_context_menu_multiple_issues_of_different_project
Chris@0 1204 @request.session[:user_id] = 2
Chris@0 1205 get :context_menu, :ids => [1, 2, 4]
Chris@0 1206 assert_response :success
Chris@0 1207 assert_template 'context_menu'
Chris@0 1208 assert_tag :tag => 'a', :content => 'Delete',
Chris@0 1209 :attributes => { :href => '#',
Chris@0 1210 :class => 'icon-del disabled' }
Chris@0 1211 end
Chris@0 1212
Chris@0 1213 def test_preview_new_issue
Chris@0 1214 @request.session[:user_id] = 2
Chris@0 1215 post :preview, :project_id => '1', :issue => {:description => 'Foo'}
Chris@0 1216 assert_response :success
Chris@0 1217 assert_template 'preview'
Chris@0 1218 assert_not_nil assigns(:description)
Chris@0 1219 end
Chris@0 1220
Chris@0 1221 def test_preview_notes
Chris@0 1222 @request.session[:user_id] = 2
Chris@0 1223 post :preview, :project_id => '1', :id => 1, :issue => {:description => Issue.find(1).description}, :notes => 'Foo'
Chris@0 1224 assert_response :success
Chris@0 1225 assert_template 'preview'
Chris@0 1226 assert_not_nil assigns(:notes)
Chris@0 1227 end
Chris@0 1228
Chris@0 1229 def test_auto_complete_should_not_be_case_sensitive
Chris@0 1230 get :auto_complete, :project_id => 'ecookbook', :q => 'ReCiPe'
Chris@0 1231 assert_response :success
Chris@0 1232 assert_not_nil assigns(:issues)
Chris@0 1233 assert assigns(:issues).detect {|issue| issue.subject.match /recipe/}
Chris@0 1234 end
Chris@0 1235
Chris@0 1236 def test_auto_complete_should_return_issue_with_given_id
Chris@0 1237 get :auto_complete, :project_id => 'subproject1', :q => '13'
Chris@0 1238 assert_response :success
Chris@0 1239 assert_not_nil assigns(:issues)
Chris@0 1240 assert assigns(:issues).include?(Issue.find(13))
Chris@0 1241 end
Chris@0 1242
Chris@0 1243 def test_destroy_issue_with_no_time_entries
Chris@0 1244 assert_nil TimeEntry.find_by_issue_id(2)
Chris@0 1245 @request.session[:user_id] = 2
Chris@0 1246 post :destroy, :id => 2
Chris@0 1247 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1248 assert_nil Issue.find_by_id(2)
Chris@0 1249 end
Chris@0 1250
Chris@0 1251 def test_destroy_issues_with_time_entries
Chris@0 1252 @request.session[:user_id] = 2
Chris@0 1253 post :destroy, :ids => [1, 3]
Chris@0 1254 assert_response :success
Chris@0 1255 assert_template 'destroy'
Chris@0 1256 assert_not_nil assigns(:hours)
Chris@0 1257 assert Issue.find_by_id(1) && Issue.find_by_id(3)
Chris@0 1258 end
Chris@0 1259
Chris@0 1260 def test_destroy_issues_and_destroy_time_entries
Chris@0 1261 @request.session[:user_id] = 2
Chris@0 1262 post :destroy, :ids => [1, 3], :todo => 'destroy'
Chris@0 1263 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1264 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
Chris@0 1265 assert_nil TimeEntry.find_by_id([1, 2])
Chris@0 1266 end
Chris@0 1267
Chris@0 1268 def test_destroy_issues_and_assign_time_entries_to_project
Chris@0 1269 @request.session[:user_id] = 2
Chris@0 1270 post :destroy, :ids => [1, 3], :todo => 'nullify'
Chris@0 1271 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1272 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
Chris@0 1273 assert_nil TimeEntry.find(1).issue_id
Chris@0 1274 assert_nil TimeEntry.find(2).issue_id
Chris@0 1275 end
Chris@0 1276
Chris@0 1277 def test_destroy_issues_and_reassign_time_entries_to_another_issue
Chris@0 1278 @request.session[:user_id] = 2
Chris@0 1279 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
Chris@0 1280 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1281 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
Chris@0 1282 assert_equal 2, TimeEntry.find(1).issue_id
Chris@0 1283 assert_equal 2, TimeEntry.find(2).issue_id
Chris@0 1284 end
Chris@0 1285
Chris@0 1286 def test_default_search_scope
Chris@0 1287 get :index
Chris@0 1288 assert_tag :div, :attributes => {:id => 'quick-search'},
Chris@0 1289 :child => {:tag => 'form',
Chris@0 1290 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
Chris@0 1291 end
Chris@0 1292 end