issues_controller_test.rb 52.4 KB
Newer Older
1
# Redmine - project management software
2
# Copyright (C) 2006-2011  Jean-Philippe Lang
3 4 5 6 7
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
8
#
9 10 11 12
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
13
#
14 15 16 17
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

18
require File.expand_path('../../test_helper', __FILE__)
19 20 21 22 23
require 'issues_controller'

# Re-raise errors caught by the controller.
class IssuesController; def rescue_action(e) raise e end; end

edavis10's avatar
edavis10 committed
24
class IssuesControllerTest < ActionController::TestCase
25 26 27 28
  fixtures :projects,
           :users,
           :roles,
           :members,
29
           :member_roles,
30 31
           :issues,
           :issue_statuses,
32
           :versions,
33
           :trackers,
34
           :projects_trackers,
35 36 37
           :issue_categories,
           :enabled_modules,
           :enumerations,
38
           :attachments,
39 40 41
           :workflows,
           :custom_fields,
           :custom_values,
jplang's avatar
jplang committed
42
           :custom_fields_projects,
43
           :custom_fields_trackers,
44 45
           :time_entries,
           :journals,
edavis10's avatar
edavis10 committed
46 47
           :journal_details,
           :queries
48

49 50 51 52 53 54
  def setup
    @controller = IssuesController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
    User.current = nil
  end
55

56
  def test_index
57
    Setting.default_language = 'en'
58

59 60 61 62 63
    get :index
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
    assert_nil assigns(:project)
64 65 66 67 68
    assert_tag :tag => 'a', :content => /Can't print recipes/
    assert_tag :tag => 'a', :content => /Subproject issue/
    # private projects hidden
    assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
    assert_no_tag :tag => 'a', :content => /Issue on project 2/
69 70
    # project column
    assert_tag :tag => 'th', :content => /Project/
71
  end
72

73 74 75 76 77 78 79 80 81 82
  def test_index_should_not_list_issues_when_module_disabled
    EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
    get :index
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
    assert_nil assigns(:project)
    assert_no_tag :tag => 'a', :content => /Can't print recipes/
    assert_tag :tag => 'a', :content => /Subproject issue/
  end
83

84 85 86 87 88 89 90 91 92 93
  def test_index_should_not_list_issues_when_module_disabled
    EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
    get :index
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
    assert_nil assigns(:project)
    assert_no_tag :tag => 'a', :content => /Can't print recipes/
    assert_tag :tag => 'a', :content => /Subproject issue/
  end
jplang's avatar
jplang committed
94 95 96 97 98 99 100

  def test_index_should_list_visible_issues_only
    get :index, :per_page => 100
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_nil assigns(:issues).detect {|issue| !issue.visible?}
  end
101

102
  def test_index_with_project
103
    Setting.display_subprojects_issues = 0
104 105 106 107
    get :index, :project_id => 1
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
108 109 110
    assert_tag :tag => 'a', :content => /Can't print recipes/
    assert_no_tag :tag => 'a', :content => /Subproject issue/
  end
111

112 113 114 115 116 117 118 119 120 121
  def test_index_with_project_and_subprojects
    Setting.display_subprojects_issues = 1
    get :index, :project_id => 1
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
    assert_tag :tag => 'a', :content => /Can't print recipes/
    assert_tag :tag => 'a', :content => /Subproject issue/
    assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
  end
122

123 124 125 126 127 128 129 130 131 132
  def test_index_with_project_and_subprojects_should_show_private_subprojects
    @request.session[:user_id] = 2
    Setting.display_subprojects_issues = 1
    get :index, :project_id => 1
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
    assert_tag :tag => 'a', :content => /Can't print recipes/
    assert_tag :tag => 'a', :content => /Subproject issue/
    assert_tag :tag => 'a', :content => /Issue of a private subproject/
133
  end
134

135
  def test_index_with_project_and_default_filter
136 137 138 139
    get :index, :project_id => 1, :set_filter => 1
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
140

141 142 143 144 145
    query = assigns(:query)
    assert_not_nil query
    # default filter
    assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
  end
146

147
  def test_index_with_project_and_filter
148
    get :index, :project_id => 1, :set_filter => 1,
jplang's avatar
jplang committed
149 150
      :f => ['tracker_id'],
      :op => {'tracker_id' => '='},
151
      :v => {'tracker_id' => ['1']}
152 153 154
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
155

156 157 158 159
    query = assigns(:query)
    assert_not_nil query
    assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
  end
160

161 162 163 164 165
  def test_index_with_project_and_empty_filters
    get :index, :project_id => 1, :set_filter => 1, :fields => ['']
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
166

167 168 169 170
    query = assigns(:query)
    assert_not_nil query
    # no filter
    assert_equal({}, query.filters)
171
  end
172

jplang's avatar
jplang committed
173 174 175 176 177 178 179
  def test_index_with_query
    get :index, :project_id => 1, :query_id => 5
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
    assert_nil assigns(:issue_count_by_group)
  end
180

181
  def test_index_with_query_grouped_by_tracker
jplang's avatar
jplang committed
182 183 184 185
    get :index, :project_id => 1, :query_id => 6
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
186
    assert_not_nil assigns(:issue_count_by_group)
187
  end
188

189 190 191 192 193
  def test_index_with_query_grouped_by_list_custom_field
    get :index, :project_id => 1, :query_id => 9
    assert_response :success
    assert_template 'index.rhtml'
    assert_not_nil assigns(:issues)
194
    assert_not_nil assigns(:issue_count_by_group)
jplang's avatar
jplang committed
195
  end
196

jplang's avatar
jplang committed
197 198 199 200
  def test_index_sort_by_field_not_included_in_columns
    Setting.issue_list_default_columns = %w(subject author)
    get :index, :sort => 'tracker'
  end
201

202
  def test_index_csv_with_project
203
    Setting.default_language = 'en'
204

205 206 207 208
    get :index, :format => 'csv'
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_equal 'text/csv', @response.content_type
209
    assert @response.body.starts_with?("#,")
210 211 212 213 214 215

    get :index, :project_id => 1, :format => 'csv'
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_equal 'text/csv', @response.content_type
  end
216

217 218 219 220 221
  def test_index_pdf
    get :index, :format => 'pdf'
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_equal 'application/pdf', @response.content_type
222

223 224 225 226
    get :index, :project_id => 1, :format => 'pdf'
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_equal 'application/pdf', @response.content_type
227

jplang's avatar
jplang committed
228 229 230 231
    get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_equal 'application/pdf', @response.content_type
232
  end
233

234 235 236 237 238 239 240
  def test_index_pdf_with_query_grouped_by_list_custom_field
    get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
    assert_response :success
    assert_not_nil assigns(:issues)
    assert_not_nil assigns(:issue_count_by_group)
    assert_equal 'application/pdf', @response.content_type
  end
241

242
  def test_index_sort
jplang's avatar
jplang committed
243
    get :index, :sort => 'tracker,id:desc'
244
    assert_response :success
245

jplang's avatar
jplang committed
246 247 248
    sort_params = @request.session['issues_index_sort']
    assert sort_params.is_a?(String)
    assert_equal 'tracker,id:desc', sort_params
249

jplang's avatar
jplang committed
250 251 252 253
    issues = assigns(:issues)
    assert_not_nil issues
    assert !issues.empty?
    assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
254
  end
255

256 257
  def test_index_with_columns
    columns = ['tracker', 'subject', 'assigned_to']
258
    get :index, :set_filter => 1, :c => columns
259
    assert_response :success
260

261 262 263 264
    # query should use specified columns
    query = assigns(:query)
    assert_kind_of Query, query
    assert_equal columns, query.column_names.map(&:to_s)
265

266 267 268 269 270
    # columns should be stored in session
    assert_kind_of Hash, session[:query]
    assert_kind_of Array, session[:query][:column_names]
    assert_equal columns, session[:query][:column_names].map(&:to_s)
  end
271

272 273 274 275
  def test_index_with_custom_field_column
    columns = %w(tracker subject cf_2)
    get :index, :set_filter => 1, :c => columns
    assert_response :success
276

277 278 279 280
    # query should use specified columns
    query = assigns(:query)
    assert_kind_of Query, query
    assert_equal columns, query.column_names.map(&:to_s)
281

282 283 284 285
    assert_tag :td,
      :attributes => {:class => 'cf_2 string'},
      :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
  end
286

287
  def test_show_by_anonymous
jplang's avatar
jplang committed
288 289 290 291
    get :show, :id => 1
    assert_response :success
    assert_template 'show.rhtml'
    assert_not_nil assigns(:issue)
292
    assert_equal Issue.find(1), assigns(:issue)
293

294 295 296
    # anonymous role is allowed to add a note
    assert_tag :tag => 'form',
               :descendant => { :tag => 'fieldset',
297
                                :child => { :tag => 'legend',
298
                                            :content => /Notes/ } }
jplang's avatar
jplang committed
299
  end
300

301 302 303 304
  def test_show_by_manager
    @request.session[:user_id] = 2
    get :show, :id => 1
    assert_response :success
305

306 307
    assert_tag :tag => 'a',
      :content => /Quote/
308

309 310
    assert_tag :tag => 'form',
               :descendant => { :tag => 'fieldset',
311
                                :child => { :tag => 'legend',
312 313
                                            :content => /Change properties/ } },
               :descendant => { :tag => 'fieldset',
314
                                :child => { :tag => 'legend',
315 316
                                            :content => /Log time/ } },
               :descendant => { :tag => 'fieldset',
317
                                :child => { :tag => 'legend',
318 319
                                            :content => /Notes/ } }
  end
320

321 322 323 324 325 326 327 328 329 330
  def test_update_form_should_not_display_inactive_enumerations
    @request.session[:user_id] = 2
    get :show, :id => 1
    assert_response :success

    assert ! IssuePriority.find(15).active?
    assert_no_tag :option, :attributes => {:value => '15'},
                           :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
  end

jplang's avatar
jplang committed
331 332 333 334 335
  def test_show_should_deny_anonymous_access_without_permission
    Role.anonymous.remove_permission!(:view_issues)
    get :show, :id => 1
    assert_response :redirect
  end
336

jplang's avatar
jplang committed
337 338 339 340 341
  def test_show_should_deny_anonymous_access_to_private_issue
    Issue.update_all(["is_private = ?", true], "id = 1")
    get :show, :id => 1
    assert_response :redirect
  end
342

jplang's avatar
jplang committed
343 344 345 346 347 348
  def test_show_should_deny_non_member_access_without_permission
    Role.non_member.remove_permission!(:view_issues)
    @request.session[:user_id] = 9
    get :show, :id => 1
    assert_response 403
  end
349

jplang's avatar
jplang committed
350 351 352 353 354 355
  def test_show_should_deny_non_member_access_to_private_issue
    Issue.update_all(["is_private = ?", true], "id = 1")
    @request.session[:user_id] = 9
    get :show, :id => 1
    assert_response 403
  end
356

jplang's avatar
jplang committed
357 358 359 360 361 362
  def test_show_should_deny_member_access_without_permission
    Role.find(1).remove_permission!(:view_issues)
    @request.session[:user_id] = 2
    get :show, :id => 1
    assert_response 403
  end
363

jplang's avatar
jplang committed
364 365 366 367 368 369
  def test_show_should_deny_member_access_to_private_issue_without_permission
    Issue.update_all(["is_private = ?", true], "id = 1")
    @request.session[:user_id] = 3
    get :show, :id => 1
    assert_response 403
  end
370

jplang's avatar
jplang committed
371 372 373 374 375 376
  def test_show_should_allow_author_access_to_private_issue
    Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
    @request.session[:user_id] = 3
    get :show, :id => 1
    assert_response :success
  end
377

jplang's avatar
jplang committed
378 379 380 381 382 383
  def test_show_should_allow_assignee_access_to_private_issue
    Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
    @request.session[:user_id] = 3
    get :show, :id => 1
    assert_response :success
  end
384

jplang's avatar
jplang committed
385 386 387 388 389 390 391
  def test_show_should_allow_member_access_to_private_issue_with_permission
    Issue.update_all(["is_private = ?", true], "id = 1")
    User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
    @request.session[:user_id] = 3
    get :show, :id => 1
    assert_response :success
  end
392

393 394 395 396 397
  def test_show_should_not_disclose_relations_to_invisible_issues
    Setting.cross_project_issue_relations = '1'
    IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
    # Relation to a private project issue
    IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
398

399 400
    get :show, :id => 1
    assert_response :success
401

402 403 404 405 406
    assert_tag :div, :attributes => { :id => 'relations' },
                     :descendant => { :tag => 'a', :content => /#2$/ }
    assert_no_tag :div, :attributes => { :id => 'relations' },
                        :descendant => { :tag => 'a', :content => /#4$/ }
  end
407

408 409 410
  def test_show_atom
    get :show, :id => 2, :format => 'atom'
    assert_response :success
411
    assert_template 'journals/index.rxml'
412
    # Inline image
413
    assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
414
  end
415

jplang's avatar
jplang committed
416
  def test_show_export_to_pdf
417
    get :show, :id => 3, :format => 'pdf'
jplang's avatar
jplang committed
418 419 420 421 422 423
    assert_response :success
    assert_equal 'application/pdf', @response.content_type
    assert @response.body.starts_with?('%PDF')
    assert_not_nil assigns(:issue)
  end

424 425 426 427 428
  def test_get_new
    @request.session[:user_id] = 2
    get :new, :project_id => 1, :tracker_id => 1
    assert_response :success
    assert_template 'new'
429

430
    assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
431
                                                 :value => 'Default string' }
432 433 434 435 436

    # Be sure we don't display inactive IssuePriorities
    assert ! IssuePriority.find(15).active?
    assert_no_tag :option, :attributes => {:value => '15'},
                           :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
437 438 439 440 441 442 443
  end

  def test_get_new_without_tracker_id
    @request.session[:user_id] = 2
    get :new, :project_id => 1
    assert_response :success
    assert_template 'new'
444

445 446 447 448
    issue = assigns(:issue)
    assert_not_nil issue
    assert_equal Project.find(1).trackers.first, issue.tracker
  end
449

450 451 452
  def test_get_new_with_no_default_status_should_display_an_error
    @request.session[:user_id] = 2
    IssueStatus.delete_all
453

454 455
    get :new, :project_id => 1
    assert_response 500
456
    assert_error_tag :content => /No default issue/
457
  end
458

459 460 461
  def test_get_new_with_no_tracker_should_display_an_error
    @request.session[:user_id] = 2
    Tracker.delete_all
462

463 464
    get :new, :project_id => 1
    assert_response 500
465
    assert_error_tag :content => /No tracker/
466
  end
467

468 469
  def test_update_new_form
    @request.session[:user_id] = 2
470
    xhr :post, :new, :project_id => 1,
471
                     :issue => {:tracker_id => 2,
472 473 474 475
                                :subject => 'This is the test_new issue',
                                :description => 'This is the description',
                                :priority_id => 5}
    assert_response :success
476
    assert_template 'attributes'
477

478 479 480 481 482 483
    issue = assigns(:issue)
    assert_kind_of Issue, issue
    assert_equal 1, issue.project_id
    assert_equal 2, issue.tracker_id
    assert_equal 'This is the test_new issue', issue.subject
  end
484

485
  def test_post_create
486
    @request.session[:user_id] = 2
edavis10's avatar
edavis10 committed
487
    assert_difference 'Issue.count' do
488
      post :create, :project_id => 1,
edavis10's avatar
edavis10 committed
489
                 :issue => {:tracker_id => 3,
490
                            :status_id => 2,
edavis10's avatar
edavis10 committed
491 492 493
                            :subject => 'This is the test_new issue',
                            :description => 'This is the description',
                            :priority_id => 5,
494
                            :start_date => '2010-11-07',
edavis10's avatar
edavis10 committed
495 496 497 498
                            :estimated_hours => '',
                            :custom_field_values => {'2' => 'Value for field 2'}}
    end
    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
499

500 501 502
    issue = Issue.find_by_subject('This is the test_new issue')
    assert_not_nil issue
    assert_equal 2, issue.author_id
503
    assert_equal 3, issue.tracker_id
504
    assert_equal 2, issue.status_id
505
    assert_equal Date.parse('2010-11-07'), issue.start_date
506
    assert_nil issue.estimated_hours
507
    v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
508 509
    assert_not_nil v
    assert_equal 'Value for field 2', v.value
510
  end
511

512 513 514
  def test_post_create_without_start_date
    @request.session[:user_id] = 2
    assert_difference 'Issue.count' do
515
      post :create, :project_id => 1,
516 517 518 519 520 521 522 523 524 525
                 :issue => {:tracker_id => 3,
                            :status_id => 2,
                            :subject => 'This is the test_new issue',
                            :description => 'This is the description',
                            :priority_id => 5,
                            :start_date => '',
                            :estimated_hours => '',
                            :custom_field_values => {'2' => 'Value for field 2'}}
    end
    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
526

527 528 529 530
    issue = Issue.find_by_subject('This is the test_new issue')
    assert_not_nil issue
    assert_nil issue.start_date
  end
531

532
  def test_post_create_and_continue
533
    @request.session[:user_id] = 2
534
    post :create, :project_id => 1,
535 536 537 538
               :issue => {:tracker_id => 3,
                          :subject => 'This is first issue',
                          :priority_id => 5},
               :continue => ''
539 540
    assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook',
                         :issue => {:tracker_id => 3}
541
  end
542

543
  def test_post_create_without_custom_fields_param
544
    @request.session[:user_id] = 2
edavis10's avatar
edavis10 committed
545
    assert_difference 'Issue.count' do
546
      post :create, :project_id => 1,
edavis10's avatar
edavis10 committed
547 548 549 550 551 552
                 :issue => {:tracker_id => 1,
                            :subject => 'This is the test_new issue',
                            :description => 'This is the description',
                            :priority_id => 5}
    end
    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
553
  end
554

555
  def test_post_create_with_required_custom_field_and_without_custom_fields_param
556 557 558 559
    field = IssueCustomField.find_by_name('Database')
    field.update_attribute(:is_required, true)

    @request.session[:user_id] = 2
560
    post :create, :project_id => 1,
561 562 563 564 565 566 567 568
               :issue => {:tracker_id => 1,
                          :subject => 'This is the test_new issue',
                          :description => 'This is the description',
                          :priority_id => 5}
    assert_response :success
    assert_template 'new'
    issue = assigns(:issue)
    assert_not_nil issue
569
    assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
570
  end
571

572
  def test_post_create_with_watchers
573 574
    @request.session[:user_id] = 2
    ActionMailer::Base.deliveries.clear
575

576
    assert_difference 'Watcher.count', 2 do
577
      post :create, :project_id => 1,
578 579 580 581 582 583 584
                 :issue => {:tracker_id => 1,
                            :subject => 'This is a new issue with watchers',
                            :description => 'This is the description',
                            :priority_id => 5,
                            :watcher_user_ids => ['2', '3']}
    end
    issue = Issue.find_by_subject('This is a new issue with watchers')
jplang's avatar
jplang committed
585 586
    assert_not_nil issue
    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
587

588 589 590 591 592 593 594 595
    # Watchers added
    assert_equal [2, 3], issue.watcher_user_ids.sort
    assert issue.watched_by?(User.find(3))
    # Watchers notified
    mail = ActionMailer::Base.deliveries.last
    assert_kind_of TMail::Mail, mail
    assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
  end
596

597
  def test_post_create_subissue
jplang's avatar
jplang committed
598
    @request.session[:user_id] = 2
599

jplang's avatar
jplang committed
600
    assert_difference 'Issue.count' do
601
      post :create, :project_id => 1,
jplang's avatar
jplang committed
602 603 604 605 606 607 608 609
                 :issue => {:tracker_id => 1,
                            :subject => 'This is a child issue',
                            :parent_issue_id => 2}
    end
    issue = Issue.find_by_subject('This is a child issue')
    assert_not_nil issue
    assert_equal Issue.find(2), issue.parent
  end
610 611 612

  def test_post_create_subissue_with_non_numeric_parent_id
    @request.session[:user_id] = 2
613

614
    assert_difference 'Issue.count' do
615
      post :create, :project_id => 1,
616 617 618 619 620 621 622 623
                 :issue => {:tracker_id => 1,
                            :subject => 'This is a child issue',
                            :parent_issue_id => 'ABC'}
    end
    issue = Issue.find_by_subject('This is a child issue')
    assert_not_nil issue
    assert_nil issue.parent
  end
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
  
  def test_post_create_private
    @request.session[:user_id] = 2

    assert_difference 'Issue.count' do
      post :create, :project_id => 1,
                 :issue => {:tracker_id => 1,
                            :subject => 'This is a private issue',
                            :is_private => '1'}
    end
    issue = Issue.first(:order => 'id DESC')
    assert issue.is_private?
  end
  
  def test_post_create_private_with_set_own_issues_private_permission
    role = Role.find(1)
    role.remove_permission! :set_issues_private
    role.add_permission! :set_own_issues_private
    
    @request.session[:user_id] = 2

    assert_difference 'Issue.count' do
      post :create, :project_id => 1,
                 :issue => {:tracker_id => 1,
                            :subject => 'This is a private issue',
                            :is_private => '1'}
    end
    issue = Issue.first(:order => 'id DESC')
    assert issue.is_private?
  end
654

655
  def test_post_create_should_send_a_notification
656 657
    ActionMailer::Base.deliveries.clear
    @request.session[:user_id] = 2
edavis10's avatar
edavis10 committed
658
    assert_difference 'Issue.count' do
659
      post :create, :project_id => 1,
edavis10's avatar
edavis10 committed
660 661 662 663 664 665 666 667
                 :issue => {:tracker_id => 3,
                            :subject => 'This is the test_new issue',
                            :description => 'This is the description',
                            :priority_id => 5,
                            :estimated_hours => '',
                            :custom_field_values => {'2' => 'Value for field 2'}}
    end
    assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
668

669 670
    assert_equal 1, ActionMailer::Base.deliveries.size
  end
671

672
  def test_post_create_should_preserve_fields_values_on_validation_failure
673
    @request.session[:user_id] = 2
674
    post :create, :project_id => 1,
675
               :issue => {:tracker_id => 1,
676 677 678
                          # empty subject
                          :subject => '',
                          :description => 'This is a description',
679 680 681 682
                          :priority_id => 6,
                          :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
    assert_response :success
    assert_template 'new'
683

684 685
    assert_tag :textarea, :attributes => { :name => 'issue[description]' },
                          :content => 'This is a description'
686 687 688
    assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
                        :child => { :tag => 'option', :attributes => { :selected => 'selected',
                                                                       :value => '6' },
689
                                                      :content => 'High' }
690 691 692 693
    # Custom fields
    assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
                        :child => { :tag => 'option', :attributes => { :selected => 'selected',
                                                                       :value => 'Oracle' },
694
                                                      :content => 'Oracle' }
695 696 697
    assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
                                        :value => 'Value for field 2'}
  end
698

699
  def test_post_create_should_ignore_non_safe_attributes
700 701
    @request.session[:user_id] = 2
    assert_nothing_raised do
702
      post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
703 704
    end
  end
705

706 707 708
  context "without workflow privilege" do
    setup do
      Workflow.delete_all(["role_id = ?", Role.anonymous.id])
709
      Role.anonymous.add_permission! :add_issues, :add_issue_notes
710
    end
711

712 713 714 715 716 717 718 719 720 721
    context "#new" do
      should "propose default status only" do
        get :new, :project_id => 1
        assert_response :success
        assert_template 'new'
        assert_tag :tag => 'select',
          :attributes => {:name => 'issue[status_id]'},
          :children => {:count => 1},
          :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
      end
722

723 724
      should "accept default status" do
        assert_difference 'Issue.count' do
725
          post :create, :project_id => 1,
726 727 728 729 730 731 732
                     :issue => {:tracker_id => 1,
                                :subject => 'This is an issue',
                                :status_id => 1}
        end
        issue = Issue.last(:order => 'id')
        assert_equal IssueStatus.default, issue.status
      end
733

734 735
      should "ignore unauthorized status" do
        assert_difference 'Issue.count' do
736
          post :create, :project_id => 1,
737 738 739 740 741 742 743 744
                     :issue => {:tracker_id => 1,
                                :subject => 'This is an issue',
                                :status_id => 3}
        end
        issue = Issue.last(:order => 'id')
        assert_equal IssueStatus.default, issue.status
      end
    end
745

746 747 748 749 750 751 752
    context "#update" do
      should "ignore status change" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
        end
        assert_equal 1, Issue.find(1).status_id
      end
753

754 755 756 757 758 759 760 761 762 763
      should "ignore attributes changes" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
        end
        issue = Issue.find(1)
        assert_equal "Can't print recipes", issue.subject
        assert_nil issue.assigned_to
      end
    end
  end
764

765 766 767 768 769 770 771
  context "with workflow privilege" do
    setup do
      Workflow.delete_all(["role_id = ?", Role.anonymous.id])
      Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
      Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
      Role.anonymous.add_permission! :add_issues, :add_issue_notes
    end
772

773 774 775 776 777 778 779
    context "#update" do
      should "accept authorized status" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
        end
        assert_equal 3, Issue.find(1).status_id
      end
780

781 782 783 784 785 786
      should "ignore unauthorized status" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
        end
        assert_equal 1, Issue.find(1).status_id
      end
787

788 789 790 791 792 793 794
      should "accept authorized attributes changes" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
        end
        issue = Issue.find(1)
        assert_equal 2, issue.assigned_to_id
      end
795

796 797 798 799 800 801 802 803
      should "ignore unauthorized attributes changes" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
        end
        issue = Issue.find(1)
        assert_equal "Can't print recipes", issue.subject
      end
    end
804

805 806 807 808 809 810 811 812 813 814 815
    context "and :edit_issues permission" do
      setup do
        Role.anonymous.add_permission! :add_issues, :edit_issues
      end

      should "accept authorized status" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
        end
        assert_equal 3, Issue.find(1).status_id
      end
816

817 818 819 820 821 822
      should "ignore unauthorized status" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
        end
        assert_equal 1, Issue.find(1).status_id
      end
823

824 825 826 827 828 829 830 831 832
      should "accept authorized attributes changes" do
        assert_difference 'Journal.count' do
          put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
        end
        issue = Issue.find(1)
        assert_equal "changed", issue.subject
        assert_equal 2, issue.assigned_to_id
      end
    end
833
  end
834

835 836 837 838 839 840 841 842
  def test_copy_issue
    @request.session[:user_id] = 2
    get :new, :project_id => 1, :copy_from => 1
    assert_template 'new'
    assert_not_nil assigns(:issue)
    orig = Issue.find(1)
    assert_equal orig.subject, assigns(:issue).subject
  end
843

jplang's avatar
jplang committed
844 845 846 847 848 849 850
  def test_get_edit
    @request.session[:user_id] = 2
    get :edit, :id => 1
    assert_response :success
    assert_template 'edit'
    assert_not_nil assigns(:issue)
    assert_equal Issue.find(1), assigns(:issue)
851 852 853 854 855

    # Be sure we don't display inactive IssuePriorities
    assert ! IssuePriority.find(15).active?
    assert_no_tag :option, :attributes => {:value => '15'},
                           :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
jplang's avatar
jplang committed
856
  end
857

858 859
  def test_get_edit_with_params
    @request.session[:user_id] = 2
860 861
    get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
        :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
862 863
    assert_response :success
    assert_template 'edit'
864

865 866
    issue = assigns(:issue)
    assert_not_nil issue
867

868 869
    assert_equal 5, issue.status_id
    assert_tag :select, :attributes => { :name => 'issue[status_id]' },
870
                        :child => { :tag => 'option',
871 872
                                    :content => 'Closed',
                                    :attributes => { :selected => 'selected' } }
873

874 875
    assert_equal 7, issue.priority_id
    assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
876
                        :child => { :tag => 'option',
877 878
                                    :content => 'Urgent',
                                    :attributes => { :selected => 'selected' } }
879 880 881