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