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