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