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