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