##// END OF EJS Templates
add tests to export issues csv in Traditional Chinese and French for csv separator (#8368)...
Toshi MARUYAMA -
r7823:0eed9198eb3e
parent child
Show More
@@ -1,1916 +1,1974
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 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
46 46 include Redmine::I18n
47 47
48 48 def setup
49 49 @controller = IssuesController.new
50 50 @request = ActionController::TestRequest.new
51 51 @response = ActionController::TestResponse.new
52 52 User.current = nil
53 53 end
54 54
55 55 def test_index
56 56 Setting.default_language = 'en'
57 57
58 58 get :index
59 59 assert_response :success
60 60 assert_template 'index'
61 61 assert_not_nil assigns(:issues)
62 62 assert_nil assigns(:project)
63 63 assert_tag :tag => 'a', :content => /Can't print recipes/
64 64 assert_tag :tag => 'a', :content => /Subproject issue/
65 65 # private projects hidden
66 66 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
67 67 assert_no_tag :tag => 'a', :content => /Issue on project 2/
68 68 # project column
69 69 assert_tag :tag => 'th', :content => /Project/
70 70 end
71 71
72 72 def test_index_should_not_list_issues_when_module_disabled
73 73 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
74 74 get :index
75 75 assert_response :success
76 76 assert_template 'index'
77 77 assert_not_nil assigns(:issues)
78 78 assert_nil assigns(:project)
79 79 assert_no_tag :tag => 'a', :content => /Can't print recipes/
80 80 assert_tag :tag => 'a', :content => /Subproject issue/
81 81 end
82 82
83 83 def test_index_should_list_visible_issues_only
84 84 get :index, :per_page => 100
85 85 assert_response :success
86 86 assert_not_nil assigns(:issues)
87 87 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
88 88 end
89 89
90 90 def test_index_with_project
91 91 Setting.display_subprojects_issues = 0
92 92 get :index, :project_id => 1
93 93 assert_response :success
94 94 assert_template 'index'
95 95 assert_not_nil assigns(:issues)
96 96 assert_tag :tag => 'a', :content => /Can't print recipes/
97 97 assert_no_tag :tag => 'a', :content => /Subproject issue/
98 98 end
99 99
100 100 def test_index_with_project_and_subprojects
101 101 Setting.display_subprojects_issues = 1
102 102 get :index, :project_id => 1
103 103 assert_response :success
104 104 assert_template 'index'
105 105 assert_not_nil assigns(:issues)
106 106 assert_tag :tag => 'a', :content => /Can't print recipes/
107 107 assert_tag :tag => 'a', :content => /Subproject issue/
108 108 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
109 109 end
110 110
111 111 def test_index_with_project_and_subprojects_should_show_private_subprojects
112 112 @request.session[:user_id] = 2
113 113 Setting.display_subprojects_issues = 1
114 114 get :index, :project_id => 1
115 115 assert_response :success
116 116 assert_template 'index'
117 117 assert_not_nil assigns(:issues)
118 118 assert_tag :tag => 'a', :content => /Can't print recipes/
119 119 assert_tag :tag => 'a', :content => /Subproject issue/
120 120 assert_tag :tag => 'a', :content => /Issue of a private subproject/
121 121 end
122 122
123 123 def test_index_with_project_and_default_filter
124 124 get :index, :project_id => 1, :set_filter => 1
125 125 assert_response :success
126 126 assert_template 'index'
127 127 assert_not_nil assigns(:issues)
128 128
129 129 query = assigns(:query)
130 130 assert_not_nil query
131 131 # default filter
132 132 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
133 133 end
134 134
135 135 def test_index_with_project_and_filter
136 136 get :index, :project_id => 1, :set_filter => 1,
137 137 :f => ['tracker_id'],
138 138 :op => {'tracker_id' => '='},
139 139 :v => {'tracker_id' => ['1']}
140 140 assert_response :success
141 141 assert_template 'index'
142 142 assert_not_nil assigns(:issues)
143 143
144 144 query = assigns(:query)
145 145 assert_not_nil query
146 146 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
147 147 end
148 148
149 149 def test_index_with_short_filters
150 150
151 151 to_test = {
152 152 'status_id' => {
153 153 'o' => { :op => 'o', :values => [''] },
154 154 'c' => { :op => 'c', :values => [''] },
155 155 '7' => { :op => '=', :values => ['7'] },
156 156 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
157 157 '=7' => { :op => '=', :values => ['7'] },
158 158 '!3' => { :op => '!', :values => ['3'] },
159 159 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
160 160 'subject' => {
161 161 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
162 162 'o' => { :op => '=', :values => ['o'] },
163 163 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
164 164 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
165 165 'tracker_id' => {
166 166 '3' => { :op => '=', :values => ['3'] },
167 167 '=3' => { :op => '=', :values => ['3'] }},
168 168 'start_date' => {
169 169 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
170 170 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
171 171 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
172 172 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
173 173 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
174 174 '<t+2' => { :op => '<t+', :values => ['2'] },
175 175 '>t+2' => { :op => '>t+', :values => ['2'] },
176 176 't+2' => { :op => 't+', :values => ['2'] },
177 177 't' => { :op => 't', :values => [''] },
178 178 'w' => { :op => 'w', :values => [''] },
179 179 '>t-2' => { :op => '>t-', :values => ['2'] },
180 180 '<t-2' => { :op => '<t-', :values => ['2'] },
181 181 't-2' => { :op => 't-', :values => ['2'] }},
182 182 'created_on' => {
183 183 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
184 184 '<t+2' => { :op => '=', :values => ['<t+2'] },
185 185 '>t+2' => { :op => '=', :values => ['>t+2'] },
186 186 't+2' => { :op => 't', :values => ['+2'] }},
187 187 'cf_1' => {
188 188 'c' => { :op => '=', :values => ['c'] },
189 189 '!c' => { :op => '!', :values => ['c'] },
190 190 '!*' => { :op => '!*', :values => [''] },
191 191 '*' => { :op => '*', :values => [''] }},
192 192 'estimated_hours' => {
193 193 '=13.4' => { :op => '=', :values => ['13.4'] },
194 194 '>=45' => { :op => '>=', :values => ['45'] },
195 195 '<=125' => { :op => '<=', :values => ['125'] },
196 196 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
197 197 '!*' => { :op => '!*', :values => [''] },
198 198 '*' => { :op => '*', :values => [''] }}
199 199 }
200 200
201 201 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
202 202
203 203 to_test.each do |field, expression_and_expected|
204 204 expression_and_expected.each do |filter_expression, expected|
205 205
206 206 get :index, :set_filter => 1, field => filter_expression
207 207
208 208 assert_response :success
209 209 assert_template 'index'
210 210 assert_not_nil assigns(:issues)
211 211
212 212 query = assigns(:query)
213 213 assert_not_nil query
214 214 assert query.has_filter?(field)
215 215 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
216 216 end
217 217 end
218 218
219 219 end
220 220
221 221 def test_index_with_project_and_empty_filters
222 222 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
223 223 assert_response :success
224 224 assert_template 'index'
225 225 assert_not_nil assigns(:issues)
226 226
227 227 query = assigns(:query)
228 228 assert_not_nil query
229 229 # no filter
230 230 assert_equal({}, query.filters)
231 231 end
232 232
233 233 def test_index_with_query
234 234 get :index, :project_id => 1, :query_id => 5
235 235 assert_response :success
236 236 assert_template 'index'
237 237 assert_not_nil assigns(:issues)
238 238 assert_nil assigns(:issue_count_by_group)
239 239 end
240 240
241 241 def test_index_with_query_grouped_by_tracker
242 242 get :index, :project_id => 1, :query_id => 6
243 243 assert_response :success
244 244 assert_template 'index'
245 245 assert_not_nil assigns(:issues)
246 246 assert_not_nil assigns(:issue_count_by_group)
247 247 end
248 248
249 249 def test_index_with_query_grouped_by_list_custom_field
250 250 get :index, :project_id => 1, :query_id => 9
251 251 assert_response :success
252 252 assert_template 'index'
253 253 assert_not_nil assigns(:issues)
254 254 assert_not_nil assigns(:issue_count_by_group)
255 255 end
256 256
257 257 def test_private_query_should_not_be_available_to_other_users
258 258 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
259 259 @request.session[:user_id] = 3
260 260
261 261 get :index, :query_id => q.id
262 262 assert_response 403
263 263 end
264 264
265 265 def test_private_query_should_be_available_to_its_user
266 266 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
267 267 @request.session[:user_id] = 2
268 268
269 269 get :index, :query_id => q.id
270 270 assert_response :success
271 271 end
272 272
273 273 def test_public_query_should_be_available_to_other_users
274 274 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
275 275 @request.session[:user_id] = 3
276 276
277 277 get :index, :query_id => q.id
278 278 assert_response :success
279 279 end
280 280
281 281 def test_index_csv
282 282 get :index, :format => 'csv'
283 283 assert_response :success
284 284 assert_not_nil assigns(:issues)
285 285 assert_equal 'text/csv', @response.content_type
286 286 assert @response.body.starts_with?("#,")
287 287 lines = @response.body.chomp.split("\n")
288 288 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
289 289 end
290 290
291 291 def test_index_csv_with_project
292 292 get :index, :project_id => 1, :format => 'csv'
293 293 assert_response :success
294 294 assert_not_nil assigns(:issues)
295 295 assert_equal 'text/csv', @response.content_type
296 296 end
297 297
298 298 def test_index_csv_with_description
299 299 get :index, :format => 'csv', :description => '1'
300 300 assert_response :success
301 301 assert_not_nil assigns(:issues)
302 302 assert_equal 'text/csv', @response.content_type
303 303 assert @response.body.starts_with?("#,")
304 304 lines = @response.body.chomp.split("\n")
305 305 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
306 306 end
307 307
308 308 def test_index_csv_with_all_columns
309 309 get :index, :format => 'csv', :columns => 'all'
310 310 assert_response :success
311 311 assert_not_nil assigns(:issues)
312 312 assert_equal 'text/csv', @response.content_type
313 313 assert @response.body.starts_with?("#,")
314 314 lines = @response.body.chomp.split("\n")
315 315 assert_equal assigns(:query).available_columns.size + 1, lines[0].split(',').size
316 316 end
317 317
318 318 def test_index_csv_big_5
319 319 with_settings :default_language => "zh-TW" do
320 320 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
321 321 str_big5 = "\xa4@\xa4\xeb"
322 322 if str_utf8.respond_to?(:force_encoding)
323 323 str_utf8.force_encoding('UTF-8')
324 324 str_big5.force_encoding('Big5')
325 325 end
326 326 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
327 327 :status_id => 1, :priority => IssuePriority.all.first,
328 328 :subject => str_utf8)
329 329 assert issue.save
330 330
331 331 get :index, :project_id => 1,
332 332 :f => ['subject'],
333 333 :op => '=', :values => [str_utf8],
334 334 :format => 'csv'
335 335 assert_equal 'text/csv', @response.content_type
336 336 lines = @response.body.chomp.split("\n")
337 337 s1 = "\xaa\xac\xbaA"
338 338 if str_utf8.respond_to?(:force_encoding)
339 339 s1.force_encoding('Big5')
340 340 end
341 341 assert lines[0].include?(s1)
342 342 assert lines[1].include?(str_big5)
343 343 end
344 344 end
345 345
346 346 def test_index_csv_cannot_convert_should_be_replaced_big_5
347 347 with_settings :default_language => "zh-TW" do
348 348 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
349 349 if str_utf8.respond_to?(:force_encoding)
350 350 str_utf8.force_encoding('UTF-8')
351 351 end
352 352 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
353 353 :status_id => 1, :priority => IssuePriority.all.first,
354 354 :subject => str_utf8)
355 355 assert issue.save
356 356
357 357 get :index, :project_id => 1,
358 358 :f => ['subject'],
359 359 :op => '=', :values => [str_utf8],
360 360 :c => ['status', 'subject'],
361 361 :format => 'csv',
362 362 :set_filter => 1
363 363 assert_equal 'text/csv', @response.content_type
364 364 lines = @response.body.chomp.split("\n")
365 365 s1 = "\xaa\xac\xbaA" # status
366 366 if str_utf8.respond_to?(:force_encoding)
367 367 s1.force_encoding('Big5')
368 368 end
369 369 assert lines[0].include?(s1)
370 370 s2 = lines[1].split(",")[2]
371 371 if s1.respond_to?(:force_encoding)
372 372 s3 = "\xa5H?" # subject
373 373 s3.force_encoding('Big5')
374 374 assert_equal s3, s2
375 375 elsif RUBY_PLATFORM == 'java'
376 376 assert_equal "??", s2
377 377 else
378 378 assert_equal "\xa5H???", s2
379 379 end
380 380 end
381 381 end
382 382
383 def test_index_csv_tw
384 with_settings :default_language => "zh-TW" do
385 str1 = "test_index_csv_tw"
386 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
387 :status_id => 1, :priority => IssuePriority.all.first,
388 :subject => str1, :estimated_hours => '1234.5')
389 assert issue.save
390 assert_equal 1234.5, issue.estimated_hours
391
392 get :index, :project_id => 1,
393 :f => ['subject'],
394 :op => '=', :values => [str1],
395 :c => ['estimated_hours', 'subject'],
396 :format => 'csv',
397 :set_filter => 1
398 assert_equal 'text/csv', @response.content_type
399 lines = @response.body.chomp.split("\n")
400 assert_equal "#{issue.id},1234.5,#{str1}", lines[1]
401
402 str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
403 if str_tw.respond_to?(:force_encoding)
404 str_tw.force_encoding('UTF-8')
405 end
406 assert_equal str_tw, l(:general_lang_name)
407 assert_equal ',', l(:general_csv_separator)
408 assert_equal '.', l(:general_csv_decimal_separator)
409 end
410 end
411
412 def test_index_csv_fr
413 with_settings :default_language => "fr" do
414 str1 = "test_index_csv_fr"
415 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
416 :status_id => 1, :priority => IssuePriority.all.first,
417 :subject => str1, :estimated_hours => '1234.5')
418 assert issue.save
419 assert_equal 1234.5, issue.estimated_hours
420
421 get :index, :project_id => 1,
422 :f => ['subject'],
423 :op => '=', :values => [str1],
424 :c => ['estimated_hours', 'subject'],
425 :format => 'csv',
426 :set_filter => 1
427 assert_equal 'text/csv', @response.content_type
428 lines = @response.body.chomp.split("\n")
429 assert_equal "#{issue.id};1234,5;#{str1}", lines[1]
430
431 str_fr = "Fran\xc3\xa7ais"
432 if str_fr.respond_to?(:force_encoding)
433 str_fr.force_encoding('UTF-8')
434 end
435 assert_equal str_fr, l(:general_lang_name)
436 assert_equal ';', l(:general_csv_separator)
437 assert_equal ',', l(:general_csv_decimal_separator)
438 end
439 end
440
383 441 def test_index_pdf
384 442 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
385 443 with_settings :default_language => lang do
386 444
387 445 get :index
388 446 assert_response :success
389 447 assert_template 'index'
390 448
391 449 if lang == "ja"
392 450 if RUBY_PLATFORM != 'java'
393 451 assert_equal "CP932", l(:general_pdf_encoding)
394 452 end
395 453 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
396 454 next
397 455 end
398 456 end
399 457
400 458 get :index, :format => 'pdf'
401 459 assert_response :success
402 460 assert_not_nil assigns(:issues)
403 461 assert_equal 'application/pdf', @response.content_type
404 462
405 463 get :index, :project_id => 1, :format => 'pdf'
406 464 assert_response :success
407 465 assert_not_nil assigns(:issues)
408 466 assert_equal 'application/pdf', @response.content_type
409 467
410 468 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
411 469 assert_response :success
412 470 assert_not_nil assigns(:issues)
413 471 assert_equal 'application/pdf', @response.content_type
414 472 end
415 473 end
416 474 end
417 475
418 476 def test_index_pdf_with_query_grouped_by_list_custom_field
419 477 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
420 478 assert_response :success
421 479 assert_not_nil assigns(:issues)
422 480 assert_not_nil assigns(:issue_count_by_group)
423 481 assert_equal 'application/pdf', @response.content_type
424 482 end
425 483
426 484 def test_index_sort
427 485 get :index, :sort => 'tracker,id:desc'
428 486 assert_response :success
429 487
430 488 sort_params = @request.session['issues_index_sort']
431 489 assert sort_params.is_a?(String)
432 490 assert_equal 'tracker,id:desc', sort_params
433 491
434 492 issues = assigns(:issues)
435 493 assert_not_nil issues
436 494 assert !issues.empty?
437 495 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
438 496 end
439 497
440 498 def test_index_sort_by_field_not_included_in_columns
441 499 Setting.issue_list_default_columns = %w(subject author)
442 500 get :index, :sort => 'tracker'
443 501 end
444 502
445 503 def test_index_sort_by_assigned_to
446 504 get :index, :sort => 'assigned_to'
447 505 assert_response :success
448 506 assignees = assigns(:issues).collect(&:assigned_to).compact
449 507 assert_equal assignees.sort, assignees
450 508 end
451 509
452 510 def test_index_sort_by_assigned_to_desc
453 511 get :index, :sort => 'assigned_to:desc'
454 512 assert_response :success
455 513 assignees = assigns(:issues).collect(&:assigned_to).compact
456 514 assert_equal assignees.sort.reverse, assignees
457 515 end
458 516
459 517 def test_index_group_by_assigned_to
460 518 get :index, :group_by => 'assigned_to', :sort => 'priority'
461 519 assert_response :success
462 520 end
463 521
464 522 def test_index_sort_by_author
465 523 get :index, :sort => 'author'
466 524 assert_response :success
467 525 authors = assigns(:issues).collect(&:author)
468 526 assert_equal authors.sort, authors
469 527 end
470 528
471 529 def test_index_sort_by_author_desc
472 530 get :index, :sort => 'author:desc'
473 531 assert_response :success
474 532 authors = assigns(:issues).collect(&:author)
475 533 assert_equal authors.sort.reverse, authors
476 534 end
477 535
478 536 def test_index_group_by_author
479 537 get :index, :group_by => 'author', :sort => 'priority'
480 538 assert_response :success
481 539 end
482 540
483 541 def test_index_with_columns
484 542 columns = ['tracker', 'subject', 'assigned_to']
485 543 get :index, :set_filter => 1, :c => columns
486 544 assert_response :success
487 545
488 546 # query should use specified columns
489 547 query = assigns(:query)
490 548 assert_kind_of Query, query
491 549 assert_equal columns, query.column_names.map(&:to_s)
492 550
493 551 # columns should be stored in session
494 552 assert_kind_of Hash, session[:query]
495 553 assert_kind_of Array, session[:query][:column_names]
496 554 assert_equal columns, session[:query][:column_names].map(&:to_s)
497 555
498 556 # ensure only these columns are kept in the selected columns list
499 557 assert_tag :tag => 'select', :attributes => { :id => 'selected_columns' },
500 558 :children => { :count => 3 }
501 559 assert_no_tag :tag => 'option', :attributes => { :value => 'project' },
502 560 :parent => { :tag => 'select', :attributes => { :id => "selected_columns" } }
503 561 end
504 562
505 563 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
506 564 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
507 565 get :index, :set_filter => 1
508 566
509 567 # query should use specified columns
510 568 query = assigns(:query)
511 569 assert_kind_of Query, query
512 570 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
513 571 end
514 572
515 573 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
516 574 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
517 575 columns = ['tracker', 'subject', 'assigned_to']
518 576 get :index, :set_filter => 1, :c => columns
519 577
520 578 # query should use specified columns
521 579 query = assigns(:query)
522 580 assert_kind_of Query, query
523 581 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
524 582 end
525 583
526 584 def test_index_with_custom_field_column
527 585 columns = %w(tracker subject cf_2)
528 586 get :index, :set_filter => 1, :c => columns
529 587 assert_response :success
530 588
531 589 # query should use specified columns
532 590 query = assigns(:query)
533 591 assert_kind_of Query, query
534 592 assert_equal columns, query.column_names.map(&:to_s)
535 593
536 594 assert_tag :td,
537 595 :attributes => {:class => 'cf_2 string'},
538 596 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
539 597 end
540 598
541 599 def test_index_send_html_if_query_is_invalid
542 600 get :index, :f => ['start_date'], :op => {:start_date => '='}
543 601 assert_equal 'text/html', @response.content_type
544 602 assert_template 'index'
545 603 end
546 604
547 605 def test_index_send_nothing_if_query_is_invalid
548 606 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
549 607 assert_equal 'text/csv', @response.content_type
550 608 assert @response.body.blank?
551 609 end
552 610
553 611 def test_show_by_anonymous
554 612 get :show, :id => 1
555 613 assert_response :success
556 614 assert_template 'show'
557 615 assert_not_nil assigns(:issue)
558 616 assert_equal Issue.find(1), assigns(:issue)
559 617
560 618 # anonymous role is allowed to add a note
561 619 assert_tag :tag => 'form',
562 620 :descendant => { :tag => 'fieldset',
563 621 :child => { :tag => 'legend',
564 622 :content => /Notes/ } }
565 623 assert_tag :tag => 'title',
566 624 :content => "Bug #1: Can't print recipes - eCookbook - Redmine"
567 625 end
568 626
569 627 def test_show_by_manager
570 628 @request.session[:user_id] = 2
571 629 get :show, :id => 1
572 630 assert_response :success
573 631
574 632 assert_tag :tag => 'a',
575 633 :content => /Quote/
576 634
577 635 assert_tag :tag => 'form',
578 636 :descendant => { :tag => 'fieldset',
579 637 :child => { :tag => 'legend',
580 638 :content => /Change properties/ } },
581 639 :descendant => { :tag => 'fieldset',
582 640 :child => { :tag => 'legend',
583 641 :content => /Log time/ } },
584 642 :descendant => { :tag => 'fieldset',
585 643 :child => { :tag => 'legend',
586 644 :content => /Notes/ } }
587 645 end
588 646
589 647 def test_update_form_should_not_display_inactive_enumerations
590 648 @request.session[:user_id] = 2
591 649 get :show, :id => 1
592 650 assert_response :success
593 651
594 652 assert ! IssuePriority.find(15).active?
595 653 assert_no_tag :option, :attributes => {:value => '15'},
596 654 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
597 655 end
598 656
599 657 def test_update_form_should_allow_attachment_upload
600 658 @request.session[:user_id] = 2
601 659 get :show, :id => 1
602 660
603 661 assert_tag :tag => 'form',
604 662 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
605 663 :descendant => {
606 664 :tag => 'input',
607 665 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
608 666 }
609 667 end
610 668
611 669 def test_show_should_deny_anonymous_access_without_permission
612 670 Role.anonymous.remove_permission!(:view_issues)
613 671 get :show, :id => 1
614 672 assert_response :redirect
615 673 end
616 674
617 675 def test_show_should_deny_anonymous_access_to_private_issue
618 676 Issue.update_all(["is_private = ?", true], "id = 1")
619 677 get :show, :id => 1
620 678 assert_response :redirect
621 679 end
622 680
623 681 def test_show_should_deny_non_member_access_without_permission
624 682 Role.non_member.remove_permission!(:view_issues)
625 683 @request.session[:user_id] = 9
626 684 get :show, :id => 1
627 685 assert_response 403
628 686 end
629 687
630 688 def test_show_should_deny_non_member_access_to_private_issue
631 689 Issue.update_all(["is_private = ?", true], "id = 1")
632 690 @request.session[:user_id] = 9
633 691 get :show, :id => 1
634 692 assert_response 403
635 693 end
636 694
637 695 def test_show_should_deny_member_access_without_permission
638 696 Role.find(1).remove_permission!(:view_issues)
639 697 @request.session[:user_id] = 2
640 698 get :show, :id => 1
641 699 assert_response 403
642 700 end
643 701
644 702 def test_show_should_deny_member_access_to_private_issue_without_permission
645 703 Issue.update_all(["is_private = ?", true], "id = 1")
646 704 @request.session[:user_id] = 3
647 705 get :show, :id => 1
648 706 assert_response 403
649 707 end
650 708
651 709 def test_show_should_allow_author_access_to_private_issue
652 710 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
653 711 @request.session[:user_id] = 3
654 712 get :show, :id => 1
655 713 assert_response :success
656 714 end
657 715
658 716 def test_show_should_allow_assignee_access_to_private_issue
659 717 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
660 718 @request.session[:user_id] = 3
661 719 get :show, :id => 1
662 720 assert_response :success
663 721 end
664 722
665 723 def test_show_should_allow_member_access_to_private_issue_with_permission
666 724 Issue.update_all(["is_private = ?", true], "id = 1")
667 725 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
668 726 @request.session[:user_id] = 3
669 727 get :show, :id => 1
670 728 assert_response :success
671 729 end
672 730
673 731 def test_show_should_not_disclose_relations_to_invisible_issues
674 732 Setting.cross_project_issue_relations = '1'
675 733 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
676 734 # Relation to a private project issue
677 735 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
678 736
679 737 get :show, :id => 1
680 738 assert_response :success
681 739
682 740 assert_tag :div, :attributes => { :id => 'relations' },
683 741 :descendant => { :tag => 'a', :content => /#2$/ }
684 742 assert_no_tag :div, :attributes => { :id => 'relations' },
685 743 :descendant => { :tag => 'a', :content => /#4$/ }
686 744 end
687 745
688 746 def test_show_atom
689 747 get :show, :id => 2, :format => 'atom'
690 748 assert_response :success
691 749 assert_template 'journals/index'
692 750 # Inline image
693 751 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
694 752 end
695 753
696 754 def test_show_export_to_pdf
697 755 get :show, :id => 3, :format => 'pdf'
698 756 assert_response :success
699 757 assert_equal 'application/pdf', @response.content_type
700 758 assert @response.body.starts_with?('%PDF')
701 759 assert_not_nil assigns(:issue)
702 760 end
703 761
704 762 def test_get_new
705 763 @request.session[:user_id] = 2
706 764 get :new, :project_id => 1, :tracker_id => 1
707 765 assert_response :success
708 766 assert_template 'new'
709 767
710 768 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
711 769 :value => 'Default string' }
712 770
713 771 # Be sure we don't display inactive IssuePriorities
714 772 assert ! IssuePriority.find(15).active?
715 773 assert_no_tag :option, :attributes => {:value => '15'},
716 774 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
717 775 end
718 776
719 777 def test_get_new_without_default_start_date_is_creation_date
720 778 Setting.default_issue_start_date_to_creation_date = 0
721 779
722 780 @request.session[:user_id] = 2
723 781 get :new, :project_id => 1, :tracker_id => 1
724 782 assert_response :success
725 783 assert_template 'new'
726 784
727 785 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
728 786 :value => nil }
729 787 end
730 788
731 789 def test_get_new_with_default_start_date_is_creation_date
732 790 Setting.default_issue_start_date_to_creation_date = 1
733 791
734 792 @request.session[:user_id] = 2
735 793 get :new, :project_id => 1, :tracker_id => 1
736 794 assert_response :success
737 795 assert_template 'new'
738 796
739 797 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
740 798 :value => Date.today.to_s }
741 799 end
742 800
743 801 def test_get_new_form_should_allow_attachment_upload
744 802 @request.session[:user_id] = 2
745 803 get :new, :project_id => 1, :tracker_id => 1
746 804
747 805 assert_tag :tag => 'form',
748 806 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
749 807 :descendant => {
750 808 :tag => 'input',
751 809 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
752 810 }
753 811 end
754 812
755 813 def test_get_new_without_tracker_id
756 814 @request.session[:user_id] = 2
757 815 get :new, :project_id => 1
758 816 assert_response :success
759 817 assert_template 'new'
760 818
761 819 issue = assigns(:issue)
762 820 assert_not_nil issue
763 821 assert_equal Project.find(1).trackers.first, issue.tracker
764 822 end
765 823
766 824 def test_get_new_with_no_default_status_should_display_an_error
767 825 @request.session[:user_id] = 2
768 826 IssueStatus.delete_all
769 827
770 828 get :new, :project_id => 1
771 829 assert_response 500
772 830 assert_error_tag :content => /No default issue/
773 831 end
774 832
775 833 def test_get_new_with_no_tracker_should_display_an_error
776 834 @request.session[:user_id] = 2
777 835 Tracker.delete_all
778 836
779 837 get :new, :project_id => 1
780 838 assert_response 500
781 839 assert_error_tag :content => /No tracker/
782 840 end
783 841
784 842 def test_update_new_form
785 843 @request.session[:user_id] = 2
786 844 xhr :post, :new, :project_id => 1,
787 845 :issue => {:tracker_id => 2,
788 846 :subject => 'This is the test_new issue',
789 847 :description => 'This is the description',
790 848 :priority_id => 5}
791 849 assert_response :success
792 850 assert_template 'attributes'
793 851
794 852 issue = assigns(:issue)
795 853 assert_kind_of Issue, issue
796 854 assert_equal 1, issue.project_id
797 855 assert_equal 2, issue.tracker_id
798 856 assert_equal 'This is the test_new issue', issue.subject
799 857 end
800 858
801 859 def test_post_create
802 860 @request.session[:user_id] = 2
803 861 assert_difference 'Issue.count' do
804 862 post :create, :project_id => 1,
805 863 :issue => {:tracker_id => 3,
806 864 :status_id => 2,
807 865 :subject => 'This is the test_new issue',
808 866 :description => 'This is the description',
809 867 :priority_id => 5,
810 868 :start_date => '2010-11-07',
811 869 :estimated_hours => '',
812 870 :custom_field_values => {'2' => 'Value for field 2'}}
813 871 end
814 872 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
815 873
816 874 issue = Issue.find_by_subject('This is the test_new issue')
817 875 assert_not_nil issue
818 876 assert_equal 2, issue.author_id
819 877 assert_equal 3, issue.tracker_id
820 878 assert_equal 2, issue.status_id
821 879 assert_equal Date.parse('2010-11-07'), issue.start_date
822 880 assert_nil issue.estimated_hours
823 881 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
824 882 assert_not_nil v
825 883 assert_equal 'Value for field 2', v.value
826 884 end
827 885
828 886 def test_post_new_with_group_assignment
829 887 group = Group.find(11)
830 888 project = Project.find(1)
831 889 project.members << Member.new(:principal => group, :roles => [Role.first])
832 890
833 891 with_settings :issue_group_assignment => '1' do
834 892 @request.session[:user_id] = 2
835 893 assert_difference 'Issue.count' do
836 894 post :create, :project_id => project.id,
837 895 :issue => {:tracker_id => 3,
838 896 :status_id => 1,
839 897 :subject => 'This is the test_new_with_group_assignment issue',
840 898 :assigned_to_id => group.id}
841 899 end
842 900 end
843 901 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
844 902
845 903 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
846 904 assert_not_nil issue
847 905 assert_equal group, issue.assigned_to
848 906 end
849 907
850 908 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
851 909 Setting.default_issue_start_date_to_creation_date = 0
852 910
853 911 @request.session[:user_id] = 2
854 912 assert_difference 'Issue.count' do
855 913 post :create, :project_id => 1,
856 914 :issue => {:tracker_id => 3,
857 915 :status_id => 2,
858 916 :subject => 'This is the test_new issue',
859 917 :description => 'This is the description',
860 918 :priority_id => 5,
861 919 :estimated_hours => '',
862 920 :custom_field_values => {'2' => 'Value for field 2'}}
863 921 end
864 922 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
865 923
866 924 issue = Issue.find_by_subject('This is the test_new issue')
867 925 assert_not_nil issue
868 926 assert_nil issue.start_date
869 927 end
870 928
871 929 def test_post_create_without_start_date_and_default_start_date_is_creation_date
872 930 Setting.default_issue_start_date_to_creation_date = 1
873 931
874 932 @request.session[:user_id] = 2
875 933 assert_difference 'Issue.count' do
876 934 post :create, :project_id => 1,
877 935 :issue => {:tracker_id => 3,
878 936 :status_id => 2,
879 937 :subject => 'This is the test_new issue',
880 938 :description => 'This is the description',
881 939 :priority_id => 5,
882 940 :estimated_hours => '',
883 941 :custom_field_values => {'2' => 'Value for field 2'}}
884 942 end
885 943 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
886 944
887 945 issue = Issue.find_by_subject('This is the test_new issue')
888 946 assert_not_nil issue
889 947 assert_equal Date.today, issue.start_date
890 948 end
891 949
892 950 def test_post_create_and_continue
893 951 @request.session[:user_id] = 2
894 952 assert_difference 'Issue.count' do
895 953 post :create, :project_id => 1,
896 954 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
897 955 :continue => ''
898 956 end
899 957
900 958 issue = Issue.first(:order => 'id DESC')
901 959 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
902 960 assert_not_nil flash[:notice], "flash was not set"
903 961 assert flash[:notice].include?("<a href='/issues/#{issue.id}'>##{issue.id}</a>"), "issue link not found in flash: #{flash[:notice]}"
904 962 end
905 963
906 964 def test_post_create_without_custom_fields_param
907 965 @request.session[:user_id] = 2
908 966 assert_difference 'Issue.count' do
909 967 post :create, :project_id => 1,
910 968 :issue => {:tracker_id => 1,
911 969 :subject => 'This is the test_new issue',
912 970 :description => 'This is the description',
913 971 :priority_id => 5}
914 972 end
915 973 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
916 974 end
917 975
918 976 def test_post_create_with_required_custom_field_and_without_custom_fields_param
919 977 field = IssueCustomField.find_by_name('Database')
920 978 field.update_attribute(:is_required, true)
921 979
922 980 @request.session[:user_id] = 2
923 981 post :create, :project_id => 1,
924 982 :issue => {:tracker_id => 1,
925 983 :subject => 'This is the test_new issue',
926 984 :description => 'This is the description',
927 985 :priority_id => 5}
928 986 assert_response :success
929 987 assert_template 'new'
930 988 issue = assigns(:issue)
931 989 assert_not_nil issue
932 990 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
933 991 end
934 992
935 993 def test_post_create_with_watchers
936 994 @request.session[:user_id] = 2
937 995 ActionMailer::Base.deliveries.clear
938 996
939 997 assert_difference 'Watcher.count', 2 do
940 998 post :create, :project_id => 1,
941 999 :issue => {:tracker_id => 1,
942 1000 :subject => 'This is a new issue with watchers',
943 1001 :description => 'This is the description',
944 1002 :priority_id => 5,
945 1003 :watcher_user_ids => ['2', '3']}
946 1004 end
947 1005 issue = Issue.find_by_subject('This is a new issue with watchers')
948 1006 assert_not_nil issue
949 1007 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
950 1008
951 1009 # Watchers added
952 1010 assert_equal [2, 3], issue.watcher_user_ids.sort
953 1011 assert issue.watched_by?(User.find(3))
954 1012 # Watchers notified
955 1013 mail = ActionMailer::Base.deliveries.last
956 1014 assert_kind_of TMail::Mail, mail
957 1015 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
958 1016 end
959 1017
960 1018 def test_post_create_subissue
961 1019 @request.session[:user_id] = 2
962 1020
963 1021 assert_difference 'Issue.count' do
964 1022 post :create, :project_id => 1,
965 1023 :issue => {:tracker_id => 1,
966 1024 :subject => 'This is a child issue',
967 1025 :parent_issue_id => 2}
968 1026 end
969 1027 issue = Issue.find_by_subject('This is a child issue')
970 1028 assert_not_nil issue
971 1029 assert_equal Issue.find(2), issue.parent
972 1030 end
973 1031
974 1032 def test_post_create_subissue_with_non_numeric_parent_id
975 1033 @request.session[:user_id] = 2
976 1034
977 1035 assert_difference 'Issue.count' do
978 1036 post :create, :project_id => 1,
979 1037 :issue => {:tracker_id => 1,
980 1038 :subject => 'This is a child issue',
981 1039 :parent_issue_id => 'ABC'}
982 1040 end
983 1041 issue = Issue.find_by_subject('This is a child issue')
984 1042 assert_not_nil issue
985 1043 assert_nil issue.parent
986 1044 end
987 1045
988 1046 def test_post_create_private
989 1047 @request.session[:user_id] = 2
990 1048
991 1049 assert_difference 'Issue.count' do
992 1050 post :create, :project_id => 1,
993 1051 :issue => {:tracker_id => 1,
994 1052 :subject => 'This is a private issue',
995 1053 :is_private => '1'}
996 1054 end
997 1055 issue = Issue.first(:order => 'id DESC')
998 1056 assert issue.is_private?
999 1057 end
1000 1058
1001 1059 def test_post_create_private_with_set_own_issues_private_permission
1002 1060 role = Role.find(1)
1003 1061 role.remove_permission! :set_issues_private
1004 1062 role.add_permission! :set_own_issues_private
1005 1063
1006 1064 @request.session[:user_id] = 2
1007 1065
1008 1066 assert_difference 'Issue.count' do
1009 1067 post :create, :project_id => 1,
1010 1068 :issue => {:tracker_id => 1,
1011 1069 :subject => 'This is a private issue',
1012 1070 :is_private => '1'}
1013 1071 end
1014 1072 issue = Issue.first(:order => 'id DESC')
1015 1073 assert issue.is_private?
1016 1074 end
1017 1075
1018 1076 def test_post_create_should_send_a_notification
1019 1077 ActionMailer::Base.deliveries.clear
1020 1078 @request.session[:user_id] = 2
1021 1079 assert_difference 'Issue.count' do
1022 1080 post :create, :project_id => 1,
1023 1081 :issue => {:tracker_id => 3,
1024 1082 :subject => 'This is the test_new issue',
1025 1083 :description => 'This is the description',
1026 1084 :priority_id => 5,
1027 1085 :estimated_hours => '',
1028 1086 :custom_field_values => {'2' => 'Value for field 2'}}
1029 1087 end
1030 1088 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1031 1089
1032 1090 assert_equal 1, ActionMailer::Base.deliveries.size
1033 1091 end
1034 1092
1035 1093 def test_post_create_should_preserve_fields_values_on_validation_failure
1036 1094 @request.session[:user_id] = 2
1037 1095 post :create, :project_id => 1,
1038 1096 :issue => {:tracker_id => 1,
1039 1097 # empty subject
1040 1098 :subject => '',
1041 1099 :description => 'This is a description',
1042 1100 :priority_id => 6,
1043 1101 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
1044 1102 assert_response :success
1045 1103 assert_template 'new'
1046 1104
1047 1105 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
1048 1106 :content => 'This is a description'
1049 1107 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1050 1108 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1051 1109 :value => '6' },
1052 1110 :content => 'High' }
1053 1111 # Custom fields
1054 1112 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
1055 1113 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1056 1114 :value => 'Oracle' },
1057 1115 :content => 'Oracle' }
1058 1116 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
1059 1117 :value => 'Value for field 2'}
1060 1118 end
1061 1119
1062 1120 def test_post_create_should_ignore_non_safe_attributes
1063 1121 @request.session[:user_id] = 2
1064 1122 assert_nothing_raised do
1065 1123 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
1066 1124 end
1067 1125 end
1068 1126
1069 1127 def test_post_create_with_attachment
1070 1128 set_tmp_attachments_directory
1071 1129 @request.session[:user_id] = 2
1072 1130
1073 1131 assert_difference 'Issue.count' do
1074 1132 assert_difference 'Attachment.count' do
1075 1133 post :create, :project_id => 1,
1076 1134 :issue => { :tracker_id => '1', :subject => 'With attachment' },
1077 1135 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1078 1136 end
1079 1137 end
1080 1138
1081 1139 issue = Issue.first(:order => 'id DESC')
1082 1140 attachment = Attachment.first(:order => 'id DESC')
1083 1141
1084 1142 assert_equal issue, attachment.container
1085 1143 assert_equal 2, attachment.author_id
1086 1144 assert_equal 'testfile.txt', attachment.filename
1087 1145 assert_equal 'text/plain', attachment.content_type
1088 1146 assert_equal 'test file', attachment.description
1089 1147 assert_equal 59, attachment.filesize
1090 1148 assert File.exists?(attachment.diskfile)
1091 1149 assert_equal 59, File.size(attachment.diskfile)
1092 1150 end
1093 1151
1094 1152 context "without workflow privilege" do
1095 1153 setup do
1096 1154 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1097 1155 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1098 1156 end
1099 1157
1100 1158 context "#new" do
1101 1159 should "propose default status only" do
1102 1160 get :new, :project_id => 1
1103 1161 assert_response :success
1104 1162 assert_template 'new'
1105 1163 assert_tag :tag => 'select',
1106 1164 :attributes => {:name => 'issue[status_id]'},
1107 1165 :children => {:count => 1},
1108 1166 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
1109 1167 end
1110 1168
1111 1169 should "accept default status" do
1112 1170 assert_difference 'Issue.count' do
1113 1171 post :create, :project_id => 1,
1114 1172 :issue => {:tracker_id => 1,
1115 1173 :subject => 'This is an issue',
1116 1174 :status_id => 1}
1117 1175 end
1118 1176 issue = Issue.last(:order => 'id')
1119 1177 assert_equal IssueStatus.default, issue.status
1120 1178 end
1121 1179
1122 1180 should "ignore unauthorized status" do
1123 1181 assert_difference 'Issue.count' do
1124 1182 post :create, :project_id => 1,
1125 1183 :issue => {:tracker_id => 1,
1126 1184 :subject => 'This is an issue',
1127 1185 :status_id => 3}
1128 1186 end
1129 1187 issue = Issue.last(:order => 'id')
1130 1188 assert_equal IssueStatus.default, issue.status
1131 1189 end
1132 1190 end
1133 1191
1134 1192 context "#update" do
1135 1193 should "ignore status change" do
1136 1194 assert_difference 'Journal.count' do
1137 1195 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1138 1196 end
1139 1197 assert_equal 1, Issue.find(1).status_id
1140 1198 end
1141 1199
1142 1200 should "ignore attributes changes" do
1143 1201 assert_difference 'Journal.count' do
1144 1202 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1145 1203 end
1146 1204 issue = Issue.find(1)
1147 1205 assert_equal "Can't print recipes", issue.subject
1148 1206 assert_nil issue.assigned_to
1149 1207 end
1150 1208 end
1151 1209 end
1152 1210
1153 1211 context "with workflow privilege" do
1154 1212 setup do
1155 1213 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1156 1214 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1157 1215 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1158 1216 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1159 1217 end
1160 1218
1161 1219 context "#update" do
1162 1220 should "accept authorized status" do
1163 1221 assert_difference 'Journal.count' do
1164 1222 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1165 1223 end
1166 1224 assert_equal 3, Issue.find(1).status_id
1167 1225 end
1168 1226
1169 1227 should "ignore unauthorized status" do
1170 1228 assert_difference 'Journal.count' do
1171 1229 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1172 1230 end
1173 1231 assert_equal 1, Issue.find(1).status_id
1174 1232 end
1175 1233
1176 1234 should "accept authorized attributes changes" do
1177 1235 assert_difference 'Journal.count' do
1178 1236 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
1179 1237 end
1180 1238 issue = Issue.find(1)
1181 1239 assert_equal 2, issue.assigned_to_id
1182 1240 end
1183 1241
1184 1242 should "ignore unauthorized attributes changes" do
1185 1243 assert_difference 'Journal.count' do
1186 1244 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
1187 1245 end
1188 1246 issue = Issue.find(1)
1189 1247 assert_equal "Can't print recipes", issue.subject
1190 1248 end
1191 1249 end
1192 1250
1193 1251 context "and :edit_issues permission" do
1194 1252 setup do
1195 1253 Role.anonymous.add_permission! :add_issues, :edit_issues
1196 1254 end
1197 1255
1198 1256 should "accept authorized status" do
1199 1257 assert_difference 'Journal.count' do
1200 1258 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1201 1259 end
1202 1260 assert_equal 3, Issue.find(1).status_id
1203 1261 end
1204 1262
1205 1263 should "ignore unauthorized status" do
1206 1264 assert_difference 'Journal.count' do
1207 1265 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1208 1266 end
1209 1267 assert_equal 1, Issue.find(1).status_id
1210 1268 end
1211 1269
1212 1270 should "accept authorized attributes changes" do
1213 1271 assert_difference 'Journal.count' do
1214 1272 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1215 1273 end
1216 1274 issue = Issue.find(1)
1217 1275 assert_equal "changed", issue.subject
1218 1276 assert_equal 2, issue.assigned_to_id
1219 1277 end
1220 1278 end
1221 1279 end
1222 1280
1223 1281 def test_copy_issue
1224 1282 @request.session[:user_id] = 2
1225 1283 get :new, :project_id => 1, :copy_from => 1
1226 1284 assert_template 'new'
1227 1285 assert_not_nil assigns(:issue)
1228 1286 orig = Issue.find(1)
1229 1287 assert_equal orig.subject, assigns(:issue).subject
1230 1288 end
1231 1289
1232 1290 def test_get_edit
1233 1291 @request.session[:user_id] = 2
1234 1292 get :edit, :id => 1
1235 1293 assert_response :success
1236 1294 assert_template 'edit'
1237 1295 assert_not_nil assigns(:issue)
1238 1296 assert_equal Issue.find(1), assigns(:issue)
1239 1297
1240 1298 # Be sure we don't display inactive IssuePriorities
1241 1299 assert ! IssuePriority.find(15).active?
1242 1300 assert_no_tag :option, :attributes => {:value => '15'},
1243 1301 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1244 1302 end
1245 1303
1246 1304 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
1247 1305 @request.session[:user_id] = 2
1248 1306 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
1249 1307
1250 1308 get :edit, :id => 1
1251 1309 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
1252 1310 end
1253 1311
1254 1312 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
1255 1313 @request.session[:user_id] = 2
1256 1314 Role.find_by_name('Manager').remove_permission! :log_time
1257 1315
1258 1316 get :edit, :id => 1
1259 1317 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
1260 1318 end
1261 1319
1262 1320 def test_get_edit_with_params
1263 1321 @request.session[:user_id] = 2
1264 1322 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
1265 1323 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
1266 1324 assert_response :success
1267 1325 assert_template 'edit'
1268 1326
1269 1327 issue = assigns(:issue)
1270 1328 assert_not_nil issue
1271 1329
1272 1330 assert_equal 5, issue.status_id
1273 1331 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
1274 1332 :child => { :tag => 'option',
1275 1333 :content => 'Closed',
1276 1334 :attributes => { :selected => 'selected' } }
1277 1335
1278 1336 assert_equal 7, issue.priority_id
1279 1337 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1280 1338 :child => { :tag => 'option',
1281 1339 :content => 'Urgent',
1282 1340 :attributes => { :selected => 'selected' } }
1283 1341
1284 1342 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
1285 1343 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
1286 1344 :child => { :tag => 'option',
1287 1345 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
1288 1346 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
1289 1347 end
1290 1348
1291 1349 def test_update_edit_form
1292 1350 @request.session[:user_id] = 2
1293 1351 xhr :post, :new, :project_id => 1,
1294 1352 :id => 1,
1295 1353 :issue => {:tracker_id => 2,
1296 1354 :subject => 'This is the test_new issue',
1297 1355 :description => 'This is the description',
1298 1356 :priority_id => 5}
1299 1357 assert_response :success
1300 1358 assert_template 'attributes'
1301 1359
1302 1360 issue = assigns(:issue)
1303 1361 assert_kind_of Issue, issue
1304 1362 assert_equal 1, issue.id
1305 1363 assert_equal 1, issue.project_id
1306 1364 assert_equal 2, issue.tracker_id
1307 1365 assert_equal 'This is the test_new issue', issue.subject
1308 1366 end
1309 1367
1310 1368 def test_update_using_invalid_http_verbs
1311 1369 @request.session[:user_id] = 2
1312 1370 subject = 'Updated by an invalid http verb'
1313 1371
1314 1372 get :update, :id => 1, :issue => {:subject => subject}
1315 1373 assert_not_equal subject, Issue.find(1).subject
1316 1374
1317 1375 post :update, :id => 1, :issue => {:subject => subject}
1318 1376 assert_not_equal subject, Issue.find(1).subject
1319 1377
1320 1378 delete :update, :id => 1, :issue => {:subject => subject}
1321 1379 assert_not_equal subject, Issue.find(1).subject
1322 1380 end
1323 1381
1324 1382 def test_put_update_without_custom_fields_param
1325 1383 @request.session[:user_id] = 2
1326 1384 ActionMailer::Base.deliveries.clear
1327 1385
1328 1386 issue = Issue.find(1)
1329 1387 assert_equal '125', issue.custom_value_for(2).value
1330 1388 old_subject = issue.subject
1331 1389 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
1332 1390
1333 1391 assert_difference('Journal.count') do
1334 1392 assert_difference('JournalDetail.count', 2) do
1335 1393 put :update, :id => 1, :issue => {:subject => new_subject,
1336 1394 :priority_id => '6',
1337 1395 :category_id => '1' # no change
1338 1396 }
1339 1397 end
1340 1398 end
1341 1399 assert_redirected_to :action => 'show', :id => '1'
1342 1400 issue.reload
1343 1401 assert_equal new_subject, issue.subject
1344 1402 # Make sure custom fields were not cleared
1345 1403 assert_equal '125', issue.custom_value_for(2).value
1346 1404
1347 1405 mail = ActionMailer::Base.deliveries.last
1348 1406 assert_kind_of TMail::Mail, mail
1349 1407 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
1350 1408 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
1351 1409 end
1352 1410
1353 1411 def test_put_update_with_custom_field_change
1354 1412 @request.session[:user_id] = 2
1355 1413 issue = Issue.find(1)
1356 1414 assert_equal '125', issue.custom_value_for(2).value
1357 1415
1358 1416 assert_difference('Journal.count') do
1359 1417 assert_difference('JournalDetail.count', 3) do
1360 1418 put :update, :id => 1, :issue => {:subject => 'Custom field change',
1361 1419 :priority_id => '6',
1362 1420 :category_id => '1', # no change
1363 1421 :custom_field_values => { '2' => 'New custom value' }
1364 1422 }
1365 1423 end
1366 1424 end
1367 1425 assert_redirected_to :action => 'show', :id => '1'
1368 1426 issue.reload
1369 1427 assert_equal 'New custom value', issue.custom_value_for(2).value
1370 1428
1371 1429 mail = ActionMailer::Base.deliveries.last
1372 1430 assert_kind_of TMail::Mail, mail
1373 1431 assert mail.body.include?("Searchable field changed from 125 to New custom value")
1374 1432 end
1375 1433
1376 1434 def test_put_update_with_status_and_assignee_change
1377 1435 issue = Issue.find(1)
1378 1436 assert_equal 1, issue.status_id
1379 1437 @request.session[:user_id] = 2
1380 1438 assert_difference('TimeEntry.count', 0) do
1381 1439 put :update,
1382 1440 :id => 1,
1383 1441 :issue => { :status_id => 2, :assigned_to_id => 3 },
1384 1442 :notes => 'Assigned to dlopper',
1385 1443 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
1386 1444 end
1387 1445 assert_redirected_to :action => 'show', :id => '1'
1388 1446 issue.reload
1389 1447 assert_equal 2, issue.status_id
1390 1448 j = Journal.find(:first, :order => 'id DESC')
1391 1449 assert_equal 'Assigned to dlopper', j.notes
1392 1450 assert_equal 2, j.details.size
1393 1451
1394 1452 mail = ActionMailer::Base.deliveries.last
1395 1453 assert mail.body.include?("Status changed from New to Assigned")
1396 1454 # subject should contain the new status
1397 1455 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
1398 1456 end
1399 1457
1400 1458 def test_put_update_with_note_only
1401 1459 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
1402 1460 # anonymous user
1403 1461 put :update,
1404 1462 :id => 1,
1405 1463 :notes => notes
1406 1464 assert_redirected_to :action => 'show', :id => '1'
1407 1465 j = Journal.find(:first, :order => 'id DESC')
1408 1466 assert_equal notes, j.notes
1409 1467 assert_equal 0, j.details.size
1410 1468 assert_equal User.anonymous, j.user
1411 1469
1412 1470 mail = ActionMailer::Base.deliveries.last
1413 1471 assert mail.body.include?(notes)
1414 1472 end
1415 1473
1416 1474 def test_put_update_with_note_and_spent_time
1417 1475 @request.session[:user_id] = 2
1418 1476 spent_hours_before = Issue.find(1).spent_hours
1419 1477 assert_difference('TimeEntry.count') do
1420 1478 put :update,
1421 1479 :id => 1,
1422 1480 :notes => '2.5 hours added',
1423 1481 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
1424 1482 end
1425 1483 assert_redirected_to :action => 'show', :id => '1'
1426 1484
1427 1485 issue = Issue.find(1)
1428 1486
1429 1487 j = Journal.find(:first, :order => 'id DESC')
1430 1488 assert_equal '2.5 hours added', j.notes
1431 1489 assert_equal 0, j.details.size
1432 1490
1433 1491 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
1434 1492 assert_not_nil t
1435 1493 assert_equal 2.5, t.hours
1436 1494 assert_equal spent_hours_before + 2.5, issue.spent_hours
1437 1495 end
1438 1496
1439 1497 def test_put_update_with_attachment_only
1440 1498 set_tmp_attachments_directory
1441 1499
1442 1500 # Delete all fixtured journals, a race condition can occur causing the wrong
1443 1501 # journal to get fetched in the next find.
1444 1502 Journal.delete_all
1445 1503
1446 1504 # anonymous user
1447 1505 assert_difference 'Attachment.count' do
1448 1506 put :update, :id => 1,
1449 1507 :notes => '',
1450 1508 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1451 1509 end
1452 1510
1453 1511 assert_redirected_to :action => 'show', :id => '1'
1454 1512 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
1455 1513 assert j.notes.blank?
1456 1514 assert_equal 1, j.details.size
1457 1515 assert_equal 'testfile.txt', j.details.first.value
1458 1516 assert_equal User.anonymous, j.user
1459 1517
1460 1518 attachment = Attachment.first(:order => 'id DESC')
1461 1519 assert_equal Issue.find(1), attachment.container
1462 1520 assert_equal User.anonymous, attachment.author
1463 1521 assert_equal 'testfile.txt', attachment.filename
1464 1522 assert_equal 'text/plain', attachment.content_type
1465 1523 assert_equal 'test file', attachment.description
1466 1524 assert_equal 59, attachment.filesize
1467 1525 assert File.exists?(attachment.diskfile)
1468 1526 assert_equal 59, File.size(attachment.diskfile)
1469 1527
1470 1528 mail = ActionMailer::Base.deliveries.last
1471 1529 assert mail.body.include?('testfile.txt')
1472 1530 end
1473 1531
1474 1532 def test_put_update_with_attachment_that_fails_to_save
1475 1533 set_tmp_attachments_directory
1476 1534
1477 1535 # Delete all fixtured journals, a race condition can occur causing the wrong
1478 1536 # journal to get fetched in the next find.
1479 1537 Journal.delete_all
1480 1538
1481 1539 # Mock out the unsaved attachment
1482 1540 Attachment.any_instance.stubs(:create).returns(Attachment.new)
1483 1541
1484 1542 # anonymous user
1485 1543 put :update,
1486 1544 :id => 1,
1487 1545 :notes => '',
1488 1546 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
1489 1547 assert_redirected_to :action => 'show', :id => '1'
1490 1548 assert_equal '1 file(s) could not be saved.', flash[:warning]
1491 1549
1492 1550 end if Object.const_defined?(:Mocha)
1493 1551
1494 1552 def test_put_update_with_no_change
1495 1553 issue = Issue.find(1)
1496 1554 issue.journals.clear
1497 1555 ActionMailer::Base.deliveries.clear
1498 1556
1499 1557 put :update,
1500 1558 :id => 1,
1501 1559 :notes => ''
1502 1560 assert_redirected_to :action => 'show', :id => '1'
1503 1561
1504 1562 issue.reload
1505 1563 assert issue.journals.empty?
1506 1564 # No email should be sent
1507 1565 assert ActionMailer::Base.deliveries.empty?
1508 1566 end
1509 1567
1510 1568 def test_put_update_should_send_a_notification
1511 1569 @request.session[:user_id] = 2
1512 1570 ActionMailer::Base.deliveries.clear
1513 1571 issue = Issue.find(1)
1514 1572 old_subject = issue.subject
1515 1573 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
1516 1574
1517 1575 put :update, :id => 1, :issue => {:subject => new_subject,
1518 1576 :priority_id => '6',
1519 1577 :category_id => '1' # no change
1520 1578 }
1521 1579 assert_equal 1, ActionMailer::Base.deliveries.size
1522 1580 end
1523 1581
1524 1582 def test_put_update_with_invalid_spent_time_hours_only
1525 1583 @request.session[:user_id] = 2
1526 1584 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1527 1585
1528 1586 assert_no_difference('Journal.count') do
1529 1587 put :update,
1530 1588 :id => 1,
1531 1589 :notes => notes,
1532 1590 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
1533 1591 end
1534 1592 assert_response :success
1535 1593 assert_template 'edit'
1536 1594
1537 1595 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1538 1596 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1539 1597 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
1540 1598 end
1541 1599
1542 1600 def test_put_update_with_invalid_spent_time_comments_only
1543 1601 @request.session[:user_id] = 2
1544 1602 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1545 1603
1546 1604 assert_no_difference('Journal.count') do
1547 1605 put :update,
1548 1606 :id => 1,
1549 1607 :notes => notes,
1550 1608 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
1551 1609 end
1552 1610 assert_response :success
1553 1611 assert_template 'edit'
1554 1612
1555 1613 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1556 1614 assert_error_tag :descendant => {:content => /Hours can't be blank/}
1557 1615 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1558 1616 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
1559 1617 end
1560 1618
1561 1619 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
1562 1620 issue = Issue.find(2)
1563 1621 @request.session[:user_id] = 2
1564 1622
1565 1623 put :update,
1566 1624 :id => issue.id,
1567 1625 :issue => {
1568 1626 :fixed_version_id => 4
1569 1627 }
1570 1628
1571 1629 assert_response :redirect
1572 1630 issue.reload
1573 1631 assert_equal 4, issue.fixed_version_id
1574 1632 assert_not_equal issue.project_id, issue.fixed_version.project_id
1575 1633 end
1576 1634
1577 1635 def test_put_update_should_redirect_back_using_the_back_url_parameter
1578 1636 issue = Issue.find(2)
1579 1637 @request.session[:user_id] = 2
1580 1638
1581 1639 put :update,
1582 1640 :id => issue.id,
1583 1641 :issue => {
1584 1642 :fixed_version_id => 4
1585 1643 },
1586 1644 :back_url => '/issues'
1587 1645
1588 1646 assert_response :redirect
1589 1647 assert_redirected_to '/issues'
1590 1648 end
1591 1649
1592 1650 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1593 1651 issue = Issue.find(2)
1594 1652 @request.session[:user_id] = 2
1595 1653
1596 1654 put :update,
1597 1655 :id => issue.id,
1598 1656 :issue => {
1599 1657 :fixed_version_id => 4
1600 1658 },
1601 1659 :back_url => 'http://google.com'
1602 1660
1603 1661 assert_response :redirect
1604 1662 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
1605 1663 end
1606 1664
1607 1665 def test_get_bulk_edit
1608 1666 @request.session[:user_id] = 2
1609 1667 get :bulk_edit, :ids => [1, 2]
1610 1668 assert_response :success
1611 1669 assert_template 'bulk_edit'
1612 1670
1613 1671 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1614 1672
1615 1673 # Project specific custom field, date type
1616 1674 field = CustomField.find(9)
1617 1675 assert !field.is_for_all?
1618 1676 assert_equal 'date', field.field_format
1619 1677 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1620 1678
1621 1679 # System wide custom field
1622 1680 assert CustomField.find(1).is_for_all?
1623 1681 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
1624 1682
1625 1683 # Be sure we don't display inactive IssuePriorities
1626 1684 assert ! IssuePriority.find(15).active?
1627 1685 assert_no_tag :option, :attributes => {:value => '15'},
1628 1686 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1629 1687 end
1630 1688
1631 1689 def test_get_bulk_edit_on_different_projects
1632 1690 @request.session[:user_id] = 2
1633 1691 get :bulk_edit, :ids => [1, 2, 6]
1634 1692 assert_response :success
1635 1693 assert_template 'bulk_edit'
1636 1694
1637 1695 # Can not set issues from different projects as children of an issue
1638 1696 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1639 1697
1640 1698 # Project specific custom field, date type
1641 1699 field = CustomField.find(9)
1642 1700 assert !field.is_for_all?
1643 1701 assert !field.project_ids.include?(Issue.find(6).project_id)
1644 1702 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1645 1703 end
1646 1704
1647 1705 def test_get_bulk_edit_with_user_custom_field
1648 1706 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
1649 1707
1650 1708 @request.session[:user_id] = 2
1651 1709 get :bulk_edit, :ids => [1, 2]
1652 1710 assert_response :success
1653 1711 assert_template 'bulk_edit'
1654 1712
1655 1713 assert_tag :select,
1656 1714 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1657 1715 :children => {
1658 1716 :only => {:tag => 'option'},
1659 1717 :count => Project.find(1).users.count + 1
1660 1718 }
1661 1719 end
1662 1720
1663 1721 def test_get_bulk_edit_with_version_custom_field
1664 1722 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
1665 1723
1666 1724 @request.session[:user_id] = 2
1667 1725 get :bulk_edit, :ids => [1, 2]
1668 1726 assert_response :success
1669 1727 assert_template 'bulk_edit'
1670 1728
1671 1729 assert_tag :select,
1672 1730 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1673 1731 :children => {
1674 1732 :only => {:tag => 'option'},
1675 1733 :count => Project.find(1).shared_versions.count + 1
1676 1734 }
1677 1735 end
1678 1736
1679 1737 def test_bulk_update
1680 1738 @request.session[:user_id] = 2
1681 1739 # update issues priority
1682 1740 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1683 1741 :issue => {:priority_id => 7,
1684 1742 :assigned_to_id => '',
1685 1743 :custom_field_values => {'2' => ''}}
1686 1744
1687 1745 assert_response 302
1688 1746 # check that the issues were updated
1689 1747 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
1690 1748
1691 1749 issue = Issue.find(1)
1692 1750 journal = issue.journals.find(:first, :order => 'created_on DESC')
1693 1751 assert_equal '125', issue.custom_value_for(2).value
1694 1752 assert_equal 'Bulk editing', journal.notes
1695 1753 assert_equal 1, journal.details.size
1696 1754 end
1697 1755
1698 1756 def test_bulk_update_with_group_assignee
1699 1757 group = Group.find(11)
1700 1758 project = Project.find(1)
1701 1759 project.members << Member.new(:principal => group, :roles => [Role.first])
1702 1760
1703 1761 @request.session[:user_id] = 2
1704 1762 # update issues assignee
1705 1763 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1706 1764 :issue => {:priority_id => '',
1707 1765 :assigned_to_id => group.id,
1708 1766 :custom_field_values => {'2' => ''}}
1709 1767
1710 1768 assert_response 302
1711 1769 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
1712 1770 end
1713 1771
1714 1772 def test_bulk_update_on_different_projects
1715 1773 @request.session[:user_id] = 2
1716 1774 # update issues priority
1717 1775 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
1718 1776 :issue => {:priority_id => 7,
1719 1777 :assigned_to_id => '',
1720 1778 :custom_field_values => {'2' => ''}}
1721 1779
1722 1780 assert_response 302
1723 1781 # check that the issues were updated
1724 1782 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
1725 1783
1726 1784 issue = Issue.find(1)
1727 1785 journal = issue.journals.find(:first, :order => 'created_on DESC')
1728 1786 assert_equal '125', issue.custom_value_for(2).value
1729 1787 assert_equal 'Bulk editing', journal.notes
1730 1788 assert_equal 1, journal.details.size
1731 1789 end
1732 1790
1733 1791 def test_bulk_update_on_different_projects_without_rights
1734 1792 @request.session[:user_id] = 3
1735 1793 user = User.find(3)
1736 1794 action = { :controller => "issues", :action => "bulk_update" }
1737 1795 assert user.allowed_to?(action, Issue.find(1).project)
1738 1796 assert ! user.allowed_to?(action, Issue.find(6).project)
1739 1797 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
1740 1798 :issue => {:priority_id => 7,
1741 1799 :assigned_to_id => '',
1742 1800 :custom_field_values => {'2' => ''}}
1743 1801 assert_response 403
1744 1802 assert_not_equal "Bulk should fail", Journal.last.notes
1745 1803 end
1746 1804
1747 1805 def test_bullk_update_should_send_a_notification
1748 1806 @request.session[:user_id] = 2
1749 1807 ActionMailer::Base.deliveries.clear
1750 1808 post(:bulk_update,
1751 1809 {
1752 1810 :ids => [1, 2],
1753 1811 :notes => 'Bulk editing',
1754 1812 :issue => {
1755 1813 :priority_id => 7,
1756 1814 :assigned_to_id => '',
1757 1815 :custom_field_values => {'2' => ''}
1758 1816 }
1759 1817 })
1760 1818
1761 1819 assert_response 302
1762 1820 assert_equal 2, ActionMailer::Base.deliveries.size
1763 1821 end
1764 1822
1765 1823 def test_bulk_update_status
1766 1824 @request.session[:user_id] = 2
1767 1825 # update issues priority
1768 1826 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
1769 1827 :issue => {:priority_id => '',
1770 1828 :assigned_to_id => '',
1771 1829 :status_id => '5'}
1772 1830
1773 1831 assert_response 302
1774 1832 issue = Issue.find(1)
1775 1833 assert issue.closed?
1776 1834 end
1777 1835
1778 1836 def test_bulk_update_parent_id
1779 1837 @request.session[:user_id] = 2
1780 1838 post :bulk_update, :ids => [1, 3],
1781 1839 :notes => 'Bulk editing parent',
1782 1840 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
1783 1841
1784 1842 assert_response 302
1785 1843 parent = Issue.find(2)
1786 1844 assert_equal parent.id, Issue.find(1).parent_id
1787 1845 assert_equal parent.id, Issue.find(3).parent_id
1788 1846 assert_equal [1, 3], parent.children.collect(&:id).sort
1789 1847 end
1790 1848
1791 1849 def test_bulk_update_custom_field
1792 1850 @request.session[:user_id] = 2
1793 1851 # update issues priority
1794 1852 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
1795 1853 :issue => {:priority_id => '',
1796 1854 :assigned_to_id => '',
1797 1855 :custom_field_values => {'2' => '777'}}
1798 1856
1799 1857 assert_response 302
1800 1858
1801 1859 issue = Issue.find(1)
1802 1860 journal = issue.journals.find(:first, :order => 'created_on DESC')
1803 1861 assert_equal '777', issue.custom_value_for(2).value
1804 1862 assert_equal 1, journal.details.size
1805 1863 assert_equal '125', journal.details.first.old_value
1806 1864 assert_equal '777', journal.details.first.value
1807 1865 end
1808 1866
1809 1867 def test_bulk_update_unassign
1810 1868 assert_not_nil Issue.find(2).assigned_to
1811 1869 @request.session[:user_id] = 2
1812 1870 # unassign issues
1813 1871 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1814 1872 assert_response 302
1815 1873 # check that the issues were updated
1816 1874 assert_nil Issue.find(2).assigned_to
1817 1875 end
1818 1876
1819 1877 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
1820 1878 @request.session[:user_id] = 2
1821 1879
1822 1880 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
1823 1881
1824 1882 assert_response :redirect
1825 1883 issues = Issue.find([1,2])
1826 1884 issues.each do |issue|
1827 1885 assert_equal 4, issue.fixed_version_id
1828 1886 assert_not_equal issue.project_id, issue.fixed_version.project_id
1829 1887 end
1830 1888 end
1831 1889
1832 1890 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
1833 1891 @request.session[:user_id] = 2
1834 1892 post :bulk_update, :ids => [1,2], :back_url => '/issues'
1835 1893
1836 1894 assert_response :redirect
1837 1895 assert_redirected_to '/issues'
1838 1896 end
1839 1897
1840 1898 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1841 1899 @request.session[:user_id] = 2
1842 1900 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
1843 1901
1844 1902 assert_response :redirect
1845 1903 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1846 1904 end
1847 1905
1848 1906 def test_destroy_issue_with_no_time_entries
1849 1907 assert_nil TimeEntry.find_by_issue_id(2)
1850 1908 @request.session[:user_id] = 2
1851 1909 post :destroy, :id => 2
1852 1910 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1853 1911 assert_nil Issue.find_by_id(2)
1854 1912 end
1855 1913
1856 1914 def test_destroy_issues_with_time_entries
1857 1915 @request.session[:user_id] = 2
1858 1916 post :destroy, :ids => [1, 3]
1859 1917 assert_response :success
1860 1918 assert_template 'destroy'
1861 1919 assert_not_nil assigns(:hours)
1862 1920 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1863 1921 end
1864 1922
1865 1923 def test_destroy_issues_and_destroy_time_entries
1866 1924 @request.session[:user_id] = 2
1867 1925 post :destroy, :ids => [1, 3], :todo => 'destroy'
1868 1926 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1869 1927 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1870 1928 assert_nil TimeEntry.find_by_id([1, 2])
1871 1929 end
1872 1930
1873 1931 def test_destroy_issues_and_assign_time_entries_to_project
1874 1932 @request.session[:user_id] = 2
1875 1933 post :destroy, :ids => [1, 3], :todo => 'nullify'
1876 1934 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1877 1935 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1878 1936 assert_nil TimeEntry.find(1).issue_id
1879 1937 assert_nil TimeEntry.find(2).issue_id
1880 1938 end
1881 1939
1882 1940 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1883 1941 @request.session[:user_id] = 2
1884 1942 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1885 1943 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1886 1944 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1887 1945 assert_equal 2, TimeEntry.find(1).issue_id
1888 1946 assert_equal 2, TimeEntry.find(2).issue_id
1889 1947 end
1890 1948
1891 1949 def test_destroy_issues_from_different_projects
1892 1950 @request.session[:user_id] = 2
1893 1951 post :destroy, :ids => [1, 2, 6], :todo => 'destroy'
1894 1952 assert_redirected_to :controller => 'issues', :action => 'index'
1895 1953 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
1896 1954 end
1897 1955
1898 1956 def test_destroy_parent_and_child_issues
1899 1957 parent = Issue.generate!(:project_id => 1, :tracker_id => 1)
1900 1958 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id)
1901 1959 assert child.is_descendant_of?(parent.reload)
1902 1960
1903 1961 @request.session[:user_id] = 2
1904 1962 assert_difference 'Issue.count', -2 do
1905 1963 post :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
1906 1964 end
1907 1965 assert_response 302
1908 1966 end
1909 1967
1910 1968 def test_default_search_scope
1911 1969 get :index
1912 1970 assert_tag :div, :attributes => {:id => 'quick-search'},
1913 1971 :child => {:tag => 'form',
1914 1972 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
1915 1973 end
1916 1974 end
General Comments 0
You need to be logged in to leave comments. Login now