annotate test/functional/issues_controller_test.rb @ 855:7294e8db2515 bug_162

Close obsolete branch bug_162
author Chris Cannam
date Thu, 14 Jul 2011 11:59:19 +0100
parents cbce1fd3b1b7
children 0c939c159af4
rev   line source
Chris@0 1 # Redmine - project management software
Chris@441 2 # Copyright (C) 2006-2011 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@441 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@441 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@119 18 require File.expand_path('../../test_helper', __FILE__)
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@441 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@441 55
Chris@0 56 def test_index
Chris@0 57 Setting.default_language = 'en'
Chris@441 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@441 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@441 94
Chris@441 95 def test_index_should_list_visible_issues_only
Chris@441 96 get :index, :per_page => 100
Chris@441 97 assert_response :success
Chris@441 98 assert_not_nil assigns(:issues)
Chris@441 99 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
Chris@441 100 end
Chris@441 101
Chris@0 102 def test_index_with_project
Chris@0 103 Setting.display_subprojects_issues = 0
Chris@0 104 get :index, :project_id => 1
Chris@0 105 assert_response :success
Chris@0 106 assert_template 'index.rhtml'
Chris@0 107 assert_not_nil assigns(:issues)
Chris@0 108 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 109 assert_no_tag :tag => 'a', :content => /Subproject issue/
Chris@0 110 end
Chris@441 111
Chris@0 112 def test_index_with_project_and_subprojects
Chris@0 113 Setting.display_subprojects_issues = 1
Chris@0 114 get :index, :project_id => 1
Chris@0 115 assert_response :success
Chris@0 116 assert_template 'index.rhtml'
Chris@0 117 assert_not_nil assigns(:issues)
Chris@0 118 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 119 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 120 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
Chris@0 121 end
Chris@441 122
Chris@0 123 def test_index_with_project_and_subprojects_should_show_private_subprojects
Chris@0 124 @request.session[:user_id] = 2
Chris@0 125 Setting.display_subprojects_issues = 1
Chris@0 126 get :index, :project_id => 1
Chris@0 127 assert_response :success
Chris@0 128 assert_template 'index.rhtml'
Chris@0 129 assert_not_nil assigns(:issues)
Chris@0 130 assert_tag :tag => 'a', :content => /Can't print recipes/
Chris@0 131 assert_tag :tag => 'a', :content => /Subproject issue/
Chris@0 132 assert_tag :tag => 'a', :content => /Issue of a private subproject/
Chris@0 133 end
Chris@441 134
chris@37 135 def test_index_with_project_and_default_filter
Chris@0 136 get :index, :project_id => 1, :set_filter => 1
Chris@0 137 assert_response :success
Chris@0 138 assert_template 'index.rhtml'
Chris@0 139 assert_not_nil assigns(:issues)
Chris@441 140
chris@37 141 query = assigns(:query)
chris@37 142 assert_not_nil query
chris@37 143 # default filter
chris@37 144 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
chris@37 145 end
Chris@441 146
chris@37 147 def test_index_with_project_and_filter
Chris@441 148 get :index, :project_id => 1, :set_filter => 1,
Chris@441 149 :f => ['tracker_id'],
Chris@441 150 :op => {'tracker_id' => '='},
Chris@441 151 :v => {'tracker_id' => ['1']}
chris@37 152 assert_response :success
chris@37 153 assert_template 'index.rhtml'
chris@37 154 assert_not_nil assigns(:issues)
Chris@441 155
chris@37 156 query = assigns(:query)
chris@37 157 assert_not_nil query
chris@37 158 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
chris@37 159 end
Chris@441 160
chris@37 161 def test_index_with_project_and_empty_filters
chris@37 162 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
chris@37 163 assert_response :success
chris@37 164 assert_template 'index.rhtml'
chris@37 165 assert_not_nil assigns(:issues)
Chris@441 166
chris@37 167 query = assigns(:query)
chris@37 168 assert_not_nil query
chris@37 169 # no filter
chris@37 170 assert_equal({}, query.filters)
Chris@0 171 end
Chris@441 172
Chris@0 173 def test_index_with_query
Chris@0 174 get :index, :project_id => 1, :query_id => 5
Chris@0 175 assert_response :success
Chris@0 176 assert_template 'index.rhtml'
Chris@0 177 assert_not_nil assigns(:issues)
Chris@0 178 assert_nil assigns(:issue_count_by_group)
Chris@0 179 end
Chris@441 180
Chris@0 181 def test_index_with_query_grouped_by_tracker
Chris@0 182 get :index, :project_id => 1, :query_id => 6
Chris@0 183 assert_response :success
Chris@0 184 assert_template 'index.rhtml'
Chris@0 185 assert_not_nil assigns(:issues)
Chris@0 186 assert_not_nil assigns(:issue_count_by_group)
Chris@0 187 end
Chris@441 188
Chris@0 189 def test_index_with_query_grouped_by_list_custom_field
Chris@0 190 get :index, :project_id => 1, :query_id => 9
Chris@0 191 assert_response :success
Chris@0 192 assert_template 'index.rhtml'
Chris@0 193 assert_not_nil assigns(:issues)
Chris@0 194 assert_not_nil assigns(:issue_count_by_group)
Chris@0 195 end
Chris@441 196
Chris@0 197 def test_index_sort_by_field_not_included_in_columns
Chris@0 198 Setting.issue_list_default_columns = %w(subject author)
Chris@0 199 get :index, :sort => 'tracker'
Chris@0 200 end
Chris@441 201
Chris@0 202 def test_index_csv_with_project
Chris@0 203 Setting.default_language = 'en'
Chris@441 204
Chris@0 205 get :index, :format => 'csv'
Chris@0 206 assert_response :success
Chris@0 207 assert_not_nil assigns(:issues)
Chris@0 208 assert_equal 'text/csv', @response.content_type
Chris@0 209 assert @response.body.starts_with?("#,")
Chris@0 210
Chris@0 211 get :index, :project_id => 1, :format => 'csv'
Chris@0 212 assert_response :success
Chris@0 213 assert_not_nil assigns(:issues)
Chris@0 214 assert_equal 'text/csv', @response.content_type
Chris@0 215 end
Chris@441 216
Chris@0 217 def test_index_pdf
Chris@0 218 get :index, :format => 'pdf'
Chris@0 219 assert_response :success
Chris@0 220 assert_not_nil assigns(:issues)
Chris@0 221 assert_equal 'application/pdf', @response.content_type
Chris@441 222
Chris@0 223 get :index, :project_id => 1, :format => 'pdf'
Chris@0 224 assert_response :success
Chris@0 225 assert_not_nil assigns(:issues)
Chris@0 226 assert_equal 'application/pdf', @response.content_type
Chris@441 227
Chris@0 228 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
Chris@0 229 assert_response :success
Chris@0 230 assert_not_nil assigns(:issues)
Chris@0 231 assert_equal 'application/pdf', @response.content_type
Chris@0 232 end
Chris@441 233
Chris@0 234 def test_index_pdf_with_query_grouped_by_list_custom_field
Chris@0 235 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
Chris@0 236 assert_response :success
Chris@0 237 assert_not_nil assigns(:issues)
Chris@0 238 assert_not_nil assigns(:issue_count_by_group)
Chris@0 239 assert_equal 'application/pdf', @response.content_type
Chris@0 240 end
Chris@441 241
Chris@0 242 def test_index_sort
Chris@0 243 get :index, :sort => 'tracker,id:desc'
Chris@0 244 assert_response :success
Chris@441 245
Chris@0 246 sort_params = @request.session['issues_index_sort']
Chris@0 247 assert sort_params.is_a?(String)
Chris@0 248 assert_equal 'tracker,id:desc', sort_params
Chris@441 249
Chris@0 250 issues = assigns(:issues)
Chris@0 251 assert_not_nil issues
Chris@0 252 assert !issues.empty?
Chris@0 253 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 254 end
Chris@441 255
Chris@0 256 def test_index_with_columns
Chris@0 257 columns = ['tracker', 'subject', 'assigned_to']
Chris@441 258 get :index, :set_filter => 1, :c => columns
Chris@0 259 assert_response :success
Chris@441 260
Chris@0 261 # query should use specified columns
Chris@0 262 query = assigns(:query)
Chris@0 263 assert_kind_of Query, query
Chris@0 264 assert_equal columns, query.column_names.map(&:to_s)
Chris@441 265
Chris@0 266 # columns should be stored in session
Chris@0 267 assert_kind_of Hash, session[:query]
Chris@0 268 assert_kind_of Array, session[:query][:column_names]
Chris@0 269 assert_equal columns, session[:query][:column_names].map(&:to_s)
Chris@0 270 end
Chris@0 271
Chris@441 272 def test_index_with_custom_field_column
Chris@441 273 columns = %w(tracker subject cf_2)
Chris@441 274 get :index, :set_filter => 1, :c => columns
Chris@441 275 assert_response :success
Chris@441 276
Chris@441 277 # query should use specified columns
Chris@441 278 query = assigns(:query)
Chris@441 279 assert_kind_of Query, query
Chris@441 280 assert_equal columns, query.column_names.map(&:to_s)
Chris@441 281
Chris@441 282 assert_tag :td,
Chris@441 283 :attributes => {:class => 'cf_2 string'},
Chris@441 284 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
Chris@441 285 end
Chris@441 286
Chris@0 287 def test_show_by_anonymous
Chris@0 288 get :show, :id => 1
Chris@0 289 assert_response :success
Chris@0 290 assert_template 'show.rhtml'
Chris@0 291 assert_not_nil assigns(:issue)
Chris@0 292 assert_equal Issue.find(1), assigns(:issue)
Chris@441 293
Chris@0 294 # anonymous role is allowed to add a note
Chris@0 295 assert_tag :tag => 'form',
Chris@0 296 :descendant => { :tag => 'fieldset',
Chris@441 297 :child => { :tag => 'legend',
Chris@0 298 :content => /Notes/ } }
Chris@0 299 end
Chris@441 300
Chris@0 301 def test_show_by_manager
Chris@0 302 @request.session[:user_id] = 2
Chris@0 303 get :show, :id => 1
Chris@0 304 assert_response :success
Chris@441 305
Chris@119 306 assert_tag :tag => 'a',
Chris@119 307 :content => /Quote/
Chris@441 308
Chris@0 309 assert_tag :tag => 'form',
Chris@0 310 :descendant => { :tag => 'fieldset',
Chris@441 311 :child => { :tag => 'legend',
Chris@0 312 :content => /Change properties/ } },
Chris@0 313 :descendant => { :tag => 'fieldset',
Chris@441 314 :child => { :tag => 'legend',
Chris@0 315 :content => /Log time/ } },
Chris@0 316 :descendant => { :tag => 'fieldset',
Chris@441 317 :child => { :tag => 'legend',
Chris@0 318 :content => /Notes/ } }
Chris@0 319 end
Chris@441 320
Chris@0 321 def test_show_should_deny_anonymous_access_without_permission
Chris@0 322 Role.anonymous.remove_permission!(:view_issues)
Chris@0 323 get :show, :id => 1
Chris@0 324 assert_response :redirect
Chris@0 325 end
Chris@441 326
Chris@441 327 def test_show_should_deny_anonymous_access_to_private_issue
Chris@441 328 Issue.update_all(["is_private = ?", true], "id = 1")
Chris@441 329 get :show, :id => 1
Chris@441 330 assert_response :redirect
Chris@441 331 end
Chris@441 332
Chris@0 333 def test_show_should_deny_non_member_access_without_permission
Chris@0 334 Role.non_member.remove_permission!(:view_issues)
Chris@0 335 @request.session[:user_id] = 9
Chris@0 336 get :show, :id => 1
Chris@0 337 assert_response 403
Chris@0 338 end
Chris@441 339
Chris@441 340 def test_show_should_deny_non_member_access_to_private_issue
Chris@441 341 Issue.update_all(["is_private = ?", true], "id = 1")
Chris@441 342 @request.session[:user_id] = 9
Chris@441 343 get :show, :id => 1
Chris@441 344 assert_response 403
Chris@441 345 end
Chris@441 346
Chris@0 347 def test_show_should_deny_member_access_without_permission
Chris@0 348 Role.find(1).remove_permission!(:view_issues)
Chris@0 349 @request.session[:user_id] = 2
Chris@0 350 get :show, :id => 1
Chris@0 351 assert_response 403
Chris@0 352 end
Chris@441 353
Chris@441 354 def test_show_should_deny_member_access_to_private_issue_without_permission
Chris@441 355 Issue.update_all(["is_private = ?", true], "id = 1")
Chris@441 356 @request.session[:user_id] = 3
Chris@441 357 get :show, :id => 1
Chris@441 358 assert_response 403
Chris@441 359 end
Chris@441 360
Chris@441 361 def test_show_should_allow_author_access_to_private_issue
Chris@441 362 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
Chris@441 363 @request.session[:user_id] = 3
Chris@441 364 get :show, :id => 1
Chris@441 365 assert_response :success
Chris@441 366 end
Chris@441 367
Chris@441 368 def test_show_should_allow_assignee_access_to_private_issue
Chris@441 369 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
Chris@441 370 @request.session[:user_id] = 3
Chris@441 371 get :show, :id => 1
Chris@441 372 assert_response :success
Chris@441 373 end
Chris@441 374
Chris@441 375 def test_show_should_allow_member_access_to_private_issue_with_permission
Chris@441 376 Issue.update_all(["is_private = ?", true], "id = 1")
Chris@441 377 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
Chris@441 378 @request.session[:user_id] = 3
Chris@441 379 get :show, :id => 1
Chris@441 380 assert_response :success
Chris@441 381 end
Chris@441 382
Chris@0 383 def test_show_should_not_disclose_relations_to_invisible_issues
Chris@0 384 Setting.cross_project_issue_relations = '1'
Chris@0 385 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
Chris@0 386 # Relation to a private project issue
Chris@0 387 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
Chris@441 388
Chris@0 389 get :show, :id => 1
Chris@0 390 assert_response :success
Chris@441 391
Chris@0 392 assert_tag :div, :attributes => { :id => 'relations' },
Chris@0 393 :descendant => { :tag => 'a', :content => /#2$/ }
Chris@0 394 assert_no_tag :div, :attributes => { :id => 'relations' },
Chris@0 395 :descendant => { :tag => 'a', :content => /#4$/ }
Chris@0 396 end
Chris@441 397
Chris@0 398 def test_show_atom
Chris@0 399 get :show, :id => 2, :format => 'atom'
Chris@0 400 assert_response :success
Chris@14 401 assert_template 'journals/index.rxml'
Chris@0 402 # Inline image
Chris@0 403 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
Chris@0 404 end
Chris@441 405
Chris@0 406 def test_show_export_to_pdf
Chris@0 407 get :show, :id => 3, :format => 'pdf'
Chris@0 408 assert_response :success
Chris@0 409 assert_equal 'application/pdf', @response.content_type
Chris@0 410 assert @response.body.starts_with?('%PDF')
Chris@0 411 assert_not_nil assigns(:issue)
Chris@0 412 end
Chris@0 413
Chris@0 414 def test_get_new
Chris@0 415 @request.session[:user_id] = 2
Chris@0 416 get :new, :project_id => 1, :tracker_id => 1
Chris@0 417 assert_response :success
Chris@0 418 assert_template 'new'
Chris@441 419
Chris@0 420 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
Chris@0 421 :value => 'Default string' }
Chris@0 422 end
Chris@0 423
Chris@0 424 def test_get_new_without_tracker_id
Chris@0 425 @request.session[:user_id] = 2
Chris@0 426 get :new, :project_id => 1
Chris@0 427 assert_response :success
Chris@0 428 assert_template 'new'
Chris@441 429
Chris@0 430 issue = assigns(:issue)
Chris@0 431 assert_not_nil issue
Chris@0 432 assert_equal Project.find(1).trackers.first, issue.tracker
Chris@0 433 end
Chris@441 434
Chris@0 435 def test_get_new_with_no_default_status_should_display_an_error
Chris@0 436 @request.session[:user_id] = 2
Chris@0 437 IssueStatus.delete_all
Chris@441 438
Chris@0 439 get :new, :project_id => 1
Chris@0 440 assert_response 500
chris@37 441 assert_error_tag :content => /No default issue/
Chris@0 442 end
Chris@441 443
Chris@0 444 def test_get_new_with_no_tracker_should_display_an_error
Chris@0 445 @request.session[:user_id] = 2
Chris@0 446 Tracker.delete_all
Chris@441 447
Chris@0 448 get :new, :project_id => 1
Chris@0 449 assert_response 500
chris@37 450 assert_error_tag :content => /No tracker/
Chris@0 451 end
Chris@441 452
Chris@0 453 def test_update_new_form
Chris@0 454 @request.session[:user_id] = 2
Chris@14 455 xhr :post, :new, :project_id => 1,
Chris@441 456 :issue => {:tracker_id => 2,
Chris@0 457 :subject => 'This is the test_new issue',
Chris@0 458 :description => 'This is the description',
Chris@0 459 :priority_id => 5}
Chris@0 460 assert_response :success
Chris@0 461 assert_template 'attributes'
Chris@441 462
Chris@0 463 issue = assigns(:issue)
Chris@0 464 assert_kind_of Issue, issue
Chris@0 465 assert_equal 1, issue.project_id
Chris@0 466 assert_equal 2, issue.tracker_id
Chris@0 467 assert_equal 'This is the test_new issue', issue.subject
Chris@0 468 end
Chris@441 469
Chris@0 470 def test_post_create
Chris@0 471 @request.session[:user_id] = 2
Chris@0 472 assert_difference 'Issue.count' do
Chris@441 473 post :create, :project_id => 1,
Chris@0 474 :issue => {:tracker_id => 3,
Chris@0 475 :status_id => 2,
Chris@0 476 :subject => 'This is the test_new issue',
Chris@0 477 :description => 'This is the description',
Chris@0 478 :priority_id => 5,
chris@37 479 :start_date => '2010-11-07',
Chris@0 480 :estimated_hours => '',
Chris@0 481 :custom_field_values => {'2' => 'Value for field 2'}}
Chris@0 482 end
Chris@0 483 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@441 484
Chris@0 485 issue = Issue.find_by_subject('This is the test_new issue')
Chris@0 486 assert_not_nil issue
Chris@0 487 assert_equal 2, issue.author_id
Chris@0 488 assert_equal 3, issue.tracker_id
Chris@0 489 assert_equal 2, issue.status_id
chris@37 490 assert_equal Date.parse('2010-11-07'), issue.start_date
Chris@0 491 assert_nil issue.estimated_hours
Chris@0 492 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
Chris@0 493 assert_not_nil v
Chris@0 494 assert_equal 'Value for field 2', v.value
Chris@0 495 end
Chris@441 496
chris@37 497 def test_post_create_without_start_date
chris@37 498 @request.session[:user_id] = 2
chris@37 499 assert_difference 'Issue.count' do
Chris@441 500 post :create, :project_id => 1,
chris@37 501 :issue => {:tracker_id => 3,
chris@37 502 :status_id => 2,
chris@37 503 :subject => 'This is the test_new issue',
chris@37 504 :description => 'This is the description',
chris@37 505 :priority_id => 5,
chris@37 506 :start_date => '',
chris@37 507 :estimated_hours => '',
chris@37 508 :custom_field_values => {'2' => 'Value for field 2'}}
chris@37 509 end
chris@37 510 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@441 511
chris@37 512 issue = Issue.find_by_subject('This is the test_new issue')
chris@37 513 assert_not_nil issue
chris@37 514 assert_nil issue.start_date
chris@37 515 end
Chris@441 516
Chris@0 517 def test_post_create_and_continue
Chris@0 518 @request.session[:user_id] = 2
Chris@441 519 post :create, :project_id => 1,
Chris@0 520 :issue => {:tracker_id => 3,
Chris@0 521 :subject => 'This is first issue',
Chris@0 522 :priority_id => 5},
Chris@0 523 :continue => ''
chris@22 524 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook',
chris@22 525 :issue => {:tracker_id => 3}
Chris@0 526 end
Chris@441 527
Chris@0 528 def test_post_create_without_custom_fields_param
Chris@0 529 @request.session[:user_id] = 2
Chris@0 530 assert_difference 'Issue.count' do
Chris@441 531 post :create, :project_id => 1,
Chris@0 532 :issue => {:tracker_id => 1,
Chris@0 533 :subject => 'This is the test_new issue',
Chris@0 534 :description => 'This is the description',
Chris@0 535 :priority_id => 5}
Chris@0 536 end
Chris@0 537 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@0 538 end
Chris@0 539
Chris@0 540 def test_post_create_with_required_custom_field_and_without_custom_fields_param
Chris@0 541 field = IssueCustomField.find_by_name('Database')
Chris@0 542 field.update_attribute(:is_required, true)
Chris@0 543
Chris@0 544 @request.session[:user_id] = 2
Chris@441 545 post :create, :project_id => 1,
Chris@0 546 :issue => {:tracker_id => 1,
Chris@0 547 :subject => 'This is the test_new issue',
Chris@0 548 :description => 'This is the description',
Chris@0 549 :priority_id => 5}
Chris@0 550 assert_response :success
Chris@0 551 assert_template 'new'
Chris@0 552 issue = assigns(:issue)
Chris@0 553 assert_not_nil issue
Chris@0 554 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
Chris@0 555 end
Chris@441 556
Chris@0 557 def test_post_create_with_watchers
Chris@0 558 @request.session[:user_id] = 2
Chris@0 559 ActionMailer::Base.deliveries.clear
Chris@441 560
Chris@0 561 assert_difference 'Watcher.count', 2 do
Chris@441 562 post :create, :project_id => 1,
Chris@0 563 :issue => {:tracker_id => 1,
Chris@0 564 :subject => 'This is a new issue with watchers',
Chris@0 565 :description => 'This is the description',
Chris@0 566 :priority_id => 5,
Chris@0 567 :watcher_user_ids => ['2', '3']}
Chris@0 568 end
Chris@0 569 issue = Issue.find_by_subject('This is a new issue with watchers')
Chris@0 570 assert_not_nil issue
Chris@0 571 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
Chris@441 572
Chris@0 573 # Watchers added
Chris@0 574 assert_equal [2, 3], issue.watcher_user_ids.sort
Chris@0 575 assert issue.watched_by?(User.find(3))
Chris@0 576 # Watchers notified
Chris@0 577 mail = ActionMailer::Base.deliveries.last
Chris@0 578 assert_kind_of TMail::Mail, mail
Chris@0 579 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
Chris@0 580 end
Chris@441 581
Chris@0 582 def test_post_create_subissue
Chris@0 583 @request.session[:user_id] = 2
Chris@441 584
Chris@0 585 assert_difference 'Issue.count' do
Chris@441 586 post :create, :project_id => 1,
Chris@0 587 :issue => {:tracker_id => 1,
Chris@0 588 :subject => 'This is a child issue',
Chris@0 589 :parent_issue_id => 2}
Chris@0 590 end
Chris@0 591 issue = Issue.find_by_subject('This is a child issue')
Chris@0 592 assert_not_nil issue
Chris@0 593 assert_equal Issue.find(2), issue.parent
Chris@0 594 end
Chris@119 595
Chris@119 596 def test_post_create_subissue_with_non_numeric_parent_id
Chris@119 597 @request.session[:user_id] = 2
Chris@441 598
Chris@119 599 assert_difference 'Issue.count' do
Chris@441 600 post :create, :project_id => 1,
Chris@119 601 :issue => {:tracker_id => 1,
Chris@119 602 :subject => 'This is a child issue',
Chris@119 603 :parent_issue_id => 'ABC'}
Chris@119 604 end
Chris@119 605 issue = Issue.find_by_subject('This is a child issue')
Chris@119 606 assert_not_nil issue
Chris@119 607 assert_nil issue.parent
Chris@119 608 end
Chris@441 609
Chris@0 610 def test_post_create_should_send_a_notification
Chris@0 611 ActionMailer::Base.deliveries.clear
Chris@0 612 @request.session[:user_id] = 2
Chris@0 613 assert_difference 'Issue.count' do
Chris@441 614 post :create, :project_id => 1,
Chris@0 615 :issue => {:tracker_id => 3,
Chris@0 616 :subject => 'This is the test_new issue',
Chris@0 617 :description => 'This is the description',
Chris@0 618 :priority_id => 5,
Chris@0 619 :estimated_hours => '',
Chris@0 620 :custom_field_values => {'2' => 'Value for field 2'}}
Chris@0 621 end
Chris@0 622 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
Chris@441 623
Chris@0 624 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 625 end
Chris@441 626
Chris@0 627 def test_post_create_should_preserve_fields_values_on_validation_failure
Chris@0 628 @request.session[:user_id] = 2
Chris@441 629 post :create, :project_id => 1,
Chris@0 630 :issue => {:tracker_id => 1,
Chris@0 631 # empty subject
Chris@0 632 :subject => '',
Chris@0 633 :description => 'This is a description',
Chris@0 634 :priority_id => 6,
Chris@0 635 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
Chris@0 636 assert_response :success
Chris@0 637 assert_template 'new'
Chris@441 638
Chris@0 639 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
Chris@0 640 :content => 'This is a description'
Chris@0 641 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
Chris@0 642 :child => { :tag => 'option', :attributes => { :selected => 'selected',
Chris@0 643 :value => '6' },
Chris@441 644 :content => 'High' }
Chris@0 645 # Custom fields
Chris@0 646 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
Chris@0 647 :child => { :tag => 'option', :attributes => { :selected => 'selected',
Chris@0 648 :value => 'Oracle' },
Chris@441 649 :content => 'Oracle' }
Chris@0 650 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
Chris@0 651 :value => 'Value for field 2'}
Chris@0 652 end
Chris@441 653
Chris@0 654 def test_post_create_should_ignore_non_safe_attributes
Chris@0 655 @request.session[:user_id] = 2
Chris@0 656 assert_nothing_raised do
Chris@0 657 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
Chris@0 658 end
Chris@0 659 end
Chris@441 660
Chris@0 661 context "without workflow privilege" do
Chris@0 662 setup do
Chris@0 663 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
chris@37 664 Role.anonymous.add_permission! :add_issues, :add_issue_notes
Chris@0 665 end
Chris@441 666
Chris@0 667 context "#new" do
Chris@0 668 should "propose default status only" do
Chris@0 669 get :new, :project_id => 1
Chris@0 670 assert_response :success
Chris@0 671 assert_template 'new'
Chris@0 672 assert_tag :tag => 'select',
Chris@0 673 :attributes => {:name => 'issue[status_id]'},
Chris@0 674 :children => {:count => 1},
Chris@0 675 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
Chris@0 676 end
Chris@441 677
Chris@0 678 should "accept default status" do
Chris@0 679 assert_difference 'Issue.count' do
Chris@441 680 post :create, :project_id => 1,
Chris@0 681 :issue => {:tracker_id => 1,
Chris@0 682 :subject => 'This is an issue',
Chris@0 683 :status_id => 1}
Chris@0 684 end
Chris@0 685 issue = Issue.last(:order => 'id')
Chris@0 686 assert_equal IssueStatus.default, issue.status
Chris@0 687 end
Chris@441 688
Chris@0 689 should "ignore unauthorized status" do
Chris@0 690 assert_difference 'Issue.count' do
Chris@441 691 post :create, :project_id => 1,
Chris@0 692 :issue => {:tracker_id => 1,
Chris@0 693 :subject => 'This is an issue',
Chris@0 694 :status_id => 3}
Chris@0 695 end
Chris@0 696 issue = Issue.last(:order => 'id')
Chris@0 697 assert_equal IssueStatus.default, issue.status
Chris@0 698 end
Chris@0 699 end
Chris@441 700
chris@37 701 context "#update" do
chris@37 702 should "ignore status change" do
chris@37 703 assert_difference 'Journal.count' do
chris@37 704 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
chris@37 705 end
chris@37 706 assert_equal 1, Issue.find(1).status_id
chris@37 707 end
Chris@441 708
chris@37 709 should "ignore attributes changes" do
chris@37 710 assert_difference 'Journal.count' do
chris@37 711 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
chris@37 712 end
chris@37 713 issue = Issue.find(1)
chris@37 714 assert_equal "Can't print recipes", issue.subject
chris@37 715 assert_nil issue.assigned_to
chris@37 716 end
chris@37 717 end
chris@37 718 end
Chris@441 719
chris@37 720 context "with workflow privilege" do
chris@37 721 setup do
chris@37 722 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
chris@37 723 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
chris@37 724 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
chris@37 725 Role.anonymous.add_permission! :add_issues, :add_issue_notes
chris@37 726 end
Chris@441 727
chris@37 728 context "#update" do
chris@37 729 should "accept authorized status" do
chris@37 730 assert_difference 'Journal.count' do
chris@37 731 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
chris@37 732 end
chris@37 733 assert_equal 3, Issue.find(1).status_id
chris@37 734 end
Chris@441 735
chris@37 736 should "ignore unauthorized status" do
chris@37 737 assert_difference 'Journal.count' do
chris@37 738 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
chris@37 739 end
chris@37 740 assert_equal 1, Issue.find(1).status_id
chris@37 741 end
Chris@441 742
chris@37 743 should "accept authorized attributes changes" do
chris@37 744 assert_difference 'Journal.count' do
chris@37 745 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
chris@37 746 end
chris@37 747 issue = Issue.find(1)
chris@37 748 assert_equal 2, issue.assigned_to_id
chris@37 749 end
Chris@441 750
chris@37 751 should "ignore unauthorized attributes changes" do
chris@37 752 assert_difference 'Journal.count' do
chris@37 753 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
chris@37 754 end
chris@37 755 issue = Issue.find(1)
chris@37 756 assert_equal "Can't print recipes", issue.subject
chris@37 757 end
chris@37 758 end
Chris@441 759
chris@37 760 context "and :edit_issues permission" do
chris@37 761 setup do
chris@37 762 Role.anonymous.add_permission! :add_issues, :edit_issues
chris@37 763 end
chris@37 764
chris@37 765 should "accept authorized status" do
chris@37 766 assert_difference 'Journal.count' do
chris@37 767 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
chris@37 768 end
chris@37 769 assert_equal 3, Issue.find(1).status_id
chris@37 770 end
Chris@441 771
chris@37 772 should "ignore unauthorized status" do
chris@37 773 assert_difference 'Journal.count' do
chris@37 774 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
chris@37 775 end
chris@37 776 assert_equal 1, Issue.find(1).status_id
chris@37 777 end
Chris@441 778
chris@37 779 should "accept authorized attributes changes" do
chris@37 780 assert_difference 'Journal.count' do
chris@37 781 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
chris@37 782 end
chris@37 783 issue = Issue.find(1)
chris@37 784 assert_equal "changed", issue.subject
chris@37 785 assert_equal 2, issue.assigned_to_id
chris@37 786 end
chris@37 787 end
Chris@0 788 end
Chris@441 789
Chris@0 790 def test_copy_issue
Chris@0 791 @request.session[:user_id] = 2
Chris@0 792 get :new, :project_id => 1, :copy_from => 1
Chris@0 793 assert_template 'new'
Chris@0 794 assert_not_nil assigns(:issue)
Chris@0 795 orig = Issue.find(1)
Chris@0 796 assert_equal orig.subject, assigns(:issue).subject
Chris@0 797 end
Chris@441 798
Chris@0 799 def test_get_edit
Chris@0 800 @request.session[:user_id] = 2
Chris@0 801 get :edit, :id => 1
Chris@0 802 assert_response :success
Chris@0 803 assert_template 'edit'
Chris@0 804 assert_not_nil assigns(:issue)
Chris@0 805 assert_equal Issue.find(1), assigns(:issue)
Chris@0 806 end
Chris@441 807
Chris@0 808 def test_get_edit_with_params
Chris@0 809 @request.session[:user_id] = 2
chris@37 810 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
chris@37 811 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
Chris@0 812 assert_response :success
Chris@0 813 assert_template 'edit'
Chris@441 814
Chris@0 815 issue = assigns(:issue)
Chris@0 816 assert_not_nil issue
Chris@441 817
Chris@0 818 assert_equal 5, issue.status_id
Chris@0 819 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
Chris@441 820 :child => { :tag => 'option',
Chris@0 821 :content => 'Closed',
Chris@0 822 :attributes => { :selected => 'selected' } }
Chris@441 823
Chris@0 824 assert_equal 7, issue.priority_id
Chris@0 825 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
Chris@441 826 :child => { :tag => 'option',
Chris@0 827 :content => 'Urgent',
Chris@0 828 :attributes => { :selected => 'selected' } }
chris@37 829
chris@37 830 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
chris@37 831 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
chris@37 832 :child => { :tag => 'option',
chris@37 833 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
chris@37 834 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
Chris@0 835 end
Chris@0 836
Chris@0 837 def test_update_edit_form
Chris@0 838 @request.session[:user_id] = 2
Chris@14 839 xhr :post, :new, :project_id => 1,
Chris@0 840 :id => 1,
Chris@441 841 :issue => {:tracker_id => 2,
Chris@0 842 :subject => 'This is the test_new issue',
Chris@0 843 :description => 'This is the description',
Chris@0 844 :priority_id => 5}
Chris@0 845 assert_response :success
Chris@0 846 assert_template 'attributes'
Chris@441 847
Chris@0 848 issue = assigns(:issue)
Chris@0 849 assert_kind_of Issue, issue
Chris@0 850 assert_equal 1, issue.id
Chris@0 851 assert_equal 1, issue.project_id
Chris@0 852 assert_equal 2, issue.tracker_id
Chris@0 853 assert_equal 'This is the test_new issue', issue.subject
Chris@0 854 end
Chris@441 855
Chris@0 856 def test_update_using_invalid_http_verbs
Chris@0 857 @request.session[:user_id] = 2
Chris@0 858 subject = 'Updated by an invalid http verb'
Chris@0 859
Chris@0 860 get :update, :id => 1, :issue => {:subject => subject}
Chris@0 861 assert_not_equal subject, Issue.find(1).subject
Chris@0 862
Chris@0 863 post :update, :id => 1, :issue => {:subject => subject}
Chris@0 864 assert_not_equal subject, Issue.find(1).subject
Chris@0 865
Chris@0 866 delete :update, :id => 1, :issue => {:subject => subject}
Chris@0 867 assert_not_equal subject, Issue.find(1).subject
Chris@0 868 end
Chris@0 869
Chris@0 870 def test_put_update_without_custom_fields_param
Chris@0 871 @request.session[:user_id] = 2
Chris@0 872 ActionMailer::Base.deliveries.clear
Chris@441 873
Chris@0 874 issue = Issue.find(1)
Chris@0 875 assert_equal '125', issue.custom_value_for(2).value
Chris@0 876 old_subject = issue.subject
Chris@0 877 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
Chris@441 878
Chris@0 879 assert_difference('Journal.count') do
Chris@0 880 assert_difference('JournalDetail.count', 2) do
Chris@0 881 put :update, :id => 1, :issue => {:subject => new_subject,
Chris@0 882 :priority_id => '6',
Chris@0 883 :category_id => '1' # no change
Chris@0 884 }
Chris@0 885 end
Chris@0 886 end
Chris@0 887 assert_redirected_to :action => 'show', :id => '1'
Chris@0 888 issue.reload
Chris@0 889 assert_equal new_subject, issue.subject
Chris@0 890 # Make sure custom fields were not cleared
Chris@0 891 assert_equal '125', issue.custom_value_for(2).value
Chris@441 892
Chris@0 893 mail = ActionMailer::Base.deliveries.last
Chris@0 894 assert_kind_of TMail::Mail, mail
Chris@0 895 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
Chris@0 896 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
Chris@0 897 end
Chris@441 898
Chris@0 899 def test_put_update_with_custom_field_change
Chris@0 900 @request.session[:user_id] = 2
Chris@0 901 issue = Issue.find(1)
Chris@0 902 assert_equal '125', issue.custom_value_for(2).value
Chris@441 903
Chris@0 904 assert_difference('Journal.count') do
Chris@0 905 assert_difference('JournalDetail.count', 3) do
Chris@0 906 put :update, :id => 1, :issue => {:subject => 'Custom field change',
Chris@0 907 :priority_id => '6',
Chris@0 908 :category_id => '1', # no change
Chris@0 909 :custom_field_values => { '2' => 'New custom value' }
Chris@0 910 }
Chris@0 911 end
Chris@0 912 end
Chris@0 913 assert_redirected_to :action => 'show', :id => '1'
Chris@0 914 issue.reload
Chris@0 915 assert_equal 'New custom value', issue.custom_value_for(2).value
Chris@441 916
Chris@0 917 mail = ActionMailer::Base.deliveries.last
Chris@0 918 assert_kind_of TMail::Mail, mail
Chris@0 919 assert mail.body.include?("Searchable field changed from 125 to New custom value")
Chris@0 920 end
Chris@441 921
Chris@0 922 def test_put_update_with_status_and_assignee_change
Chris@0 923 issue = Issue.find(1)
Chris@0 924 assert_equal 1, issue.status_id
Chris@0 925 @request.session[:user_id] = 2
Chris@0 926 assert_difference('TimeEntry.count', 0) do
Chris@0 927 put :update,
Chris@0 928 :id => 1,
Chris@0 929 :issue => { :status_id => 2, :assigned_to_id => 3 },
Chris@0 930 :notes => 'Assigned to dlopper',
Chris@0 931 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
Chris@0 932 end
Chris@0 933 assert_redirected_to :action => 'show', :id => '1'
Chris@0 934 issue.reload
Chris@0 935 assert_equal 2, issue.status_id
Chris@0 936 j = Journal.find(:first, :order => 'id DESC')
Chris@0 937 assert_equal 'Assigned to dlopper', j.notes
Chris@0 938 assert_equal 2, j.details.size
Chris@441 939
Chris@0 940 mail = ActionMailer::Base.deliveries.last
Chris@0 941 assert mail.body.include?("Status changed from New to Assigned")
Chris@0 942 # subject should contain the new status
Chris@0 943 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
Chris@0 944 end
Chris@441 945
Chris@0 946 def test_put_update_with_note_only
Chris@0 947 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
Chris@0 948 # anonymous user
Chris@0 949 put :update,
Chris@0 950 :id => 1,
Chris@0 951 :notes => notes
Chris@0 952 assert_redirected_to :action => 'show', :id => '1'
Chris@0 953 j = Journal.find(:first, :order => 'id DESC')
Chris@0 954 assert_equal notes, j.notes
Chris@0 955 assert_equal 0, j.details.size
Chris@0 956 assert_equal User.anonymous, j.user
Chris@441 957
Chris@0 958 mail = ActionMailer::Base.deliveries.last
Chris@0 959 assert mail.body.include?(notes)
Chris@0 960 end
Chris@441 961
Chris@0 962 def test_put_update_with_note_and_spent_time
Chris@0 963 @request.session[:user_id] = 2
Chris@0 964 spent_hours_before = Issue.find(1).spent_hours
Chris@0 965 assert_difference('TimeEntry.count') do
Chris@0 966 put :update,
Chris@0 967 :id => 1,
Chris@0 968 :notes => '2.5 hours added',
Chris@0 969 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
Chris@0 970 end
Chris@0 971 assert_redirected_to :action => 'show', :id => '1'
Chris@441 972
Chris@0 973 issue = Issue.find(1)
Chris@441 974
Chris@0 975 j = Journal.find(:first, :order => 'id DESC')
Chris@0 976 assert_equal '2.5 hours added', j.notes
Chris@0 977 assert_equal 0, j.details.size
Chris@441 978
Chris@0 979 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
Chris@0 980 assert_not_nil t
Chris@0 981 assert_equal 2.5, t.hours
Chris@0 982 assert_equal spent_hours_before + 2.5, issue.spent_hours
Chris@0 983 end
Chris@441 984
Chris@0 985 def test_put_update_with_attachment_only
Chris@0 986 set_tmp_attachments_directory
Chris@441 987
Chris@0 988 # Delete all fixtured journals, a race condition can occur causing the wrong
Chris@0 989 # journal to get fetched in the next find.
Chris@0 990 Journal.delete_all
Chris@0 991
Chris@0 992 # anonymous user
Chris@0 993 put :update,
Chris@0 994 :id => 1,
Chris@0 995 :notes => '',
Chris@0 996 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
Chris@0 997 assert_redirected_to :action => 'show', :id => '1'
Chris@0 998 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
Chris@0 999 assert j.notes.blank?
Chris@0 1000 assert_equal 1, j.details.size
Chris@0 1001 assert_equal 'testfile.txt', j.details.first.value
Chris@0 1002 assert_equal User.anonymous, j.user
Chris@441 1003
Chris@0 1004 mail = ActionMailer::Base.deliveries.last
Chris@0 1005 assert mail.body.include?('testfile.txt')
Chris@0 1006 end
Chris@0 1007
Chris@0 1008 def test_put_update_with_attachment_that_fails_to_save
Chris@0 1009 set_tmp_attachments_directory
Chris@441 1010
Chris@0 1011 # Delete all fixtured journals, a race condition can occur causing the wrong
Chris@0 1012 # journal to get fetched in the next find.
Chris@0 1013 Journal.delete_all
Chris@0 1014
Chris@0 1015 # Mock out the unsaved attachment
Chris@0 1016 Attachment.any_instance.stubs(:create).returns(Attachment.new)
Chris@441 1017
Chris@0 1018 # anonymous user
Chris@0 1019 put :update,
Chris@0 1020 :id => 1,
Chris@0 1021 :notes => '',
Chris@0 1022 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
Chris@0 1023 assert_redirected_to :action => 'show', :id => '1'
Chris@0 1024 assert_equal '1 file(s) could not be saved.', flash[:warning]
Chris@0 1025
Chris@0 1026 end if Object.const_defined?(:Mocha)
Chris@0 1027
Chris@0 1028 def test_put_update_with_no_change
Chris@0 1029 issue = Issue.find(1)
Chris@0 1030 issue.journals.clear
Chris@0 1031 ActionMailer::Base.deliveries.clear
Chris@441 1032
Chris@0 1033 put :update,
Chris@0 1034 :id => 1,
Chris@0 1035 :notes => ''
Chris@0 1036 assert_redirected_to :action => 'show', :id => '1'
Chris@441 1037
Chris@0 1038 issue.reload
Chris@0 1039 assert issue.journals.empty?
Chris@0 1040 # No email should be sent
Chris@0 1041 assert ActionMailer::Base.deliveries.empty?
Chris@0 1042 end
Chris@0 1043
Chris@0 1044 def test_put_update_should_send_a_notification
Chris@0 1045 @request.session[:user_id] = 2
Chris@0 1046 ActionMailer::Base.deliveries.clear
Chris@0 1047 issue = Issue.find(1)
Chris@0 1048 old_subject = issue.subject
Chris@0 1049 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
Chris@441 1050
Chris@0 1051 put :update, :id => 1, :issue => {:subject => new_subject,
Chris@0 1052 :priority_id => '6',
Chris@0 1053 :category_id => '1' # no change
Chris@0 1054 }
Chris@0 1055 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 1056 end
Chris@441 1057
Chris@441 1058 def test_put_update_with_invalid_spent_time_hours_only
Chris@0 1059 @request.session[:user_id] = 2
Chris@0 1060 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
Chris@441 1061
Chris@0 1062 assert_no_difference('Journal.count') do
Chris@0 1063 put :update,
Chris@0 1064 :id => 1,
Chris@0 1065 :notes => notes,
Chris@0 1066 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
Chris@0 1067 end
Chris@0 1068 assert_response :success
Chris@0 1069 assert_template 'edit'
Chris@441 1070
Chris@441 1071 assert_error_tag :descendant => {:content => /Activity can't be blank/}
Chris@441 1072 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
Chris@0 1073 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
Chris@0 1074 end
Chris@441 1075
Chris@441 1076 def test_put_update_with_invalid_spent_time_comments_only
Chris@441 1077 @request.session[:user_id] = 2
Chris@441 1078 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
Chris@441 1079
Chris@441 1080 assert_no_difference('Journal.count') do
Chris@441 1081 put :update,
Chris@441 1082 :id => 1,
Chris@441 1083 :notes => notes,
Chris@441 1084 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
Chris@441 1085 end
Chris@441 1086 assert_response :success
Chris@441 1087 assert_template 'edit'
Chris@441 1088
Chris@441 1089 assert_error_tag :descendant => {:content => /Activity can't be blank/}
Chris@441 1090 assert_error_tag :descendant => {:content => /Hours can't be blank/}
Chris@441 1091 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
Chris@441 1092 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
Chris@441 1093 end
Chris@441 1094
Chris@0 1095 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
Chris@0 1096 issue = Issue.find(2)
Chris@0 1097 @request.session[:user_id] = 2
Chris@0 1098
Chris@0 1099 put :update,
Chris@0 1100 :id => issue.id,
Chris@0 1101 :issue => {
Chris@0 1102 :fixed_version_id => 4
Chris@0 1103 }
Chris@0 1104
Chris@0 1105 assert_response :redirect
Chris@0 1106 issue.reload
Chris@0 1107 assert_equal 4, issue.fixed_version_id
Chris@0 1108 assert_not_equal issue.project_id, issue.fixed_version.project_id
Chris@0 1109 end
Chris@0 1110
Chris@0 1111 def test_put_update_should_redirect_back_using_the_back_url_parameter
Chris@0 1112 issue = Issue.find(2)
Chris@0 1113 @request.session[:user_id] = 2
Chris@0 1114
Chris@0 1115 put :update,
Chris@0 1116 :id => issue.id,
Chris@0 1117 :issue => {
Chris@0 1118 :fixed_version_id => 4
Chris@0 1119 },
Chris@0 1120 :back_url => '/issues'
Chris@0 1121
Chris@0 1122 assert_response :redirect
Chris@0 1123 assert_redirected_to '/issues'
Chris@0 1124 end
Chris@441 1125
Chris@0 1126 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
Chris@0 1127 issue = Issue.find(2)
Chris@0 1128 @request.session[:user_id] = 2
Chris@0 1129
Chris@0 1130 put :update,
Chris@0 1131 :id => issue.id,
Chris@0 1132 :issue => {
Chris@0 1133 :fixed_version_id => 4
Chris@0 1134 },
Chris@0 1135 :back_url => 'http://google.com'
Chris@0 1136
Chris@0 1137 assert_response :redirect
Chris@0 1138 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
Chris@0 1139 end
Chris@441 1140
Chris@0 1141 def test_get_bulk_edit
Chris@0 1142 @request.session[:user_id] = 2
Chris@0 1143 get :bulk_edit, :ids => [1, 2]
Chris@0 1144 assert_response :success
Chris@0 1145 assert_template 'bulk_edit'
Chris@441 1146
Chris@441 1147 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
Chris@441 1148
Chris@0 1149 # Project specific custom field, date type
Chris@0 1150 field = CustomField.find(9)
Chris@0 1151 assert !field.is_for_all?
Chris@0 1152 assert_equal 'date', field.field_format
Chris@0 1153 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
Chris@441 1154
Chris@0 1155 # System wide custom field
Chris@0 1156 assert CustomField.find(1).is_for_all?
Chris@0 1157 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
Chris@0 1158 end
Chris@0 1159
chris@37 1160 def test_get_bulk_edit_on_different_projects
chris@37 1161 @request.session[:user_id] = 2
chris@37 1162 get :bulk_edit, :ids => [1, 2, 6]
chris@37 1163 assert_response :success
chris@37 1164 assert_template 'bulk_edit'
Chris@441 1165
Chris@441 1166 # Can not set issues from different projects as children of an issue
Chris@441 1167 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
Chris@441 1168
chris@37 1169 # Project specific custom field, date type
chris@37 1170 field = CustomField.find(9)
chris@37 1171 assert !field.is_for_all?
chris@37 1172 assert !field.project_ids.include?(Issue.find(6).project_id)
chris@37 1173 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
chris@37 1174 end
chris@37 1175
Chris@441 1176 def test_get_bulk_edit_with_user_custom_field
Chris@441 1177 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
Chris@441 1178
Chris@441 1179 @request.session[:user_id] = 2
Chris@441 1180 get :bulk_edit, :ids => [1, 2]
Chris@441 1181 assert_response :success
Chris@441 1182 assert_template 'bulk_edit'
Chris@441 1183
Chris@441 1184 assert_tag :select,
Chris@441 1185 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
Chris@441 1186 :children => {
Chris@441 1187 :only => {:tag => 'option'},
Chris@441 1188 :count => Project.find(1).users.count + 1
Chris@441 1189 }
Chris@441 1190 end
Chris@441 1191
Chris@441 1192 def test_get_bulk_edit_with_version_custom_field
Chris@441 1193 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
Chris@441 1194
Chris@441 1195 @request.session[:user_id] = 2
Chris@441 1196 get :bulk_edit, :ids => [1, 2]
Chris@441 1197 assert_response :success
Chris@441 1198 assert_template 'bulk_edit'
Chris@441 1199
Chris@441 1200 assert_tag :select,
Chris@441 1201 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
Chris@441 1202 :children => {
Chris@441 1203 :only => {:tag => 'option'},
Chris@441 1204 :count => Project.find(1).versions.count + 1
Chris@441 1205 }
Chris@441 1206 end
Chris@441 1207
Chris@14 1208 def test_bulk_update
Chris@0 1209 @request.session[:user_id] = 2
Chris@0 1210 # update issues priority
Chris@14 1211 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
Chris@0 1212 :issue => {:priority_id => 7,
Chris@0 1213 :assigned_to_id => '',
Chris@0 1214 :custom_field_values => {'2' => ''}}
Chris@441 1215
Chris@0 1216 assert_response 302
Chris@0 1217 # check that the issues were updated
Chris@0 1218 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
Chris@441 1219
Chris@0 1220 issue = Issue.find(1)
Chris@0 1221 journal = issue.journals.find(:first, :order => 'created_on DESC')
Chris@0 1222 assert_equal '125', issue.custom_value_for(2).value
Chris@0 1223 assert_equal 'Bulk editing', journal.notes
Chris@0 1224 assert_equal 1, journal.details.size
Chris@0 1225 end
Chris@0 1226
chris@37 1227 def test_bulk_update_on_different_projects
chris@37 1228 @request.session[:user_id] = 2
chris@37 1229 # update issues priority
chris@37 1230 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
chris@37 1231 :issue => {:priority_id => 7,
chris@37 1232 :assigned_to_id => '',
chris@37 1233 :custom_field_values => {'2' => ''}}
Chris@441 1234
chris@37 1235 assert_response 302
chris@37 1236 # check that the issues were updated
chris@37 1237 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
Chris@441 1238
chris@37 1239 issue = Issue.find(1)
chris@37 1240 journal = issue.journals.find(:first, :order => 'created_on DESC')
chris@37 1241 assert_equal '125', issue.custom_value_for(2).value
chris@37 1242 assert_equal 'Bulk editing', journal.notes
chris@37 1243 assert_equal 1, journal.details.size
chris@37 1244 end
chris@37 1245
chris@37 1246 def test_bulk_update_on_different_projects_without_rights
chris@37 1247 @request.session[:user_id] = 3
chris@37 1248 user = User.find(3)
chris@37 1249 action = { :controller => "issues", :action => "bulk_update" }
chris@37 1250 assert user.allowed_to?(action, Issue.find(1).project)
chris@37 1251 assert ! user.allowed_to?(action, Issue.find(6).project)
chris@37 1252 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
chris@37 1253 :issue => {:priority_id => 7,
chris@37 1254 :assigned_to_id => '',
chris@37 1255 :custom_field_values => {'2' => ''}}
chris@37 1256 assert_response 403
chris@37 1257 assert_not_equal "Bulk should fail", Journal.last.notes
chris@37 1258 end
Chris@441 1259
Chris@14 1260 def test_bullk_update_should_send_a_notification
Chris@0 1261 @request.session[:user_id] = 2
Chris@0 1262 ActionMailer::Base.deliveries.clear
Chris@14 1263 post(:bulk_update,
Chris@0 1264 {
Chris@0 1265 :ids => [1, 2],
Chris@0 1266 :notes => 'Bulk editing',
Chris@0 1267 :issue => {
Chris@0 1268 :priority_id => 7,
Chris@0 1269 :assigned_to_id => '',
Chris@0 1270 :custom_field_values => {'2' => ''}
Chris@0 1271 }
Chris@0 1272 })
Chris@0 1273
Chris@0 1274 assert_response 302
Chris@0 1275 assert_equal 2, ActionMailer::Base.deliveries.size
Chris@0 1276 end
Chris@0 1277
Chris@14 1278 def test_bulk_update_status
Chris@0 1279 @request.session[:user_id] = 2
Chris@0 1280 # update issues priority
Chris@14 1281 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
Chris@0 1282 :issue => {:priority_id => '',
Chris@0 1283 :assigned_to_id => '',
Chris@0 1284 :status_id => '5'}
Chris@441 1285
Chris@0 1286 assert_response 302
Chris@0 1287 issue = Issue.find(1)
Chris@0 1288 assert issue.closed?
Chris@0 1289 end
Chris@0 1290
Chris@441 1291 def test_bulk_update_parent_id
Chris@441 1292 @request.session[:user_id] = 2
Chris@441 1293 post :bulk_update, :ids => [1, 3],
Chris@441 1294 :notes => 'Bulk editing parent',
Chris@441 1295 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
Chris@441 1296
Chris@441 1297 assert_response 302
Chris@441 1298 parent = Issue.find(2)
Chris@441 1299 assert_equal parent.id, Issue.find(1).parent_id
Chris@441 1300 assert_equal parent.id, Issue.find(3).parent_id
Chris@441 1301 assert_equal [1, 3], parent.children.collect(&:id).sort
Chris@441 1302 end
Chris@441 1303
Chris@14 1304 def test_bulk_update_custom_field
Chris@0 1305 @request.session[:user_id] = 2
Chris@0 1306 # update issues priority
Chris@14 1307 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
Chris@0 1308 :issue => {:priority_id => '',
Chris@0 1309 :assigned_to_id => '',
Chris@0 1310 :custom_field_values => {'2' => '777'}}
Chris@441 1311
Chris@0 1312 assert_response 302
Chris@441 1313
Chris@0 1314 issue = Issue.find(1)
Chris@0 1315 journal = issue.journals.find(:first, :order => 'created_on DESC')
Chris@0 1316 assert_equal '777', issue.custom_value_for(2).value
Chris@0 1317 assert_equal 1, journal.details.size
Chris@0 1318 assert_equal '125', journal.details.first.old_value
Chris@0 1319 assert_equal '777', journal.details.first.value
Chris@0 1320 end
Chris@0 1321
Chris@14 1322 def test_bulk_update_unassign
Chris@0 1323 assert_not_nil Issue.find(2).assigned_to
Chris@0 1324 @request.session[:user_id] = 2
Chris@0 1325 # unassign issues
Chris@14 1326 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
Chris@0 1327 assert_response 302
Chris@0 1328 # check that the issues were updated
Chris@0 1329 assert_nil Issue.find(2).assigned_to
Chris@0 1330 end
Chris@441 1331
Chris@14 1332 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
Chris@0 1333 @request.session[:user_id] = 2
Chris@0 1334
Chris@14 1335 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
Chris@0 1336
Chris@0 1337 assert_response :redirect
Chris@0 1338 issues = Issue.find([1,2])
Chris@0 1339 issues.each do |issue|
Chris@0 1340 assert_equal 4, issue.fixed_version_id
Chris@0 1341 assert_not_equal issue.project_id, issue.fixed_version.project_id
Chris@0 1342 end
Chris@0 1343 end
Chris@0 1344
Chris@14 1345 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
Chris@0 1346 @request.session[:user_id] = 2
Chris@14 1347 post :bulk_update, :ids => [1,2], :back_url => '/issues'
Chris@0 1348
Chris@0 1349 assert_response :redirect
Chris@0 1350 assert_redirected_to '/issues'
Chris@0 1351 end
Chris@0 1352
Chris@14 1353 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
Chris@0 1354 @request.session[:user_id] = 2
Chris@14 1355 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
Chris@0 1356
Chris@0 1357 assert_response :redirect
Chris@0 1358 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
Chris@0 1359 end
Chris@441 1360
Chris@0 1361 def test_destroy_issue_with_no_time_entries
Chris@0 1362 assert_nil TimeEntry.find_by_issue_id(2)
Chris@0 1363 @request.session[:user_id] = 2
Chris@0 1364 post :destroy, :id => 2
Chris@0 1365 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1366 assert_nil Issue.find_by_id(2)
Chris@0 1367 end
Chris@0 1368
Chris@0 1369 def test_destroy_issues_with_time_entries
Chris@0 1370 @request.session[:user_id] = 2
Chris@0 1371 post :destroy, :ids => [1, 3]
Chris@0 1372 assert_response :success
Chris@0 1373 assert_template 'destroy'
Chris@0 1374 assert_not_nil assigns(:hours)
Chris@0 1375 assert Issue.find_by_id(1) && Issue.find_by_id(3)
Chris@0 1376 end
Chris@0 1377
Chris@0 1378 def test_destroy_issues_and_destroy_time_entries
Chris@0 1379 @request.session[:user_id] = 2
Chris@0 1380 post :destroy, :ids => [1, 3], :todo => 'destroy'
Chris@0 1381 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1382 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
Chris@0 1383 assert_nil TimeEntry.find_by_id([1, 2])
Chris@0 1384 end
Chris@0 1385
Chris@0 1386 def test_destroy_issues_and_assign_time_entries_to_project
Chris@0 1387 @request.session[:user_id] = 2
Chris@0 1388 post :destroy, :ids => [1, 3], :todo => 'nullify'
Chris@0 1389 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1390 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
Chris@0 1391 assert_nil TimeEntry.find(1).issue_id
Chris@0 1392 assert_nil TimeEntry.find(2).issue_id
Chris@0 1393 end
Chris@441 1394
Chris@0 1395 def test_destroy_issues_and_reassign_time_entries_to_another_issue
Chris@0 1396 @request.session[:user_id] = 2
Chris@0 1397 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
Chris@0 1398 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
Chris@0 1399 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
Chris@0 1400 assert_equal 2, TimeEntry.find(1).issue_id
Chris@0 1401 assert_equal 2, TimeEntry.find(2).issue_id
Chris@0 1402 end
Chris@441 1403
chris@37 1404 def test_destroy_issues_from_different_projects
chris@37 1405 @request.session[:user_id] = 2
chris@37 1406 post :destroy, :ids => [1, 2, 6], :todo => 'destroy'
chris@37 1407 assert_redirected_to :controller => 'issues', :action => 'index'
chris@37 1408 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
chris@37 1409 end
Chris@441 1410
Chris@441 1411 def test_destroy_parent_and_child_issues
Chris@441 1412 parent = Issue.generate!(:project_id => 1, :tracker_id => 1)
Chris@441 1413 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id)
Chris@441 1414 assert child.is_descendant_of?(parent.reload)
Chris@441 1415
Chris@441 1416 @request.session[:user_id] = 2
Chris@441 1417 assert_difference 'Issue.count', -2 do
Chris@441 1418 post :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
Chris@441 1419 end
Chris@441 1420 assert_response 302
Chris@441 1421 end
Chris@441 1422
Chris@0 1423 def test_default_search_scope
Chris@0 1424 get :index
Chris@0 1425 assert_tag :div, :attributes => {:id => 'quick-search'},
Chris@0 1426 :child => {:tag => 'form',
Chris@0 1427 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
Chris@0 1428 end
Chris@0 1429 end