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