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