To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / test / functional / issues_controller_test.rb @ 441:cbce1fd3b1b7

History | View | Annotate | Download (50.3 KB)

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