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