comparison test/functional/issues_controller_test.rb @ 524:1248a47e81b3 feature_36

Merge from branch "luisf"
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Mon, 25 Jul 2011 14:39:38 +0100
parents 0c939c159af4
children cbb26bc654de
comparison
equal deleted inserted replaced
519:3be6bc3c2a17 524:1248a47e81b3
1 # Redmine - project management software 1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang 2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 # 3 #
4 # This program is free software; you can redistribute it and/or 4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License 5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2 6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version. 7 # of the License, or (at your option) any later version.
8 # 8 #
9 # This program is distributed in the hope that it will be useful, 9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details. 12 # GNU General Public License for more details.
13 # 13 #
14 # You should have received a copy of the GNU General Public License 14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software 15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require File.dirname(__FILE__) + '/../test_helper' 18 require File.expand_path('../../test_helper', __FILE__)
19 require 'issues_controller' 19 require 'issues_controller'
20
21 # Re-raise errors caught by the controller.
22 class IssuesController; def rescue_action(e) raise e end; end
23 20
24 class IssuesControllerTest < ActionController::TestCase 21 class IssuesControllerTest < ActionController::TestCase
25 fixtures :projects, 22 fixtures :projects,
26 :users, 23 :users,
27 :roles, 24 :roles,
43 :custom_fields_trackers, 40 :custom_fields_trackers,
44 :time_entries, 41 :time_entries,
45 :journals, 42 :journals,
46 :journal_details, 43 :journal_details,
47 :queries 44 :queries
48 45
49 def setup 46 def setup
50 @controller = IssuesController.new 47 @controller = IssuesController.new
51 @request = ActionController::TestRequest.new 48 @request = ActionController::TestRequest.new
52 @response = ActionController::TestResponse.new 49 @response = ActionController::TestResponse.new
53 User.current = nil 50 User.current = nil
54 end 51 end
55 52
56 def test_index 53 def test_index
57 Setting.default_language = 'en' 54 Setting.default_language = 'en'
58 55
59 get :index 56 get :index
60 assert_response :success 57 assert_response :success
61 assert_template 'index.rhtml' 58 assert_template 'index.rhtml'
62 assert_not_nil assigns(:issues) 59 assert_not_nil assigns(:issues)
63 assert_nil assigns(:project) 60 assert_nil assigns(:project)
67 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/ 64 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
68 assert_no_tag :tag => 'a', :content => /Issue on project 2/ 65 assert_no_tag :tag => 'a', :content => /Issue on project 2/
69 # project column 66 # project column
70 assert_tag :tag => 'th', :content => /Project/ 67 assert_tag :tag => 'th', :content => /Project/
71 end 68 end
72 69
73 def test_index_should_not_list_issues_when_module_disabled 70 def test_index_should_not_list_issues_when_module_disabled
74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1") 71 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
75 get :index 72 get :index
76 assert_response :success 73 assert_response :success
77 assert_template 'index.rhtml' 74 assert_template 'index.rhtml'
89 assert_not_nil assigns(:issues) 86 assert_not_nil assigns(:issues)
90 assert_nil assigns(:project) 87 assert_nil assigns(:project)
91 assert_no_tag :tag => 'a', :content => /Can't print recipes/ 88 assert_no_tag :tag => 'a', :content => /Can't print recipes/
92 assert_tag :tag => 'a', :content => /Subproject issue/ 89 assert_tag :tag => 'a', :content => /Subproject issue/
93 end 90 end
94 91
92 def test_index_should_list_visible_issues_only
93 get :index, :per_page => 100
94 assert_response :success
95 assert_not_nil assigns(:issues)
96 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
97 end
98
95 def test_index_with_project 99 def test_index_with_project
96 Setting.display_subprojects_issues = 0 100 Setting.display_subprojects_issues = 0
97 get :index, :project_id => 1 101 get :index, :project_id => 1
98 assert_response :success 102 assert_response :success
99 assert_template 'index.rhtml' 103 assert_template 'index.rhtml'
100 assert_not_nil assigns(:issues) 104 assert_not_nil assigns(:issues)
101 assert_tag :tag => 'a', :content => /Can't print recipes/ 105 assert_tag :tag => 'a', :content => /Can't print recipes/
102 assert_no_tag :tag => 'a', :content => /Subproject issue/ 106 assert_no_tag :tag => 'a', :content => /Subproject issue/
103 end 107 end
104 108
105 def test_index_with_project_and_subprojects 109 def test_index_with_project_and_subprojects
106 Setting.display_subprojects_issues = 1 110 Setting.display_subprojects_issues = 1
107 get :index, :project_id => 1 111 get :index, :project_id => 1
108 assert_response :success 112 assert_response :success
109 assert_template 'index.rhtml' 113 assert_template 'index.rhtml'
110 assert_not_nil assigns(:issues) 114 assert_not_nil assigns(:issues)
111 assert_tag :tag => 'a', :content => /Can't print recipes/ 115 assert_tag :tag => 'a', :content => /Can't print recipes/
112 assert_tag :tag => 'a', :content => /Subproject issue/ 116 assert_tag :tag => 'a', :content => /Subproject issue/
113 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/ 117 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
114 end 118 end
115 119
116 def test_index_with_project_and_subprojects_should_show_private_subprojects 120 def test_index_with_project_and_subprojects_should_show_private_subprojects
117 @request.session[:user_id] = 2 121 @request.session[:user_id] = 2
118 Setting.display_subprojects_issues = 1 122 Setting.display_subprojects_issues = 1
119 get :index, :project_id => 1 123 get :index, :project_id => 1
120 assert_response :success 124 assert_response :success
122 assert_not_nil assigns(:issues) 126 assert_not_nil assigns(:issues)
123 assert_tag :tag => 'a', :content => /Can't print recipes/ 127 assert_tag :tag => 'a', :content => /Can't print recipes/
124 assert_tag :tag => 'a', :content => /Subproject issue/ 128 assert_tag :tag => 'a', :content => /Subproject issue/
125 assert_tag :tag => 'a', :content => /Issue of a private subproject/ 129 assert_tag :tag => 'a', :content => /Issue of a private subproject/
126 end 130 end
127 131
128 def test_index_with_project_and_default_filter 132 def test_index_with_project_and_default_filter
129 get :index, :project_id => 1, :set_filter => 1 133 get :index, :project_id => 1, :set_filter => 1
130 assert_response :success 134 assert_response :success
131 assert_template 'index.rhtml' 135 assert_template 'index.rhtml'
132 assert_not_nil assigns(:issues) 136 assert_not_nil assigns(:issues)
133 137
134 query = assigns(:query) 138 query = assigns(:query)
135 assert_not_nil query 139 assert_not_nil query
136 # default filter 140 # default filter
137 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters) 141 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
138 end 142 end
139 143
140 def test_index_with_project_and_filter 144 def test_index_with_project_and_filter
141 get :index, :project_id => 1, :set_filter => 1, 145 get :index, :project_id => 1, :set_filter => 1,
142 :fields => ['tracker_id'], 146 :f => ['tracker_id'],
143 :operators => {'tracker_id' => '='}, 147 :op => {'tracker_id' => '='},
144 :values => {'tracker_id' => ['1']} 148 :v => {'tracker_id' => ['1']}
145 assert_response :success 149 assert_response :success
146 assert_template 'index.rhtml' 150 assert_template 'index.rhtml'
147 assert_not_nil assigns(:issues) 151 assert_not_nil assigns(:issues)
148 152
149 query = assigns(:query) 153 query = assigns(:query)
150 assert_not_nil query 154 assert_not_nil query
151 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters) 155 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
152 end 156 end
153 157
154 def test_index_with_project_and_empty_filters 158 def test_index_with_project_and_empty_filters
155 get :index, :project_id => 1, :set_filter => 1, :fields => [''] 159 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
156 assert_response :success 160 assert_response :success
157 assert_template 'index.rhtml' 161 assert_template 'index.rhtml'
158 assert_not_nil assigns(:issues) 162 assert_not_nil assigns(:issues)
159 163
160 query = assigns(:query) 164 query = assigns(:query)
161 assert_not_nil query 165 assert_not_nil query
162 # no filter 166 # no filter
163 assert_equal({}, query.filters) 167 assert_equal({}, query.filters)
164 end 168 end
165 169
166 def test_index_with_query 170 def test_index_with_query
167 get :index, :project_id => 1, :query_id => 5 171 get :index, :project_id => 1, :query_id => 5
168 assert_response :success 172 assert_response :success
169 assert_template 'index.rhtml' 173 assert_template 'index.rhtml'
170 assert_not_nil assigns(:issues) 174 assert_not_nil assigns(:issues)
171 assert_nil assigns(:issue_count_by_group) 175 assert_nil assigns(:issue_count_by_group)
172 end 176 end
173 177
174 def test_index_with_query_grouped_by_tracker 178 def test_index_with_query_grouped_by_tracker
175 get :index, :project_id => 1, :query_id => 6 179 get :index, :project_id => 1, :query_id => 6
176 assert_response :success 180 assert_response :success
177 assert_template 'index.rhtml' 181 assert_template 'index.rhtml'
178 assert_not_nil assigns(:issues) 182 assert_not_nil assigns(:issues)
179 assert_not_nil assigns(:issue_count_by_group) 183 assert_not_nil assigns(:issue_count_by_group)
180 end 184 end
181 185
182 def test_index_with_query_grouped_by_list_custom_field 186 def test_index_with_query_grouped_by_list_custom_field
183 get :index, :project_id => 1, :query_id => 9 187 get :index, :project_id => 1, :query_id => 9
184 assert_response :success 188 assert_response :success
185 assert_template 'index.rhtml' 189 assert_template 'index.rhtml'
186 assert_not_nil assigns(:issues) 190 assert_not_nil assigns(:issues)
187 assert_not_nil assigns(:issue_count_by_group) 191 assert_not_nil assigns(:issue_count_by_group)
188 end 192 end
189 193
194 def test_private_query_should_not_be_available_to_other_users
195 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
196 @request.session[:user_id] = 3
197
198 get :index, :query_id => q.id
199 assert_response 403
200 end
201
202 def test_private_query_should_be_available_to_its_user
203 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
204 @request.session[:user_id] = 2
205
206 get :index, :query_id => q.id
207 assert_response :success
208 end
209
210 def test_public_query_should_be_available_to_other_users
211 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
212 @request.session[:user_id] = 3
213
214 get :index, :query_id => q.id
215 assert_response :success
216 end
217
190 def test_index_sort_by_field_not_included_in_columns 218 def test_index_sort_by_field_not_included_in_columns
191 Setting.issue_list_default_columns = %w(subject author) 219 Setting.issue_list_default_columns = %w(subject author)
192 get :index, :sort => 'tracker' 220 get :index, :sort => 'tracker'
193 end 221 end
194 222
195 def test_index_csv_with_project 223 def test_index_csv_with_project
196 Setting.default_language = 'en' 224 Setting.default_language = 'en'
197 225
198 get :index, :format => 'csv' 226 get :index, :format => 'csv'
199 assert_response :success 227 assert_response :success
200 assert_not_nil assigns(:issues) 228 assert_not_nil assigns(:issues)
201 assert_equal 'text/csv', @response.content_type 229 assert_equal 'text/csv', @response.content_type
202 assert @response.body.starts_with?("#,") 230 assert @response.body.starts_with?("#,")
204 get :index, :project_id => 1, :format => 'csv' 232 get :index, :project_id => 1, :format => 'csv'
205 assert_response :success 233 assert_response :success
206 assert_not_nil assigns(:issues) 234 assert_not_nil assigns(:issues)
207 assert_equal 'text/csv', @response.content_type 235 assert_equal 'text/csv', @response.content_type
208 end 236 end
209 237
210 def test_index_pdf 238 def test_index_pdf
211 get :index, :format => 'pdf' 239 get :index, :format => 'pdf'
212 assert_response :success 240 assert_response :success
213 assert_not_nil assigns(:issues) 241 assert_not_nil assigns(:issues)
214 assert_equal 'application/pdf', @response.content_type 242 assert_equal 'application/pdf', @response.content_type
215 243
216 get :index, :project_id => 1, :format => 'pdf' 244 get :index, :project_id => 1, :format => 'pdf'
217 assert_response :success 245 assert_response :success
218 assert_not_nil assigns(:issues) 246 assert_not_nil assigns(:issues)
219 assert_equal 'application/pdf', @response.content_type 247 assert_equal 'application/pdf', @response.content_type
220 248
221 get :index, :project_id => 1, :query_id => 6, :format => 'pdf' 249 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
222 assert_response :success 250 assert_response :success
223 assert_not_nil assigns(:issues) 251 assert_not_nil assigns(:issues)
224 assert_equal 'application/pdf', @response.content_type 252 assert_equal 'application/pdf', @response.content_type
225 end 253 end
226 254
227 def test_index_pdf_with_query_grouped_by_list_custom_field 255 def test_index_pdf_with_query_grouped_by_list_custom_field
228 get :index, :project_id => 1, :query_id => 9, :format => 'pdf' 256 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
229 assert_response :success 257 assert_response :success
230 assert_not_nil assigns(:issues) 258 assert_not_nil assigns(:issues)
231 assert_not_nil assigns(:issue_count_by_group) 259 assert_not_nil assigns(:issue_count_by_group)
232 assert_equal 'application/pdf', @response.content_type 260 assert_equal 'application/pdf', @response.content_type
233 end 261 end
234 262
235 def test_index_sort 263 def test_index_sort
236 get :index, :sort => 'tracker,id:desc' 264 get :index, :sort => 'tracker,id:desc'
237 assert_response :success 265 assert_response :success
238 266
239 sort_params = @request.session['issues_index_sort'] 267 sort_params = @request.session['issues_index_sort']
240 assert sort_params.is_a?(String) 268 assert sort_params.is_a?(String)
241 assert_equal 'tracker,id:desc', sort_params 269 assert_equal 'tracker,id:desc', sort_params
242 270
243 issues = assigns(:issues) 271 issues = assigns(:issues)
244 assert_not_nil issues 272 assert_not_nil issues
245 assert !issues.empty? 273 assert !issues.empty?
246 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id) 274 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
247 end 275 end
248 276
249 def test_index_with_columns 277 def test_index_with_columns
250 columns = ['tracker', 'subject', 'assigned_to'] 278 columns = ['tracker', 'subject', 'assigned_to']
251 get :index, :set_filter => 1, :query => { 'column_names' => columns} 279 get :index, :set_filter => 1, :c => columns
252 assert_response :success 280 assert_response :success
253 281
254 # query should use specified columns 282 # query should use specified columns
255 query = assigns(:query) 283 query = assigns(:query)
256 assert_kind_of Query, query 284 assert_kind_of Query, query
257 assert_equal columns, query.column_names.map(&:to_s) 285 assert_equal columns, query.column_names.map(&:to_s)
258 286
259 # columns should be stored in session 287 # columns should be stored in session
260 assert_kind_of Hash, session[:query] 288 assert_kind_of Hash, session[:query]
261 assert_kind_of Array, session[:query][:column_names] 289 assert_kind_of Array, session[:query][:column_names]
262 assert_equal columns, session[:query][:column_names].map(&:to_s) 290 assert_equal columns, session[:query][:column_names].map(&:to_s)
291
292 # ensure only these columns are kept in the selected columns list
293 assert_tag :tag => 'select', :attributes => { :id => 'selected_columns' },
294 :children => { :count => 3 }
295 assert_no_tag :tag => 'option', :attributes => { :value => 'project' },
296 :parent => { :tag => 'select', :attributes => { :id => "selected_columns" } }
297 end
298
299 def test_index_with_custom_field_column
300 columns = %w(tracker subject cf_2)
301 get :index, :set_filter => 1, :c => columns
302 assert_response :success
303
304 # query should use specified columns
305 query = assigns(:query)
306 assert_kind_of Query, query
307 assert_equal columns, query.column_names.map(&:to_s)
308
309 assert_tag :td,
310 :attributes => {:class => 'cf_2 string'},
311 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
263 end 312 end
264 313
265 def test_show_by_anonymous 314 def test_show_by_anonymous
266 get :show, :id => 1 315 get :show, :id => 1
267 assert_response :success 316 assert_response :success
268 assert_template 'show.rhtml' 317 assert_template 'show.rhtml'
269 assert_not_nil assigns(:issue) 318 assert_not_nil assigns(:issue)
270 assert_equal Issue.find(1), assigns(:issue) 319 assert_equal Issue.find(1), assigns(:issue)
271 320
272 # anonymous role is allowed to add a note 321 # anonymous role is allowed to add a note
273 assert_tag :tag => 'form', 322 assert_tag :tag => 'form',
274 :descendant => { :tag => 'fieldset', 323 :descendant => { :tag => 'fieldset',
275 :child => { :tag => 'legend', 324 :child => { :tag => 'legend',
276 :content => /Notes/ } } 325 :content => /Notes/ } }
277 end 326 end
278 327
279 def test_show_by_manager 328 def test_show_by_manager
280 @request.session[:user_id] = 2 329 @request.session[:user_id] = 2
281 get :show, :id => 1 330 get :show, :id => 1
282 assert_response :success 331 assert_response :success
283 332
333 assert_tag :tag => 'a',
334 :content => /Quote/
335
284 assert_tag :tag => 'form', 336 assert_tag :tag => 'form',
285 :descendant => { :tag => 'fieldset', 337 :descendant => { :tag => 'fieldset',
286 :child => { :tag => 'legend', 338 :child => { :tag => 'legend',
287 :content => /Change properties/ } }, 339 :content => /Change properties/ } },
288 :descendant => { :tag => 'fieldset', 340 :descendant => { :tag => 'fieldset',
289 :child => { :tag => 'legend', 341 :child => { :tag => 'legend',
290 :content => /Log time/ } }, 342 :content => /Log time/ } },
291 :descendant => { :tag => 'fieldset', 343 :descendant => { :tag => 'fieldset',
292 :child => { :tag => 'legend', 344 :child => { :tag => 'legend',
293 :content => /Notes/ } } 345 :content => /Notes/ } }
294 end 346 end
295 347
296 def test_show_should_deny_anonymous_access_without_permission 348 def test_show_should_deny_anonymous_access_without_permission
297 Role.anonymous.remove_permission!(:view_issues) 349 Role.anonymous.remove_permission!(:view_issues)
298 get :show, :id => 1 350 get :show, :id => 1
299 assert_response :redirect 351 assert_response :redirect
300 end 352 end
301 353
354 def test_show_should_deny_anonymous_access_to_private_issue
355 Issue.update_all(["is_private = ?", true], "id = 1")
356 get :show, :id => 1
357 assert_response :redirect
358 end
359
302 def test_show_should_deny_non_member_access_without_permission 360 def test_show_should_deny_non_member_access_without_permission
303 Role.non_member.remove_permission!(:view_issues) 361 Role.non_member.remove_permission!(:view_issues)
304 @request.session[:user_id] = 9 362 @request.session[:user_id] = 9
305 get :show, :id => 1 363 get :show, :id => 1
306 assert_response 403 364 assert_response 403
307 end 365 end
308 366
367 def test_show_should_deny_non_member_access_to_private_issue
368 Issue.update_all(["is_private = ?", true], "id = 1")
369 @request.session[:user_id] = 9
370 get :show, :id => 1
371 assert_response 403
372 end
373
309 def test_show_should_deny_member_access_without_permission 374 def test_show_should_deny_member_access_without_permission
310 Role.find(1).remove_permission!(:view_issues) 375 Role.find(1).remove_permission!(:view_issues)
311 @request.session[:user_id] = 2 376 @request.session[:user_id] = 2
312 get :show, :id => 1 377 get :show, :id => 1
313 assert_response 403 378 assert_response 403
314 end 379 end
315 380
381 def test_show_should_deny_member_access_to_private_issue_without_permission
382 Issue.update_all(["is_private = ?", true], "id = 1")
383 @request.session[:user_id] = 3
384 get :show, :id => 1
385 assert_response 403
386 end
387
388 def test_show_should_allow_author_access_to_private_issue
389 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
390 @request.session[:user_id] = 3
391 get :show, :id => 1
392 assert_response :success
393 end
394
395 def test_show_should_allow_assignee_access_to_private_issue
396 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
397 @request.session[:user_id] = 3
398 get :show, :id => 1
399 assert_response :success
400 end
401
402 def test_show_should_allow_member_access_to_private_issue_with_permission
403 Issue.update_all(["is_private = ?", true], "id = 1")
404 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
405 @request.session[:user_id] = 3
406 get :show, :id => 1
407 assert_response :success
408 end
409
316 def test_show_should_not_disclose_relations_to_invisible_issues 410 def test_show_should_not_disclose_relations_to_invisible_issues
317 Setting.cross_project_issue_relations = '1' 411 Setting.cross_project_issue_relations = '1'
318 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates') 412 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
319 # Relation to a private project issue 413 # Relation to a private project issue
320 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates') 414 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
321 415
322 get :show, :id => 1 416 get :show, :id => 1
323 assert_response :success 417 assert_response :success
324 418
325 assert_tag :div, :attributes => { :id => 'relations' }, 419 assert_tag :div, :attributes => { :id => 'relations' },
326 :descendant => { :tag => 'a', :content => /#2$/ } 420 :descendant => { :tag => 'a', :content => /#2$/ }
327 assert_no_tag :div, :attributes => { :id => 'relations' }, 421 assert_no_tag :div, :attributes => { :id => 'relations' },
328 :descendant => { :tag => 'a', :content => /#4$/ } 422 :descendant => { :tag => 'a', :content => /#4$/ }
329 end 423 end
330 424
331 def test_show_atom 425 def test_show_atom
332 get :show, :id => 2, :format => 'atom' 426 get :show, :id => 2, :format => 'atom'
333 assert_response :success 427 assert_response :success
334 assert_template 'journals/index.rxml' 428 assert_template 'journals/index.rxml'
335 # Inline image 429 # Inline image
336 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10')) 430 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
337 end 431 end
338 432
339 def test_show_export_to_pdf 433 def test_show_export_to_pdf
340 get :show, :id => 3, :format => 'pdf' 434 get :show, :id => 3, :format => 'pdf'
341 assert_response :success 435 assert_response :success
342 assert_equal 'application/pdf', @response.content_type 436 assert_equal 'application/pdf', @response.content_type
343 assert @response.body.starts_with?('%PDF') 437 assert @response.body.starts_with?('%PDF')
347 def test_get_new 441 def test_get_new
348 @request.session[:user_id] = 2 442 @request.session[:user_id] = 2
349 get :new, :project_id => 1, :tracker_id => 1 443 get :new, :project_id => 1, :tracker_id => 1
350 assert_response :success 444 assert_response :success
351 assert_template 'new' 445 assert_template 'new'
352 446
353 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]', 447 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
354 :value => 'Default string' } 448 :value => 'Default string' }
355 end 449 end
356 450
357 def test_get_new_without_tracker_id 451 def test_get_new_without_tracker_id
358 @request.session[:user_id] = 2 452 @request.session[:user_id] = 2
359 get :new, :project_id => 1 453 get :new, :project_id => 1
360 assert_response :success 454 assert_response :success
361 assert_template 'new' 455 assert_template 'new'
362 456
363 issue = assigns(:issue) 457 issue = assigns(:issue)
364 assert_not_nil issue 458 assert_not_nil issue
365 assert_equal Project.find(1).trackers.first, issue.tracker 459 assert_equal Project.find(1).trackers.first, issue.tracker
366 end 460 end
367 461
368 def test_get_new_with_no_default_status_should_display_an_error 462 def test_get_new_with_no_default_status_should_display_an_error
369 @request.session[:user_id] = 2 463 @request.session[:user_id] = 2
370 IssueStatus.delete_all 464 IssueStatus.delete_all
371 465
372 get :new, :project_id => 1 466 get :new, :project_id => 1
373 assert_response 500 467 assert_response 500
374 assert_error_tag :content => /No default issue/ 468 assert_error_tag :content => /No default issue/
375 end 469 end
376 470
377 def test_get_new_with_no_tracker_should_display_an_error 471 def test_get_new_with_no_tracker_should_display_an_error
378 @request.session[:user_id] = 2 472 @request.session[:user_id] = 2
379 Tracker.delete_all 473 Tracker.delete_all
380 474
381 get :new, :project_id => 1 475 get :new, :project_id => 1
382 assert_response 500 476 assert_response 500
383 assert_error_tag :content => /No tracker/ 477 assert_error_tag :content => /No tracker/
384 end 478 end
385 479
386 def test_update_new_form 480 def test_update_new_form
387 @request.session[:user_id] = 2 481 @request.session[:user_id] = 2
388 xhr :post, :new, :project_id => 1, 482 xhr :post, :new, :project_id => 1,
389 :issue => {:tracker_id => 2, 483 :issue => {:tracker_id => 2,
390 :subject => 'This is the test_new issue', 484 :subject => 'This is the test_new issue',
391 :description => 'This is the description', 485 :description => 'This is the description',
392 :priority_id => 5} 486 :priority_id => 5}
393 assert_response :success 487 assert_response :success
394 assert_template 'attributes' 488 assert_template 'attributes'
395 489
396 issue = assigns(:issue) 490 issue = assigns(:issue)
397 assert_kind_of Issue, issue 491 assert_kind_of Issue, issue
398 assert_equal 1, issue.project_id 492 assert_equal 1, issue.project_id
399 assert_equal 2, issue.tracker_id 493 assert_equal 2, issue.tracker_id
400 assert_equal 'This is the test_new issue', issue.subject 494 assert_equal 'This is the test_new issue', issue.subject
401 end 495 end
402 496
403 def test_post_create 497 def test_post_create
404 @request.session[:user_id] = 2 498 @request.session[:user_id] = 2
405 assert_difference 'Issue.count' do 499 assert_difference 'Issue.count' do
406 post :create, :project_id => 1, 500 post :create, :project_id => 1,
407 :issue => {:tracker_id => 3, 501 :issue => {:tracker_id => 3,
408 :status_id => 2, 502 :status_id => 2,
409 :subject => 'This is the test_new issue', 503 :subject => 'This is the test_new issue',
410 :description => 'This is the description', 504 :description => 'This is the description',
411 :priority_id => 5, 505 :priority_id => 5,
412 :start_date => '2010-11-07', 506 :start_date => '2010-11-07',
413 :estimated_hours => '', 507 :estimated_hours => '',
414 :custom_field_values => {'2' => 'Value for field 2'}} 508 :custom_field_values => {'2' => 'Value for field 2'}}
415 end 509 end
416 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id 510 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
417 511
418 issue = Issue.find_by_subject('This is the test_new issue') 512 issue = Issue.find_by_subject('This is the test_new issue')
419 assert_not_nil issue 513 assert_not_nil issue
420 assert_equal 2, issue.author_id 514 assert_equal 2, issue.author_id
421 assert_equal 3, issue.tracker_id 515 assert_equal 3, issue.tracker_id
422 assert_equal 2, issue.status_id 516 assert_equal 2, issue.status_id
424 assert_nil issue.estimated_hours 518 assert_nil issue.estimated_hours
425 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2}) 519 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
426 assert_not_nil v 520 assert_not_nil v
427 assert_equal 'Value for field 2', v.value 521 assert_equal 'Value for field 2', v.value
428 end 522 end
429 523
430 def test_post_create_without_start_date 524 def test_post_create_without_start_date
431 @request.session[:user_id] = 2 525 @request.session[:user_id] = 2
432 assert_difference 'Issue.count' do 526 assert_difference 'Issue.count' do
433 post :create, :project_id => 1, 527 post :create, :project_id => 1,
434 :issue => {:tracker_id => 3, 528 :issue => {:tracker_id => 3,
435 :status_id => 2, 529 :status_id => 2,
436 :subject => 'This is the test_new issue', 530 :subject => 'This is the test_new issue',
437 :description => 'This is the description', 531 :description => 'This is the description',
438 :priority_id => 5, 532 :priority_id => 5,
439 :start_date => '', 533 :start_date => '',
440 :estimated_hours => '', 534 :estimated_hours => '',
441 :custom_field_values => {'2' => 'Value for field 2'}} 535 :custom_field_values => {'2' => 'Value for field 2'}}
442 end 536 end
443 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id 537 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
444 538
445 issue = Issue.find_by_subject('This is the test_new issue') 539 issue = Issue.find_by_subject('This is the test_new issue')
446 assert_not_nil issue 540 assert_not_nil issue
447 assert_nil issue.start_date 541 assert_nil issue.start_date
448 end 542 end
449 543
450 def test_post_create_and_continue 544 def test_post_create_and_continue
451 @request.session[:user_id] = 2 545 @request.session[:user_id] = 2
452 post :create, :project_id => 1, 546 post :create, :project_id => 1,
453 :issue => {:tracker_id => 3, 547 :issue => {:tracker_id => 3,
454 :subject => 'This is first issue', 548 :subject => 'This is first issue',
455 :priority_id => 5}, 549 :priority_id => 5},
456 :continue => '' 550 :continue => ''
457 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', 551 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook',
458 :issue => {:tracker_id => 3} 552 :issue => {:tracker_id => 3}
459 end 553 end
460 554
461 def test_post_create_without_custom_fields_param 555 def test_post_create_without_custom_fields_param
462 @request.session[:user_id] = 2 556 @request.session[:user_id] = 2
463 assert_difference 'Issue.count' do 557 assert_difference 'Issue.count' do
464 post :create, :project_id => 1, 558 post :create, :project_id => 1,
465 :issue => {:tracker_id => 1, 559 :issue => {:tracker_id => 1,
466 :subject => 'This is the test_new issue', 560 :subject => 'This is the test_new issue',
467 :description => 'This is the description', 561 :description => 'This is the description',
468 :priority_id => 5} 562 :priority_id => 5}
469 end 563 end
473 def test_post_create_with_required_custom_field_and_without_custom_fields_param 567 def test_post_create_with_required_custom_field_and_without_custom_fields_param
474 field = IssueCustomField.find_by_name('Database') 568 field = IssueCustomField.find_by_name('Database')
475 field.update_attribute(:is_required, true) 569 field.update_attribute(:is_required, true)
476 570
477 @request.session[:user_id] = 2 571 @request.session[:user_id] = 2
478 post :create, :project_id => 1, 572 post :create, :project_id => 1,
479 :issue => {:tracker_id => 1, 573 :issue => {:tracker_id => 1,
480 :subject => 'This is the test_new issue', 574 :subject => 'This is the test_new issue',
481 :description => 'This is the description', 575 :description => 'This is the description',
482 :priority_id => 5} 576 :priority_id => 5}
483 assert_response :success 577 assert_response :success
484 assert_template 'new' 578 assert_template 'new'
485 issue = assigns(:issue) 579 issue = assigns(:issue)
486 assert_not_nil issue 580 assert_not_nil issue
487 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values) 581 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
488 end 582 end
489 583
490 def test_post_create_with_watchers 584 def test_post_create_with_watchers
491 @request.session[:user_id] = 2 585 @request.session[:user_id] = 2
492 ActionMailer::Base.deliveries.clear 586 ActionMailer::Base.deliveries.clear
493 587
494 assert_difference 'Watcher.count', 2 do 588 assert_difference 'Watcher.count', 2 do
495 post :create, :project_id => 1, 589 post :create, :project_id => 1,
496 :issue => {:tracker_id => 1, 590 :issue => {:tracker_id => 1,
497 :subject => 'This is a new issue with watchers', 591 :subject => 'This is a new issue with watchers',
498 :description => 'This is the description', 592 :description => 'This is the description',
499 :priority_id => 5, 593 :priority_id => 5,
500 :watcher_user_ids => ['2', '3']} 594 :watcher_user_ids => ['2', '3']}
501 end 595 end
502 issue = Issue.find_by_subject('This is a new issue with watchers') 596 issue = Issue.find_by_subject('This is a new issue with watchers')
503 assert_not_nil issue 597 assert_not_nil issue
504 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue 598 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
505 599
506 # Watchers added 600 # Watchers added
507 assert_equal [2, 3], issue.watcher_user_ids.sort 601 assert_equal [2, 3], issue.watcher_user_ids.sort
508 assert issue.watched_by?(User.find(3)) 602 assert issue.watched_by?(User.find(3))
509 # Watchers notified 603 # Watchers notified
510 mail = ActionMailer::Base.deliveries.last 604 mail = ActionMailer::Base.deliveries.last
511 assert_kind_of TMail::Mail, mail 605 assert_kind_of TMail::Mail, mail
512 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail) 606 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
513 end 607 end
514 608
515 def test_post_create_subissue 609 def test_post_create_subissue
516 @request.session[:user_id] = 2 610 @request.session[:user_id] = 2
517 611
518 assert_difference 'Issue.count' do 612 assert_difference 'Issue.count' do
519 post :create, :project_id => 1, 613 post :create, :project_id => 1,
520 :issue => {:tracker_id => 1, 614 :issue => {:tracker_id => 1,
521 :subject => 'This is a child issue', 615 :subject => 'This is a child issue',
522 :parent_issue_id => 2} 616 :parent_issue_id => 2}
523 end 617 end
524 issue = Issue.find_by_subject('This is a child issue') 618 issue = Issue.find_by_subject('This is a child issue')
525 assert_not_nil issue 619 assert_not_nil issue
526 assert_equal Issue.find(2), issue.parent 620 assert_equal Issue.find(2), issue.parent
527 end 621 end
622
623 def test_post_create_subissue_with_non_numeric_parent_id
624 @request.session[:user_id] = 2
625
626 assert_difference 'Issue.count' do
627 post :create, :project_id => 1,
628 :issue => {:tracker_id => 1,
629 :subject => 'This is a child issue',
630 :parent_issue_id => 'ABC'}
631 end
632 issue = Issue.find_by_subject('This is a child issue')
633 assert_not_nil issue
634 assert_nil issue.parent
635 end
528 636
637 def test_post_create_private
638 @request.session[:user_id] = 2
639
640 assert_difference 'Issue.count' do
641 post :create, :project_id => 1,
642 :issue => {:tracker_id => 1,
643 :subject => 'This is a private issue',
644 :is_private => '1'}
645 end
646 issue = Issue.first(:order => 'id DESC')
647 assert issue.is_private?
648 end
649
650 def test_post_create_private_with_set_own_issues_private_permission
651 role = Role.find(1)
652 role.remove_permission! :set_issues_private
653 role.add_permission! :set_own_issues_private
654
655 @request.session[:user_id] = 2
656
657 assert_difference 'Issue.count' do
658 post :create, :project_id => 1,
659 :issue => {:tracker_id => 1,
660 :subject => 'This is a private issue',
661 :is_private => '1'}
662 end
663 issue = Issue.first(:order => 'id DESC')
664 assert issue.is_private?
665 end
666
529 def test_post_create_should_send_a_notification 667 def test_post_create_should_send_a_notification
530 ActionMailer::Base.deliveries.clear 668 ActionMailer::Base.deliveries.clear
531 @request.session[:user_id] = 2 669 @request.session[:user_id] = 2
532 assert_difference 'Issue.count' do 670 assert_difference 'Issue.count' do
533 post :create, :project_id => 1, 671 post :create, :project_id => 1,
534 :issue => {:tracker_id => 3, 672 :issue => {:tracker_id => 3,
535 :subject => 'This is the test_new issue', 673 :subject => 'This is the test_new issue',
536 :description => 'This is the description', 674 :description => 'This is the description',
537 :priority_id => 5, 675 :priority_id => 5,
538 :estimated_hours => '', 676 :estimated_hours => '',
539 :custom_field_values => {'2' => 'Value for field 2'}} 677 :custom_field_values => {'2' => 'Value for field 2'}}
540 end 678 end
541 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id 679 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
542 680
543 assert_equal 1, ActionMailer::Base.deliveries.size 681 assert_equal 1, ActionMailer::Base.deliveries.size
544 end 682 end
545 683
546 def test_post_create_should_preserve_fields_values_on_validation_failure 684 def test_post_create_should_preserve_fields_values_on_validation_failure
547 @request.session[:user_id] = 2 685 @request.session[:user_id] = 2
548 post :create, :project_id => 1, 686 post :create, :project_id => 1,
549 :issue => {:tracker_id => 1, 687 :issue => {:tracker_id => 1,
550 # empty subject 688 # empty subject
551 :subject => '', 689 :subject => '',
552 :description => 'This is a description', 690 :description => 'This is a description',
553 :priority_id => 6, 691 :priority_id => 6,
554 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}} 692 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
555 assert_response :success 693 assert_response :success
556 assert_template 'new' 694 assert_template 'new'
557 695
558 assert_tag :textarea, :attributes => { :name => 'issue[description]' }, 696 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
559 :content => 'This is a description' 697 :content => 'This is a description'
560 assert_tag :select, :attributes => { :name => 'issue[priority_id]' }, 698 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
561 :child => { :tag => 'option', :attributes => { :selected => 'selected', 699 :child => { :tag => 'option', :attributes => { :selected => 'selected',
562 :value => '6' }, 700 :value => '6' },
563 :content => 'High' } 701 :content => 'High' }
564 # Custom fields 702 # Custom fields
565 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' }, 703 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
566 :child => { :tag => 'option', :attributes => { :selected => 'selected', 704 :child => { :tag => 'option', :attributes => { :selected => 'selected',
567 :value => 'Oracle' }, 705 :value => 'Oracle' },
568 :content => 'Oracle' } 706 :content => 'Oracle' }
569 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]', 707 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
570 :value => 'Value for field 2'} 708 :value => 'Value for field 2'}
571 end 709 end
572 710
573 def test_post_create_should_ignore_non_safe_attributes 711 def test_post_create_should_ignore_non_safe_attributes
574 @request.session[:user_id] = 2 712 @request.session[:user_id] = 2
575 assert_nothing_raised do 713 assert_nothing_raised do
576 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" } 714 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
577 end 715 end
578 end 716 end
579 717
580 context "without workflow privilege" do 718 context "without workflow privilege" do
581 setup do 719 setup do
582 Workflow.delete_all(["role_id = ?", Role.anonymous.id]) 720 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
583 Role.anonymous.add_permission! :add_issues, :add_issue_notes 721 Role.anonymous.add_permission! :add_issues, :add_issue_notes
584 end 722 end
585 723
586 context "#new" do 724 context "#new" do
587 should "propose default status only" do 725 should "propose default status only" do
588 get :new, :project_id => 1 726 get :new, :project_id => 1
589 assert_response :success 727 assert_response :success
590 assert_template 'new' 728 assert_template 'new'
591 assert_tag :tag => 'select', 729 assert_tag :tag => 'select',
592 :attributes => {:name => 'issue[status_id]'}, 730 :attributes => {:name => 'issue[status_id]'},
593 :children => {:count => 1}, 731 :children => {:count => 1},
594 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}} 732 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
595 end 733 end
596 734
597 should "accept default status" do 735 should "accept default status" do
598 assert_difference 'Issue.count' do 736 assert_difference 'Issue.count' do
599 post :create, :project_id => 1, 737 post :create, :project_id => 1,
600 :issue => {:tracker_id => 1, 738 :issue => {:tracker_id => 1,
601 :subject => 'This is an issue', 739 :subject => 'This is an issue',
602 :status_id => 1} 740 :status_id => 1}
603 end 741 end
604 issue = Issue.last(:order => 'id') 742 issue = Issue.last(:order => 'id')
605 assert_equal IssueStatus.default, issue.status 743 assert_equal IssueStatus.default, issue.status
606 end 744 end
607 745
608 should "accept default status" do
609 assert_difference 'Issue.count' do
610 post :create, :project_id => 1,
611 :issue => {:tracker_id => 1,
612 :subject => 'This is an issue',
613 :status_id => 1}
614 end
615 issue = Issue.last(:order => 'id')
616 assert_equal IssueStatus.default, issue.status
617 end
618
619 should "ignore unauthorized status" do 746 should "ignore unauthorized status" do
620 assert_difference 'Issue.count' do 747 assert_difference 'Issue.count' do
621 post :create, :project_id => 1, 748 post :create, :project_id => 1,
622 :issue => {:tracker_id => 1, 749 :issue => {:tracker_id => 1,
623 :subject => 'This is an issue', 750 :subject => 'This is an issue',
624 :status_id => 3} 751 :status_id => 3}
625 end 752 end
626 issue = Issue.last(:order => 'id') 753 issue = Issue.last(:order => 'id')
627 assert_equal IssueStatus.default, issue.status 754 assert_equal IssueStatus.default, issue.status
628 end 755 end
629 end 756 end
630 757
631 context "#update" do 758 context "#update" do
632 should "ignore status change" do 759 should "ignore status change" do
633 assert_difference 'Journal.count' do 760 assert_difference 'Journal.count' do
634 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3} 761 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
635 end 762 end
636 assert_equal 1, Issue.find(1).status_id 763 assert_equal 1, Issue.find(1).status_id
637 end 764 end
638 765
639 should "ignore attributes changes" do 766 should "ignore attributes changes" do
640 assert_difference 'Journal.count' do 767 assert_difference 'Journal.count' do
641 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2} 768 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
642 end 769 end
643 issue = Issue.find(1) 770 issue = Issue.find(1)
644 assert_equal "Can't print recipes", issue.subject 771 assert_equal "Can't print recipes", issue.subject
645 assert_nil issue.assigned_to 772 assert_nil issue.assigned_to
646 end 773 end
647 end 774 end
648 end 775 end
649 776
650 context "with workflow privilege" do 777 context "with workflow privilege" do
651 setup do 778 setup do
652 Workflow.delete_all(["role_id = ?", Role.anonymous.id]) 779 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
653 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3) 780 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
654 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4) 781 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
655 Role.anonymous.add_permission! :add_issues, :add_issue_notes 782 Role.anonymous.add_permission! :add_issues, :add_issue_notes
656 end 783 end
657 784
658 context "#update" do 785 context "#update" do
659 should "accept authorized status" do 786 should "accept authorized status" do
660 assert_difference 'Journal.count' do 787 assert_difference 'Journal.count' do
661 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3} 788 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
662 end 789 end
663 assert_equal 3, Issue.find(1).status_id 790 assert_equal 3, Issue.find(1).status_id
664 end 791 end
665 792
666 should "ignore unauthorized status" do 793 should "ignore unauthorized status" do
667 assert_difference 'Journal.count' do 794 assert_difference 'Journal.count' do
668 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2} 795 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
669 end 796 end
670 assert_equal 1, Issue.find(1).status_id 797 assert_equal 1, Issue.find(1).status_id
671 end 798 end
672 799
673 should "accept authorized attributes changes" do 800 should "accept authorized attributes changes" do
674 assert_difference 'Journal.count' do 801 assert_difference 'Journal.count' do
675 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2} 802 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
676 end 803 end
677 issue = Issue.find(1) 804 issue = Issue.find(1)
678 assert_equal 2, issue.assigned_to_id 805 assert_equal 2, issue.assigned_to_id
679 end 806 end
680 807
681 should "ignore unauthorized attributes changes" do 808 should "ignore unauthorized attributes changes" do
682 assert_difference 'Journal.count' do 809 assert_difference 'Journal.count' do
683 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'} 810 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
684 end 811 end
685 issue = Issue.find(1) 812 issue = Issue.find(1)
686 assert_equal "Can't print recipes", issue.subject 813 assert_equal "Can't print recipes", issue.subject
687 end 814 end
688 end 815 end
689 816
690 context "and :edit_issues permission" do 817 context "and :edit_issues permission" do
691 setup do 818 setup do
692 Role.anonymous.add_permission! :add_issues, :edit_issues 819 Role.anonymous.add_permission! :add_issues, :edit_issues
693 end 820 end
694 821
696 assert_difference 'Journal.count' do 823 assert_difference 'Journal.count' do
697 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3} 824 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
698 end 825 end
699 assert_equal 3, Issue.find(1).status_id 826 assert_equal 3, Issue.find(1).status_id
700 end 827 end
701 828
702 should "ignore unauthorized status" do 829 should "ignore unauthorized status" do
703 assert_difference 'Journal.count' do 830 assert_difference 'Journal.count' do
704 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2} 831 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
705 end 832 end
706 assert_equal 1, Issue.find(1).status_id 833 assert_equal 1, Issue.find(1).status_id
707 end 834 end
708 835
709 should "accept authorized attributes changes" do 836 should "accept authorized attributes changes" do
710 assert_difference 'Journal.count' do 837 assert_difference 'Journal.count' do
711 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2} 838 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
712 end 839 end
713 issue = Issue.find(1) 840 issue = Issue.find(1)
714 assert_equal "changed", issue.subject 841 assert_equal "changed", issue.subject
715 assert_equal 2, issue.assigned_to_id 842 assert_equal 2, issue.assigned_to_id
716 end 843 end
717 end 844 end
718 end 845 end
719 846
720 def test_copy_issue 847 def test_copy_issue
721 @request.session[:user_id] = 2 848 @request.session[:user_id] = 2
722 get :new, :project_id => 1, :copy_from => 1 849 get :new, :project_id => 1, :copy_from => 1
723 assert_template 'new' 850 assert_template 'new'
724 assert_not_nil assigns(:issue) 851 assert_not_nil assigns(:issue)
725 orig = Issue.find(1) 852 orig = Issue.find(1)
726 assert_equal orig.subject, assigns(:issue).subject 853 assert_equal orig.subject, assigns(:issue).subject
727 end 854 end
728 855
729 def test_get_edit 856 def test_get_edit
730 @request.session[:user_id] = 2 857 @request.session[:user_id] = 2
731 get :edit, :id => 1 858 get :edit, :id => 1
732 assert_response :success 859 assert_response :success
733 assert_template 'edit' 860 assert_template 'edit'
734 assert_not_nil assigns(:issue) 861 assert_not_nil assigns(:issue)
735 assert_equal Issue.find(1), assigns(:issue) 862 assert_equal Issue.find(1), assigns(:issue)
736 end 863 end
737 864
738 def test_get_edit_with_params 865 def test_get_edit_with_params
739 @request.session[:user_id] = 2 866 @request.session[:user_id] = 2
740 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }, 867 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
741 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id } 868 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
742 assert_response :success 869 assert_response :success
743 assert_template 'edit' 870 assert_template 'edit'
744 871
745 issue = assigns(:issue) 872 issue = assigns(:issue)
746 assert_not_nil issue 873 assert_not_nil issue
747 874
748 assert_equal 5, issue.status_id 875 assert_equal 5, issue.status_id
749 assert_tag :select, :attributes => { :name => 'issue[status_id]' }, 876 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
750 :child => { :tag => 'option', 877 :child => { :tag => 'option',
751 :content => 'Closed', 878 :content => 'Closed',
752 :attributes => { :selected => 'selected' } } 879 :attributes => { :selected => 'selected' } }
753 880
754 assert_equal 7, issue.priority_id 881 assert_equal 7, issue.priority_id
755 assert_tag :select, :attributes => { :name => 'issue[priority_id]' }, 882 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
756 :child => { :tag => 'option', 883 :child => { :tag => 'option',
757 :content => 'Urgent', 884 :content => 'Urgent',
758 :attributes => { :selected => 'selected' } } 885 :attributes => { :selected => 'selected' } }
759 886
760 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' } 887 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
761 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' }, 888 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
766 893
767 def test_update_edit_form 894 def test_update_edit_form
768 @request.session[:user_id] = 2 895 @request.session[:user_id] = 2
769 xhr :post, :new, :project_id => 1, 896 xhr :post, :new, :project_id => 1,
770 :id => 1, 897 :id => 1,
771 :issue => {:tracker_id => 2, 898 :issue => {:tracker_id => 2,
772 :subject => 'This is the test_new issue', 899 :subject => 'This is the test_new issue',
773 :description => 'This is the description', 900 :description => 'This is the description',
774 :priority_id => 5} 901 :priority_id => 5}
775 assert_response :success 902 assert_response :success
776 assert_template 'attributes' 903 assert_template 'attributes'
777 904
778 issue = assigns(:issue) 905 issue = assigns(:issue)
779 assert_kind_of Issue, issue 906 assert_kind_of Issue, issue
780 assert_equal 1, issue.id 907 assert_equal 1, issue.id
781 assert_equal 1, issue.project_id 908 assert_equal 1, issue.project_id
782 assert_equal 2, issue.tracker_id 909 assert_equal 2, issue.tracker_id
783 assert_equal 'This is the test_new issue', issue.subject 910 assert_equal 'This is the test_new issue', issue.subject
784 end 911 end
785 912
786 def test_update_using_invalid_http_verbs 913 def test_update_using_invalid_http_verbs
787 @request.session[:user_id] = 2 914 @request.session[:user_id] = 2
788 subject = 'Updated by an invalid http verb' 915 subject = 'Updated by an invalid http verb'
789 916
790 get :update, :id => 1, :issue => {:subject => subject} 917 get :update, :id => 1, :issue => {:subject => subject}
798 end 925 end
799 926
800 def test_put_update_without_custom_fields_param 927 def test_put_update_without_custom_fields_param
801 @request.session[:user_id] = 2 928 @request.session[:user_id] = 2
802 ActionMailer::Base.deliveries.clear 929 ActionMailer::Base.deliveries.clear
803 930
804 issue = Issue.find(1) 931 issue = Issue.find(1)
805 assert_equal '125', issue.custom_value_for(2).value 932 assert_equal '125', issue.custom_value_for(2).value
806 old_subject = issue.subject 933 old_subject = issue.subject
807 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit' 934 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
808 935
809 assert_difference('Journal.count') do 936 assert_difference('Journal.count') do
810 assert_difference('JournalDetail.count', 2) do 937 assert_difference('JournalDetail.count', 2) do
811 put :update, :id => 1, :issue => {:subject => new_subject, 938 put :update, :id => 1, :issue => {:subject => new_subject,
812 :priority_id => '6', 939 :priority_id => '6',
813 :category_id => '1' # no change 940 :category_id => '1' # no change
817 assert_redirected_to :action => 'show', :id => '1' 944 assert_redirected_to :action => 'show', :id => '1'
818 issue.reload 945 issue.reload
819 assert_equal new_subject, issue.subject 946 assert_equal new_subject, issue.subject
820 # Make sure custom fields were not cleared 947 # Make sure custom fields were not cleared
821 assert_equal '125', issue.custom_value_for(2).value 948 assert_equal '125', issue.custom_value_for(2).value
822 949
823 mail = ActionMailer::Base.deliveries.last 950 mail = ActionMailer::Base.deliveries.last
824 assert_kind_of TMail::Mail, mail 951 assert_kind_of TMail::Mail, mail
825 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]") 952 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
826 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}") 953 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
827 end 954 end
828 955
829 def test_put_update_with_custom_field_change 956 def test_put_update_with_custom_field_change
830 @request.session[:user_id] = 2 957 @request.session[:user_id] = 2
831 issue = Issue.find(1) 958 issue = Issue.find(1)
832 assert_equal '125', issue.custom_value_for(2).value 959 assert_equal '125', issue.custom_value_for(2).value
833 960
834 assert_difference('Journal.count') do 961 assert_difference('Journal.count') do
835 assert_difference('JournalDetail.count', 3) do 962 assert_difference('JournalDetail.count', 3) do
836 put :update, :id => 1, :issue => {:subject => 'Custom field change', 963 put :update, :id => 1, :issue => {:subject => 'Custom field change',
837 :priority_id => '6', 964 :priority_id => '6',
838 :category_id => '1', # no change 965 :category_id => '1', # no change
841 end 968 end
842 end 969 end
843 assert_redirected_to :action => 'show', :id => '1' 970 assert_redirected_to :action => 'show', :id => '1'
844 issue.reload 971 issue.reload
845 assert_equal 'New custom value', issue.custom_value_for(2).value 972 assert_equal 'New custom value', issue.custom_value_for(2).value
846 973
847 mail = ActionMailer::Base.deliveries.last 974 mail = ActionMailer::Base.deliveries.last
848 assert_kind_of TMail::Mail, mail 975 assert_kind_of TMail::Mail, mail
849 assert mail.body.include?("Searchable field changed from 125 to New custom value") 976 assert mail.body.include?("Searchable field changed from 125 to New custom value")
850 end 977 end
851 978
852 def test_put_update_with_status_and_assignee_change 979 def test_put_update_with_status_and_assignee_change
853 issue = Issue.find(1) 980 issue = Issue.find(1)
854 assert_equal 1, issue.status_id 981 assert_equal 1, issue.status_id
855 @request.session[:user_id] = 2 982 @request.session[:user_id] = 2
856 assert_difference('TimeEntry.count', 0) do 983 assert_difference('TimeEntry.count', 0) do
864 issue.reload 991 issue.reload
865 assert_equal 2, issue.status_id 992 assert_equal 2, issue.status_id
866 j = Journal.find(:first, :order => 'id DESC') 993 j = Journal.find(:first, :order => 'id DESC')
867 assert_equal 'Assigned to dlopper', j.notes 994 assert_equal 'Assigned to dlopper', j.notes
868 assert_equal 2, j.details.size 995 assert_equal 2, j.details.size
869 996
870 mail = ActionMailer::Base.deliveries.last 997 mail = ActionMailer::Base.deliveries.last
871 assert mail.body.include?("Status changed from New to Assigned") 998 assert mail.body.include?("Status changed from New to Assigned")
872 # subject should contain the new status 999 # subject should contain the new status
873 assert mail.subject.include?("(#{ IssueStatus.find(2).name })") 1000 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
874 end 1001 end
875 1002
876 def test_put_update_with_note_only 1003 def test_put_update_with_note_only
877 notes = 'Note added by IssuesControllerTest#test_update_with_note_only' 1004 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
878 # anonymous user 1005 # anonymous user
879 put :update, 1006 put :update,
880 :id => 1, 1007 :id => 1,
882 assert_redirected_to :action => 'show', :id => '1' 1009 assert_redirected_to :action => 'show', :id => '1'
883 j = Journal.find(:first, :order => 'id DESC') 1010 j = Journal.find(:first, :order => 'id DESC')
884 assert_equal notes, j.notes 1011 assert_equal notes, j.notes
885 assert_equal 0, j.details.size 1012 assert_equal 0, j.details.size
886 assert_equal User.anonymous, j.user 1013 assert_equal User.anonymous, j.user
887 1014
888 mail = ActionMailer::Base.deliveries.last 1015 mail = ActionMailer::Base.deliveries.last
889 assert mail.body.include?(notes) 1016 assert mail.body.include?(notes)
890 end 1017 end
891 1018
892 def test_put_update_with_note_and_spent_time 1019 def test_put_update_with_note_and_spent_time
893 @request.session[:user_id] = 2 1020 @request.session[:user_id] = 2
894 spent_hours_before = Issue.find(1).spent_hours 1021 spent_hours_before = Issue.find(1).spent_hours
895 assert_difference('TimeEntry.count') do 1022 assert_difference('TimeEntry.count') do
896 put :update, 1023 put :update,
897 :id => 1, 1024 :id => 1,
898 :notes => '2.5 hours added', 1025 :notes => '2.5 hours added',
899 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id } 1026 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
900 end 1027 end
901 assert_redirected_to :action => 'show', :id => '1' 1028 assert_redirected_to :action => 'show', :id => '1'
902 1029
903 issue = Issue.find(1) 1030 issue = Issue.find(1)
904 1031
905 j = Journal.find(:first, :order => 'id DESC') 1032 j = Journal.find(:first, :order => 'id DESC')
906 assert_equal '2.5 hours added', j.notes 1033 assert_equal '2.5 hours added', j.notes
907 assert_equal 0, j.details.size 1034 assert_equal 0, j.details.size
908 1035
909 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time') 1036 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
910 assert_not_nil t 1037 assert_not_nil t
911 assert_equal 2.5, t.hours 1038 assert_equal 2.5, t.hours
912 assert_equal spent_hours_before + 2.5, issue.spent_hours 1039 assert_equal spent_hours_before + 2.5, issue.spent_hours
913 end 1040 end
914 1041
915 def test_put_update_with_attachment_only 1042 def test_put_update_with_attachment_only
916 set_tmp_attachments_directory 1043 set_tmp_attachments_directory
917 1044
918 # Delete all fixtured journals, a race condition can occur causing the wrong 1045 # Delete all fixtured journals, a race condition can occur causing the wrong
919 # journal to get fetched in the next find. 1046 # journal to get fetched in the next find.
920 Journal.delete_all 1047 Journal.delete_all
921 1048
922 # anonymous user 1049 # anonymous user
928 j = Issue.find(1).journals.find(:first, :order => 'id DESC') 1055 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
929 assert j.notes.blank? 1056 assert j.notes.blank?
930 assert_equal 1, j.details.size 1057 assert_equal 1, j.details.size
931 assert_equal 'testfile.txt', j.details.first.value 1058 assert_equal 'testfile.txt', j.details.first.value
932 assert_equal User.anonymous, j.user 1059 assert_equal User.anonymous, j.user
933 1060
934 mail = ActionMailer::Base.deliveries.last 1061 mail = ActionMailer::Base.deliveries.last
935 assert mail.body.include?('testfile.txt') 1062 assert mail.body.include?('testfile.txt')
936 end 1063 end
937 1064
938 def test_put_update_with_attachment_that_fails_to_save 1065 def test_put_update_with_attachment_that_fails_to_save
939 set_tmp_attachments_directory 1066 set_tmp_attachments_directory
940 1067
941 # Delete all fixtured journals, a race condition can occur causing the wrong 1068 # Delete all fixtured journals, a race condition can occur causing the wrong
942 # journal to get fetched in the next find. 1069 # journal to get fetched in the next find.
943 Journal.delete_all 1070 Journal.delete_all
944 1071
945 # Mock out the unsaved attachment 1072 # Mock out the unsaved attachment
946 Attachment.any_instance.stubs(:create).returns(Attachment.new) 1073 Attachment.any_instance.stubs(:create).returns(Attachment.new)
947 1074
948 # anonymous user 1075 # anonymous user
949 put :update, 1076 put :update,
950 :id => 1, 1077 :id => 1,
951 :notes => '', 1078 :notes => '',
952 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}} 1079 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
957 1084
958 def test_put_update_with_no_change 1085 def test_put_update_with_no_change
959 issue = Issue.find(1) 1086 issue = Issue.find(1)
960 issue.journals.clear 1087 issue.journals.clear
961 ActionMailer::Base.deliveries.clear 1088 ActionMailer::Base.deliveries.clear
962 1089
963 put :update, 1090 put :update,
964 :id => 1, 1091 :id => 1,
965 :notes => '' 1092 :notes => ''
966 assert_redirected_to :action => 'show', :id => '1' 1093 assert_redirected_to :action => 'show', :id => '1'
967 1094
968 issue.reload 1095 issue.reload
969 assert issue.journals.empty? 1096 assert issue.journals.empty?
970 # No email should be sent 1097 # No email should be sent
971 assert ActionMailer::Base.deliveries.empty? 1098 assert ActionMailer::Base.deliveries.empty?
972 end 1099 end
975 @request.session[:user_id] = 2 1102 @request.session[:user_id] = 2
976 ActionMailer::Base.deliveries.clear 1103 ActionMailer::Base.deliveries.clear
977 issue = Issue.find(1) 1104 issue = Issue.find(1)
978 old_subject = issue.subject 1105 old_subject = issue.subject
979 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit' 1106 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
980 1107
981 put :update, :id => 1, :issue => {:subject => new_subject, 1108 put :update, :id => 1, :issue => {:subject => new_subject,
982 :priority_id => '6', 1109 :priority_id => '6',
983 :category_id => '1' # no change 1110 :category_id => '1' # no change
984 } 1111 }
985 assert_equal 1, ActionMailer::Base.deliveries.size 1112 assert_equal 1, ActionMailer::Base.deliveries.size
986 end 1113 end
987 1114
988 def test_put_update_with_invalid_spent_time 1115 def test_put_update_with_invalid_spent_time_hours_only
989 @request.session[:user_id] = 2 1116 @request.session[:user_id] = 2
990 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time' 1117 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
991 1118
992 assert_no_difference('Journal.count') do 1119 assert_no_difference('Journal.count') do
993 put :update, 1120 put :update,
994 :id => 1, 1121 :id => 1,
995 :notes => notes, 1122 :notes => notes,
996 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"} 1123 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
997 end 1124 end
998 assert_response :success 1125 assert_response :success
999 assert_template 'edit' 1126 assert_template 'edit'
1000 1127
1001 assert_tag :textarea, :attributes => { :name => 'notes' }, 1128 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1002 :content => notes 1129 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1003 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" } 1130 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
1004 end 1131 end
1005 1132
1133 def test_put_update_with_invalid_spent_time_comments_only
1134 @request.session[:user_id] = 2
1135 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1136
1137 assert_no_difference('Journal.count') do
1138 put :update,
1139 :id => 1,
1140 :notes => notes,
1141 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
1142 end
1143 assert_response :success
1144 assert_template 'edit'
1145
1146 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1147 assert_error_tag :descendant => {:content => /Hours can't be blank/}
1148 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1149 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
1150 end
1151
1006 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject 1152 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
1007 issue = Issue.find(2) 1153 issue = Issue.find(2)
1008 @request.session[:user_id] = 2 1154 @request.session[:user_id] = 2
1009 1155
1010 put :update, 1156 put :update,
1031 :back_url => '/issues' 1177 :back_url => '/issues'
1032 1178
1033 assert_response :redirect 1179 assert_response :redirect
1034 assert_redirected_to '/issues' 1180 assert_redirected_to '/issues'
1035 end 1181 end
1036 1182
1037 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host 1183 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1038 issue = Issue.find(2) 1184 issue = Issue.find(2)
1039 @request.session[:user_id] = 2 1185 @request.session[:user_id] = 2
1040 1186
1041 put :update, 1187 put :update,
1046 :back_url => 'http://google.com' 1192 :back_url => 'http://google.com'
1047 1193
1048 assert_response :redirect 1194 assert_response :redirect
1049 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id 1195 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
1050 end 1196 end
1051 1197
1052 def test_get_bulk_edit 1198 def test_get_bulk_edit
1053 @request.session[:user_id] = 2 1199 @request.session[:user_id] = 2
1054 get :bulk_edit, :ids => [1, 2] 1200 get :bulk_edit, :ids => [1, 2]
1055 assert_response :success 1201 assert_response :success
1056 assert_template 'bulk_edit' 1202 assert_template 'bulk_edit'
1057 1203
1204 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1205
1058 # Project specific custom field, date type 1206 # Project specific custom field, date type
1059 field = CustomField.find(9) 1207 field = CustomField.find(9)
1060 assert !field.is_for_all? 1208 assert !field.is_for_all?
1061 assert_equal 'date', field.field_format 1209 assert_equal 'date', field.field_format
1062 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'} 1210 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1063 1211
1064 # System wide custom field 1212 # System wide custom field
1065 assert CustomField.find(1).is_for_all? 1213 assert CustomField.find(1).is_for_all?
1066 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'} 1214 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
1067 end 1215 end
1068 1216
1069 def test_get_bulk_edit_on_different_projects 1217 def test_get_bulk_edit_on_different_projects
1070 @request.session[:user_id] = 2 1218 @request.session[:user_id] = 2
1071 get :bulk_edit, :ids => [1, 2, 6] 1219 get :bulk_edit, :ids => [1, 2, 6]
1072 assert_response :success 1220 assert_response :success
1073 assert_template 'bulk_edit' 1221 assert_template 'bulk_edit'
1074 1222
1223 # Can not set issues from different projects as children of an issue
1224 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1225
1075 # Project specific custom field, date type 1226 # Project specific custom field, date type
1076 field = CustomField.find(9) 1227 field = CustomField.find(9)
1077 assert !field.is_for_all? 1228 assert !field.is_for_all?
1078 assert !field.project_ids.include?(Issue.find(6).project_id) 1229 assert !field.project_ids.include?(Issue.find(6).project_id)
1079 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'} 1230 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1080 end 1231 end
1081 1232
1233 def test_get_bulk_edit_with_user_custom_field
1234 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
1235
1236 @request.session[:user_id] = 2
1237 get :bulk_edit, :ids => [1, 2]
1238 assert_response :success
1239 assert_template 'bulk_edit'
1240
1241 assert_tag :select,
1242 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1243 :children => {
1244 :only => {:tag => 'option'},
1245 :count => Project.find(1).users.count + 1
1246 }
1247 end
1248
1249 def test_get_bulk_edit_with_version_custom_field
1250 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
1251
1252 @request.session[:user_id] = 2
1253 get :bulk_edit, :ids => [1, 2]
1254 assert_response :success
1255 assert_template 'bulk_edit'
1256
1257 assert_tag :select,
1258 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1259 :children => {
1260 :only => {:tag => 'option'},
1261 :count => Project.find(1).versions.count + 1
1262 }
1263 end
1264
1082 def test_bulk_update 1265 def test_bulk_update
1083 @request.session[:user_id] = 2 1266 @request.session[:user_id] = 2
1084 # update issues priority 1267 # update issues priority
1085 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing', 1268 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1086 :issue => {:priority_id => 7, 1269 :issue => {:priority_id => 7,
1087 :assigned_to_id => '', 1270 :assigned_to_id => '',
1088 :custom_field_values => {'2' => ''}} 1271 :custom_field_values => {'2' => ''}}
1089 1272
1090 assert_response 302 1273 assert_response 302
1091 # check that the issues were updated 1274 # check that the issues were updated
1092 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id} 1275 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
1093 1276
1094 issue = Issue.find(1) 1277 issue = Issue.find(1)
1095 journal = issue.journals.find(:first, :order => 'created_on DESC') 1278 journal = issue.journals.find(:first, :order => 'created_on DESC')
1096 assert_equal '125', issue.custom_value_for(2).value 1279 assert_equal '125', issue.custom_value_for(2).value
1097 assert_equal 'Bulk editing', journal.notes 1280 assert_equal 'Bulk editing', journal.notes
1098 assert_equal 1, journal.details.size 1281 assert_equal 1, journal.details.size
1103 # update issues priority 1286 # update issues priority
1104 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing', 1287 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
1105 :issue => {:priority_id => 7, 1288 :issue => {:priority_id => 7,
1106 :assigned_to_id => '', 1289 :assigned_to_id => '',
1107 :custom_field_values => {'2' => ''}} 1290 :custom_field_values => {'2' => ''}}
1108 1291
1109 assert_response 302 1292 assert_response 302
1110 # check that the issues were updated 1293 # check that the issues were updated
1111 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id) 1294 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
1112 1295
1113 issue = Issue.find(1) 1296 issue = Issue.find(1)
1114 journal = issue.journals.find(:first, :order => 'created_on DESC') 1297 journal = issue.journals.find(:first, :order => 'created_on DESC')
1115 assert_equal '125', issue.custom_value_for(2).value 1298 assert_equal '125', issue.custom_value_for(2).value
1116 assert_equal 'Bulk editing', journal.notes 1299 assert_equal 'Bulk editing', journal.notes
1117 assert_equal 1, journal.details.size 1300 assert_equal 1, journal.details.size
1128 :assigned_to_id => '', 1311 :assigned_to_id => '',
1129 :custom_field_values => {'2' => ''}} 1312 :custom_field_values => {'2' => ''}}
1130 assert_response 403 1313 assert_response 403
1131 assert_not_equal "Bulk should fail", Journal.last.notes 1314 assert_not_equal "Bulk should fail", Journal.last.notes
1132 end 1315 end
1133 1316
1134 def test_bullk_update_should_send_a_notification 1317 def test_bullk_update_should_send_a_notification
1135 @request.session[:user_id] = 2 1318 @request.session[:user_id] = 2
1136 ActionMailer::Base.deliveries.clear 1319 ActionMailer::Base.deliveries.clear
1137 post(:bulk_update, 1320 post(:bulk_update,
1138 { 1321 {
1154 # update issues priority 1337 # update issues priority
1155 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status', 1338 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
1156 :issue => {:priority_id => '', 1339 :issue => {:priority_id => '',
1157 :assigned_to_id => '', 1340 :assigned_to_id => '',
1158 :status_id => '5'} 1341 :status_id => '5'}
1159 1342
1160 assert_response 302 1343 assert_response 302
1161 issue = Issue.find(1) 1344 issue = Issue.find(1)
1162 assert issue.closed? 1345 assert issue.closed?
1346 end
1347
1348 def test_bulk_update_parent_id
1349 @request.session[:user_id] = 2
1350 post :bulk_update, :ids => [1, 3],
1351 :notes => 'Bulk editing parent',
1352 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
1353
1354 assert_response 302
1355 parent = Issue.find(2)
1356 assert_equal parent.id, Issue.find(1).parent_id
1357 assert_equal parent.id, Issue.find(3).parent_id
1358 assert_equal [1, 3], parent.children.collect(&:id).sort
1163 end 1359 end
1164 1360
1165 def test_bulk_update_custom_field 1361 def test_bulk_update_custom_field
1166 @request.session[:user_id] = 2 1362 @request.session[:user_id] = 2
1167 # update issues priority 1363 # update issues priority
1168 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field', 1364 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
1169 :issue => {:priority_id => '', 1365 :issue => {:priority_id => '',
1170 :assigned_to_id => '', 1366 :assigned_to_id => '',
1171 :custom_field_values => {'2' => '777'}} 1367 :custom_field_values => {'2' => '777'}}
1172 1368
1173 assert_response 302 1369 assert_response 302
1174 1370
1175 issue = Issue.find(1) 1371 issue = Issue.find(1)
1176 journal = issue.journals.find(:first, :order => 'created_on DESC') 1372 journal = issue.journals.find(:first, :order => 'created_on DESC')
1177 assert_equal '777', issue.custom_value_for(2).value 1373 assert_equal '777', issue.custom_value_for(2).value
1178 assert_equal 1, journal.details.size 1374 assert_equal 1, journal.details.size
1179 assert_equal '125', journal.details.first.old_value 1375 assert_equal '125', journal.details.first.old_value
1187 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'} 1383 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1188 assert_response 302 1384 assert_response 302
1189 # check that the issues were updated 1385 # check that the issues were updated
1190 assert_nil Issue.find(2).assigned_to 1386 assert_nil Issue.find(2).assigned_to
1191 end 1387 end
1192 1388
1193 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject 1389 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
1194 @request.session[:user_id] = 2 1390 @request.session[:user_id] = 2
1195 1391
1196 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4} 1392 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
1197 1393
1216 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com' 1412 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
1217 1413
1218 assert_response :redirect 1414 assert_response :redirect
1219 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier 1415 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1220 end 1416 end
1221 1417
1222 def test_destroy_issue_with_no_time_entries 1418 def test_destroy_issue_with_no_time_entries
1223 assert_nil TimeEntry.find_by_issue_id(2) 1419 assert_nil TimeEntry.find_by_issue_id(2)
1224 @request.session[:user_id] = 2 1420 @request.session[:user_id] = 2
1225 post :destroy, :id => 2 1421 post :destroy, :id => 2
1226 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 1422 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1250 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 1446 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1251 assert !(Issue.find_by_id(1) || Issue.find_by_id(3)) 1447 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1252 assert_nil TimeEntry.find(1).issue_id 1448 assert_nil TimeEntry.find(1).issue_id
1253 assert_nil TimeEntry.find(2).issue_id 1449 assert_nil TimeEntry.find(2).issue_id
1254 end 1450 end
1255 1451
1256 def test_destroy_issues_and_reassign_time_entries_to_another_issue 1452 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1257 @request.session[:user_id] = 2 1453 @request.session[:user_id] = 2
1258 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2 1454 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1259 assert_redirected_to :action => 'index', :project_id => 'ecookbook' 1455 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1260 assert !(Issue.find_by_id(1) || Issue.find_by_id(3)) 1456 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1261 assert_equal 2, TimeEntry.find(1).issue_id 1457 assert_equal 2, TimeEntry.find(1).issue_id
1262 assert_equal 2, TimeEntry.find(2).issue_id 1458 assert_equal 2, TimeEntry.find(2).issue_id
1263 end 1459 end
1264 1460
1265 def test_destroy_issues_from_different_projects 1461 def test_destroy_issues_from_different_projects
1266 @request.session[:user_id] = 2 1462 @request.session[:user_id] = 2
1267 post :destroy, :ids => [1, 2, 6], :todo => 'destroy' 1463 post :destroy, :ids => [1, 2, 6], :todo => 'destroy'
1268 assert_redirected_to :controller => 'issues', :action => 'index' 1464 assert_redirected_to :controller => 'issues', :action => 'index'
1269 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6)) 1465 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
1270 end 1466 end
1271 1467
1468 def test_destroy_parent_and_child_issues
1469 parent = Issue.generate!(:project_id => 1, :tracker_id => 1)
1470 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id)
1471 assert child.is_descendant_of?(parent.reload)
1472
1473 @request.session[:user_id] = 2
1474 assert_difference 'Issue.count', -2 do
1475 post :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
1476 end
1477 assert_response 302
1478 end
1479
1272 def test_default_search_scope 1480 def test_default_search_scope
1273 get :index 1481 get :index
1274 assert_tag :div, :attributes => {:id => 'quick-search'}, 1482 assert_tag :div, :attributes => {:id => 'quick-search'},
1275 :child => {:tag => 'form', 1483 :child => {:tag => 'form',
1276 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}} 1484 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}