##// END OF EJS Templates
Adds a test for displaying list custom fields on the new issue form....
Jean-Philippe Lang -
r8938:7edf345fbec7
parent child
Show More
@@ -1,3107 +1,3119
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'issues_controller'
20 20
21 21 class IssuesControllerTest < ActionController::TestCase
22 22 fixtures :projects,
23 23 :users,
24 24 :roles,
25 25 :members,
26 26 :member_roles,
27 27 :issues,
28 28 :issue_statuses,
29 29 :versions,
30 30 :trackers,
31 31 :projects_trackers,
32 32 :issue_categories,
33 33 :enabled_modules,
34 34 :enumerations,
35 35 :attachments,
36 36 :workflows,
37 37 :custom_fields,
38 38 :custom_values,
39 39 :custom_fields_projects,
40 40 :custom_fields_trackers,
41 41 :time_entries,
42 42 :journals,
43 43 :journal_details,
44 44 :queries,
45 45 :repositories,
46 46 :changesets
47 47
48 48 include Redmine::I18n
49 49
50 50 def setup
51 51 @controller = IssuesController.new
52 52 @request = ActionController::TestRequest.new
53 53 @response = ActionController::TestResponse.new
54 54 User.current = nil
55 55 end
56 56
57 57 def test_index
58 58 with_settings :default_language => "en" do
59 59 get :index
60 60 assert_response :success
61 61 assert_template 'index'
62 62 assert_not_nil assigns(:issues)
63 63 assert_nil assigns(:project)
64 64 assert_tag :tag => 'a', :content => /Can't print recipes/
65 65 assert_tag :tag => 'a', :content => /Subproject issue/
66 66 # private projects hidden
67 67 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
68 68 assert_no_tag :tag => 'a', :content => /Issue on project 2/
69 69 # project column
70 70 assert_tag :tag => 'th', :content => /Project/
71 71 end
72 72 end
73 73
74 74 def test_index_should_not_list_issues_when_module_disabled
75 75 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
76 76 get :index
77 77 assert_response :success
78 78 assert_template 'index'
79 79 assert_not_nil assigns(:issues)
80 80 assert_nil assigns(:project)
81 81 assert_no_tag :tag => 'a', :content => /Can't print recipes/
82 82 assert_tag :tag => 'a', :content => /Subproject issue/
83 83 end
84 84
85 85 def test_index_should_list_visible_issues_only
86 86 get :index, :per_page => 100
87 87 assert_response :success
88 88 assert_not_nil assigns(:issues)
89 89 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
90 90 end
91 91
92 92 def test_index_with_project
93 93 Setting.display_subprojects_issues = 0
94 94 get :index, :project_id => 1
95 95 assert_response :success
96 96 assert_template 'index'
97 97 assert_not_nil assigns(:issues)
98 98 assert_tag :tag => 'a', :content => /Can't print recipes/
99 99 assert_no_tag :tag => 'a', :content => /Subproject issue/
100 100 end
101 101
102 102 def test_index_with_project_and_subprojects
103 103 Setting.display_subprojects_issues = 1
104 104 get :index, :project_id => 1
105 105 assert_response :success
106 106 assert_template 'index'
107 107 assert_not_nil assigns(:issues)
108 108 assert_tag :tag => 'a', :content => /Can't print recipes/
109 109 assert_tag :tag => 'a', :content => /Subproject issue/
110 110 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
111 111 end
112 112
113 113 def test_index_with_project_and_subprojects_should_show_private_subprojects
114 114 @request.session[:user_id] = 2
115 115 Setting.display_subprojects_issues = 1
116 116 get :index, :project_id => 1
117 117 assert_response :success
118 118 assert_template 'index'
119 119 assert_not_nil assigns(:issues)
120 120 assert_tag :tag => 'a', :content => /Can't print recipes/
121 121 assert_tag :tag => 'a', :content => /Subproject issue/
122 122 assert_tag :tag => 'a', :content => /Issue of a private subproject/
123 123 end
124 124
125 125 def test_index_with_project_and_default_filter
126 126 get :index, :project_id => 1, :set_filter => 1
127 127 assert_response :success
128 128 assert_template 'index'
129 129 assert_not_nil assigns(:issues)
130 130
131 131 query = assigns(:query)
132 132 assert_not_nil query
133 133 # default filter
134 134 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
135 135 end
136 136
137 137 def test_index_with_project_and_filter
138 138 get :index, :project_id => 1, :set_filter => 1,
139 139 :f => ['tracker_id'],
140 140 :op => {'tracker_id' => '='},
141 141 :v => {'tracker_id' => ['1']}
142 142 assert_response :success
143 143 assert_template 'index'
144 144 assert_not_nil assigns(:issues)
145 145
146 146 query = assigns(:query)
147 147 assert_not_nil query
148 148 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
149 149 end
150 150
151 151 def test_index_with_short_filters
152 152 to_test = {
153 153 'status_id' => {
154 154 'o' => { :op => 'o', :values => [''] },
155 155 'c' => { :op => 'c', :values => [''] },
156 156 '7' => { :op => '=', :values => ['7'] },
157 157 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
158 158 '=7' => { :op => '=', :values => ['7'] },
159 159 '!3' => { :op => '!', :values => ['3'] },
160 160 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
161 161 'subject' => {
162 162 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
163 163 'o' => { :op => '=', :values => ['o'] },
164 164 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
165 165 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
166 166 'tracker_id' => {
167 167 '3' => { :op => '=', :values => ['3'] },
168 168 '=3' => { :op => '=', :values => ['3'] }},
169 169 'start_date' => {
170 170 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
171 171 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
172 172 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
173 173 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
174 174 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
175 175 '<t+2' => { :op => '<t+', :values => ['2'] },
176 176 '>t+2' => { :op => '>t+', :values => ['2'] },
177 177 't+2' => { :op => 't+', :values => ['2'] },
178 178 't' => { :op => 't', :values => [''] },
179 179 'w' => { :op => 'w', :values => [''] },
180 180 '>t-2' => { :op => '>t-', :values => ['2'] },
181 181 '<t-2' => { :op => '<t-', :values => ['2'] },
182 182 't-2' => { :op => 't-', :values => ['2'] }},
183 183 'created_on' => {
184 184 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
185 185 '<t-2' => { :op => '<t-', :values => ['2'] },
186 186 '>t-2' => { :op => '>t-', :values => ['2'] },
187 187 't-2' => { :op => 't-', :values => ['2'] }},
188 188 'cf_1' => {
189 189 'c' => { :op => '=', :values => ['c'] },
190 190 '!c' => { :op => '!', :values => ['c'] },
191 191 '!*' => { :op => '!*', :values => [''] },
192 192 '*' => { :op => '*', :values => [''] }},
193 193 'estimated_hours' => {
194 194 '=13.4' => { :op => '=', :values => ['13.4'] },
195 195 '>=45' => { :op => '>=', :values => ['45'] },
196 196 '<=125' => { :op => '<=', :values => ['125'] },
197 197 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
198 198 '!*' => { :op => '!*', :values => [''] },
199 199 '*' => { :op => '*', :values => [''] }}
200 200 }
201 201
202 202 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
203 203
204 204 to_test.each do |field, expression_and_expected|
205 205 expression_and_expected.each do |filter_expression, expected|
206 206
207 207 get :index, :set_filter => 1, field => filter_expression
208 208
209 209 assert_response :success
210 210 assert_template 'index'
211 211 assert_not_nil assigns(:issues)
212 212
213 213 query = assigns(:query)
214 214 assert_not_nil query
215 215 assert query.has_filter?(field)
216 216 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
217 217 end
218 218 end
219 219 end
220 220
221 221 def test_index_with_project_and_empty_filters
222 222 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
223 223 assert_response :success
224 224 assert_template 'index'
225 225 assert_not_nil assigns(:issues)
226 226
227 227 query = assigns(:query)
228 228 assert_not_nil query
229 229 # no filter
230 230 assert_equal({}, query.filters)
231 231 end
232 232
233 233 def test_index_with_query
234 234 get :index, :project_id => 1, :query_id => 5
235 235 assert_response :success
236 236 assert_template 'index'
237 237 assert_not_nil assigns(:issues)
238 238 assert_nil assigns(:issue_count_by_group)
239 239 end
240 240
241 241 def test_index_with_query_grouped_by_tracker
242 242 get :index, :project_id => 1, :query_id => 6
243 243 assert_response :success
244 244 assert_template 'index'
245 245 assert_not_nil assigns(:issues)
246 246 assert_not_nil assigns(:issue_count_by_group)
247 247 end
248 248
249 249 def test_index_with_query_grouped_by_list_custom_field
250 250 get :index, :project_id => 1, :query_id => 9
251 251 assert_response :success
252 252 assert_template 'index'
253 253 assert_not_nil assigns(:issues)
254 254 assert_not_nil assigns(:issue_count_by_group)
255 255 end
256 256
257 257 def test_index_with_query_id_and_project_id_should_set_session_query
258 258 get :index, :project_id => 1, :query_id => 4
259 259 assert_response :success
260 260 assert_kind_of Hash, session[:query]
261 261 assert_equal 4, session[:query][:id]
262 262 assert_equal 1, session[:query][:project_id]
263 263 end
264 264
265 265 def test_index_with_cross_project_query_in_session_should_show_project_issues
266 266 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
267 267 @request.session[:query] = {:id => q.id, :project_id => 1}
268 268
269 269 with_settings :display_subprojects_issues => '0' do
270 270 get :index, :project_id => 1
271 271 end
272 272 assert_response :success
273 273 assert_not_nil assigns(:query)
274 274 assert_equal q.id, assigns(:query).id
275 275 assert_equal 1, assigns(:query).project_id
276 276 assert_equal [1], assigns(:issues).map(&:project_id).uniq
277 277 end
278 278
279 279 def test_private_query_should_not_be_available_to_other_users
280 280 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
281 281 @request.session[:user_id] = 3
282 282
283 283 get :index, :query_id => q.id
284 284 assert_response 403
285 285 end
286 286
287 287 def test_private_query_should_be_available_to_its_user
288 288 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
289 289 @request.session[:user_id] = 2
290 290
291 291 get :index, :query_id => q.id
292 292 assert_response :success
293 293 end
294 294
295 295 def test_public_query_should_be_available_to_other_users
296 296 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
297 297 @request.session[:user_id] = 3
298 298
299 299 get :index, :query_id => q.id
300 300 assert_response :success
301 301 end
302 302
303 303 def test_index_csv
304 304 get :index, :format => 'csv'
305 305 assert_response :success
306 306 assert_not_nil assigns(:issues)
307 307 assert_equal 'text/csv', @response.content_type
308 308 assert @response.body.starts_with?("#,")
309 309 lines = @response.body.chomp.split("\n")
310 310 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
311 311 end
312 312
313 313 def test_index_csv_with_project
314 314 get :index, :project_id => 1, :format => 'csv'
315 315 assert_response :success
316 316 assert_not_nil assigns(:issues)
317 317 assert_equal 'text/csv', @response.content_type
318 318 end
319 319
320 320 def test_index_csv_with_description
321 321 get :index, :format => 'csv', :description => '1'
322 322 assert_response :success
323 323 assert_not_nil assigns(:issues)
324 324 assert_equal 'text/csv', @response.content_type
325 325 assert @response.body.starts_with?("#,")
326 326 lines = @response.body.chomp.split("\n")
327 327 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
328 328 end
329 329
330 330 def test_index_csv_with_spent_time_column
331 331 issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column')
332 332 TimeEntry.generate!(:project_id => issue.project_id, :issue_id => issue.id, :hours => 7.33)
333 333
334 334 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
335 335 assert_response :success
336 336 assert_equal 'text/csv', @response.content_type
337 337 lines = @response.body.chomp.split("\n")
338 338 assert_include "#{issue.id},#{issue.subject},7.33", lines
339 339 end
340 340
341 341 def test_index_csv_with_all_columns
342 342 get :index, :format => 'csv', :columns => 'all'
343 343 assert_response :success
344 344 assert_not_nil assigns(:issues)
345 345 assert_equal 'text/csv', @response.content_type
346 346 assert @response.body.starts_with?("#,")
347 347 lines = @response.body.chomp.split("\n")
348 348 assert_equal assigns(:query).available_columns.size + 1, lines[0].split(',').size
349 349 end
350 350
351 351 def test_index_csv_with_multi_column_field
352 352 CustomField.find(1).update_attribute :multiple, true
353 353 issue = Issue.find(1)
354 354 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
355 355 issue.save!
356 356
357 357 get :index, :format => 'csv', :columns => 'all'
358 358 assert_response :success
359 359 lines = @response.body.chomp.split("\n")
360 360 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
361 361 end
362 362
363 363 def test_index_csv_big_5
364 364 with_settings :default_language => "zh-TW" do
365 365 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
366 366 str_big5 = "\xa4@\xa4\xeb"
367 367 if str_utf8.respond_to?(:force_encoding)
368 368 str_utf8.force_encoding('UTF-8')
369 369 str_big5.force_encoding('Big5')
370 370 end
371 371 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
372 372 :status_id => 1, :priority => IssuePriority.all.first,
373 373 :subject => str_utf8)
374 374 assert issue.save
375 375
376 376 get :index, :project_id => 1,
377 377 :f => ['subject'],
378 378 :op => '=', :values => [str_utf8],
379 379 :format => 'csv'
380 380 assert_equal 'text/csv', @response.content_type
381 381 lines = @response.body.chomp.split("\n")
382 382 s1 = "\xaa\xac\xbaA"
383 383 if str_utf8.respond_to?(:force_encoding)
384 384 s1.force_encoding('Big5')
385 385 end
386 386 assert lines[0].include?(s1)
387 387 assert lines[1].include?(str_big5)
388 388 end
389 389 end
390 390
391 391 def test_index_csv_cannot_convert_should_be_replaced_big_5
392 392 with_settings :default_language => "zh-TW" do
393 393 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
394 394 if str_utf8.respond_to?(:force_encoding)
395 395 str_utf8.force_encoding('UTF-8')
396 396 end
397 397 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
398 398 :status_id => 1, :priority => IssuePriority.all.first,
399 399 :subject => str_utf8)
400 400 assert issue.save
401 401
402 402 get :index, :project_id => 1,
403 403 :f => ['subject'],
404 404 :op => '=', :values => [str_utf8],
405 405 :c => ['status', 'subject'],
406 406 :format => 'csv',
407 407 :set_filter => 1
408 408 assert_equal 'text/csv', @response.content_type
409 409 lines = @response.body.chomp.split("\n")
410 410 s1 = "\xaa\xac\xbaA" # status
411 411 if str_utf8.respond_to?(:force_encoding)
412 412 s1.force_encoding('Big5')
413 413 end
414 414 assert lines[0].include?(s1)
415 415 s2 = lines[1].split(",")[2]
416 416 if s1.respond_to?(:force_encoding)
417 417 s3 = "\xa5H?" # subject
418 418 s3.force_encoding('Big5')
419 419 assert_equal s3, s2
420 420 elsif RUBY_PLATFORM == 'java'
421 421 assert_equal "??", s2
422 422 else
423 423 assert_equal "\xa5H???", s2
424 424 end
425 425 end
426 426 end
427 427
428 428 def test_index_csv_tw
429 429 with_settings :default_language => "zh-TW" do
430 430 str1 = "test_index_csv_tw"
431 431 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
432 432 :status_id => 1, :priority => IssuePriority.all.first,
433 433 :subject => str1, :estimated_hours => '1234.5')
434 434 assert issue.save
435 435 assert_equal 1234.5, issue.estimated_hours
436 436
437 437 get :index, :project_id => 1,
438 438 :f => ['subject'],
439 439 :op => '=', :values => [str1],
440 440 :c => ['estimated_hours', 'subject'],
441 441 :format => 'csv',
442 442 :set_filter => 1
443 443 assert_equal 'text/csv', @response.content_type
444 444 lines = @response.body.chomp.split("\n")
445 445 assert_equal "#{issue.id},1234.50,#{str1}", lines[1]
446 446
447 447 str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
448 448 if str_tw.respond_to?(:force_encoding)
449 449 str_tw.force_encoding('UTF-8')
450 450 end
451 451 assert_equal str_tw, l(:general_lang_name)
452 452 assert_equal ',', l(:general_csv_separator)
453 453 assert_equal '.', l(:general_csv_decimal_separator)
454 454 end
455 455 end
456 456
457 457 def test_index_csv_fr
458 458 with_settings :default_language => "fr" do
459 459 str1 = "test_index_csv_fr"
460 460 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
461 461 :status_id => 1, :priority => IssuePriority.all.first,
462 462 :subject => str1, :estimated_hours => '1234.5')
463 463 assert issue.save
464 464 assert_equal 1234.5, issue.estimated_hours
465 465
466 466 get :index, :project_id => 1,
467 467 :f => ['subject'],
468 468 :op => '=', :values => [str1],
469 469 :c => ['estimated_hours', 'subject'],
470 470 :format => 'csv',
471 471 :set_filter => 1
472 472 assert_equal 'text/csv', @response.content_type
473 473 lines = @response.body.chomp.split("\n")
474 474 assert_equal "#{issue.id};1234,50;#{str1}", lines[1]
475 475
476 476 str_fr = "Fran\xc3\xa7ais"
477 477 if str_fr.respond_to?(:force_encoding)
478 478 str_fr.force_encoding('UTF-8')
479 479 end
480 480 assert_equal str_fr, l(:general_lang_name)
481 481 assert_equal ';', l(:general_csv_separator)
482 482 assert_equal ',', l(:general_csv_decimal_separator)
483 483 end
484 484 end
485 485
486 486 def test_index_pdf
487 487 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
488 488 with_settings :default_language => lang do
489 489
490 490 get :index
491 491 assert_response :success
492 492 assert_template 'index'
493 493
494 494 if lang == "ja"
495 495 if RUBY_PLATFORM != 'java'
496 496 assert_equal "CP932", l(:general_pdf_encoding)
497 497 end
498 498 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
499 499 next
500 500 end
501 501 end
502 502
503 503 get :index, :format => 'pdf'
504 504 assert_response :success
505 505 assert_not_nil assigns(:issues)
506 506 assert_equal 'application/pdf', @response.content_type
507 507
508 508 get :index, :project_id => 1, :format => 'pdf'
509 509 assert_response :success
510 510 assert_not_nil assigns(:issues)
511 511 assert_equal 'application/pdf', @response.content_type
512 512
513 513 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
514 514 assert_response :success
515 515 assert_not_nil assigns(:issues)
516 516 assert_equal 'application/pdf', @response.content_type
517 517 end
518 518 end
519 519 end
520 520
521 521 def test_index_pdf_with_query_grouped_by_list_custom_field
522 522 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
523 523 assert_response :success
524 524 assert_not_nil assigns(:issues)
525 525 assert_not_nil assigns(:issue_count_by_group)
526 526 assert_equal 'application/pdf', @response.content_type
527 527 end
528 528
529 529 def test_index_sort
530 530 get :index, :sort => 'tracker,id:desc'
531 531 assert_response :success
532 532
533 533 sort_params = @request.session['issues_index_sort']
534 534 assert sort_params.is_a?(String)
535 535 assert_equal 'tracker,id:desc', sort_params
536 536
537 537 issues = assigns(:issues)
538 538 assert_not_nil issues
539 539 assert !issues.empty?
540 540 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
541 541 end
542 542
543 543 def test_index_sort_by_field_not_included_in_columns
544 544 Setting.issue_list_default_columns = %w(subject author)
545 545 get :index, :sort => 'tracker'
546 546 end
547 547
548 548 def test_index_sort_by_assigned_to
549 549 get :index, :sort => 'assigned_to'
550 550 assert_response :success
551 551 assignees = assigns(:issues).collect(&:assigned_to).compact
552 552 assert_equal assignees.sort, assignees
553 553 end
554 554
555 555 def test_index_sort_by_assigned_to_desc
556 556 get :index, :sort => 'assigned_to:desc'
557 557 assert_response :success
558 558 assignees = assigns(:issues).collect(&:assigned_to).compact
559 559 assert_equal assignees.sort.reverse, assignees
560 560 end
561 561
562 562 def test_index_group_by_assigned_to
563 563 get :index, :group_by => 'assigned_to', :sort => 'priority'
564 564 assert_response :success
565 565 end
566 566
567 567 def test_index_sort_by_author
568 568 get :index, :sort => 'author'
569 569 assert_response :success
570 570 authors = assigns(:issues).collect(&:author)
571 571 assert_equal authors.sort, authors
572 572 end
573 573
574 574 def test_index_sort_by_author_desc
575 575 get :index, :sort => 'author:desc'
576 576 assert_response :success
577 577 authors = assigns(:issues).collect(&:author)
578 578 assert_equal authors.sort.reverse, authors
579 579 end
580 580
581 581 def test_index_group_by_author
582 582 get :index, :group_by => 'author', :sort => 'priority'
583 583 assert_response :success
584 584 end
585 585
586 586 def test_index_sort_by_spent_hours
587 587 get :index, :sort => 'spent_hours:desc'
588 588 assert_response :success
589 589 hours = assigns(:issues).collect(&:spent_hours)
590 590 assert_equal hours.sort.reverse, hours
591 591 end
592 592
593 593 def test_index_with_columns
594 594 columns = ['tracker', 'subject', 'assigned_to']
595 595 get :index, :set_filter => 1, :c => columns
596 596 assert_response :success
597 597
598 598 # query should use specified columns
599 599 query = assigns(:query)
600 600 assert_kind_of Query, query
601 601 assert_equal columns, query.column_names.map(&:to_s)
602 602
603 603 # columns should be stored in session
604 604 assert_kind_of Hash, session[:query]
605 605 assert_kind_of Array, session[:query][:column_names]
606 606 assert_equal columns, session[:query][:column_names].map(&:to_s)
607 607
608 608 # ensure only these columns are kept in the selected columns list
609 609 assert_tag :tag => 'select', :attributes => { :id => 'selected_columns' },
610 610 :children => { :count => 3 }
611 611 assert_no_tag :tag => 'option', :attributes => { :value => 'project' },
612 612 :parent => { :tag => 'select', :attributes => { :id => "selected_columns" } }
613 613 end
614 614
615 615 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
616 616 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
617 617 get :index, :set_filter => 1
618 618
619 619 # query should use specified columns
620 620 query = assigns(:query)
621 621 assert_kind_of Query, query
622 622 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
623 623 end
624 624
625 625 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
626 626 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
627 627 columns = ['tracker', 'subject', 'assigned_to']
628 628 get :index, :set_filter => 1, :c => columns
629 629
630 630 # query should use specified columns
631 631 query = assigns(:query)
632 632 assert_kind_of Query, query
633 633 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
634 634 end
635 635
636 636 def test_index_with_custom_field_column
637 637 columns = %w(tracker subject cf_2)
638 638 get :index, :set_filter => 1, :c => columns
639 639 assert_response :success
640 640
641 641 # query should use specified columns
642 642 query = assigns(:query)
643 643 assert_kind_of Query, query
644 644 assert_equal columns, query.column_names.map(&:to_s)
645 645
646 646 assert_tag :td,
647 647 :attributes => {:class => 'cf_2 string'},
648 648 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
649 649 end
650 650
651 651 def test_index_with_multi_custom_field_column
652 652 field = CustomField.find(1)
653 653 field.update_attribute :multiple, true
654 654 issue = Issue.find(1)
655 655 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
656 656 issue.save!
657 657
658 658 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
659 659 assert_response :success
660 660
661 661 assert_tag :td,
662 662 :attributes => {:class => /cf_1/},
663 663 :content => 'MySQL, Oracle'
664 664 end
665 665
666 666 def test_index_with_multi_user_custom_field_column
667 667 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
668 668 :tracker_ids => [1], :is_for_all => true)
669 669 issue = Issue.find(1)
670 670 issue.custom_field_values = {field.id => ['2', '3']}
671 671 issue.save!
672 672
673 673 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
674 674 assert_response :success
675 675
676 676 assert_tag :td,
677 677 :attributes => {:class => /cf_#{field.id}/},
678 678 :child => {:tag => 'a', :content => 'John Smith'}
679 679 end
680 680
681 681 def test_index_with_date_column
682 682 Issue.find(1).update_attribute :start_date, '1987-08-24'
683 683
684 684 with_settings :date_format => '%d/%m/%Y' do
685 685 get :index, :set_filter => 1, :c => %w(start_date)
686 686 assert_tag 'td', :attributes => {:class => /start_date/}, :content => '24/08/1987'
687 687 end
688 688 end
689 689
690 690 def test_index_with_done_ratio
691 691 Issue.find(1).update_attribute :done_ratio, 40
692 692
693 693 get :index, :set_filter => 1, :c => %w(done_ratio)
694 694 assert_tag 'td', :attributes => {:class => /done_ratio/},
695 695 :child => {:tag => 'table', :attributes => {:class => 'progress'},
696 696 :descendant => {:tag => 'td', :attributes => {:class => 'closed', :style => 'width: 40%;'}}
697 697 }
698 698 end
699 699
700 700 def test_index_with_spent_hours_column
701 701 get :index, :set_filter => 1, :c => %w(subject spent_hours)
702 702
703 703 assert_tag 'tr', :attributes => {:id => 'issue-3'},
704 704 :child => {
705 705 :tag => 'td', :attributes => {:class => /spent_hours/}, :content => '1.00'
706 706 }
707 707 end
708 708
709 709 def test_index_should_not_show_spent_hours_column_without_permission
710 710 Role.anonymous.remove_permission! :view_time_entries
711 711 get :index, :set_filter => 1, :c => %w(subject spent_hours)
712 712
713 713 assert_no_tag 'td', :attributes => {:class => /spent_hours/}
714 714 end
715 715
716 716 def test_index_with_fixed_version
717 717 get :index, :set_filter => 1, :c => %w(fixed_version)
718 718 assert_tag 'td', :attributes => {:class => /fixed_version/},
719 719 :child => {:tag => 'a', :content => '1.0', :attributes => {:href => '/versions/2'}}
720 720 end
721 721
722 722 def test_index_send_html_if_query_is_invalid
723 723 get :index, :f => ['start_date'], :op => {:start_date => '='}
724 724 assert_equal 'text/html', @response.content_type
725 725 assert_template 'index'
726 726 end
727 727
728 728 def test_index_send_nothing_if_query_is_invalid
729 729 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
730 730 assert_equal 'text/csv', @response.content_type
731 731 assert @response.body.blank?
732 732 end
733 733
734 734 def test_show_by_anonymous
735 735 get :show, :id => 1
736 736 assert_response :success
737 737 assert_template 'show'
738 738 assert_not_nil assigns(:issue)
739 739 assert_equal Issue.find(1), assigns(:issue)
740 740
741 741 # anonymous role is allowed to add a note
742 742 assert_tag :tag => 'form',
743 743 :descendant => { :tag => 'fieldset',
744 744 :child => { :tag => 'legend',
745 745 :content => /Notes/ } }
746 746 assert_tag :tag => 'title',
747 747 :content => "Bug #1: Can't print recipes - eCookbook - Redmine"
748 748 end
749 749
750 750 def test_show_by_manager
751 751 @request.session[:user_id] = 2
752 752 get :show, :id => 1
753 753 assert_response :success
754 754
755 755 assert_tag :tag => 'a',
756 756 :content => /Quote/
757 757
758 758 assert_tag :tag => 'form',
759 759 :descendant => { :tag => 'fieldset',
760 760 :child => { :tag => 'legend',
761 761 :content => /Change properties/ } },
762 762 :descendant => { :tag => 'fieldset',
763 763 :child => { :tag => 'legend',
764 764 :content => /Log time/ } },
765 765 :descendant => { :tag => 'fieldset',
766 766 :child => { :tag => 'legend',
767 767 :content => /Notes/ } }
768 768 end
769 769
770 770 def test_show_should_display_update_form
771 771 @request.session[:user_id] = 2
772 772 get :show, :id => 1
773 773 assert_response :success
774 774
775 775 assert_tag 'form', :attributes => {:id => 'issue-form'}
776 776 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
777 777 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
778 778 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
779 779 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
780 780 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
781 781 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
782 782 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
783 783 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
784 784 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
785 785 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
786 786 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
787 787 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
788 788 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
789 789 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
790 790 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
791 791 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
792 792 assert_tag 'textarea', :attributes => {:name => 'notes'}
793 793 end
794 794
795 795 def test_show_should_display_update_form_with_minimal_permissions
796 796 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
797 797 Workflow.delete_all :role_id => 1
798 798
799 799 @request.session[:user_id] = 2
800 800 get :show, :id => 1
801 801 assert_response :success
802 802
803 803 assert_tag 'form', :attributes => {:id => 'issue-form'}
804 804 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
805 805 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
806 806 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
807 807 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
808 808 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
809 809 assert_no_tag 'select', :attributes => {:name => 'issue[status_id]'}
810 810 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
811 811 assert_no_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
812 812 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
813 813 assert_no_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
814 814 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
815 815 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
816 816 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
817 817 assert_no_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
818 818 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
819 819 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
820 820 assert_tag 'textarea', :attributes => {:name => 'notes'}
821 821 end
822 822
823 823 def test_show_should_display_update_form_with_workflow_permissions
824 824 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
825 825
826 826 @request.session[:user_id] = 2
827 827 get :show, :id => 1
828 828 assert_response :success
829 829
830 830 assert_tag 'form', :attributes => {:id => 'issue-form'}
831 831 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
832 832 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
833 833 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
834 834 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
835 835 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
836 836 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
837 837 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
838 838 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
839 839 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
840 840 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
841 841 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
842 842 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
843 843 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
844 844 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
845 845 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
846 846 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
847 847 assert_tag 'textarea', :attributes => {:name => 'notes'}
848 848 end
849 849
850 850 def test_show_should_not_display_update_form_without_permissions
851 851 Role.find(1).update_attribute :permissions, [:view_issues]
852 852
853 853 @request.session[:user_id] = 2
854 854 get :show, :id => 1
855 855 assert_response :success
856 856
857 857 assert_no_tag 'form', :attributes => {:id => 'issue-form'}
858 858 end
859 859
860 860 def test_update_form_should_not_display_inactive_enumerations
861 861 @request.session[:user_id] = 2
862 862 get :show, :id => 1
863 863 assert_response :success
864 864
865 865 assert ! IssuePriority.find(15).active?
866 866 assert_no_tag :option, :attributes => {:value => '15'},
867 867 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
868 868 end
869 869
870 870 def test_update_form_should_allow_attachment_upload
871 871 @request.session[:user_id] = 2
872 872 get :show, :id => 1
873 873
874 874 assert_tag :tag => 'form',
875 875 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
876 876 :descendant => {
877 877 :tag => 'input',
878 878 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
879 879 }
880 880 end
881 881
882 882 def test_show_should_deny_anonymous_access_without_permission
883 883 Role.anonymous.remove_permission!(:view_issues)
884 884 get :show, :id => 1
885 885 assert_response :redirect
886 886 end
887 887
888 888 def test_show_should_deny_anonymous_access_to_private_issue
889 889 Issue.update_all(["is_private = ?", true], "id = 1")
890 890 get :show, :id => 1
891 891 assert_response :redirect
892 892 end
893 893
894 894 def test_show_should_deny_non_member_access_without_permission
895 895 Role.non_member.remove_permission!(:view_issues)
896 896 @request.session[:user_id] = 9
897 897 get :show, :id => 1
898 898 assert_response 403
899 899 end
900 900
901 901 def test_show_should_deny_non_member_access_to_private_issue
902 902 Issue.update_all(["is_private = ?", true], "id = 1")
903 903 @request.session[:user_id] = 9
904 904 get :show, :id => 1
905 905 assert_response 403
906 906 end
907 907
908 908 def test_show_should_deny_member_access_without_permission
909 909 Role.find(1).remove_permission!(:view_issues)
910 910 @request.session[:user_id] = 2
911 911 get :show, :id => 1
912 912 assert_response 403
913 913 end
914 914
915 915 def test_show_should_deny_member_access_to_private_issue_without_permission
916 916 Issue.update_all(["is_private = ?", true], "id = 1")
917 917 @request.session[:user_id] = 3
918 918 get :show, :id => 1
919 919 assert_response 403
920 920 end
921 921
922 922 def test_show_should_allow_author_access_to_private_issue
923 923 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
924 924 @request.session[:user_id] = 3
925 925 get :show, :id => 1
926 926 assert_response :success
927 927 end
928 928
929 929 def test_show_should_allow_assignee_access_to_private_issue
930 930 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
931 931 @request.session[:user_id] = 3
932 932 get :show, :id => 1
933 933 assert_response :success
934 934 end
935 935
936 936 def test_show_should_allow_member_access_to_private_issue_with_permission
937 937 Issue.update_all(["is_private = ?", true], "id = 1")
938 938 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
939 939 @request.session[:user_id] = 3
940 940 get :show, :id => 1
941 941 assert_response :success
942 942 end
943 943
944 944 def test_show_should_not_disclose_relations_to_invisible_issues
945 945 Setting.cross_project_issue_relations = '1'
946 946 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
947 947 # Relation to a private project issue
948 948 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
949 949
950 950 get :show, :id => 1
951 951 assert_response :success
952 952
953 953 assert_tag :div, :attributes => { :id => 'relations' },
954 954 :descendant => { :tag => 'a', :content => /#2$/ }
955 955 assert_no_tag :div, :attributes => { :id => 'relations' },
956 956 :descendant => { :tag => 'a', :content => /#4$/ }
957 957 end
958 958
959 959 def test_show_should_list_subtasks
960 960 Issue.generate!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
961 961
962 962 get :show, :id => 1
963 963 assert_response :success
964 964 assert_tag 'div', :attributes => {:id => 'issue_tree'},
965 965 :descendant => {:tag => 'td', :content => /Child Issue/, :attributes => {:class => /subject/}}
966 966 end
967 967
968 968 def test_show_should_list_parents
969 969 issue = Issue.generate!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
970 970
971 971 get :show, :id => issue.id
972 972 assert_response :success
973 973 assert_tag 'div', :attributes => {:class => 'subject'},
974 974 :descendant => {:tag => 'h3', :content => 'Child Issue'}
975 975 assert_tag 'div', :attributes => {:class => 'subject'},
976 976 :descendant => {:tag => 'a', :attributes => {:href => '/issues/1'}}
977 977 end
978 978
979 979 def test_show_should_not_display_prev_next_links_without_query_in_session
980 980 get :show, :id => 1
981 981 assert_response :success
982 982 assert_nil assigns(:prev_issue_id)
983 983 assert_nil assigns(:next_issue_id)
984 984
985 985 assert_no_tag 'div', :attributes => {:class => /next-prev-links/}
986 986 end
987 987
988 988 def test_show_should_display_prev_next_links_with_query_in_session
989 989 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
990 990 @request.session['issues_index_sort'] = 'id'
991 991
992 992 with_settings :display_subprojects_issues => '0' do
993 993 get :show, :id => 3
994 994 end
995 995
996 996 assert_response :success
997 997 # Previous and next issues for all projects
998 998 assert_equal 2, assigns(:prev_issue_id)
999 999 assert_equal 5, assigns(:next_issue_id)
1000 1000
1001 1001 assert_tag 'div', :attributes => {:class => /next-prev-links/}
1002 1002 assert_tag 'a', :attributes => {:href => '/issues/2'}, :content => /Previous/
1003 1003 assert_tag 'a', :attributes => {:href => '/issues/5'}, :content => /Next/
1004 1004
1005 1005 count = Issue.open.visible.count
1006 1006 assert_tag 'span', :attributes => {:class => 'position'}, :content => "3 of #{count}"
1007 1007 end
1008 1008
1009 1009 def test_show_should_display_prev_next_links_with_saved_query_in_session
1010 1010 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1,
1011 1011 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1012 1012 :sort_criteria => [['id', 'asc']])
1013 1013 @request.session[:query] = {:id => query.id, :project_id => nil}
1014 1014
1015 1015 get :show, :id => 11
1016 1016
1017 1017 assert_response :success
1018 1018 assert_equal query, assigns(:query)
1019 1019 # Previous and next issues for all projects
1020 1020 assert_equal 8, assigns(:prev_issue_id)
1021 1021 assert_equal 12, assigns(:next_issue_id)
1022 1022
1023 1023 assert_tag 'a', :attributes => {:href => '/issues/8'}, :content => /Previous/
1024 1024 assert_tag 'a', :attributes => {:href => '/issues/12'}, :content => /Next/
1025 1025 end
1026 1026
1027 1027 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1028 1028 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1029 1029
1030 1030 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1031 1031 @request.session['issues_index_sort'] = assoc_sort
1032 1032
1033 1033 get :show, :id => 3
1034 1034 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1035 1035
1036 1036 assert_tag 'div', :attributes => {:class => /next-prev-links/}, :content => /Previous/
1037 1037 assert_tag 'div', :attributes => {:class => /next-prev-links/}, :content => /Next/
1038 1038 end
1039 1039 end
1040 1040
1041 1041 def test_show_should_display_prev_next_links_with_project_query_in_session
1042 1042 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1043 1043 @request.session['issues_index_sort'] = 'id'
1044 1044
1045 1045 with_settings :display_subprojects_issues => '0' do
1046 1046 get :show, :id => 3
1047 1047 end
1048 1048
1049 1049 assert_response :success
1050 1050 # Previous and next issues inside project
1051 1051 assert_equal 2, assigns(:prev_issue_id)
1052 1052 assert_equal 7, assigns(:next_issue_id)
1053 1053
1054 1054 assert_tag 'a', :attributes => {:href => '/issues/2'}, :content => /Previous/
1055 1055 assert_tag 'a', :attributes => {:href => '/issues/7'}, :content => /Next/
1056 1056 end
1057 1057
1058 1058 def test_show_should_not_display_prev_link_for_first_issue
1059 1059 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1060 1060 @request.session['issues_index_sort'] = 'id'
1061 1061
1062 1062 with_settings :display_subprojects_issues => '0' do
1063 1063 get :show, :id => 1
1064 1064 end
1065 1065
1066 1066 assert_response :success
1067 1067 assert_nil assigns(:prev_issue_id)
1068 1068 assert_equal 2, assigns(:next_issue_id)
1069 1069
1070 1070 assert_no_tag 'a', :content => /Previous/
1071 1071 assert_tag 'a', :attributes => {:href => '/issues/2'}, :content => /Next/
1072 1072 end
1073 1073
1074 1074 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1075 1075 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1076 1076 @request.session['issues_index_sort'] = 'id'
1077 1077
1078 1078 get :show, :id => 1
1079 1079
1080 1080 assert_response :success
1081 1081 assert_nil assigns(:prev_issue_id)
1082 1082 assert_nil assigns(:next_issue_id)
1083 1083
1084 1084 assert_no_tag 'a', :content => /Previous/
1085 1085 assert_no_tag 'a', :content => /Next/
1086 1086 end
1087 1087
1088 1088 def test_show_should_display_visible_changesets_from_other_projects
1089 1089 project = Project.find(2)
1090 1090 issue = project.issues.first
1091 1091 issue.changeset_ids = [102]
1092 1092 issue.save!
1093 1093 project.disable_module! :repository
1094 1094
1095 1095 @request.session[:user_id] = 2
1096 1096 get :show, :id => issue.id
1097 1097 assert_tag 'a', :attributes => {:href => "/projects/ecookbook/repository/revisions/3"}
1098 1098 end
1099 1099
1100 1100 def test_show_with_multi_custom_field
1101 1101 field = CustomField.find(1)
1102 1102 field.update_attribute :multiple, true
1103 1103 issue = Issue.find(1)
1104 1104 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1105 1105 issue.save!
1106 1106
1107 1107 get :show, :id => 1
1108 1108 assert_response :success
1109 1109
1110 1110 assert_tag :td, :content => 'MySQL, Oracle'
1111 1111 end
1112 1112
1113 1113 def test_show_with_multi_user_custom_field
1114 1114 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1115 1115 :tracker_ids => [1], :is_for_all => true)
1116 1116 issue = Issue.find(1)
1117 1117 issue.custom_field_values = {field.id => ['2', '3']}
1118 1118 issue.save!
1119 1119
1120 1120 get :show, :id => 1
1121 1121 assert_response :success
1122 1122
1123 1123 # TODO: should display links
1124 1124 assert_tag :td, :content => 'Dave Lopper, John Smith'
1125 1125 end
1126 1126
1127 1127 def test_show_atom
1128 1128 get :show, :id => 2, :format => 'atom'
1129 1129 assert_response :success
1130 1130 assert_template 'journals/index'
1131 1131 # Inline image
1132 1132 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1133 1133 end
1134 1134
1135 1135 def test_show_export_to_pdf
1136 1136 get :show, :id => 3, :format => 'pdf'
1137 1137 assert_response :success
1138 1138 assert_equal 'application/pdf', @response.content_type
1139 1139 assert @response.body.starts_with?('%PDF')
1140 1140 assert_not_nil assigns(:issue)
1141 1141 end
1142 1142
1143 1143 def test_get_new
1144 1144 @request.session[:user_id] = 2
1145 1145 get :new, :project_id => 1, :tracker_id => 1
1146 1146 assert_response :success
1147 1147 assert_template 'new'
1148 1148
1149 1149 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
1150 1150 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1151 1151 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1152 1152 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1153 1153 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1154 1154 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1155 1155 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1156 1156 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1157 1157 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1158 1158 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1159 1159 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1160 1160 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1161 1161 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1162 1162 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1163 1163 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1164 1164 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1165 1165
1166 1166 # Be sure we don't display inactive IssuePriorities
1167 1167 assert ! IssuePriority.find(15).active?
1168 1168 assert_no_tag :option, :attributes => {:value => '15'},
1169 1169 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1170 1170 end
1171 1171
1172 1172 def test_get_new_with_minimal_permissions
1173 1173 Role.find(1).update_attribute :permissions, [:add_issues]
1174 1174 Workflow.delete_all :role_id => 1
1175 1175
1176 1176 @request.session[:user_id] = 2
1177 1177 get :new, :project_id => 1, :tracker_id => 1
1178 1178 assert_response :success
1179 1179 assert_template 'new'
1180 1180
1181 1181 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
1182 1182 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1183 1183 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1184 1184 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1185 1185 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1186 1186 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1187 1187 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1188 1188 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1189 1189 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1190 1190 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1191 1191 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1192 1192 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1193 1193 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1194 1194 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1195 1195 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1196 1196 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1197 1197 end
1198 1198
1199 def test_get_new_with_list_custom_field
1200 @request.session[:user_id] = 2
1201 get :new, :project_id => 1, :tracker_id => 1
1202 assert_response :success
1203 assert_template 'new'
1204
1205 assert_tag 'select',
1206 :attributes => {:name => 'issue[custom_field_values][1]'},
1207 :children => {:count => 4},
1208 :child => {:tag => 'option', :attributes => {:value => 'MySQL'}, :content => 'MySQL'}
1209 end
1210
1199 1211 def test_get_new_with_multi_custom_field
1200 1212 field = IssueCustomField.find(1)
1201 1213 field.update_attribute :multiple, true
1202 1214
1203 1215 @request.session[:user_id] = 2
1204 1216 get :new, :project_id => 1, :tracker_id => 1
1205 1217 assert_response :success
1206 1218 assert_template 'new'
1207 1219
1208 1220 assert_tag 'select',
1209 1221 :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'},
1210 1222 :children => {:count => 3},
1211 1223 :child => {:tag => 'option', :attributes => {:value => 'MySQL'}, :content => 'MySQL'}
1212 1224 assert_tag 'input',
1213 1225 :attributes => {:name => 'issue[custom_field_values][1][]', :value => ''}
1214 1226 end
1215 1227
1216 1228 def test_get_new_with_multi_user_custom_field
1217 1229 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1218 1230 :tracker_ids => [1], :is_for_all => true)
1219 1231
1220 1232 @request.session[:user_id] = 2
1221 1233 get :new, :project_id => 1, :tracker_id => 1
1222 1234 assert_response :success
1223 1235 assert_template 'new'
1224 1236
1225 1237 assert_tag 'select',
1226 1238 :attributes => {:name => "issue[custom_field_values][#{field.id}][]", :multiple => 'multiple'},
1227 1239 :children => {:count => Project.find(1).users.count},
1228 1240 :child => {:tag => 'option', :attributes => {:value => '2'}, :content => 'John Smith'}
1229 1241 assert_tag 'input',
1230 1242 :attributes => {:name => "issue[custom_field_values][#{field.id}][]", :value => ''}
1231 1243 end
1232 1244
1233 1245 def test_get_new_without_default_start_date_is_creation_date
1234 1246 Setting.default_issue_start_date_to_creation_date = 0
1235 1247
1236 1248 @request.session[:user_id] = 2
1237 1249 get :new, :project_id => 1, :tracker_id => 1
1238 1250 assert_response :success
1239 1251 assert_template 'new'
1240 1252
1241 1253 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
1242 1254 :value => nil }
1243 1255 end
1244 1256
1245 1257 def test_get_new_with_default_start_date_is_creation_date
1246 1258 Setting.default_issue_start_date_to_creation_date = 1
1247 1259
1248 1260 @request.session[:user_id] = 2
1249 1261 get :new, :project_id => 1, :tracker_id => 1
1250 1262 assert_response :success
1251 1263 assert_template 'new'
1252 1264
1253 1265 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
1254 1266 :value => Date.today.to_s }
1255 1267 end
1256 1268
1257 1269 def test_get_new_form_should_allow_attachment_upload
1258 1270 @request.session[:user_id] = 2
1259 1271 get :new, :project_id => 1, :tracker_id => 1
1260 1272
1261 1273 assert_tag :tag => 'form',
1262 1274 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
1263 1275 :descendant => {
1264 1276 :tag => 'input',
1265 1277 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
1266 1278 }
1267 1279 end
1268 1280
1269 1281 def test_get_new_without_tracker_id
1270 1282 @request.session[:user_id] = 2
1271 1283 get :new, :project_id => 1
1272 1284 assert_response :success
1273 1285 assert_template 'new'
1274 1286
1275 1287 issue = assigns(:issue)
1276 1288 assert_not_nil issue
1277 1289 assert_equal Project.find(1).trackers.first, issue.tracker
1278 1290 end
1279 1291
1280 1292 def test_get_new_with_no_default_status_should_display_an_error
1281 1293 @request.session[:user_id] = 2
1282 1294 IssueStatus.delete_all
1283 1295
1284 1296 get :new, :project_id => 1
1285 1297 assert_response 500
1286 1298 assert_error_tag :content => /No default issue/
1287 1299 end
1288 1300
1289 1301 def test_get_new_with_no_tracker_should_display_an_error
1290 1302 @request.session[:user_id] = 2
1291 1303 Tracker.delete_all
1292 1304
1293 1305 get :new, :project_id => 1
1294 1306 assert_response 500
1295 1307 assert_error_tag :content => /No tracker/
1296 1308 end
1297 1309
1298 1310 def test_update_new_form
1299 1311 @request.session[:user_id] = 2
1300 1312 xhr :post, :new, :project_id => 1,
1301 1313 :issue => {:tracker_id => 2,
1302 1314 :subject => 'This is the test_new issue',
1303 1315 :description => 'This is the description',
1304 1316 :priority_id => 5}
1305 1317 assert_response :success
1306 1318 assert_template 'attributes'
1307 1319
1308 1320 issue = assigns(:issue)
1309 1321 assert_kind_of Issue, issue
1310 1322 assert_equal 1, issue.project_id
1311 1323 assert_equal 2, issue.tracker_id
1312 1324 assert_equal 'This is the test_new issue', issue.subject
1313 1325 end
1314 1326
1315 1327 def test_post_create
1316 1328 @request.session[:user_id] = 2
1317 1329 assert_difference 'Issue.count' do
1318 1330 post :create, :project_id => 1,
1319 1331 :issue => {:tracker_id => 3,
1320 1332 :status_id => 2,
1321 1333 :subject => 'This is the test_new issue',
1322 1334 :description => 'This is the description',
1323 1335 :priority_id => 5,
1324 1336 :start_date => '2010-11-07',
1325 1337 :estimated_hours => '',
1326 1338 :custom_field_values => {'2' => 'Value for field 2'}}
1327 1339 end
1328 1340 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1329 1341
1330 1342 issue = Issue.find_by_subject('This is the test_new issue')
1331 1343 assert_not_nil issue
1332 1344 assert_equal 2, issue.author_id
1333 1345 assert_equal 3, issue.tracker_id
1334 1346 assert_equal 2, issue.status_id
1335 1347 assert_equal Date.parse('2010-11-07'), issue.start_date
1336 1348 assert_nil issue.estimated_hours
1337 1349 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
1338 1350 assert_not_nil v
1339 1351 assert_equal 'Value for field 2', v.value
1340 1352 end
1341 1353
1342 1354 def test_post_new_with_group_assignment
1343 1355 group = Group.find(11)
1344 1356 project = Project.find(1)
1345 1357 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
1346 1358
1347 1359 with_settings :issue_group_assignment => '1' do
1348 1360 @request.session[:user_id] = 2
1349 1361 assert_difference 'Issue.count' do
1350 1362 post :create, :project_id => project.id,
1351 1363 :issue => {:tracker_id => 3,
1352 1364 :status_id => 1,
1353 1365 :subject => 'This is the test_new_with_group_assignment issue',
1354 1366 :assigned_to_id => group.id}
1355 1367 end
1356 1368 end
1357 1369 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1358 1370
1359 1371 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
1360 1372 assert_not_nil issue
1361 1373 assert_equal group, issue.assigned_to
1362 1374 end
1363 1375
1364 1376 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
1365 1377 Setting.default_issue_start_date_to_creation_date = 0
1366 1378
1367 1379 @request.session[:user_id] = 2
1368 1380 assert_difference 'Issue.count' do
1369 1381 post :create, :project_id => 1,
1370 1382 :issue => {:tracker_id => 3,
1371 1383 :status_id => 2,
1372 1384 :subject => 'This is the test_new issue',
1373 1385 :description => 'This is the description',
1374 1386 :priority_id => 5,
1375 1387 :estimated_hours => '',
1376 1388 :custom_field_values => {'2' => 'Value for field 2'}}
1377 1389 end
1378 1390 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1379 1391
1380 1392 issue = Issue.find_by_subject('This is the test_new issue')
1381 1393 assert_not_nil issue
1382 1394 assert_nil issue.start_date
1383 1395 end
1384 1396
1385 1397 def test_post_create_without_start_date_and_default_start_date_is_creation_date
1386 1398 Setting.default_issue_start_date_to_creation_date = 1
1387 1399
1388 1400 @request.session[:user_id] = 2
1389 1401 assert_difference 'Issue.count' do
1390 1402 post :create, :project_id => 1,
1391 1403 :issue => {:tracker_id => 3,
1392 1404 :status_id => 2,
1393 1405 :subject => 'This is the test_new issue',
1394 1406 :description => 'This is the description',
1395 1407 :priority_id => 5,
1396 1408 :estimated_hours => '',
1397 1409 :custom_field_values => {'2' => 'Value for field 2'}}
1398 1410 end
1399 1411 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1400 1412
1401 1413 issue = Issue.find_by_subject('This is the test_new issue')
1402 1414 assert_not_nil issue
1403 1415 assert_equal Date.today, issue.start_date
1404 1416 end
1405 1417
1406 1418 def test_post_create_and_continue
1407 1419 @request.session[:user_id] = 2
1408 1420 assert_difference 'Issue.count' do
1409 1421 post :create, :project_id => 1,
1410 1422 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
1411 1423 :continue => ''
1412 1424 end
1413 1425
1414 1426 issue = Issue.first(:order => 'id DESC')
1415 1427 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1416 1428 assert_not_nil flash[:notice], "flash was not set"
1417 1429 assert flash[:notice].include?("<a href='/issues/#{issue.id}'>##{issue.id}</a>"), "issue link not found in flash: #{flash[:notice]}"
1418 1430 end
1419 1431
1420 1432 def test_post_create_without_custom_fields_param
1421 1433 @request.session[:user_id] = 2
1422 1434 assert_difference 'Issue.count' do
1423 1435 post :create, :project_id => 1,
1424 1436 :issue => {:tracker_id => 1,
1425 1437 :subject => 'This is the test_new issue',
1426 1438 :description => 'This is the description',
1427 1439 :priority_id => 5}
1428 1440 end
1429 1441 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1430 1442 end
1431 1443
1432 1444 def test_post_create_with_multi_custom_field
1433 1445 field = IssueCustomField.find_by_name('Database')
1434 1446 field.update_attribute(:multiple, true)
1435 1447
1436 1448 @request.session[:user_id] = 2
1437 1449 assert_difference 'Issue.count' do
1438 1450 post :create, :project_id => 1,
1439 1451 :issue => {:tracker_id => 1,
1440 1452 :subject => 'This is the test_new issue',
1441 1453 :description => 'This is the description',
1442 1454 :priority_id => 5,
1443 1455 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
1444 1456 end
1445 1457 assert_response 302
1446 1458 issue = Issue.first(:order => 'id DESC')
1447 1459 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
1448 1460 end
1449 1461
1450 1462 def test_post_create_with_empty_multi_custom_field
1451 1463 field = IssueCustomField.find_by_name('Database')
1452 1464 field.update_attribute(:multiple, true)
1453 1465
1454 1466 @request.session[:user_id] = 2
1455 1467 assert_difference 'Issue.count' do
1456 1468 post :create, :project_id => 1,
1457 1469 :issue => {:tracker_id => 1,
1458 1470 :subject => 'This is the test_new issue',
1459 1471 :description => 'This is the description',
1460 1472 :priority_id => 5,
1461 1473 :custom_field_values => {'1' => ['']}}
1462 1474 end
1463 1475 assert_response 302
1464 1476 issue = Issue.first(:order => 'id DESC')
1465 1477 assert_equal [''], issue.custom_field_value(1).sort
1466 1478 end
1467 1479
1468 1480 def test_post_create_with_multi_user_custom_field
1469 1481 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1470 1482 :tracker_ids => [1], :is_for_all => true)
1471 1483
1472 1484 @request.session[:user_id] = 2
1473 1485 assert_difference 'Issue.count' do
1474 1486 post :create, :project_id => 1,
1475 1487 :issue => {:tracker_id => 1,
1476 1488 :subject => 'This is the test_new issue',
1477 1489 :description => 'This is the description',
1478 1490 :priority_id => 5,
1479 1491 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
1480 1492 end
1481 1493 assert_response 302
1482 1494 issue = Issue.first(:order => 'id DESC')
1483 1495 assert_equal ['2', '3'], issue.custom_field_value(field).sort
1484 1496 end
1485 1497
1486 1498 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1487 1499 field = IssueCustomField.find_by_name('Database')
1488 1500 field.update_attribute(:is_required, true)
1489 1501
1490 1502 @request.session[:user_id] = 2
1491 1503 assert_no_difference 'Issue.count' do
1492 1504 post :create, :project_id => 1,
1493 1505 :issue => {:tracker_id => 1,
1494 1506 :subject => 'This is the test_new issue',
1495 1507 :description => 'This is the description',
1496 1508 :priority_id => 5}
1497 1509 end
1498 1510 assert_response :success
1499 1511 assert_template 'new'
1500 1512 issue = assigns(:issue)
1501 1513 assert_not_nil issue
1502 1514 assert_error_tag :content => /Database can't be blank/
1503 1515 end
1504 1516
1505 1517 def test_post_create_with_watchers
1506 1518 @request.session[:user_id] = 2
1507 1519 ActionMailer::Base.deliveries.clear
1508 1520
1509 1521 assert_difference 'Watcher.count', 2 do
1510 1522 post :create, :project_id => 1,
1511 1523 :issue => {:tracker_id => 1,
1512 1524 :subject => 'This is a new issue with watchers',
1513 1525 :description => 'This is the description',
1514 1526 :priority_id => 5,
1515 1527 :watcher_user_ids => ['2', '3']}
1516 1528 end
1517 1529 issue = Issue.find_by_subject('This is a new issue with watchers')
1518 1530 assert_not_nil issue
1519 1531 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1520 1532
1521 1533 # Watchers added
1522 1534 assert_equal [2, 3], issue.watcher_user_ids.sort
1523 1535 assert issue.watched_by?(User.find(3))
1524 1536 # Watchers notified
1525 1537 mail = ActionMailer::Base.deliveries.last
1526 1538 assert_not_nil mail
1527 1539 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1528 1540 end
1529 1541
1530 1542 def test_post_create_subissue
1531 1543 @request.session[:user_id] = 2
1532 1544
1533 1545 assert_difference 'Issue.count' do
1534 1546 post :create, :project_id => 1,
1535 1547 :issue => {:tracker_id => 1,
1536 1548 :subject => 'This is a child issue',
1537 1549 :parent_issue_id => 2}
1538 1550 end
1539 1551 issue = Issue.find_by_subject('This is a child issue')
1540 1552 assert_not_nil issue
1541 1553 assert_equal Issue.find(2), issue.parent
1542 1554 end
1543 1555
1544 1556 def test_post_create_subissue_with_non_numeric_parent_id
1545 1557 @request.session[:user_id] = 2
1546 1558
1547 1559 assert_difference 'Issue.count' do
1548 1560 post :create, :project_id => 1,
1549 1561 :issue => {:tracker_id => 1,
1550 1562 :subject => 'This is a child issue',
1551 1563 :parent_issue_id => 'ABC'}
1552 1564 end
1553 1565 issue = Issue.find_by_subject('This is a child issue')
1554 1566 assert_not_nil issue
1555 1567 assert_nil issue.parent
1556 1568 end
1557 1569
1558 1570 def test_post_create_private
1559 1571 @request.session[:user_id] = 2
1560 1572
1561 1573 assert_difference 'Issue.count' do
1562 1574 post :create, :project_id => 1,
1563 1575 :issue => {:tracker_id => 1,
1564 1576 :subject => 'This is a private issue',
1565 1577 :is_private => '1'}
1566 1578 end
1567 1579 issue = Issue.first(:order => 'id DESC')
1568 1580 assert issue.is_private?
1569 1581 end
1570 1582
1571 1583 def test_post_create_private_with_set_own_issues_private_permission
1572 1584 role = Role.find(1)
1573 1585 role.remove_permission! :set_issues_private
1574 1586 role.add_permission! :set_own_issues_private
1575 1587
1576 1588 @request.session[:user_id] = 2
1577 1589
1578 1590 assert_difference 'Issue.count' do
1579 1591 post :create, :project_id => 1,
1580 1592 :issue => {:tracker_id => 1,
1581 1593 :subject => 'This is a private issue',
1582 1594 :is_private => '1'}
1583 1595 end
1584 1596 issue = Issue.first(:order => 'id DESC')
1585 1597 assert issue.is_private?
1586 1598 end
1587 1599
1588 1600 def test_post_create_should_send_a_notification
1589 1601 ActionMailer::Base.deliveries.clear
1590 1602 @request.session[:user_id] = 2
1591 1603 assert_difference 'Issue.count' do
1592 1604 post :create, :project_id => 1,
1593 1605 :issue => {:tracker_id => 3,
1594 1606 :subject => 'This is the test_new issue',
1595 1607 :description => 'This is the description',
1596 1608 :priority_id => 5,
1597 1609 :estimated_hours => '',
1598 1610 :custom_field_values => {'2' => 'Value for field 2'}}
1599 1611 end
1600 1612 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1601 1613
1602 1614 assert_equal 1, ActionMailer::Base.deliveries.size
1603 1615 end
1604 1616
1605 1617 def test_post_create_should_preserve_fields_values_on_validation_failure
1606 1618 @request.session[:user_id] = 2
1607 1619 post :create, :project_id => 1,
1608 1620 :issue => {:tracker_id => 1,
1609 1621 # empty subject
1610 1622 :subject => '',
1611 1623 :description => 'This is a description',
1612 1624 :priority_id => 6,
1613 1625 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
1614 1626 assert_response :success
1615 1627 assert_template 'new'
1616 1628
1617 1629 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
1618 1630 :content => 'This is a description'
1619 1631 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1620 1632 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1621 1633 :value => '6' },
1622 1634 :content => 'High' }
1623 1635 # Custom fields
1624 1636 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
1625 1637 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1626 1638 :value => 'Oracle' },
1627 1639 :content => 'Oracle' }
1628 1640 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
1629 1641 :value => 'Value for field 2'}
1630 1642 end
1631 1643
1632 1644 def test_post_create_should_ignore_non_safe_attributes
1633 1645 @request.session[:user_id] = 2
1634 1646 assert_nothing_raised do
1635 1647 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
1636 1648 end
1637 1649 end
1638 1650
1639 1651 def test_post_create_with_attachment
1640 1652 set_tmp_attachments_directory
1641 1653 @request.session[:user_id] = 2
1642 1654
1643 1655 assert_difference 'Issue.count' do
1644 1656 assert_difference 'Attachment.count' do
1645 1657 post :create, :project_id => 1,
1646 1658 :issue => { :tracker_id => '1', :subject => 'With attachment' },
1647 1659 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1648 1660 end
1649 1661 end
1650 1662
1651 1663 issue = Issue.first(:order => 'id DESC')
1652 1664 attachment = Attachment.first(:order => 'id DESC')
1653 1665
1654 1666 assert_equal issue, attachment.container
1655 1667 assert_equal 2, attachment.author_id
1656 1668 assert_equal 'testfile.txt', attachment.filename
1657 1669 assert_equal 'text/plain', attachment.content_type
1658 1670 assert_equal 'test file', attachment.description
1659 1671 assert_equal 59, attachment.filesize
1660 1672 assert File.exists?(attachment.diskfile)
1661 1673 assert_equal 59, File.size(attachment.diskfile)
1662 1674 end
1663 1675
1664 1676 def test_post_create_with_failure_should_save_attachments
1665 1677 set_tmp_attachments_directory
1666 1678 @request.session[:user_id] = 2
1667 1679
1668 1680 assert_no_difference 'Issue.count' do
1669 1681 assert_difference 'Attachment.count' do
1670 1682 post :create, :project_id => 1,
1671 1683 :issue => { :tracker_id => '1', :subject => '' },
1672 1684 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1673 1685 assert_response :success
1674 1686 assert_template 'new'
1675 1687 end
1676 1688 end
1677 1689
1678 1690 attachment = Attachment.first(:order => 'id DESC')
1679 1691 assert_equal 'testfile.txt', attachment.filename
1680 1692 assert File.exists?(attachment.diskfile)
1681 1693 assert_nil attachment.container
1682 1694
1683 1695 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
1684 1696 assert_tag 'span', :content => /testfile.txt/
1685 1697 end
1686 1698
1687 1699 def test_post_create_with_failure_should_keep_saved_attachments
1688 1700 set_tmp_attachments_directory
1689 1701 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
1690 1702 @request.session[:user_id] = 2
1691 1703
1692 1704 assert_no_difference 'Issue.count' do
1693 1705 assert_no_difference 'Attachment.count' do
1694 1706 post :create, :project_id => 1,
1695 1707 :issue => { :tracker_id => '1', :subject => '' },
1696 1708 :attachments => {'p0' => {'token' => attachment.token}}
1697 1709 assert_response :success
1698 1710 assert_template 'new'
1699 1711 end
1700 1712 end
1701 1713
1702 1714 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
1703 1715 assert_tag 'span', :content => /testfile.txt/
1704 1716 end
1705 1717
1706 1718 def test_post_create_should_attach_saved_attachments
1707 1719 set_tmp_attachments_directory
1708 1720 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
1709 1721 @request.session[:user_id] = 2
1710 1722
1711 1723 assert_difference 'Issue.count' do
1712 1724 assert_no_difference 'Attachment.count' do
1713 1725 post :create, :project_id => 1,
1714 1726 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
1715 1727 :attachments => {'p0' => {'token' => attachment.token}}
1716 1728 assert_response 302
1717 1729 end
1718 1730 end
1719 1731
1720 1732 issue = Issue.first(:order => 'id DESC')
1721 1733 assert_equal 1, issue.attachments.count
1722 1734
1723 1735 attachment.reload
1724 1736 assert_equal issue, attachment.container
1725 1737 end
1726 1738
1727 1739 context "without workflow privilege" do
1728 1740 setup do
1729 1741 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1730 1742 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1731 1743 end
1732 1744
1733 1745 context "#new" do
1734 1746 should "propose default status only" do
1735 1747 get :new, :project_id => 1
1736 1748 assert_response :success
1737 1749 assert_template 'new'
1738 1750 assert_tag :tag => 'select',
1739 1751 :attributes => {:name => 'issue[status_id]'},
1740 1752 :children => {:count => 1},
1741 1753 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
1742 1754 end
1743 1755
1744 1756 should "accept default status" do
1745 1757 assert_difference 'Issue.count' do
1746 1758 post :create, :project_id => 1,
1747 1759 :issue => {:tracker_id => 1,
1748 1760 :subject => 'This is an issue',
1749 1761 :status_id => 1}
1750 1762 end
1751 1763 issue = Issue.last(:order => 'id')
1752 1764 assert_equal IssueStatus.default, issue.status
1753 1765 end
1754 1766
1755 1767 should "ignore unauthorized status" do
1756 1768 assert_difference 'Issue.count' do
1757 1769 post :create, :project_id => 1,
1758 1770 :issue => {:tracker_id => 1,
1759 1771 :subject => 'This is an issue',
1760 1772 :status_id => 3}
1761 1773 end
1762 1774 issue = Issue.last(:order => 'id')
1763 1775 assert_equal IssueStatus.default, issue.status
1764 1776 end
1765 1777 end
1766 1778
1767 1779 context "#update" do
1768 1780 should "ignore status change" do
1769 1781 assert_difference 'Journal.count' do
1770 1782 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1771 1783 end
1772 1784 assert_equal 1, Issue.find(1).status_id
1773 1785 end
1774 1786
1775 1787 should "ignore attributes changes" do
1776 1788 assert_difference 'Journal.count' do
1777 1789 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1778 1790 end
1779 1791 issue = Issue.find(1)
1780 1792 assert_equal "Can't print recipes", issue.subject
1781 1793 assert_nil issue.assigned_to
1782 1794 end
1783 1795 end
1784 1796 end
1785 1797
1786 1798 context "with workflow privilege" do
1787 1799 setup do
1788 1800 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1789 1801 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1790 1802 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1791 1803 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1792 1804 end
1793 1805
1794 1806 context "#update" do
1795 1807 should "accept authorized status" do
1796 1808 assert_difference 'Journal.count' do
1797 1809 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1798 1810 end
1799 1811 assert_equal 3, Issue.find(1).status_id
1800 1812 end
1801 1813
1802 1814 should "ignore unauthorized status" do
1803 1815 assert_difference 'Journal.count' do
1804 1816 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1805 1817 end
1806 1818 assert_equal 1, Issue.find(1).status_id
1807 1819 end
1808 1820
1809 1821 should "accept authorized attributes changes" do
1810 1822 assert_difference 'Journal.count' do
1811 1823 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
1812 1824 end
1813 1825 issue = Issue.find(1)
1814 1826 assert_equal 2, issue.assigned_to_id
1815 1827 end
1816 1828
1817 1829 should "ignore unauthorized attributes changes" do
1818 1830 assert_difference 'Journal.count' do
1819 1831 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
1820 1832 end
1821 1833 issue = Issue.find(1)
1822 1834 assert_equal "Can't print recipes", issue.subject
1823 1835 end
1824 1836 end
1825 1837
1826 1838 context "and :edit_issues permission" do
1827 1839 setup do
1828 1840 Role.anonymous.add_permission! :add_issues, :edit_issues
1829 1841 end
1830 1842
1831 1843 should "accept authorized status" do
1832 1844 assert_difference 'Journal.count' do
1833 1845 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1834 1846 end
1835 1847 assert_equal 3, Issue.find(1).status_id
1836 1848 end
1837 1849
1838 1850 should "ignore unauthorized status" do
1839 1851 assert_difference 'Journal.count' do
1840 1852 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1841 1853 end
1842 1854 assert_equal 1, Issue.find(1).status_id
1843 1855 end
1844 1856
1845 1857 should "accept authorized attributes changes" do
1846 1858 assert_difference 'Journal.count' do
1847 1859 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1848 1860 end
1849 1861 issue = Issue.find(1)
1850 1862 assert_equal "changed", issue.subject
1851 1863 assert_equal 2, issue.assigned_to_id
1852 1864 end
1853 1865 end
1854 1866 end
1855 1867
1856 1868 def test_new_as_copy
1857 1869 @request.session[:user_id] = 2
1858 1870 get :new, :project_id => 1, :copy_from => 1
1859 1871
1860 1872 assert_response :success
1861 1873 assert_template 'new'
1862 1874
1863 1875 assert_not_nil assigns(:issue)
1864 1876 orig = Issue.find(1)
1865 1877 assert_equal 1, assigns(:issue).project_id
1866 1878 assert_equal orig.subject, assigns(:issue).subject
1867 1879 assert assigns(:issue).copy?
1868 1880
1869 1881 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
1870 1882 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
1871 1883 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
1872 1884 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
1873 1885 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
1874 1886 :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
1875 1887 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
1876 1888 end
1877 1889
1878 1890 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
1879 1891 @request.session[:user_id] = 2
1880 1892 issue = Issue.find(3)
1881 1893 assert issue.attachments.count > 0
1882 1894 get :new, :project_id => 1, :copy_from => 3
1883 1895
1884 1896 assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
1885 1897 end
1886 1898
1887 1899 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
1888 1900 @request.session[:user_id] = 2
1889 1901 issue = Issue.find(3)
1890 1902 issue.attachments.delete_all
1891 1903 get :new, :project_id => 1, :copy_from => 3
1892 1904
1893 1905 assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
1894 1906 end
1895 1907
1896 1908 def test_new_as_copy_with_invalid_issue_should_respond_with_404
1897 1909 @request.session[:user_id] = 2
1898 1910 get :new, :project_id => 1, :copy_from => 99999
1899 1911 assert_response 404
1900 1912 end
1901 1913
1902 1914 def test_create_as_copy_on_different_project
1903 1915 @request.session[:user_id] = 2
1904 1916 assert_difference 'Issue.count' do
1905 1917 post :create, :project_id => 1, :copy_from => 1,
1906 1918 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
1907 1919
1908 1920 assert_not_nil assigns(:issue)
1909 1921 assert assigns(:issue).copy?
1910 1922 end
1911 1923 issue = Issue.first(:order => 'id DESC')
1912 1924 assert_redirected_to "/issues/#{issue.id}"
1913 1925
1914 1926 assert_equal 2, issue.project_id
1915 1927 assert_equal 3, issue.tracker_id
1916 1928 assert_equal 'Copy', issue.subject
1917 1929 end
1918 1930
1919 1931 def test_create_as_copy_should_copy_attachments
1920 1932 @request.session[:user_id] = 2
1921 1933 issue = Issue.find(3)
1922 1934 count = issue.attachments.count
1923 1935 assert count > 0
1924 1936
1925 1937 assert_difference 'Issue.count' do
1926 1938 assert_difference 'Attachment.count', count do
1927 1939 assert_no_difference 'Journal.count' do
1928 1940 post :create, :project_id => 1, :copy_from => 3,
1929 1941 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
1930 1942 :copy_attachments => '1'
1931 1943 end
1932 1944 end
1933 1945 end
1934 1946 copy = Issue.first(:order => 'id DESC')
1935 1947 assert_equal count, copy.attachments.count
1936 1948 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
1937 1949 end
1938 1950
1939 1951 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
1940 1952 @request.session[:user_id] = 2
1941 1953 issue = Issue.find(3)
1942 1954 count = issue.attachments.count
1943 1955 assert count > 0
1944 1956
1945 1957 assert_difference 'Issue.count' do
1946 1958 assert_no_difference 'Attachment.count' do
1947 1959 assert_no_difference 'Journal.count' do
1948 1960 post :create, :project_id => 1, :copy_from => 3,
1949 1961 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
1950 1962 end
1951 1963 end
1952 1964 end
1953 1965 copy = Issue.first(:order => 'id DESC')
1954 1966 assert_equal 0, copy.attachments.count
1955 1967 end
1956 1968
1957 1969 def test_create_as_copy_with_attachments_should_add_new_files
1958 1970 @request.session[:user_id] = 2
1959 1971 issue = Issue.find(3)
1960 1972 count = issue.attachments.count
1961 1973 assert count > 0
1962 1974
1963 1975 assert_difference 'Issue.count' do
1964 1976 assert_difference 'Attachment.count', count + 1 do
1965 1977 assert_no_difference 'Journal.count' do
1966 1978 post :create, :project_id => 1, :copy_from => 3,
1967 1979 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
1968 1980 :copy_attachments => '1',
1969 1981 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1970 1982 end
1971 1983 end
1972 1984 end
1973 1985 copy = Issue.first(:order => 'id DESC')
1974 1986 assert_equal count + 1, copy.attachments.count
1975 1987 end
1976 1988
1977 1989 def test_create_as_copy_with_failure
1978 1990 @request.session[:user_id] = 2
1979 1991 post :create, :project_id => 1, :copy_from => 1,
1980 1992 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
1981 1993
1982 1994 assert_response :success
1983 1995 assert_template 'new'
1984 1996
1985 1997 assert_not_nil assigns(:issue)
1986 1998 assert assigns(:issue).copy?
1987 1999
1988 2000 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
1989 2001 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
1990 2002 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
1991 2003 :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
1992 2004 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
1993 2005 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
1994 2006 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
1995 2007 end
1996 2008
1997 2009 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
1998 2010 @request.session[:user_id] = 2
1999 2011 assert !User.find(2).member_of?(Project.find(4))
2000 2012
2001 2013 assert_difference 'Issue.count' do
2002 2014 post :create, :project_id => 1, :copy_from => 1,
2003 2015 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2004 2016 end
2005 2017 issue = Issue.first(:order => 'id DESC')
2006 2018 assert_equal 1, issue.project_id
2007 2019 end
2008 2020
2009 2021 def test_get_edit
2010 2022 @request.session[:user_id] = 2
2011 2023 get :edit, :id => 1
2012 2024 assert_response :success
2013 2025 assert_template 'edit'
2014 2026 assert_not_nil assigns(:issue)
2015 2027 assert_equal Issue.find(1), assigns(:issue)
2016 2028
2017 2029 # Be sure we don't display inactive IssuePriorities
2018 2030 assert ! IssuePriority.find(15).active?
2019 2031 assert_no_tag :option, :attributes => {:value => '15'},
2020 2032 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2021 2033 end
2022 2034
2023 2035 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
2024 2036 @request.session[:user_id] = 2
2025 2037 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
2026 2038
2027 2039 get :edit, :id => 1
2028 2040 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2029 2041 end
2030 2042
2031 2043 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
2032 2044 @request.session[:user_id] = 2
2033 2045 Role.find_by_name('Manager').remove_permission! :log_time
2034 2046
2035 2047 get :edit, :id => 1
2036 2048 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2037 2049 end
2038 2050
2039 2051 def test_get_edit_with_params
2040 2052 @request.session[:user_id] = 2
2041 2053 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
2042 2054 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
2043 2055 assert_response :success
2044 2056 assert_template 'edit'
2045 2057
2046 2058 issue = assigns(:issue)
2047 2059 assert_not_nil issue
2048 2060
2049 2061 assert_equal 5, issue.status_id
2050 2062 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
2051 2063 :child => { :tag => 'option',
2052 2064 :content => 'Closed',
2053 2065 :attributes => { :selected => 'selected' } }
2054 2066
2055 2067 assert_equal 7, issue.priority_id
2056 2068 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2057 2069 :child => { :tag => 'option',
2058 2070 :content => 'Urgent',
2059 2071 :attributes => { :selected => 'selected' } }
2060 2072
2061 2073 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
2062 2074 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
2063 2075 :child => { :tag => 'option',
2064 2076 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
2065 2077 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
2066 2078 end
2067 2079
2068 2080 def test_get_edit_with_multi_custom_field
2069 2081 field = CustomField.find(1)
2070 2082 field.update_attribute :multiple, true
2071 2083 issue = Issue.find(1)
2072 2084 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2073 2085 issue.save!
2074 2086
2075 2087 @request.session[:user_id] = 2
2076 2088 get :edit, :id => 1
2077 2089 assert_response :success
2078 2090 assert_template 'edit'
2079 2091
2080 2092 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
2081 2093 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2082 2094 :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
2083 2095 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2084 2096 :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
2085 2097 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2086 2098 :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
2087 2099 end
2088 2100
2089 2101 def test_update_edit_form
2090 2102 @request.session[:user_id] = 2
2091 2103 xhr :put, :new, :project_id => 1,
2092 2104 :id => 1,
2093 2105 :issue => {:tracker_id => 2,
2094 2106 :subject => 'This is the test_new issue',
2095 2107 :description => 'This is the description',
2096 2108 :priority_id => 5}
2097 2109 assert_response :success
2098 2110 assert_template 'attributes'
2099 2111
2100 2112 issue = assigns(:issue)
2101 2113 assert_kind_of Issue, issue
2102 2114 assert_equal 1, issue.id
2103 2115 assert_equal 1, issue.project_id
2104 2116 assert_equal 2, issue.tracker_id
2105 2117 assert_equal 'This is the test_new issue', issue.subject
2106 2118 end
2107 2119
2108 2120 def test_update_edit_form_with_project_change
2109 2121 @request.session[:user_id] = 2
2110 2122 xhr :put, :new, :project_id => 1,
2111 2123 :id => 1,
2112 2124 :project_change => '1',
2113 2125 :issue => {:project_id => 2,
2114 2126 :tracker_id => 2,
2115 2127 :subject => 'This is the test_new issue',
2116 2128 :description => 'This is the description',
2117 2129 :priority_id => 5}
2118 2130 assert_response :success
2119 2131 assert_template 'form'
2120 2132
2121 2133 issue = assigns(:issue)
2122 2134 assert_kind_of Issue, issue
2123 2135 assert_equal 1, issue.id
2124 2136 assert_equal 2, issue.project_id
2125 2137 assert_equal 2, issue.tracker_id
2126 2138 assert_equal 'This is the test_new issue', issue.subject
2127 2139 end
2128 2140
2129 2141 def test_update_using_invalid_http_verbs
2130 2142 @request.session[:user_id] = 2
2131 2143 subject = 'Updated by an invalid http verb'
2132 2144
2133 2145 get :update, :id => 1, :issue => {:subject => subject}
2134 2146 assert_not_equal subject, Issue.find(1).subject
2135 2147
2136 2148 post :update, :id => 1, :issue => {:subject => subject}
2137 2149 assert_not_equal subject, Issue.find(1).subject
2138 2150
2139 2151 delete :update, :id => 1, :issue => {:subject => subject}
2140 2152 assert_not_equal subject, Issue.find(1).subject
2141 2153 end
2142 2154
2143 2155 def test_put_update_without_custom_fields_param
2144 2156 @request.session[:user_id] = 2
2145 2157 ActionMailer::Base.deliveries.clear
2146 2158
2147 2159 issue = Issue.find(1)
2148 2160 assert_equal '125', issue.custom_value_for(2).value
2149 2161 old_subject = issue.subject
2150 2162 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2151 2163
2152 2164 assert_difference('Journal.count') do
2153 2165 assert_difference('JournalDetail.count', 2) do
2154 2166 put :update, :id => 1, :issue => {:subject => new_subject,
2155 2167 :priority_id => '6',
2156 2168 :category_id => '1' # no change
2157 2169 }
2158 2170 end
2159 2171 end
2160 2172 assert_redirected_to :action => 'show', :id => '1'
2161 2173 issue.reload
2162 2174 assert_equal new_subject, issue.subject
2163 2175 # Make sure custom fields were not cleared
2164 2176 assert_equal '125', issue.custom_value_for(2).value
2165 2177
2166 2178 mail = ActionMailer::Base.deliveries.last
2167 2179 assert_not_nil mail
2168 2180 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2169 2181 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
2170 2182 end
2171 2183
2172 2184 def test_put_update_with_project_change
2173 2185 @request.session[:user_id] = 2
2174 2186 ActionMailer::Base.deliveries.clear
2175 2187
2176 2188 assert_difference('Journal.count') do
2177 2189 assert_difference('JournalDetail.count', 3) do
2178 2190 put :update, :id => 1, :issue => {:project_id => '2',
2179 2191 :tracker_id => '1', # no change
2180 2192 :priority_id => '6',
2181 2193 :category_id => '3'
2182 2194 }
2183 2195 end
2184 2196 end
2185 2197 assert_redirected_to :action => 'show', :id => '1'
2186 2198 issue = Issue.find(1)
2187 2199 assert_equal 2, issue.project_id
2188 2200 assert_equal 1, issue.tracker_id
2189 2201 assert_equal 6, issue.priority_id
2190 2202 assert_equal 3, issue.category_id
2191 2203
2192 2204 mail = ActionMailer::Base.deliveries.last
2193 2205 assert_not_nil mail
2194 2206 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2195 2207 assert mail.body.include?("Project changed from eCookbook to OnlineStore")
2196 2208 end
2197 2209
2198 2210 def test_put_update_with_tracker_change
2199 2211 @request.session[:user_id] = 2
2200 2212 ActionMailer::Base.deliveries.clear
2201 2213
2202 2214 assert_difference('Journal.count') do
2203 2215 assert_difference('JournalDetail.count', 2) do
2204 2216 put :update, :id => 1, :issue => {:project_id => '1',
2205 2217 :tracker_id => '2',
2206 2218 :priority_id => '6'
2207 2219 }
2208 2220 end
2209 2221 end
2210 2222 assert_redirected_to :action => 'show', :id => '1'
2211 2223 issue = Issue.find(1)
2212 2224 assert_equal 1, issue.project_id
2213 2225 assert_equal 2, issue.tracker_id
2214 2226 assert_equal 6, issue.priority_id
2215 2227 assert_equal 1, issue.category_id
2216 2228
2217 2229 mail = ActionMailer::Base.deliveries.last
2218 2230 assert_not_nil mail
2219 2231 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2220 2232 assert mail.body.include?("Tracker changed from Bug to Feature request")
2221 2233 end
2222 2234
2223 2235 def test_put_update_with_custom_field_change
2224 2236 @request.session[:user_id] = 2
2225 2237 issue = Issue.find(1)
2226 2238 assert_equal '125', issue.custom_value_for(2).value
2227 2239
2228 2240 assert_difference('Journal.count') do
2229 2241 assert_difference('JournalDetail.count', 3) do
2230 2242 put :update, :id => 1, :issue => {:subject => 'Custom field change',
2231 2243 :priority_id => '6',
2232 2244 :category_id => '1', # no change
2233 2245 :custom_field_values => { '2' => 'New custom value' }
2234 2246 }
2235 2247 end
2236 2248 end
2237 2249 assert_redirected_to :action => 'show', :id => '1'
2238 2250 issue.reload
2239 2251 assert_equal 'New custom value', issue.custom_value_for(2).value
2240 2252
2241 2253 mail = ActionMailer::Base.deliveries.last
2242 2254 assert_not_nil mail
2243 2255 assert mail.body.include?("Searchable field changed from 125 to New custom value")
2244 2256 end
2245 2257
2246 2258 def test_put_update_with_multi_custom_field_change
2247 2259 field = CustomField.find(1)
2248 2260 field.update_attribute :multiple, true
2249 2261 issue = Issue.find(1)
2250 2262 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2251 2263 issue.save!
2252 2264
2253 2265 @request.session[:user_id] = 2
2254 2266 assert_difference('Journal.count') do
2255 2267 assert_difference('JournalDetail.count', 3) do
2256 2268 put :update, :id => 1,
2257 2269 :issue => {
2258 2270 :subject => 'Custom field change',
2259 2271 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
2260 2272 }
2261 2273 end
2262 2274 end
2263 2275 assert_redirected_to :action => 'show', :id => '1'
2264 2276 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
2265 2277 end
2266 2278
2267 2279 def test_put_update_with_status_and_assignee_change
2268 2280 issue = Issue.find(1)
2269 2281 assert_equal 1, issue.status_id
2270 2282 @request.session[:user_id] = 2
2271 2283 assert_difference('TimeEntry.count', 0) do
2272 2284 put :update,
2273 2285 :id => 1,
2274 2286 :issue => { :status_id => 2, :assigned_to_id => 3 },
2275 2287 :notes => 'Assigned to dlopper',
2276 2288 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
2277 2289 end
2278 2290 assert_redirected_to :action => 'show', :id => '1'
2279 2291 issue.reload
2280 2292 assert_equal 2, issue.status_id
2281 2293 j = Journal.find(:first, :order => 'id DESC')
2282 2294 assert_equal 'Assigned to dlopper', j.notes
2283 2295 assert_equal 2, j.details.size
2284 2296
2285 2297 mail = ActionMailer::Base.deliveries.last
2286 2298 assert mail.body.include?("Status changed from New to Assigned")
2287 2299 # subject should contain the new status
2288 2300 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
2289 2301 end
2290 2302
2291 2303 def test_put_update_with_note_only
2292 2304 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
2293 2305 # anonymous user
2294 2306 put :update,
2295 2307 :id => 1,
2296 2308 :notes => notes
2297 2309 assert_redirected_to :action => 'show', :id => '1'
2298 2310 j = Journal.find(:first, :order => 'id DESC')
2299 2311 assert_equal notes, j.notes
2300 2312 assert_equal 0, j.details.size
2301 2313 assert_equal User.anonymous, j.user
2302 2314
2303 2315 mail = ActionMailer::Base.deliveries.last
2304 2316 assert mail.body.include?(notes)
2305 2317 end
2306 2318
2307 2319 def test_put_update_with_note_and_spent_time
2308 2320 @request.session[:user_id] = 2
2309 2321 spent_hours_before = Issue.find(1).spent_hours
2310 2322 assert_difference('TimeEntry.count') do
2311 2323 put :update,
2312 2324 :id => 1,
2313 2325 :notes => '2.5 hours added',
2314 2326 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
2315 2327 end
2316 2328 assert_redirected_to :action => 'show', :id => '1'
2317 2329
2318 2330 issue = Issue.find(1)
2319 2331
2320 2332 j = Journal.find(:first, :order => 'id DESC')
2321 2333 assert_equal '2.5 hours added', j.notes
2322 2334 assert_equal 0, j.details.size
2323 2335
2324 2336 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
2325 2337 assert_not_nil t
2326 2338 assert_equal 2.5, t.hours
2327 2339 assert_equal spent_hours_before + 2.5, issue.spent_hours
2328 2340 end
2329 2341
2330 2342 def test_put_update_with_attachment_only
2331 2343 set_tmp_attachments_directory
2332 2344
2333 2345 # Delete all fixtured journals, a race condition can occur causing the wrong
2334 2346 # journal to get fetched in the next find.
2335 2347 Journal.delete_all
2336 2348
2337 2349 # anonymous user
2338 2350 assert_difference 'Attachment.count' do
2339 2351 put :update, :id => 1,
2340 2352 :notes => '',
2341 2353 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2342 2354 end
2343 2355
2344 2356 assert_redirected_to :action => 'show', :id => '1'
2345 2357 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
2346 2358 assert j.notes.blank?
2347 2359 assert_equal 1, j.details.size
2348 2360 assert_equal 'testfile.txt', j.details.first.value
2349 2361 assert_equal User.anonymous, j.user
2350 2362
2351 2363 attachment = Attachment.first(:order => 'id DESC')
2352 2364 assert_equal Issue.find(1), attachment.container
2353 2365 assert_equal User.anonymous, attachment.author
2354 2366 assert_equal 'testfile.txt', attachment.filename
2355 2367 assert_equal 'text/plain', attachment.content_type
2356 2368 assert_equal 'test file', attachment.description
2357 2369 assert_equal 59, attachment.filesize
2358 2370 assert File.exists?(attachment.diskfile)
2359 2371 assert_equal 59, File.size(attachment.diskfile)
2360 2372
2361 2373 mail = ActionMailer::Base.deliveries.last
2362 2374 assert mail.body.include?('testfile.txt')
2363 2375 end
2364 2376
2365 2377 def test_put_update_with_failure_should_save_attachments
2366 2378 set_tmp_attachments_directory
2367 2379 @request.session[:user_id] = 2
2368 2380
2369 2381 assert_no_difference 'Journal.count' do
2370 2382 assert_difference 'Attachment.count' do
2371 2383 put :update, :id => 1,
2372 2384 :issue => { :subject => '' },
2373 2385 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2374 2386 assert_response :success
2375 2387 assert_template 'edit'
2376 2388 end
2377 2389 end
2378 2390
2379 2391 attachment = Attachment.first(:order => 'id DESC')
2380 2392 assert_equal 'testfile.txt', attachment.filename
2381 2393 assert File.exists?(attachment.diskfile)
2382 2394 assert_nil attachment.container
2383 2395
2384 2396 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2385 2397 assert_tag 'span', :content => /testfile.txt/
2386 2398 end
2387 2399
2388 2400 def test_put_update_with_failure_should_keep_saved_attachments
2389 2401 set_tmp_attachments_directory
2390 2402 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2391 2403 @request.session[:user_id] = 2
2392 2404
2393 2405 assert_no_difference 'Journal.count' do
2394 2406 assert_no_difference 'Attachment.count' do
2395 2407 put :update, :id => 1,
2396 2408 :issue => { :subject => '' },
2397 2409 :attachments => {'p0' => {'token' => attachment.token}}
2398 2410 assert_response :success
2399 2411 assert_template 'edit'
2400 2412 end
2401 2413 end
2402 2414
2403 2415 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2404 2416 assert_tag 'span', :content => /testfile.txt/
2405 2417 end
2406 2418
2407 2419 def test_put_update_should_attach_saved_attachments
2408 2420 set_tmp_attachments_directory
2409 2421 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2410 2422 @request.session[:user_id] = 2
2411 2423
2412 2424 assert_difference 'Journal.count' do
2413 2425 assert_difference 'JournalDetail.count' do
2414 2426 assert_no_difference 'Attachment.count' do
2415 2427 put :update, :id => 1,
2416 2428 :notes => 'Attachment added',
2417 2429 :attachments => {'p0' => {'token' => attachment.token}}
2418 2430 assert_redirected_to '/issues/1'
2419 2431 end
2420 2432 end
2421 2433 end
2422 2434
2423 2435 attachment.reload
2424 2436 assert_equal Issue.find(1), attachment.container
2425 2437
2426 2438 journal = Journal.first(:order => 'id DESC')
2427 2439 assert_equal 1, journal.details.size
2428 2440 assert_equal 'testfile.txt', journal.details.first.value
2429 2441 end
2430 2442
2431 2443 def test_put_update_with_attachment_that_fails_to_save
2432 2444 set_tmp_attachments_directory
2433 2445
2434 2446 # Delete all fixtured journals, a race condition can occur causing the wrong
2435 2447 # journal to get fetched in the next find.
2436 2448 Journal.delete_all
2437 2449
2438 2450 # Mock out the unsaved attachment
2439 2451 Attachment.any_instance.stubs(:create).returns(Attachment.new)
2440 2452
2441 2453 # anonymous user
2442 2454 put :update,
2443 2455 :id => 1,
2444 2456 :notes => '',
2445 2457 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
2446 2458 assert_redirected_to :action => 'show', :id => '1'
2447 2459 assert_equal '1 file(s) could not be saved.', flash[:warning]
2448 2460 end
2449 2461
2450 2462 def test_put_update_with_no_change
2451 2463 issue = Issue.find(1)
2452 2464 issue.journals.clear
2453 2465 ActionMailer::Base.deliveries.clear
2454 2466
2455 2467 put :update,
2456 2468 :id => 1,
2457 2469 :notes => ''
2458 2470 assert_redirected_to :action => 'show', :id => '1'
2459 2471
2460 2472 issue.reload
2461 2473 assert issue.journals.empty?
2462 2474 # No email should be sent
2463 2475 assert ActionMailer::Base.deliveries.empty?
2464 2476 end
2465 2477
2466 2478 def test_put_update_should_send_a_notification
2467 2479 @request.session[:user_id] = 2
2468 2480 ActionMailer::Base.deliveries.clear
2469 2481 issue = Issue.find(1)
2470 2482 old_subject = issue.subject
2471 2483 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2472 2484
2473 2485 put :update, :id => 1, :issue => {:subject => new_subject,
2474 2486 :priority_id => '6',
2475 2487 :category_id => '1' # no change
2476 2488 }
2477 2489 assert_equal 1, ActionMailer::Base.deliveries.size
2478 2490 end
2479 2491
2480 2492 def test_put_update_with_invalid_spent_time_hours_only
2481 2493 @request.session[:user_id] = 2
2482 2494 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
2483 2495
2484 2496 assert_no_difference('Journal.count') do
2485 2497 put :update,
2486 2498 :id => 1,
2487 2499 :notes => notes,
2488 2500 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
2489 2501 end
2490 2502 assert_response :success
2491 2503 assert_template 'edit'
2492 2504
2493 2505 assert_error_tag :descendant => {:content => /Activity can't be blank/}
2494 2506 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
2495 2507 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
2496 2508 end
2497 2509
2498 2510 def test_put_update_with_invalid_spent_time_comments_only
2499 2511 @request.session[:user_id] = 2
2500 2512 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
2501 2513
2502 2514 assert_no_difference('Journal.count') do
2503 2515 put :update,
2504 2516 :id => 1,
2505 2517 :notes => notes,
2506 2518 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
2507 2519 end
2508 2520 assert_response :success
2509 2521 assert_template 'edit'
2510 2522
2511 2523 assert_error_tag :descendant => {:content => /Activity can't be blank/}
2512 2524 assert_error_tag :descendant => {:content => /Hours can't be blank/}
2513 2525 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
2514 2526 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
2515 2527 end
2516 2528
2517 2529 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
2518 2530 issue = Issue.find(2)
2519 2531 @request.session[:user_id] = 2
2520 2532
2521 2533 put :update,
2522 2534 :id => issue.id,
2523 2535 :issue => {
2524 2536 :fixed_version_id => 4
2525 2537 }
2526 2538
2527 2539 assert_response :redirect
2528 2540 issue.reload
2529 2541 assert_equal 4, issue.fixed_version_id
2530 2542 assert_not_equal issue.project_id, issue.fixed_version.project_id
2531 2543 end
2532 2544
2533 2545 def test_put_update_should_redirect_back_using_the_back_url_parameter
2534 2546 issue = Issue.find(2)
2535 2547 @request.session[:user_id] = 2
2536 2548
2537 2549 put :update,
2538 2550 :id => issue.id,
2539 2551 :issue => {
2540 2552 :fixed_version_id => 4
2541 2553 },
2542 2554 :back_url => '/issues'
2543 2555
2544 2556 assert_response :redirect
2545 2557 assert_redirected_to '/issues'
2546 2558 end
2547 2559
2548 2560 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
2549 2561 issue = Issue.find(2)
2550 2562 @request.session[:user_id] = 2
2551 2563
2552 2564 put :update,
2553 2565 :id => issue.id,
2554 2566 :issue => {
2555 2567 :fixed_version_id => 4
2556 2568 },
2557 2569 :back_url => 'http://google.com'
2558 2570
2559 2571 assert_response :redirect
2560 2572 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
2561 2573 end
2562 2574
2563 2575 def test_get_bulk_edit
2564 2576 @request.session[:user_id] = 2
2565 2577 get :bulk_edit, :ids => [1, 2]
2566 2578 assert_response :success
2567 2579 assert_template 'bulk_edit'
2568 2580
2569 2581 assert_tag :select, :attributes => {:name => 'issue[project_id]'}
2570 2582 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
2571 2583
2572 2584 # Project specific custom field, date type
2573 2585 field = CustomField.find(9)
2574 2586 assert !field.is_for_all?
2575 2587 assert_equal 'date', field.field_format
2576 2588 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
2577 2589
2578 2590 # System wide custom field
2579 2591 assert CustomField.find(1).is_for_all?
2580 2592 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
2581 2593
2582 2594 # Be sure we don't display inactive IssuePriorities
2583 2595 assert ! IssuePriority.find(15).active?
2584 2596 assert_no_tag :option, :attributes => {:value => '15'},
2585 2597 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2586 2598 end
2587 2599
2588 2600 def test_get_bulk_edit_on_different_projects
2589 2601 @request.session[:user_id] = 2
2590 2602 get :bulk_edit, :ids => [1, 2, 6]
2591 2603 assert_response :success
2592 2604 assert_template 'bulk_edit'
2593 2605
2594 2606 # Can not set issues from different projects as children of an issue
2595 2607 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
2596 2608
2597 2609 # Project specific custom field, date type
2598 2610 field = CustomField.find(9)
2599 2611 assert !field.is_for_all?
2600 2612 assert !field.project_ids.include?(Issue.find(6).project_id)
2601 2613 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
2602 2614 end
2603 2615
2604 2616 def test_get_bulk_edit_with_user_custom_field
2605 2617 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
2606 2618
2607 2619 @request.session[:user_id] = 2
2608 2620 get :bulk_edit, :ids => [1, 2]
2609 2621 assert_response :success
2610 2622 assert_template 'bulk_edit'
2611 2623
2612 2624 assert_tag :select,
2613 2625 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
2614 2626 :children => {
2615 2627 :only => {:tag => 'option'},
2616 2628 :count => Project.find(1).users.count + 1
2617 2629 }
2618 2630 end
2619 2631
2620 2632 def test_get_bulk_edit_with_version_custom_field
2621 2633 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
2622 2634
2623 2635 @request.session[:user_id] = 2
2624 2636 get :bulk_edit, :ids => [1, 2]
2625 2637 assert_response :success
2626 2638 assert_template 'bulk_edit'
2627 2639
2628 2640 assert_tag :select,
2629 2641 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
2630 2642 :children => {
2631 2643 :only => {:tag => 'option'},
2632 2644 :count => Project.find(1).shared_versions.count + 1
2633 2645 }
2634 2646 end
2635 2647
2636 2648 def test_get_bulk_edit_with_multi_custom_field
2637 2649 field = CustomField.find(1)
2638 2650 field.update_attribute :multiple, true
2639 2651
2640 2652 @request.session[:user_id] = 2
2641 2653 get :bulk_edit, :ids => [1, 2]
2642 2654 assert_response :success
2643 2655 assert_template 'bulk_edit'
2644 2656
2645 2657 assert_tag :select,
2646 2658 :attributes => {:name => "issue[custom_field_values][1][]"},
2647 2659 :children => {
2648 2660 :only => {:tag => 'option'},
2649 2661 :count => 3
2650 2662 }
2651 2663 end
2652 2664
2653 2665 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
2654 2666 Workflow.delete_all
2655 2667 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
2656 2668 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2657 2669 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2658 2670 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2659 2671 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
2660 2672 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2661 2673 @request.session[:user_id] = 2
2662 2674 get :bulk_edit, :ids => [1, 2]
2663 2675
2664 2676 assert_response :success
2665 2677 statuses = assigns(:available_statuses)
2666 2678 assert_not_nil statuses
2667 2679 assert_equal [1, 3], statuses.map(&:id).sort
2668 2680
2669 2681 assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
2670 2682 :children => {:count => 3} # 2 statuses + "no change" option
2671 2683 end
2672 2684
2673 2685 def test_bulk_edit_should_propose_target_project_open_shared_versions
2674 2686 @request.session[:user_id] = 2
2675 2687 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
2676 2688 assert_response :success
2677 2689 assert_template 'bulk_edit'
2678 2690 assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
2679 2691 assert_tag 'select',
2680 2692 :attributes => {:name => 'issue[fixed_version_id]'},
2681 2693 :descendant => {:tag => 'option', :content => '2.0'}
2682 2694 end
2683 2695
2684 2696 def test_bulk_edit_should_propose_target_project_categories
2685 2697 @request.session[:user_id] = 2
2686 2698 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
2687 2699 assert_response :success
2688 2700 assert_template 'bulk_edit'
2689 2701 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
2690 2702 assert_tag 'select',
2691 2703 :attributes => {:name => 'issue[category_id]'},
2692 2704 :descendant => {:tag => 'option', :content => 'Recipes'}
2693 2705 end
2694 2706
2695 2707 def test_bulk_update
2696 2708 @request.session[:user_id] = 2
2697 2709 # update issues priority
2698 2710 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
2699 2711 :issue => {:priority_id => 7,
2700 2712 :assigned_to_id => '',
2701 2713 :custom_field_values => {'2' => ''}}
2702 2714
2703 2715 assert_response 302
2704 2716 # check that the issues were updated
2705 2717 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
2706 2718
2707 2719 issue = Issue.find(1)
2708 2720 journal = issue.journals.find(:first, :order => 'created_on DESC')
2709 2721 assert_equal '125', issue.custom_value_for(2).value
2710 2722 assert_equal 'Bulk editing', journal.notes
2711 2723 assert_equal 1, journal.details.size
2712 2724 end
2713 2725
2714 2726 def test_bulk_update_with_group_assignee
2715 2727 group = Group.find(11)
2716 2728 project = Project.find(1)
2717 2729 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2718 2730
2719 2731 @request.session[:user_id] = 2
2720 2732 # update issues assignee
2721 2733 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
2722 2734 :issue => {:priority_id => '',
2723 2735 :assigned_to_id => group.id,
2724 2736 :custom_field_values => {'2' => ''}}
2725 2737
2726 2738 assert_response 302
2727 2739 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
2728 2740 end
2729 2741
2730 2742 def test_bulk_update_on_different_projects
2731 2743 @request.session[:user_id] = 2
2732 2744 # update issues priority
2733 2745 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
2734 2746 :issue => {:priority_id => 7,
2735 2747 :assigned_to_id => '',
2736 2748 :custom_field_values => {'2' => ''}}
2737 2749
2738 2750 assert_response 302
2739 2751 # check that the issues were updated
2740 2752 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
2741 2753
2742 2754 issue = Issue.find(1)
2743 2755 journal = issue.journals.find(:first, :order => 'created_on DESC')
2744 2756 assert_equal '125', issue.custom_value_for(2).value
2745 2757 assert_equal 'Bulk editing', journal.notes
2746 2758 assert_equal 1, journal.details.size
2747 2759 end
2748 2760
2749 2761 def test_bulk_update_on_different_projects_without_rights
2750 2762 @request.session[:user_id] = 3
2751 2763 user = User.find(3)
2752 2764 action = { :controller => "issues", :action => "bulk_update" }
2753 2765 assert user.allowed_to?(action, Issue.find(1).project)
2754 2766 assert ! user.allowed_to?(action, Issue.find(6).project)
2755 2767 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
2756 2768 :issue => {:priority_id => 7,
2757 2769 :assigned_to_id => '',
2758 2770 :custom_field_values => {'2' => ''}}
2759 2771 assert_response 403
2760 2772 assert_not_equal "Bulk should fail", Journal.last.notes
2761 2773 end
2762 2774
2763 2775 def test_bullk_update_should_send_a_notification
2764 2776 @request.session[:user_id] = 2
2765 2777 ActionMailer::Base.deliveries.clear
2766 2778 post(:bulk_update,
2767 2779 {
2768 2780 :ids => [1, 2],
2769 2781 :notes => 'Bulk editing',
2770 2782 :issue => {
2771 2783 :priority_id => 7,
2772 2784 :assigned_to_id => '',
2773 2785 :custom_field_values => {'2' => ''}
2774 2786 }
2775 2787 })
2776 2788
2777 2789 assert_response 302
2778 2790 assert_equal 2, ActionMailer::Base.deliveries.size
2779 2791 end
2780 2792
2781 2793 def test_bulk_update_project
2782 2794 @request.session[:user_id] = 2
2783 2795 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
2784 2796 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2785 2797 # Issues moved to project 2
2786 2798 assert_equal 2, Issue.find(1).project_id
2787 2799 assert_equal 2, Issue.find(2).project_id
2788 2800 # No tracker change
2789 2801 assert_equal 1, Issue.find(1).tracker_id
2790 2802 assert_equal 2, Issue.find(2).tracker_id
2791 2803 end
2792 2804
2793 2805 def test_bulk_update_project_on_single_issue_should_follow_when_needed
2794 2806 @request.session[:user_id] = 2
2795 2807 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
2796 2808 assert_redirected_to '/issues/1'
2797 2809 end
2798 2810
2799 2811 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
2800 2812 @request.session[:user_id] = 2
2801 2813 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
2802 2814 assert_redirected_to '/projects/onlinestore/issues'
2803 2815 end
2804 2816
2805 2817 def test_bulk_update_tracker
2806 2818 @request.session[:user_id] = 2
2807 2819 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
2808 2820 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2809 2821 assert_equal 2, Issue.find(1).tracker_id
2810 2822 assert_equal 2, Issue.find(2).tracker_id
2811 2823 end
2812 2824
2813 2825 def test_bulk_update_status
2814 2826 @request.session[:user_id] = 2
2815 2827 # update issues priority
2816 2828 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
2817 2829 :issue => {:priority_id => '',
2818 2830 :assigned_to_id => '',
2819 2831 :status_id => '5'}
2820 2832
2821 2833 assert_response 302
2822 2834 issue = Issue.find(1)
2823 2835 assert issue.closed?
2824 2836 end
2825 2837
2826 2838 def test_bulk_update_priority
2827 2839 @request.session[:user_id] = 2
2828 2840 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
2829 2841
2830 2842 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2831 2843 assert_equal 6, Issue.find(1).priority_id
2832 2844 assert_equal 6, Issue.find(2).priority_id
2833 2845 end
2834 2846
2835 2847 def test_bulk_update_with_notes
2836 2848 @request.session[:user_id] = 2
2837 2849 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
2838 2850
2839 2851 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2840 2852 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
2841 2853 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
2842 2854 end
2843 2855
2844 2856 def test_bulk_update_parent_id
2845 2857 @request.session[:user_id] = 2
2846 2858 post :bulk_update, :ids => [1, 3],
2847 2859 :notes => 'Bulk editing parent',
2848 2860 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
2849 2861
2850 2862 assert_response 302
2851 2863 parent = Issue.find(2)
2852 2864 assert_equal parent.id, Issue.find(1).parent_id
2853 2865 assert_equal parent.id, Issue.find(3).parent_id
2854 2866 assert_equal [1, 3], parent.children.collect(&:id).sort
2855 2867 end
2856 2868
2857 2869 def test_bulk_update_custom_field
2858 2870 @request.session[:user_id] = 2
2859 2871 # update issues priority
2860 2872 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
2861 2873 :issue => {:priority_id => '',
2862 2874 :assigned_to_id => '',
2863 2875 :custom_field_values => {'2' => '777'}}
2864 2876
2865 2877 assert_response 302
2866 2878
2867 2879 issue = Issue.find(1)
2868 2880 journal = issue.journals.find(:first, :order => 'created_on DESC')
2869 2881 assert_equal '777', issue.custom_value_for(2).value
2870 2882 assert_equal 1, journal.details.size
2871 2883 assert_equal '125', journal.details.first.old_value
2872 2884 assert_equal '777', journal.details.first.value
2873 2885 end
2874 2886
2875 2887 def test_bulk_update_multi_custom_field
2876 2888 field = CustomField.find(1)
2877 2889 field.update_attribute :multiple, true
2878 2890
2879 2891 @request.session[:user_id] = 2
2880 2892 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
2881 2893 :issue => {:priority_id => '',
2882 2894 :assigned_to_id => '',
2883 2895 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
2884 2896
2885 2897 assert_response 302
2886 2898
2887 2899 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
2888 2900 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
2889 2901 # the custom field is not associated with the issue tracker
2890 2902 assert_nil Issue.find(2).custom_field_value(1)
2891 2903 end
2892 2904
2893 2905 def test_bulk_update_unassign
2894 2906 assert_not_nil Issue.find(2).assigned_to
2895 2907 @request.session[:user_id] = 2
2896 2908 # unassign issues
2897 2909 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
2898 2910 assert_response 302
2899 2911 # check that the issues were updated
2900 2912 assert_nil Issue.find(2).assigned_to
2901 2913 end
2902 2914
2903 2915 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
2904 2916 @request.session[:user_id] = 2
2905 2917
2906 2918 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
2907 2919
2908 2920 assert_response :redirect
2909 2921 issues = Issue.find([1,2])
2910 2922 issues.each do |issue|
2911 2923 assert_equal 4, issue.fixed_version_id
2912 2924 assert_not_equal issue.project_id, issue.fixed_version.project_id
2913 2925 end
2914 2926 end
2915 2927
2916 2928 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
2917 2929 @request.session[:user_id] = 2
2918 2930 post :bulk_update, :ids => [1,2], :back_url => '/issues'
2919 2931
2920 2932 assert_response :redirect
2921 2933 assert_redirected_to '/issues'
2922 2934 end
2923 2935
2924 2936 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
2925 2937 @request.session[:user_id] = 2
2926 2938 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
2927 2939
2928 2940 assert_response :redirect
2929 2941 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
2930 2942 end
2931 2943
2932 2944 def test_bulk_copy_to_another_project
2933 2945 @request.session[:user_id] = 2
2934 2946 assert_difference 'Issue.count', 2 do
2935 2947 assert_no_difference 'Project.find(1).issues.count' do
2936 2948 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
2937 2949 end
2938 2950 end
2939 2951 assert_redirected_to '/projects/ecookbook/issues'
2940 2952 end
2941 2953
2942 2954 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
2943 2955 @request.session[:user_id] = 2
2944 2956 issue_before_move = Issue.find(1)
2945 2957 assert_difference 'Issue.count', 1 do
2946 2958 assert_no_difference 'Project.find(1).issues.count' do
2947 2959 post :bulk_update, :ids => [1], :copy => '1',
2948 2960 :issue => {
2949 2961 :project_id => '2', :tracker_id => '', :assigned_to_id => '',
2950 2962 :status_id => '', :start_date => '', :due_date => ''
2951 2963 }
2952 2964 end
2953 2965 end
2954 2966 issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
2955 2967 assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
2956 2968 assert_equal issue_before_move.status_id, issue_after_move.status_id
2957 2969 assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
2958 2970 end
2959 2971
2960 2972 def test_bulk_copy_should_allow_changing_the_issue_attributes
2961 2973 # Fixes random test failure with Mysql
2962 2974 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
2963 2975 # doesn't return the expected results
2964 2976 Issue.delete_all("project_id=2")
2965 2977
2966 2978 @request.session[:user_id] = 2
2967 2979 assert_difference 'Issue.count', 2 do
2968 2980 assert_no_difference 'Project.find(1).issues.count' do
2969 2981 post :bulk_update, :ids => [1, 2], :copy => '1',
2970 2982 :issue => {
2971 2983 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
2972 2984 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
2973 2985 }
2974 2986 end
2975 2987 end
2976 2988
2977 2989 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
2978 2990 assert_equal 2, copied_issues.size
2979 2991 copied_issues.each do |issue|
2980 2992 assert_equal 2, issue.project_id, "Project is incorrect"
2981 2993 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
2982 2994 assert_equal 3, issue.status_id, "Status is incorrect"
2983 2995 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
2984 2996 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
2985 2997 end
2986 2998 end
2987 2999
2988 3000 def test_bulk_copy_should_allow_adding_a_note
2989 3001 @request.session[:user_id] = 2
2990 3002 assert_difference 'Issue.count', 1 do
2991 3003 post :bulk_update, :ids => [1], :copy => '1',
2992 3004 :notes => 'Copying one issue',
2993 3005 :issue => {
2994 3006 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
2995 3007 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
2996 3008 }
2997 3009 end
2998 3010
2999 3011 issue = Issue.first(:order => 'id DESC')
3000 3012 assert_equal 1, issue.journals.size
3001 3013 journal = issue.journals.first
3002 3014 assert_equal 0, journal.details.size
3003 3015 assert_equal 'Copying one issue', journal.notes
3004 3016 end
3005 3017
3006 3018 def test_bulk_copy_to_another_project_should_follow_when_needed
3007 3019 @request.session[:user_id] = 2
3008 3020 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
3009 3021 issue = Issue.first(:order => 'id DESC')
3010 3022 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
3011 3023 end
3012 3024
3013 3025 def test_destroy_issue_with_no_time_entries
3014 3026 assert_nil TimeEntry.find_by_issue_id(2)
3015 3027 @request.session[:user_id] = 2
3016 3028
3017 3029 assert_difference 'Issue.count', -1 do
3018 3030 delete :destroy, :id => 2
3019 3031 end
3020 3032 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3021 3033 assert_nil Issue.find_by_id(2)
3022 3034 end
3023 3035
3024 3036 def test_destroy_issues_with_time_entries
3025 3037 @request.session[:user_id] = 2
3026 3038
3027 3039 assert_no_difference 'Issue.count' do
3028 3040 delete :destroy, :ids => [1, 3]
3029 3041 end
3030 3042 assert_response :success
3031 3043 assert_template 'destroy'
3032 3044 assert_not_nil assigns(:hours)
3033 3045 assert Issue.find_by_id(1) && Issue.find_by_id(3)
3034 3046 assert_tag 'form',
3035 3047 :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
3036 3048 end
3037 3049
3038 3050 def test_destroy_issues_and_destroy_time_entries
3039 3051 @request.session[:user_id] = 2
3040 3052
3041 3053 assert_difference 'Issue.count', -2 do
3042 3054 assert_difference 'TimeEntry.count', -3 do
3043 3055 delete :destroy, :ids => [1, 3], :todo => 'destroy'
3044 3056 end
3045 3057 end
3046 3058 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3047 3059 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3048 3060 assert_nil TimeEntry.find_by_id([1, 2])
3049 3061 end
3050 3062
3051 3063 def test_destroy_issues_and_assign_time_entries_to_project
3052 3064 @request.session[:user_id] = 2
3053 3065
3054 3066 assert_difference 'Issue.count', -2 do
3055 3067 assert_no_difference 'TimeEntry.count' do
3056 3068 delete :destroy, :ids => [1, 3], :todo => 'nullify'
3057 3069 end
3058 3070 end
3059 3071 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3060 3072 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3061 3073 assert_nil TimeEntry.find(1).issue_id
3062 3074 assert_nil TimeEntry.find(2).issue_id
3063 3075 end
3064 3076
3065 3077 def test_destroy_issues_and_reassign_time_entries_to_another_issue
3066 3078 @request.session[:user_id] = 2
3067 3079
3068 3080 assert_difference 'Issue.count', -2 do
3069 3081 assert_no_difference 'TimeEntry.count' do
3070 3082 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
3071 3083 end
3072 3084 end
3073 3085 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3074 3086 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3075 3087 assert_equal 2, TimeEntry.find(1).issue_id
3076 3088 assert_equal 2, TimeEntry.find(2).issue_id
3077 3089 end
3078 3090
3079 3091 def test_destroy_issues_from_different_projects
3080 3092 @request.session[:user_id] = 2
3081 3093
3082 3094 assert_difference 'Issue.count', -3 do
3083 3095 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
3084 3096 end
3085 3097 assert_redirected_to :controller => 'issues', :action => 'index'
3086 3098 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
3087 3099 end
3088 3100
3089 3101 def test_destroy_parent_and_child_issues
3090 3102 parent = Issue.generate!(:project_id => 1, :tracker_id => 1)
3091 3103 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id)
3092 3104 assert child.is_descendant_of?(parent.reload)
3093 3105
3094 3106 @request.session[:user_id] = 2
3095 3107 assert_difference 'Issue.count', -2 do
3096 3108 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
3097 3109 end
3098 3110 assert_response 302
3099 3111 end
3100 3112
3101 3113 def test_default_search_scope
3102 3114 get :index
3103 3115 assert_tag :div, :attributes => {:id => 'quick-search'},
3104 3116 :child => {:tag => 'form',
3105 3117 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
3106 3118 end
3107 3119 end
General Comments 0
You need to be logged in to leave comments. Login now