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