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