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