##// END OF EJS Templates
Use assert_select to check the download link. (#4204)...
Eric Davis -
r3444:ddaa95523ab9
parent child
Show More
@@ -1,1267 +1,1267
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2008 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.dirname(__FILE__) + '/../test_helper'
19 require 'issues_controller'
19 require 'issues_controller'
20
20
21 # Re-raise errors caught by the controller.
21 # Re-raise errors caught by the controller.
22 class IssuesController; def rescue_action(e) raise e end; end
22 class IssuesController; def rescue_action(e) raise e end; end
23
23
24 class IssuesControllerTest < ActionController::TestCase
24 class IssuesControllerTest < ActionController::TestCase
25 fixtures :projects,
25 fixtures :projects,
26 :users,
26 :users,
27 :roles,
27 :roles,
28 :members,
28 :members,
29 :member_roles,
29 :member_roles,
30 :issues,
30 :issues,
31 :issue_statuses,
31 :issue_statuses,
32 :versions,
32 :versions,
33 :trackers,
33 :trackers,
34 :projects_trackers,
34 :projects_trackers,
35 :issue_categories,
35 :issue_categories,
36 :enabled_modules,
36 :enabled_modules,
37 :enumerations,
37 :enumerations,
38 :attachments,
38 :attachments,
39 :workflows,
39 :workflows,
40 :custom_fields,
40 :custom_fields,
41 :custom_values,
41 :custom_values,
42 :custom_fields_projects,
42 :custom_fields_projects,
43 :custom_fields_trackers,
43 :custom_fields_trackers,
44 :time_entries,
44 :time_entries,
45 :journals,
45 :journals,
46 :journal_details,
46 :journal_details,
47 :queries
47 :queries
48
48
49 def setup
49 def setup
50 @controller = IssuesController.new
50 @controller = IssuesController.new
51 @request = ActionController::TestRequest.new
51 @request = ActionController::TestRequest.new
52 @response = ActionController::TestResponse.new
52 @response = ActionController::TestResponse.new
53 User.current = nil
53 User.current = nil
54 end
54 end
55
55
56 def test_index
56 def test_index
57 Setting.default_language = 'en'
57 Setting.default_language = 'en'
58
58
59 get :index
59 get :index
60 assert_response :success
60 assert_response :success
61 assert_template 'index.rhtml'
61 assert_template 'index.rhtml'
62 assert_not_nil assigns(:issues)
62 assert_not_nil assigns(:issues)
63 assert_nil assigns(:project)
63 assert_nil assigns(:project)
64 assert_tag :tag => 'a', :content => /Can't print recipes/
64 assert_tag :tag => 'a', :content => /Can't print recipes/
65 assert_tag :tag => 'a', :content => /Subproject issue/
65 assert_tag :tag => 'a', :content => /Subproject issue/
66 # private projects hidden
66 # private projects hidden
67 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
67 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
68 assert_no_tag :tag => 'a', :content => /Issue on project 2/
68 assert_no_tag :tag => 'a', :content => /Issue on project 2/
69 # project column
69 # project column
70 assert_tag :tag => 'th', :content => /Project/
70 assert_tag :tag => 'th', :content => /Project/
71 end
71 end
72
72
73 def test_index_should_not_list_issues_when_module_disabled
73 def test_index_should_not_list_issues_when_module_disabled
74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
74 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
75 get :index
75 get :index
76 assert_response :success
76 assert_response :success
77 assert_template 'index.rhtml'
77 assert_template 'index.rhtml'
78 assert_not_nil assigns(:issues)
78 assert_not_nil assigns(:issues)
79 assert_nil assigns(:project)
79 assert_nil assigns(:project)
80 assert_no_tag :tag => 'a', :content => /Can't print recipes/
80 assert_no_tag :tag => 'a', :content => /Can't print recipes/
81 assert_tag :tag => 'a', :content => /Subproject issue/
81 assert_tag :tag => 'a', :content => /Subproject issue/
82 end
82 end
83
83
84 def test_index_should_not_list_issues_when_module_disabled
84 def test_index_should_not_list_issues_when_module_disabled
85 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
85 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
86 get :index
86 get :index
87 assert_response :success
87 assert_response :success
88 assert_template 'index.rhtml'
88 assert_template 'index.rhtml'
89 assert_not_nil assigns(:issues)
89 assert_not_nil assigns(:issues)
90 assert_nil assigns(:project)
90 assert_nil assigns(:project)
91 assert_no_tag :tag => 'a', :content => /Can't print recipes/
91 assert_no_tag :tag => 'a', :content => /Can't print recipes/
92 assert_tag :tag => 'a', :content => /Subproject issue/
92 assert_tag :tag => 'a', :content => /Subproject issue/
93 end
93 end
94
94
95 def test_index_with_project
95 def test_index_with_project
96 Setting.display_subprojects_issues = 0
96 Setting.display_subprojects_issues = 0
97 get :index, :project_id => 1
97 get :index, :project_id => 1
98 assert_response :success
98 assert_response :success
99 assert_template 'index.rhtml'
99 assert_template 'index.rhtml'
100 assert_not_nil assigns(:issues)
100 assert_not_nil assigns(:issues)
101 assert_tag :tag => 'a', :content => /Can't print recipes/
101 assert_tag :tag => 'a', :content => /Can't print recipes/
102 assert_no_tag :tag => 'a', :content => /Subproject issue/
102 assert_no_tag :tag => 'a', :content => /Subproject issue/
103 end
103 end
104
104
105 def test_index_with_project_and_subprojects
105 def test_index_with_project_and_subprojects
106 Setting.display_subprojects_issues = 1
106 Setting.display_subprojects_issues = 1
107 get :index, :project_id => 1
107 get :index, :project_id => 1
108 assert_response :success
108 assert_response :success
109 assert_template 'index.rhtml'
109 assert_template 'index.rhtml'
110 assert_not_nil assigns(:issues)
110 assert_not_nil assigns(:issues)
111 assert_tag :tag => 'a', :content => /Can't print recipes/
111 assert_tag :tag => 'a', :content => /Can't print recipes/
112 assert_tag :tag => 'a', :content => /Subproject issue/
112 assert_tag :tag => 'a', :content => /Subproject issue/
113 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
113 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
114 end
114 end
115
115
116 def test_index_with_project_and_subprojects_should_show_private_subprojects
116 def test_index_with_project_and_subprojects_should_show_private_subprojects
117 @request.session[:user_id] = 2
117 @request.session[:user_id] = 2
118 Setting.display_subprojects_issues = 1
118 Setting.display_subprojects_issues = 1
119 get :index, :project_id => 1
119 get :index, :project_id => 1
120 assert_response :success
120 assert_response :success
121 assert_template 'index.rhtml'
121 assert_template 'index.rhtml'
122 assert_not_nil assigns(:issues)
122 assert_not_nil assigns(:issues)
123 assert_tag :tag => 'a', :content => /Can't print recipes/
123 assert_tag :tag => 'a', :content => /Can't print recipes/
124 assert_tag :tag => 'a', :content => /Subproject issue/
124 assert_tag :tag => 'a', :content => /Subproject issue/
125 assert_tag :tag => 'a', :content => /Issue of a private subproject/
125 assert_tag :tag => 'a', :content => /Issue of a private subproject/
126 end
126 end
127
127
128 def test_index_with_project_and_filter
128 def test_index_with_project_and_filter
129 get :index, :project_id => 1, :set_filter => 1
129 get :index, :project_id => 1, :set_filter => 1
130 assert_response :success
130 assert_response :success
131 assert_template 'index.rhtml'
131 assert_template 'index.rhtml'
132 assert_not_nil assigns(:issues)
132 assert_not_nil assigns(:issues)
133 end
133 end
134
134
135 def test_index_with_query
135 def test_index_with_query
136 get :index, :project_id => 1, :query_id => 5
136 get :index, :project_id => 1, :query_id => 5
137 assert_response :success
137 assert_response :success
138 assert_template 'index.rhtml'
138 assert_template 'index.rhtml'
139 assert_not_nil assigns(:issues)
139 assert_not_nil assigns(:issues)
140 assert_nil assigns(:issue_count_by_group)
140 assert_nil assigns(:issue_count_by_group)
141 end
141 end
142
142
143 def test_index_with_query_grouped_by_tracker
143 def test_index_with_query_grouped_by_tracker
144 get :index, :project_id => 1, :query_id => 6
144 get :index, :project_id => 1, :query_id => 6
145 assert_response :success
145 assert_response :success
146 assert_template 'index.rhtml'
146 assert_template 'index.rhtml'
147 assert_not_nil assigns(:issues)
147 assert_not_nil assigns(:issues)
148 assert_not_nil assigns(:issue_count_by_group)
148 assert_not_nil assigns(:issue_count_by_group)
149 end
149 end
150
150
151 def test_index_with_query_grouped_by_list_custom_field
151 def test_index_with_query_grouped_by_list_custom_field
152 get :index, :project_id => 1, :query_id => 9
152 get :index, :project_id => 1, :query_id => 9
153 assert_response :success
153 assert_response :success
154 assert_template 'index.rhtml'
154 assert_template 'index.rhtml'
155 assert_not_nil assigns(:issues)
155 assert_not_nil assigns(:issues)
156 assert_not_nil assigns(:issue_count_by_group)
156 assert_not_nil assigns(:issue_count_by_group)
157 end
157 end
158
158
159 def test_index_sort_by_field_not_included_in_columns
159 def test_index_sort_by_field_not_included_in_columns
160 Setting.issue_list_default_columns = %w(subject author)
160 Setting.issue_list_default_columns = %w(subject author)
161 get :index, :sort => 'tracker'
161 get :index, :sort => 'tracker'
162 end
162 end
163
163
164 def test_index_csv_with_project
164 def test_index_csv_with_project
165 Setting.default_language = 'en'
165 Setting.default_language = 'en'
166
166
167 get :index, :format => 'csv'
167 get :index, :format => 'csv'
168 assert_response :success
168 assert_response :success
169 assert_not_nil assigns(:issues)
169 assert_not_nil assigns(:issues)
170 assert_equal 'text/csv', @response.content_type
170 assert_equal 'text/csv', @response.content_type
171 assert @response.body.starts_with?("#,")
171 assert @response.body.starts_with?("#,")
172
172
173 get :index, :project_id => 1, :format => 'csv'
173 get :index, :project_id => 1, :format => 'csv'
174 assert_response :success
174 assert_response :success
175 assert_not_nil assigns(:issues)
175 assert_not_nil assigns(:issues)
176 assert_equal 'text/csv', @response.content_type
176 assert_equal 'text/csv', @response.content_type
177 end
177 end
178
178
179 def test_index_pdf
179 def test_index_pdf
180 get :index, :format => 'pdf'
180 get :index, :format => 'pdf'
181 assert_response :success
181 assert_response :success
182 assert_not_nil assigns(:issues)
182 assert_not_nil assigns(:issues)
183 assert_equal 'application/pdf', @response.content_type
183 assert_equal 'application/pdf', @response.content_type
184
184
185 get :index, :project_id => 1, :format => 'pdf'
185 get :index, :project_id => 1, :format => 'pdf'
186 assert_response :success
186 assert_response :success
187 assert_not_nil assigns(:issues)
187 assert_not_nil assigns(:issues)
188 assert_equal 'application/pdf', @response.content_type
188 assert_equal 'application/pdf', @response.content_type
189
189
190 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
190 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
191 assert_response :success
191 assert_response :success
192 assert_not_nil assigns(:issues)
192 assert_not_nil assigns(:issues)
193 assert_equal 'application/pdf', @response.content_type
193 assert_equal 'application/pdf', @response.content_type
194 end
194 end
195
195
196 def test_index_pdf_with_query_grouped_by_list_custom_field
196 def test_index_pdf_with_query_grouped_by_list_custom_field
197 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
197 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
198 assert_response :success
198 assert_response :success
199 assert_not_nil assigns(:issues)
199 assert_not_nil assigns(:issues)
200 assert_not_nil assigns(:issue_count_by_group)
200 assert_not_nil assigns(:issue_count_by_group)
201 assert_equal 'application/pdf', @response.content_type
201 assert_equal 'application/pdf', @response.content_type
202 end
202 end
203
203
204 def test_index_sort
204 def test_index_sort
205 get :index, :sort => 'tracker,id:desc'
205 get :index, :sort => 'tracker,id:desc'
206 assert_response :success
206 assert_response :success
207
207
208 sort_params = @request.session['issues_index_sort']
208 sort_params = @request.session['issues_index_sort']
209 assert sort_params.is_a?(String)
209 assert sort_params.is_a?(String)
210 assert_equal 'tracker,id:desc', sort_params
210 assert_equal 'tracker,id:desc', sort_params
211
211
212 issues = assigns(:issues)
212 issues = assigns(:issues)
213 assert_not_nil issues
213 assert_not_nil issues
214 assert !issues.empty?
214 assert !issues.empty?
215 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
215 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
216 end
216 end
217
217
218 def test_index_with_columns
218 def test_index_with_columns
219 columns = ['tracker', 'subject', 'assigned_to']
219 columns = ['tracker', 'subject', 'assigned_to']
220 get :index, :set_filter => 1, :query => { 'column_names' => columns}
220 get :index, :set_filter => 1, :query => { 'column_names' => columns}
221 assert_response :success
221 assert_response :success
222
222
223 # query should use specified columns
223 # query should use specified columns
224 query = assigns(:query)
224 query = assigns(:query)
225 assert_kind_of Query, query
225 assert_kind_of Query, query
226 assert_equal columns, query.column_names.map(&:to_s)
226 assert_equal columns, query.column_names.map(&:to_s)
227
227
228 # columns should be stored in session
228 # columns should be stored in session
229 assert_kind_of Hash, session[:query]
229 assert_kind_of Hash, session[:query]
230 assert_kind_of Array, session[:query][:column_names]
230 assert_kind_of Array, session[:query][:column_names]
231 assert_equal columns, session[:query][:column_names].map(&:to_s)
231 assert_equal columns, session[:query][:column_names].map(&:to_s)
232 end
232 end
233
233
234 def test_gantt
234 def test_gantt
235 get :gantt, :project_id => 1
235 get :gantt, :project_id => 1
236 assert_response :success
236 assert_response :success
237 assert_template 'gantt.rhtml'
237 assert_template 'gantt.rhtml'
238 assert_not_nil assigns(:gantt)
238 assert_not_nil assigns(:gantt)
239 events = assigns(:gantt).events
239 events = assigns(:gantt).events
240 assert_not_nil events
240 assert_not_nil events
241 # Issue with start and due dates
241 # Issue with start and due dates
242 i = Issue.find(1)
242 i = Issue.find(1)
243 assert_not_nil i.due_date
243 assert_not_nil i.due_date
244 assert events.include?(Issue.find(1))
244 assert events.include?(Issue.find(1))
245 # Issue with without due date but targeted to a version with date
245 # Issue with without due date but targeted to a version with date
246 i = Issue.find(2)
246 i = Issue.find(2)
247 assert_nil i.due_date
247 assert_nil i.due_date
248 assert events.include?(i)
248 assert events.include?(i)
249 end
249 end
250
250
251 def test_cross_project_gantt
251 def test_cross_project_gantt
252 get :gantt
252 get :gantt
253 assert_response :success
253 assert_response :success
254 assert_template 'gantt.rhtml'
254 assert_template 'gantt.rhtml'
255 assert_not_nil assigns(:gantt)
255 assert_not_nil assigns(:gantt)
256 events = assigns(:gantt).events
256 events = assigns(:gantt).events
257 assert_not_nil events
257 assert_not_nil events
258 end
258 end
259
259
260 def test_gantt_export_to_pdf
260 def test_gantt_export_to_pdf
261 get :gantt, :project_id => 1, :format => 'pdf'
261 get :gantt, :project_id => 1, :format => 'pdf'
262 assert_response :success
262 assert_response :success
263 assert_equal 'application/pdf', @response.content_type
263 assert_equal 'application/pdf', @response.content_type
264 assert @response.body.starts_with?('%PDF')
264 assert @response.body.starts_with?('%PDF')
265 assert_not_nil assigns(:gantt)
265 assert_not_nil assigns(:gantt)
266 end
266 end
267
267
268 def test_cross_project_gantt_export_to_pdf
268 def test_cross_project_gantt_export_to_pdf
269 get :gantt, :format => 'pdf'
269 get :gantt, :format => 'pdf'
270 assert_response :success
270 assert_response :success
271 assert_equal 'application/pdf', @response.content_type
271 assert_equal 'application/pdf', @response.content_type
272 assert @response.body.starts_with?('%PDF')
272 assert @response.body.starts_with?('%PDF')
273 assert_not_nil assigns(:gantt)
273 assert_not_nil assigns(:gantt)
274 end
274 end
275
275
276 if Object.const_defined?(:Magick)
276 if Object.const_defined?(:Magick)
277 def test_gantt_image
277 def test_gantt_image
278 get :gantt, :project_id => 1, :format => 'png'
278 get :gantt, :project_id => 1, :format => 'png'
279 assert_response :success
279 assert_response :success
280 assert_equal 'image/png', @response.content_type
280 assert_equal 'image/png', @response.content_type
281 end
281 end
282 else
282 else
283 puts "RMagick not installed. Skipping tests !!!"
283 puts "RMagick not installed. Skipping tests !!!"
284 end
284 end
285
285
286 def test_calendar
286 def test_calendar
287 get :calendar, :project_id => 1
287 get :calendar, :project_id => 1
288 assert_response :success
288 assert_response :success
289 assert_template 'calendar'
289 assert_template 'calendar'
290 assert_not_nil assigns(:calendar)
290 assert_not_nil assigns(:calendar)
291 end
291 end
292
292
293 def test_cross_project_calendar
293 def test_cross_project_calendar
294 get :calendar
294 get :calendar
295 assert_response :success
295 assert_response :success
296 assert_template 'calendar'
296 assert_template 'calendar'
297 assert_not_nil assigns(:calendar)
297 assert_not_nil assigns(:calendar)
298 end
298 end
299
299
300 def test_changes
300 def test_changes
301 get :changes, :project_id => 1
301 get :changes, :project_id => 1
302 assert_response :success
302 assert_response :success
303 assert_not_nil assigns(:journals)
303 assert_not_nil assigns(:journals)
304 assert_equal 'application/atom+xml', @response.content_type
304 assert_equal 'application/atom+xml', @response.content_type
305 end
305 end
306
306
307 def test_show_by_anonymous
307 def test_show_by_anonymous
308 get :show, :id => 1
308 get :show, :id => 1
309 assert_response :success
309 assert_response :success
310 assert_template 'show.rhtml'
310 assert_template 'show.rhtml'
311 assert_not_nil assigns(:issue)
311 assert_not_nil assigns(:issue)
312 assert_equal Issue.find(1), assigns(:issue)
312 assert_equal Issue.find(1), assigns(:issue)
313
313
314 # anonymous role is allowed to add a note
314 # anonymous role is allowed to add a note
315 assert_tag :tag => 'form',
315 assert_tag :tag => 'form',
316 :descendant => { :tag => 'fieldset',
316 :descendant => { :tag => 'fieldset',
317 :child => { :tag => 'legend',
317 :child => { :tag => 'legend',
318 :content => /Notes/ } }
318 :content => /Notes/ } }
319 end
319 end
320
320
321 def test_show_by_manager
321 def test_show_by_manager
322 @request.session[:user_id] = 2
322 @request.session[:user_id] = 2
323 get :show, :id => 1
323 get :show, :id => 1
324 assert_response :success
324 assert_response :success
325
325
326 assert_tag :tag => 'form',
326 assert_tag :tag => 'form',
327 :descendant => { :tag => 'fieldset',
327 :descendant => { :tag => 'fieldset',
328 :child => { :tag => 'legend',
328 :child => { :tag => 'legend',
329 :content => /Change properties/ } },
329 :content => /Change properties/ } },
330 :descendant => { :tag => 'fieldset',
330 :descendant => { :tag => 'fieldset',
331 :child => { :tag => 'legend',
331 :child => { :tag => 'legend',
332 :content => /Log time/ } },
332 :content => /Log time/ } },
333 :descendant => { :tag => 'fieldset',
333 :descendant => { :tag => 'fieldset',
334 :child => { :tag => 'legend',
334 :child => { :tag => 'legend',
335 :content => /Notes/ } }
335 :content => /Notes/ } }
336 end
336 end
337
337
338 def test_show_should_deny_anonymous_access_without_permission
338 def test_show_should_deny_anonymous_access_without_permission
339 Role.anonymous.remove_permission!(:view_issues)
339 Role.anonymous.remove_permission!(:view_issues)
340 get :show, :id => 1
340 get :show, :id => 1
341 assert_response :redirect
341 assert_response :redirect
342 end
342 end
343
343
344 def test_show_should_deny_non_member_access_without_permission
344 def test_show_should_deny_non_member_access_without_permission
345 Role.non_member.remove_permission!(:view_issues)
345 Role.non_member.remove_permission!(:view_issues)
346 @request.session[:user_id] = 9
346 @request.session[:user_id] = 9
347 get :show, :id => 1
347 get :show, :id => 1
348 assert_response 403
348 assert_response 403
349 end
349 end
350
350
351 def test_show_should_deny_member_access_without_permission
351 def test_show_should_deny_member_access_without_permission
352 Role.find(1).remove_permission!(:view_issues)
352 Role.find(1).remove_permission!(:view_issues)
353 @request.session[:user_id] = 2
353 @request.session[:user_id] = 2
354 get :show, :id => 1
354 get :show, :id => 1
355 assert_response 403
355 assert_response 403
356 end
356 end
357
357
358 def test_show_should_not_disclose_relations_to_invisible_issues
358 def test_show_should_not_disclose_relations_to_invisible_issues
359 Setting.cross_project_issue_relations = '1'
359 Setting.cross_project_issue_relations = '1'
360 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
360 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
361 # Relation to a private project issue
361 # Relation to a private project issue
362 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
362 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
363
363
364 get :show, :id => 1
364 get :show, :id => 1
365 assert_response :success
365 assert_response :success
366
366
367 assert_tag :div, :attributes => { :id => 'relations' },
367 assert_tag :div, :attributes => { :id => 'relations' },
368 :descendant => { :tag => 'a', :content => /#2$/ }
368 :descendant => { :tag => 'a', :content => /#2$/ }
369 assert_no_tag :div, :attributes => { :id => 'relations' },
369 assert_no_tag :div, :attributes => { :id => 'relations' },
370 :descendant => { :tag => 'a', :content => /#4$/ }
370 :descendant => { :tag => 'a', :content => /#4$/ }
371 end
371 end
372
372
373 def test_show_atom
373 def test_show_atom
374 get :show, :id => 2, :format => 'atom'
374 get :show, :id => 2, :format => 'atom'
375 assert_response :success
375 assert_response :success
376 assert_template 'changes.rxml'
376 assert_template 'changes.rxml'
377 # Inline image
377 # Inline image
378 assert @response.body.include?("&lt;img src=\"http://test.host/attachments/download/10\" alt=\"\" /&gt;"), "Body did not match. Body: #{@response.body}"
378 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
379 end
379 end
380
380
381 def test_show_export_to_pdf
381 def test_show_export_to_pdf
382 get :show, :id => 3, :format => 'pdf'
382 get :show, :id => 3, :format => 'pdf'
383 assert_response :success
383 assert_response :success
384 assert_equal 'application/pdf', @response.content_type
384 assert_equal 'application/pdf', @response.content_type
385 assert @response.body.starts_with?('%PDF')
385 assert @response.body.starts_with?('%PDF')
386 assert_not_nil assigns(:issue)
386 assert_not_nil assigns(:issue)
387 end
387 end
388
388
389 def test_get_new
389 def test_get_new
390 @request.session[:user_id] = 2
390 @request.session[:user_id] = 2
391 get :new, :project_id => 1, :tracker_id => 1
391 get :new, :project_id => 1, :tracker_id => 1
392 assert_response :success
392 assert_response :success
393 assert_template 'new'
393 assert_template 'new'
394
394
395 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
395 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
396 :value => 'Default string' }
396 :value => 'Default string' }
397 end
397 end
398
398
399 def test_get_new_without_tracker_id
399 def test_get_new_without_tracker_id
400 @request.session[:user_id] = 2
400 @request.session[:user_id] = 2
401 get :new, :project_id => 1
401 get :new, :project_id => 1
402 assert_response :success
402 assert_response :success
403 assert_template 'new'
403 assert_template 'new'
404
404
405 issue = assigns(:issue)
405 issue = assigns(:issue)
406 assert_not_nil issue
406 assert_not_nil issue
407 assert_equal Project.find(1).trackers.first, issue.tracker
407 assert_equal Project.find(1).trackers.first, issue.tracker
408 end
408 end
409
409
410 def test_get_new_with_no_default_status_should_display_an_error
410 def test_get_new_with_no_default_status_should_display_an_error
411 @request.session[:user_id] = 2
411 @request.session[:user_id] = 2
412 IssueStatus.delete_all
412 IssueStatus.delete_all
413
413
414 get :new, :project_id => 1
414 get :new, :project_id => 1
415 assert_response 500
415 assert_response 500
416 assert_not_nil flash[:error]
416 assert_not_nil flash[:error]
417 assert_tag :tag => 'div', :attributes => { :class => /error/ },
417 assert_tag :tag => 'div', :attributes => { :class => /error/ },
418 :content => /No default issue/
418 :content => /No default issue/
419 end
419 end
420
420
421 def test_get_new_with_no_tracker_should_display_an_error
421 def test_get_new_with_no_tracker_should_display_an_error
422 @request.session[:user_id] = 2
422 @request.session[:user_id] = 2
423 Tracker.delete_all
423 Tracker.delete_all
424
424
425 get :new, :project_id => 1
425 get :new, :project_id => 1
426 assert_response 500
426 assert_response 500
427 assert_not_nil flash[:error]
427 assert_not_nil flash[:error]
428 assert_tag :tag => 'div', :attributes => { :class => /error/ },
428 assert_tag :tag => 'div', :attributes => { :class => /error/ },
429 :content => /No tracker/
429 :content => /No tracker/
430 end
430 end
431
431
432 def test_update_new_form
432 def test_update_new_form
433 @request.session[:user_id] = 2
433 @request.session[:user_id] = 2
434 xhr :post, :update_form, :project_id => 1,
434 xhr :post, :update_form, :project_id => 1,
435 :issue => {:tracker_id => 2,
435 :issue => {:tracker_id => 2,
436 :subject => 'This is the test_new issue',
436 :subject => 'This is the test_new issue',
437 :description => 'This is the description',
437 :description => 'This is the description',
438 :priority_id => 5}
438 :priority_id => 5}
439 assert_response :success
439 assert_response :success
440 assert_template 'attributes'
440 assert_template 'attributes'
441
441
442 issue = assigns(:issue)
442 issue = assigns(:issue)
443 assert_kind_of Issue, issue
443 assert_kind_of Issue, issue
444 assert_equal 1, issue.project_id
444 assert_equal 1, issue.project_id
445 assert_equal 2, issue.tracker_id
445 assert_equal 2, issue.tracker_id
446 assert_equal 'This is the test_new issue', issue.subject
446 assert_equal 'This is the test_new issue', issue.subject
447 end
447 end
448
448
449 def test_post_new
449 def test_post_new
450 @request.session[:user_id] = 2
450 @request.session[:user_id] = 2
451 assert_difference 'Issue.count' do
451 assert_difference 'Issue.count' do
452 post :new, :project_id => 1,
452 post :new, :project_id => 1,
453 :issue => {:tracker_id => 3,
453 :issue => {:tracker_id => 3,
454 :subject => 'This is the test_new issue',
454 :subject => 'This is the test_new issue',
455 :description => 'This is the description',
455 :description => 'This is the description',
456 :priority_id => 5,
456 :priority_id => 5,
457 :estimated_hours => '',
457 :estimated_hours => '',
458 :custom_field_values => {'2' => 'Value for field 2'}}
458 :custom_field_values => {'2' => 'Value for field 2'}}
459 end
459 end
460 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
460 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
461
461
462 issue = Issue.find_by_subject('This is the test_new issue')
462 issue = Issue.find_by_subject('This is the test_new issue')
463 assert_not_nil issue
463 assert_not_nil issue
464 assert_equal 2, issue.author_id
464 assert_equal 2, issue.author_id
465 assert_equal 3, issue.tracker_id
465 assert_equal 3, issue.tracker_id
466 assert_nil issue.estimated_hours
466 assert_nil issue.estimated_hours
467 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
467 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
468 assert_not_nil v
468 assert_not_nil v
469 assert_equal 'Value for field 2', v.value
469 assert_equal 'Value for field 2', v.value
470 end
470 end
471
471
472 def test_post_new_and_continue
472 def test_post_new_and_continue
473 @request.session[:user_id] = 2
473 @request.session[:user_id] = 2
474 post :new, :project_id => 1,
474 post :new, :project_id => 1,
475 :issue => {:tracker_id => 3,
475 :issue => {:tracker_id => 3,
476 :subject => 'This is first issue',
476 :subject => 'This is first issue',
477 :priority_id => 5},
477 :priority_id => 5},
478 :continue => ''
478 :continue => ''
479 assert_redirected_to :controller => 'issues', :action => 'new', :tracker_id => 3
479 assert_redirected_to :controller => 'issues', :action => 'new', :tracker_id => 3
480 end
480 end
481
481
482 def test_post_new_without_custom_fields_param
482 def test_post_new_without_custom_fields_param
483 @request.session[:user_id] = 2
483 @request.session[:user_id] = 2
484 assert_difference 'Issue.count' do
484 assert_difference 'Issue.count' do
485 post :new, :project_id => 1,
485 post :new, :project_id => 1,
486 :issue => {:tracker_id => 1,
486 :issue => {:tracker_id => 1,
487 :subject => 'This is the test_new issue',
487 :subject => 'This is the test_new issue',
488 :description => 'This is the description',
488 :description => 'This is the description',
489 :priority_id => 5}
489 :priority_id => 5}
490 end
490 end
491 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
491 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
492 end
492 end
493
493
494 def test_post_new_with_required_custom_field_and_without_custom_fields_param
494 def test_post_new_with_required_custom_field_and_without_custom_fields_param
495 field = IssueCustomField.find_by_name('Database')
495 field = IssueCustomField.find_by_name('Database')
496 field.update_attribute(:is_required, true)
496 field.update_attribute(:is_required, true)
497
497
498 @request.session[:user_id] = 2
498 @request.session[:user_id] = 2
499 post :new, :project_id => 1,
499 post :new, :project_id => 1,
500 :issue => {:tracker_id => 1,
500 :issue => {:tracker_id => 1,
501 :subject => 'This is the test_new issue',
501 :subject => 'This is the test_new issue',
502 :description => 'This is the description',
502 :description => 'This is the description',
503 :priority_id => 5}
503 :priority_id => 5}
504 assert_response :success
504 assert_response :success
505 assert_template 'new'
505 assert_template 'new'
506 issue = assigns(:issue)
506 issue = assigns(:issue)
507 assert_not_nil issue
507 assert_not_nil issue
508 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
508 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
509 end
509 end
510
510
511 def test_post_new_with_watchers
511 def test_post_new_with_watchers
512 @request.session[:user_id] = 2
512 @request.session[:user_id] = 2
513 ActionMailer::Base.deliveries.clear
513 ActionMailer::Base.deliveries.clear
514
514
515 assert_difference 'Watcher.count', 2 do
515 assert_difference 'Watcher.count', 2 do
516 post :new, :project_id => 1,
516 post :new, :project_id => 1,
517 :issue => {:tracker_id => 1,
517 :issue => {:tracker_id => 1,
518 :subject => 'This is a new issue with watchers',
518 :subject => 'This is a new issue with watchers',
519 :description => 'This is the description',
519 :description => 'This is the description',
520 :priority_id => 5,
520 :priority_id => 5,
521 :watcher_user_ids => ['2', '3']}
521 :watcher_user_ids => ['2', '3']}
522 end
522 end
523 issue = Issue.find_by_subject('This is a new issue with watchers')
523 issue = Issue.find_by_subject('This is a new issue with watchers')
524 assert_not_nil issue
524 assert_not_nil issue
525 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
525 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
526
526
527 # Watchers added
527 # Watchers added
528 assert_equal [2, 3], issue.watcher_user_ids.sort
528 assert_equal [2, 3], issue.watcher_user_ids.sort
529 assert issue.watched_by?(User.find(3))
529 assert issue.watched_by?(User.find(3))
530 # Watchers notified
530 # Watchers notified
531 mail = ActionMailer::Base.deliveries.last
531 mail = ActionMailer::Base.deliveries.last
532 assert_kind_of TMail::Mail, mail
532 assert_kind_of TMail::Mail, mail
533 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
533 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
534 end
534 end
535
535
536 def test_post_new_should_send_a_notification
536 def test_post_new_should_send_a_notification
537 ActionMailer::Base.deliveries.clear
537 ActionMailer::Base.deliveries.clear
538 @request.session[:user_id] = 2
538 @request.session[:user_id] = 2
539 assert_difference 'Issue.count' do
539 assert_difference 'Issue.count' do
540 post :new, :project_id => 1,
540 post :new, :project_id => 1,
541 :issue => {:tracker_id => 3,
541 :issue => {:tracker_id => 3,
542 :subject => 'This is the test_new issue',
542 :subject => 'This is the test_new issue',
543 :description => 'This is the description',
543 :description => 'This is the description',
544 :priority_id => 5,
544 :priority_id => 5,
545 :estimated_hours => '',
545 :estimated_hours => '',
546 :custom_field_values => {'2' => 'Value for field 2'}}
546 :custom_field_values => {'2' => 'Value for field 2'}}
547 end
547 end
548 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
548 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
549
549
550 assert_equal 1, ActionMailer::Base.deliveries.size
550 assert_equal 1, ActionMailer::Base.deliveries.size
551 end
551 end
552
552
553 def test_post_should_preserve_fields_values_on_validation_failure
553 def test_post_should_preserve_fields_values_on_validation_failure
554 @request.session[:user_id] = 2
554 @request.session[:user_id] = 2
555 post :new, :project_id => 1,
555 post :new, :project_id => 1,
556 :issue => {:tracker_id => 1,
556 :issue => {:tracker_id => 1,
557 # empty subject
557 # empty subject
558 :subject => '',
558 :subject => '',
559 :description => 'This is a description',
559 :description => 'This is a description',
560 :priority_id => 6,
560 :priority_id => 6,
561 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
561 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
562 assert_response :success
562 assert_response :success
563 assert_template 'new'
563 assert_template 'new'
564
564
565 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
565 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
566 :content => 'This is a description'
566 :content => 'This is a description'
567 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
567 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
568 :child => { :tag => 'option', :attributes => { :selected => 'selected',
568 :child => { :tag => 'option', :attributes => { :selected => 'selected',
569 :value => '6' },
569 :value => '6' },
570 :content => 'High' }
570 :content => 'High' }
571 # Custom fields
571 # Custom fields
572 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
572 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
573 :child => { :tag => 'option', :attributes => { :selected => 'selected',
573 :child => { :tag => 'option', :attributes => { :selected => 'selected',
574 :value => 'Oracle' },
574 :value => 'Oracle' },
575 :content => 'Oracle' }
575 :content => 'Oracle' }
576 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
576 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
577 :value => 'Value for field 2'}
577 :value => 'Value for field 2'}
578 end
578 end
579
579
580 def test_post_new_should_ignore_non_safe_attributes
580 def test_post_new_should_ignore_non_safe_attributes
581 @request.session[:user_id] = 2
581 @request.session[:user_id] = 2
582 assert_nothing_raised do
582 assert_nothing_raised do
583 post :new, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
583 post :new, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
584 end
584 end
585 end
585 end
586
586
587 def test_copy_issue
587 def test_copy_issue
588 @request.session[:user_id] = 2
588 @request.session[:user_id] = 2
589 get :new, :project_id => 1, :copy_from => 1
589 get :new, :project_id => 1, :copy_from => 1
590 assert_template 'new'
590 assert_template 'new'
591 assert_not_nil assigns(:issue)
591 assert_not_nil assigns(:issue)
592 orig = Issue.find(1)
592 orig = Issue.find(1)
593 assert_equal orig.subject, assigns(:issue).subject
593 assert_equal orig.subject, assigns(:issue).subject
594 end
594 end
595
595
596 def test_get_edit
596 def test_get_edit
597 @request.session[:user_id] = 2
597 @request.session[:user_id] = 2
598 get :edit, :id => 1
598 get :edit, :id => 1
599 assert_response :success
599 assert_response :success
600 assert_template 'edit'
600 assert_template 'edit'
601 assert_not_nil assigns(:issue)
601 assert_not_nil assigns(:issue)
602 assert_equal Issue.find(1), assigns(:issue)
602 assert_equal Issue.find(1), assigns(:issue)
603 end
603 end
604
604
605 def test_get_edit_with_params
605 def test_get_edit_with_params
606 @request.session[:user_id] = 2
606 @request.session[:user_id] = 2
607 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }
607 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }
608 assert_response :success
608 assert_response :success
609 assert_template 'edit'
609 assert_template 'edit'
610
610
611 issue = assigns(:issue)
611 issue = assigns(:issue)
612 assert_not_nil issue
612 assert_not_nil issue
613
613
614 assert_equal 5, issue.status_id
614 assert_equal 5, issue.status_id
615 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
615 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
616 :child => { :tag => 'option',
616 :child => { :tag => 'option',
617 :content => 'Closed',
617 :content => 'Closed',
618 :attributes => { :selected => 'selected' } }
618 :attributes => { :selected => 'selected' } }
619
619
620 assert_equal 7, issue.priority_id
620 assert_equal 7, issue.priority_id
621 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
621 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
622 :child => { :tag => 'option',
622 :child => { :tag => 'option',
623 :content => 'Urgent',
623 :content => 'Urgent',
624 :attributes => { :selected => 'selected' } }
624 :attributes => { :selected => 'selected' } }
625 end
625 end
626
626
627 def test_update_edit_form
627 def test_update_edit_form
628 @request.session[:user_id] = 2
628 @request.session[:user_id] = 2
629 xhr :post, :update_form, :project_id => 1,
629 xhr :post, :update_form, :project_id => 1,
630 :id => 1,
630 :id => 1,
631 :issue => {:tracker_id => 2,
631 :issue => {:tracker_id => 2,
632 :subject => 'This is the test_new issue',
632 :subject => 'This is the test_new issue',
633 :description => 'This is the description',
633 :description => 'This is the description',
634 :priority_id => 5}
634 :priority_id => 5}
635 assert_response :success
635 assert_response :success
636 assert_template 'attributes'
636 assert_template 'attributes'
637
637
638 issue = assigns(:issue)
638 issue = assigns(:issue)
639 assert_kind_of Issue, issue
639 assert_kind_of Issue, issue
640 assert_equal 1, issue.id
640 assert_equal 1, issue.id
641 assert_equal 1, issue.project_id
641 assert_equal 1, issue.project_id
642 assert_equal 2, issue.tracker_id
642 assert_equal 2, issue.tracker_id
643 assert_equal 'This is the test_new issue', issue.subject
643 assert_equal 'This is the test_new issue', issue.subject
644 end
644 end
645
645
646 def test_reply_to_issue
646 def test_reply_to_issue
647 @request.session[:user_id] = 2
647 @request.session[:user_id] = 2
648 get :reply, :id => 1
648 get :reply, :id => 1
649 assert_response :success
649 assert_response :success
650 assert_select_rjs :show, "update"
650 assert_select_rjs :show, "update"
651 end
651 end
652
652
653 def test_reply_to_note
653 def test_reply_to_note
654 @request.session[:user_id] = 2
654 @request.session[:user_id] = 2
655 get :reply, :id => 1, :journal_id => 2
655 get :reply, :id => 1, :journal_id => 2
656 assert_response :success
656 assert_response :success
657 assert_select_rjs :show, "update"
657 assert_select_rjs :show, "update"
658 end
658 end
659
659
660 def test_update_using_invalid_http_verbs
660 def test_update_using_invalid_http_verbs
661 @request.session[:user_id] = 2
661 @request.session[:user_id] = 2
662 subject = 'Updated by an invalid http verb'
662 subject = 'Updated by an invalid http verb'
663
663
664 get :update, :id => 1, :issue => {:subject => subject}
664 get :update, :id => 1, :issue => {:subject => subject}
665 assert_not_equal subject, Issue.find(1).subject
665 assert_not_equal subject, Issue.find(1).subject
666
666
667 post :update, :id => 1, :issue => {:subject => subject}
667 post :update, :id => 1, :issue => {:subject => subject}
668 assert_not_equal subject, Issue.find(1).subject
668 assert_not_equal subject, Issue.find(1).subject
669
669
670 delete :update, :id => 1, :issue => {:subject => subject}
670 delete :update, :id => 1, :issue => {:subject => subject}
671 assert_not_equal subject, Issue.find(1).subject
671 assert_not_equal subject, Issue.find(1).subject
672 end
672 end
673
673
674 def test_put_update_without_custom_fields_param
674 def test_put_update_without_custom_fields_param
675 @request.session[:user_id] = 2
675 @request.session[:user_id] = 2
676 ActionMailer::Base.deliveries.clear
676 ActionMailer::Base.deliveries.clear
677
677
678 issue = Issue.find(1)
678 issue = Issue.find(1)
679 assert_equal '125', issue.custom_value_for(2).value
679 assert_equal '125', issue.custom_value_for(2).value
680 old_subject = issue.subject
680 old_subject = issue.subject
681 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
681 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
682
682
683 assert_difference('Journal.count') do
683 assert_difference('Journal.count') do
684 assert_difference('JournalDetail.count', 2) do
684 assert_difference('JournalDetail.count', 2) do
685 put :update, :id => 1, :issue => {:subject => new_subject,
685 put :update, :id => 1, :issue => {:subject => new_subject,
686 :priority_id => '6',
686 :priority_id => '6',
687 :category_id => '1' # no change
687 :category_id => '1' # no change
688 }
688 }
689 end
689 end
690 end
690 end
691 assert_redirected_to :action => 'show', :id => '1'
691 assert_redirected_to :action => 'show', :id => '1'
692 issue.reload
692 issue.reload
693 assert_equal new_subject, issue.subject
693 assert_equal new_subject, issue.subject
694 # Make sure custom fields were not cleared
694 # Make sure custom fields were not cleared
695 assert_equal '125', issue.custom_value_for(2).value
695 assert_equal '125', issue.custom_value_for(2).value
696
696
697 mail = ActionMailer::Base.deliveries.last
697 mail = ActionMailer::Base.deliveries.last
698 assert_kind_of TMail::Mail, mail
698 assert_kind_of TMail::Mail, mail
699 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
699 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
700 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
700 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
701 end
701 end
702
702
703 def test_put_update_with_custom_field_change
703 def test_put_update_with_custom_field_change
704 @request.session[:user_id] = 2
704 @request.session[:user_id] = 2
705 issue = Issue.find(1)
705 issue = Issue.find(1)
706 assert_equal '125', issue.custom_value_for(2).value
706 assert_equal '125', issue.custom_value_for(2).value
707
707
708 assert_difference('Journal.count') do
708 assert_difference('Journal.count') do
709 assert_difference('JournalDetail.count', 3) do
709 assert_difference('JournalDetail.count', 3) do
710 put :update, :id => 1, :issue => {:subject => 'Custom field change',
710 put :update, :id => 1, :issue => {:subject => 'Custom field change',
711 :priority_id => '6',
711 :priority_id => '6',
712 :category_id => '1', # no change
712 :category_id => '1', # no change
713 :custom_field_values => { '2' => 'New custom value' }
713 :custom_field_values => { '2' => 'New custom value' }
714 }
714 }
715 end
715 end
716 end
716 end
717 assert_redirected_to :action => 'show', :id => '1'
717 assert_redirected_to :action => 'show', :id => '1'
718 issue.reload
718 issue.reload
719 assert_equal 'New custom value', issue.custom_value_for(2).value
719 assert_equal 'New custom value', issue.custom_value_for(2).value
720
720
721 mail = ActionMailer::Base.deliveries.last
721 mail = ActionMailer::Base.deliveries.last
722 assert_kind_of TMail::Mail, mail
722 assert_kind_of TMail::Mail, mail
723 assert mail.body.include?("Searchable field changed from 125 to New custom value")
723 assert mail.body.include?("Searchable field changed from 125 to New custom value")
724 end
724 end
725
725
726 def test_put_update_with_status_and_assignee_change
726 def test_put_update_with_status_and_assignee_change
727 issue = Issue.find(1)
727 issue = Issue.find(1)
728 assert_equal 1, issue.status_id
728 assert_equal 1, issue.status_id
729 @request.session[:user_id] = 2
729 @request.session[:user_id] = 2
730 assert_difference('TimeEntry.count', 0) do
730 assert_difference('TimeEntry.count', 0) do
731 put :update,
731 put :update,
732 :id => 1,
732 :id => 1,
733 :issue => { :status_id => 2, :assigned_to_id => 3 },
733 :issue => { :status_id => 2, :assigned_to_id => 3 },
734 :notes => 'Assigned to dlopper',
734 :notes => 'Assigned to dlopper',
735 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
735 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
736 end
736 end
737 assert_redirected_to :action => 'show', :id => '1'
737 assert_redirected_to :action => 'show', :id => '1'
738 issue.reload
738 issue.reload
739 assert_equal 2, issue.status_id
739 assert_equal 2, issue.status_id
740 j = Journal.find(:first, :order => 'id DESC')
740 j = Journal.find(:first, :order => 'id DESC')
741 assert_equal 'Assigned to dlopper', j.notes
741 assert_equal 'Assigned to dlopper', j.notes
742 assert_equal 2, j.details.size
742 assert_equal 2, j.details.size
743
743
744 mail = ActionMailer::Base.deliveries.last
744 mail = ActionMailer::Base.deliveries.last
745 assert mail.body.include?("Status changed from New to Assigned")
745 assert mail.body.include?("Status changed from New to Assigned")
746 # subject should contain the new status
746 # subject should contain the new status
747 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
747 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
748 end
748 end
749
749
750 def test_put_update_with_note_only
750 def test_put_update_with_note_only
751 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
751 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
752 # anonymous user
752 # anonymous user
753 put :update,
753 put :update,
754 :id => 1,
754 :id => 1,
755 :notes => notes
755 :notes => notes
756 assert_redirected_to :action => 'show', :id => '1'
756 assert_redirected_to :action => 'show', :id => '1'
757 j = Journal.find(:first, :order => 'id DESC')
757 j = Journal.find(:first, :order => 'id DESC')
758 assert_equal notes, j.notes
758 assert_equal notes, j.notes
759 assert_equal 0, j.details.size
759 assert_equal 0, j.details.size
760 assert_equal User.anonymous, j.user
760 assert_equal User.anonymous, j.user
761
761
762 mail = ActionMailer::Base.deliveries.last
762 mail = ActionMailer::Base.deliveries.last
763 assert mail.body.include?(notes)
763 assert mail.body.include?(notes)
764 end
764 end
765
765
766 def test_put_update_with_note_and_spent_time
766 def test_put_update_with_note_and_spent_time
767 @request.session[:user_id] = 2
767 @request.session[:user_id] = 2
768 spent_hours_before = Issue.find(1).spent_hours
768 spent_hours_before = Issue.find(1).spent_hours
769 assert_difference('TimeEntry.count') do
769 assert_difference('TimeEntry.count') do
770 put :update,
770 put :update,
771 :id => 1,
771 :id => 1,
772 :notes => '2.5 hours added',
772 :notes => '2.5 hours added',
773 :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first }
773 :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first }
774 end
774 end
775 assert_redirected_to :action => 'show', :id => '1'
775 assert_redirected_to :action => 'show', :id => '1'
776
776
777 issue = Issue.find(1)
777 issue = Issue.find(1)
778
778
779 j = Journal.find(:first, :order => 'id DESC')
779 j = Journal.find(:first, :order => 'id DESC')
780 assert_equal '2.5 hours added', j.notes
780 assert_equal '2.5 hours added', j.notes
781 assert_equal 0, j.details.size
781 assert_equal 0, j.details.size
782
782
783 t = issue.time_entries.find(:first, :order => 'id DESC')
783 t = issue.time_entries.find(:first, :order => 'id DESC')
784 assert_not_nil t
784 assert_not_nil t
785 assert_equal 2.5, t.hours
785 assert_equal 2.5, t.hours
786 assert_equal spent_hours_before + 2.5, issue.spent_hours
786 assert_equal spent_hours_before + 2.5, issue.spent_hours
787 end
787 end
788
788
789 def test_put_update_with_attachment_only
789 def test_put_update_with_attachment_only
790 set_tmp_attachments_directory
790 set_tmp_attachments_directory
791
791
792 # Delete all fixtured journals, a race condition can occur causing the wrong
792 # Delete all fixtured journals, a race condition can occur causing the wrong
793 # journal to get fetched in the next find.
793 # journal to get fetched in the next find.
794 Journal.delete_all
794 Journal.delete_all
795
795
796 # anonymous user
796 # anonymous user
797 put :update,
797 put :update,
798 :id => 1,
798 :id => 1,
799 :notes => '',
799 :notes => '',
800 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
800 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
801 assert_redirected_to :action => 'show', :id => '1'
801 assert_redirected_to :action => 'show', :id => '1'
802 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
802 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
803 assert j.notes.blank?
803 assert j.notes.blank?
804 assert_equal 1, j.details.size
804 assert_equal 1, j.details.size
805 assert_equal 'testfile.txt', j.details.first.value
805 assert_equal 'testfile.txt', j.details.first.value
806 assert_equal User.anonymous, j.user
806 assert_equal User.anonymous, j.user
807
807
808 mail = ActionMailer::Base.deliveries.last
808 mail = ActionMailer::Base.deliveries.last
809 assert mail.body.include?('testfile.txt')
809 assert mail.body.include?('testfile.txt')
810 end
810 end
811
811
812 def test_put_update_with_attachment_that_fails_to_save
812 def test_put_update_with_attachment_that_fails_to_save
813 set_tmp_attachments_directory
813 set_tmp_attachments_directory
814
814
815 # Delete all fixtured journals, a race condition can occur causing the wrong
815 # Delete all fixtured journals, a race condition can occur causing the wrong
816 # journal to get fetched in the next find.
816 # journal to get fetched in the next find.
817 Journal.delete_all
817 Journal.delete_all
818
818
819 # Mock out the unsaved attachment
819 # Mock out the unsaved attachment
820 Attachment.any_instance.stubs(:create).returns(Attachment.new)
820 Attachment.any_instance.stubs(:create).returns(Attachment.new)
821
821
822 # anonymous user
822 # anonymous user
823 put :update,
823 put :update,
824 :id => 1,
824 :id => 1,
825 :notes => '',
825 :notes => '',
826 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
826 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
827 assert_redirected_to :action => 'show', :id => '1'
827 assert_redirected_to :action => 'show', :id => '1'
828 assert_equal '1 file(s) could not be saved.', flash[:warning]
828 assert_equal '1 file(s) could not be saved.', flash[:warning]
829
829
830 end if Object.const_defined?(:Mocha)
830 end if Object.const_defined?(:Mocha)
831
831
832 def test_put_update_with_no_change
832 def test_put_update_with_no_change
833 issue = Issue.find(1)
833 issue = Issue.find(1)
834 issue.journals.clear
834 issue.journals.clear
835 ActionMailer::Base.deliveries.clear
835 ActionMailer::Base.deliveries.clear
836
836
837 put :update,
837 put :update,
838 :id => 1,
838 :id => 1,
839 :notes => ''
839 :notes => ''
840 assert_redirected_to :action => 'show', :id => '1'
840 assert_redirected_to :action => 'show', :id => '1'
841
841
842 issue.reload
842 issue.reload
843 assert issue.journals.empty?
843 assert issue.journals.empty?
844 # No email should be sent
844 # No email should be sent
845 assert ActionMailer::Base.deliveries.empty?
845 assert ActionMailer::Base.deliveries.empty?
846 end
846 end
847
847
848 def test_put_update_should_send_a_notification
848 def test_put_update_should_send_a_notification
849 @request.session[:user_id] = 2
849 @request.session[:user_id] = 2
850 ActionMailer::Base.deliveries.clear
850 ActionMailer::Base.deliveries.clear
851 issue = Issue.find(1)
851 issue = Issue.find(1)
852 old_subject = issue.subject
852 old_subject = issue.subject
853 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
853 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
854
854
855 put :update, :id => 1, :issue => {:subject => new_subject,
855 put :update, :id => 1, :issue => {:subject => new_subject,
856 :priority_id => '6',
856 :priority_id => '6',
857 :category_id => '1' # no change
857 :category_id => '1' # no change
858 }
858 }
859 assert_equal 1, ActionMailer::Base.deliveries.size
859 assert_equal 1, ActionMailer::Base.deliveries.size
860 end
860 end
861
861
862 def test_put_update_with_invalid_spent_time
862 def test_put_update_with_invalid_spent_time
863 @request.session[:user_id] = 2
863 @request.session[:user_id] = 2
864 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
864 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
865
865
866 assert_no_difference('Journal.count') do
866 assert_no_difference('Journal.count') do
867 put :update,
867 put :update,
868 :id => 1,
868 :id => 1,
869 :notes => notes,
869 :notes => notes,
870 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
870 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
871 end
871 end
872 assert_response :success
872 assert_response :success
873 assert_template 'edit'
873 assert_template 'edit'
874
874
875 assert_tag :textarea, :attributes => { :name => 'notes' },
875 assert_tag :textarea, :attributes => { :name => 'notes' },
876 :content => notes
876 :content => notes
877 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
877 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
878 end
878 end
879
879
880 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
880 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
881 issue = Issue.find(2)
881 issue = Issue.find(2)
882 @request.session[:user_id] = 2
882 @request.session[:user_id] = 2
883
883
884 put :update,
884 put :update,
885 :id => issue.id,
885 :id => issue.id,
886 :issue => {
886 :issue => {
887 :fixed_version_id => 4
887 :fixed_version_id => 4
888 }
888 }
889
889
890 assert_response :redirect
890 assert_response :redirect
891 issue.reload
891 issue.reload
892 assert_equal 4, issue.fixed_version_id
892 assert_equal 4, issue.fixed_version_id
893 assert_not_equal issue.project_id, issue.fixed_version.project_id
893 assert_not_equal issue.project_id, issue.fixed_version.project_id
894 end
894 end
895
895
896 def test_put_update_should_redirect_back_using_the_back_url_parameter
896 def test_put_update_should_redirect_back_using_the_back_url_parameter
897 issue = Issue.find(2)
897 issue = Issue.find(2)
898 @request.session[:user_id] = 2
898 @request.session[:user_id] = 2
899
899
900 put :update,
900 put :update,
901 :id => issue.id,
901 :id => issue.id,
902 :issue => {
902 :issue => {
903 :fixed_version_id => 4
903 :fixed_version_id => 4
904 },
904 },
905 :back_url => '/issues'
905 :back_url => '/issues'
906
906
907 assert_response :redirect
907 assert_response :redirect
908 assert_redirected_to '/issues'
908 assert_redirected_to '/issues'
909 end
909 end
910
910
911 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
911 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
912 issue = Issue.find(2)
912 issue = Issue.find(2)
913 @request.session[:user_id] = 2
913 @request.session[:user_id] = 2
914
914
915 put :update,
915 put :update,
916 :id => issue.id,
916 :id => issue.id,
917 :issue => {
917 :issue => {
918 :fixed_version_id => 4
918 :fixed_version_id => 4
919 },
919 },
920 :back_url => 'http://google.com'
920 :back_url => 'http://google.com'
921
921
922 assert_response :redirect
922 assert_response :redirect
923 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
923 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
924 end
924 end
925
925
926 def test_get_bulk_edit
926 def test_get_bulk_edit
927 @request.session[:user_id] = 2
927 @request.session[:user_id] = 2
928 get :bulk_edit, :ids => [1, 2]
928 get :bulk_edit, :ids => [1, 2]
929 assert_response :success
929 assert_response :success
930 assert_template 'bulk_edit'
930 assert_template 'bulk_edit'
931
931
932 # Project specific custom field, date type
932 # Project specific custom field, date type
933 field = CustomField.find(9)
933 field = CustomField.find(9)
934 assert !field.is_for_all?
934 assert !field.is_for_all?
935 assert_equal 'date', field.field_format
935 assert_equal 'date', field.field_format
936 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
936 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
937
937
938 # System wide custom field
938 # System wide custom field
939 assert CustomField.find(1).is_for_all?
939 assert CustomField.find(1).is_for_all?
940 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
940 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
941 end
941 end
942
942
943 def test_bulk_edit
943 def test_bulk_edit
944 @request.session[:user_id] = 2
944 @request.session[:user_id] = 2
945 # update issues priority
945 # update issues priority
946 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing',
946 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing',
947 :issue => {:priority_id => 7,
947 :issue => {:priority_id => 7,
948 :assigned_to_id => '',
948 :assigned_to_id => '',
949 :custom_field_values => {'2' => ''}}
949 :custom_field_values => {'2' => ''}}
950
950
951 assert_response 302
951 assert_response 302
952 # check that the issues were updated
952 # check that the issues were updated
953 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
953 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
954
954
955 issue = Issue.find(1)
955 issue = Issue.find(1)
956 journal = issue.journals.find(:first, :order => 'created_on DESC')
956 journal = issue.journals.find(:first, :order => 'created_on DESC')
957 assert_equal '125', issue.custom_value_for(2).value
957 assert_equal '125', issue.custom_value_for(2).value
958 assert_equal 'Bulk editing', journal.notes
958 assert_equal 'Bulk editing', journal.notes
959 assert_equal 1, journal.details.size
959 assert_equal 1, journal.details.size
960 end
960 end
961
961
962 def test_bullk_edit_should_send_a_notification
962 def test_bullk_edit_should_send_a_notification
963 @request.session[:user_id] = 2
963 @request.session[:user_id] = 2
964 ActionMailer::Base.deliveries.clear
964 ActionMailer::Base.deliveries.clear
965 post(:bulk_edit,
965 post(:bulk_edit,
966 {
966 {
967 :ids => [1, 2],
967 :ids => [1, 2],
968 :notes => 'Bulk editing',
968 :notes => 'Bulk editing',
969 :issue => {
969 :issue => {
970 :priority_id => 7,
970 :priority_id => 7,
971 :assigned_to_id => '',
971 :assigned_to_id => '',
972 :custom_field_values => {'2' => ''}
972 :custom_field_values => {'2' => ''}
973 }
973 }
974 })
974 })
975
975
976 assert_response 302
976 assert_response 302
977 assert_equal 2, ActionMailer::Base.deliveries.size
977 assert_equal 2, ActionMailer::Base.deliveries.size
978 end
978 end
979
979
980 def test_bulk_edit_status
980 def test_bulk_edit_status
981 @request.session[:user_id] = 2
981 @request.session[:user_id] = 2
982 # update issues priority
982 # update issues priority
983 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing status',
983 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing status',
984 :issue => {:priority_id => '',
984 :issue => {:priority_id => '',
985 :assigned_to_id => '',
985 :assigned_to_id => '',
986 :status_id => '5'}
986 :status_id => '5'}
987
987
988 assert_response 302
988 assert_response 302
989 issue = Issue.find(1)
989 issue = Issue.find(1)
990 assert issue.closed?
990 assert issue.closed?
991 end
991 end
992
992
993 def test_bulk_edit_custom_field
993 def test_bulk_edit_custom_field
994 @request.session[:user_id] = 2
994 @request.session[:user_id] = 2
995 # update issues priority
995 # update issues priority
996 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing custom field',
996 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk editing custom field',
997 :issue => {:priority_id => '',
997 :issue => {:priority_id => '',
998 :assigned_to_id => '',
998 :assigned_to_id => '',
999 :custom_field_values => {'2' => '777'}}
999 :custom_field_values => {'2' => '777'}}
1000
1000
1001 assert_response 302
1001 assert_response 302
1002
1002
1003 issue = Issue.find(1)
1003 issue = Issue.find(1)
1004 journal = issue.journals.find(:first, :order => 'created_on DESC')
1004 journal = issue.journals.find(:first, :order => 'created_on DESC')
1005 assert_equal '777', issue.custom_value_for(2).value
1005 assert_equal '777', issue.custom_value_for(2).value
1006 assert_equal 1, journal.details.size
1006 assert_equal 1, journal.details.size
1007 assert_equal '125', journal.details.first.old_value
1007 assert_equal '125', journal.details.first.old_value
1008 assert_equal '777', journal.details.first.value
1008 assert_equal '777', journal.details.first.value
1009 end
1009 end
1010
1010
1011 def test_bulk_unassign
1011 def test_bulk_unassign
1012 assert_not_nil Issue.find(2).assigned_to
1012 assert_not_nil Issue.find(2).assigned_to
1013 @request.session[:user_id] = 2
1013 @request.session[:user_id] = 2
1014 # unassign issues
1014 # unassign issues
1015 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1015 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1016 assert_response 302
1016 assert_response 302
1017 # check that the issues were updated
1017 # check that the issues were updated
1018 assert_nil Issue.find(2).assigned_to
1018 assert_nil Issue.find(2).assigned_to
1019 end
1019 end
1020
1020
1021 def test_post_bulk_edit_should_allow_fixed_version_to_be_set_to_a_subproject
1021 def test_post_bulk_edit_should_allow_fixed_version_to_be_set_to_a_subproject
1022 @request.session[:user_id] = 2
1022 @request.session[:user_id] = 2
1023
1023
1024 post :bulk_edit, :ids => [1,2], :issue => {:fixed_version_id => 4}
1024 post :bulk_edit, :ids => [1,2], :issue => {:fixed_version_id => 4}
1025
1025
1026 assert_response :redirect
1026 assert_response :redirect
1027 issues = Issue.find([1,2])
1027 issues = Issue.find([1,2])
1028 issues.each do |issue|
1028 issues.each do |issue|
1029 assert_equal 4, issue.fixed_version_id
1029 assert_equal 4, issue.fixed_version_id
1030 assert_not_equal issue.project_id, issue.fixed_version.project_id
1030 assert_not_equal issue.project_id, issue.fixed_version.project_id
1031 end
1031 end
1032 end
1032 end
1033
1033
1034 def test_post_bulk_edit_should_redirect_back_using_the_back_url_parameter
1034 def test_post_bulk_edit_should_redirect_back_using_the_back_url_parameter
1035 @request.session[:user_id] = 2
1035 @request.session[:user_id] = 2
1036 post :bulk_edit, :ids => [1,2], :back_url => '/issues'
1036 post :bulk_edit, :ids => [1,2], :back_url => '/issues'
1037
1037
1038 assert_response :redirect
1038 assert_response :redirect
1039 assert_redirected_to '/issues'
1039 assert_redirected_to '/issues'
1040 end
1040 end
1041
1041
1042 def test_post_bulk_edit_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1042 def test_post_bulk_edit_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1043 @request.session[:user_id] = 2
1043 @request.session[:user_id] = 2
1044 post :bulk_edit, :ids => [1,2], :back_url => 'http://google.com'
1044 post :bulk_edit, :ids => [1,2], :back_url => 'http://google.com'
1045
1045
1046 assert_response :redirect
1046 assert_response :redirect
1047 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1047 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1048 end
1048 end
1049
1049
1050 def test_move_one_issue_to_another_project
1050 def test_move_one_issue_to_another_project
1051 @request.session[:user_id] = 2
1051 @request.session[:user_id] = 2
1052 post :move, :id => 1, :new_project_id => 2, :tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
1052 post :move, :id => 1, :new_project_id => 2, :tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
1053 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1053 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1054 assert_equal 2, Issue.find(1).project_id
1054 assert_equal 2, Issue.find(1).project_id
1055 end
1055 end
1056
1056
1057 def test_move_one_issue_to_another_project_should_follow_when_needed
1057 def test_move_one_issue_to_another_project_should_follow_when_needed
1058 @request.session[:user_id] = 2
1058 @request.session[:user_id] = 2
1059 post :move, :id => 1, :new_project_id => 2, :follow => '1'
1059 post :move, :id => 1, :new_project_id => 2, :follow => '1'
1060 assert_redirected_to '/issues/1'
1060 assert_redirected_to '/issues/1'
1061 end
1061 end
1062
1062
1063 def test_bulk_move_to_another_project
1063 def test_bulk_move_to_another_project
1064 @request.session[:user_id] = 2
1064 @request.session[:user_id] = 2
1065 post :move, :ids => [1, 2], :new_project_id => 2
1065 post :move, :ids => [1, 2], :new_project_id => 2
1066 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1066 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1067 # Issues moved to project 2
1067 # Issues moved to project 2
1068 assert_equal 2, Issue.find(1).project_id
1068 assert_equal 2, Issue.find(1).project_id
1069 assert_equal 2, Issue.find(2).project_id
1069 assert_equal 2, Issue.find(2).project_id
1070 # No tracker change
1070 # No tracker change
1071 assert_equal 1, Issue.find(1).tracker_id
1071 assert_equal 1, Issue.find(1).tracker_id
1072 assert_equal 2, Issue.find(2).tracker_id
1072 assert_equal 2, Issue.find(2).tracker_id
1073 end
1073 end
1074
1074
1075 def test_bulk_move_to_another_tracker
1075 def test_bulk_move_to_another_tracker
1076 @request.session[:user_id] = 2
1076 @request.session[:user_id] = 2
1077 post :move, :ids => [1, 2], :new_tracker_id => 2
1077 post :move, :ids => [1, 2], :new_tracker_id => 2
1078 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1078 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1079 assert_equal 2, Issue.find(1).tracker_id
1079 assert_equal 2, Issue.find(1).tracker_id
1080 assert_equal 2, Issue.find(2).tracker_id
1080 assert_equal 2, Issue.find(2).tracker_id
1081 end
1081 end
1082
1082
1083 def test_bulk_copy_to_another_project
1083 def test_bulk_copy_to_another_project
1084 @request.session[:user_id] = 2
1084 @request.session[:user_id] = 2
1085 assert_difference 'Issue.count', 2 do
1085 assert_difference 'Issue.count', 2 do
1086 assert_no_difference 'Project.find(1).issues.count' do
1086 assert_no_difference 'Project.find(1).issues.count' do
1087 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
1087 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
1088 end
1088 end
1089 end
1089 end
1090 assert_redirected_to 'projects/ecookbook/issues'
1090 assert_redirected_to 'projects/ecookbook/issues'
1091 end
1091 end
1092
1092
1093 context "#move via bulk copy" do
1093 context "#move via bulk copy" do
1094 should "allow not changing the issue's attributes" do
1094 should "allow not changing the issue's attributes" do
1095 @request.session[:user_id] = 2
1095 @request.session[:user_id] = 2
1096 issue_before_move = Issue.find(1)
1096 issue_before_move = Issue.find(1)
1097 assert_difference 'Issue.count', 1 do
1097 assert_difference 'Issue.count', 1 do
1098 assert_no_difference 'Project.find(1).issues.count' do
1098 assert_no_difference 'Project.find(1).issues.count' do
1099 post :move, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
1099 post :move, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => '', :status_id => '', :start_date => '', :due_date => ''
1100 end
1100 end
1101 end
1101 end
1102 issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
1102 issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
1103 assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
1103 assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
1104 assert_equal issue_before_move.status_id, issue_after_move.status_id
1104 assert_equal issue_before_move.status_id, issue_after_move.status_id
1105 assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
1105 assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
1106 end
1106 end
1107
1107
1108 should "allow changing the issue's attributes" do
1108 should "allow changing the issue's attributes" do
1109 @request.session[:user_id] = 2
1109 @request.session[:user_id] = 2
1110 assert_difference 'Issue.count', 2 do
1110 assert_difference 'Issue.count', 2 do
1111 assert_no_difference 'Project.find(1).issues.count' do
1111 assert_no_difference 'Project.find(1).issues.count' do
1112 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => 4, :status_id => 3, :start_date => '2009-12-01', :due_date => '2009-12-31'
1112 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}, :new_tracker_id => '', :assigned_to_id => 4, :status_id => 3, :start_date => '2009-12-01', :due_date => '2009-12-31'
1113 end
1113 end
1114 end
1114 end
1115
1115
1116 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
1116 copied_issues = Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
1117 assert_equal 2, copied_issues.size
1117 assert_equal 2, copied_issues.size
1118 copied_issues.each do |issue|
1118 copied_issues.each do |issue|
1119 assert_equal 2, issue.project_id, "Project is incorrect"
1119 assert_equal 2, issue.project_id, "Project is incorrect"
1120 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
1120 assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
1121 assert_equal 3, issue.status_id, "Status is incorrect"
1121 assert_equal 3, issue.status_id, "Status is incorrect"
1122 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
1122 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
1123 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
1123 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
1124 end
1124 end
1125 end
1125 end
1126 end
1126 end
1127
1127
1128 def test_copy_to_another_project_should_follow_when_needed
1128 def test_copy_to_another_project_should_follow_when_needed
1129 @request.session[:user_id] = 2
1129 @request.session[:user_id] = 2
1130 post :move, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :follow => '1'
1130 post :move, :ids => [1], :new_project_id => 2, :copy_options => {:copy => '1'}, :follow => '1'
1131 issue = Issue.first(:order => 'id DESC')
1131 issue = Issue.first(:order => 'id DESC')
1132 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1132 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1133 end
1133 end
1134
1134
1135 def test_context_menu_one_issue
1135 def test_context_menu_one_issue
1136 @request.session[:user_id] = 2
1136 @request.session[:user_id] = 2
1137 get :context_menu, :ids => [1]
1137 get :context_menu, :ids => [1]
1138 assert_response :success
1138 assert_response :success
1139 assert_template 'context_menu'
1139 assert_template 'context_menu'
1140 assert_tag :tag => 'a', :content => 'Edit',
1140 assert_tag :tag => 'a', :content => 'Edit',
1141 :attributes => { :href => '/issues/1/edit',
1141 :attributes => { :href => '/issues/1/edit',
1142 :class => 'icon-edit' }
1142 :class => 'icon-edit' }
1143 assert_tag :tag => 'a', :content => 'Closed',
1143 assert_tag :tag => 'a', :content => 'Closed',
1144 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
1144 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
1145 :class => '' }
1145 :class => '' }
1146 assert_tag :tag => 'a', :content => 'Immediate',
1146 assert_tag :tag => 'a', :content => 'Immediate',
1147 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
1147 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
1148 :class => '' }
1148 :class => '' }
1149 # Versions
1149 # Versions
1150 assert_tag :tag => 'a', :content => '2.0',
1150 assert_tag :tag => 'a', :content => '2.0',
1151 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
1151 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
1152 :class => '' }
1152 :class => '' }
1153 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
1153 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
1154 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
1154 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
1155 :class => '' }
1155 :class => '' }
1156
1156
1157 assert_tag :tag => 'a', :content => 'Dave Lopper',
1157 assert_tag :tag => 'a', :content => 'Dave Lopper',
1158 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
1158 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
1159 :class => '' }
1159 :class => '' }
1160 assert_tag :tag => 'a', :content => 'Duplicate',
1160 assert_tag :tag => 'a', :content => 'Duplicate',
1161 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
1161 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
1162 :class => 'icon-duplicate' }
1162 :class => 'icon-duplicate' }
1163 assert_tag :tag => 'a', :content => 'Copy',
1163 assert_tag :tag => 'a', :content => 'Copy',
1164 :attributes => { :href => '/issues/move?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
1164 :attributes => { :href => '/issues/move?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
1165 :class => 'icon-copy' }
1165 :class => 'icon-copy' }
1166 assert_tag :tag => 'a', :content => 'Move',
1166 assert_tag :tag => 'a', :content => 'Move',
1167 :attributes => { :href => '/issues/move?ids%5B%5D=1',
1167 :attributes => { :href => '/issues/move?ids%5B%5D=1',
1168 :class => 'icon-move' }
1168 :class => 'icon-move' }
1169 assert_tag :tag => 'a', :content => 'Delete',
1169 assert_tag :tag => 'a', :content => 'Delete',
1170 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
1170 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
1171 :class => 'icon-del' }
1171 :class => 'icon-del' }
1172 end
1172 end
1173
1173
1174 def test_context_menu_one_issue_by_anonymous
1174 def test_context_menu_one_issue_by_anonymous
1175 get :context_menu, :ids => [1]
1175 get :context_menu, :ids => [1]
1176 assert_response :success
1176 assert_response :success
1177 assert_template 'context_menu'
1177 assert_template 'context_menu'
1178 assert_tag :tag => 'a', :content => 'Delete',
1178 assert_tag :tag => 'a', :content => 'Delete',
1179 :attributes => { :href => '#',
1179 :attributes => { :href => '#',
1180 :class => 'icon-del disabled' }
1180 :class => 'icon-del disabled' }
1181 end
1181 end
1182
1182
1183 def test_context_menu_multiple_issues_of_same_project
1183 def test_context_menu_multiple_issues_of_same_project
1184 @request.session[:user_id] = 2
1184 @request.session[:user_id] = 2
1185 get :context_menu, :ids => [1, 2]
1185 get :context_menu, :ids => [1, 2]
1186 assert_response :success
1186 assert_response :success
1187 assert_template 'context_menu'
1187 assert_template 'context_menu'
1188 assert_tag :tag => 'a', :content => 'Edit',
1188 assert_tag :tag => 'a', :content => 'Edit',
1189 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
1189 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
1190 :class => 'icon-edit' }
1190 :class => 'icon-edit' }
1191 assert_tag :tag => 'a', :content => 'Immediate',
1191 assert_tag :tag => 'a', :content => 'Immediate',
1192 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bpriority_id%5D=8',
1192 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bpriority_id%5D=8',
1193 :class => '' }
1193 :class => '' }
1194 assert_tag :tag => 'a', :content => 'Dave Lopper',
1194 assert_tag :tag => 'a', :content => 'Dave Lopper',
1195 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bassigned_to_id%5D=3',
1195 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bassigned_to_id%5D=3',
1196 :class => '' }
1196 :class => '' }
1197 assert_tag :tag => 'a', :content => 'Copy',
1197 assert_tag :tag => 'a', :content => 'Copy',
1198 :attributes => { :href => '/issues/move?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
1198 :attributes => { :href => '/issues/move?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
1199 :class => 'icon-copy' }
1199 :class => 'icon-copy' }
1200 assert_tag :tag => 'a', :content => 'Move',
1200 assert_tag :tag => 'a', :content => 'Move',
1201 :attributes => { :href => '/issues/move?ids%5B%5D=1&amp;ids%5B%5D=2',
1201 :attributes => { :href => '/issues/move?ids%5B%5D=1&amp;ids%5B%5D=2',
1202 :class => 'icon-move' }
1202 :class => 'icon-move' }
1203 assert_tag :tag => 'a', :content => 'Delete',
1203 assert_tag :tag => 'a', :content => 'Delete',
1204 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
1204 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
1205 :class => 'icon-del' }
1205 :class => 'icon-del' }
1206 end
1206 end
1207
1207
1208 def test_context_menu_multiple_issues_of_different_project
1208 def test_context_menu_multiple_issues_of_different_project
1209 @request.session[:user_id] = 2
1209 @request.session[:user_id] = 2
1210 get :context_menu, :ids => [1, 2, 4]
1210 get :context_menu, :ids => [1, 2, 4]
1211 assert_response :success
1211 assert_response :success
1212 assert_template 'context_menu'
1212 assert_template 'context_menu'
1213 assert_tag :tag => 'a', :content => 'Delete',
1213 assert_tag :tag => 'a', :content => 'Delete',
1214 :attributes => { :href => '#',
1214 :attributes => { :href => '#',
1215 :class => 'icon-del disabled' }
1215 :class => 'icon-del disabled' }
1216 end
1216 end
1217
1217
1218 def test_destroy_issue_with_no_time_entries
1218 def test_destroy_issue_with_no_time_entries
1219 assert_nil TimeEntry.find_by_issue_id(2)
1219 assert_nil TimeEntry.find_by_issue_id(2)
1220 @request.session[:user_id] = 2
1220 @request.session[:user_id] = 2
1221 post :destroy, :id => 2
1221 post :destroy, :id => 2
1222 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1222 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1223 assert_nil Issue.find_by_id(2)
1223 assert_nil Issue.find_by_id(2)
1224 end
1224 end
1225
1225
1226 def test_destroy_issues_with_time_entries
1226 def test_destroy_issues_with_time_entries
1227 @request.session[:user_id] = 2
1227 @request.session[:user_id] = 2
1228 post :destroy, :ids => [1, 3]
1228 post :destroy, :ids => [1, 3]
1229 assert_response :success
1229 assert_response :success
1230 assert_template 'destroy'
1230 assert_template 'destroy'
1231 assert_not_nil assigns(:hours)
1231 assert_not_nil assigns(:hours)
1232 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1232 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1233 end
1233 end
1234
1234
1235 def test_destroy_issues_and_destroy_time_entries
1235 def test_destroy_issues_and_destroy_time_entries
1236 @request.session[:user_id] = 2
1236 @request.session[:user_id] = 2
1237 post :destroy, :ids => [1, 3], :todo => 'destroy'
1237 post :destroy, :ids => [1, 3], :todo => 'destroy'
1238 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1238 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1239 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1239 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1240 assert_nil TimeEntry.find_by_id([1, 2])
1240 assert_nil TimeEntry.find_by_id([1, 2])
1241 end
1241 end
1242
1242
1243 def test_destroy_issues_and_assign_time_entries_to_project
1243 def test_destroy_issues_and_assign_time_entries_to_project
1244 @request.session[:user_id] = 2
1244 @request.session[:user_id] = 2
1245 post :destroy, :ids => [1, 3], :todo => 'nullify'
1245 post :destroy, :ids => [1, 3], :todo => 'nullify'
1246 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1246 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1247 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1247 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1248 assert_nil TimeEntry.find(1).issue_id
1248 assert_nil TimeEntry.find(1).issue_id
1249 assert_nil TimeEntry.find(2).issue_id
1249 assert_nil TimeEntry.find(2).issue_id
1250 end
1250 end
1251
1251
1252 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1252 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1253 @request.session[:user_id] = 2
1253 @request.session[:user_id] = 2
1254 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1254 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1255 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1255 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1256 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1256 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1257 assert_equal 2, TimeEntry.find(1).issue_id
1257 assert_equal 2, TimeEntry.find(1).issue_id
1258 assert_equal 2, TimeEntry.find(2).issue_id
1258 assert_equal 2, TimeEntry.find(2).issue_id
1259 end
1259 end
1260
1260
1261 def test_default_search_scope
1261 def test_default_search_scope
1262 get :index
1262 get :index
1263 assert_tag :div, :attributes => {:id => 'quick-search'},
1263 assert_tag :div, :attributes => {:id => 'quick-search'},
1264 :child => {:tag => 'form',
1264 :child => {:tag => 'form',
1265 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
1265 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
1266 end
1266 end
1267 end
1267 end
General Comments 0
You need to be logged in to leave comments. Login now