##// END OF EJS Templates
Fixes that test randomly fails....
Jean-Philippe Lang -
r10515:8a2786c91e52
parent child
Show More
@@ -1,3805 +1,3804
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
65 65 # links to visible issues
66 66 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
67 67 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
68 68 # private projects hidden
69 69 assert_select 'a[href=/issues/6]', 0
70 70 assert_select 'a[href=/issues/4]', 0
71 71 # project column
72 72 assert_select 'th', :text => /Project/
73 73 end
74 74 end
75 75
76 76 def test_index_should_not_list_issues_when_module_disabled
77 77 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
78 78 get :index
79 79 assert_response :success
80 80 assert_template 'index'
81 81 assert_not_nil assigns(:issues)
82 82 assert_nil assigns(:project)
83 83
84 84 assert_select 'a[href=/issues/1]', 0
85 85 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
86 86 end
87 87
88 88 def test_index_should_list_visible_issues_only
89 89 get :index, :per_page => 100
90 90 assert_response :success
91 91 assert_not_nil assigns(:issues)
92 92 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
93 93 end
94 94
95 95 def test_index_with_project
96 96 Setting.display_subprojects_issues = 0
97 97 get :index, :project_id => 1
98 98 assert_response :success
99 99 assert_template 'index'
100 100 assert_not_nil assigns(:issues)
101 101
102 102 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
103 103 assert_select 'a[href=/issues/5]', 0
104 104 end
105 105
106 106 def test_index_with_project_and_subprojects
107 107 Setting.display_subprojects_issues = 1
108 108 get :index, :project_id => 1
109 109 assert_response :success
110 110 assert_template 'index'
111 111 assert_not_nil assigns(:issues)
112 112
113 113 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
114 114 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
115 115 assert_select 'a[href=/issues/6]', 0
116 116 end
117 117
118 118 def test_index_with_project_and_subprojects_should_show_private_subprojects_with_permission
119 119 @request.session[:user_id] = 2
120 120 Setting.display_subprojects_issues = 1
121 121 get :index, :project_id => 1
122 122 assert_response :success
123 123 assert_template 'index'
124 124 assert_not_nil assigns(:issues)
125 125
126 126 assert_select 'a[href=/issues/1]', :text => /Can&#x27;t print recipes/
127 127 assert_select 'a[href=/issues/5]', :text => /Subproject issue/
128 128 assert_select 'a[href=/issues/6]', :text => /Issue of a private subproject/
129 129 end
130 130
131 131 def test_index_with_project_and_default_filter
132 132 get :index, :project_id => 1, :set_filter => 1
133 133 assert_response :success
134 134 assert_template 'index'
135 135 assert_not_nil assigns(:issues)
136 136
137 137 query = assigns(:query)
138 138 assert_not_nil query
139 139 # default filter
140 140 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
141 141 end
142 142
143 143 def test_index_with_project_and_filter
144 144 get :index, :project_id => 1, :set_filter => 1,
145 145 :f => ['tracker_id'],
146 146 :op => {'tracker_id' => '='},
147 147 :v => {'tracker_id' => ['1']}
148 148 assert_response :success
149 149 assert_template 'index'
150 150 assert_not_nil assigns(:issues)
151 151
152 152 query = assigns(:query)
153 153 assert_not_nil query
154 154 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
155 155 end
156 156
157 157 def test_index_with_short_filters
158 158 to_test = {
159 159 'status_id' => {
160 160 'o' => { :op => 'o', :values => [''] },
161 161 'c' => { :op => 'c', :values => [''] },
162 162 '7' => { :op => '=', :values => ['7'] },
163 163 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
164 164 '=7' => { :op => '=', :values => ['7'] },
165 165 '!3' => { :op => '!', :values => ['3'] },
166 166 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
167 167 'subject' => {
168 168 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
169 169 'o' => { :op => '=', :values => ['o'] },
170 170 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
171 171 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
172 172 'tracker_id' => {
173 173 '3' => { :op => '=', :values => ['3'] },
174 174 '=3' => { :op => '=', :values => ['3'] }},
175 175 'start_date' => {
176 176 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
177 177 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
178 178 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
179 179 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
180 180 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
181 181 '<t+2' => { :op => '<t+', :values => ['2'] },
182 182 '>t+2' => { :op => '>t+', :values => ['2'] },
183 183 't+2' => { :op => 't+', :values => ['2'] },
184 184 't' => { :op => 't', :values => [''] },
185 185 'w' => { :op => 'w', :values => [''] },
186 186 '>t-2' => { :op => '>t-', :values => ['2'] },
187 187 '<t-2' => { :op => '<t-', :values => ['2'] },
188 188 't-2' => { :op => 't-', :values => ['2'] }},
189 189 'created_on' => {
190 190 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
191 191 '<t-2' => { :op => '<t-', :values => ['2'] },
192 192 '>t-2' => { :op => '>t-', :values => ['2'] },
193 193 't-2' => { :op => 't-', :values => ['2'] }},
194 194 'cf_1' => {
195 195 'c' => { :op => '=', :values => ['c'] },
196 196 '!c' => { :op => '!', :values => ['c'] },
197 197 '!*' => { :op => '!*', :values => [''] },
198 198 '*' => { :op => '*', :values => [''] }},
199 199 'estimated_hours' => {
200 200 '=13.4' => { :op => '=', :values => ['13.4'] },
201 201 '>=45' => { :op => '>=', :values => ['45'] },
202 202 '<=125' => { :op => '<=', :values => ['125'] },
203 203 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
204 204 '!*' => { :op => '!*', :values => [''] },
205 205 '*' => { :op => '*', :values => [''] }}
206 206 }
207 207
208 208 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
209 209
210 210 to_test.each do |field, expression_and_expected|
211 211 expression_and_expected.each do |filter_expression, expected|
212 212
213 213 get :index, :set_filter => 1, field => filter_expression
214 214
215 215 assert_response :success
216 216 assert_template 'index'
217 217 assert_not_nil assigns(:issues)
218 218
219 219 query = assigns(:query)
220 220 assert_not_nil query
221 221 assert query.has_filter?(field)
222 222 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
223 223 end
224 224 end
225 225 end
226 226
227 227 def test_index_with_project_and_empty_filters
228 228 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
229 229 assert_response :success
230 230 assert_template 'index'
231 231 assert_not_nil assigns(:issues)
232 232
233 233 query = assigns(:query)
234 234 assert_not_nil query
235 235 # no filter
236 236 assert_equal({}, query.filters)
237 237 end
238 238
239 239 def test_index_with_project_custom_field_filter
240 240 field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string')
241 241 CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo')
242 242 CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo')
243 243 filter_name = "project.cf_#{field.id}"
244 244 @request.session[:user_id] = 1
245 245
246 246 get :index, :set_filter => 1,
247 247 :f => [filter_name],
248 248 :op => {filter_name => '='},
249 249 :v => {filter_name => ['Foo']}
250 250 assert_response :success
251 251 assert_template 'index'
252 252 assert_equal [3, 5], assigns(:issues).map(&:project_id).uniq.sort
253 253 end
254 254
255 255 def test_index_with_query
256 256 get :index, :project_id => 1, :query_id => 5
257 257 assert_response :success
258 258 assert_template 'index'
259 259 assert_not_nil assigns(:issues)
260 260 assert_nil assigns(:issue_count_by_group)
261 261 end
262 262
263 263 def test_index_with_query_grouped_by_tracker
264 264 get :index, :project_id => 1, :query_id => 6
265 265 assert_response :success
266 266 assert_template 'index'
267 267 assert_not_nil assigns(:issues)
268 268 assert_not_nil assigns(:issue_count_by_group)
269 269 end
270 270
271 271 def test_index_with_query_grouped_by_list_custom_field
272 272 get :index, :project_id => 1, :query_id => 9
273 273 assert_response :success
274 274 assert_template 'index'
275 275 assert_not_nil assigns(:issues)
276 276 assert_not_nil assigns(:issue_count_by_group)
277 277 end
278 278
279 279 def test_index_with_query_grouped_by_user_custom_field
280 280 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
281 281 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
282 282 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
283 283 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
284 284 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
285 285
286 286 get :index, :project_id => 1, :set_filter => 1, :group_by => "cf_#{cf.id}"
287 287 assert_response :success
288 288
289 289 assert_select 'tr.group', 3
290 290 assert_select 'tr.group' do
291 291 assert_select 'a', :text => 'John Smith'
292 292 assert_select 'span.count', :text => '1'
293 293 end
294 294 assert_select 'tr.group' do
295 295 assert_select 'a', :text => 'Dave Lopper'
296 296 assert_select 'span.count', :text => '2'
297 297 end
298 298 end
299 299
300 300 def test_index_with_query_id_and_project_id_should_set_session_query
301 301 get :index, :project_id => 1, :query_id => 4
302 302 assert_response :success
303 303 assert_kind_of Hash, session[:query]
304 304 assert_equal 4, session[:query][:id]
305 305 assert_equal 1, session[:query][:project_id]
306 306 end
307 307
308 308 def test_index_with_invalid_query_id_should_respond_404
309 309 get :index, :project_id => 1, :query_id => 999
310 310 assert_response 404
311 311 end
312 312
313 313 def test_index_with_cross_project_query_in_session_should_show_project_issues
314 314 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
315 315 @request.session[:query] = {:id => q.id, :project_id => 1}
316 316
317 317 with_settings :display_subprojects_issues => '0' do
318 318 get :index, :project_id => 1
319 319 end
320 320 assert_response :success
321 321 assert_not_nil assigns(:query)
322 322 assert_equal q.id, assigns(:query).id
323 323 assert_equal 1, assigns(:query).project_id
324 324 assert_equal [1], assigns(:issues).map(&:project_id).uniq
325 325 end
326 326
327 327 def test_private_query_should_not_be_available_to_other_users
328 328 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
329 329 @request.session[:user_id] = 3
330 330
331 331 get :index, :query_id => q.id
332 332 assert_response 403
333 333 end
334 334
335 335 def test_private_query_should_be_available_to_its_user
336 336 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
337 337 @request.session[:user_id] = 2
338 338
339 339 get :index, :query_id => q.id
340 340 assert_response :success
341 341 end
342 342
343 343 def test_public_query_should_be_available_to_other_users
344 344 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
345 345 @request.session[:user_id] = 3
346 346
347 347 get :index, :query_id => q.id
348 348 assert_response :success
349 349 end
350 350
351 351 def test_index_should_omit_page_param_in_export_links
352 352 get :index, :page => 2
353 353 assert_response :success
354 354 assert_select 'a.atom[href=/issues.atom]'
355 355 assert_select 'a.csv[href=/issues.csv]'
356 356 assert_select 'a.pdf[href=/issues.pdf]'
357 357 assert_select 'form#csv-export-form[action=/issues.csv]'
358 358 end
359 359
360 360 def test_index_csv
361 361 get :index, :format => 'csv'
362 362 assert_response :success
363 363 assert_not_nil assigns(:issues)
364 364 assert_equal 'text/csv; header=present', @response.content_type
365 365 assert @response.body.starts_with?("#,")
366 366 lines = @response.body.chomp.split("\n")
367 367 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
368 368 end
369 369
370 370 def test_index_csv_with_project
371 371 get :index, :project_id => 1, :format => 'csv'
372 372 assert_response :success
373 373 assert_not_nil assigns(:issues)
374 374 assert_equal 'text/csv; header=present', @response.content_type
375 375 end
376 376
377 377 def test_index_csv_with_description
378 378 get :index, :format => 'csv', :description => '1'
379 379 assert_response :success
380 380 assert_not_nil assigns(:issues)
381 381 assert_equal 'text/csv; header=present', @response.content_type
382 382 assert @response.body.starts_with?("#,")
383 383 lines = @response.body.chomp.split("\n")
384 384 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
385 385 end
386 386
387 387 def test_index_csv_with_spent_time_column
388 388 issue = Issue.create!(:project_id => 1, :tracker_id => 1, :subject => 'test_index_csv_with_spent_time_column', :author_id => 2)
389 389 TimeEntry.create!(:project => issue.project, :issue => issue, :hours => 7.33, :user => User.find(2), :spent_on => Date.today)
390 390
391 391 get :index, :format => 'csv', :set_filter => '1', :c => %w(subject spent_hours)
392 392 assert_response :success
393 393 assert_equal 'text/csv; header=present', @response.content_type
394 394 lines = @response.body.chomp.split("\n")
395 395 assert_include "#{issue.id},#{issue.subject},7.33", lines
396 396 end
397 397
398 398 def test_index_csv_with_all_columns
399 399 get :index, :format => 'csv', :columns => 'all'
400 400 assert_response :success
401 401 assert_not_nil assigns(:issues)
402 402 assert_equal 'text/csv; header=present', @response.content_type
403 403 assert @response.body.starts_with?("#,")
404 404 lines = @response.body.chomp.split("\n")
405 405 assert_equal assigns(:query).available_columns.size + 1, lines[0].split(',').size
406 406 end
407 407
408 408 def test_index_csv_with_multi_column_field
409 409 CustomField.find(1).update_attribute :multiple, true
410 410 issue = Issue.find(1)
411 411 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
412 412 issue.save!
413 413
414 414 get :index, :format => 'csv', :columns => 'all'
415 415 assert_response :success
416 416 lines = @response.body.chomp.split("\n")
417 417 assert lines.detect {|line| line.include?('"MySQL, Oracle"')}
418 418 end
419 419
420 420 def test_index_csv_big_5
421 421 with_settings :default_language => "zh-TW" do
422 422 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
423 423 str_big5 = "\xa4@\xa4\xeb"
424 424 if str_utf8.respond_to?(:force_encoding)
425 425 str_utf8.force_encoding('UTF-8')
426 426 str_big5.force_encoding('Big5')
427 427 end
428 428 issue = Issue.generate!(:subject => str_utf8)
429 429
430 430 get :index, :project_id => 1,
431 431 :f => ['subject'],
432 432 :op => '=', :values => [str_utf8],
433 433 :format => 'csv'
434 434 assert_equal 'text/csv; header=present', @response.content_type
435 435 lines = @response.body.chomp.split("\n")
436 436 s1 = "\xaa\xac\xbaA"
437 437 if str_utf8.respond_to?(:force_encoding)
438 438 s1.force_encoding('Big5')
439 439 end
440 440 assert lines[0].include?(s1)
441 441 assert lines[1].include?(str_big5)
442 442 end
443 443 end
444 444
445 445 def test_index_csv_cannot_convert_should_be_replaced_big_5
446 446 with_settings :default_language => "zh-TW" do
447 447 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
448 448 if str_utf8.respond_to?(:force_encoding)
449 449 str_utf8.force_encoding('UTF-8')
450 450 end
451 451 issue = Issue.generate!(:subject => str_utf8)
452 452
453 453 get :index, :project_id => 1,
454 454 :f => ['subject'],
455 455 :op => '=', :values => [str_utf8],
456 456 :c => ['status', 'subject'],
457 457 :format => 'csv',
458 458 :set_filter => 1
459 459 assert_equal 'text/csv; header=present', @response.content_type
460 460 lines = @response.body.chomp.split("\n")
461 461 s1 = "\xaa\xac\xbaA" # status
462 462 if str_utf8.respond_to?(:force_encoding)
463 463 s1.force_encoding('Big5')
464 464 end
465 465 assert lines[0].include?(s1)
466 466 s2 = lines[1].split(",")[2]
467 467 if s1.respond_to?(:force_encoding)
468 468 s3 = "\xa5H?" # subject
469 469 s3.force_encoding('Big5')
470 470 assert_equal s3, s2
471 471 elsif RUBY_PLATFORM == 'java'
472 472 assert_equal "??", s2
473 473 else
474 474 assert_equal "\xa5H???", s2
475 475 end
476 476 end
477 477 end
478 478
479 479 def test_index_csv_tw
480 480 with_settings :default_language => "zh-TW" do
481 481 str1 = "test_index_csv_tw"
482 482 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
483 483
484 484 get :index, :project_id => 1,
485 485 :f => ['subject'],
486 486 :op => '=', :values => [str1],
487 487 :c => ['estimated_hours', 'subject'],
488 488 :format => 'csv',
489 489 :set_filter => 1
490 490 assert_equal 'text/csv; header=present', @response.content_type
491 491 lines = @response.body.chomp.split("\n")
492 492 assert_equal "#{issue.id},1234.50,#{str1}", lines[1]
493 493 end
494 494 end
495 495
496 496 def test_index_csv_fr
497 497 with_settings :default_language => "fr" do
498 498 str1 = "test_index_csv_fr"
499 499 issue = Issue.generate!(:subject => str1, :estimated_hours => '1234.5')
500 500
501 501 get :index, :project_id => 1,
502 502 :f => ['subject'],
503 503 :op => '=', :values => [str1],
504 504 :c => ['estimated_hours', 'subject'],
505 505 :format => 'csv',
506 506 :set_filter => 1
507 507 assert_equal 'text/csv; header=present', @response.content_type
508 508 lines = @response.body.chomp.split("\n")
509 509 assert_equal "#{issue.id};1234,50;#{str1}", lines[1]
510 510 end
511 511 end
512 512
513 513 def test_index_pdf
514 514 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
515 515 with_settings :default_language => lang do
516 516
517 517 get :index
518 518 assert_response :success
519 519 assert_template 'index'
520 520
521 521 if lang == "ja"
522 522 if RUBY_PLATFORM != 'java'
523 523 assert_equal "CP932", l(:general_pdf_encoding)
524 524 end
525 525 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
526 526 next
527 527 end
528 528 end
529 529
530 530 get :index, :format => 'pdf'
531 531 assert_response :success
532 532 assert_not_nil assigns(:issues)
533 533 assert_equal 'application/pdf', @response.content_type
534 534
535 535 get :index, :project_id => 1, :format => 'pdf'
536 536 assert_response :success
537 537 assert_not_nil assigns(:issues)
538 538 assert_equal 'application/pdf', @response.content_type
539 539
540 540 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
541 541 assert_response :success
542 542 assert_not_nil assigns(:issues)
543 543 assert_equal 'application/pdf', @response.content_type
544 544 end
545 545 end
546 546 end
547 547
548 548 def test_index_pdf_with_query_grouped_by_list_custom_field
549 549 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
550 550 assert_response :success
551 551 assert_not_nil assigns(:issues)
552 552 assert_not_nil assigns(:issue_count_by_group)
553 553 assert_equal 'application/pdf', @response.content_type
554 554 end
555 555
556 556 def test_index_atom
557 557 get :index, :project_id => 'ecookbook', :format => 'atom'
558 558 assert_response :success
559 559 assert_template 'common/feed'
560 560 assert_equal 'application/atom+xml', response.content_type
561 561
562 562 assert_select 'feed' do
563 563 assert_select 'link[rel=self][href=?]', 'http://test.host/projects/ecookbook/issues.atom'
564 564 assert_select 'link[rel=alternate][href=?]', 'http://test.host/projects/ecookbook/issues'
565 565 assert_select 'entry link[href=?]', 'http://test.host/issues/1'
566 566 end
567 567 end
568 568
569 569 def test_index_sort
570 570 get :index, :sort => 'tracker,id:desc'
571 571 assert_response :success
572 572
573 573 sort_params = @request.session['issues_index_sort']
574 574 assert sort_params.is_a?(String)
575 575 assert_equal 'tracker,id:desc', sort_params
576 576
577 577 issues = assigns(:issues)
578 578 assert_not_nil issues
579 579 assert !issues.empty?
580 580 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
581 581 end
582 582
583 583 def test_index_sort_by_field_not_included_in_columns
584 584 Setting.issue_list_default_columns = %w(subject author)
585 585 get :index, :sort => 'tracker'
586 586 end
587 587
588 588 def test_index_sort_by_assigned_to
589 589 get :index, :sort => 'assigned_to'
590 590 assert_response :success
591 591 assignees = assigns(:issues).collect(&:assigned_to).compact
592 592 assert_equal assignees.sort, assignees
593 593 end
594 594
595 595 def test_index_sort_by_assigned_to_desc
596 596 get :index, :sort => 'assigned_to:desc'
597 597 assert_response :success
598 598 assignees = assigns(:issues).collect(&:assigned_to).compact
599 599 assert_equal assignees.sort.reverse, assignees
600 600 end
601 601
602 602 def test_index_group_by_assigned_to
603 603 get :index, :group_by => 'assigned_to', :sort => 'priority'
604 604 assert_response :success
605 605 end
606 606
607 607 def test_index_sort_by_author
608 608 get :index, :sort => 'author'
609 609 assert_response :success
610 610 authors = assigns(:issues).collect(&:author)
611 611 assert_equal authors.sort, authors
612 612 end
613 613
614 614 def test_index_sort_by_author_desc
615 615 get :index, :sort => 'author:desc'
616 616 assert_response :success
617 617 authors = assigns(:issues).collect(&:author)
618 618 assert_equal authors.sort.reverse, authors
619 619 end
620 620
621 621 def test_index_group_by_author
622 622 get :index, :group_by => 'author', :sort => 'priority'
623 623 assert_response :success
624 624 end
625 625
626 626 def test_index_sort_by_spent_hours
627 627 get :index, :sort => 'spent_hours:desc'
628 628 assert_response :success
629 629 hours = assigns(:issues).collect(&:spent_hours)
630 630 assert_equal hours.sort.reverse, hours
631 631 end
632 632
633 633 def test_index_sort_by_user_custom_field
634 634 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
635 635 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
636 636 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
637 637 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
638 638 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
639 639
640 640 get :index, :project_id => 1, :set_filter => 1, :sort => "cf_#{cf.id},id"
641 641 assert_response :success
642 642
643 643 assert_equal [2, 3, 1], assigns(:issues).select {|issue| issue.custom_field_value(cf).present?}.map(&:id)
644 644 end
645 645
646 646 def test_index_with_columns
647 647 columns = ['tracker', 'subject', 'assigned_to']
648 648 get :index, :set_filter => 1, :c => columns
649 649 assert_response :success
650 650
651 651 # query should use specified columns
652 652 query = assigns(:query)
653 653 assert_kind_of Query, query
654 654 assert_equal columns, query.column_names.map(&:to_s)
655 655
656 656 # columns should be stored in session
657 657 assert_kind_of Hash, session[:query]
658 658 assert_kind_of Array, session[:query][:column_names]
659 659 assert_equal columns, session[:query][:column_names].map(&:to_s)
660 660
661 661 # ensure only these columns are kept in the selected columns list
662 662 assert_select 'select#selected_columns option' do
663 663 assert_select 'option', 3
664 664 assert_select 'option[value=tracker]'
665 665 assert_select 'option[value=project]', 0
666 666 end
667 667 end
668 668
669 669 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
670 670 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
671 671 get :index, :set_filter => 1
672 672
673 673 # query should use specified columns
674 674 query = assigns(:query)
675 675 assert_kind_of Query, query
676 676 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
677 677 end
678 678
679 679 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
680 680 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
681 681 columns = ['tracker', 'subject', 'assigned_to']
682 682 get :index, :set_filter => 1, :c => columns
683 683
684 684 # query should use specified columns
685 685 query = assigns(:query)
686 686 assert_kind_of Query, query
687 687 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
688 688 end
689 689
690 690 def test_index_with_custom_field_column
691 691 columns = %w(tracker subject cf_2)
692 692 get :index, :set_filter => 1, :c => columns
693 693 assert_response :success
694 694
695 695 # query should use specified columns
696 696 query = assigns(:query)
697 697 assert_kind_of Query, query
698 698 assert_equal columns, query.column_names.map(&:to_s)
699 699
700 700 assert_select 'table.issues td.cf_2.string'
701 701 end
702 702
703 703 def test_index_with_multi_custom_field_column
704 704 field = CustomField.find(1)
705 705 field.update_attribute :multiple, true
706 706 issue = Issue.find(1)
707 707 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
708 708 issue.save!
709 709
710 710 get :index, :set_filter => 1, :c => %w(tracker subject cf_1)
711 711 assert_response :success
712 712
713 713 assert_select 'table.issues td.cf_1', :text => 'MySQL, Oracle'
714 714 end
715 715
716 716 def test_index_with_multi_user_custom_field_column
717 717 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
718 718 :tracker_ids => [1], :is_for_all => true)
719 719 issue = Issue.find(1)
720 720 issue.custom_field_values = {field.id => ['2', '3']}
721 721 issue.save!
722 722
723 723 get :index, :set_filter => 1, :c => ['tracker', 'subject', "cf_#{field.id}"]
724 724 assert_response :success
725 725
726 726 assert_select "table.issues td.cf_#{field.id}" do
727 727 assert_select 'a', 2
728 728 assert_select 'a[href=?]', '/users/2', :text => 'John Smith'
729 729 assert_select 'a[href=?]', '/users/3', :text => 'Dave Lopper'
730 730 end
731 731 end
732 732
733 733 def test_index_with_date_column
734 734 with_settings :date_format => '%d/%m/%Y' do
735 735 Issue.find(1).update_attribute :start_date, '1987-08-24'
736 736
737 737 get :index, :set_filter => 1, :c => %w(start_date)
738 738
739 739 assert_select "table.issues td.start_date", :text => '24/08/1987'
740 740 end
741 741 end
742 742
743 743 def test_index_with_done_ratio_column
744 744 Issue.find(1).update_attribute :done_ratio, 40
745 745
746 746 get :index, :set_filter => 1, :c => %w(done_ratio)
747 747
748 748 assert_select 'table.issues td.done_ratio' do
749 749 assert_select 'table.progress' do
750 750 assert_select 'td.closed[style=?]', 'width: 40%;'
751 751 end
752 752 end
753 753 end
754 754
755 755 def test_index_with_spent_hours_column
756 756 get :index, :set_filter => 1, :c => %w(subject spent_hours)
757 757
758 758 assert_select 'table.issues tr#issue-3 td.spent_hours', :text => '1.00'
759 759 end
760 760
761 761 def test_index_should_not_show_spent_hours_column_without_permission
762 762 Role.anonymous.remove_permission! :view_time_entries
763 763 get :index, :set_filter => 1, :c => %w(subject spent_hours)
764 764
765 765 assert_select 'td.spent_hours', 0
766 766 end
767 767
768 768 def test_index_with_fixed_version_column
769 769 get :index, :set_filter => 1, :c => %w(fixed_version)
770 770
771 771 assert_select 'table.issues td.fixed_version' do
772 772 assert_select 'a[href=?]', '/versions/2', :text => '1.0'
773 773 end
774 774 end
775 775
776 776 def test_index_with_relations_column
777 777 IssueRelation.delete_all
778 778 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(7))
779 779 IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(8), :issue_to => Issue.find(1))
780 780 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(1), :issue_to => Issue.find(11))
781 781 IssueRelation.create!(:relation_type => "blocks", :issue_from => Issue.find(12), :issue_to => Issue.find(2))
782 782
783 783 get :index, :set_filter => 1, :c => %w(subject relations)
784 784 assert_response :success
785 785 assert_select "tr#issue-1 td.relations" do
786 786 assert_select "span", 3
787 787 assert_select "span", :text => "Related to #7"
788 788 assert_select "span", :text => "Related to #8"
789 789 assert_select "span", :text => "Blocks #11"
790 790 end
791 791 assert_select "tr#issue-2 td.relations" do
792 792 assert_select "span", 1
793 793 assert_select "span", :text => "Blocked by #12"
794 794 end
795 795 assert_select "tr#issue-3 td.relations" do
796 796 assert_select "span", 0
797 797 end
798 798
799 799 get :index, :set_filter => 1, :c => %w(relations), :format => 'csv'
800 800 assert_response :success
801 801 assert_equal 'text/csv; header=present', response.content_type
802 802 lines = response.body.chomp.split("\n")
803 803 assert_include '1,"Related to #7, Related to #8, Blocks #11"', lines
804 804 assert_include '2,Blocked by #12', lines
805 805 assert_include '3,""', lines
806 806
807 807 get :index, :set_filter => 1, :c => %w(subject relations), :format => 'pdf'
808 808 assert_response :success
809 809 assert_equal 'application/pdf', response.content_type
810 810 end
811 811
812 812 def test_index_send_html_if_query_is_invalid
813 813 get :index, :f => ['start_date'], :op => {:start_date => '='}
814 814 assert_equal 'text/html', @response.content_type
815 815 assert_template 'index'
816 816 end
817 817
818 818 def test_index_send_nothing_if_query_is_invalid
819 819 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
820 820 assert_equal 'text/csv', @response.content_type
821 821 assert @response.body.blank?
822 822 end
823 823
824 824 def test_show_by_anonymous
825 825 get :show, :id => 1
826 826 assert_response :success
827 827 assert_template 'show'
828 828 assert_equal Issue.find(1), assigns(:issue)
829 829
830 830 # anonymous role is allowed to add a note
831 831 assert_select 'form#issue-form' do
832 832 assert_select 'fieldset' do
833 833 assert_select 'legend', :text => 'Notes'
834 834 assert_select 'textarea[name=?]', 'issue[notes]'
835 835 end
836 836 end
837 837
838 838 assert_select 'title', :text => "Bug #1: Can&#x27;t print recipes - eCookbook - Redmine"
839 839 end
840 840
841 841 def test_show_by_manager
842 842 @request.session[:user_id] = 2
843 843 get :show, :id => 1
844 844 assert_response :success
845 845
846 846 assert_select 'a', :text => /Quote/
847 847
848 848 assert_select 'form#issue-form' do
849 849 assert_select 'fieldset' do
850 850 assert_select 'legend', :text => 'Change properties'
851 851 assert_select 'input[name=?]', 'issue[subject]'
852 852 end
853 853 assert_select 'fieldset' do
854 854 assert_select 'legend', :text => 'Log time'
855 855 assert_select 'input[name=?]', 'time_entry[hours]'
856 856 end
857 857 assert_select 'fieldset' do
858 858 assert_select 'legend', :text => 'Notes'
859 859 assert_select 'textarea[name=?]', 'issue[notes]'
860 860 end
861 861 end
862 862 end
863 863
864 864 def test_show_should_display_update_form
865 865 @request.session[:user_id] = 2
866 866 get :show, :id => 1
867 867 assert_response :success
868 868
869 869 assert_tag 'form', :attributes => {:id => 'issue-form'}
870 870 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
871 871 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
872 872 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
873 873 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
874 874 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
875 875 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
876 876 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
877 877 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
878 878 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
879 879 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
880 880 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
881 881 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
882 882 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
883 883 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
884 884 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
885 885 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
886 886 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
887 887 end
888 888
889 889 def test_show_should_display_update_form_with_minimal_permissions
890 890 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
891 891 WorkflowTransition.delete_all :role_id => 1
892 892
893 893 @request.session[:user_id] = 2
894 894 get :show, :id => 1
895 895 assert_response :success
896 896
897 897 assert_tag 'form', :attributes => {:id => 'issue-form'}
898 898 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
899 899 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
900 900 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
901 901 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
902 902 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
903 903 assert_no_tag 'select', :attributes => {:name => 'issue[status_id]'}
904 904 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
905 905 assert_no_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
906 906 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
907 907 assert_no_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
908 908 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
909 909 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
910 910 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
911 911 assert_no_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
912 912 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
913 913 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
914 914 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
915 915 end
916 916
917 917 def test_show_should_display_update_form_with_workflow_permissions
918 918 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
919 919
920 920 @request.session[:user_id] = 2
921 921 get :show, :id => 1
922 922 assert_response :success
923 923
924 924 assert_tag 'form', :attributes => {:id => 'issue-form'}
925 925 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
926 926 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
927 927 assert_no_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
928 928 assert_no_tag 'input', :attributes => {:name => 'issue[subject]'}
929 929 assert_no_tag 'textarea', :attributes => {:name => 'issue[description]'}
930 930 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
931 931 assert_no_tag 'select', :attributes => {:name => 'issue[priority_id]'}
932 932 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
933 933 assert_no_tag 'select', :attributes => {:name => 'issue[category_id]'}
934 934 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
935 935 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
936 936 assert_no_tag 'input', :attributes => {:name => 'issue[start_date]'}
937 937 assert_no_tag 'input', :attributes => {:name => 'issue[due_date]'}
938 938 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
939 939 assert_no_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]' }
940 940 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
941 941 assert_tag 'textarea', :attributes => {:name => 'issue[notes]'}
942 942 end
943 943
944 944 def test_show_should_not_display_update_form_without_permissions
945 945 Role.find(1).update_attribute :permissions, [:view_issues]
946 946
947 947 @request.session[:user_id] = 2
948 948 get :show, :id => 1
949 949 assert_response :success
950 950
951 951 assert_select 'form#issue-form', 0
952 952 end
953 953
954 954 def test_update_form_should_not_display_inactive_enumerations
955 955 assert !IssuePriority.find(15).active?
956 956
957 957 @request.session[:user_id] = 2
958 958 get :show, :id => 1
959 959 assert_response :success
960 960
961 961 assert_select 'form#issue-form' do
962 962 assert_select 'select[name=?]', 'issue[priority_id]' do
963 963 assert_select 'option[value=4]'
964 964 assert_select 'option[value=15]', 0
965 965 end
966 966 end
967 967 end
968 968
969 969 def test_update_form_should_allow_attachment_upload
970 970 @request.session[:user_id] = 2
971 971 get :show, :id => 1
972 972
973 973 assert_select 'form#issue-form[method=post][enctype=multipart/form-data]' do
974 974 assert_select 'input[type=file][name=?]', 'attachments[1][file]'
975 975 end
976 976 end
977 977
978 978 def test_show_should_deny_anonymous_access_without_permission
979 979 Role.anonymous.remove_permission!(:view_issues)
980 980 get :show, :id => 1
981 981 assert_response :redirect
982 982 end
983 983
984 984 def test_show_should_deny_anonymous_access_to_private_issue
985 985 Issue.update_all(["is_private = ?", true], "id = 1")
986 986 get :show, :id => 1
987 987 assert_response :redirect
988 988 end
989 989
990 990 def test_show_should_deny_non_member_access_without_permission
991 991 Role.non_member.remove_permission!(:view_issues)
992 992 @request.session[:user_id] = 9
993 993 get :show, :id => 1
994 994 assert_response 403
995 995 end
996 996
997 997 def test_show_should_deny_non_member_access_to_private_issue
998 998 Issue.update_all(["is_private = ?", true], "id = 1")
999 999 @request.session[:user_id] = 9
1000 1000 get :show, :id => 1
1001 1001 assert_response 403
1002 1002 end
1003 1003
1004 1004 def test_show_should_deny_member_access_without_permission
1005 1005 Role.find(1).remove_permission!(:view_issues)
1006 1006 @request.session[:user_id] = 2
1007 1007 get :show, :id => 1
1008 1008 assert_response 403
1009 1009 end
1010 1010
1011 1011 def test_show_should_deny_member_access_to_private_issue_without_permission
1012 1012 Issue.update_all(["is_private = ?", true], "id = 1")
1013 1013 @request.session[:user_id] = 3
1014 1014 get :show, :id => 1
1015 1015 assert_response 403
1016 1016 end
1017 1017
1018 1018 def test_show_should_allow_author_access_to_private_issue
1019 1019 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
1020 1020 @request.session[:user_id] = 3
1021 1021 get :show, :id => 1
1022 1022 assert_response :success
1023 1023 end
1024 1024
1025 1025 def test_show_should_allow_assignee_access_to_private_issue
1026 1026 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
1027 1027 @request.session[:user_id] = 3
1028 1028 get :show, :id => 1
1029 1029 assert_response :success
1030 1030 end
1031 1031
1032 1032 def test_show_should_allow_member_access_to_private_issue_with_permission
1033 1033 Issue.update_all(["is_private = ?", true], "id = 1")
1034 1034 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1035 1035 @request.session[:user_id] = 3
1036 1036 get :show, :id => 1
1037 1037 assert_response :success
1038 1038 end
1039 1039
1040 1040 def test_show_should_not_disclose_relations_to_invisible_issues
1041 1041 Setting.cross_project_issue_relations = '1'
1042 1042 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1043 1043 # Relation to a private project issue
1044 1044 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1045 1045
1046 1046 get :show, :id => 1
1047 1047 assert_response :success
1048 1048
1049 1049 assert_select 'div#relations' do
1050 1050 assert_select 'a', :text => /#2$/
1051 1051 assert_select 'a', :text => /#4$/, :count => 0
1052 1052 end
1053 1053 end
1054 1054
1055 1055 def test_show_should_list_subtasks
1056 1056 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1057 1057
1058 1058 get :show, :id => 1
1059 1059 assert_response :success
1060 1060
1061 1061 assert_select 'div#issue_tree' do
1062 1062 assert_select 'td.subject', :text => /Child Issue/
1063 1063 end
1064 1064 end
1065 1065
1066 1066 def test_show_should_list_parents
1067 1067 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1068 1068
1069 1069 get :show, :id => issue.id
1070 1070 assert_response :success
1071 1071
1072 1072 assert_select 'div.subject' do
1073 1073 assert_select 'h3', 'Child Issue'
1074 1074 assert_select 'a[href=/issues/1]'
1075 1075 end
1076 1076 end
1077 1077
1078 1078 def test_show_should_not_display_prev_next_links_without_query_in_session
1079 1079 get :show, :id => 1
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_select 'div.next-prev-links', 0
1085 1085 end
1086 1086
1087 1087 def test_show_should_display_prev_next_links_with_query_in_session
1088 1088 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1089 1089 @request.session['issues_index_sort'] = 'id'
1090 1090
1091 1091 with_settings :display_subprojects_issues => '0' do
1092 1092 get :show, :id => 3
1093 1093 end
1094 1094
1095 1095 assert_response :success
1096 1096 # Previous and next issues for all projects
1097 1097 assert_equal 2, assigns(:prev_issue_id)
1098 1098 assert_equal 5, assigns(:next_issue_id)
1099 1099
1100 1100 count = Issue.open.visible.count
1101 1101
1102 1102 assert_select 'div.next-prev-links' do
1103 1103 assert_select 'a[href=/issues/2]', :text => /Previous/
1104 1104 assert_select 'a[href=/issues/5]', :text => /Next/
1105 1105 assert_select 'span.position', :text => "3 of #{count}"
1106 1106 end
1107 1107 end
1108 1108
1109 1109 def test_show_should_display_prev_next_links_with_saved_query_in_session
1110 1110 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1,
1111 1111 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1112 1112 :sort_criteria => [['id', 'asc']])
1113 1113 @request.session[:query] = {:id => query.id, :project_id => nil}
1114 1114
1115 1115 get :show, :id => 11
1116 1116
1117 1117 assert_response :success
1118 1118 assert_equal query, assigns(:query)
1119 1119 # Previous and next issues for all projects
1120 1120 assert_equal 8, assigns(:prev_issue_id)
1121 1121 assert_equal 12, assigns(:next_issue_id)
1122 1122
1123 1123 assert_select 'div.next-prev-links' do
1124 1124 assert_select 'a[href=/issues/8]', :text => /Previous/
1125 1125 assert_select 'a[href=/issues/12]', :text => /Next/
1126 1126 end
1127 1127 end
1128 1128
1129 1129 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1130 1130 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1131 1131
1132 1132 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1133 1133 @request.session['issues_index_sort'] = assoc_sort
1134 1134
1135 1135 get :show, :id => 3
1136 1136 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1137 1137
1138 1138 assert_select 'div.next-prev-links' do
1139 assert_select 'a', :text => /Previous/
1140 assert_select 'a', :text => /Next/
1139 assert_select 'a', :text => /(Previous|Next)/
1141 1140 end
1142 1141 end
1143 1142 end
1144 1143
1145 1144 def test_show_should_display_prev_next_links_with_project_query_in_session
1146 1145 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1147 1146 @request.session['issues_index_sort'] = 'id'
1148 1147
1149 1148 with_settings :display_subprojects_issues => '0' do
1150 1149 get :show, :id => 3
1151 1150 end
1152 1151
1153 1152 assert_response :success
1154 1153 # Previous and next issues inside project
1155 1154 assert_equal 2, assigns(:prev_issue_id)
1156 1155 assert_equal 7, assigns(:next_issue_id)
1157 1156
1158 1157 assert_select 'div.next-prev-links' do
1159 1158 assert_select 'a[href=/issues/2]', :text => /Previous/
1160 1159 assert_select 'a[href=/issues/7]', :text => /Next/
1161 1160 end
1162 1161 end
1163 1162
1164 1163 def test_show_should_not_display_prev_link_for_first_issue
1165 1164 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1166 1165 @request.session['issues_index_sort'] = 'id'
1167 1166
1168 1167 with_settings :display_subprojects_issues => '0' do
1169 1168 get :show, :id => 1
1170 1169 end
1171 1170
1172 1171 assert_response :success
1173 1172 assert_nil assigns(:prev_issue_id)
1174 1173 assert_equal 2, assigns(:next_issue_id)
1175 1174
1176 1175 assert_select 'div.next-prev-links' do
1177 1176 assert_select 'a', :text => /Previous/, :count => 0
1178 1177 assert_select 'a[href=/issues/2]', :text => /Next/
1179 1178 end
1180 1179 end
1181 1180
1182 1181 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1183 1182 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1184 1183 @request.session['issues_index_sort'] = 'id'
1185 1184
1186 1185 get :show, :id => 1
1187 1186
1188 1187 assert_response :success
1189 1188 assert_nil assigns(:prev_issue_id)
1190 1189 assert_nil assigns(:next_issue_id)
1191 1190
1192 1191 assert_select 'a', :text => /Previous/, :count => 0
1193 1192 assert_select 'a', :text => /Next/, :count => 0
1194 1193 end
1195 1194
1196 1195 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1197 1196 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1198 1197 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1199 1198 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1200 1199 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1201 1200 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1202 1201
1203 1202 query = Query.create!(:name => 'test', :is_public => true, :user_id => 1, :filters => {},
1204 1203 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1205 1204 @request.session[:query] = {:id => query.id, :project_id => nil}
1206 1205
1207 1206 get :show, :id => 3
1208 1207 assert_response :success
1209 1208
1210 1209 assert_equal 2, assigns(:prev_issue_id)
1211 1210 assert_equal 1, assigns(:next_issue_id)
1212 1211
1213 1212 assert_select 'div.next-prev-links' do
1214 1213 assert_select 'a[href=/issues/2]', :text => /Previous/
1215 1214 assert_select 'a[href=/issues/1]', :text => /Next/
1216 1215 end
1217 1216 end
1218 1217
1219 1218 def test_show_should_display_link_to_the_assignee
1220 1219 get :show, :id => 2
1221 1220 assert_response :success
1222 1221 assert_select '.assigned-to' do
1223 1222 assert_select 'a[href=/users/3]'
1224 1223 end
1225 1224 end
1226 1225
1227 1226 def test_show_should_display_visible_changesets_from_other_projects
1228 1227 project = Project.find(2)
1229 1228 issue = project.issues.first
1230 1229 issue.changeset_ids = [102]
1231 1230 issue.save!
1232 1231 # changesets from other projects should be displayed even if repository
1233 1232 # is disabled on issue's project
1234 1233 project.disable_module! :repository
1235 1234
1236 1235 @request.session[:user_id] = 2
1237 1236 get :show, :id => issue.id
1238 1237
1239 1238 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1240 1239 end
1241 1240
1242 1241 def test_show_should_display_watchers
1243 1242 @request.session[:user_id] = 2
1244 1243 Issue.find(1).add_watcher User.find(2)
1245 1244
1246 1245 get :show, :id => 1
1247 1246 assert_select 'div#watchers ul' do
1248 1247 assert_select 'li' do
1249 1248 assert_select 'a[href=/users/2]'
1250 1249 assert_select 'a img[alt=Delete]'
1251 1250 end
1252 1251 end
1253 1252 end
1254 1253
1255 1254 def test_show_should_display_watchers_with_gravatars
1256 1255 @request.session[:user_id] = 2
1257 1256 Issue.find(1).add_watcher User.find(2)
1258 1257
1259 1258 with_settings :gravatar_enabled => '1' do
1260 1259 get :show, :id => 1
1261 1260 end
1262 1261
1263 1262 assert_select 'div#watchers ul' do
1264 1263 assert_select 'li' do
1265 1264 assert_select 'img.gravatar'
1266 1265 assert_select 'a[href=/users/2]'
1267 1266 assert_select 'a img[alt=Delete]'
1268 1267 end
1269 1268 end
1270 1269 end
1271 1270
1272 1271 def test_show_with_thumbnails_enabled_should_display_thumbnails
1273 1272 @request.session[:user_id] = 2
1274 1273
1275 1274 with_settings :thumbnails_enabled => '1' do
1276 1275 get :show, :id => 14
1277 1276 assert_response :success
1278 1277 end
1279 1278
1280 1279 assert_select 'div.thumbnails' do
1281 1280 assert_select 'a[href=/attachments/16/testfile.png]' do
1282 1281 assert_select 'img[src=/attachments/thumbnail/16]'
1283 1282 end
1284 1283 end
1285 1284 end
1286 1285
1287 1286 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1288 1287 @request.session[:user_id] = 2
1289 1288
1290 1289 with_settings :thumbnails_enabled => '0' do
1291 1290 get :show, :id => 14
1292 1291 assert_response :success
1293 1292 end
1294 1293
1295 1294 assert_select 'div.thumbnails', 0
1296 1295 end
1297 1296
1298 1297 def test_show_with_multi_custom_field
1299 1298 field = CustomField.find(1)
1300 1299 field.update_attribute :multiple, true
1301 1300 issue = Issue.find(1)
1302 1301 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1303 1302 issue.save!
1304 1303
1305 1304 get :show, :id => 1
1306 1305 assert_response :success
1307 1306
1308 1307 assert_select 'td', :text => 'MySQL, Oracle'
1309 1308 end
1310 1309
1311 1310 def test_show_with_multi_user_custom_field
1312 1311 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1313 1312 :tracker_ids => [1], :is_for_all => true)
1314 1313 issue = Issue.find(1)
1315 1314 issue.custom_field_values = {field.id => ['2', '3']}
1316 1315 issue.save!
1317 1316
1318 1317 get :show, :id => 1
1319 1318 assert_response :success
1320 1319
1321 1320 # TODO: should display links
1322 1321 assert_select 'td', :text => 'Dave Lopper, John Smith'
1323 1322 end
1324 1323
1325 1324 def test_show_should_display_private_notes_with_permission_only
1326 1325 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1327 1326 @request.session[:user_id] = 2
1328 1327
1329 1328 get :show, :id => 2
1330 1329 assert_response :success
1331 1330 assert_include journal, assigns(:journals)
1332 1331
1333 1332 Role.find(1).remove_permission! :view_private_notes
1334 1333 get :show, :id => 2
1335 1334 assert_response :success
1336 1335 assert_not_include journal, assigns(:journals)
1337 1336 end
1338 1337
1339 1338 def test_show_atom
1340 1339 get :show, :id => 2, :format => 'atom'
1341 1340 assert_response :success
1342 1341 assert_template 'journals/index'
1343 1342 # Inline image
1344 1343 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1345 1344 end
1346 1345
1347 1346 def test_show_export_to_pdf
1348 1347 get :show, :id => 3, :format => 'pdf'
1349 1348 assert_response :success
1350 1349 assert_equal 'application/pdf', @response.content_type
1351 1350 assert @response.body.starts_with?('%PDF')
1352 1351 assert_not_nil assigns(:issue)
1353 1352 end
1354 1353
1355 1354 def test_show_export_to_pdf_with_ancestors
1356 1355 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1357 1356
1358 1357 get :show, :id => issue.id, :format => 'pdf'
1359 1358 assert_response :success
1360 1359 assert_equal 'application/pdf', @response.content_type
1361 1360 assert @response.body.starts_with?('%PDF')
1362 1361 end
1363 1362
1364 1363 def test_show_export_to_pdf_with_descendants
1365 1364 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1366 1365 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1367 1366 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1368 1367
1369 1368 get :show, :id => 1, :format => 'pdf'
1370 1369 assert_response :success
1371 1370 assert_equal 'application/pdf', @response.content_type
1372 1371 assert @response.body.starts_with?('%PDF')
1373 1372 end
1374 1373
1375 1374 def test_show_export_to_pdf_with_journals
1376 1375 get :show, :id => 1, :format => 'pdf'
1377 1376 assert_response :success
1378 1377 assert_equal 'application/pdf', @response.content_type
1379 1378 assert @response.body.starts_with?('%PDF')
1380 1379 end
1381 1380
1382 1381 def test_show_export_to_pdf_with_changesets
1383 1382 Issue.find(3).changesets = Changeset.find_all_by_id(100, 101, 102)
1384 1383
1385 1384 get :show, :id => 3, :format => 'pdf'
1386 1385 assert_response :success
1387 1386 assert_equal 'application/pdf', @response.content_type
1388 1387 assert @response.body.starts_with?('%PDF')
1389 1388 end
1390 1389
1391 1390 def test_get_new
1392 1391 @request.session[:user_id] = 2
1393 1392 get :new, :project_id => 1, :tracker_id => 1
1394 1393 assert_response :success
1395 1394 assert_template 'new'
1396 1395
1397 1396 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
1398 1397 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1399 1398 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1400 1399 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1401 1400 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1402 1401 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1403 1402 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1404 1403 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1405 1404 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1406 1405 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1407 1406 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1408 1407 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1409 1408 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1410 1409 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1411 1410 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1412 1411 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1413 1412
1414 1413 # Be sure we don't display inactive IssuePriorities
1415 1414 assert ! IssuePriority.find(15).active?
1416 1415 assert_no_tag :option, :attributes => {:value => '15'},
1417 1416 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1418 1417 end
1419 1418
1420 1419 def test_get_new_with_minimal_permissions
1421 1420 Role.find(1).update_attribute :permissions, [:add_issues]
1422 1421 WorkflowTransition.delete_all :role_id => 1
1423 1422
1424 1423 @request.session[:user_id] = 2
1425 1424 get :new, :project_id => 1, :tracker_id => 1
1426 1425 assert_response :success
1427 1426 assert_template 'new'
1428 1427
1429 1428 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
1430 1429 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1431 1430 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1432 1431 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1433 1432 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1434 1433 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1435 1434 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1436 1435 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1437 1436 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1438 1437 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1439 1438 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1440 1439 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1441 1440 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1442 1441 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1443 1442 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1444 1443 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1445 1444 end
1446 1445
1447 1446 def test_get_new_with_list_custom_field
1448 1447 @request.session[:user_id] = 2
1449 1448 get :new, :project_id => 1, :tracker_id => 1
1450 1449 assert_response :success
1451 1450 assert_template 'new'
1452 1451
1453 1452 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1454 1453 assert_select 'option', 4
1455 1454 assert_select 'option[value=MySQL]', :text => 'MySQL'
1456 1455 end
1457 1456 end
1458 1457
1459 1458 def test_get_new_with_multi_custom_field
1460 1459 field = IssueCustomField.find(1)
1461 1460 field.update_attribute :multiple, true
1462 1461
1463 1462 @request.session[:user_id] = 2
1464 1463 get :new, :project_id => 1, :tracker_id => 1
1465 1464 assert_response :success
1466 1465 assert_template 'new'
1467 1466
1468 1467 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1469 1468 assert_select 'option', 3
1470 1469 assert_select 'option[value=MySQL]', :text => 'MySQL'
1471 1470 end
1472 1471 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1473 1472 end
1474 1473
1475 1474 def test_get_new_with_multi_user_custom_field
1476 1475 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1477 1476 :tracker_ids => [1], :is_for_all => true)
1478 1477
1479 1478 @request.session[:user_id] = 2
1480 1479 get :new, :project_id => 1, :tracker_id => 1
1481 1480 assert_response :success
1482 1481 assert_template 'new'
1483 1482
1484 1483 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1485 1484 assert_select 'option', Project.find(1).users.count
1486 1485 assert_select 'option[value=2]', :text => 'John Smith'
1487 1486 end
1488 1487 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1489 1488 end
1490 1489
1491 1490 def test_get_new_with_date_custom_field
1492 1491 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1493 1492
1494 1493 @request.session[:user_id] = 2
1495 1494 get :new, :project_id => 1, :tracker_id => 1
1496 1495 assert_response :success
1497 1496
1498 1497 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1499 1498 end
1500 1499
1501 1500 def test_get_new_with_text_custom_field
1502 1501 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1503 1502
1504 1503 @request.session[:user_id] = 2
1505 1504 get :new, :project_id => 1, :tracker_id => 1
1506 1505 assert_response :success
1507 1506
1508 1507 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1509 1508 end
1510 1509
1511 1510 def test_get_new_without_default_start_date_is_creation_date
1512 1511 Setting.default_issue_start_date_to_creation_date = 0
1513 1512
1514 1513 @request.session[:user_id] = 2
1515 1514 get :new, :project_id => 1, :tracker_id => 1
1516 1515 assert_response :success
1517 1516 assert_template 'new'
1518 1517
1519 1518 assert_select 'input[name=?]', 'issue[start_date]'
1520 1519 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1521 1520 end
1522 1521
1523 1522 def test_get_new_with_default_start_date_is_creation_date
1524 1523 Setting.default_issue_start_date_to_creation_date = 1
1525 1524
1526 1525 @request.session[:user_id] = 2
1527 1526 get :new, :project_id => 1, :tracker_id => 1
1528 1527 assert_response :success
1529 1528 assert_template 'new'
1530 1529
1531 1530 assert_select 'input[name=?][value=?]', 'issue[start_date]', Date.today.to_s
1532 1531 end
1533 1532
1534 1533 def test_get_new_form_should_allow_attachment_upload
1535 1534 @request.session[:user_id] = 2
1536 1535 get :new, :project_id => 1, :tracker_id => 1
1537 1536
1538 1537 assert_select 'form[id=issue-form][method=post][enctype=multipart/form-data]' do
1539 1538 assert_select 'input[name=?][type=file]', 'attachments[1][file]'
1540 1539 assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
1541 1540 end
1542 1541 end
1543 1542
1544 1543 def test_get_new_should_prefill_the_form_from_params
1545 1544 @request.session[:user_id] = 2
1546 1545 get :new, :project_id => 1,
1547 1546 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1548 1547
1549 1548 issue = assigns(:issue)
1550 1549 assert_equal 3, issue.tracker_id
1551 1550 assert_equal 'Prefilled', issue.description
1552 1551 assert_equal 'Custom field value', issue.custom_field_value(2)
1553 1552
1554 1553 assert_select 'select[name=?]', 'issue[tracker_id]' do
1555 1554 assert_select 'option[value=3][selected=selected]'
1556 1555 end
1557 1556 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1558 1557 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1559 1558 end
1560 1559
1561 1560 def test_get_new_should_mark_required_fields
1562 1561 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1563 1562 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1564 1563 WorkflowPermission.delete_all
1565 1564 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1566 1565 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1567 1566 @request.session[:user_id] = 2
1568 1567
1569 1568 get :new, :project_id => 1
1570 1569 assert_response :success
1571 1570 assert_template 'new'
1572 1571
1573 1572 assert_select 'label[for=issue_start_date]' do
1574 1573 assert_select 'span[class=required]', 0
1575 1574 end
1576 1575 assert_select 'label[for=issue_due_date]' do
1577 1576 assert_select 'span[class=required]'
1578 1577 end
1579 1578 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1580 1579 assert_select 'span[class=required]', 0
1581 1580 end
1582 1581 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1583 1582 assert_select 'span[class=required]'
1584 1583 end
1585 1584 end
1586 1585
1587 1586 def test_get_new_should_not_display_readonly_fields
1588 1587 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1589 1588 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1590 1589 WorkflowPermission.delete_all
1591 1590 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1592 1591 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1593 1592 @request.session[:user_id] = 2
1594 1593
1595 1594 get :new, :project_id => 1
1596 1595 assert_response :success
1597 1596 assert_template 'new'
1598 1597
1599 1598 assert_select 'input[name=?]', 'issue[start_date]'
1600 1599 assert_select 'input[name=?]', 'issue[due_date]', 0
1601 1600 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1602 1601 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1603 1602 end
1604 1603
1605 1604 def test_get_new_without_tracker_id
1606 1605 @request.session[:user_id] = 2
1607 1606 get :new, :project_id => 1
1608 1607 assert_response :success
1609 1608 assert_template 'new'
1610 1609
1611 1610 issue = assigns(:issue)
1612 1611 assert_not_nil issue
1613 1612 assert_equal Project.find(1).trackers.first, issue.tracker
1614 1613 end
1615 1614
1616 1615 def test_get_new_with_no_default_status_should_display_an_error
1617 1616 @request.session[:user_id] = 2
1618 1617 IssueStatus.delete_all
1619 1618
1620 1619 get :new, :project_id => 1
1621 1620 assert_response 500
1622 1621 assert_error_tag :content => /No default issue/
1623 1622 end
1624 1623
1625 1624 def test_get_new_with_no_tracker_should_display_an_error
1626 1625 @request.session[:user_id] = 2
1627 1626 Tracker.delete_all
1628 1627
1629 1628 get :new, :project_id => 1
1630 1629 assert_response 500
1631 1630 assert_error_tag :content => /No tracker/
1632 1631 end
1633 1632
1634 1633 def test_update_new_form
1635 1634 @request.session[:user_id] = 2
1636 1635 xhr :post, :new, :project_id => 1,
1637 1636 :issue => {:tracker_id => 2,
1638 1637 :subject => 'This is the test_new issue',
1639 1638 :description => 'This is the description',
1640 1639 :priority_id => 5}
1641 1640 assert_response :success
1642 1641 assert_template 'update_form'
1643 1642 assert_template 'form'
1644 1643 assert_equal 'text/javascript', response.content_type
1645 1644
1646 1645 issue = assigns(:issue)
1647 1646 assert_kind_of Issue, issue
1648 1647 assert_equal 1, issue.project_id
1649 1648 assert_equal 2, issue.tracker_id
1650 1649 assert_equal 'This is the test_new issue', issue.subject
1651 1650 end
1652 1651
1653 1652 def test_update_new_form_should_propose_transitions_based_on_initial_status
1654 1653 @request.session[:user_id] = 2
1655 1654 WorkflowTransition.delete_all
1656 1655 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1657 1656 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1658 1657 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1659 1658
1660 1659 xhr :post, :new, :project_id => 1,
1661 1660 :issue => {:tracker_id => 1,
1662 1661 :status_id => 5,
1663 1662 :subject => 'This is an issue'}
1664 1663
1665 1664 assert_equal 5, assigns(:issue).status_id
1666 1665 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
1667 1666 end
1668 1667
1669 1668 def test_post_create
1670 1669 @request.session[:user_id] = 2
1671 1670 assert_difference 'Issue.count' do
1672 1671 post :create, :project_id => 1,
1673 1672 :issue => {:tracker_id => 3,
1674 1673 :status_id => 2,
1675 1674 :subject => 'This is the test_new issue',
1676 1675 :description => 'This is the description',
1677 1676 :priority_id => 5,
1678 1677 :start_date => '2010-11-07',
1679 1678 :estimated_hours => '',
1680 1679 :custom_field_values => {'2' => 'Value for field 2'}}
1681 1680 end
1682 1681 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1683 1682
1684 1683 issue = Issue.find_by_subject('This is the test_new issue')
1685 1684 assert_not_nil issue
1686 1685 assert_equal 2, issue.author_id
1687 1686 assert_equal 3, issue.tracker_id
1688 1687 assert_equal 2, issue.status_id
1689 1688 assert_equal Date.parse('2010-11-07'), issue.start_date
1690 1689 assert_nil issue.estimated_hours
1691 1690 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
1692 1691 assert_not_nil v
1693 1692 assert_equal 'Value for field 2', v.value
1694 1693 end
1695 1694
1696 1695 def test_post_new_with_group_assignment
1697 1696 group = Group.find(11)
1698 1697 project = Project.find(1)
1699 1698 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
1700 1699
1701 1700 with_settings :issue_group_assignment => '1' do
1702 1701 @request.session[:user_id] = 2
1703 1702 assert_difference 'Issue.count' do
1704 1703 post :create, :project_id => project.id,
1705 1704 :issue => {:tracker_id => 3,
1706 1705 :status_id => 1,
1707 1706 :subject => 'This is the test_new_with_group_assignment issue',
1708 1707 :assigned_to_id => group.id}
1709 1708 end
1710 1709 end
1711 1710 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1712 1711
1713 1712 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
1714 1713 assert_not_nil issue
1715 1714 assert_equal group, issue.assigned_to
1716 1715 end
1717 1716
1718 1717 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
1719 1718 Setting.default_issue_start_date_to_creation_date = 0
1720 1719
1721 1720 @request.session[:user_id] = 2
1722 1721 assert_difference 'Issue.count' do
1723 1722 post :create, :project_id => 1,
1724 1723 :issue => {:tracker_id => 3,
1725 1724 :status_id => 2,
1726 1725 :subject => 'This is the test_new issue',
1727 1726 :description => 'This is the description',
1728 1727 :priority_id => 5,
1729 1728 :estimated_hours => '',
1730 1729 :custom_field_values => {'2' => 'Value for field 2'}}
1731 1730 end
1732 1731 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1733 1732
1734 1733 issue = Issue.find_by_subject('This is the test_new issue')
1735 1734 assert_not_nil issue
1736 1735 assert_nil issue.start_date
1737 1736 end
1738 1737
1739 1738 def test_post_create_without_start_date_and_default_start_date_is_creation_date
1740 1739 Setting.default_issue_start_date_to_creation_date = 1
1741 1740
1742 1741 @request.session[:user_id] = 2
1743 1742 assert_difference 'Issue.count' do
1744 1743 post :create, :project_id => 1,
1745 1744 :issue => {:tracker_id => 3,
1746 1745 :status_id => 2,
1747 1746 :subject => 'This is the test_new issue',
1748 1747 :description => 'This is the description',
1749 1748 :priority_id => 5,
1750 1749 :estimated_hours => '',
1751 1750 :custom_field_values => {'2' => 'Value for field 2'}}
1752 1751 end
1753 1752 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1754 1753
1755 1754 issue = Issue.find_by_subject('This is the test_new issue')
1756 1755 assert_not_nil issue
1757 1756 assert_equal Date.today, issue.start_date
1758 1757 end
1759 1758
1760 1759 def test_post_create_and_continue
1761 1760 @request.session[:user_id] = 2
1762 1761 assert_difference 'Issue.count' do
1763 1762 post :create, :project_id => 1,
1764 1763 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
1765 1764 :continue => ''
1766 1765 end
1767 1766
1768 1767 issue = Issue.first(:order => 'id DESC')
1769 1768 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1770 1769 assert_not_nil flash[:notice], "flash was not set"
1771 1770 assert_include %|<a href="/issues/#{issue.id}" title="This is first issue">##{issue.id}</a>|, flash[:notice], "issue link not found in the flash message"
1772 1771 end
1773 1772
1774 1773 def test_post_create_without_custom_fields_param
1775 1774 @request.session[:user_id] = 2
1776 1775 assert_difference 'Issue.count' do
1777 1776 post :create, :project_id => 1,
1778 1777 :issue => {:tracker_id => 1,
1779 1778 :subject => 'This is the test_new issue',
1780 1779 :description => 'This is the description',
1781 1780 :priority_id => 5}
1782 1781 end
1783 1782 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1784 1783 end
1785 1784
1786 1785 def test_post_create_with_multi_custom_field
1787 1786 field = IssueCustomField.find_by_name('Database')
1788 1787 field.update_attribute(:multiple, true)
1789 1788
1790 1789 @request.session[:user_id] = 2
1791 1790 assert_difference 'Issue.count' do
1792 1791 post :create, :project_id => 1,
1793 1792 :issue => {:tracker_id => 1,
1794 1793 :subject => 'This is the test_new issue',
1795 1794 :description => 'This is the description',
1796 1795 :priority_id => 5,
1797 1796 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
1798 1797 end
1799 1798 assert_response 302
1800 1799 issue = Issue.first(:order => 'id DESC')
1801 1800 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
1802 1801 end
1803 1802
1804 1803 def test_post_create_with_empty_multi_custom_field
1805 1804 field = IssueCustomField.find_by_name('Database')
1806 1805 field.update_attribute(:multiple, true)
1807 1806
1808 1807 @request.session[:user_id] = 2
1809 1808 assert_difference 'Issue.count' do
1810 1809 post :create, :project_id => 1,
1811 1810 :issue => {:tracker_id => 1,
1812 1811 :subject => 'This is the test_new issue',
1813 1812 :description => 'This is the description',
1814 1813 :priority_id => 5,
1815 1814 :custom_field_values => {'1' => ['']}}
1816 1815 end
1817 1816 assert_response 302
1818 1817 issue = Issue.first(:order => 'id DESC')
1819 1818 assert_equal [''], issue.custom_field_value(1).sort
1820 1819 end
1821 1820
1822 1821 def test_post_create_with_multi_user_custom_field
1823 1822 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1824 1823 :tracker_ids => [1], :is_for_all => true)
1825 1824
1826 1825 @request.session[:user_id] = 2
1827 1826 assert_difference 'Issue.count' do
1828 1827 post :create, :project_id => 1,
1829 1828 :issue => {:tracker_id => 1,
1830 1829 :subject => 'This is the test_new issue',
1831 1830 :description => 'This is the description',
1832 1831 :priority_id => 5,
1833 1832 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
1834 1833 end
1835 1834 assert_response 302
1836 1835 issue = Issue.first(:order => 'id DESC')
1837 1836 assert_equal ['2', '3'], issue.custom_field_value(field).sort
1838 1837 end
1839 1838
1840 1839 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1841 1840 field = IssueCustomField.find_by_name('Database')
1842 1841 field.update_attribute(:is_required, true)
1843 1842
1844 1843 @request.session[:user_id] = 2
1845 1844 assert_no_difference 'Issue.count' do
1846 1845 post :create, :project_id => 1,
1847 1846 :issue => {:tracker_id => 1,
1848 1847 :subject => 'This is the test_new issue',
1849 1848 :description => 'This is the description',
1850 1849 :priority_id => 5}
1851 1850 end
1852 1851 assert_response :success
1853 1852 assert_template 'new'
1854 1853 issue = assigns(:issue)
1855 1854 assert_not_nil issue
1856 1855 assert_error_tag :content => /Database can&#x27;t be blank/
1857 1856 end
1858 1857
1859 1858 def test_create_should_validate_required_fields
1860 1859 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1861 1860 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1862 1861 WorkflowPermission.delete_all
1863 1862 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1864 1863 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1865 1864 @request.session[:user_id] = 2
1866 1865
1867 1866 assert_no_difference 'Issue.count' do
1868 1867 post :create, :project_id => 1, :issue => {
1869 1868 :tracker_id => 2,
1870 1869 :status_id => 1,
1871 1870 :subject => 'Test',
1872 1871 :start_date => '',
1873 1872 :due_date => '',
1874 1873 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
1875 1874 }
1876 1875 assert_response :success
1877 1876 assert_template 'new'
1878 1877 end
1879 1878
1880 1879 assert_error_tag :content => /Due date can&#x27;t be blank/i
1881 1880 assert_error_tag :content => /Bar can&#x27;t be blank/i
1882 1881 end
1883 1882
1884 1883 def test_create_should_ignore_readonly_fields
1885 1884 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1886 1885 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1887 1886 WorkflowPermission.delete_all
1888 1887 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1889 1888 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1890 1889 @request.session[:user_id] = 2
1891 1890
1892 1891 assert_difference 'Issue.count' do
1893 1892 post :create, :project_id => 1, :issue => {
1894 1893 :tracker_id => 2,
1895 1894 :status_id => 1,
1896 1895 :subject => 'Test',
1897 1896 :start_date => '2012-07-14',
1898 1897 :due_date => '2012-07-16',
1899 1898 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
1900 1899 }
1901 1900 assert_response 302
1902 1901 end
1903 1902
1904 1903 issue = Issue.first(:order => 'id DESC')
1905 1904 assert_equal Date.parse('2012-07-14'), issue.start_date
1906 1905 assert_nil issue.due_date
1907 1906 assert_equal 'value1', issue.custom_field_value(cf1)
1908 1907 assert_nil issue.custom_field_value(cf2)
1909 1908 end
1910 1909
1911 1910 def test_post_create_with_watchers
1912 1911 @request.session[:user_id] = 2
1913 1912 ActionMailer::Base.deliveries.clear
1914 1913
1915 1914 assert_difference 'Watcher.count', 2 do
1916 1915 post :create, :project_id => 1,
1917 1916 :issue => {:tracker_id => 1,
1918 1917 :subject => 'This is a new issue with watchers',
1919 1918 :description => 'This is the description',
1920 1919 :priority_id => 5,
1921 1920 :watcher_user_ids => ['2', '3']}
1922 1921 end
1923 1922 issue = Issue.find_by_subject('This is a new issue with watchers')
1924 1923 assert_not_nil issue
1925 1924 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1926 1925
1927 1926 # Watchers added
1928 1927 assert_equal [2, 3], issue.watcher_user_ids.sort
1929 1928 assert issue.watched_by?(User.find(3))
1930 1929 # Watchers notified
1931 1930 mail = ActionMailer::Base.deliveries.last
1932 1931 assert_not_nil mail
1933 1932 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1934 1933 end
1935 1934
1936 1935 def test_post_create_subissue
1937 1936 @request.session[:user_id] = 2
1938 1937
1939 1938 assert_difference 'Issue.count' do
1940 1939 post :create, :project_id => 1,
1941 1940 :issue => {:tracker_id => 1,
1942 1941 :subject => 'This is a child issue',
1943 1942 :parent_issue_id => '2'}
1944 1943 assert_response 302
1945 1944 end
1946 1945 issue = Issue.order('id DESC').first
1947 1946 assert_equal Issue.find(2), issue.parent
1948 1947 end
1949 1948
1950 1949 def test_post_create_subissue_with_sharp_parent_id
1951 1950 @request.session[:user_id] = 2
1952 1951
1953 1952 assert_difference 'Issue.count' do
1954 1953 post :create, :project_id => 1,
1955 1954 :issue => {:tracker_id => 1,
1956 1955 :subject => 'This is a child issue',
1957 1956 :parent_issue_id => '#2'}
1958 1957 assert_response 302
1959 1958 end
1960 1959 issue = Issue.order('id DESC').first
1961 1960 assert_equal Issue.find(2), issue.parent
1962 1961 end
1963 1962
1964 1963 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
1965 1964 @request.session[:user_id] = 2
1966 1965
1967 1966 assert_no_difference 'Issue.count' do
1968 1967 post :create, :project_id => 1,
1969 1968 :issue => {:tracker_id => 1,
1970 1969 :subject => 'This is a child issue',
1971 1970 :parent_issue_id => '4'}
1972 1971
1973 1972 assert_response :success
1974 1973 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
1975 1974 assert_error_tag :content => /Parent task is invalid/i
1976 1975 end
1977 1976 end
1978 1977
1979 1978 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
1980 1979 @request.session[:user_id] = 2
1981 1980
1982 1981 assert_no_difference 'Issue.count' do
1983 1982 post :create, :project_id => 1,
1984 1983 :issue => {:tracker_id => 1,
1985 1984 :subject => 'This is a child issue',
1986 1985 :parent_issue_id => '01ABC'}
1987 1986
1988 1987 assert_response :success
1989 1988 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
1990 1989 assert_error_tag :content => /Parent task is invalid/i
1991 1990 end
1992 1991 end
1993 1992
1994 1993 def test_post_create_private
1995 1994 @request.session[:user_id] = 2
1996 1995
1997 1996 assert_difference 'Issue.count' do
1998 1997 post :create, :project_id => 1,
1999 1998 :issue => {:tracker_id => 1,
2000 1999 :subject => 'This is a private issue',
2001 2000 :is_private => '1'}
2002 2001 end
2003 2002 issue = Issue.first(:order => 'id DESC')
2004 2003 assert issue.is_private?
2005 2004 end
2006 2005
2007 2006 def test_post_create_private_with_set_own_issues_private_permission
2008 2007 role = Role.find(1)
2009 2008 role.remove_permission! :set_issues_private
2010 2009 role.add_permission! :set_own_issues_private
2011 2010
2012 2011 @request.session[:user_id] = 2
2013 2012
2014 2013 assert_difference 'Issue.count' do
2015 2014 post :create, :project_id => 1,
2016 2015 :issue => {:tracker_id => 1,
2017 2016 :subject => 'This is a private issue',
2018 2017 :is_private => '1'}
2019 2018 end
2020 2019 issue = Issue.first(:order => 'id DESC')
2021 2020 assert issue.is_private?
2022 2021 end
2023 2022
2024 2023 def test_post_create_should_send_a_notification
2025 2024 ActionMailer::Base.deliveries.clear
2026 2025 @request.session[:user_id] = 2
2027 2026 assert_difference 'Issue.count' do
2028 2027 post :create, :project_id => 1,
2029 2028 :issue => {:tracker_id => 3,
2030 2029 :subject => 'This is the test_new issue',
2031 2030 :description => 'This is the description',
2032 2031 :priority_id => 5,
2033 2032 :estimated_hours => '',
2034 2033 :custom_field_values => {'2' => 'Value for field 2'}}
2035 2034 end
2036 2035 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2037 2036
2038 2037 assert_equal 1, ActionMailer::Base.deliveries.size
2039 2038 end
2040 2039
2041 2040 def test_post_create_should_preserve_fields_values_on_validation_failure
2042 2041 @request.session[:user_id] = 2
2043 2042 post :create, :project_id => 1,
2044 2043 :issue => {:tracker_id => 1,
2045 2044 # empty subject
2046 2045 :subject => '',
2047 2046 :description => 'This is a description',
2048 2047 :priority_id => 6,
2049 2048 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2050 2049 assert_response :success
2051 2050 assert_template 'new'
2052 2051
2053 2052 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
2054 2053 :content => "\nThis is a description"
2055 2054 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2056 2055 :child => { :tag => 'option', :attributes => { :selected => 'selected',
2057 2056 :value => '6' },
2058 2057 :content => 'High' }
2059 2058 # Custom fields
2060 2059 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
2061 2060 :child => { :tag => 'option', :attributes => { :selected => 'selected',
2062 2061 :value => 'Oracle' },
2063 2062 :content => 'Oracle' }
2064 2063 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
2065 2064 :value => 'Value for field 2'}
2066 2065 end
2067 2066
2068 2067 def test_post_create_with_failure_should_preserve_watchers
2069 2068 assert !User.find(8).member_of?(Project.find(1))
2070 2069
2071 2070 @request.session[:user_id] = 2
2072 2071 post :create, :project_id => 1,
2073 2072 :issue => {:tracker_id => 1,
2074 2073 :watcher_user_ids => ['3', '8']}
2075 2074 assert_response :success
2076 2075 assert_template 'new'
2077 2076
2078 2077 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '2', :checked => nil}
2079 2078 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '3', :checked => 'checked'}
2080 2079 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '8', :checked => 'checked'}
2081 2080 end
2082 2081
2083 2082 def test_post_create_should_ignore_non_safe_attributes
2084 2083 @request.session[:user_id] = 2
2085 2084 assert_nothing_raised do
2086 2085 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2087 2086 end
2088 2087 end
2089 2088
2090 2089 def test_post_create_with_attachment
2091 2090 set_tmp_attachments_directory
2092 2091 @request.session[:user_id] = 2
2093 2092
2094 2093 assert_difference 'Issue.count' do
2095 2094 assert_difference 'Attachment.count' do
2096 2095 post :create, :project_id => 1,
2097 2096 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2098 2097 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2099 2098 end
2100 2099 end
2101 2100
2102 2101 issue = Issue.first(:order => 'id DESC')
2103 2102 attachment = Attachment.first(:order => 'id DESC')
2104 2103
2105 2104 assert_equal issue, attachment.container
2106 2105 assert_equal 2, attachment.author_id
2107 2106 assert_equal 'testfile.txt', attachment.filename
2108 2107 assert_equal 'text/plain', attachment.content_type
2109 2108 assert_equal 'test file', attachment.description
2110 2109 assert_equal 59, attachment.filesize
2111 2110 assert File.exists?(attachment.diskfile)
2112 2111 assert_equal 59, File.size(attachment.diskfile)
2113 2112 end
2114 2113
2115 2114 def test_post_create_with_failure_should_save_attachments
2116 2115 set_tmp_attachments_directory
2117 2116 @request.session[:user_id] = 2
2118 2117
2119 2118 assert_no_difference 'Issue.count' do
2120 2119 assert_difference 'Attachment.count' do
2121 2120 post :create, :project_id => 1,
2122 2121 :issue => { :tracker_id => '1', :subject => '' },
2123 2122 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2124 2123 assert_response :success
2125 2124 assert_template 'new'
2126 2125 end
2127 2126 end
2128 2127
2129 2128 attachment = Attachment.first(:order => 'id DESC')
2130 2129 assert_equal 'testfile.txt', attachment.filename
2131 2130 assert File.exists?(attachment.diskfile)
2132 2131 assert_nil attachment.container
2133 2132
2134 2133 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2135 2134 assert_tag 'span', :content => /testfile.txt/
2136 2135 end
2137 2136
2138 2137 def test_post_create_with_failure_should_keep_saved_attachments
2139 2138 set_tmp_attachments_directory
2140 2139 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2141 2140 @request.session[:user_id] = 2
2142 2141
2143 2142 assert_no_difference 'Issue.count' do
2144 2143 assert_no_difference 'Attachment.count' do
2145 2144 post :create, :project_id => 1,
2146 2145 :issue => { :tracker_id => '1', :subject => '' },
2147 2146 :attachments => {'p0' => {'token' => attachment.token}}
2148 2147 assert_response :success
2149 2148 assert_template 'new'
2150 2149 end
2151 2150 end
2152 2151
2153 2152 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2154 2153 assert_tag 'span', :content => /testfile.txt/
2155 2154 end
2156 2155
2157 2156 def test_post_create_should_attach_saved_attachments
2158 2157 set_tmp_attachments_directory
2159 2158 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2160 2159 @request.session[:user_id] = 2
2161 2160
2162 2161 assert_difference 'Issue.count' do
2163 2162 assert_no_difference 'Attachment.count' do
2164 2163 post :create, :project_id => 1,
2165 2164 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2166 2165 :attachments => {'p0' => {'token' => attachment.token}}
2167 2166 assert_response 302
2168 2167 end
2169 2168 end
2170 2169
2171 2170 issue = Issue.first(:order => 'id DESC')
2172 2171 assert_equal 1, issue.attachments.count
2173 2172
2174 2173 attachment.reload
2175 2174 assert_equal issue, attachment.container
2176 2175 end
2177 2176
2178 2177 context "without workflow privilege" do
2179 2178 setup do
2180 2179 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2181 2180 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2182 2181 end
2183 2182
2184 2183 context "#new" do
2185 2184 should "propose default status only" do
2186 2185 get :new, :project_id => 1
2187 2186 assert_response :success
2188 2187 assert_template 'new'
2189 2188 assert_tag :tag => 'select',
2190 2189 :attributes => {:name => 'issue[status_id]'},
2191 2190 :children => {:count => 1},
2192 2191 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
2193 2192 end
2194 2193
2195 2194 should "accept default status" do
2196 2195 assert_difference 'Issue.count' do
2197 2196 post :create, :project_id => 1,
2198 2197 :issue => {:tracker_id => 1,
2199 2198 :subject => 'This is an issue',
2200 2199 :status_id => 1}
2201 2200 end
2202 2201 issue = Issue.last(:order => 'id')
2203 2202 assert_equal IssueStatus.default, issue.status
2204 2203 end
2205 2204
2206 2205 should "ignore unauthorized status" do
2207 2206 assert_difference 'Issue.count' do
2208 2207 post :create, :project_id => 1,
2209 2208 :issue => {:tracker_id => 1,
2210 2209 :subject => 'This is an issue',
2211 2210 :status_id => 3}
2212 2211 end
2213 2212 issue = Issue.last(:order => 'id')
2214 2213 assert_equal IssueStatus.default, issue.status
2215 2214 end
2216 2215 end
2217 2216
2218 2217 context "#update" do
2219 2218 should "ignore status change" do
2220 2219 assert_difference 'Journal.count' do
2221 2220 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2222 2221 end
2223 2222 assert_equal 1, Issue.find(1).status_id
2224 2223 end
2225 2224
2226 2225 should "ignore attributes changes" do
2227 2226 assert_difference 'Journal.count' do
2228 2227 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
2229 2228 end
2230 2229 issue = Issue.find(1)
2231 2230 assert_equal "Can't print recipes", issue.subject
2232 2231 assert_nil issue.assigned_to
2233 2232 end
2234 2233 end
2235 2234 end
2236 2235
2237 2236 context "with workflow privilege" do
2238 2237 setup do
2239 2238 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2240 2239 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2241 2240 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2242 2241 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2243 2242 end
2244 2243
2245 2244 context "#update" do
2246 2245 should "accept authorized status" do
2247 2246 assert_difference 'Journal.count' do
2248 2247 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2249 2248 end
2250 2249 assert_equal 3, Issue.find(1).status_id
2251 2250 end
2252 2251
2253 2252 should "ignore unauthorized status" do
2254 2253 assert_difference 'Journal.count' do
2255 2254 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2256 2255 end
2257 2256 assert_equal 1, Issue.find(1).status_id
2258 2257 end
2259 2258
2260 2259 should "accept authorized attributes changes" do
2261 2260 assert_difference 'Journal.count' do
2262 2261 put :update, :id => 1, :issue => {:assigned_to_id => 2, :notes => 'just trying'}
2263 2262 end
2264 2263 issue = Issue.find(1)
2265 2264 assert_equal 2, issue.assigned_to_id
2266 2265 end
2267 2266
2268 2267 should "ignore unauthorized attributes changes" do
2269 2268 assert_difference 'Journal.count' do
2270 2269 put :update, :id => 1, :issue => {:subject => 'changed', :notes => 'just trying'}
2271 2270 end
2272 2271 issue = Issue.find(1)
2273 2272 assert_equal "Can't print recipes", issue.subject
2274 2273 end
2275 2274 end
2276 2275
2277 2276 context "and :edit_issues permission" do
2278 2277 setup do
2279 2278 Role.anonymous.add_permission! :add_issues, :edit_issues
2280 2279 end
2281 2280
2282 2281 should "accept authorized status" do
2283 2282 assert_difference 'Journal.count' do
2284 2283 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2285 2284 end
2286 2285 assert_equal 3, Issue.find(1).status_id
2287 2286 end
2288 2287
2289 2288 should "ignore unauthorized status" do
2290 2289 assert_difference 'Journal.count' do
2291 2290 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2292 2291 end
2293 2292 assert_equal 1, Issue.find(1).status_id
2294 2293 end
2295 2294
2296 2295 should "accept authorized attributes changes" do
2297 2296 assert_difference 'Journal.count' do
2298 2297 put :update, :id => 1, :issue => {:subject => 'changed', :assigned_to_id => 2, :notes => 'just trying'}
2299 2298 end
2300 2299 issue = Issue.find(1)
2301 2300 assert_equal "changed", issue.subject
2302 2301 assert_equal 2, issue.assigned_to_id
2303 2302 end
2304 2303 end
2305 2304 end
2306 2305
2307 2306 def test_new_as_copy
2308 2307 @request.session[:user_id] = 2
2309 2308 get :new, :project_id => 1, :copy_from => 1
2310 2309
2311 2310 assert_response :success
2312 2311 assert_template 'new'
2313 2312
2314 2313 assert_not_nil assigns(:issue)
2315 2314 orig = Issue.find(1)
2316 2315 assert_equal 1, assigns(:issue).project_id
2317 2316 assert_equal orig.subject, assigns(:issue).subject
2318 2317 assert assigns(:issue).copy?
2319 2318
2320 2319 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2321 2320 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2322 2321 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2323 2322 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
2324 2323 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2325 2324 :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
2326 2325 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2327 2326 end
2328 2327
2329 2328 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2330 2329 @request.session[:user_id] = 2
2331 2330 issue = Issue.find(3)
2332 2331 assert issue.attachments.count > 0
2333 2332 get :new, :project_id => 1, :copy_from => 3
2334 2333
2335 2334 assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2336 2335 end
2337 2336
2338 2337 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2339 2338 @request.session[:user_id] = 2
2340 2339 issue = Issue.find(3)
2341 2340 issue.attachments.delete_all
2342 2341 get :new, :project_id => 1, :copy_from => 3
2343 2342
2344 2343 assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2345 2344 end
2346 2345
2347 2346 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2348 2347 @request.session[:user_id] = 2
2349 2348 issue = Issue.generate_with_descendants!
2350 2349 get :new, :project_id => 1, :copy_from => issue.id
2351 2350
2352 2351 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value=1]'
2353 2352 end
2354 2353
2355 2354 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2356 2355 @request.session[:user_id] = 2
2357 2356 get :new, :project_id => 1, :copy_from => 99999
2358 2357 assert_response 404
2359 2358 end
2360 2359
2361 2360 def test_create_as_copy_on_different_project
2362 2361 @request.session[:user_id] = 2
2363 2362 assert_difference 'Issue.count' do
2364 2363 post :create, :project_id => 1, :copy_from => 1,
2365 2364 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2366 2365
2367 2366 assert_not_nil assigns(:issue)
2368 2367 assert assigns(:issue).copy?
2369 2368 end
2370 2369 issue = Issue.first(:order => 'id DESC')
2371 2370 assert_redirected_to "/issues/#{issue.id}"
2372 2371
2373 2372 assert_equal 2, issue.project_id
2374 2373 assert_equal 3, issue.tracker_id
2375 2374 assert_equal 'Copy', issue.subject
2376 2375 end
2377 2376
2378 2377 def test_create_as_copy_should_copy_attachments
2379 2378 @request.session[:user_id] = 2
2380 2379 issue = Issue.find(3)
2381 2380 count = issue.attachments.count
2382 2381 assert count > 0
2383 2382
2384 2383 assert_difference 'Issue.count' do
2385 2384 assert_difference 'Attachment.count', count do
2386 2385 assert_no_difference 'Journal.count' do
2387 2386 post :create, :project_id => 1, :copy_from => 3,
2388 2387 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2389 2388 :copy_attachments => '1'
2390 2389 end
2391 2390 end
2392 2391 end
2393 2392 copy = Issue.first(:order => 'id DESC')
2394 2393 assert_equal count, copy.attachments.count
2395 2394 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2396 2395 end
2397 2396
2398 2397 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2399 2398 @request.session[:user_id] = 2
2400 2399 issue = Issue.find(3)
2401 2400 count = issue.attachments.count
2402 2401 assert count > 0
2403 2402
2404 2403 assert_difference 'Issue.count' do
2405 2404 assert_no_difference 'Attachment.count' do
2406 2405 assert_no_difference 'Journal.count' do
2407 2406 post :create, :project_id => 1, :copy_from => 3,
2408 2407 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
2409 2408 end
2410 2409 end
2411 2410 end
2412 2411 copy = Issue.first(:order => 'id DESC')
2413 2412 assert_equal 0, copy.attachments.count
2414 2413 end
2415 2414
2416 2415 def test_create_as_copy_with_attachments_should_add_new_files
2417 2416 @request.session[:user_id] = 2
2418 2417 issue = Issue.find(3)
2419 2418 count = issue.attachments.count
2420 2419 assert count > 0
2421 2420
2422 2421 assert_difference 'Issue.count' do
2423 2422 assert_difference 'Attachment.count', count + 1 do
2424 2423 assert_no_difference 'Journal.count' do
2425 2424 post :create, :project_id => 1, :copy_from => 3,
2426 2425 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2427 2426 :copy_attachments => '1',
2428 2427 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2429 2428 end
2430 2429 end
2431 2430 end
2432 2431 copy = Issue.first(:order => 'id DESC')
2433 2432 assert_equal count + 1, copy.attachments.count
2434 2433 end
2435 2434
2436 2435 def test_create_as_copy_should_add_relation_with_copied_issue
2437 2436 @request.session[:user_id] = 2
2438 2437
2439 2438 assert_difference 'Issue.count' do
2440 2439 assert_difference 'IssueRelation.count' do
2441 2440 post :create, :project_id => 1, :copy_from => 1,
2442 2441 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2443 2442 end
2444 2443 end
2445 2444 copy = Issue.first(:order => 'id DESC')
2446 2445 assert_equal 1, copy.relations.size
2447 2446 end
2448 2447
2449 2448 def test_create_as_copy_should_copy_subtasks
2450 2449 @request.session[:user_id] = 2
2451 2450 issue = Issue.generate_with_descendants!
2452 2451 count = issue.descendants.count
2453 2452
2454 2453 assert_difference 'Issue.count', count+1 do
2455 2454 assert_no_difference 'Journal.count' do
2456 2455 post :create, :project_id => 1, :copy_from => issue.id,
2457 2456 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'},
2458 2457 :copy_subtasks => '1'
2459 2458 end
2460 2459 end
2461 2460 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2462 2461 assert_equal count, copy.descendants.count
2463 2462 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
2464 2463 end
2465 2464
2466 2465 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
2467 2466 @request.session[:user_id] = 2
2468 2467 issue = Issue.generate_with_descendants!
2469 2468
2470 2469 assert_difference 'Issue.count', 1 do
2471 2470 assert_no_difference 'Journal.count' do
2472 2471 post :create, :project_id => 1, :copy_from => 3,
2473 2472 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with subtasks'}
2474 2473 end
2475 2474 end
2476 2475 copy = Issue.where(:parent_id => nil).first(:order => 'id DESC')
2477 2476 assert_equal 0, copy.descendants.count
2478 2477 end
2479 2478
2480 2479 def test_create_as_copy_with_failure
2481 2480 @request.session[:user_id] = 2
2482 2481 post :create, :project_id => 1, :copy_from => 1,
2483 2482 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
2484 2483
2485 2484 assert_response :success
2486 2485 assert_template 'new'
2487 2486
2488 2487 assert_not_nil assigns(:issue)
2489 2488 assert assigns(:issue).copy?
2490 2489
2491 2490 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2492 2491 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2493 2492 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2494 2493 :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
2495 2494 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2496 2495 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
2497 2496 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2498 2497 end
2499 2498
2500 2499 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
2501 2500 @request.session[:user_id] = 2
2502 2501 assert !User.find(2).member_of?(Project.find(4))
2503 2502
2504 2503 assert_difference 'Issue.count' do
2505 2504 post :create, :project_id => 1, :copy_from => 1,
2506 2505 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2507 2506 end
2508 2507 issue = Issue.first(:order => 'id DESC')
2509 2508 assert_equal 1, issue.project_id
2510 2509 end
2511 2510
2512 2511 def test_get_edit
2513 2512 @request.session[:user_id] = 2
2514 2513 get :edit, :id => 1
2515 2514 assert_response :success
2516 2515 assert_template 'edit'
2517 2516 assert_not_nil assigns(:issue)
2518 2517 assert_equal Issue.find(1), assigns(:issue)
2519 2518
2520 2519 # Be sure we don't display inactive IssuePriorities
2521 2520 assert ! IssuePriority.find(15).active?
2522 2521 assert_no_tag :option, :attributes => {:value => '15'},
2523 2522 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2524 2523 end
2525 2524
2526 2525 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
2527 2526 @request.session[:user_id] = 2
2528 2527 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
2529 2528
2530 2529 get :edit, :id => 1
2531 2530 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2532 2531 end
2533 2532
2534 2533 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
2535 2534 @request.session[:user_id] = 2
2536 2535 Role.find_by_name('Manager').remove_permission! :log_time
2537 2536
2538 2537 get :edit, :id => 1
2539 2538 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2540 2539 end
2541 2540
2542 2541 def test_get_edit_with_params
2543 2542 @request.session[:user_id] = 2
2544 2543 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
2545 2544 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
2546 2545 assert_response :success
2547 2546 assert_template 'edit'
2548 2547
2549 2548 issue = assigns(:issue)
2550 2549 assert_not_nil issue
2551 2550
2552 2551 assert_equal 5, issue.status_id
2553 2552 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
2554 2553 :child => { :tag => 'option',
2555 2554 :content => 'Closed',
2556 2555 :attributes => { :selected => 'selected' } }
2557 2556
2558 2557 assert_equal 7, issue.priority_id
2559 2558 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2560 2559 :child => { :tag => 'option',
2561 2560 :content => 'Urgent',
2562 2561 :attributes => { :selected => 'selected' } }
2563 2562
2564 2563 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
2565 2564 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
2566 2565 :child => { :tag => 'option',
2567 2566 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
2568 2567 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
2569 2568 end
2570 2569
2571 2570 def test_get_edit_with_multi_custom_field
2572 2571 field = CustomField.find(1)
2573 2572 field.update_attribute :multiple, true
2574 2573 issue = Issue.find(1)
2575 2574 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2576 2575 issue.save!
2577 2576
2578 2577 @request.session[:user_id] = 2
2579 2578 get :edit, :id => 1
2580 2579 assert_response :success
2581 2580 assert_template 'edit'
2582 2581
2583 2582 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
2584 2583 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2585 2584 :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
2586 2585 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2587 2586 :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
2588 2587 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2589 2588 :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
2590 2589 end
2591 2590
2592 2591 def test_update_edit_form
2593 2592 @request.session[:user_id] = 2
2594 2593 xhr :put, :new, :project_id => 1,
2595 2594 :id => 1,
2596 2595 :issue => {:tracker_id => 2,
2597 2596 :subject => 'This is the test_new issue',
2598 2597 :description => 'This is the description',
2599 2598 :priority_id => 5}
2600 2599 assert_response :success
2601 2600 assert_equal 'text/javascript', response.content_type
2602 2601 assert_template 'update_form'
2603 2602 assert_template 'form'
2604 2603
2605 2604 issue = assigns(:issue)
2606 2605 assert_kind_of Issue, issue
2607 2606 assert_equal 1, issue.id
2608 2607 assert_equal 1, issue.project_id
2609 2608 assert_equal 2, issue.tracker_id
2610 2609 assert_equal 'This is the test_new issue', issue.subject
2611 2610 end
2612 2611
2613 2612 def test_update_edit_form_should_keep_issue_author
2614 2613 @request.session[:user_id] = 3
2615 2614 xhr :put, :new, :project_id => 1, :id => 1, :issue => {:subject => 'Changed'}
2616 2615 assert_response :success
2617 2616 assert_equal 'text/javascript', response.content_type
2618 2617
2619 2618 issue = assigns(:issue)
2620 2619 assert_equal User.find(2), issue.author
2621 2620 assert_equal 2, issue.author_id
2622 2621 assert_not_equal User.current, issue.author
2623 2622 end
2624 2623
2625 2624 def test_update_edit_form_should_propose_transitions_based_on_initial_status
2626 2625 @request.session[:user_id] = 2
2627 2626 WorkflowTransition.delete_all
2628 2627 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2629 2628 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2630 2629 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2631 2630
2632 2631 xhr :put, :new, :project_id => 1,
2633 2632 :id => 2,
2634 2633 :issue => {:tracker_id => 2,
2635 2634 :status_id => 5,
2636 2635 :subject => 'This is an issue'}
2637 2636
2638 2637 assert_equal 5, assigns(:issue).status_id
2639 2638 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
2640 2639 end
2641 2640
2642 2641 def test_update_edit_form_with_project_change
2643 2642 @request.session[:user_id] = 2
2644 2643 xhr :put, :new, :project_id => 1,
2645 2644 :id => 1,
2646 2645 :issue => {:project_id => 2,
2647 2646 :tracker_id => 2,
2648 2647 :subject => 'This is the test_new issue',
2649 2648 :description => 'This is the description',
2650 2649 :priority_id => 5}
2651 2650 assert_response :success
2652 2651 assert_template 'form'
2653 2652
2654 2653 issue = assigns(:issue)
2655 2654 assert_kind_of Issue, issue
2656 2655 assert_equal 1, issue.id
2657 2656 assert_equal 2, issue.project_id
2658 2657 assert_equal 2, issue.tracker_id
2659 2658 assert_equal 'This is the test_new issue', issue.subject
2660 2659 end
2661 2660
2662 2661 def test_put_update_without_custom_fields_param
2663 2662 @request.session[:user_id] = 2
2664 2663 ActionMailer::Base.deliveries.clear
2665 2664
2666 2665 issue = Issue.find(1)
2667 2666 assert_equal '125', issue.custom_value_for(2).value
2668 2667 old_subject = issue.subject
2669 2668 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2670 2669
2671 2670 assert_difference('Journal.count') do
2672 2671 assert_difference('JournalDetail.count', 2) do
2673 2672 put :update, :id => 1, :issue => {:subject => new_subject,
2674 2673 :priority_id => '6',
2675 2674 :category_id => '1' # no change
2676 2675 }
2677 2676 end
2678 2677 end
2679 2678 assert_redirected_to :action => 'show', :id => '1'
2680 2679 issue.reload
2681 2680 assert_equal new_subject, issue.subject
2682 2681 # Make sure custom fields were not cleared
2683 2682 assert_equal '125', issue.custom_value_for(2).value
2684 2683
2685 2684 mail = ActionMailer::Base.deliveries.last
2686 2685 assert_not_nil mail
2687 2686 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2688 2687 assert_mail_body_match "Subject changed from #{old_subject} to #{new_subject}", mail
2689 2688 end
2690 2689
2691 2690 def test_put_update_with_project_change
2692 2691 @request.session[:user_id] = 2
2693 2692 ActionMailer::Base.deliveries.clear
2694 2693
2695 2694 assert_difference('Journal.count') do
2696 2695 assert_difference('JournalDetail.count', 3) do
2697 2696 put :update, :id => 1, :issue => {:project_id => '2',
2698 2697 :tracker_id => '1', # no change
2699 2698 :priority_id => '6',
2700 2699 :category_id => '3'
2701 2700 }
2702 2701 end
2703 2702 end
2704 2703 assert_redirected_to :action => 'show', :id => '1'
2705 2704 issue = Issue.find(1)
2706 2705 assert_equal 2, issue.project_id
2707 2706 assert_equal 1, issue.tracker_id
2708 2707 assert_equal 6, issue.priority_id
2709 2708 assert_equal 3, issue.category_id
2710 2709
2711 2710 mail = ActionMailer::Base.deliveries.last
2712 2711 assert_not_nil mail
2713 2712 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2714 2713 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
2715 2714 end
2716 2715
2717 2716 def test_put_update_with_tracker_change
2718 2717 @request.session[:user_id] = 2
2719 2718 ActionMailer::Base.deliveries.clear
2720 2719
2721 2720 assert_difference('Journal.count') do
2722 2721 assert_difference('JournalDetail.count', 2) do
2723 2722 put :update, :id => 1, :issue => {:project_id => '1',
2724 2723 :tracker_id => '2',
2725 2724 :priority_id => '6'
2726 2725 }
2727 2726 end
2728 2727 end
2729 2728 assert_redirected_to :action => 'show', :id => '1'
2730 2729 issue = Issue.find(1)
2731 2730 assert_equal 1, issue.project_id
2732 2731 assert_equal 2, issue.tracker_id
2733 2732 assert_equal 6, issue.priority_id
2734 2733 assert_equal 1, issue.category_id
2735 2734
2736 2735 mail = ActionMailer::Base.deliveries.last
2737 2736 assert_not_nil mail
2738 2737 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2739 2738 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
2740 2739 end
2741 2740
2742 2741 def test_put_update_with_custom_field_change
2743 2742 @request.session[:user_id] = 2
2744 2743 issue = Issue.find(1)
2745 2744 assert_equal '125', issue.custom_value_for(2).value
2746 2745
2747 2746 assert_difference('Journal.count') do
2748 2747 assert_difference('JournalDetail.count', 3) do
2749 2748 put :update, :id => 1, :issue => {:subject => 'Custom field change',
2750 2749 :priority_id => '6',
2751 2750 :category_id => '1', # no change
2752 2751 :custom_field_values => { '2' => 'New custom value' }
2753 2752 }
2754 2753 end
2755 2754 end
2756 2755 assert_redirected_to :action => 'show', :id => '1'
2757 2756 issue.reload
2758 2757 assert_equal 'New custom value', issue.custom_value_for(2).value
2759 2758
2760 2759 mail = ActionMailer::Base.deliveries.last
2761 2760 assert_not_nil mail
2762 2761 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
2763 2762 end
2764 2763
2765 2764 def test_put_update_with_multi_custom_field_change
2766 2765 field = CustomField.find(1)
2767 2766 field.update_attribute :multiple, true
2768 2767 issue = Issue.find(1)
2769 2768 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2770 2769 issue.save!
2771 2770
2772 2771 @request.session[:user_id] = 2
2773 2772 assert_difference('Journal.count') do
2774 2773 assert_difference('JournalDetail.count', 3) do
2775 2774 put :update, :id => 1,
2776 2775 :issue => {
2777 2776 :subject => 'Custom field change',
2778 2777 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
2779 2778 }
2780 2779 end
2781 2780 end
2782 2781 assert_redirected_to :action => 'show', :id => '1'
2783 2782 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
2784 2783 end
2785 2784
2786 2785 def test_put_update_with_status_and_assignee_change
2787 2786 issue = Issue.find(1)
2788 2787 assert_equal 1, issue.status_id
2789 2788 @request.session[:user_id] = 2
2790 2789 assert_difference('TimeEntry.count', 0) do
2791 2790 put :update,
2792 2791 :id => 1,
2793 2792 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
2794 2793 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
2795 2794 end
2796 2795 assert_redirected_to :action => 'show', :id => '1'
2797 2796 issue.reload
2798 2797 assert_equal 2, issue.status_id
2799 2798 j = Journal.find(:first, :order => 'id DESC')
2800 2799 assert_equal 'Assigned to dlopper', j.notes
2801 2800 assert_equal 2, j.details.size
2802 2801
2803 2802 mail = ActionMailer::Base.deliveries.last
2804 2803 assert_mail_body_match "Status changed from New to Assigned", mail
2805 2804 # subject should contain the new status
2806 2805 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
2807 2806 end
2808 2807
2809 2808 def test_put_update_with_note_only
2810 2809 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
2811 2810 # anonymous user
2812 2811 put :update,
2813 2812 :id => 1,
2814 2813 :issue => { :notes => notes }
2815 2814 assert_redirected_to :action => 'show', :id => '1'
2816 2815 j = Journal.find(:first, :order => 'id DESC')
2817 2816 assert_equal notes, j.notes
2818 2817 assert_equal 0, j.details.size
2819 2818 assert_equal User.anonymous, j.user
2820 2819
2821 2820 mail = ActionMailer::Base.deliveries.last
2822 2821 assert_mail_body_match notes, mail
2823 2822 end
2824 2823
2825 2824 def test_put_update_with_private_note_only
2826 2825 notes = 'Private note'
2827 2826 @request.session[:user_id] = 2
2828 2827
2829 2828 assert_difference 'Journal.count' do
2830 2829 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
2831 2830 assert_redirected_to :action => 'show', :id => '1'
2832 2831 end
2833 2832
2834 2833 j = Journal.order('id DESC').first
2835 2834 assert_equal notes, j.notes
2836 2835 assert_equal true, j.private_notes
2837 2836 end
2838 2837
2839 2838 def test_put_update_with_private_note_and_changes
2840 2839 notes = 'Private note'
2841 2840 @request.session[:user_id] = 2
2842 2841
2843 2842 assert_difference 'Journal.count', 2 do
2844 2843 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
2845 2844 assert_redirected_to :action => 'show', :id => '1'
2846 2845 end
2847 2846
2848 2847 j = Journal.order('id DESC').first
2849 2848 assert_equal notes, j.notes
2850 2849 assert_equal true, j.private_notes
2851 2850 assert_equal 0, j.details.count
2852 2851
2853 2852 j = Journal.order('id DESC').offset(1).first
2854 2853 assert_nil j.notes
2855 2854 assert_equal false, j.private_notes
2856 2855 assert_equal 1, j.details.count
2857 2856 end
2858 2857
2859 2858 def test_put_update_with_note_and_spent_time
2860 2859 @request.session[:user_id] = 2
2861 2860 spent_hours_before = Issue.find(1).spent_hours
2862 2861 assert_difference('TimeEntry.count') do
2863 2862 put :update,
2864 2863 :id => 1,
2865 2864 :issue => { :notes => '2.5 hours added' },
2866 2865 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
2867 2866 end
2868 2867 assert_redirected_to :action => 'show', :id => '1'
2869 2868
2870 2869 issue = Issue.find(1)
2871 2870
2872 2871 j = Journal.find(:first, :order => 'id DESC')
2873 2872 assert_equal '2.5 hours added', j.notes
2874 2873 assert_equal 0, j.details.size
2875 2874
2876 2875 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
2877 2876 assert_not_nil t
2878 2877 assert_equal 2.5, t.hours
2879 2878 assert_equal spent_hours_before + 2.5, issue.spent_hours
2880 2879 end
2881 2880
2882 2881 def test_put_update_with_attachment_only
2883 2882 set_tmp_attachments_directory
2884 2883
2885 2884 # Delete all fixtured journals, a race condition can occur causing the wrong
2886 2885 # journal to get fetched in the next find.
2887 2886 Journal.delete_all
2888 2887
2889 2888 # anonymous user
2890 2889 assert_difference 'Attachment.count' do
2891 2890 put :update, :id => 1,
2892 2891 :issue => {:notes => ''},
2893 2892 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2894 2893 end
2895 2894
2896 2895 assert_redirected_to :action => 'show', :id => '1'
2897 2896 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
2898 2897 assert j.notes.blank?
2899 2898 assert_equal 1, j.details.size
2900 2899 assert_equal 'testfile.txt', j.details.first.value
2901 2900 assert_equal User.anonymous, j.user
2902 2901
2903 2902 attachment = Attachment.first(:order => 'id DESC')
2904 2903 assert_equal Issue.find(1), attachment.container
2905 2904 assert_equal User.anonymous, attachment.author
2906 2905 assert_equal 'testfile.txt', attachment.filename
2907 2906 assert_equal 'text/plain', attachment.content_type
2908 2907 assert_equal 'test file', attachment.description
2909 2908 assert_equal 59, attachment.filesize
2910 2909 assert File.exists?(attachment.diskfile)
2911 2910 assert_equal 59, File.size(attachment.diskfile)
2912 2911
2913 2912 mail = ActionMailer::Base.deliveries.last
2914 2913 assert_mail_body_match 'testfile.txt', mail
2915 2914 end
2916 2915
2917 2916 def test_put_update_with_failure_should_save_attachments
2918 2917 set_tmp_attachments_directory
2919 2918 @request.session[:user_id] = 2
2920 2919
2921 2920 assert_no_difference 'Journal.count' do
2922 2921 assert_difference 'Attachment.count' do
2923 2922 put :update, :id => 1,
2924 2923 :issue => { :subject => '' },
2925 2924 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2926 2925 assert_response :success
2927 2926 assert_template 'edit'
2928 2927 end
2929 2928 end
2930 2929
2931 2930 attachment = Attachment.first(:order => 'id DESC')
2932 2931 assert_equal 'testfile.txt', attachment.filename
2933 2932 assert File.exists?(attachment.diskfile)
2934 2933 assert_nil attachment.container
2935 2934
2936 2935 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2937 2936 assert_tag 'span', :content => /testfile.txt/
2938 2937 end
2939 2938
2940 2939 def test_put_update_with_failure_should_keep_saved_attachments
2941 2940 set_tmp_attachments_directory
2942 2941 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2943 2942 @request.session[:user_id] = 2
2944 2943
2945 2944 assert_no_difference 'Journal.count' do
2946 2945 assert_no_difference 'Attachment.count' do
2947 2946 put :update, :id => 1,
2948 2947 :issue => { :subject => '' },
2949 2948 :attachments => {'p0' => {'token' => attachment.token}}
2950 2949 assert_response :success
2951 2950 assert_template 'edit'
2952 2951 end
2953 2952 end
2954 2953
2955 2954 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2956 2955 assert_tag 'span', :content => /testfile.txt/
2957 2956 end
2958 2957
2959 2958 def test_put_update_should_attach_saved_attachments
2960 2959 set_tmp_attachments_directory
2961 2960 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2962 2961 @request.session[:user_id] = 2
2963 2962
2964 2963 assert_difference 'Journal.count' do
2965 2964 assert_difference 'JournalDetail.count' do
2966 2965 assert_no_difference 'Attachment.count' do
2967 2966 put :update, :id => 1,
2968 2967 :issue => {:notes => 'Attachment added'},
2969 2968 :attachments => {'p0' => {'token' => attachment.token}}
2970 2969 assert_redirected_to '/issues/1'
2971 2970 end
2972 2971 end
2973 2972 end
2974 2973
2975 2974 attachment.reload
2976 2975 assert_equal Issue.find(1), attachment.container
2977 2976
2978 2977 journal = Journal.first(:order => 'id DESC')
2979 2978 assert_equal 1, journal.details.size
2980 2979 assert_equal 'testfile.txt', journal.details.first.value
2981 2980 end
2982 2981
2983 2982 def test_put_update_with_attachment_that_fails_to_save
2984 2983 set_tmp_attachments_directory
2985 2984
2986 2985 # Delete all fixtured journals, a race condition can occur causing the wrong
2987 2986 # journal to get fetched in the next find.
2988 2987 Journal.delete_all
2989 2988
2990 2989 # Mock out the unsaved attachment
2991 2990 Attachment.any_instance.stubs(:create).returns(Attachment.new)
2992 2991
2993 2992 # anonymous user
2994 2993 put :update,
2995 2994 :id => 1,
2996 2995 :issue => {:notes => ''},
2997 2996 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
2998 2997 assert_redirected_to :action => 'show', :id => '1'
2999 2998 assert_equal '1 file(s) could not be saved.', flash[:warning]
3000 2999 end
3001 3000
3002 3001 def test_put_update_with_no_change
3003 3002 issue = Issue.find(1)
3004 3003 issue.journals.clear
3005 3004 ActionMailer::Base.deliveries.clear
3006 3005
3007 3006 put :update,
3008 3007 :id => 1,
3009 3008 :issue => {:notes => ''}
3010 3009 assert_redirected_to :action => 'show', :id => '1'
3011 3010
3012 3011 issue.reload
3013 3012 assert issue.journals.empty?
3014 3013 # No email should be sent
3015 3014 assert ActionMailer::Base.deliveries.empty?
3016 3015 end
3017 3016
3018 3017 def test_put_update_should_send_a_notification
3019 3018 @request.session[:user_id] = 2
3020 3019 ActionMailer::Base.deliveries.clear
3021 3020 issue = Issue.find(1)
3022 3021 old_subject = issue.subject
3023 3022 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3024 3023
3025 3024 put :update, :id => 1, :issue => {:subject => new_subject,
3026 3025 :priority_id => '6',
3027 3026 :category_id => '1' # no change
3028 3027 }
3029 3028 assert_equal 1, ActionMailer::Base.deliveries.size
3030 3029 end
3031 3030
3032 3031 def test_put_update_with_invalid_spent_time_hours_only
3033 3032 @request.session[:user_id] = 2
3034 3033 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3035 3034
3036 3035 assert_no_difference('Journal.count') do
3037 3036 put :update,
3038 3037 :id => 1,
3039 3038 :issue => {:notes => notes},
3040 3039 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3041 3040 end
3042 3041 assert_response :success
3043 3042 assert_template 'edit'
3044 3043
3045 3044 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
3046 3045 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
3047 3046 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
3048 3047 end
3049 3048
3050 3049 def test_put_update_with_invalid_spent_time_comments_only
3051 3050 @request.session[:user_id] = 2
3052 3051 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3053 3052
3054 3053 assert_no_difference('Journal.count') do
3055 3054 put :update,
3056 3055 :id => 1,
3057 3056 :issue => {:notes => notes},
3058 3057 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3059 3058 end
3060 3059 assert_response :success
3061 3060 assert_template 'edit'
3062 3061
3063 3062 assert_error_tag :descendant => {:content => /Activity can&#x27;t be blank/}
3064 3063 assert_error_tag :descendant => {:content => /Hours can&#x27;t be blank/}
3065 3064 assert_tag :textarea, :attributes => { :name => 'issue[notes]' }, :content => "\n"+notes
3066 3065 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
3067 3066 end
3068 3067
3069 3068 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3070 3069 issue = Issue.find(2)
3071 3070 @request.session[:user_id] = 2
3072 3071
3073 3072 put :update,
3074 3073 :id => issue.id,
3075 3074 :issue => {
3076 3075 :fixed_version_id => 4
3077 3076 }
3078 3077
3079 3078 assert_response :redirect
3080 3079 issue.reload
3081 3080 assert_equal 4, issue.fixed_version_id
3082 3081 assert_not_equal issue.project_id, issue.fixed_version.project_id
3083 3082 end
3084 3083
3085 3084 def test_put_update_should_redirect_back_using_the_back_url_parameter
3086 3085 issue = Issue.find(2)
3087 3086 @request.session[:user_id] = 2
3088 3087
3089 3088 put :update,
3090 3089 :id => issue.id,
3091 3090 :issue => {
3092 3091 :fixed_version_id => 4
3093 3092 },
3094 3093 :back_url => '/issues'
3095 3094
3096 3095 assert_response :redirect
3097 3096 assert_redirected_to '/issues'
3098 3097 end
3099 3098
3100 3099 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3101 3100 issue = Issue.find(2)
3102 3101 @request.session[:user_id] = 2
3103 3102
3104 3103 put :update,
3105 3104 :id => issue.id,
3106 3105 :issue => {
3107 3106 :fixed_version_id => 4
3108 3107 },
3109 3108 :back_url => 'http://google.com'
3110 3109
3111 3110 assert_response :redirect
3112 3111 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3113 3112 end
3114 3113
3115 3114 def test_get_bulk_edit
3116 3115 @request.session[:user_id] = 2
3117 3116 get :bulk_edit, :ids => [1, 2]
3118 3117 assert_response :success
3119 3118 assert_template 'bulk_edit'
3120 3119
3121 3120 assert_tag :select, :attributes => {:name => 'issue[project_id]'}
3122 3121 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
3123 3122
3124 3123 # Project specific custom field, date type
3125 3124 field = CustomField.find(9)
3126 3125 assert !field.is_for_all?
3127 3126 assert_equal 'date', field.field_format
3128 3127 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
3129 3128
3130 3129 # System wide custom field
3131 3130 assert CustomField.find(1).is_for_all?
3132 3131 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
3133 3132
3134 3133 # Be sure we don't display inactive IssuePriorities
3135 3134 assert ! IssuePriority.find(15).active?
3136 3135 assert_no_tag :option, :attributes => {:value => '15'},
3137 3136 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
3138 3137 end
3139 3138
3140 3139 def test_get_bulk_edit_on_different_projects
3141 3140 @request.session[:user_id] = 2
3142 3141 get :bulk_edit, :ids => [1, 2, 6]
3143 3142 assert_response :success
3144 3143 assert_template 'bulk_edit'
3145 3144
3146 3145 # Can not set issues from different projects as children of an issue
3147 3146 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
3148 3147
3149 3148 # Project specific custom field, date type
3150 3149 field = CustomField.find(9)
3151 3150 assert !field.is_for_all?
3152 3151 assert !field.project_ids.include?(Issue.find(6).project_id)
3153 3152 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
3154 3153 end
3155 3154
3156 3155 def test_get_bulk_edit_with_user_custom_field
3157 3156 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
3158 3157
3159 3158 @request.session[:user_id] = 2
3160 3159 get :bulk_edit, :ids => [1, 2]
3161 3160 assert_response :success
3162 3161 assert_template 'bulk_edit'
3163 3162
3164 3163 assert_tag :select,
3165 3164 :attributes => {:name => "issue[custom_field_values][#{field.id}]", :class => 'user_cf'},
3166 3165 :children => {
3167 3166 :only => {:tag => 'option'},
3168 3167 :count => Project.find(1).users.count + 2 # "no change" + "none" options
3169 3168 }
3170 3169 end
3171 3170
3172 3171 def test_get_bulk_edit_with_version_custom_field
3173 3172 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
3174 3173
3175 3174 @request.session[:user_id] = 2
3176 3175 get :bulk_edit, :ids => [1, 2]
3177 3176 assert_response :success
3178 3177 assert_template 'bulk_edit'
3179 3178
3180 3179 assert_tag :select,
3181 3180 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
3182 3181 :children => {
3183 3182 :only => {:tag => 'option'},
3184 3183 :count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3185 3184 }
3186 3185 end
3187 3186
3188 3187 def test_get_bulk_edit_with_multi_custom_field
3189 3188 field = CustomField.find(1)
3190 3189 field.update_attribute :multiple, true
3191 3190
3192 3191 @request.session[:user_id] = 2
3193 3192 get :bulk_edit, :ids => [1, 2]
3194 3193 assert_response :success
3195 3194 assert_template 'bulk_edit'
3196 3195
3197 3196 assert_tag :select,
3198 3197 :attributes => {:name => "issue[custom_field_values][1][]"},
3199 3198 :children => {
3200 3199 :only => {:tag => 'option'},
3201 3200 :count => field.possible_values.size + 1 # "none" options
3202 3201 }
3203 3202 end
3204 3203
3205 3204 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3206 3205 WorkflowTransition.delete_all
3207 3206 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
3208 3207 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
3209 3208 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
3210 3209 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3211 3210 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3212 3211 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3213 3212 @request.session[:user_id] = 2
3214 3213 get :bulk_edit, :ids => [1, 2]
3215 3214
3216 3215 assert_response :success
3217 3216 statuses = assigns(:available_statuses)
3218 3217 assert_not_nil statuses
3219 3218 assert_equal [1, 3], statuses.map(&:id).sort
3220 3219
3221 3220 assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
3222 3221 :children => {:count => 3} # 2 statuses + "no change" option
3223 3222 end
3224 3223
3225 3224 def test_bulk_edit_should_propose_target_project_open_shared_versions
3226 3225 @request.session[:user_id] = 2
3227 3226 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3228 3227 assert_response :success
3229 3228 assert_template 'bulk_edit'
3230 3229 assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
3231 3230 assert_tag 'select',
3232 3231 :attributes => {:name => 'issue[fixed_version_id]'},
3233 3232 :descendant => {:tag => 'option', :content => '2.0'}
3234 3233 end
3235 3234
3236 3235 def test_bulk_edit_should_propose_target_project_categories
3237 3236 @request.session[:user_id] = 2
3238 3237 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3239 3238 assert_response :success
3240 3239 assert_template 'bulk_edit'
3241 3240 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3242 3241 assert_tag 'select',
3243 3242 :attributes => {:name => 'issue[category_id]'},
3244 3243 :descendant => {:tag => 'option', :content => 'Recipes'}
3245 3244 end
3246 3245
3247 3246 def test_bulk_update
3248 3247 @request.session[:user_id] = 2
3249 3248 # update issues priority
3250 3249 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3251 3250 :issue => {:priority_id => 7,
3252 3251 :assigned_to_id => '',
3253 3252 :custom_field_values => {'2' => ''}}
3254 3253
3255 3254 assert_response 302
3256 3255 # check that the issues were updated
3257 3256 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
3258 3257
3259 3258 issue = Issue.find(1)
3260 3259 journal = issue.journals.find(:first, :order => 'created_on DESC')
3261 3260 assert_equal '125', issue.custom_value_for(2).value
3262 3261 assert_equal 'Bulk editing', journal.notes
3263 3262 assert_equal 1, journal.details.size
3264 3263 end
3265 3264
3266 3265 def test_bulk_update_with_group_assignee
3267 3266 group = Group.find(11)
3268 3267 project = Project.find(1)
3269 3268 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3270 3269
3271 3270 @request.session[:user_id] = 2
3272 3271 # update issues assignee
3273 3272 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3274 3273 :issue => {:priority_id => '',
3275 3274 :assigned_to_id => group.id,
3276 3275 :custom_field_values => {'2' => ''}}
3277 3276
3278 3277 assert_response 302
3279 3278 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
3280 3279 end
3281 3280
3282 3281 def test_bulk_update_on_different_projects
3283 3282 @request.session[:user_id] = 2
3284 3283 # update issues priority
3285 3284 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3286 3285 :issue => {:priority_id => 7,
3287 3286 :assigned_to_id => '',
3288 3287 :custom_field_values => {'2' => ''}}
3289 3288
3290 3289 assert_response 302
3291 3290 # check that the issues were updated
3292 3291 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3293 3292
3294 3293 issue = Issue.find(1)
3295 3294 journal = issue.journals.find(:first, :order => 'created_on DESC')
3296 3295 assert_equal '125', issue.custom_value_for(2).value
3297 3296 assert_equal 'Bulk editing', journal.notes
3298 3297 assert_equal 1, journal.details.size
3299 3298 end
3300 3299
3301 3300 def test_bulk_update_on_different_projects_without_rights
3302 3301 @request.session[:user_id] = 3
3303 3302 user = User.find(3)
3304 3303 action = { :controller => "issues", :action => "bulk_update" }
3305 3304 assert user.allowed_to?(action, Issue.find(1).project)
3306 3305 assert ! user.allowed_to?(action, Issue.find(6).project)
3307 3306 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3308 3307 :issue => {:priority_id => 7,
3309 3308 :assigned_to_id => '',
3310 3309 :custom_field_values => {'2' => ''}}
3311 3310 assert_response 403
3312 3311 assert_not_equal "Bulk should fail", Journal.last.notes
3313 3312 end
3314 3313
3315 3314 def test_bullk_update_should_send_a_notification
3316 3315 @request.session[:user_id] = 2
3317 3316 ActionMailer::Base.deliveries.clear
3318 3317 post(:bulk_update,
3319 3318 {
3320 3319 :ids => [1, 2],
3321 3320 :notes => 'Bulk editing',
3322 3321 :issue => {
3323 3322 :priority_id => 7,
3324 3323 :assigned_to_id => '',
3325 3324 :custom_field_values => {'2' => ''}
3326 3325 }
3327 3326 })
3328 3327
3329 3328 assert_response 302
3330 3329 assert_equal 2, ActionMailer::Base.deliveries.size
3331 3330 end
3332 3331
3333 3332 def test_bulk_update_project
3334 3333 @request.session[:user_id] = 2
3335 3334 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3336 3335 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3337 3336 # Issues moved to project 2
3338 3337 assert_equal 2, Issue.find(1).project_id
3339 3338 assert_equal 2, Issue.find(2).project_id
3340 3339 # No tracker change
3341 3340 assert_equal 1, Issue.find(1).tracker_id
3342 3341 assert_equal 2, Issue.find(2).tracker_id
3343 3342 end
3344 3343
3345 3344 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3346 3345 @request.session[:user_id] = 2
3347 3346 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3348 3347 assert_redirected_to '/issues/1'
3349 3348 end
3350 3349
3351 3350 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3352 3351 @request.session[:user_id] = 2
3353 3352 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3354 3353 assert_redirected_to '/projects/onlinestore/issues'
3355 3354 end
3356 3355
3357 3356 def test_bulk_update_tracker
3358 3357 @request.session[:user_id] = 2
3359 3358 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3360 3359 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3361 3360 assert_equal 2, Issue.find(1).tracker_id
3362 3361 assert_equal 2, Issue.find(2).tracker_id
3363 3362 end
3364 3363
3365 3364 def test_bulk_update_status
3366 3365 @request.session[:user_id] = 2
3367 3366 # update issues priority
3368 3367 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
3369 3368 :issue => {:priority_id => '',
3370 3369 :assigned_to_id => '',
3371 3370 :status_id => '5'}
3372 3371
3373 3372 assert_response 302
3374 3373 issue = Issue.find(1)
3375 3374 assert issue.closed?
3376 3375 end
3377 3376
3378 3377 def test_bulk_update_priority
3379 3378 @request.session[:user_id] = 2
3380 3379 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3381 3380
3382 3381 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3383 3382 assert_equal 6, Issue.find(1).priority_id
3384 3383 assert_equal 6, Issue.find(2).priority_id
3385 3384 end
3386 3385
3387 3386 def test_bulk_update_with_notes
3388 3387 @request.session[:user_id] = 2
3389 3388 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
3390 3389
3391 3390 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3392 3391 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
3393 3392 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
3394 3393 end
3395 3394
3396 3395 def test_bulk_update_parent_id
3397 3396 @request.session[:user_id] = 2
3398 3397 post :bulk_update, :ids => [1, 3],
3399 3398 :notes => 'Bulk editing parent',
3400 3399 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
3401 3400
3402 3401 assert_response 302
3403 3402 parent = Issue.find(2)
3404 3403 assert_equal parent.id, Issue.find(1).parent_id
3405 3404 assert_equal parent.id, Issue.find(3).parent_id
3406 3405 assert_equal [1, 3], parent.children.collect(&:id).sort
3407 3406 end
3408 3407
3409 3408 def test_bulk_update_custom_field
3410 3409 @request.session[:user_id] = 2
3411 3410 # update issues priority
3412 3411 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
3413 3412 :issue => {:priority_id => '',
3414 3413 :assigned_to_id => '',
3415 3414 :custom_field_values => {'2' => '777'}}
3416 3415
3417 3416 assert_response 302
3418 3417
3419 3418 issue = Issue.find(1)
3420 3419 journal = issue.journals.find(:first, :order => 'created_on DESC')
3421 3420 assert_equal '777', issue.custom_value_for(2).value
3422 3421 assert_equal 1, journal.details.size
3423 3422 assert_equal '125', journal.details.first.old_value
3424 3423 assert_equal '777', journal.details.first.value
3425 3424 end
3426 3425
3427 3426 def test_bulk_update_custom_field_to_blank
3428 3427 @request.session[:user_id] = 2
3429 3428 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
3430 3429 :issue => {:priority_id => '',
3431 3430 :assigned_to_id => '',
3432 3431 :custom_field_values => {'1' => '__none__'}}
3433 3432 assert_response 302
3434 3433 assert_equal '', Issue.find(1).custom_field_value(1)
3435 3434 assert_equal '', Issue.find(3).custom_field_value(1)
3436 3435 end
3437 3436
3438 3437 def test_bulk_update_multi_custom_field
3439 3438 field = CustomField.find(1)
3440 3439 field.update_attribute :multiple, true
3441 3440
3442 3441 @request.session[:user_id] = 2
3443 3442 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
3444 3443 :issue => {:priority_id => '',
3445 3444 :assigned_to_id => '',
3446 3445 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
3447 3446
3448 3447 assert_response 302
3449 3448
3450 3449 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
3451 3450 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
3452 3451 # the custom field is not associated with the issue tracker
3453 3452 assert_nil Issue.find(2).custom_field_value(1)
3454 3453 end
3455 3454
3456 3455 def test_bulk_update_multi_custom_field_to_blank
3457 3456 field = CustomField.find(1)
3458 3457 field.update_attribute :multiple, true
3459 3458
3460 3459 @request.session[:user_id] = 2
3461 3460 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
3462 3461 :issue => {:priority_id => '',
3463 3462 :assigned_to_id => '',
3464 3463 :custom_field_values => {'1' => ['__none__']}}
3465 3464 assert_response 302
3466 3465 assert_equal [''], Issue.find(1).custom_field_value(1)
3467 3466 assert_equal [''], Issue.find(3).custom_field_value(1)
3468 3467 end
3469 3468
3470 3469 def test_bulk_update_unassign
3471 3470 assert_not_nil Issue.find(2).assigned_to
3472 3471 @request.session[:user_id] = 2
3473 3472 # unassign issues
3474 3473 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
3475 3474 assert_response 302
3476 3475 # check that the issues were updated
3477 3476 assert_nil Issue.find(2).assigned_to
3478 3477 end
3479 3478
3480 3479 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
3481 3480 @request.session[:user_id] = 2
3482 3481
3483 3482 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
3484 3483
3485 3484 assert_response :redirect
3486 3485 issues = Issue.find([1,2])
3487 3486 issues.each do |issue|
3488 3487 assert_equal 4, issue.fixed_version_id
3489 3488 assert_not_equal issue.project_id, issue.fixed_version.project_id
3490 3489 end
3491 3490 end
3492 3491
3493 3492 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
3494 3493 @request.session[:user_id] = 2
3495 3494 post :bulk_update, :ids => [1,2], :back_url => '/issues'
3496 3495
3497 3496 assert_response :redirect
3498 3497 assert_redirected_to '/issues'
3499 3498 end
3500 3499
3501 3500 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3502 3501 @request.session[:user_id] = 2
3503 3502 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
3504 3503
3505 3504 assert_response :redirect
3506 3505 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
3507 3506 end
3508 3507
3509 3508 def test_bulk_update_with_failure_should_set_flash
3510 3509 @request.session[:user_id] = 2
3511 3510 Issue.update_all("subject = ''", "id = 2") # Make it invalid
3512 3511 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3513 3512
3514 3513 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3515 3514 assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
3516 3515 end
3517 3516
3518 3517 def test_get_bulk_copy
3519 3518 @request.session[:user_id] = 2
3520 3519 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
3521 3520 assert_response :success
3522 3521 assert_template 'bulk_edit'
3523 3522
3524 3523 issues = assigns(:issues)
3525 3524 assert_not_nil issues
3526 3525 assert_equal [1, 2, 3], issues.map(&:id).sort
3527 3526
3528 3527 assert_select 'input[name=copy_attachments]'
3529 3528 end
3530 3529
3531 3530 def test_bulk_copy_to_another_project
3532 3531 @request.session[:user_id] = 2
3533 3532 assert_difference 'Issue.count', 2 do
3534 3533 assert_no_difference 'Project.find(1).issues.count' do
3535 3534 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
3536 3535 end
3537 3536 end
3538 3537 assert_redirected_to '/projects/ecookbook/issues'
3539 3538
3540 3539 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3541 3540 copies.each do |copy|
3542 3541 assert_equal 2, copy.project_id
3543 3542 end
3544 3543 end
3545 3544
3546 3545 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
3547 3546 @request.session[:user_id] = 2
3548 3547 issues = [
3549 3548 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
3550 3549 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
3551 3550 ]
3552 3551
3553 3552 assert_difference 'Issue.count', issues.size do
3554 3553 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
3555 3554 :issue => {
3556 3555 :project_id => '', :tracker_id => '', :assigned_to_id => '',
3557 3556 :status_id => '', :start_date => '', :due_date => ''
3558 3557 }
3559 3558 end
3560 3559
3561 3560 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3562 3561 issues.each do |orig|
3563 3562 copy = copies.detect {|c| c.subject == orig.subject}
3564 3563 assert_not_nil copy
3565 3564 assert_equal orig.project_id, copy.project_id
3566 3565 assert_equal orig.tracker_id, copy.tracker_id
3567 3566 assert_equal orig.status_id, copy.status_id
3568 3567 assert_equal orig.assigned_to_id, copy.assigned_to_id
3569 3568 assert_equal orig.priority_id, copy.priority_id
3570 3569 end
3571 3570 end
3572 3571
3573 3572 def test_bulk_copy_should_allow_changing_the_issue_attributes
3574 3573 # Fixes random test failure with Mysql
3575 3574 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3576 3575 # doesn't return the expected results
3577 3576 Issue.delete_all("project_id=2")
3578 3577
3579 3578 @request.session[:user_id] = 2
3580 3579 assert_difference 'Issue.count', 2 do
3581 3580 assert_no_difference 'Project.find(1).issues.count' do
3582 3581 post :bulk_update, :ids => [1, 2], :copy => '1',
3583 3582 :issue => {
3584 3583 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
3585 3584 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
3586 3585 }
3587 3586 end
3588 3587 end
3589 3588
3590 3589 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3591 3590 assert_equal 2, copied_issues.size
3592 3591 copied_issues.each do |issue|
3593 3592 assert_equal 2, issue.project_id, "Project is incorrect"
3594 3593 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
3595 3594 assert_equal 1, issue.status_id, "Status is incorrect"
3596 3595 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
3597 3596 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
3598 3597 end
3599 3598 end
3600 3599
3601 3600 def test_bulk_copy_should_allow_adding_a_note
3602 3601 @request.session[:user_id] = 2
3603 3602 assert_difference 'Issue.count', 1 do
3604 3603 post :bulk_update, :ids => [1], :copy => '1',
3605 3604 :notes => 'Copying one issue',
3606 3605 :issue => {
3607 3606 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
3608 3607 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
3609 3608 }
3610 3609 end
3611 3610
3612 3611 issue = Issue.first(:order => 'id DESC')
3613 3612 assert_equal 1, issue.journals.size
3614 3613 journal = issue.journals.first
3615 3614 assert_equal 0, journal.details.size
3616 3615 assert_equal 'Copying one issue', journal.notes
3617 3616 end
3618 3617
3619 3618 def test_bulk_copy_should_allow_not_copying_the_attachments
3620 3619 attachment_count = Issue.find(3).attachments.size
3621 3620 assert attachment_count > 0
3622 3621 @request.session[:user_id] = 2
3623 3622
3624 3623 assert_difference 'Issue.count', 1 do
3625 3624 assert_no_difference 'Attachment.count' do
3626 3625 post :bulk_update, :ids => [3], :copy => '1',
3627 3626 :issue => {
3628 3627 :project_id => ''
3629 3628 }
3630 3629 end
3631 3630 end
3632 3631 end
3633 3632
3634 3633 def test_bulk_copy_should_allow_copying_the_attachments
3635 3634 attachment_count = Issue.find(3).attachments.size
3636 3635 assert attachment_count > 0
3637 3636 @request.session[:user_id] = 2
3638 3637
3639 3638 assert_difference 'Issue.count', 1 do
3640 3639 assert_difference 'Attachment.count', attachment_count do
3641 3640 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
3642 3641 :issue => {
3643 3642 :project_id => ''
3644 3643 }
3645 3644 end
3646 3645 end
3647 3646 end
3648 3647
3649 3648 def test_bulk_copy_should_add_relations_with_copied_issues
3650 3649 @request.session[:user_id] = 2
3651 3650
3652 3651 assert_difference 'Issue.count', 2 do
3653 3652 assert_difference 'IssueRelation.count', 2 do
3654 3653 post :bulk_update, :ids => [1, 3], :copy => '1',
3655 3654 :issue => {
3656 3655 :project_id => '1'
3657 3656 }
3658 3657 end
3659 3658 end
3660 3659 end
3661 3660
3662 3661 def test_bulk_copy_should_allow_not_copying_the_subtasks
3663 3662 issue = Issue.generate_with_descendants!
3664 3663 @request.session[:user_id] = 2
3665 3664
3666 3665 assert_difference 'Issue.count', 1 do
3667 3666 post :bulk_update, :ids => [issue.id], :copy => '1',
3668 3667 :issue => {
3669 3668 :project_id => ''
3670 3669 }
3671 3670 end
3672 3671 end
3673 3672
3674 3673 def test_bulk_copy_should_allow_copying_the_subtasks
3675 3674 issue = Issue.generate_with_descendants!
3676 3675 count = issue.descendants.count
3677 3676 @request.session[:user_id] = 2
3678 3677
3679 3678 assert_difference 'Issue.count', count+1 do
3680 3679 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
3681 3680 :issue => {
3682 3681 :project_id => ''
3683 3682 }
3684 3683 end
3685 3684 copy = Issue.where(:parent_id => nil).order("id DESC").first
3686 3685 assert_equal count, copy.descendants.count
3687 3686 end
3688 3687
3689 3688 def test_bulk_copy_should_not_copy_selected_subtasks_twice
3690 3689 issue = Issue.generate_with_descendants!
3691 3690 count = issue.descendants.count
3692 3691 @request.session[:user_id] = 2
3693 3692
3694 3693 assert_difference 'Issue.count', count+1 do
3695 3694 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
3696 3695 :issue => {
3697 3696 :project_id => ''
3698 3697 }
3699 3698 end
3700 3699 copy = Issue.where(:parent_id => nil).order("id DESC").first
3701 3700 assert_equal count, copy.descendants.count
3702 3701 end
3703 3702
3704 3703 def test_bulk_copy_to_another_project_should_follow_when_needed
3705 3704 @request.session[:user_id] = 2
3706 3705 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
3707 3706 issue = Issue.first(:order => 'id DESC')
3708 3707 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
3709 3708 end
3710 3709
3711 3710 def test_destroy_issue_with_no_time_entries
3712 3711 assert_nil TimeEntry.find_by_issue_id(2)
3713 3712 @request.session[:user_id] = 2
3714 3713
3715 3714 assert_difference 'Issue.count', -1 do
3716 3715 delete :destroy, :id => 2
3717 3716 end
3718 3717 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3719 3718 assert_nil Issue.find_by_id(2)
3720 3719 end
3721 3720
3722 3721 def test_destroy_issues_with_time_entries
3723 3722 @request.session[:user_id] = 2
3724 3723
3725 3724 assert_no_difference 'Issue.count' do
3726 3725 delete :destroy, :ids => [1, 3]
3727 3726 end
3728 3727 assert_response :success
3729 3728 assert_template 'destroy'
3730 3729 assert_not_nil assigns(:hours)
3731 3730 assert Issue.find_by_id(1) && Issue.find_by_id(3)
3732 3731 assert_tag 'form',
3733 3732 :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
3734 3733 end
3735 3734
3736 3735 def test_destroy_issues_and_destroy_time_entries
3737 3736 @request.session[:user_id] = 2
3738 3737
3739 3738 assert_difference 'Issue.count', -2 do
3740 3739 assert_difference 'TimeEntry.count', -3 do
3741 3740 delete :destroy, :ids => [1, 3], :todo => 'destroy'
3742 3741 end
3743 3742 end
3744 3743 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3745 3744 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3746 3745 assert_nil TimeEntry.find_by_id([1, 2])
3747 3746 end
3748 3747
3749 3748 def test_destroy_issues_and_assign_time_entries_to_project
3750 3749 @request.session[:user_id] = 2
3751 3750
3752 3751 assert_difference 'Issue.count', -2 do
3753 3752 assert_no_difference 'TimeEntry.count' do
3754 3753 delete :destroy, :ids => [1, 3], :todo => 'nullify'
3755 3754 end
3756 3755 end
3757 3756 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3758 3757 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3759 3758 assert_nil TimeEntry.find(1).issue_id
3760 3759 assert_nil TimeEntry.find(2).issue_id
3761 3760 end
3762 3761
3763 3762 def test_destroy_issues_and_reassign_time_entries_to_another_issue
3764 3763 @request.session[:user_id] = 2
3765 3764
3766 3765 assert_difference 'Issue.count', -2 do
3767 3766 assert_no_difference 'TimeEntry.count' do
3768 3767 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
3769 3768 end
3770 3769 end
3771 3770 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3772 3771 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3773 3772 assert_equal 2, TimeEntry.find(1).issue_id
3774 3773 assert_equal 2, TimeEntry.find(2).issue_id
3775 3774 end
3776 3775
3777 3776 def test_destroy_issues_from_different_projects
3778 3777 @request.session[:user_id] = 2
3779 3778
3780 3779 assert_difference 'Issue.count', -3 do
3781 3780 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
3782 3781 end
3783 3782 assert_redirected_to :controller => 'issues', :action => 'index'
3784 3783 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
3785 3784 end
3786 3785
3787 3786 def test_destroy_parent_and_child_issues
3788 3787 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
3789 3788 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
3790 3789 assert child.is_descendant_of?(parent.reload)
3791 3790
3792 3791 @request.session[:user_id] = 2
3793 3792 assert_difference 'Issue.count', -2 do
3794 3793 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
3795 3794 end
3796 3795 assert_response 302
3797 3796 end
3798 3797
3799 3798 def test_default_search_scope
3800 3799 get :index
3801 3800 assert_tag :div, :attributes => {:id => 'quick-search'},
3802 3801 :child => {:tag => 'form',
3803 3802 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
3804 3803 end
3805 3804 end
General Comments 0
You need to be logged in to leave comments. Login now