##// END OF EJS Templates
Merged r9982 from trunk....
Jean-Philippe Lang -
r9815:873a5cda4fb3
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,3358 +1,3359
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 Workflow.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_visible_changesets_from_other_projects
1118 1118 project = Project.find(2)
1119 1119 issue = project.issues.first
1120 1120 issue.changeset_ids = [102]
1121 1121 issue.save!
1122 1122 project.disable_module! :repository
1123 1123
1124 1124 @request.session[:user_id] = 2
1125 1125 get :show, :id => issue.id
1126 1126 assert_tag 'a', :attributes => {:href => "/projects/ecookbook/repository/revisions/3"}
1127 1127 end
1128 1128
1129 1129 def test_show_should_display_watchers
1130 1130 @request.session[:user_id] = 2
1131 1131 Issue.find(1).add_watcher User.find(2)
1132 1132
1133 1133 get :show, :id => 1
1134 1134 assert_select 'div#watchers ul' do
1135 1135 assert_select 'li' do
1136 1136 assert_select 'a[href=/users/2]'
1137 1137 assert_select 'a img[alt=Delete]'
1138 1138 end
1139 1139 end
1140 1140 end
1141 1141
1142 1142 def test_show_should_display_watchers_with_gravatars
1143 1143 @request.session[:user_id] = 2
1144 1144 Issue.find(1).add_watcher User.find(2)
1145 1145
1146 1146 with_settings :gravatar_enabled => '1' do
1147 1147 get :show, :id => 1
1148 1148 end
1149 1149
1150 1150 assert_select 'div#watchers ul' do
1151 1151 assert_select 'li' do
1152 1152 assert_select 'img.gravatar'
1153 1153 assert_select 'a[href=/users/2]'
1154 1154 assert_select 'a img[alt=Delete]'
1155 1155 end
1156 1156 end
1157 1157 end
1158 1158
1159 1159 def test_show_with_multi_custom_field
1160 1160 field = CustomField.find(1)
1161 1161 field.update_attribute :multiple, true
1162 1162 issue = Issue.find(1)
1163 1163 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1164 1164 issue.save!
1165 1165
1166 1166 get :show, :id => 1
1167 1167 assert_response :success
1168 1168
1169 1169 assert_tag :td, :content => 'MySQL, Oracle'
1170 1170 end
1171 1171
1172 1172 def test_show_with_multi_user_custom_field
1173 1173 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1174 1174 :tracker_ids => [1], :is_for_all => true)
1175 1175 issue = Issue.find(1)
1176 1176 issue.custom_field_values = {field.id => ['2', '3']}
1177 1177 issue.save!
1178 1178
1179 1179 get :show, :id => 1
1180 1180 assert_response :success
1181 1181
1182 1182 # TODO: should display links
1183 1183 assert_tag :td, :content => 'Dave Lopper, John Smith'
1184 1184 end
1185 1185
1186 1186 def test_show_atom
1187 1187 get :show, :id => 2, :format => 'atom'
1188 1188 assert_response :success
1189 1189 assert_template 'journals/index'
1190 1190 # Inline image
1191 1191 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1192 1192 end
1193 1193
1194 1194 def test_show_export_to_pdf
1195 1195 get :show, :id => 3, :format => 'pdf'
1196 1196 assert_response :success
1197 1197 assert_equal 'application/pdf', @response.content_type
1198 1198 assert @response.body.starts_with?('%PDF')
1199 1199 assert_not_nil assigns(:issue)
1200 1200 end
1201 1201
1202 1202 def test_show_export_to_pdf_with_ancestors
1203 1203 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1204 1204
1205 1205 get :show, :id => issue.id, :format => 'pdf'
1206 1206 assert_response :success
1207 1207 assert_equal 'application/pdf', @response.content_type
1208 1208 assert @response.body.starts_with?('%PDF')
1209 1209 end
1210 1210
1211 1211 def test_show_export_to_pdf_with_descendants
1212 1212 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1213 1213 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1214 1214 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1215 1215
1216 1216 get :show, :id => 1, :format => 'pdf'
1217 1217 assert_response :success
1218 1218 assert_equal 'application/pdf', @response.content_type
1219 1219 assert @response.body.starts_with?('%PDF')
1220 1220 end
1221 1221
1222 1222 def test_show_export_to_pdf_with_journals
1223 1223 get :show, :id => 1, :format => 'pdf'
1224 1224 assert_response :success
1225 1225 assert_equal 'application/pdf', @response.content_type
1226 1226 assert @response.body.starts_with?('%PDF')
1227 1227 end
1228 1228
1229 1229 def test_show_export_to_pdf_with_changesets
1230 1230 Issue.find(3).changesets = Changeset.find_all_by_id(100, 101, 102)
1231 1231
1232 1232 get :show, :id => 3, :format => 'pdf'
1233 1233 assert_response :success
1234 1234 assert_equal 'application/pdf', @response.content_type
1235 1235 assert @response.body.starts_with?('%PDF')
1236 1236 end
1237 1237
1238 1238 def test_get_new
1239 1239 @request.session[:user_id] = 2
1240 1240 get :new, :project_id => 1, :tracker_id => 1
1241 1241 assert_response :success
1242 1242 assert_template 'new'
1243 1243
1244 1244 assert_tag 'input', :attributes => {:name => 'issue[is_private]'}
1245 1245 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1246 1246 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1247 1247 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1248 1248 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1249 1249 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1250 1250 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1251 1251 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1252 1252 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1253 1253 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1254 1254 assert_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1255 1255 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1256 1256 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1257 1257 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1258 1258 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1259 1259 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1260 1260
1261 1261 # Be sure we don't display inactive IssuePriorities
1262 1262 assert ! IssuePriority.find(15).active?
1263 1263 assert_no_tag :option, :attributes => {:value => '15'},
1264 1264 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1265 1265 end
1266 1266
1267 1267 def test_get_new_with_minimal_permissions
1268 1268 Role.find(1).update_attribute :permissions, [:add_issues]
1269 1269 Workflow.delete_all :role_id => 1
1270 1270
1271 1271 @request.session[:user_id] = 2
1272 1272 get :new, :project_id => 1, :tracker_id => 1
1273 1273 assert_response :success
1274 1274 assert_template 'new'
1275 1275
1276 1276 assert_no_tag 'input', :attributes => {:name => 'issue[is_private]'}
1277 1277 assert_no_tag 'select', :attributes => {:name => 'issue[project_id]'}
1278 1278 assert_tag 'select', :attributes => {:name => 'issue[tracker_id]'}
1279 1279 assert_tag 'input', :attributes => {:name => 'issue[subject]'}
1280 1280 assert_tag 'textarea', :attributes => {:name => 'issue[description]'}
1281 1281 assert_tag 'select', :attributes => {:name => 'issue[status_id]'}
1282 1282 assert_tag 'select', :attributes => {:name => 'issue[priority_id]'}
1283 1283 assert_tag 'select', :attributes => {:name => 'issue[assigned_to_id]'}
1284 1284 assert_tag 'select', :attributes => {:name => 'issue[category_id]'}
1285 1285 assert_tag 'select', :attributes => {:name => 'issue[fixed_version_id]'}
1286 1286 assert_no_tag 'input', :attributes => {:name => 'issue[parent_issue_id]'}
1287 1287 assert_tag 'input', :attributes => {:name => 'issue[start_date]'}
1288 1288 assert_tag 'input', :attributes => {:name => 'issue[due_date]'}
1289 1289 assert_tag 'select', :attributes => {:name => 'issue[done_ratio]'}
1290 1290 assert_tag 'input', :attributes => { :name => 'issue[custom_field_values][2]', :value => 'Default string' }
1291 1291 assert_no_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]'}
1292 1292 end
1293 1293
1294 1294 def test_get_new_with_list_custom_field
1295 1295 @request.session[:user_id] = 2
1296 1296 get :new, :project_id => 1, :tracker_id => 1
1297 1297 assert_response :success
1298 1298 assert_template 'new'
1299 1299
1300 1300 assert_tag 'select',
1301 1301 :attributes => {:name => 'issue[custom_field_values][1]', :class => 'list_cf'},
1302 1302 :children => {:count => 4},
1303 1303 :child => {:tag => 'option', :attributes => {:value => 'MySQL'}, :content => 'MySQL'}
1304 1304 end
1305 1305
1306 1306 def test_get_new_with_multi_custom_field
1307 1307 field = IssueCustomField.find(1)
1308 1308 field.update_attribute :multiple, true
1309 1309
1310 1310 @request.session[:user_id] = 2
1311 1311 get :new, :project_id => 1, :tracker_id => 1
1312 1312 assert_response :success
1313 1313 assert_template 'new'
1314 1314
1315 1315 assert_tag 'select',
1316 1316 :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'},
1317 1317 :children => {:count => 3},
1318 1318 :child => {:tag => 'option', :attributes => {:value => 'MySQL'}, :content => 'MySQL'}
1319 1319 assert_tag 'input',
1320 1320 :attributes => {:name => 'issue[custom_field_values][1][]', :value => ''}
1321 1321 end
1322 1322
1323 1323 def test_get_new_with_multi_user_custom_field
1324 1324 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1325 1325 :tracker_ids => [1], :is_for_all => true)
1326 1326
1327 1327 @request.session[:user_id] = 2
1328 1328 get :new, :project_id => 1, :tracker_id => 1
1329 1329 assert_response :success
1330 1330 assert_template 'new'
1331 1331
1332 1332 assert_tag 'select',
1333 1333 :attributes => {:name => "issue[custom_field_values][#{field.id}][]", :multiple => 'multiple'},
1334 1334 :children => {:count => Project.find(1).users.count},
1335 1335 :child => {:tag => 'option', :attributes => {:value => '2'}, :content => 'John Smith'}
1336 1336 assert_tag 'input',
1337 1337 :attributes => {:name => "issue[custom_field_values][#{field.id}][]", :value => ''}
1338 1338 end
1339 1339
1340 1340 def test_get_new_without_default_start_date_is_creation_date
1341 1341 Setting.default_issue_start_date_to_creation_date = 0
1342 1342
1343 1343 @request.session[:user_id] = 2
1344 1344 get :new, :project_id => 1, :tracker_id => 1
1345 1345 assert_response :success
1346 1346 assert_template 'new'
1347 1347
1348 1348 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
1349 1349 :value => nil }
1350 1350 end
1351 1351
1352 1352 def test_get_new_with_default_start_date_is_creation_date
1353 1353 Setting.default_issue_start_date_to_creation_date = 1
1354 1354
1355 1355 @request.session[:user_id] = 2
1356 1356 get :new, :project_id => 1, :tracker_id => 1
1357 1357 assert_response :success
1358 1358 assert_template 'new'
1359 1359
1360 1360 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
1361 1361 :value => Date.today.to_s }
1362 1362 end
1363 1363
1364 1364 def test_get_new_form_should_allow_attachment_upload
1365 1365 @request.session[:user_id] = 2
1366 1366 get :new, :project_id => 1, :tracker_id => 1
1367 1367
1368 1368 assert_tag :tag => 'form',
1369 1369 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
1370 1370 :descendant => {
1371 1371 :tag => 'input',
1372 1372 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
1373 1373 }
1374 assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
1374 1375 end
1375 1376
1376 1377 def test_get_new_should_prefill_the_form_from_params
1377 1378 @request.session[:user_id] = 2
1378 1379 get :new, :project_id => 1,
1379 1380 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1380 1381
1381 1382 issue = assigns(:issue)
1382 1383 assert_equal 3, issue.tracker_id
1383 1384 assert_equal 'Prefilled', issue.description
1384 1385 assert_equal 'Custom field value', issue.custom_field_value(2)
1385 1386
1386 1387 assert_tag 'select',
1387 1388 :attributes => {:name => 'issue[tracker_id]'},
1388 1389 :child => {:tag => 'option', :attributes => {:value => '3', :selected => 'selected'}}
1389 1390 assert_tag 'textarea',
1390 1391 :attributes => {:name => 'issue[description]'}, :content => "\nPrefilled"
1391 1392 assert_tag 'input',
1392 1393 :attributes => {:name => 'issue[custom_field_values][2]', :value => 'Custom field value'}
1393 1394 end
1394 1395
1395 1396 def test_get_new_without_tracker_id
1396 1397 @request.session[:user_id] = 2
1397 1398 get :new, :project_id => 1
1398 1399 assert_response :success
1399 1400 assert_template 'new'
1400 1401
1401 1402 issue = assigns(:issue)
1402 1403 assert_not_nil issue
1403 1404 assert_equal Project.find(1).trackers.first, issue.tracker
1404 1405 end
1405 1406
1406 1407 def test_get_new_with_no_default_status_should_display_an_error
1407 1408 @request.session[:user_id] = 2
1408 1409 IssueStatus.delete_all
1409 1410
1410 1411 get :new, :project_id => 1
1411 1412 assert_response 500
1412 1413 assert_error_tag :content => /No default issue/
1413 1414 end
1414 1415
1415 1416 def test_get_new_with_no_tracker_should_display_an_error
1416 1417 @request.session[:user_id] = 2
1417 1418 Tracker.delete_all
1418 1419
1419 1420 get :new, :project_id => 1
1420 1421 assert_response 500
1421 1422 assert_error_tag :content => /No tracker/
1422 1423 end
1423 1424
1424 1425 def test_update_new_form
1425 1426 @request.session[:user_id] = 2
1426 1427 xhr :post, :new, :project_id => 1,
1427 1428 :issue => {:tracker_id => 2,
1428 1429 :subject => 'This is the test_new issue',
1429 1430 :description => 'This is the description',
1430 1431 :priority_id => 5}
1431 1432 assert_response :success
1432 1433 assert_template 'attributes'
1433 1434
1434 1435 issue = assigns(:issue)
1435 1436 assert_kind_of Issue, issue
1436 1437 assert_equal 1, issue.project_id
1437 1438 assert_equal 2, issue.tracker_id
1438 1439 assert_equal 'This is the test_new issue', issue.subject
1439 1440 end
1440 1441
1441 1442 def test_update_new_form_should_propose_transitions_based_on_initial_status
1442 1443 @request.session[:user_id] = 2
1443 1444 Workflow.delete_all
1444 1445 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1445 1446 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1446 1447 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1447 1448
1448 1449 xhr :post, :new, :project_id => 1,
1449 1450 :issue => {:tracker_id => 1,
1450 1451 :status_id => 5,
1451 1452 :subject => 'This is an issue'}
1452 1453
1453 1454 assert_equal 5, assigns(:issue).status_id
1454 1455 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
1455 1456 end
1456 1457
1457 1458 def test_post_create
1458 1459 @request.session[:user_id] = 2
1459 1460 assert_difference 'Issue.count' do
1460 1461 post :create, :project_id => 1,
1461 1462 :issue => {:tracker_id => 3,
1462 1463 :status_id => 2,
1463 1464 :subject => 'This is the test_new issue',
1464 1465 :description => 'This is the description',
1465 1466 :priority_id => 5,
1466 1467 :start_date => '2010-11-07',
1467 1468 :estimated_hours => '',
1468 1469 :custom_field_values => {'2' => 'Value for field 2'}}
1469 1470 end
1470 1471 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1471 1472
1472 1473 issue = Issue.find_by_subject('This is the test_new issue')
1473 1474 assert_not_nil issue
1474 1475 assert_equal 2, issue.author_id
1475 1476 assert_equal 3, issue.tracker_id
1476 1477 assert_equal 2, issue.status_id
1477 1478 assert_equal Date.parse('2010-11-07'), issue.start_date
1478 1479 assert_nil issue.estimated_hours
1479 1480 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
1480 1481 assert_not_nil v
1481 1482 assert_equal 'Value for field 2', v.value
1482 1483 end
1483 1484
1484 1485 def test_post_new_with_group_assignment
1485 1486 group = Group.find(11)
1486 1487 project = Project.find(1)
1487 1488 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
1488 1489
1489 1490 with_settings :issue_group_assignment => '1' do
1490 1491 @request.session[:user_id] = 2
1491 1492 assert_difference 'Issue.count' do
1492 1493 post :create, :project_id => project.id,
1493 1494 :issue => {:tracker_id => 3,
1494 1495 :status_id => 1,
1495 1496 :subject => 'This is the test_new_with_group_assignment issue',
1496 1497 :assigned_to_id => group.id}
1497 1498 end
1498 1499 end
1499 1500 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1500 1501
1501 1502 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
1502 1503 assert_not_nil issue
1503 1504 assert_equal group, issue.assigned_to
1504 1505 end
1505 1506
1506 1507 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
1507 1508 Setting.default_issue_start_date_to_creation_date = 0
1508 1509
1509 1510 @request.session[:user_id] = 2
1510 1511 assert_difference 'Issue.count' do
1511 1512 post :create, :project_id => 1,
1512 1513 :issue => {:tracker_id => 3,
1513 1514 :status_id => 2,
1514 1515 :subject => 'This is the test_new issue',
1515 1516 :description => 'This is the description',
1516 1517 :priority_id => 5,
1517 1518 :estimated_hours => '',
1518 1519 :custom_field_values => {'2' => 'Value for field 2'}}
1519 1520 end
1520 1521 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1521 1522
1522 1523 issue = Issue.find_by_subject('This is the test_new issue')
1523 1524 assert_not_nil issue
1524 1525 assert_nil issue.start_date
1525 1526 end
1526 1527
1527 1528 def test_post_create_without_start_date_and_default_start_date_is_creation_date
1528 1529 Setting.default_issue_start_date_to_creation_date = 1
1529 1530
1530 1531 @request.session[:user_id] = 2
1531 1532 assert_difference 'Issue.count' do
1532 1533 post :create, :project_id => 1,
1533 1534 :issue => {:tracker_id => 3,
1534 1535 :status_id => 2,
1535 1536 :subject => 'This is the test_new issue',
1536 1537 :description => 'This is the description',
1537 1538 :priority_id => 5,
1538 1539 :estimated_hours => '',
1539 1540 :custom_field_values => {'2' => 'Value for field 2'}}
1540 1541 end
1541 1542 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1542 1543
1543 1544 issue = Issue.find_by_subject('This is the test_new issue')
1544 1545 assert_not_nil issue
1545 1546 assert_equal Date.today, issue.start_date
1546 1547 end
1547 1548
1548 1549 def test_post_create_and_continue
1549 1550 @request.session[:user_id] = 2
1550 1551 assert_difference 'Issue.count' do
1551 1552 post :create, :project_id => 1,
1552 1553 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
1553 1554 :continue => ''
1554 1555 end
1555 1556
1556 1557 issue = Issue.first(:order => 'id DESC')
1557 1558 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1558 1559 assert_not_nil flash[:notice], "flash was not set"
1559 1560 assert flash[:notice].include?("<a href='/issues/#{issue.id}'>##{issue.id}</a>"), "issue link not found in flash: #{flash[:notice]}"
1560 1561 end
1561 1562
1562 1563 def test_post_create_without_custom_fields_param
1563 1564 @request.session[:user_id] = 2
1564 1565 assert_difference 'Issue.count' do
1565 1566 post :create, :project_id => 1,
1566 1567 :issue => {:tracker_id => 1,
1567 1568 :subject => 'This is the test_new issue',
1568 1569 :description => 'This is the description',
1569 1570 :priority_id => 5}
1570 1571 end
1571 1572 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1572 1573 end
1573 1574
1574 1575 def test_post_create_with_multi_custom_field
1575 1576 field = IssueCustomField.find_by_name('Database')
1576 1577 field.update_attribute(:multiple, true)
1577 1578
1578 1579 @request.session[:user_id] = 2
1579 1580 assert_difference 'Issue.count' do
1580 1581 post :create, :project_id => 1,
1581 1582 :issue => {:tracker_id => 1,
1582 1583 :subject => 'This is the test_new issue',
1583 1584 :description => 'This is the description',
1584 1585 :priority_id => 5,
1585 1586 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
1586 1587 end
1587 1588 assert_response 302
1588 1589 issue = Issue.first(:order => 'id DESC')
1589 1590 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
1590 1591 end
1591 1592
1592 1593 def test_post_create_with_empty_multi_custom_field
1593 1594 field = IssueCustomField.find_by_name('Database')
1594 1595 field.update_attribute(:multiple, true)
1595 1596
1596 1597 @request.session[:user_id] = 2
1597 1598 assert_difference 'Issue.count' do
1598 1599 post :create, :project_id => 1,
1599 1600 :issue => {:tracker_id => 1,
1600 1601 :subject => 'This is the test_new issue',
1601 1602 :description => 'This is the description',
1602 1603 :priority_id => 5,
1603 1604 :custom_field_values => {'1' => ['']}}
1604 1605 end
1605 1606 assert_response 302
1606 1607 issue = Issue.first(:order => 'id DESC')
1607 1608 assert_equal [''], issue.custom_field_value(1).sort
1608 1609 end
1609 1610
1610 1611 def test_post_create_with_multi_user_custom_field
1611 1612 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1612 1613 :tracker_ids => [1], :is_for_all => true)
1613 1614
1614 1615 @request.session[:user_id] = 2
1615 1616 assert_difference 'Issue.count' do
1616 1617 post :create, :project_id => 1,
1617 1618 :issue => {:tracker_id => 1,
1618 1619 :subject => 'This is the test_new issue',
1619 1620 :description => 'This is the description',
1620 1621 :priority_id => 5,
1621 1622 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
1622 1623 end
1623 1624 assert_response 302
1624 1625 issue = Issue.first(:order => 'id DESC')
1625 1626 assert_equal ['2', '3'], issue.custom_field_value(field).sort
1626 1627 end
1627 1628
1628 1629 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1629 1630 field = IssueCustomField.find_by_name('Database')
1630 1631 field.update_attribute(:is_required, true)
1631 1632
1632 1633 @request.session[:user_id] = 2
1633 1634 assert_no_difference 'Issue.count' do
1634 1635 post :create, :project_id => 1,
1635 1636 :issue => {:tracker_id => 1,
1636 1637 :subject => 'This is the test_new issue',
1637 1638 :description => 'This is the description',
1638 1639 :priority_id => 5}
1639 1640 end
1640 1641 assert_response :success
1641 1642 assert_template 'new'
1642 1643 issue = assigns(:issue)
1643 1644 assert_not_nil issue
1644 1645 assert_error_tag :content => /Database can't be blank/
1645 1646 end
1646 1647
1647 1648 def test_post_create_with_watchers
1648 1649 @request.session[:user_id] = 2
1649 1650 ActionMailer::Base.deliveries.clear
1650 1651
1651 1652 assert_difference 'Watcher.count', 2 do
1652 1653 post :create, :project_id => 1,
1653 1654 :issue => {:tracker_id => 1,
1654 1655 :subject => 'This is a new issue with watchers',
1655 1656 :description => 'This is the description',
1656 1657 :priority_id => 5,
1657 1658 :watcher_user_ids => ['2', '3']}
1658 1659 end
1659 1660 issue = Issue.find_by_subject('This is a new issue with watchers')
1660 1661 assert_not_nil issue
1661 1662 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1662 1663
1663 1664 # Watchers added
1664 1665 assert_equal [2, 3], issue.watcher_user_ids.sort
1665 1666 assert issue.watched_by?(User.find(3))
1666 1667 # Watchers notified
1667 1668 mail = ActionMailer::Base.deliveries.last
1668 1669 assert_not_nil mail
1669 1670 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1670 1671 end
1671 1672
1672 1673 def test_post_create_subissue
1673 1674 @request.session[:user_id] = 2
1674 1675
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 a child issue',
1679 1680 :parent_issue_id => 2}
1680 1681 end
1681 1682 issue = Issue.find_by_subject('This is a child issue')
1682 1683 assert_not_nil issue
1683 1684 assert_equal Issue.find(2), issue.parent
1684 1685 end
1685 1686
1686 1687 def test_post_create_subissue_with_non_numeric_parent_id
1687 1688 @request.session[:user_id] = 2
1688 1689
1689 1690 assert_difference 'Issue.count' do
1690 1691 post :create, :project_id => 1,
1691 1692 :issue => {:tracker_id => 1,
1692 1693 :subject => 'This is a child issue',
1693 1694 :parent_issue_id => 'ABC'}
1694 1695 end
1695 1696 issue = Issue.find_by_subject('This is a child issue')
1696 1697 assert_not_nil issue
1697 1698 assert_nil issue.parent
1698 1699 end
1699 1700
1700 1701 def test_post_create_private
1701 1702 @request.session[:user_id] = 2
1702 1703
1703 1704 assert_difference 'Issue.count' do
1704 1705 post :create, :project_id => 1,
1705 1706 :issue => {:tracker_id => 1,
1706 1707 :subject => 'This is a private issue',
1707 1708 :is_private => '1'}
1708 1709 end
1709 1710 issue = Issue.first(:order => 'id DESC')
1710 1711 assert issue.is_private?
1711 1712 end
1712 1713
1713 1714 def test_post_create_private_with_set_own_issues_private_permission
1714 1715 role = Role.find(1)
1715 1716 role.remove_permission! :set_issues_private
1716 1717 role.add_permission! :set_own_issues_private
1717 1718
1718 1719 @request.session[:user_id] = 2
1719 1720
1720 1721 assert_difference 'Issue.count' do
1721 1722 post :create, :project_id => 1,
1722 1723 :issue => {:tracker_id => 1,
1723 1724 :subject => 'This is a private issue',
1724 1725 :is_private => '1'}
1725 1726 end
1726 1727 issue = Issue.first(:order => 'id DESC')
1727 1728 assert issue.is_private?
1728 1729 end
1729 1730
1730 1731 def test_post_create_should_send_a_notification
1731 1732 ActionMailer::Base.deliveries.clear
1732 1733 @request.session[:user_id] = 2
1733 1734 assert_difference 'Issue.count' do
1734 1735 post :create, :project_id => 1,
1735 1736 :issue => {:tracker_id => 3,
1736 1737 :subject => 'This is the test_new issue',
1737 1738 :description => 'This is the description',
1738 1739 :priority_id => 5,
1739 1740 :estimated_hours => '',
1740 1741 :custom_field_values => {'2' => 'Value for field 2'}}
1741 1742 end
1742 1743 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1743 1744
1744 1745 assert_equal 1, ActionMailer::Base.deliveries.size
1745 1746 end
1746 1747
1747 1748 def test_post_create_should_preserve_fields_values_on_validation_failure
1748 1749 @request.session[:user_id] = 2
1749 1750 post :create, :project_id => 1,
1750 1751 :issue => {:tracker_id => 1,
1751 1752 # empty subject
1752 1753 :subject => '',
1753 1754 :description => 'This is a description',
1754 1755 :priority_id => 6,
1755 1756 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
1756 1757 assert_response :success
1757 1758 assert_template 'new'
1758 1759
1759 1760 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
1760 1761 :content => "\nThis is a description"
1761 1762 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1762 1763 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1763 1764 :value => '6' },
1764 1765 :content => 'High' }
1765 1766 # Custom fields
1766 1767 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
1767 1768 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1768 1769 :value => 'Oracle' },
1769 1770 :content => 'Oracle' }
1770 1771 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
1771 1772 :value => 'Value for field 2'}
1772 1773 end
1773 1774
1774 1775 def test_post_create_with_failure_should_preserve_watchers
1775 1776 assert !User.find(8).member_of?(Project.find(1))
1776 1777
1777 1778 @request.session[:user_id] = 2
1778 1779 post :create, :project_id => 1,
1779 1780 :issue => {:tracker_id => 1,
1780 1781 :watcher_user_ids => ['3', '8']}
1781 1782 assert_response :success
1782 1783 assert_template 'new'
1783 1784
1784 1785 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '2', :checked => nil}
1785 1786 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '3', :checked => 'checked'}
1786 1787 assert_tag 'input', :attributes => {:name => 'issue[watcher_user_ids][]', :value => '8', :checked => 'checked'}
1787 1788 end
1788 1789
1789 1790 def test_post_create_should_ignore_non_safe_attributes
1790 1791 @request.session[:user_id] = 2
1791 1792 assert_nothing_raised do
1792 1793 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
1793 1794 end
1794 1795 end
1795 1796
1796 1797 def test_post_create_with_attachment
1797 1798 set_tmp_attachments_directory
1798 1799 @request.session[:user_id] = 2
1799 1800
1800 1801 assert_difference 'Issue.count' do
1801 1802 assert_difference 'Attachment.count' do
1802 1803 post :create, :project_id => 1,
1803 1804 :issue => { :tracker_id => '1', :subject => 'With attachment' },
1804 1805 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1805 1806 end
1806 1807 end
1807 1808
1808 1809 issue = Issue.first(:order => 'id DESC')
1809 1810 attachment = Attachment.first(:order => 'id DESC')
1810 1811
1811 1812 assert_equal issue, attachment.container
1812 1813 assert_equal 2, attachment.author_id
1813 1814 assert_equal 'testfile.txt', attachment.filename
1814 1815 assert_equal 'text/plain', attachment.content_type
1815 1816 assert_equal 'test file', attachment.description
1816 1817 assert_equal 59, attachment.filesize
1817 1818 assert File.exists?(attachment.diskfile)
1818 1819 assert_equal 59, File.size(attachment.diskfile)
1819 1820 end
1820 1821
1821 1822 def test_post_create_with_failure_should_save_attachments
1822 1823 set_tmp_attachments_directory
1823 1824 @request.session[:user_id] = 2
1824 1825
1825 1826 assert_no_difference 'Issue.count' do
1826 1827 assert_difference 'Attachment.count' do
1827 1828 post :create, :project_id => 1,
1828 1829 :issue => { :tracker_id => '1', :subject => '' },
1829 1830 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1830 1831 assert_response :success
1831 1832 assert_template 'new'
1832 1833 end
1833 1834 end
1834 1835
1835 1836 attachment = Attachment.first(:order => 'id DESC')
1836 1837 assert_equal 'testfile.txt', attachment.filename
1837 1838 assert File.exists?(attachment.diskfile)
1838 1839 assert_nil attachment.container
1839 1840
1840 1841 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
1841 1842 assert_tag 'span', :content => /testfile.txt/
1842 1843 end
1843 1844
1844 1845 def test_post_create_with_failure_should_keep_saved_attachments
1845 1846 set_tmp_attachments_directory
1846 1847 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
1847 1848 @request.session[:user_id] = 2
1848 1849
1849 1850 assert_no_difference 'Issue.count' do
1850 1851 assert_no_difference 'Attachment.count' do
1851 1852 post :create, :project_id => 1,
1852 1853 :issue => { :tracker_id => '1', :subject => '' },
1853 1854 :attachments => {'p0' => {'token' => attachment.token}}
1854 1855 assert_response :success
1855 1856 assert_template 'new'
1856 1857 end
1857 1858 end
1858 1859
1859 1860 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
1860 1861 assert_tag 'span', :content => /testfile.txt/
1861 1862 end
1862 1863
1863 1864 def test_post_create_should_attach_saved_attachments
1864 1865 set_tmp_attachments_directory
1865 1866 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
1866 1867 @request.session[:user_id] = 2
1867 1868
1868 1869 assert_difference 'Issue.count' do
1869 1870 assert_no_difference 'Attachment.count' do
1870 1871 post :create, :project_id => 1,
1871 1872 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
1872 1873 :attachments => {'p0' => {'token' => attachment.token}}
1873 1874 assert_response 302
1874 1875 end
1875 1876 end
1876 1877
1877 1878 issue = Issue.first(:order => 'id DESC')
1878 1879 assert_equal 1, issue.attachments.count
1879 1880
1880 1881 attachment.reload
1881 1882 assert_equal issue, attachment.container
1882 1883 end
1883 1884
1884 1885 context "without workflow privilege" do
1885 1886 setup do
1886 1887 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1887 1888 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1888 1889 end
1889 1890
1890 1891 context "#new" do
1891 1892 should "propose default status only" do
1892 1893 get :new, :project_id => 1
1893 1894 assert_response :success
1894 1895 assert_template 'new'
1895 1896 assert_tag :tag => 'select',
1896 1897 :attributes => {:name => 'issue[status_id]'},
1897 1898 :children => {:count => 1},
1898 1899 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
1899 1900 end
1900 1901
1901 1902 should "accept default status" do
1902 1903 assert_difference 'Issue.count' do
1903 1904 post :create, :project_id => 1,
1904 1905 :issue => {:tracker_id => 1,
1905 1906 :subject => 'This is an issue',
1906 1907 :status_id => 1}
1907 1908 end
1908 1909 issue = Issue.last(:order => 'id')
1909 1910 assert_equal IssueStatus.default, issue.status
1910 1911 end
1911 1912
1912 1913 should "ignore unauthorized status" do
1913 1914 assert_difference 'Issue.count' do
1914 1915 post :create, :project_id => 1,
1915 1916 :issue => {:tracker_id => 1,
1916 1917 :subject => 'This is an issue',
1917 1918 :status_id => 3}
1918 1919 end
1919 1920 issue = Issue.last(:order => 'id')
1920 1921 assert_equal IssueStatus.default, issue.status
1921 1922 end
1922 1923 end
1923 1924
1924 1925 context "#update" do
1925 1926 should "ignore status change" do
1926 1927 assert_difference 'Journal.count' do
1927 1928 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1928 1929 end
1929 1930 assert_equal 1, Issue.find(1).status_id
1930 1931 end
1931 1932
1932 1933 should "ignore attributes changes" do
1933 1934 assert_difference 'Journal.count' do
1934 1935 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1935 1936 end
1936 1937 issue = Issue.find(1)
1937 1938 assert_equal "Can't print recipes", issue.subject
1938 1939 assert_nil issue.assigned_to
1939 1940 end
1940 1941 end
1941 1942 end
1942 1943
1943 1944 context "with workflow privilege" do
1944 1945 setup do
1945 1946 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1946 1947 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1947 1948 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1948 1949 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1949 1950 end
1950 1951
1951 1952 context "#update" do
1952 1953 should "accept authorized status" do
1953 1954 assert_difference 'Journal.count' do
1954 1955 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1955 1956 end
1956 1957 assert_equal 3, Issue.find(1).status_id
1957 1958 end
1958 1959
1959 1960 should "ignore unauthorized status" do
1960 1961 assert_difference 'Journal.count' do
1961 1962 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1962 1963 end
1963 1964 assert_equal 1, Issue.find(1).status_id
1964 1965 end
1965 1966
1966 1967 should "accept authorized attributes changes" do
1967 1968 assert_difference 'Journal.count' do
1968 1969 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
1969 1970 end
1970 1971 issue = Issue.find(1)
1971 1972 assert_equal 2, issue.assigned_to_id
1972 1973 end
1973 1974
1974 1975 should "ignore unauthorized attributes changes" do
1975 1976 assert_difference 'Journal.count' do
1976 1977 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
1977 1978 end
1978 1979 issue = Issue.find(1)
1979 1980 assert_equal "Can't print recipes", issue.subject
1980 1981 end
1981 1982 end
1982 1983
1983 1984 context "and :edit_issues permission" do
1984 1985 setup do
1985 1986 Role.anonymous.add_permission! :add_issues, :edit_issues
1986 1987 end
1987 1988
1988 1989 should "accept authorized status" do
1989 1990 assert_difference 'Journal.count' do
1990 1991 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1991 1992 end
1992 1993 assert_equal 3, Issue.find(1).status_id
1993 1994 end
1994 1995
1995 1996 should "ignore unauthorized status" do
1996 1997 assert_difference 'Journal.count' do
1997 1998 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1998 1999 end
1999 2000 assert_equal 1, Issue.find(1).status_id
2000 2001 end
2001 2002
2002 2003 should "accept authorized attributes changes" do
2003 2004 assert_difference 'Journal.count' do
2004 2005 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
2005 2006 end
2006 2007 issue = Issue.find(1)
2007 2008 assert_equal "changed", issue.subject
2008 2009 assert_equal 2, issue.assigned_to_id
2009 2010 end
2010 2011 end
2011 2012 end
2012 2013
2013 2014 def test_new_as_copy
2014 2015 @request.session[:user_id] = 2
2015 2016 get :new, :project_id => 1, :copy_from => 1
2016 2017
2017 2018 assert_response :success
2018 2019 assert_template 'new'
2019 2020
2020 2021 assert_not_nil assigns(:issue)
2021 2022 orig = Issue.find(1)
2022 2023 assert_equal 1, assigns(:issue).project_id
2023 2024 assert_equal orig.subject, assigns(:issue).subject
2024 2025 assert assigns(:issue).copy?
2025 2026
2026 2027 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2027 2028 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2028 2029 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2029 2030 :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}, :content => 'eCookbook'}
2030 2031 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2031 2032 :child => {:tag => 'option', :attributes => {:value => '2', :selected => nil}, :content => 'OnlineStore'}
2032 2033 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2033 2034 end
2034 2035
2035 2036 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2036 2037 @request.session[:user_id] = 2
2037 2038 issue = Issue.find(3)
2038 2039 assert issue.attachments.count > 0
2039 2040 get :new, :project_id => 1, :copy_from => 3
2040 2041
2041 2042 assert_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2042 2043 end
2043 2044
2044 2045 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2045 2046 @request.session[:user_id] = 2
2046 2047 issue = Issue.find(3)
2047 2048 issue.attachments.delete_all
2048 2049 get :new, :project_id => 1, :copy_from => 3
2049 2050
2050 2051 assert_no_tag 'input', :attributes => {:name => 'copy_attachments', :type => 'checkbox', :checked => 'checked', :value => '1'}
2051 2052 end
2052 2053
2053 2054 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2054 2055 @request.session[:user_id] = 2
2055 2056 get :new, :project_id => 1, :copy_from => 99999
2056 2057 assert_response 404
2057 2058 end
2058 2059
2059 2060 def test_create_as_copy_on_different_project
2060 2061 @request.session[:user_id] = 2
2061 2062 assert_difference 'Issue.count' do
2062 2063 post :create, :project_id => 1, :copy_from => 1,
2063 2064 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2064 2065
2065 2066 assert_not_nil assigns(:issue)
2066 2067 assert assigns(:issue).copy?
2067 2068 end
2068 2069 issue = Issue.first(:order => 'id DESC')
2069 2070 assert_redirected_to "/issues/#{issue.id}"
2070 2071
2071 2072 assert_equal 2, issue.project_id
2072 2073 assert_equal 3, issue.tracker_id
2073 2074 assert_equal 'Copy', issue.subject
2074 2075 end
2075 2076
2076 2077 def test_create_as_copy_should_copy_attachments
2077 2078 @request.session[:user_id] = 2
2078 2079 issue = Issue.find(3)
2079 2080 count = issue.attachments.count
2080 2081 assert count > 0
2081 2082
2082 2083 assert_difference 'Issue.count' do
2083 2084 assert_difference 'Attachment.count', count do
2084 2085 assert_no_difference 'Journal.count' do
2085 2086 post :create, :project_id => 1, :copy_from => 3,
2086 2087 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2087 2088 :copy_attachments => '1'
2088 2089 end
2089 2090 end
2090 2091 end
2091 2092 copy = Issue.first(:order => 'id DESC')
2092 2093 assert_equal count, copy.attachments.count
2093 2094 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2094 2095 end
2095 2096
2096 2097 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2097 2098 @request.session[:user_id] = 2
2098 2099 issue = Issue.find(3)
2099 2100 count = issue.attachments.count
2100 2101 assert count > 0
2101 2102
2102 2103 assert_difference 'Issue.count' do
2103 2104 assert_no_difference 'Attachment.count' do
2104 2105 assert_no_difference 'Journal.count' do
2105 2106 post :create, :project_id => 1, :copy_from => 3,
2106 2107 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'}
2107 2108 end
2108 2109 end
2109 2110 end
2110 2111 copy = Issue.first(:order => 'id DESC')
2111 2112 assert_equal 0, copy.attachments.count
2112 2113 end
2113 2114
2114 2115 def test_create_as_copy_with_attachments_should_add_new_files
2115 2116 @request.session[:user_id] = 2
2116 2117 issue = Issue.find(3)
2117 2118 count = issue.attachments.count
2118 2119 assert count > 0
2119 2120
2120 2121 assert_difference 'Issue.count' do
2121 2122 assert_difference 'Attachment.count', count + 1 do
2122 2123 assert_no_difference 'Journal.count' do
2123 2124 post :create, :project_id => 1, :copy_from => 3,
2124 2125 :issue => {:project_id => '1', :tracker_id => '3', :status_id => '1', :subject => 'Copy with attachments'},
2125 2126 :copy_attachments => '1',
2126 2127 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2127 2128 end
2128 2129 end
2129 2130 end
2130 2131 copy = Issue.first(:order => 'id DESC')
2131 2132 assert_equal count + 1, copy.attachments.count
2132 2133 end
2133 2134
2134 2135 def test_create_as_copy_with_failure
2135 2136 @request.session[:user_id] = 2
2136 2137 post :create, :project_id => 1, :copy_from => 1,
2137 2138 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
2138 2139
2139 2140 assert_response :success
2140 2141 assert_template 'new'
2141 2142
2142 2143 assert_not_nil assigns(:issue)
2143 2144 assert assigns(:issue).copy?
2144 2145
2145 2146 assert_tag 'form', :attributes => {:id => 'issue-form', :action => '/projects/ecookbook/issues'}
2146 2147 assert_tag 'select', :attributes => {:name => 'issue[project_id]'}
2147 2148 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2148 2149 :child => {:tag => 'option', :attributes => {:value => '1', :selected => nil}, :content => 'eCookbook'}
2149 2150 assert_tag 'select', :attributes => {:name => 'issue[project_id]'},
2150 2151 :child => {:tag => 'option', :attributes => {:value => '2', :selected => 'selected'}, :content => 'OnlineStore'}
2151 2152 assert_tag 'input', :attributes => {:name => 'copy_from', :value => '1'}
2152 2153 end
2153 2154
2154 2155 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
2155 2156 @request.session[:user_id] = 2
2156 2157 assert !User.find(2).member_of?(Project.find(4))
2157 2158
2158 2159 assert_difference 'Issue.count' do
2159 2160 post :create, :project_id => 1, :copy_from => 1,
2160 2161 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2161 2162 end
2162 2163 issue = Issue.first(:order => 'id DESC')
2163 2164 assert_equal 1, issue.project_id
2164 2165 end
2165 2166
2166 2167 def test_get_edit
2167 2168 @request.session[:user_id] = 2
2168 2169 get :edit, :id => 1
2169 2170 assert_response :success
2170 2171 assert_template 'edit'
2171 2172 assert_not_nil assigns(:issue)
2172 2173 assert_equal Issue.find(1), assigns(:issue)
2173 2174
2174 2175 # Be sure we don't display inactive IssuePriorities
2175 2176 assert ! IssuePriority.find(15).active?
2176 2177 assert_no_tag :option, :attributes => {:value => '15'},
2177 2178 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2178 2179 end
2179 2180
2180 2181 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
2181 2182 @request.session[:user_id] = 2
2182 2183 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
2183 2184
2184 2185 get :edit, :id => 1
2185 2186 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2186 2187 end
2187 2188
2188 2189 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
2189 2190 @request.session[:user_id] = 2
2190 2191 Role.find_by_name('Manager').remove_permission! :log_time
2191 2192
2192 2193 get :edit, :id => 1
2193 2194 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
2194 2195 end
2195 2196
2196 2197 def test_get_edit_with_params
2197 2198 @request.session[:user_id] = 2
2198 2199 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
2199 2200 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
2200 2201 assert_response :success
2201 2202 assert_template 'edit'
2202 2203
2203 2204 issue = assigns(:issue)
2204 2205 assert_not_nil issue
2205 2206
2206 2207 assert_equal 5, issue.status_id
2207 2208 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
2208 2209 :child => { :tag => 'option',
2209 2210 :content => 'Closed',
2210 2211 :attributes => { :selected => 'selected' } }
2211 2212
2212 2213 assert_equal 7, issue.priority_id
2213 2214 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
2214 2215 :child => { :tag => 'option',
2215 2216 :content => 'Urgent',
2216 2217 :attributes => { :selected => 'selected' } }
2217 2218
2218 2219 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
2219 2220 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
2220 2221 :child => { :tag => 'option',
2221 2222 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
2222 2223 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
2223 2224 end
2224 2225
2225 2226 def test_get_edit_with_multi_custom_field
2226 2227 field = CustomField.find(1)
2227 2228 field.update_attribute :multiple, true
2228 2229 issue = Issue.find(1)
2229 2230 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2230 2231 issue.save!
2231 2232
2232 2233 @request.session[:user_id] = 2
2233 2234 get :edit, :id => 1
2234 2235 assert_response :success
2235 2236 assert_template 'edit'
2236 2237
2237 2238 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]', :multiple => 'multiple'}
2238 2239 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2239 2240 :child => {:tag => 'option', :attributes => {:value => 'MySQL', :selected => 'selected'}}
2240 2241 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2241 2242 :child => {:tag => 'option', :attributes => {:value => 'PostgreSQL', :selected => nil}}
2242 2243 assert_tag 'select', :attributes => {:name => 'issue[custom_field_values][1][]'},
2243 2244 :child => {:tag => 'option', :attributes => {:value => 'Oracle', :selected => 'selected'}}
2244 2245 end
2245 2246
2246 2247 def test_update_edit_form
2247 2248 @request.session[:user_id] = 2
2248 2249 xhr :put, :new, :project_id => 1,
2249 2250 :id => 1,
2250 2251 :issue => {:tracker_id => 2,
2251 2252 :subject => 'This is the test_new issue',
2252 2253 :description => 'This is the description',
2253 2254 :priority_id => 5}
2254 2255 assert_response :success
2255 2256 assert_template 'attributes'
2256 2257
2257 2258 issue = assigns(:issue)
2258 2259 assert_kind_of Issue, issue
2259 2260 assert_equal 1, issue.id
2260 2261 assert_equal 1, issue.project_id
2261 2262 assert_equal 2, issue.tracker_id
2262 2263 assert_equal 'This is the test_new issue', issue.subject
2263 2264 end
2264 2265
2265 2266 def test_update_edit_form_should_propose_transitions_based_on_initial_status
2266 2267 @request.session[:user_id] = 2
2267 2268 Workflow.delete_all
2268 2269 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2269 2270 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2270 2271 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2271 2272
2272 2273 xhr :put, :new, :project_id => 1,
2273 2274 :id => 2,
2274 2275 :issue => {:tracker_id => 2,
2275 2276 :status_id => 5,
2276 2277 :subject => 'This is an issue'}
2277 2278
2278 2279 assert_equal 5, assigns(:issue).status_id
2279 2280 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
2280 2281 end
2281 2282
2282 2283 def test_update_edit_form_with_project_change
2283 2284 @request.session[:user_id] = 2
2284 2285 xhr :put, :new, :project_id => 1,
2285 2286 :id => 1,
2286 2287 :project_change => '1',
2287 2288 :issue => {:project_id => 2,
2288 2289 :tracker_id => 2,
2289 2290 :subject => 'This is the test_new issue',
2290 2291 :description => 'This is the description',
2291 2292 :priority_id => 5}
2292 2293 assert_response :success
2293 2294 assert_template 'form'
2294 2295
2295 2296 issue = assigns(:issue)
2296 2297 assert_kind_of Issue, issue
2297 2298 assert_equal 1, issue.id
2298 2299 assert_equal 2, issue.project_id
2299 2300 assert_equal 2, issue.tracker_id
2300 2301 assert_equal 'This is the test_new issue', issue.subject
2301 2302 end
2302 2303
2303 2304 def test_put_update_without_custom_fields_param
2304 2305 @request.session[:user_id] = 2
2305 2306 ActionMailer::Base.deliveries.clear
2306 2307
2307 2308 issue = Issue.find(1)
2308 2309 assert_equal '125', issue.custom_value_for(2).value
2309 2310 old_subject = issue.subject
2310 2311 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2311 2312
2312 2313 assert_difference('Journal.count') do
2313 2314 assert_difference('JournalDetail.count', 2) do
2314 2315 put :update, :id => 1, :issue => {:subject => new_subject,
2315 2316 :priority_id => '6',
2316 2317 :category_id => '1' # no change
2317 2318 }
2318 2319 end
2319 2320 end
2320 2321 assert_redirected_to :action => 'show', :id => '1'
2321 2322 issue.reload
2322 2323 assert_equal new_subject, issue.subject
2323 2324 # Make sure custom fields were not cleared
2324 2325 assert_equal '125', issue.custom_value_for(2).value
2325 2326
2326 2327 mail = ActionMailer::Base.deliveries.last
2327 2328 assert_not_nil mail
2328 2329 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2329 2330 assert_mail_body_match "Subject changed from #{old_subject} to #{new_subject}", mail
2330 2331 end
2331 2332
2332 2333 def test_put_update_with_project_change
2333 2334 @request.session[:user_id] = 2
2334 2335 ActionMailer::Base.deliveries.clear
2335 2336
2336 2337 assert_difference('Journal.count') do
2337 2338 assert_difference('JournalDetail.count', 3) do
2338 2339 put :update, :id => 1, :issue => {:project_id => '2',
2339 2340 :tracker_id => '1', # no change
2340 2341 :priority_id => '6',
2341 2342 :category_id => '3'
2342 2343 }
2343 2344 end
2344 2345 end
2345 2346 assert_redirected_to :action => 'show', :id => '1'
2346 2347 issue = Issue.find(1)
2347 2348 assert_equal 2, issue.project_id
2348 2349 assert_equal 1, issue.tracker_id
2349 2350 assert_equal 6, issue.priority_id
2350 2351 assert_equal 3, issue.category_id
2351 2352
2352 2353 mail = ActionMailer::Base.deliveries.last
2353 2354 assert_not_nil mail
2354 2355 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2355 2356 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
2356 2357 end
2357 2358
2358 2359 def test_put_update_with_tracker_change
2359 2360 @request.session[:user_id] = 2
2360 2361 ActionMailer::Base.deliveries.clear
2361 2362
2362 2363 assert_difference('Journal.count') do
2363 2364 assert_difference('JournalDetail.count', 2) do
2364 2365 put :update, :id => 1, :issue => {:project_id => '1',
2365 2366 :tracker_id => '2',
2366 2367 :priority_id => '6'
2367 2368 }
2368 2369 end
2369 2370 end
2370 2371 assert_redirected_to :action => 'show', :id => '1'
2371 2372 issue = Issue.find(1)
2372 2373 assert_equal 1, issue.project_id
2373 2374 assert_equal 2, issue.tracker_id
2374 2375 assert_equal 6, issue.priority_id
2375 2376 assert_equal 1, issue.category_id
2376 2377
2377 2378 mail = ActionMailer::Base.deliveries.last
2378 2379 assert_not_nil mail
2379 2380 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
2380 2381 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
2381 2382 end
2382 2383
2383 2384 def test_put_update_with_custom_field_change
2384 2385 @request.session[:user_id] = 2
2385 2386 issue = Issue.find(1)
2386 2387 assert_equal '125', issue.custom_value_for(2).value
2387 2388
2388 2389 assert_difference('Journal.count') do
2389 2390 assert_difference('JournalDetail.count', 3) do
2390 2391 put :update, :id => 1, :issue => {:subject => 'Custom field change',
2391 2392 :priority_id => '6',
2392 2393 :category_id => '1', # no change
2393 2394 :custom_field_values => { '2' => 'New custom value' }
2394 2395 }
2395 2396 end
2396 2397 end
2397 2398 assert_redirected_to :action => 'show', :id => '1'
2398 2399 issue.reload
2399 2400 assert_equal 'New custom value', issue.custom_value_for(2).value
2400 2401
2401 2402 mail = ActionMailer::Base.deliveries.last
2402 2403 assert_not_nil mail
2403 2404 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
2404 2405 end
2405 2406
2406 2407 def test_put_update_with_multi_custom_field_change
2407 2408 field = CustomField.find(1)
2408 2409 field.update_attribute :multiple, true
2409 2410 issue = Issue.find(1)
2410 2411 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
2411 2412 issue.save!
2412 2413
2413 2414 @request.session[:user_id] = 2
2414 2415 assert_difference('Journal.count') do
2415 2416 assert_difference('JournalDetail.count', 3) do
2416 2417 put :update, :id => 1,
2417 2418 :issue => {
2418 2419 :subject => 'Custom field change',
2419 2420 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
2420 2421 }
2421 2422 end
2422 2423 end
2423 2424 assert_redirected_to :action => 'show', :id => '1'
2424 2425 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
2425 2426 end
2426 2427
2427 2428 def test_put_update_with_status_and_assignee_change
2428 2429 issue = Issue.find(1)
2429 2430 assert_equal 1, issue.status_id
2430 2431 @request.session[:user_id] = 2
2431 2432 assert_difference('TimeEntry.count', 0) do
2432 2433 put :update,
2433 2434 :id => 1,
2434 2435 :issue => { :status_id => 2, :assigned_to_id => 3 },
2435 2436 :notes => 'Assigned to dlopper',
2436 2437 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
2437 2438 end
2438 2439 assert_redirected_to :action => 'show', :id => '1'
2439 2440 issue.reload
2440 2441 assert_equal 2, issue.status_id
2441 2442 j = Journal.find(:first, :order => 'id DESC')
2442 2443 assert_equal 'Assigned to dlopper', j.notes
2443 2444 assert_equal 2, j.details.size
2444 2445
2445 2446 mail = ActionMailer::Base.deliveries.last
2446 2447 assert_mail_body_match "Status changed from New to Assigned", mail
2447 2448 # subject should contain the new status
2448 2449 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
2449 2450 end
2450 2451
2451 2452 def test_put_update_with_note_only
2452 2453 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
2453 2454 # anonymous user
2454 2455 put :update,
2455 2456 :id => 1,
2456 2457 :notes => notes
2457 2458 assert_redirected_to :action => 'show', :id => '1'
2458 2459 j = Journal.find(:first, :order => 'id DESC')
2459 2460 assert_equal notes, j.notes
2460 2461 assert_equal 0, j.details.size
2461 2462 assert_equal User.anonymous, j.user
2462 2463
2463 2464 mail = ActionMailer::Base.deliveries.last
2464 2465 assert_mail_body_match notes, mail
2465 2466 end
2466 2467
2467 2468 def test_put_update_with_note_and_spent_time
2468 2469 @request.session[:user_id] = 2
2469 2470 spent_hours_before = Issue.find(1).spent_hours
2470 2471 assert_difference('TimeEntry.count') do
2471 2472 put :update,
2472 2473 :id => 1,
2473 2474 :notes => '2.5 hours added',
2474 2475 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
2475 2476 end
2476 2477 assert_redirected_to :action => 'show', :id => '1'
2477 2478
2478 2479 issue = Issue.find(1)
2479 2480
2480 2481 j = Journal.find(:first, :order => 'id DESC')
2481 2482 assert_equal '2.5 hours added', j.notes
2482 2483 assert_equal 0, j.details.size
2483 2484
2484 2485 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
2485 2486 assert_not_nil t
2486 2487 assert_equal 2.5, t.hours
2487 2488 assert_equal spent_hours_before + 2.5, issue.spent_hours
2488 2489 end
2489 2490
2490 2491 def test_put_update_with_attachment_only
2491 2492 set_tmp_attachments_directory
2492 2493
2493 2494 # Delete all fixtured journals, a race condition can occur causing the wrong
2494 2495 # journal to get fetched in the next find.
2495 2496 Journal.delete_all
2496 2497
2497 2498 # anonymous user
2498 2499 assert_difference 'Attachment.count' do
2499 2500 put :update, :id => 1,
2500 2501 :notes => '',
2501 2502 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2502 2503 end
2503 2504
2504 2505 assert_redirected_to :action => 'show', :id => '1'
2505 2506 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
2506 2507 assert j.notes.blank?
2507 2508 assert_equal 1, j.details.size
2508 2509 assert_equal 'testfile.txt', j.details.first.value
2509 2510 assert_equal User.anonymous, j.user
2510 2511
2511 2512 attachment = Attachment.first(:order => 'id DESC')
2512 2513 assert_equal Issue.find(1), attachment.container
2513 2514 assert_equal User.anonymous, attachment.author
2514 2515 assert_equal 'testfile.txt', attachment.filename
2515 2516 assert_equal 'text/plain', attachment.content_type
2516 2517 assert_equal 'test file', attachment.description
2517 2518 assert_equal 59, attachment.filesize
2518 2519 assert File.exists?(attachment.diskfile)
2519 2520 assert_equal 59, File.size(attachment.diskfile)
2520 2521
2521 2522 mail = ActionMailer::Base.deliveries.last
2522 2523 assert_mail_body_match 'testfile.txt', mail
2523 2524 end
2524 2525
2525 2526 def test_put_update_with_failure_should_save_attachments
2526 2527 set_tmp_attachments_directory
2527 2528 @request.session[:user_id] = 2
2528 2529
2529 2530 assert_no_difference 'Journal.count' do
2530 2531 assert_difference 'Attachment.count' do
2531 2532 put :update, :id => 1,
2532 2533 :issue => { :subject => '' },
2533 2534 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2534 2535 assert_response :success
2535 2536 assert_template 'edit'
2536 2537 end
2537 2538 end
2538 2539
2539 2540 attachment = Attachment.first(:order => 'id DESC')
2540 2541 assert_equal 'testfile.txt', attachment.filename
2541 2542 assert File.exists?(attachment.diskfile)
2542 2543 assert_nil attachment.container
2543 2544
2544 2545 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2545 2546 assert_tag 'span', :content => /testfile.txt/
2546 2547 end
2547 2548
2548 2549 def test_put_update_with_failure_should_keep_saved_attachments
2549 2550 set_tmp_attachments_directory
2550 2551 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2551 2552 @request.session[:user_id] = 2
2552 2553
2553 2554 assert_no_difference 'Journal.count' do
2554 2555 assert_no_difference 'Attachment.count' do
2555 2556 put :update, :id => 1,
2556 2557 :issue => { :subject => '' },
2557 2558 :attachments => {'p0' => {'token' => attachment.token}}
2558 2559 assert_response :success
2559 2560 assert_template 'edit'
2560 2561 end
2561 2562 end
2562 2563
2563 2564 assert_tag 'input', :attributes => {:name => 'attachments[p0][token]', :value => attachment.token}
2564 2565 assert_tag 'span', :content => /testfile.txt/
2565 2566 end
2566 2567
2567 2568 def test_put_update_should_attach_saved_attachments
2568 2569 set_tmp_attachments_directory
2569 2570 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2570 2571 @request.session[:user_id] = 2
2571 2572
2572 2573 assert_difference 'Journal.count' do
2573 2574 assert_difference 'JournalDetail.count' do
2574 2575 assert_no_difference 'Attachment.count' do
2575 2576 put :update, :id => 1,
2576 2577 :notes => 'Attachment added',
2577 2578 :attachments => {'p0' => {'token' => attachment.token}}
2578 2579 assert_redirected_to '/issues/1'
2579 2580 end
2580 2581 end
2581 2582 end
2582 2583
2583 2584 attachment.reload
2584 2585 assert_equal Issue.find(1), attachment.container
2585 2586
2586 2587 journal = Journal.first(:order => 'id DESC')
2587 2588 assert_equal 1, journal.details.size
2588 2589 assert_equal 'testfile.txt', journal.details.first.value
2589 2590 end
2590 2591
2591 2592 def test_put_update_with_attachment_that_fails_to_save
2592 2593 set_tmp_attachments_directory
2593 2594
2594 2595 # Delete all fixtured journals, a race condition can occur causing the wrong
2595 2596 # journal to get fetched in the next find.
2596 2597 Journal.delete_all
2597 2598
2598 2599 # Mock out the unsaved attachment
2599 2600 Attachment.any_instance.stubs(:create).returns(Attachment.new)
2600 2601
2601 2602 # anonymous user
2602 2603 put :update,
2603 2604 :id => 1,
2604 2605 :notes => '',
2605 2606 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
2606 2607 assert_redirected_to :action => 'show', :id => '1'
2607 2608 assert_equal '1 file(s) could not be saved.', flash[:warning]
2608 2609 end
2609 2610
2610 2611 def test_put_update_with_no_change
2611 2612 issue = Issue.find(1)
2612 2613 issue.journals.clear
2613 2614 ActionMailer::Base.deliveries.clear
2614 2615
2615 2616 put :update,
2616 2617 :id => 1,
2617 2618 :notes => ''
2618 2619 assert_redirected_to :action => 'show', :id => '1'
2619 2620
2620 2621 issue.reload
2621 2622 assert issue.journals.empty?
2622 2623 # No email should be sent
2623 2624 assert ActionMailer::Base.deliveries.empty?
2624 2625 end
2625 2626
2626 2627 def test_put_update_should_send_a_notification
2627 2628 @request.session[:user_id] = 2
2628 2629 ActionMailer::Base.deliveries.clear
2629 2630 issue = Issue.find(1)
2630 2631 old_subject = issue.subject
2631 2632 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
2632 2633
2633 2634 put :update, :id => 1, :issue => {:subject => new_subject,
2634 2635 :priority_id => '6',
2635 2636 :category_id => '1' # no change
2636 2637 }
2637 2638 assert_equal 1, ActionMailer::Base.deliveries.size
2638 2639 end
2639 2640
2640 2641 def test_put_update_with_invalid_spent_time_hours_only
2641 2642 @request.session[:user_id] = 2
2642 2643 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
2643 2644
2644 2645 assert_no_difference('Journal.count') do
2645 2646 put :update,
2646 2647 :id => 1,
2647 2648 :notes => notes,
2648 2649 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
2649 2650 end
2650 2651 assert_response :success
2651 2652 assert_template 'edit'
2652 2653
2653 2654 assert_error_tag :descendant => {:content => /Activity can't be blank/}
2654 2655 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => "\n"+notes
2655 2656 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
2656 2657 end
2657 2658
2658 2659 def test_put_update_with_invalid_spent_time_comments_only
2659 2660 @request.session[:user_id] = 2
2660 2661 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
2661 2662
2662 2663 assert_no_difference('Journal.count') do
2663 2664 put :update,
2664 2665 :id => 1,
2665 2666 :notes => notes,
2666 2667 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
2667 2668 end
2668 2669 assert_response :success
2669 2670 assert_template 'edit'
2670 2671
2671 2672 assert_error_tag :descendant => {:content => /Activity can't be blank/}
2672 2673 assert_error_tag :descendant => {:content => /Hours can't be blank/}
2673 2674 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => "\n"+notes
2674 2675 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
2675 2676 end
2676 2677
2677 2678 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
2678 2679 issue = Issue.find(2)
2679 2680 @request.session[:user_id] = 2
2680 2681
2681 2682 put :update,
2682 2683 :id => issue.id,
2683 2684 :issue => {
2684 2685 :fixed_version_id => 4
2685 2686 }
2686 2687
2687 2688 assert_response :redirect
2688 2689 issue.reload
2689 2690 assert_equal 4, issue.fixed_version_id
2690 2691 assert_not_equal issue.project_id, issue.fixed_version.project_id
2691 2692 end
2692 2693
2693 2694 def test_put_update_should_redirect_back_using_the_back_url_parameter
2694 2695 issue = Issue.find(2)
2695 2696 @request.session[:user_id] = 2
2696 2697
2697 2698 put :update,
2698 2699 :id => issue.id,
2699 2700 :issue => {
2700 2701 :fixed_version_id => 4
2701 2702 },
2702 2703 :back_url => '/issues'
2703 2704
2704 2705 assert_response :redirect
2705 2706 assert_redirected_to '/issues'
2706 2707 end
2707 2708
2708 2709 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
2709 2710 issue = Issue.find(2)
2710 2711 @request.session[:user_id] = 2
2711 2712
2712 2713 put :update,
2713 2714 :id => issue.id,
2714 2715 :issue => {
2715 2716 :fixed_version_id => 4
2716 2717 },
2717 2718 :back_url => 'http://google.com'
2718 2719
2719 2720 assert_response :redirect
2720 2721 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
2721 2722 end
2722 2723
2723 2724 def test_get_bulk_edit
2724 2725 @request.session[:user_id] = 2
2725 2726 get :bulk_edit, :ids => [1, 2]
2726 2727 assert_response :success
2727 2728 assert_template 'bulk_edit'
2728 2729
2729 2730 assert_tag :select, :attributes => {:name => 'issue[project_id]'}
2730 2731 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
2731 2732
2732 2733 # Project specific custom field, date type
2733 2734 field = CustomField.find(9)
2734 2735 assert !field.is_for_all?
2735 2736 assert_equal 'date', field.field_format
2736 2737 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
2737 2738
2738 2739 # System wide custom field
2739 2740 assert CustomField.find(1).is_for_all?
2740 2741 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
2741 2742
2742 2743 # Be sure we don't display inactive IssuePriorities
2743 2744 assert ! IssuePriority.find(15).active?
2744 2745 assert_no_tag :option, :attributes => {:value => '15'},
2745 2746 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
2746 2747 end
2747 2748
2748 2749 def test_get_bulk_edit_on_different_projects
2749 2750 @request.session[:user_id] = 2
2750 2751 get :bulk_edit, :ids => [1, 2, 6]
2751 2752 assert_response :success
2752 2753 assert_template 'bulk_edit'
2753 2754
2754 2755 # Can not set issues from different projects as children of an issue
2755 2756 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
2756 2757
2757 2758 # Project specific custom field, date type
2758 2759 field = CustomField.find(9)
2759 2760 assert !field.is_for_all?
2760 2761 assert !field.project_ids.include?(Issue.find(6).project_id)
2761 2762 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
2762 2763 end
2763 2764
2764 2765 def test_get_bulk_edit_with_user_custom_field
2765 2766 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
2766 2767
2767 2768 @request.session[:user_id] = 2
2768 2769 get :bulk_edit, :ids => [1, 2]
2769 2770 assert_response :success
2770 2771 assert_template 'bulk_edit'
2771 2772
2772 2773 assert_tag :select,
2773 2774 :attributes => {:name => "issue[custom_field_values][#{field.id}]", :class => 'user_cf'},
2774 2775 :children => {
2775 2776 :only => {:tag => 'option'},
2776 2777 :count => Project.find(1).users.count + 2 # "no change" + "none" options
2777 2778 }
2778 2779 end
2779 2780
2780 2781 def test_get_bulk_edit_with_version_custom_field
2781 2782 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
2782 2783
2783 2784 @request.session[:user_id] = 2
2784 2785 get :bulk_edit, :ids => [1, 2]
2785 2786 assert_response :success
2786 2787 assert_template 'bulk_edit'
2787 2788
2788 2789 assert_tag :select,
2789 2790 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
2790 2791 :children => {
2791 2792 :only => {:tag => 'option'},
2792 2793 :count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
2793 2794 }
2794 2795 end
2795 2796
2796 2797 def test_get_bulk_edit_with_multi_custom_field
2797 2798 field = CustomField.find(1)
2798 2799 field.update_attribute :multiple, true
2799 2800
2800 2801 @request.session[:user_id] = 2
2801 2802 get :bulk_edit, :ids => [1, 2]
2802 2803 assert_response :success
2803 2804 assert_template 'bulk_edit'
2804 2805
2805 2806 assert_tag :select,
2806 2807 :attributes => {:name => "issue[custom_field_values][1][]"},
2807 2808 :children => {
2808 2809 :only => {:tag => 'option'},
2809 2810 :count => field.possible_values.size + 1 # "none" options
2810 2811 }
2811 2812 end
2812 2813
2813 2814 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
2814 2815 Workflow.delete_all
2815 2816 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
2816 2817 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2817 2818 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2818 2819 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2819 2820 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
2820 2821 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2821 2822 @request.session[:user_id] = 2
2822 2823 get :bulk_edit, :ids => [1, 2]
2823 2824
2824 2825 assert_response :success
2825 2826 statuses = assigns(:available_statuses)
2826 2827 assert_not_nil statuses
2827 2828 assert_equal [1, 3], statuses.map(&:id).sort
2828 2829
2829 2830 assert_tag 'select', :attributes => {:name => 'issue[status_id]'},
2830 2831 :children => {:count => 3} # 2 statuses + "no change" option
2831 2832 end
2832 2833
2833 2834 def test_bulk_edit_should_propose_target_project_open_shared_versions
2834 2835 @request.session[:user_id] = 2
2835 2836 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
2836 2837 assert_response :success
2837 2838 assert_template 'bulk_edit'
2838 2839 assert_equal Project.find(1).shared_versions.open.all.sort, assigns(:versions).sort
2839 2840 assert_tag 'select',
2840 2841 :attributes => {:name => 'issue[fixed_version_id]'},
2841 2842 :descendant => {:tag => 'option', :content => '2.0'}
2842 2843 end
2843 2844
2844 2845 def test_bulk_edit_should_propose_target_project_categories
2845 2846 @request.session[:user_id] = 2
2846 2847 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
2847 2848 assert_response :success
2848 2849 assert_template 'bulk_edit'
2849 2850 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
2850 2851 assert_tag 'select',
2851 2852 :attributes => {:name => 'issue[category_id]'},
2852 2853 :descendant => {:tag => 'option', :content => 'Recipes'}
2853 2854 end
2854 2855
2855 2856 def test_bulk_update
2856 2857 @request.session[:user_id] = 2
2857 2858 # update issues priority
2858 2859 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
2859 2860 :issue => {:priority_id => 7,
2860 2861 :assigned_to_id => '',
2861 2862 :custom_field_values => {'2' => ''}}
2862 2863
2863 2864 assert_response 302
2864 2865 # check that the issues were updated
2865 2866 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
2866 2867
2867 2868 issue = Issue.find(1)
2868 2869 journal = issue.journals.find(:first, :order => 'created_on DESC')
2869 2870 assert_equal '125', issue.custom_value_for(2).value
2870 2871 assert_equal 'Bulk editing', journal.notes
2871 2872 assert_equal 1, journal.details.size
2872 2873 end
2873 2874
2874 2875 def test_bulk_update_with_group_assignee
2875 2876 group = Group.find(11)
2876 2877 project = Project.find(1)
2877 2878 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2878 2879
2879 2880 @request.session[:user_id] = 2
2880 2881 # update issues assignee
2881 2882 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
2882 2883 :issue => {:priority_id => '',
2883 2884 :assigned_to_id => group.id,
2884 2885 :custom_field_values => {'2' => ''}}
2885 2886
2886 2887 assert_response 302
2887 2888 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
2888 2889 end
2889 2890
2890 2891 def test_bulk_update_on_different_projects
2891 2892 @request.session[:user_id] = 2
2892 2893 # update issues priority
2893 2894 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
2894 2895 :issue => {:priority_id => 7,
2895 2896 :assigned_to_id => '',
2896 2897 :custom_field_values => {'2' => ''}}
2897 2898
2898 2899 assert_response 302
2899 2900 # check that the issues were updated
2900 2901 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
2901 2902
2902 2903 issue = Issue.find(1)
2903 2904 journal = issue.journals.find(:first, :order => 'created_on DESC')
2904 2905 assert_equal '125', issue.custom_value_for(2).value
2905 2906 assert_equal 'Bulk editing', journal.notes
2906 2907 assert_equal 1, journal.details.size
2907 2908 end
2908 2909
2909 2910 def test_bulk_update_on_different_projects_without_rights
2910 2911 @request.session[:user_id] = 3
2911 2912 user = User.find(3)
2912 2913 action = { :controller => "issues", :action => "bulk_update" }
2913 2914 assert user.allowed_to?(action, Issue.find(1).project)
2914 2915 assert ! user.allowed_to?(action, Issue.find(6).project)
2915 2916 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
2916 2917 :issue => {:priority_id => 7,
2917 2918 :assigned_to_id => '',
2918 2919 :custom_field_values => {'2' => ''}}
2919 2920 assert_response 403
2920 2921 assert_not_equal "Bulk should fail", Journal.last.notes
2921 2922 end
2922 2923
2923 2924 def test_bullk_update_should_send_a_notification
2924 2925 @request.session[:user_id] = 2
2925 2926 ActionMailer::Base.deliveries.clear
2926 2927 post(:bulk_update,
2927 2928 {
2928 2929 :ids => [1, 2],
2929 2930 :notes => 'Bulk editing',
2930 2931 :issue => {
2931 2932 :priority_id => 7,
2932 2933 :assigned_to_id => '',
2933 2934 :custom_field_values => {'2' => ''}
2934 2935 }
2935 2936 })
2936 2937
2937 2938 assert_response 302
2938 2939 assert_equal 2, ActionMailer::Base.deliveries.size
2939 2940 end
2940 2941
2941 2942 def test_bulk_update_project
2942 2943 @request.session[:user_id] = 2
2943 2944 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
2944 2945 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2945 2946 # Issues moved to project 2
2946 2947 assert_equal 2, Issue.find(1).project_id
2947 2948 assert_equal 2, Issue.find(2).project_id
2948 2949 # No tracker change
2949 2950 assert_equal 1, Issue.find(1).tracker_id
2950 2951 assert_equal 2, Issue.find(2).tracker_id
2951 2952 end
2952 2953
2953 2954 def test_bulk_update_project_on_single_issue_should_follow_when_needed
2954 2955 @request.session[:user_id] = 2
2955 2956 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
2956 2957 assert_redirected_to '/issues/1'
2957 2958 end
2958 2959
2959 2960 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
2960 2961 @request.session[:user_id] = 2
2961 2962 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
2962 2963 assert_redirected_to '/projects/onlinestore/issues'
2963 2964 end
2964 2965
2965 2966 def test_bulk_update_tracker
2966 2967 @request.session[:user_id] = 2
2967 2968 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
2968 2969 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2969 2970 assert_equal 2, Issue.find(1).tracker_id
2970 2971 assert_equal 2, Issue.find(2).tracker_id
2971 2972 end
2972 2973
2973 2974 def test_bulk_update_status
2974 2975 @request.session[:user_id] = 2
2975 2976 # update issues priority
2976 2977 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
2977 2978 :issue => {:priority_id => '',
2978 2979 :assigned_to_id => '',
2979 2980 :status_id => '5'}
2980 2981
2981 2982 assert_response 302
2982 2983 issue = Issue.find(1)
2983 2984 assert issue.closed?
2984 2985 end
2985 2986
2986 2987 def test_bulk_update_priority
2987 2988 @request.session[:user_id] = 2
2988 2989 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
2989 2990
2990 2991 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
2991 2992 assert_equal 6, Issue.find(1).priority_id
2992 2993 assert_equal 6, Issue.find(2).priority_id
2993 2994 end
2994 2995
2995 2996 def test_bulk_update_with_notes
2996 2997 @request.session[:user_id] = 2
2997 2998 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
2998 2999
2999 3000 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3000 3001 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
3001 3002 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
3002 3003 end
3003 3004
3004 3005 def test_bulk_update_parent_id
3005 3006 @request.session[:user_id] = 2
3006 3007 post :bulk_update, :ids => [1, 3],
3007 3008 :notes => 'Bulk editing parent',
3008 3009 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
3009 3010
3010 3011 assert_response 302
3011 3012 parent = Issue.find(2)
3012 3013 assert_equal parent.id, Issue.find(1).parent_id
3013 3014 assert_equal parent.id, Issue.find(3).parent_id
3014 3015 assert_equal [1, 3], parent.children.collect(&:id).sort
3015 3016 end
3016 3017
3017 3018 def test_bulk_update_custom_field
3018 3019 @request.session[:user_id] = 2
3019 3020 # update issues priority
3020 3021 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
3021 3022 :issue => {:priority_id => '',
3022 3023 :assigned_to_id => '',
3023 3024 :custom_field_values => {'2' => '777'}}
3024 3025
3025 3026 assert_response 302
3026 3027
3027 3028 issue = Issue.find(1)
3028 3029 journal = issue.journals.find(:first, :order => 'created_on DESC')
3029 3030 assert_equal '777', issue.custom_value_for(2).value
3030 3031 assert_equal 1, journal.details.size
3031 3032 assert_equal '125', journal.details.first.old_value
3032 3033 assert_equal '777', journal.details.first.value
3033 3034 end
3034 3035
3035 3036 def test_bulk_update_custom_field_to_blank
3036 3037 @request.session[:user_id] = 2
3037 3038 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
3038 3039 :issue => {:priority_id => '',
3039 3040 :assigned_to_id => '',
3040 3041 :custom_field_values => {'1' => '__none__'}}
3041 3042 assert_response 302
3042 3043 assert_equal '', Issue.find(1).custom_field_value(1)
3043 3044 assert_equal '', Issue.find(3).custom_field_value(1)
3044 3045 end
3045 3046
3046 3047 def test_bulk_update_multi_custom_field
3047 3048 field = CustomField.find(1)
3048 3049 field.update_attribute :multiple, true
3049 3050
3050 3051 @request.session[:user_id] = 2
3051 3052 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
3052 3053 :issue => {:priority_id => '',
3053 3054 :assigned_to_id => '',
3054 3055 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
3055 3056
3056 3057 assert_response 302
3057 3058
3058 3059 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
3059 3060 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
3060 3061 # the custom field is not associated with the issue tracker
3061 3062 assert_nil Issue.find(2).custom_field_value(1)
3062 3063 end
3063 3064
3064 3065 def test_bulk_update_multi_custom_field_to_blank
3065 3066 field = CustomField.find(1)
3066 3067 field.update_attribute :multiple, true
3067 3068
3068 3069 @request.session[:user_id] = 2
3069 3070 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
3070 3071 :issue => {:priority_id => '',
3071 3072 :assigned_to_id => '',
3072 3073 :custom_field_values => {'1' => ['__none__']}}
3073 3074 assert_response 302
3074 3075 assert_equal [''], Issue.find(1).custom_field_value(1)
3075 3076 assert_equal [''], Issue.find(3).custom_field_value(1)
3076 3077 end
3077 3078
3078 3079 def test_bulk_update_unassign
3079 3080 assert_not_nil Issue.find(2).assigned_to
3080 3081 @request.session[:user_id] = 2
3081 3082 # unassign issues
3082 3083 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
3083 3084 assert_response 302
3084 3085 # check that the issues were updated
3085 3086 assert_nil Issue.find(2).assigned_to
3086 3087 end
3087 3088
3088 3089 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
3089 3090 @request.session[:user_id] = 2
3090 3091
3091 3092 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
3092 3093
3093 3094 assert_response :redirect
3094 3095 issues = Issue.find([1,2])
3095 3096 issues.each do |issue|
3096 3097 assert_equal 4, issue.fixed_version_id
3097 3098 assert_not_equal issue.project_id, issue.fixed_version.project_id
3098 3099 end
3099 3100 end
3100 3101
3101 3102 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
3102 3103 @request.session[:user_id] = 2
3103 3104 post :bulk_update, :ids => [1,2], :back_url => '/issues'
3104 3105
3105 3106 assert_response :redirect
3106 3107 assert_redirected_to '/issues'
3107 3108 end
3108 3109
3109 3110 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3110 3111 @request.session[:user_id] = 2
3111 3112 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
3112 3113
3113 3114 assert_response :redirect
3114 3115 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
3115 3116 end
3116 3117
3117 3118 def test_bulk_update_with_failure_should_set_flash
3118 3119 @request.session[:user_id] = 2
3119 3120 Issue.update_all("subject = ''", "id = 2") # Make it invalid
3120 3121 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
3121 3122
3122 3123 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3123 3124 assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
3124 3125 end
3125 3126
3126 3127 def test_get_bulk_copy
3127 3128 @request.session[:user_id] = 2
3128 3129 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
3129 3130 assert_response :success
3130 3131 assert_template 'bulk_edit'
3131 3132
3132 3133 issues = assigns(:issues)
3133 3134 assert_not_nil issues
3134 3135 assert_equal [1, 2, 3], issues.map(&:id).sort
3135 3136
3136 3137 assert_select 'input[name=copy_attachments]'
3137 3138 end
3138 3139
3139 3140 def test_bulk_copy_to_another_project
3140 3141 @request.session[:user_id] = 2
3141 3142 assert_difference 'Issue.count', 2 do
3142 3143 assert_no_difference 'Project.find(1).issues.count' do
3143 3144 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
3144 3145 end
3145 3146 end
3146 3147 assert_redirected_to '/projects/ecookbook/issues'
3147 3148
3148 3149 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3149 3150 copies.each do |copy|
3150 3151 assert_equal 2, copy.project_id
3151 3152 end
3152 3153 end
3153 3154
3154 3155 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
3155 3156 @request.session[:user_id] = 2
3156 3157 issues = [
3157 3158 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
3158 3159 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
3159 3160 ]
3160 3161
3161 3162 assert_difference 'Issue.count', issues.size do
3162 3163 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
3163 3164 :issue => {
3164 3165 :project_id => '', :tracker_id => '', :assigned_to_id => '',
3165 3166 :status_id => '', :start_date => '', :due_date => ''
3166 3167 }
3167 3168 end
3168 3169
3169 3170 copies = Issue.all(:order => 'id DESC', :limit => issues.size)
3170 3171 issues.each do |orig|
3171 3172 copy = copies.detect {|c| c.subject == orig.subject}
3172 3173 assert_not_nil copy
3173 3174 assert_equal orig.project_id, copy.project_id
3174 3175 assert_equal orig.tracker_id, copy.tracker_id
3175 3176 assert_equal orig.status_id, copy.status_id
3176 3177 assert_equal orig.assigned_to_id, copy.assigned_to_id
3177 3178 assert_equal orig.priority_id, copy.priority_id
3178 3179 end
3179 3180 end
3180 3181
3181 3182 def test_bulk_copy_should_allow_changing_the_issue_attributes
3182 3183 # Fixes random test failure with Mysql
3183 3184 # where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3184 3185 # doesn't return the expected results
3185 3186 Issue.delete_all("project_id=2")
3186 3187
3187 3188 @request.session[:user_id] = 2
3188 3189 assert_difference 'Issue.count', 2 do
3189 3190 assert_no_difference 'Project.find(1).issues.count' do
3190 3191 post :bulk_update, :ids => [1, 2], :copy => '1',
3191 3192 :issue => {
3192 3193 :project_id => '2', :tracker_id => '', :assigned_to_id => '4',
3193 3194 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
3194 3195 }
3195 3196 end
3196 3197 end
3197 3198
3198 3199 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
3199 3200 assert_equal 2, copied_issues.size
3200 3201 copied_issues.each do |issue|
3201 3202 assert_equal 2, issue.project_id, "Project is incorrect"
3202 3203 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
3203 3204 assert_equal 1, issue.status_id, "Status is incorrect"
3204 3205 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
3205 3206 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
3206 3207 end
3207 3208 end
3208 3209
3209 3210 def test_bulk_copy_should_allow_adding_a_note
3210 3211 @request.session[:user_id] = 2
3211 3212 assert_difference 'Issue.count', 1 do
3212 3213 post :bulk_update, :ids => [1], :copy => '1',
3213 3214 :notes => 'Copying one issue',
3214 3215 :issue => {
3215 3216 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
3216 3217 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
3217 3218 }
3218 3219 end
3219 3220
3220 3221 issue = Issue.first(:order => 'id DESC')
3221 3222 assert_equal 1, issue.journals.size
3222 3223 journal = issue.journals.first
3223 3224 assert_equal 0, journal.details.size
3224 3225 assert_equal 'Copying one issue', journal.notes
3225 3226 end
3226 3227
3227 3228 def test_bulk_copy_should_allow_not_copying_the_attachments
3228 3229 attachment_count = Issue.find(3).attachments.size
3229 3230 assert attachment_count > 0
3230 3231 @request.session[:user_id] = 2
3231 3232
3232 3233 assert_difference 'Issue.count', 1 do
3233 3234 assert_no_difference 'Attachment.count' do
3234 3235 post :bulk_update, :ids => [3], :copy => '1',
3235 3236 :issue => {
3236 3237 :project_id => ''
3237 3238 }
3238 3239 end
3239 3240 end
3240 3241 end
3241 3242
3242 3243 def test_bulk_copy_should_allow_copying_the_attachments
3243 3244 attachment_count = Issue.find(3).attachments.size
3244 3245 assert attachment_count > 0
3245 3246 @request.session[:user_id] = 2
3246 3247
3247 3248 assert_difference 'Issue.count', 1 do
3248 3249 assert_difference 'Attachment.count', attachment_count do
3249 3250 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
3250 3251 :issue => {
3251 3252 :project_id => ''
3252 3253 }
3253 3254 end
3254 3255 end
3255 3256 end
3256 3257
3257 3258 def test_bulk_copy_to_another_project_should_follow_when_needed
3258 3259 @request.session[:user_id] = 2
3259 3260 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
3260 3261 issue = Issue.first(:order => 'id DESC')
3261 3262 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
3262 3263 end
3263 3264
3264 3265 def test_destroy_issue_with_no_time_entries
3265 3266 assert_nil TimeEntry.find_by_issue_id(2)
3266 3267 @request.session[:user_id] = 2
3267 3268
3268 3269 assert_difference 'Issue.count', -1 do
3269 3270 delete :destroy, :id => 2
3270 3271 end
3271 3272 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3272 3273 assert_nil Issue.find_by_id(2)
3273 3274 end
3274 3275
3275 3276 def test_destroy_issues_with_time_entries
3276 3277 @request.session[:user_id] = 2
3277 3278
3278 3279 assert_no_difference 'Issue.count' do
3279 3280 delete :destroy, :ids => [1, 3]
3280 3281 end
3281 3282 assert_response :success
3282 3283 assert_template 'destroy'
3283 3284 assert_not_nil assigns(:hours)
3284 3285 assert Issue.find_by_id(1) && Issue.find_by_id(3)
3285 3286 assert_tag 'form',
3286 3287 :descendant => {:tag => 'input', :attributes => {:name => '_method', :value => 'delete'}}
3287 3288 end
3288 3289
3289 3290 def test_destroy_issues_and_destroy_time_entries
3290 3291 @request.session[:user_id] = 2
3291 3292
3292 3293 assert_difference 'Issue.count', -2 do
3293 3294 assert_difference 'TimeEntry.count', -3 do
3294 3295 delete :destroy, :ids => [1, 3], :todo => 'destroy'
3295 3296 end
3296 3297 end
3297 3298 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3298 3299 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3299 3300 assert_nil TimeEntry.find_by_id([1, 2])
3300 3301 end
3301 3302
3302 3303 def test_destroy_issues_and_assign_time_entries_to_project
3303 3304 @request.session[:user_id] = 2
3304 3305
3305 3306 assert_difference 'Issue.count', -2 do
3306 3307 assert_no_difference 'TimeEntry.count' do
3307 3308 delete :destroy, :ids => [1, 3], :todo => 'nullify'
3308 3309 end
3309 3310 end
3310 3311 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3311 3312 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3312 3313 assert_nil TimeEntry.find(1).issue_id
3313 3314 assert_nil TimeEntry.find(2).issue_id
3314 3315 end
3315 3316
3316 3317 def test_destroy_issues_and_reassign_time_entries_to_another_issue
3317 3318 @request.session[:user_id] = 2
3318 3319
3319 3320 assert_difference 'Issue.count', -2 do
3320 3321 assert_no_difference 'TimeEntry.count' do
3321 3322 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
3322 3323 end
3323 3324 end
3324 3325 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
3325 3326 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
3326 3327 assert_equal 2, TimeEntry.find(1).issue_id
3327 3328 assert_equal 2, TimeEntry.find(2).issue_id
3328 3329 end
3329 3330
3330 3331 def test_destroy_issues_from_different_projects
3331 3332 @request.session[:user_id] = 2
3332 3333
3333 3334 assert_difference 'Issue.count', -3 do
3334 3335 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
3335 3336 end
3336 3337 assert_redirected_to :controller => 'issues', :action => 'index'
3337 3338 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
3338 3339 end
3339 3340
3340 3341 def test_destroy_parent_and_child_issues
3341 3342 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
3342 3343 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
3343 3344 assert child.is_descendant_of?(parent.reload)
3344 3345
3345 3346 @request.session[:user_id] = 2
3346 3347 assert_difference 'Issue.count', -2 do
3347 3348 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
3348 3349 end
3349 3350 assert_response 302
3350 3351 end
3351 3352
3352 3353 def test_default_search_scope
3353 3354 get :index
3354 3355 assert_tag :div, :attributes => {:id => 'quick-search'},
3355 3356 :child => {:tag => 'form',
3356 3357 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
3357 3358 end
3358 3359 end
General Comments 0
You need to be logged in to leave comments. Login now