##// END OF EJS Templates
Merged r15608 (#23206)....
Jean-Philippe Lang -
r15231:3cbbba85134b
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_related_issues
28 group = :label_related_issues
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,4557 +1,4568
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,
22 :users, :email_addresses,
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 header.include?(status)
614 assert header.include?(status)
604 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
615 issue_line = lines.find {|l| l =~ /^#{issue.id},/}
605 assert issue_line.include?(str_big5)
616 assert issue_line.include?(str_big5)
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_show_by_anonymous
1087 def test_show_by_anonymous
1077 get :show, :id => 1
1088 get :show, :id => 1
1078 assert_response :success
1089 assert_response :success
1079 assert_template 'show'
1090 assert_template 'show'
1080 assert_equal Issue.find(1), assigns(:issue)
1091 assert_equal Issue.find(1), assigns(:issue)
1081 assert_select 'div.issue div.description', :text => /Unable to print recipes/
1092 assert_select 'div.issue div.description', :text => /Unable to print recipes/
1082 # anonymous role is allowed to add a note
1093 # anonymous role is allowed to add a note
1083 assert_select 'form#issue-form' do
1094 assert_select 'form#issue-form' do
1084 assert_select 'fieldset' do
1095 assert_select 'fieldset' do
1085 assert_select 'legend', :text => 'Notes'
1096 assert_select 'legend', :text => 'Notes'
1086 assert_select 'textarea[name=?]', 'issue[notes]'
1097 assert_select 'textarea[name=?]', 'issue[notes]'
1087 end
1098 end
1088 end
1099 end
1089 assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
1100 assert_select 'title', :text => "Bug #1: Cannot print recipes - eCookbook - Redmine"
1090 end
1101 end
1091
1102
1092 def test_show_by_manager
1103 def test_show_by_manager
1093 @request.session[:user_id] = 2
1104 @request.session[:user_id] = 2
1094 get :show, :id => 1
1105 get :show, :id => 1
1095 assert_response :success
1106 assert_response :success
1096 assert_select 'a', :text => /Quote/
1107 assert_select 'a', :text => /Quote/
1097 assert_select 'form#issue-form' do
1108 assert_select 'form#issue-form' do
1098 assert_select 'fieldset' do
1109 assert_select 'fieldset' do
1099 assert_select 'legend', :text => 'Change properties'
1110 assert_select 'legend', :text => 'Change properties'
1100 assert_select 'input[name=?]', 'issue[subject]'
1111 assert_select 'input[name=?]', 'issue[subject]'
1101 end
1112 end
1102 assert_select 'fieldset' do
1113 assert_select 'fieldset' do
1103 assert_select 'legend', :text => 'Log time'
1114 assert_select 'legend', :text => 'Log time'
1104 assert_select 'input[name=?]', 'time_entry[hours]'
1115 assert_select 'input[name=?]', 'time_entry[hours]'
1105 end
1116 end
1106 assert_select 'fieldset' do
1117 assert_select 'fieldset' do
1107 assert_select 'legend', :text => 'Notes'
1118 assert_select 'legend', :text => 'Notes'
1108 assert_select 'textarea[name=?]', 'issue[notes]'
1119 assert_select 'textarea[name=?]', 'issue[notes]'
1109 end
1120 end
1110 end
1121 end
1111 end
1122 end
1112
1123
1113 def test_show_should_display_update_form
1124 def test_show_should_display_update_form
1114 @request.session[:user_id] = 2
1125 @request.session[:user_id] = 2
1115 get :show, :id => 1
1126 get :show, :id => 1
1116 assert_response :success
1127 assert_response :success
1117
1128
1118 assert_select 'form#issue-form' do
1129 assert_select 'form#issue-form' do
1119 assert_select 'input[name=?]', 'issue[is_private]'
1130 assert_select 'input[name=?]', 'issue[is_private]'
1120 assert_select 'select[name=?]', 'issue[project_id]'
1131 assert_select 'select[name=?]', 'issue[project_id]'
1121 assert_select 'select[name=?]', 'issue[tracker_id]'
1132 assert_select 'select[name=?]', 'issue[tracker_id]'
1122 assert_select 'input[name=?]', 'issue[subject]'
1133 assert_select 'input[name=?]', 'issue[subject]'
1123 assert_select 'textarea[name=?]', 'issue[description]'
1134 assert_select 'textarea[name=?]', 'issue[description]'
1124 assert_select 'select[name=?]', 'issue[status_id]'
1135 assert_select 'select[name=?]', 'issue[status_id]'
1125 assert_select 'select[name=?]', 'issue[priority_id]'
1136 assert_select 'select[name=?]', 'issue[priority_id]'
1126 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1137 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1127 assert_select 'select[name=?]', 'issue[category_id]'
1138 assert_select 'select[name=?]', 'issue[category_id]'
1128 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1139 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1129 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1140 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1130 assert_select 'input[name=?]', 'issue[start_date]'
1141 assert_select 'input[name=?]', 'issue[start_date]'
1131 assert_select 'input[name=?]', 'issue[due_date]'
1142 assert_select 'input[name=?]', 'issue[due_date]'
1132 assert_select 'select[name=?]', 'issue[done_ratio]'
1143 assert_select 'select[name=?]', 'issue[done_ratio]'
1133 assert_select 'input[name=?]', 'issue[custom_field_values][2]'
1144 assert_select 'input[name=?]', 'issue[custom_field_values][2]'
1134 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1145 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1135 assert_select 'textarea[name=?]', 'issue[notes]'
1146 assert_select 'textarea[name=?]', 'issue[notes]'
1136 end
1147 end
1137 end
1148 end
1138
1149
1139 def test_show_should_display_update_form_with_minimal_permissions
1150 def test_show_should_display_update_form_with_minimal_permissions
1140 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
1151 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
1141 WorkflowTransition.delete_all :role_id => 1
1152 WorkflowTransition.delete_all :role_id => 1
1142
1153
1143 @request.session[:user_id] = 2
1154 @request.session[:user_id] = 2
1144 get :show, :id => 1
1155 get :show, :id => 1
1145 assert_response :success
1156 assert_response :success
1146
1157
1147 assert_select 'form#issue-form' do
1158 assert_select 'form#issue-form' do
1148 assert_select 'input[name=?]', 'issue[is_private]', 0
1159 assert_select 'input[name=?]', 'issue[is_private]', 0
1149 assert_select 'select[name=?]', 'issue[project_id]', 0
1160 assert_select 'select[name=?]', 'issue[project_id]', 0
1150 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1161 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1151 assert_select 'input[name=?]', 'issue[subject]', 0
1162 assert_select 'input[name=?]', 'issue[subject]', 0
1152 assert_select 'textarea[name=?]', 'issue[description]', 0
1163 assert_select 'textarea[name=?]', 'issue[description]', 0
1153 assert_select 'select[name=?]', 'issue[status_id]', 0
1164 assert_select 'select[name=?]', 'issue[status_id]', 0
1154 assert_select 'select[name=?]', 'issue[priority_id]', 0
1165 assert_select 'select[name=?]', 'issue[priority_id]', 0
1155 assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
1166 assert_select 'select[name=?]', 'issue[assigned_to_id]', 0
1156 assert_select 'select[name=?]', 'issue[category_id]', 0
1167 assert_select 'select[name=?]', 'issue[category_id]', 0
1157 assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
1168 assert_select 'select[name=?]', 'issue[fixed_version_id]', 0
1158 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1169 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1159 assert_select 'input[name=?]', 'issue[start_date]', 0
1170 assert_select 'input[name=?]', 'issue[start_date]', 0
1160 assert_select 'input[name=?]', 'issue[due_date]', 0
1171 assert_select 'input[name=?]', 'issue[due_date]', 0
1161 assert_select 'select[name=?]', 'issue[done_ratio]', 0
1172 assert_select 'select[name=?]', 'issue[done_ratio]', 0
1162 assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
1173 assert_select 'input[name=?]', 'issue[custom_field_values][2]', 0
1163 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1174 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1164 assert_select 'textarea[name=?]', 'issue[notes]'
1175 assert_select 'textarea[name=?]', 'issue[notes]'
1165 end
1176 end
1166 end
1177 end
1167
1178
1168 def test_show_should_not_display_update_form_without_permissions
1179 def test_show_should_not_display_update_form_without_permissions
1169 Role.find(1).update_attribute :permissions, [:view_issues]
1180 Role.find(1).update_attribute :permissions, [:view_issues]
1170
1181
1171 @request.session[:user_id] = 2
1182 @request.session[:user_id] = 2
1172 get :show, :id => 1
1183 get :show, :id => 1
1173 assert_response :success
1184 assert_response :success
1174
1185
1175 assert_select 'form#issue-form', 0
1186 assert_select 'form#issue-form', 0
1176 end
1187 end
1177
1188
1178 def test_update_form_should_not_display_inactive_enumerations
1189 def test_update_form_should_not_display_inactive_enumerations
1179 assert !IssuePriority.find(15).active?
1190 assert !IssuePriority.find(15).active?
1180
1191
1181 @request.session[:user_id] = 2
1192 @request.session[:user_id] = 2
1182 get :show, :id => 1
1193 get :show, :id => 1
1183 assert_response :success
1194 assert_response :success
1184
1195
1185 assert_select 'form#issue-form' do
1196 assert_select 'form#issue-form' do
1186 assert_select 'select[name=?]', 'issue[priority_id]' do
1197 assert_select 'select[name=?]', 'issue[priority_id]' do
1187 assert_select 'option[value="4"]'
1198 assert_select 'option[value="4"]'
1188 assert_select 'option[value="15"]', 0
1199 assert_select 'option[value="15"]', 0
1189 end
1200 end
1190 end
1201 end
1191 end
1202 end
1192
1203
1193 def test_update_form_should_allow_attachment_upload
1204 def test_update_form_should_allow_attachment_upload
1194 @request.session[:user_id] = 2
1205 @request.session[:user_id] = 2
1195 get :show, :id => 1
1206 get :show, :id => 1
1196
1207
1197 assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
1208 assert_select 'form#issue-form[method=post][enctype="multipart/form-data"]' do
1198 assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
1209 assert_select 'input[type=file][name=?]', 'attachments[dummy][file]'
1199 end
1210 end
1200 end
1211 end
1201
1212
1202 def test_show_should_deny_anonymous_access_without_permission
1213 def test_show_should_deny_anonymous_access_without_permission
1203 Role.anonymous.remove_permission!(:view_issues)
1214 Role.anonymous.remove_permission!(:view_issues)
1204 get :show, :id => 1
1215 get :show, :id => 1
1205 assert_response :redirect
1216 assert_response :redirect
1206 end
1217 end
1207
1218
1208 def test_show_should_deny_anonymous_access_to_private_issue
1219 def test_show_should_deny_anonymous_access_to_private_issue
1209 Issue.where(:id => 1).update_all(["is_private = ?", true])
1220 Issue.where(:id => 1).update_all(["is_private = ?", true])
1210 get :show, :id => 1
1221 get :show, :id => 1
1211 assert_response :redirect
1222 assert_response :redirect
1212 end
1223 end
1213
1224
1214 def test_show_should_deny_non_member_access_without_permission
1225 def test_show_should_deny_non_member_access_without_permission
1215 Role.non_member.remove_permission!(:view_issues)
1226 Role.non_member.remove_permission!(:view_issues)
1216 @request.session[:user_id] = 9
1227 @request.session[:user_id] = 9
1217 get :show, :id => 1
1228 get :show, :id => 1
1218 assert_response 403
1229 assert_response 403
1219 end
1230 end
1220
1231
1221 def test_show_should_deny_non_member_access_to_private_issue
1232 def test_show_should_deny_non_member_access_to_private_issue
1222 Issue.where(:id => 1).update_all(["is_private = ?", true])
1233 Issue.where(:id => 1).update_all(["is_private = ?", true])
1223 @request.session[:user_id] = 9
1234 @request.session[:user_id] = 9
1224 get :show, :id => 1
1235 get :show, :id => 1
1225 assert_response 403
1236 assert_response 403
1226 end
1237 end
1227
1238
1228 def test_show_should_deny_member_access_without_permission
1239 def test_show_should_deny_member_access_without_permission
1229 Role.find(1).remove_permission!(:view_issues)
1240 Role.find(1).remove_permission!(:view_issues)
1230 @request.session[:user_id] = 2
1241 @request.session[:user_id] = 2
1231 get :show, :id => 1
1242 get :show, :id => 1
1232 assert_response 403
1243 assert_response 403
1233 end
1244 end
1234
1245
1235 def test_show_should_deny_member_access_to_private_issue_without_permission
1246 def test_show_should_deny_member_access_to_private_issue_without_permission
1236 Issue.where(:id => 1).update_all(["is_private = ?", true])
1247 Issue.where(:id => 1).update_all(["is_private = ?", true])
1237 @request.session[:user_id] = 3
1248 @request.session[:user_id] = 3
1238 get :show, :id => 1
1249 get :show, :id => 1
1239 assert_response 403
1250 assert_response 403
1240 end
1251 end
1241
1252
1242 def test_show_should_allow_author_access_to_private_issue
1253 def test_show_should_allow_author_access_to_private_issue
1243 Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
1254 Issue.where(:id => 1).update_all(["is_private = ?, author_id = 3", true])
1244 @request.session[:user_id] = 3
1255 @request.session[:user_id] = 3
1245 get :show, :id => 1
1256 get :show, :id => 1
1246 assert_response :success
1257 assert_response :success
1247 end
1258 end
1248
1259
1249 def test_show_should_allow_assignee_access_to_private_issue
1260 def test_show_should_allow_assignee_access_to_private_issue
1250 Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
1261 Issue.where(:id => 1).update_all(["is_private = ?, assigned_to_id = 3", true])
1251 @request.session[:user_id] = 3
1262 @request.session[:user_id] = 3
1252 get :show, :id => 1
1263 get :show, :id => 1
1253 assert_response :success
1264 assert_response :success
1254 end
1265 end
1255
1266
1256 def test_show_should_allow_member_access_to_private_issue_with_permission
1267 def test_show_should_allow_member_access_to_private_issue_with_permission
1257 Issue.where(:id => 1).update_all(["is_private = ?", true])
1268 Issue.where(:id => 1).update_all(["is_private = ?", true])
1258 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1269 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
1259 @request.session[:user_id] = 3
1270 @request.session[:user_id] = 3
1260 get :show, :id => 1
1271 get :show, :id => 1
1261 assert_response :success
1272 assert_response :success
1262 end
1273 end
1263
1274
1264 def test_show_should_not_disclose_relations_to_invisible_issues
1275 def test_show_should_not_disclose_relations_to_invisible_issues
1265 Setting.cross_project_issue_relations = '1'
1276 Setting.cross_project_issue_relations = '1'
1266 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1277 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
1267 # Relation to a private project issue
1278 # Relation to a private project issue
1268 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1279 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
1269
1280
1270 get :show, :id => 1
1281 get :show, :id => 1
1271 assert_response :success
1282 assert_response :success
1272
1283
1273 assert_select 'div#relations' do
1284 assert_select 'div#relations' do
1274 assert_select 'a', :text => /#2$/
1285 assert_select 'a', :text => /#2$/
1275 assert_select 'a', :text => /#4$/, :count => 0
1286 assert_select 'a', :text => /#4$/, :count => 0
1276 end
1287 end
1277 end
1288 end
1278
1289
1279 def test_show_should_list_subtasks
1290 def test_show_should_list_subtasks
1280 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1291 Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1281
1292
1282 get :show, :id => 1
1293 get :show, :id => 1
1283 assert_response :success
1294 assert_response :success
1284
1295
1285 assert_select 'div#issue_tree' do
1296 assert_select 'div#issue_tree' do
1286 assert_select 'td.subject', :text => /Child Issue/
1297 assert_select 'td.subject', :text => /Child Issue/
1287 end
1298 end
1288 end
1299 end
1289
1300
1290 def test_show_should_list_parents
1301 def test_show_should_list_parents
1291 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1302 issue = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :parent_issue_id => 1, :subject => 'Child Issue')
1292
1303
1293 get :show, :id => issue.id
1304 get :show, :id => issue.id
1294 assert_response :success
1305 assert_response :success
1295
1306
1296 assert_select 'div.subject' do
1307 assert_select 'div.subject' do
1297 assert_select 'h3', 'Child Issue'
1308 assert_select 'h3', 'Child Issue'
1298 assert_select 'a[href="/issues/1"]'
1309 assert_select 'a[href="/issues/1"]'
1299 end
1310 end
1300 end
1311 end
1301
1312
1302 def test_show_should_not_display_prev_next_links_without_query_in_session
1313 def test_show_should_not_display_prev_next_links_without_query_in_session
1303 get :show, :id => 1
1314 get :show, :id => 1
1304 assert_response :success
1315 assert_response :success
1305 assert_nil assigns(:prev_issue_id)
1316 assert_nil assigns(:prev_issue_id)
1306 assert_nil assigns(:next_issue_id)
1317 assert_nil assigns(:next_issue_id)
1307
1318
1308 assert_select 'div.next-prev-links', 0
1319 assert_select 'div.next-prev-links', 0
1309 end
1320 end
1310
1321
1311 def test_show_should_display_prev_next_links_with_query_in_session
1322 def test_show_should_display_prev_next_links_with_query_in_session
1312 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1323 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1313 @request.session['issues_index_sort'] = 'id'
1324 @request.session['issues_index_sort'] = 'id'
1314
1325
1315 with_settings :display_subprojects_issues => '0' do
1326 with_settings :display_subprojects_issues => '0' do
1316 get :show, :id => 3
1327 get :show, :id => 3
1317 end
1328 end
1318
1329
1319 assert_response :success
1330 assert_response :success
1320 # Previous and next issues for all projects
1331 # Previous and next issues for all projects
1321 assert_equal 2, assigns(:prev_issue_id)
1332 assert_equal 2, assigns(:prev_issue_id)
1322 assert_equal 5, assigns(:next_issue_id)
1333 assert_equal 5, assigns(:next_issue_id)
1323
1334
1324 count = Issue.open.visible.count
1335 count = Issue.open.visible.count
1325
1336
1326 assert_select 'div.next-prev-links' do
1337 assert_select 'div.next-prev-links' do
1327 assert_select 'a[href="/issues/2"]', :text => /Previous/
1338 assert_select 'a[href="/issues/2"]', :text => /Previous/
1328 assert_select 'a[href="/issues/5"]', :text => /Next/
1339 assert_select 'a[href="/issues/5"]', :text => /Next/
1329 assert_select 'span.position', :text => "3 of #{count}"
1340 assert_select 'span.position', :text => "3 of #{count}"
1330 end
1341 end
1331 end
1342 end
1332
1343
1333 def test_show_should_display_prev_next_links_with_saved_query_in_session
1344 def test_show_should_display_prev_next_links_with_saved_query_in_session
1334 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
1345 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1,
1335 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1346 :filters => {'status_id' => {:values => ['5'], :operator => '='}},
1336 :sort_criteria => [['id', 'asc']])
1347 :sort_criteria => [['id', 'asc']])
1337 @request.session[:query] = {:id => query.id, :project_id => nil}
1348 @request.session[:query] = {:id => query.id, :project_id => nil}
1338
1349
1339 get :show, :id => 11
1350 get :show, :id => 11
1340
1351
1341 assert_response :success
1352 assert_response :success
1342 assert_equal query, assigns(:query)
1353 assert_equal query, assigns(:query)
1343 # Previous and next issues for all projects
1354 # Previous and next issues for all projects
1344 assert_equal 8, assigns(:prev_issue_id)
1355 assert_equal 8, assigns(:prev_issue_id)
1345 assert_equal 12, assigns(:next_issue_id)
1356 assert_equal 12, assigns(:next_issue_id)
1346
1357
1347 assert_select 'div.next-prev-links' do
1358 assert_select 'div.next-prev-links' do
1348 assert_select 'a[href="/issues/8"]', :text => /Previous/
1359 assert_select 'a[href="/issues/8"]', :text => /Previous/
1349 assert_select 'a[href="/issues/12"]', :text => /Next/
1360 assert_select 'a[href="/issues/12"]', :text => /Next/
1350 end
1361 end
1351 end
1362 end
1352
1363
1353 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1364 def test_show_should_display_prev_next_links_with_query_and_sort_on_association
1354 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1365 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => nil}
1355
1366
1356 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1367 %w(project tracker status priority author assigned_to category fixed_version).each do |assoc_sort|
1357 @request.session['issues_index_sort'] = assoc_sort
1368 @request.session['issues_index_sort'] = assoc_sort
1358
1369
1359 get :show, :id => 3
1370 get :show, :id => 3
1360 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1371 assert_response :success, "Wrong response status for #{assoc_sort} sort"
1361
1372
1362 assert_select 'div.next-prev-links' do
1373 assert_select 'div.next-prev-links' do
1363 assert_select 'a', :text => /(Previous|Next)/
1374 assert_select 'a', :text => /(Previous|Next)/
1364 end
1375 end
1365 end
1376 end
1366 end
1377 end
1367
1378
1368 def test_show_should_display_prev_next_links_with_project_query_in_session
1379 def test_show_should_display_prev_next_links_with_project_query_in_session
1369 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1380 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1370 @request.session['issues_index_sort'] = 'id'
1381 @request.session['issues_index_sort'] = 'id'
1371
1382
1372 with_settings :display_subprojects_issues => '0' do
1383 with_settings :display_subprojects_issues => '0' do
1373 get :show, :id => 3
1384 get :show, :id => 3
1374 end
1385 end
1375
1386
1376 assert_response :success
1387 assert_response :success
1377 # Previous and next issues inside project
1388 # Previous and next issues inside project
1378 assert_equal 2, assigns(:prev_issue_id)
1389 assert_equal 2, assigns(:prev_issue_id)
1379 assert_equal 7, assigns(:next_issue_id)
1390 assert_equal 7, assigns(:next_issue_id)
1380
1391
1381 assert_select 'div.next-prev-links' do
1392 assert_select 'div.next-prev-links' do
1382 assert_select 'a[href="/issues/2"]', :text => /Previous/
1393 assert_select 'a[href="/issues/2"]', :text => /Previous/
1383 assert_select 'a[href="/issues/7"]', :text => /Next/
1394 assert_select 'a[href="/issues/7"]', :text => /Next/
1384 end
1395 end
1385 end
1396 end
1386
1397
1387 def test_show_should_not_display_prev_link_for_first_issue
1398 def test_show_should_not_display_prev_link_for_first_issue
1388 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
1399 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'o'}}, :project_id => 1}
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 => 1
1403 get :show, :id => 1
1393 end
1404 end
1394
1405
1395 assert_response :success
1406 assert_response :success
1396 assert_nil assigns(:prev_issue_id)
1407 assert_nil assigns(:prev_issue_id)
1397 assert_equal 2, assigns(:next_issue_id)
1408 assert_equal 2, assigns(:next_issue_id)
1398
1409
1399 assert_select 'div.next-prev-links' do
1410 assert_select 'div.next-prev-links' do
1400 assert_select 'a', :text => /Previous/, :count => 0
1411 assert_select 'a', :text => /Previous/, :count => 0
1401 assert_select 'a[href="/issues/2"]', :text => /Next/
1412 assert_select 'a[href="/issues/2"]', :text => /Next/
1402 end
1413 end
1403 end
1414 end
1404
1415
1405 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1416 def test_show_should_not_display_prev_next_links_for_issue_not_in_query_results
1406 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1417 @request.session[:query] = {:filters => {'status_id' => {:values => [''], :operator => 'c'}}, :project_id => 1}
1407 @request.session['issues_index_sort'] = 'id'
1418 @request.session['issues_index_sort'] = 'id'
1408
1419
1409 get :show, :id => 1
1420 get :show, :id => 1
1410
1421
1411 assert_response :success
1422 assert_response :success
1412 assert_nil assigns(:prev_issue_id)
1423 assert_nil assigns(:prev_issue_id)
1413 assert_nil assigns(:next_issue_id)
1424 assert_nil assigns(:next_issue_id)
1414
1425
1415 assert_select 'a', :text => /Previous/, :count => 0
1426 assert_select 'a', :text => /Previous/, :count => 0
1416 assert_select 'a', :text => /Next/, :count => 0
1427 assert_select 'a', :text => /Next/, :count => 0
1417 end
1428 end
1418
1429
1419 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1430 def test_show_show_should_display_prev_next_links_with_query_sort_by_user_custom_field
1420 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1431 cf = IssueCustomField.create!(:name => 'User', :is_for_all => true, :tracker_ids => [1,2,3], :field_format => 'user')
1421 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1432 CustomValue.create!(:custom_field => cf, :customized => Issue.find(1), :value => '2')
1422 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1433 CustomValue.create!(:custom_field => cf, :customized => Issue.find(2), :value => '3')
1423 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1434 CustomValue.create!(:custom_field => cf, :customized => Issue.find(3), :value => '3')
1424 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1435 CustomValue.create!(:custom_field => cf, :customized => Issue.find(5), :value => '')
1425
1436
1426 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
1437 query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC, :user_id => 1, :filters => {},
1427 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1438 :sort_criteria => [["cf_#{cf.id}", 'asc'], ['id', 'asc']])
1428 @request.session[:query] = {:id => query.id, :project_id => nil}
1439 @request.session[:query] = {:id => query.id, :project_id => nil}
1429
1440
1430 get :show, :id => 3
1441 get :show, :id => 3
1431 assert_response :success
1442 assert_response :success
1432
1443
1433 assert_equal 2, assigns(:prev_issue_id)
1444 assert_equal 2, assigns(:prev_issue_id)
1434 assert_equal 1, assigns(:next_issue_id)
1445 assert_equal 1, assigns(:next_issue_id)
1435
1446
1436 assert_select 'div.next-prev-links' do
1447 assert_select 'div.next-prev-links' do
1437 assert_select 'a[href="/issues/2"]', :text => /Previous/
1448 assert_select 'a[href="/issues/2"]', :text => /Previous/
1438 assert_select 'a[href="/issues/1"]', :text => /Next/
1449 assert_select 'a[href="/issues/1"]', :text => /Next/
1439 end
1450 end
1440 end
1451 end
1441
1452
1442 def test_show_should_display_category_field_if_categories_are_defined
1453 def test_show_should_display_category_field_if_categories_are_defined
1443 Issue.update_all :category_id => nil
1454 Issue.update_all :category_id => nil
1444
1455
1445 get :show, :id => 1
1456 get :show, :id => 1
1446 assert_response :success
1457 assert_response :success
1447 assert_select '.attributes .category'
1458 assert_select '.attributes .category'
1448 end
1459 end
1449
1460
1450 def test_show_should_not_display_category_field_if_no_categories_are_defined
1461 def test_show_should_not_display_category_field_if_no_categories_are_defined
1451 Project.find(1).issue_categories.delete_all
1462 Project.find(1).issue_categories.delete_all
1452
1463
1453 get :show, :id => 1
1464 get :show, :id => 1
1454 assert_response :success
1465 assert_response :success
1455 assert_select 'table.attributes .category', 0
1466 assert_select 'table.attributes .category', 0
1456 end
1467 end
1457
1468
1458 def test_show_should_display_link_to_the_assignee
1469 def test_show_should_display_link_to_the_assignee
1459 get :show, :id => 2
1470 get :show, :id => 2
1460 assert_response :success
1471 assert_response :success
1461 assert_select '.assigned-to' do
1472 assert_select '.assigned-to' do
1462 assert_select 'a[href="/users/3"]'
1473 assert_select 'a[href="/users/3"]'
1463 end
1474 end
1464 end
1475 end
1465
1476
1466 def test_show_should_display_visible_changesets_from_other_projects
1477 def test_show_should_display_visible_changesets_from_other_projects
1467 project = Project.find(2)
1478 project = Project.find(2)
1468 issue = project.issues.first
1479 issue = project.issues.first
1469 issue.changeset_ids = [102]
1480 issue.changeset_ids = [102]
1470 issue.save!
1481 issue.save!
1471 # changesets from other projects should be displayed even if repository
1482 # changesets from other projects should be displayed even if repository
1472 # is disabled on issue's project
1483 # is disabled on issue's project
1473 project.disable_module! :repository
1484 project.disable_module! :repository
1474
1485
1475 @request.session[:user_id] = 2
1486 @request.session[:user_id] = 2
1476 get :show, :id => issue.id
1487 get :show, :id => issue.id
1477
1488
1478 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1489 assert_select 'a[href=?]', '/projects/ecookbook/repository/revisions/3'
1479 end
1490 end
1480
1491
1481 def test_show_should_display_watchers
1492 def test_show_should_display_watchers
1482 @request.session[:user_id] = 2
1493 @request.session[:user_id] = 2
1483 Issue.find(1).add_watcher User.find(2)
1494 Issue.find(1).add_watcher User.find(2)
1484
1495
1485 get :show, :id => 1
1496 get :show, :id => 1
1486 assert_select 'div#watchers ul' do
1497 assert_select 'div#watchers ul' do
1487 assert_select 'li' do
1498 assert_select 'li' do
1488 assert_select 'a[href="/users/2"]'
1499 assert_select 'a[href="/users/2"]'
1489 assert_select 'a img[alt=Delete]'
1500 assert_select 'a img[alt=Delete]'
1490 end
1501 end
1491 end
1502 end
1492 end
1503 end
1493
1504
1494 def test_show_should_display_watchers_with_gravatars
1505 def test_show_should_display_watchers_with_gravatars
1495 @request.session[:user_id] = 2
1506 @request.session[:user_id] = 2
1496 Issue.find(1).add_watcher User.find(2)
1507 Issue.find(1).add_watcher User.find(2)
1497
1508
1498 with_settings :gravatar_enabled => '1' do
1509 with_settings :gravatar_enabled => '1' do
1499 get :show, :id => 1
1510 get :show, :id => 1
1500 end
1511 end
1501
1512
1502 assert_select 'div#watchers ul' do
1513 assert_select 'div#watchers ul' do
1503 assert_select 'li' do
1514 assert_select 'li' do
1504 assert_select 'img.gravatar'
1515 assert_select 'img.gravatar'
1505 assert_select 'a[href="/users/2"]'
1516 assert_select 'a[href="/users/2"]'
1506 assert_select 'a img[alt=Delete]'
1517 assert_select 'a img[alt=Delete]'
1507 end
1518 end
1508 end
1519 end
1509 end
1520 end
1510
1521
1511 def test_show_with_thumbnails_enabled_should_display_thumbnails
1522 def test_show_with_thumbnails_enabled_should_display_thumbnails
1512 @request.session[:user_id] = 2
1523 @request.session[:user_id] = 2
1513
1524
1514 with_settings :thumbnails_enabled => '1' do
1525 with_settings :thumbnails_enabled => '1' do
1515 get :show, :id => 14
1526 get :show, :id => 14
1516 assert_response :success
1527 assert_response :success
1517 end
1528 end
1518
1529
1519 assert_select 'div.thumbnails' do
1530 assert_select 'div.thumbnails' do
1520 assert_select 'a[href="/attachments/16/testfile.png"]' do
1531 assert_select 'a[href="/attachments/16/testfile.png"]' do
1521 assert_select 'img[src="/attachments/thumbnail/16"]'
1532 assert_select 'img[src="/attachments/thumbnail/16"]'
1522 end
1533 end
1523 end
1534 end
1524 end
1535 end
1525
1536
1526 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1537 def test_show_with_thumbnails_disabled_should_not_display_thumbnails
1527 @request.session[:user_id] = 2
1538 @request.session[:user_id] = 2
1528
1539
1529 with_settings :thumbnails_enabled => '0' do
1540 with_settings :thumbnails_enabled => '0' do
1530 get :show, :id => 14
1541 get :show, :id => 14
1531 assert_response :success
1542 assert_response :success
1532 end
1543 end
1533
1544
1534 assert_select 'div.thumbnails', 0
1545 assert_select 'div.thumbnails', 0
1535 end
1546 end
1536
1547
1537 def test_show_with_multi_custom_field
1548 def test_show_with_multi_custom_field
1538 field = CustomField.find(1)
1549 field = CustomField.find(1)
1539 field.update_attribute :multiple, true
1550 field.update_attribute :multiple, true
1540 issue = Issue.find(1)
1551 issue = Issue.find(1)
1541 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1552 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
1542 issue.save!
1553 issue.save!
1543
1554
1544 get :show, :id => 1
1555 get :show, :id => 1
1545 assert_response :success
1556 assert_response :success
1546
1557
1547 assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
1558 assert_select ".cf_1 .value", :text => 'MySQL, Oracle'
1548 end
1559 end
1549
1560
1550 def test_show_with_multi_user_custom_field
1561 def test_show_with_multi_user_custom_field
1551 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1562 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1552 :tracker_ids => [1], :is_for_all => true)
1563 :tracker_ids => [1], :is_for_all => true)
1553 issue = Issue.find(1)
1564 issue = Issue.find(1)
1554 issue.custom_field_values = {field.id => ['2', '3']}
1565 issue.custom_field_values = {field.id => ['2', '3']}
1555 issue.save!
1566 issue.save!
1556
1567
1557 get :show, :id => 1
1568 get :show, :id => 1
1558 assert_response :success
1569 assert_response :success
1559
1570
1560 assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
1571 assert_select ".cf_#{field.id} .value", :text => 'Dave Lopper, John Smith' do
1561 assert_select 'a', :text => 'Dave Lopper'
1572 assert_select 'a', :text => 'Dave Lopper'
1562 assert_select 'a', :text => 'John Smith'
1573 assert_select 'a', :text => 'John Smith'
1563 end
1574 end
1564 end
1575 end
1565
1576
1566 def test_show_should_display_private_notes_with_permission_only
1577 def test_show_should_display_private_notes_with_permission_only
1567 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1578 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
1568 @request.session[:user_id] = 2
1579 @request.session[:user_id] = 2
1569
1580
1570 get :show, :id => 2
1581 get :show, :id => 2
1571 assert_response :success
1582 assert_response :success
1572 assert_include journal, assigns(:journals)
1583 assert_include journal, assigns(:journals)
1573
1584
1574 Role.find(1).remove_permission! :view_private_notes
1585 Role.find(1).remove_permission! :view_private_notes
1575 get :show, :id => 2
1586 get :show, :id => 2
1576 assert_response :success
1587 assert_response :success
1577 assert_not_include journal, assigns(:journals)
1588 assert_not_include journal, assigns(:journals)
1578 end
1589 end
1579
1590
1580 def test_show_atom
1591 def test_show_atom
1581 get :show, :id => 2, :format => 'atom'
1592 get :show, :id => 2, :format => 'atom'
1582 assert_response :success
1593 assert_response :success
1583 assert_template 'journals/index'
1594 assert_template 'journals/index'
1584 # Inline image
1595 # Inline image
1585 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1596 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
1586 end
1597 end
1587
1598
1588 def test_show_export_to_pdf
1599 def test_show_export_to_pdf
1589 issue = Issue.find(3)
1600 issue = Issue.find(3)
1590 assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
1601 assert issue.relations.select{|r| r.other_issue(issue).visible?}.present?
1591 get :show, :id => 3, :format => 'pdf'
1602 get :show, :id => 3, :format => 'pdf'
1592 assert_response :success
1603 assert_response :success
1593 assert_equal 'application/pdf', @response.content_type
1604 assert_equal 'application/pdf', @response.content_type
1594 assert @response.body.starts_with?('%PDF')
1605 assert @response.body.starts_with?('%PDF')
1595 assert_not_nil assigns(:issue)
1606 assert_not_nil assigns(:issue)
1596 end
1607 end
1597
1608
1598 def test_export_to_pdf_with_utf8_u_fffd
1609 def test_export_to_pdf_with_utf8_u_fffd
1599 # U+FFFD
1610 # U+FFFD
1600 s = "\xef\xbf\xbd"
1611 s = "\xef\xbf\xbd"
1601 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
1612 s.force_encoding('UTF-8') if s.respond_to?(:force_encoding)
1602 issue = Issue.generate!(:subject => s)
1613 issue = Issue.generate!(:subject => s)
1603 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
1614 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
1604 with_settings :default_language => lang do
1615 with_settings :default_language => lang do
1605 get :show, :id => issue.id, :format => 'pdf'
1616 get :show, :id => issue.id, :format => 'pdf'
1606 assert_response :success
1617 assert_response :success
1607 assert_equal 'application/pdf', @response.content_type
1618 assert_equal 'application/pdf', @response.content_type
1608 assert @response.body.starts_with?('%PDF')
1619 assert @response.body.starts_with?('%PDF')
1609 assert_not_nil assigns(:issue)
1620 assert_not_nil assigns(:issue)
1610 end
1621 end
1611 end
1622 end
1612 end
1623 end
1613
1624
1614 def test_show_export_to_pdf_with_ancestors
1625 def test_show_export_to_pdf_with_ancestors
1615 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1626 issue = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1616
1627
1617 get :show, :id => issue.id, :format => 'pdf'
1628 get :show, :id => issue.id, :format => 'pdf'
1618 assert_response :success
1629 assert_response :success
1619 assert_equal 'application/pdf', @response.content_type
1630 assert_equal 'application/pdf', @response.content_type
1620 assert @response.body.starts_with?('%PDF')
1631 assert @response.body.starts_with?('%PDF')
1621 end
1632 end
1622
1633
1623 def test_show_export_to_pdf_with_descendants
1634 def test_show_export_to_pdf_with_descendants
1624 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1635 c1 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1625 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1636 c2 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => 1)
1626 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1637 c3 = Issue.generate!(:project_id => 1, :author_id => 2, :tracker_id => 1, :subject => 'child', :parent_issue_id => c1.id)
1627
1638
1628 get :show, :id => 1, :format => 'pdf'
1639 get :show, :id => 1, :format => 'pdf'
1629 assert_response :success
1640 assert_response :success
1630 assert_equal 'application/pdf', @response.content_type
1641 assert_equal 'application/pdf', @response.content_type
1631 assert @response.body.starts_with?('%PDF')
1642 assert @response.body.starts_with?('%PDF')
1632 end
1643 end
1633
1644
1634 def test_show_export_to_pdf_with_journals
1645 def test_show_export_to_pdf_with_journals
1635 get :show, :id => 1, :format => 'pdf'
1646 get :show, :id => 1, :format => 'pdf'
1636 assert_response :success
1647 assert_response :success
1637 assert_equal 'application/pdf', @response.content_type
1648 assert_equal 'application/pdf', @response.content_type
1638 assert @response.body.starts_with?('%PDF')
1649 assert @response.body.starts_with?('%PDF')
1639 end
1650 end
1640
1651
1641 def test_show_export_to_pdf_with_changesets
1652 def test_show_export_to_pdf_with_changesets
1642 [[100], [100, 101], [100, 101, 102]].each do |cs|
1653 [[100], [100, 101], [100, 101, 102]].each do |cs|
1643 issue1 = Issue.find(3)
1654 issue1 = Issue.find(3)
1644 issue1.changesets = Changeset.find(cs)
1655 issue1.changesets = Changeset.find(cs)
1645 issue1.save!
1656 issue1.save!
1646 issue = Issue.find(3)
1657 issue = Issue.find(3)
1647 assert_equal issue.changesets.count, cs.size
1658 assert_equal issue.changesets.count, cs.size
1648 get :show, :id => 3, :format => 'pdf'
1659 get :show, :id => 3, :format => 'pdf'
1649 assert_response :success
1660 assert_response :success
1650 assert_equal 'application/pdf', @response.content_type
1661 assert_equal 'application/pdf', @response.content_type
1651 assert @response.body.starts_with?('%PDF')
1662 assert @response.body.starts_with?('%PDF')
1652 end
1663 end
1653 end
1664 end
1654
1665
1655 def test_show_invalid_should_respond_with_404
1666 def test_show_invalid_should_respond_with_404
1656 get :show, :id => 999
1667 get :show, :id => 999
1657 assert_response 404
1668 assert_response 404
1658 end
1669 end
1659
1670
1660 def test_get_new
1671 def test_get_new
1661 @request.session[:user_id] = 2
1672 @request.session[:user_id] = 2
1662 get :new, :project_id => 1, :tracker_id => 1
1673 get :new, :project_id => 1, :tracker_id => 1
1663 assert_response :success
1674 assert_response :success
1664 assert_template 'new'
1675 assert_template 'new'
1665
1676
1666 assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
1677 assert_select 'form#issue-form[action=?]', '/projects/ecookbook/issues'
1667 assert_select 'form#issue-form' do
1678 assert_select 'form#issue-form' do
1668 assert_select 'input[name=?]', 'issue[is_private]'
1679 assert_select 'input[name=?]', 'issue[is_private]'
1669 assert_select 'select[name=?]', 'issue[project_id]', 0
1680 assert_select 'select[name=?]', 'issue[project_id]', 0
1670 assert_select 'select[name=?]', 'issue[tracker_id]'
1681 assert_select 'select[name=?]', 'issue[tracker_id]'
1671 assert_select 'input[name=?]', 'issue[subject]'
1682 assert_select 'input[name=?]', 'issue[subject]'
1672 assert_select 'textarea[name=?]', 'issue[description]'
1683 assert_select 'textarea[name=?]', 'issue[description]'
1673 assert_select 'select[name=?]', 'issue[status_id]'
1684 assert_select 'select[name=?]', 'issue[status_id]'
1674 assert_select 'select[name=?]', 'issue[priority_id]'
1685 assert_select 'select[name=?]', 'issue[priority_id]'
1675 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1686 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1676 assert_select 'select[name=?]', 'issue[category_id]'
1687 assert_select 'select[name=?]', 'issue[category_id]'
1677 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1688 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1678 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1689 assert_select 'input[name=?]', 'issue[parent_issue_id]'
1679 assert_select 'input[name=?]', 'issue[start_date]'
1690 assert_select 'input[name=?]', 'issue[start_date]'
1680 assert_select 'input[name=?]', 'issue[due_date]'
1691 assert_select 'input[name=?]', 'issue[due_date]'
1681 assert_select 'select[name=?]', 'issue[done_ratio]'
1692 assert_select 'select[name=?]', 'issue[done_ratio]'
1682 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1693 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1683 assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
1694 assert_select 'input[name=?]', 'issue[watcher_user_ids][]'
1684 end
1695 end
1685
1696
1686 # Be sure we don't display inactive IssuePriorities
1697 # Be sure we don't display inactive IssuePriorities
1687 assert ! IssuePriority.find(15).active?
1698 assert ! IssuePriority.find(15).active?
1688 assert_select 'select[name=?]', 'issue[priority_id]' do
1699 assert_select 'select[name=?]', 'issue[priority_id]' do
1689 assert_select 'option[value="15"]', 0
1700 assert_select 'option[value="15"]', 0
1690 end
1701 end
1691 end
1702 end
1692
1703
1693 def test_get_new_with_minimal_permissions
1704 def test_get_new_with_minimal_permissions
1694 Role.find(1).update_attribute :permissions, [:add_issues]
1705 Role.find(1).update_attribute :permissions, [:add_issues]
1695 WorkflowTransition.delete_all :role_id => 1
1706 WorkflowTransition.delete_all :role_id => 1
1696
1707
1697 @request.session[:user_id] = 2
1708 @request.session[:user_id] = 2
1698 get :new, :project_id => 1, :tracker_id => 1
1709 get :new, :project_id => 1, :tracker_id => 1
1699 assert_response :success
1710 assert_response :success
1700 assert_template 'new'
1711 assert_template 'new'
1701
1712
1702 assert_select 'form#issue-form' do
1713 assert_select 'form#issue-form' do
1703 assert_select 'input[name=?]', 'issue[is_private]', 0
1714 assert_select 'input[name=?]', 'issue[is_private]', 0
1704 assert_select 'select[name=?]', 'issue[project_id]', 0
1715 assert_select 'select[name=?]', 'issue[project_id]', 0
1705 assert_select 'select[name=?]', 'issue[tracker_id]'
1716 assert_select 'select[name=?]', 'issue[tracker_id]'
1706 assert_select 'input[name=?]', 'issue[subject]'
1717 assert_select 'input[name=?]', 'issue[subject]'
1707 assert_select 'textarea[name=?]', 'issue[description]'
1718 assert_select 'textarea[name=?]', 'issue[description]'
1708 assert_select 'select[name=?]', 'issue[status_id]'
1719 assert_select 'select[name=?]', 'issue[status_id]'
1709 assert_select 'select[name=?]', 'issue[priority_id]'
1720 assert_select 'select[name=?]', 'issue[priority_id]'
1710 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1721 assert_select 'select[name=?]', 'issue[assigned_to_id]'
1711 assert_select 'select[name=?]', 'issue[category_id]'
1722 assert_select 'select[name=?]', 'issue[category_id]'
1712 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1723 assert_select 'select[name=?]', 'issue[fixed_version_id]'
1713 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1724 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
1714 assert_select 'input[name=?]', 'issue[start_date]'
1725 assert_select 'input[name=?]', 'issue[start_date]'
1715 assert_select 'input[name=?]', 'issue[due_date]'
1726 assert_select 'input[name=?]', 'issue[due_date]'
1716 assert_select 'select[name=?]', 'issue[done_ratio]'
1727 assert_select 'select[name=?]', 'issue[done_ratio]'
1717 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1728 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Default string'
1718 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1729 assert_select 'input[name=?]', 'issue[watcher_user_ids][]', 0
1719 end
1730 end
1720 end
1731 end
1721
1732
1722 def test_new_without_project_id
1733 def test_new_without_project_id
1723 @request.session[:user_id] = 2
1734 @request.session[:user_id] = 2
1724 get :new
1735 get :new
1725 assert_response :success
1736 assert_response :success
1726 assert_template 'new'
1737 assert_template 'new'
1727
1738
1728 assert_select 'form#issue-form[action=?]', '/issues'
1739 assert_select 'form#issue-form[action=?]', '/issues'
1729 assert_select 'form#issue-form' do
1740 assert_select 'form#issue-form' do
1730 assert_select 'select[name=?]', 'issue[project_id]'
1741 assert_select 'select[name=?]', 'issue[project_id]'
1731 end
1742 end
1732
1743
1733 assert_nil assigns(:project)
1744 assert_nil assigns(:project)
1734 assert_not_nil assigns(:issue)
1745 assert_not_nil assigns(:issue)
1735 end
1746 end
1736
1747
1737 def test_new_should_select_default_status
1748 def test_new_should_select_default_status
1738 @request.session[:user_id] = 2
1749 @request.session[:user_id] = 2
1739
1750
1740 get :new, :project_id => 1
1751 get :new, :project_id => 1
1741 assert_response :success
1752 assert_response :success
1742 assert_template 'new'
1753 assert_template 'new'
1743 assert_select 'select[name=?]', 'issue[status_id]' do
1754 assert_select 'select[name=?]', 'issue[status_id]' do
1744 assert_select 'option[value="1"][selected=selected]'
1755 assert_select 'option[value="1"][selected=selected]'
1745 end
1756 end
1746 assert_select 'input[name=was_default_status][value="1"]'
1757 assert_select 'input[name=was_default_status][value="1"]'
1747 end
1758 end
1748
1759
1749 def test_new_should_propose_allowed_statuses
1760 def test_new_should_propose_allowed_statuses
1750 WorkflowTransition.delete_all
1761 WorkflowTransition.delete_all
1751 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
1762 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 1)
1752 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
1763 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 3)
1753 @request.session[:user_id] = 2
1764 @request.session[:user_id] = 2
1754
1765
1755 get :new, :project_id => 1
1766 get :new, :project_id => 1
1756 assert_response :success
1767 assert_response :success
1757 assert_select 'select[name=?]', 'issue[status_id]' do
1768 assert_select 'select[name=?]', 'issue[status_id]' do
1758 assert_select 'option[value="1"]'
1769 assert_select 'option[value="1"]'
1759 assert_select 'option[value="3"]'
1770 assert_select 'option[value="3"]'
1760 assert_select 'option', 2
1771 assert_select 'option', 2
1761 assert_select 'option[value="1"][selected=selected]'
1772 assert_select 'option[value="1"][selected=selected]'
1762 end
1773 end
1763 end
1774 end
1764
1775
1765 def test_new_should_propose_allowed_statuses_without_default_status_allowed
1776 def test_new_should_propose_allowed_statuses_without_default_status_allowed
1766 WorkflowTransition.delete_all
1777 WorkflowTransition.delete_all
1767 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
1778 WorkflowTransition.create!(:tracker_id => 1, :role_id => 1, :old_status_id => 0, :new_status_id => 2)
1768 assert_equal 1, Tracker.find(1).default_status_id
1779 assert_equal 1, Tracker.find(1).default_status_id
1769 @request.session[:user_id] = 2
1780 @request.session[:user_id] = 2
1770
1781
1771 get :new, :project_id => 1
1782 get :new, :project_id => 1
1772 assert_response :success
1783 assert_response :success
1773 assert_select 'select[name=?]', 'issue[status_id]' do
1784 assert_select 'select[name=?]', 'issue[status_id]' do
1774 assert_select 'option[value="2"]'
1785 assert_select 'option[value="2"]'
1775 assert_select 'option', 1
1786 assert_select 'option', 1
1776 assert_select 'option[value="2"][selected=selected]'
1787 assert_select 'option[value="2"][selected=selected]'
1777 end
1788 end
1778 end
1789 end
1779
1790
1780 def test_new_should_preselect_default_version
1791 def test_new_should_preselect_default_version
1781 version = Version.generate!(:project_id => 1)
1792 version = Version.generate!(:project_id => 1)
1782 Project.find(1).update_attribute :default_version_id, version.id
1793 Project.find(1).update_attribute :default_version_id, version.id
1783 @request.session[:user_id] = 2
1794 @request.session[:user_id] = 2
1784
1795
1785 get :new, :project_id => 1
1796 get :new, :project_id => 1
1786 assert_response :success
1797 assert_response :success
1787 assert_equal version, assigns(:issue).fixed_version
1798 assert_equal version, assigns(:issue).fixed_version
1788 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
1799 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
1789 assert_select 'option[value=?][selected=selected]', version.id.to_s
1800 assert_select 'option[value=?][selected=selected]', version.id.to_s
1790 end
1801 end
1791 end
1802 end
1792
1803
1793 def test_get_new_with_list_custom_field
1804 def test_get_new_with_list_custom_field
1794 @request.session[:user_id] = 2
1805 @request.session[:user_id] = 2
1795 get :new, :project_id => 1, :tracker_id => 1
1806 get :new, :project_id => 1, :tracker_id => 1
1796 assert_response :success
1807 assert_response :success
1797 assert_template 'new'
1808 assert_template 'new'
1798
1809
1799 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1810 assert_select 'select.list_cf[name=?]', 'issue[custom_field_values][1]' do
1800 assert_select 'option', 4
1811 assert_select 'option', 4
1801 assert_select 'option[value=MySQL]', :text => 'MySQL'
1812 assert_select 'option[value=MySQL]', :text => 'MySQL'
1802 end
1813 end
1803 end
1814 end
1804
1815
1805 def test_get_new_with_multi_custom_field
1816 def test_get_new_with_multi_custom_field
1806 field = IssueCustomField.find(1)
1817 field = IssueCustomField.find(1)
1807 field.update_attribute :multiple, true
1818 field.update_attribute :multiple, true
1808
1819
1809 @request.session[:user_id] = 2
1820 @request.session[:user_id] = 2
1810 get :new, :project_id => 1, :tracker_id => 1
1821 get :new, :project_id => 1, :tracker_id => 1
1811 assert_response :success
1822 assert_response :success
1812 assert_template 'new'
1823 assert_template 'new'
1813
1824
1814 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1825 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
1815 assert_select 'option', 3
1826 assert_select 'option', 3
1816 assert_select 'option[value=MySQL]', :text => 'MySQL'
1827 assert_select 'option[value=MySQL]', :text => 'MySQL'
1817 end
1828 end
1818 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1829 assert_select 'input[name=?][type=hidden][value=?]', 'issue[custom_field_values][1][]', ''
1819 end
1830 end
1820
1831
1821 def test_get_new_with_multi_user_custom_field
1832 def test_get_new_with_multi_user_custom_field
1822 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1833 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
1823 :tracker_ids => [1], :is_for_all => true)
1834 :tracker_ids => [1], :is_for_all => true)
1824
1835
1825 @request.session[:user_id] = 2
1836 @request.session[:user_id] = 2
1826 get :new, :project_id => 1, :tracker_id => 1
1837 get :new, :project_id => 1, :tracker_id => 1
1827 assert_response :success
1838 assert_response :success
1828 assert_template 'new'
1839 assert_template 'new'
1829
1840
1830 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1841 assert_select 'select[name=?][multiple=multiple]', "issue[custom_field_values][#{field.id}][]" do
1831 assert_select 'option', Project.find(1).users.count
1842 assert_select 'option', Project.find(1).users.count
1832 assert_select 'option[value="2"]', :text => 'John Smith'
1843 assert_select 'option[value="2"]', :text => 'John Smith'
1833 end
1844 end
1834 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1845 assert_select 'input[name=?][type=hidden][value=?]', "issue[custom_field_values][#{field.id}][]", ''
1835 end
1846 end
1836
1847
1837 def test_get_new_with_date_custom_field
1848 def test_get_new_with_date_custom_field
1838 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1849 field = IssueCustomField.create!(:name => 'Date', :field_format => 'date', :tracker_ids => [1], :is_for_all => true)
1839
1850
1840 @request.session[:user_id] = 2
1851 @request.session[:user_id] = 2
1841 get :new, :project_id => 1, :tracker_id => 1
1852 get :new, :project_id => 1, :tracker_id => 1
1842 assert_response :success
1853 assert_response :success
1843
1854
1844 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1855 assert_select 'input[name=?]', "issue[custom_field_values][#{field.id}]"
1845 end
1856 end
1846
1857
1847 def test_get_new_with_text_custom_field
1858 def test_get_new_with_text_custom_field
1848 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1859 field = IssueCustomField.create!(:name => 'Text', :field_format => 'text', :tracker_ids => [1], :is_for_all => true)
1849
1860
1850 @request.session[:user_id] = 2
1861 @request.session[:user_id] = 2
1851 get :new, :project_id => 1, :tracker_id => 1
1862 get :new, :project_id => 1, :tracker_id => 1
1852 assert_response :success
1863 assert_response :success
1853
1864
1854 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1865 assert_select 'textarea[name=?]', "issue[custom_field_values][#{field.id}]"
1855 end
1866 end
1856
1867
1857 def test_get_new_without_default_start_date_is_creation_date
1868 def test_get_new_without_default_start_date_is_creation_date
1858 with_settings :default_issue_start_date_to_creation_date => 0 do
1869 with_settings :default_issue_start_date_to_creation_date => 0 do
1859 @request.session[:user_id] = 2
1870 @request.session[:user_id] = 2
1860 get :new, :project_id => 1, :tracker_id => 1
1871 get :new, :project_id => 1, :tracker_id => 1
1861 assert_response :success
1872 assert_response :success
1862 assert_template 'new'
1873 assert_template 'new'
1863 assert_select 'input[name=?]', 'issue[start_date]'
1874 assert_select 'input[name=?]', 'issue[start_date]'
1864 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1875 assert_select 'input[name=?][value]', 'issue[start_date]', 0
1865 end
1876 end
1866 end
1877 end
1867
1878
1868 def test_get_new_with_default_start_date_is_creation_date
1879 def test_get_new_with_default_start_date_is_creation_date
1869 with_settings :default_issue_start_date_to_creation_date => 1 do
1880 with_settings :default_issue_start_date_to_creation_date => 1 do
1870 @request.session[:user_id] = 2
1881 @request.session[:user_id] = 2
1871 get :new, :project_id => 1, :tracker_id => 1
1882 get :new, :project_id => 1, :tracker_id => 1
1872 assert_response :success
1883 assert_response :success
1873 assert_template 'new'
1884 assert_template 'new'
1874 assert_select 'input[name=?][value=?]', 'issue[start_date]',
1885 assert_select 'input[name=?][value=?]', 'issue[start_date]',
1875 Date.today.to_s
1886 Date.today.to_s
1876 end
1887 end
1877 end
1888 end
1878
1889
1879 def test_get_new_form_should_allow_attachment_upload
1890 def test_get_new_form_should_allow_attachment_upload
1880 @request.session[:user_id] = 2
1891 @request.session[:user_id] = 2
1881 get :new, :project_id => 1, :tracker_id => 1
1892 get :new, :project_id => 1, :tracker_id => 1
1882
1893
1883 assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
1894 assert_select 'form[id=issue-form][method=post][enctype="multipart/form-data"]' do
1884 assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
1895 assert_select 'input[name=?][type=file]', 'attachments[dummy][file]'
1885 end
1896 end
1886 end
1897 end
1887
1898
1888 def test_get_new_should_prefill_the_form_from_params
1899 def test_get_new_should_prefill_the_form_from_params
1889 @request.session[:user_id] = 2
1900 @request.session[:user_id] = 2
1890 get :new, :project_id => 1,
1901 get :new, :project_id => 1,
1891 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1902 :issue => {:tracker_id => 3, :description => 'Prefilled', :custom_field_values => {'2' => 'Custom field value'}}
1892
1903
1893 issue = assigns(:issue)
1904 issue = assigns(:issue)
1894 assert_equal 3, issue.tracker_id
1905 assert_equal 3, issue.tracker_id
1895 assert_equal 'Prefilled', issue.description
1906 assert_equal 'Prefilled', issue.description
1896 assert_equal 'Custom field value', issue.custom_field_value(2)
1907 assert_equal 'Custom field value', issue.custom_field_value(2)
1897
1908
1898 assert_select 'select[name=?]', 'issue[tracker_id]' do
1909 assert_select 'select[name=?]', 'issue[tracker_id]' do
1899 assert_select 'option[value="3"][selected=selected]'
1910 assert_select 'option[value="3"][selected=selected]'
1900 end
1911 end
1901 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1912 assert_select 'textarea[name=?]', 'issue[description]', :text => /Prefilled/
1902 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1913 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Custom field value'
1903 end
1914 end
1904
1915
1905 def test_get_new_should_mark_required_fields
1916 def test_get_new_should_mark_required_fields
1906 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1917 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1907 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1918 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1908 WorkflowPermission.delete_all
1919 WorkflowPermission.delete_all
1909 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1920 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1910 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1921 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1911 @request.session[:user_id] = 2
1922 @request.session[:user_id] = 2
1912
1923
1913 get :new, :project_id => 1
1924 get :new, :project_id => 1
1914 assert_response :success
1925 assert_response :success
1915 assert_template 'new'
1926 assert_template 'new'
1916
1927
1917 assert_select 'label[for=issue_start_date]' do
1928 assert_select 'label[for=issue_start_date]' do
1918 assert_select 'span[class=required]', 0
1929 assert_select 'span[class=required]', 0
1919 end
1930 end
1920 assert_select 'label[for=issue_due_date]' do
1931 assert_select 'label[for=issue_due_date]' do
1921 assert_select 'span[class=required]'
1932 assert_select 'span[class=required]'
1922 end
1933 end
1923 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1934 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1924 assert_select 'span[class=required]', 0
1935 assert_select 'span[class=required]', 0
1925 end
1936 end
1926 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1937 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1927 assert_select 'span[class=required]'
1938 assert_select 'span[class=required]'
1928 end
1939 end
1929 end
1940 end
1930
1941
1931 def test_get_new_should_not_display_readonly_fields
1942 def test_get_new_should_not_display_readonly_fields
1932 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1943 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1933 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1944 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1934 WorkflowPermission.delete_all
1945 WorkflowPermission.delete_all
1935 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1946 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1936 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1947 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1937 @request.session[:user_id] = 2
1948 @request.session[:user_id] = 2
1938
1949
1939 get :new, :project_id => 1
1950 get :new, :project_id => 1
1940 assert_response :success
1951 assert_response :success
1941 assert_template 'new'
1952 assert_template 'new'
1942
1953
1943 assert_select 'input[name=?]', 'issue[start_date]'
1954 assert_select 'input[name=?]', 'issue[start_date]'
1944 assert_select 'input[name=?]', 'issue[due_date]', 0
1955 assert_select 'input[name=?]', 'issue[due_date]', 0
1945 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1956 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1946 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1957 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1947 end
1958 end
1948
1959
1949 def test_new_with_tracker_set_as_readonly_should_accept_status
1960 def test_new_with_tracker_set_as_readonly_should_accept_status
1950 WorkflowPermission.delete_all
1961 WorkflowPermission.delete_all
1951 [1, 2].each do |status_id|
1962 [1, 2].each do |status_id|
1952 WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
1963 WorkflowPermission.create!(:tracker_id => 1, :old_status_id => status_id, :role_id => 1, :field_name => 'tracker_id', :rule => 'readonly')
1953 end
1964 end
1954 @request.session[:user_id] = 2
1965 @request.session[:user_id] = 2
1955
1966
1956 get :new, :project_id => 1, :issue => {:status_id => 2}
1967 get :new, :project_id => 1, :issue => {:status_id => 2}
1957 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1968 assert_select 'select[name=?]', 'issue[tracker_id]', 0
1958 assert_equal 2, assigns(:issue).status_id
1969 assert_equal 2, assigns(:issue).status_id
1959 end
1970 end
1960
1971
1961 def test_get_new_without_tracker_id
1972 def test_get_new_without_tracker_id
1962 @request.session[:user_id] = 2
1973 @request.session[:user_id] = 2
1963 get :new, :project_id => 1
1974 get :new, :project_id => 1
1964 assert_response :success
1975 assert_response :success
1965 assert_template 'new'
1976 assert_template 'new'
1966
1977
1967 issue = assigns(:issue)
1978 issue = assigns(:issue)
1968 assert_not_nil issue
1979 assert_not_nil issue
1969 assert_equal Project.find(1).trackers.first, issue.tracker
1980 assert_equal Project.find(1).trackers.first, issue.tracker
1970 end
1981 end
1971
1982
1972 def test_get_new_with_no_default_status_should_display_an_error
1983 def test_get_new_with_no_default_status_should_display_an_error
1973 @request.session[:user_id] = 2
1984 @request.session[:user_id] = 2
1974 IssueStatus.delete_all
1985 IssueStatus.delete_all
1975
1986
1976 get :new, :project_id => 1
1987 get :new, :project_id => 1
1977 assert_response 500
1988 assert_response 500
1978 assert_select_error /No default issue/
1989 assert_select_error /No default issue/
1979 end
1990 end
1980
1991
1981 def test_get_new_with_no_tracker_should_display_an_error
1992 def test_get_new_with_no_tracker_should_display_an_error
1982 @request.session[:user_id] = 2
1993 @request.session[:user_id] = 2
1983 Tracker.delete_all
1994 Tracker.delete_all
1984
1995
1985 get :new, :project_id => 1
1996 get :new, :project_id => 1
1986 assert_response 500
1997 assert_response 500
1987 assert_select_error /No tracker/
1998 assert_select_error /No tracker/
1988 end
1999 end
1989
2000
1990 def test_new_with_invalid_project_id
2001 def test_new_with_invalid_project_id
1991 @request.session[:user_id] = 1
2002 @request.session[:user_id] = 1
1992 get :new, :project_id => 'invalid'
2003 get :new, :project_id => 'invalid'
1993 assert_response 404
2004 assert_response 404
1994 end
2005 end
1995
2006
1996 def test_update_form_for_new_issue
2007 def test_update_form_for_new_issue
1997 @request.session[:user_id] = 2
2008 @request.session[:user_id] = 2
1998 xhr :post, :new, :project_id => 1,
2009 xhr :post, :new, :project_id => 1,
1999 :issue => {:tracker_id => 2,
2010 :issue => {:tracker_id => 2,
2000 :subject => 'This is the test_new issue',
2011 :subject => 'This is the test_new issue',
2001 :description => 'This is the description',
2012 :description => 'This is the description',
2002 :priority_id => 5}
2013 :priority_id => 5}
2003 assert_response :success
2014 assert_response :success
2004 assert_template 'new'
2015 assert_template 'new'
2005 assert_template :partial => '_form'
2016 assert_template :partial => '_form'
2006 assert_equal 'text/javascript', response.content_type
2017 assert_equal 'text/javascript', response.content_type
2007
2018
2008 issue = assigns(:issue)
2019 issue = assigns(:issue)
2009 assert_kind_of Issue, issue
2020 assert_kind_of Issue, issue
2010 assert_equal 1, issue.project_id
2021 assert_equal 1, issue.project_id
2011 assert_equal 2, issue.tracker_id
2022 assert_equal 2, issue.tracker_id
2012 assert_equal 'This is the test_new issue', issue.subject
2023 assert_equal 'This is the test_new issue', issue.subject
2013 end
2024 end
2014
2025
2015 def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
2026 def test_update_form_for_new_issue_should_propose_transitions_based_on_initial_status
2016 @request.session[:user_id] = 2
2027 @request.session[:user_id] = 2
2017 WorkflowTransition.delete_all
2028 WorkflowTransition.delete_all
2018 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
2029 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 2)
2019 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
2030 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 0, :new_status_id => 5)
2020 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
2031 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
2021
2032
2022 xhr :post, :new, :project_id => 1,
2033 xhr :post, :new, :project_id => 1,
2023 :issue => {:tracker_id => 1,
2034 :issue => {:tracker_id => 1,
2024 :status_id => 5,
2035 :status_id => 5,
2025 :subject => 'This is an issue'}
2036 :subject => 'This is an issue'}
2026
2037
2027 assert_equal 5, assigns(:issue).status_id
2038 assert_equal 5, assigns(:issue).status_id
2028 assert_equal [2,5], assigns(:allowed_statuses).map(&:id).sort
2039 assert_equal [2,5], assigns(:allowed_statuses).map(&:id).sort
2029 end
2040 end
2030
2041
2031 def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
2042 def test_update_form_with_default_status_should_ignore_submitted_status_id_if_equals
2032 @request.session[:user_id] = 2
2043 @request.session[:user_id] = 2
2033 tracker = Tracker.find(2)
2044 tracker = Tracker.find(2)
2034 tracker.update! :default_status_id => 2
2045 tracker.update! :default_status_id => 2
2035 tracker.generate_transitions! 2, 1, :clear => true
2046 tracker.generate_transitions! 2, 1, :clear => true
2036
2047
2037 xhr :post, :new, :project_id => 1,
2048 xhr :post, :new, :project_id => 1,
2038 :issue => {:tracker_id => 2,
2049 :issue => {:tracker_id => 2,
2039 :status_id => 1},
2050 :status_id => 1},
2040 :was_default_status => 1
2051 :was_default_status => 1
2041
2052
2042 assert_equal 2, assigns(:issue).status_id
2053 assert_equal 2, assigns(:issue).status_id
2043 end
2054 end
2044
2055
2045 def test_update_form_for_new_issue_should_ignore_version_when_changing_project
2056 def test_update_form_for_new_issue_should_ignore_version_when_changing_project
2046 version = Version.generate!(:project_id => 1)
2057 version = Version.generate!(:project_id => 1)
2047 Project.find(1).update_attribute :default_version_id, version.id
2058 Project.find(1).update_attribute :default_version_id, version.id
2048 @request.session[:user_id] = 2
2059 @request.session[:user_id] = 2
2049
2060
2050 xhr :post, :new, :issue => {:project_id => 1,
2061 xhr :post, :new, :issue => {:project_id => 1,
2051 :fixed_version_id => ''},
2062 :fixed_version_id => ''},
2052 :form_update_triggered_by => 'issue_project_id'
2063 :form_update_triggered_by => 'issue_project_id'
2053 assert_response :success
2064 assert_response :success
2054 assert_template 'new'
2065 assert_template 'new'
2055
2066
2056 issue = assigns(:issue)
2067 issue = assigns(:issue)
2057 assert_equal 1, issue.project_id
2068 assert_equal 1, issue.project_id
2058 assert_equal version, issue.fixed_version
2069 assert_equal version, issue.fixed_version
2059 end
2070 end
2060
2071
2061 def test_post_create
2072 def test_post_create
2062 @request.session[:user_id] = 2
2073 @request.session[:user_id] = 2
2063 assert_difference 'Issue.count' do
2074 assert_difference 'Issue.count' do
2064 assert_no_difference 'Journal.count' do
2075 assert_no_difference 'Journal.count' do
2065 post :create, :project_id => 1,
2076 post :create, :project_id => 1,
2066 :issue => {:tracker_id => 3,
2077 :issue => {:tracker_id => 3,
2067 :status_id => 2,
2078 :status_id => 2,
2068 :subject => 'This is the test_new issue',
2079 :subject => 'This is the test_new issue',
2069 :description => 'This is the description',
2080 :description => 'This is the description',
2070 :priority_id => 5,
2081 :priority_id => 5,
2071 :start_date => '2010-11-07',
2082 :start_date => '2010-11-07',
2072 :estimated_hours => '',
2083 :estimated_hours => '',
2073 :custom_field_values => {'2' => 'Value for field 2'}}
2084 :custom_field_values => {'2' => 'Value for field 2'}}
2074 end
2085 end
2075 end
2086 end
2076 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2087 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2077
2088
2078 issue = Issue.find_by_subject('This is the test_new issue')
2089 issue = Issue.find_by_subject('This is the test_new issue')
2079 assert_not_nil issue
2090 assert_not_nil issue
2080 assert_equal 2, issue.author_id
2091 assert_equal 2, issue.author_id
2081 assert_equal 3, issue.tracker_id
2092 assert_equal 3, issue.tracker_id
2082 assert_equal 2, issue.status_id
2093 assert_equal 2, issue.status_id
2083 assert_equal Date.parse('2010-11-07'), issue.start_date
2094 assert_equal Date.parse('2010-11-07'), issue.start_date
2084 assert_nil issue.estimated_hours
2095 assert_nil issue.estimated_hours
2085 v = issue.custom_values.where(:custom_field_id => 2).first
2096 v = issue.custom_values.where(:custom_field_id => 2).first
2086 assert_not_nil v
2097 assert_not_nil v
2087 assert_equal 'Value for field 2', v.value
2098 assert_equal 'Value for field 2', v.value
2088 end
2099 end
2089
2100
2090 def test_post_new_with_group_assignment
2101 def test_post_new_with_group_assignment
2091 group = Group.find(11)
2102 group = Group.find(11)
2092 project = Project.find(1)
2103 project = Project.find(1)
2093 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2104 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
2094
2105
2095 with_settings :issue_group_assignment => '1' do
2106 with_settings :issue_group_assignment => '1' do
2096 @request.session[:user_id] = 2
2107 @request.session[:user_id] = 2
2097 assert_difference 'Issue.count' do
2108 assert_difference 'Issue.count' do
2098 post :create, :project_id => project.id,
2109 post :create, :project_id => project.id,
2099 :issue => {:tracker_id => 3,
2110 :issue => {:tracker_id => 3,
2100 :status_id => 1,
2111 :status_id => 1,
2101 :subject => 'This is the test_new_with_group_assignment issue',
2112 :subject => 'This is the test_new_with_group_assignment issue',
2102 :assigned_to_id => group.id}
2113 :assigned_to_id => group.id}
2103 end
2114 end
2104 end
2115 end
2105 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2116 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2106
2117
2107 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
2118 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
2108 assert_not_nil issue
2119 assert_not_nil issue
2109 assert_equal group, issue.assigned_to
2120 assert_equal group, issue.assigned_to
2110 end
2121 end
2111
2122
2112 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
2123 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
2113 with_settings :default_issue_start_date_to_creation_date => 0 do
2124 with_settings :default_issue_start_date_to_creation_date => 0 do
2114 @request.session[:user_id] = 2
2125 @request.session[:user_id] = 2
2115 assert_difference 'Issue.count' do
2126 assert_difference 'Issue.count' do
2116 post :create, :project_id => 1,
2127 post :create, :project_id => 1,
2117 :issue => {:tracker_id => 3,
2128 :issue => {:tracker_id => 3,
2118 :status_id => 2,
2129 :status_id => 2,
2119 :subject => 'This is the test_new issue',
2130 :subject => 'This is the test_new issue',
2120 :description => 'This is the description',
2131 :description => 'This is the description',
2121 :priority_id => 5,
2132 :priority_id => 5,
2122 :estimated_hours => '',
2133 :estimated_hours => '',
2123 :custom_field_values => {'2' => 'Value for field 2'}}
2134 :custom_field_values => {'2' => 'Value for field 2'}}
2124 end
2135 end
2125 assert_redirected_to :controller => 'issues', :action => 'show',
2136 assert_redirected_to :controller => 'issues', :action => 'show',
2126 :id => Issue.last.id
2137 :id => Issue.last.id
2127 issue = Issue.find_by_subject('This is the test_new issue')
2138 issue = Issue.find_by_subject('This is the test_new issue')
2128 assert_not_nil issue
2139 assert_not_nil issue
2129 assert_nil issue.start_date
2140 assert_nil issue.start_date
2130 end
2141 end
2131 end
2142 end
2132
2143
2133 def test_post_create_without_start_date_and_default_start_date_is_creation_date
2144 def test_post_create_without_start_date_and_default_start_date_is_creation_date
2134 with_settings :default_issue_start_date_to_creation_date => 1 do
2145 with_settings :default_issue_start_date_to_creation_date => 1 do
2135 @request.session[:user_id] = 2
2146 @request.session[:user_id] = 2
2136 assert_difference 'Issue.count' do
2147 assert_difference 'Issue.count' do
2137 post :create, :project_id => 1,
2148 post :create, :project_id => 1,
2138 :issue => {:tracker_id => 3,
2149 :issue => {:tracker_id => 3,
2139 :status_id => 2,
2150 :status_id => 2,
2140 :subject => 'This is the test_new issue',
2151 :subject => 'This is the test_new issue',
2141 :description => 'This is the description',
2152 :description => 'This is the description',
2142 :priority_id => 5,
2153 :priority_id => 5,
2143 :estimated_hours => '',
2154 :estimated_hours => '',
2144 :custom_field_values => {'2' => 'Value for field 2'}}
2155 :custom_field_values => {'2' => 'Value for field 2'}}
2145 end
2156 end
2146 assert_redirected_to :controller => 'issues', :action => 'show',
2157 assert_redirected_to :controller => 'issues', :action => 'show',
2147 :id => Issue.last.id
2158 :id => Issue.last.id
2148 issue = Issue.find_by_subject('This is the test_new issue')
2159 issue = Issue.find_by_subject('This is the test_new issue')
2149 assert_not_nil issue
2160 assert_not_nil issue
2150 assert_equal Date.today, issue.start_date
2161 assert_equal Date.today, issue.start_date
2151 end
2162 end
2152 end
2163 end
2153
2164
2154 def test_post_create_and_continue
2165 def test_post_create_and_continue
2155 @request.session[:user_id] = 2
2166 @request.session[:user_id] = 2
2156 assert_difference 'Issue.count' do
2167 assert_difference 'Issue.count' do
2157 post :create, :project_id => 1,
2168 post :create, :project_id => 1,
2158 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
2169 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
2159 :continue => ''
2170 :continue => ''
2160 end
2171 end
2161
2172
2162 issue = Issue.order('id DESC').first
2173 issue = Issue.order('id DESC').first
2163 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
2174 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
2164 assert_not_nil flash[:notice], "flash was not set"
2175 assert_not_nil flash[:notice], "flash was not set"
2165 assert_select_in flash[:notice],
2176 assert_select_in flash[:notice],
2166 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
2177 'a[href=?][title=?]', "/issues/#{issue.id}", "This is first issue", :text => "##{issue.id}"
2167 end
2178 end
2168
2179
2169 def test_post_create_without_custom_fields_param
2180 def test_post_create_without_custom_fields_param
2170 @request.session[:user_id] = 2
2181 @request.session[:user_id] = 2
2171 assert_difference 'Issue.count' do
2182 assert_difference 'Issue.count' do
2172 post :create, :project_id => 1,
2183 post :create, :project_id => 1,
2173 :issue => {:tracker_id => 1,
2184 :issue => {:tracker_id => 1,
2174 :subject => 'This is the test_new issue',
2185 :subject => 'This is the test_new issue',
2175 :description => 'This is the description',
2186 :description => 'This is the description',
2176 :priority_id => 5}
2187 :priority_id => 5}
2177 end
2188 end
2178 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2189 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2179 end
2190 end
2180
2191
2181 def test_post_create_with_multi_custom_field
2192 def test_post_create_with_multi_custom_field
2182 field = IssueCustomField.find_by_name('Database')
2193 field = IssueCustomField.find_by_name('Database')
2183 field.update_attribute(:multiple, true)
2194 field.update_attribute(:multiple, true)
2184
2195
2185 @request.session[:user_id] = 2
2196 @request.session[:user_id] = 2
2186 assert_difference 'Issue.count' do
2197 assert_difference 'Issue.count' do
2187 post :create, :project_id => 1,
2198 post :create, :project_id => 1,
2188 :issue => {:tracker_id => 1,
2199 :issue => {:tracker_id => 1,
2189 :subject => 'This is the test_new issue',
2200 :subject => 'This is the test_new issue',
2190 :description => 'This is the description',
2201 :description => 'This is the description',
2191 :priority_id => 5,
2202 :priority_id => 5,
2192 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
2203 :custom_field_values => {'1' => ['', 'MySQL', 'Oracle']}}
2193 end
2204 end
2194 assert_response 302
2205 assert_response 302
2195 issue = Issue.order('id DESC').first
2206 issue = Issue.order('id DESC').first
2196 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
2207 assert_equal ['MySQL', 'Oracle'], issue.custom_field_value(1).sort
2197 end
2208 end
2198
2209
2199 def test_post_create_with_empty_multi_custom_field
2210 def test_post_create_with_empty_multi_custom_field
2200 field = IssueCustomField.find_by_name('Database')
2211 field = IssueCustomField.find_by_name('Database')
2201 field.update_attribute(:multiple, true)
2212 field.update_attribute(:multiple, true)
2202
2213
2203 @request.session[:user_id] = 2
2214 @request.session[:user_id] = 2
2204 assert_difference 'Issue.count' do
2215 assert_difference 'Issue.count' do
2205 post :create, :project_id => 1,
2216 post :create, :project_id => 1,
2206 :issue => {:tracker_id => 1,
2217 :issue => {:tracker_id => 1,
2207 :subject => 'This is the test_new issue',
2218 :subject => 'This is the test_new issue',
2208 :description => 'This is the description',
2219 :description => 'This is the description',
2209 :priority_id => 5,
2220 :priority_id => 5,
2210 :custom_field_values => {'1' => ['']}}
2221 :custom_field_values => {'1' => ['']}}
2211 end
2222 end
2212 assert_response 302
2223 assert_response 302
2213 issue = Issue.order('id DESC').first
2224 issue = Issue.order('id DESC').first
2214 assert_equal [''], issue.custom_field_value(1).sort
2225 assert_equal [''], issue.custom_field_value(1).sort
2215 end
2226 end
2216
2227
2217 def test_post_create_with_multi_user_custom_field
2228 def test_post_create_with_multi_user_custom_field
2218 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
2229 field = IssueCustomField.create!(:name => 'Multi user', :field_format => 'user', :multiple => true,
2219 :tracker_ids => [1], :is_for_all => true)
2230 :tracker_ids => [1], :is_for_all => true)
2220
2231
2221 @request.session[:user_id] = 2
2232 @request.session[:user_id] = 2
2222 assert_difference 'Issue.count' do
2233 assert_difference 'Issue.count' do
2223 post :create, :project_id => 1,
2234 post :create, :project_id => 1,
2224 :issue => {:tracker_id => 1,
2235 :issue => {:tracker_id => 1,
2225 :subject => 'This is the test_new issue',
2236 :subject => 'This is the test_new issue',
2226 :description => 'This is the description',
2237 :description => 'This is the description',
2227 :priority_id => 5,
2238 :priority_id => 5,
2228 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
2239 :custom_field_values => {field.id.to_s => ['', '2', '3']}}
2229 end
2240 end
2230 assert_response 302
2241 assert_response 302
2231 issue = Issue.order('id DESC').first
2242 issue = Issue.order('id DESC').first
2232 assert_equal ['2', '3'], issue.custom_field_value(field).sort
2243 assert_equal ['2', '3'], issue.custom_field_value(field).sort
2233 end
2244 end
2234
2245
2235 def test_post_create_with_required_custom_field_and_without_custom_fields_param
2246 def test_post_create_with_required_custom_field_and_without_custom_fields_param
2236 field = IssueCustomField.find_by_name('Database')
2247 field = IssueCustomField.find_by_name('Database')
2237 field.update_attribute(:is_required, true)
2248 field.update_attribute(:is_required, true)
2238
2249
2239 @request.session[:user_id] = 2
2250 @request.session[:user_id] = 2
2240 assert_no_difference 'Issue.count' do
2251 assert_no_difference 'Issue.count' do
2241 post :create, :project_id => 1,
2252 post :create, :project_id => 1,
2242 :issue => {:tracker_id => 1,
2253 :issue => {:tracker_id => 1,
2243 :subject => 'This is the test_new issue',
2254 :subject => 'This is the test_new issue',
2244 :description => 'This is the description',
2255 :description => 'This is the description',
2245 :priority_id => 5}
2256 :priority_id => 5}
2246 end
2257 end
2247 assert_response :success
2258 assert_response :success
2248 assert_template 'new'
2259 assert_template 'new'
2249 issue = assigns(:issue)
2260 issue = assigns(:issue)
2250 assert_not_nil issue
2261 assert_not_nil issue
2251 assert_select_error /Database cannot be blank/
2262 assert_select_error /Database cannot be blank/
2252 end
2263 end
2253
2264
2254 def test_create_should_validate_required_fields
2265 def test_create_should_validate_required_fields
2255 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2266 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2256 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2267 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2257 WorkflowPermission.delete_all
2268 WorkflowPermission.delete_all
2258 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
2269 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
2259 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2270 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2260 @request.session[:user_id] = 2
2271 @request.session[:user_id] = 2
2261
2272
2262 assert_no_difference 'Issue.count' do
2273 assert_no_difference 'Issue.count' do
2263 post :create, :project_id => 1, :issue => {
2274 post :create, :project_id => 1, :issue => {
2264 :tracker_id => 2,
2275 :tracker_id => 2,
2265 :status_id => 1,
2276 :status_id => 1,
2266 :subject => 'Test',
2277 :subject => 'Test',
2267 :start_date => '',
2278 :start_date => '',
2268 :due_date => '',
2279 :due_date => '',
2269 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
2280 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
2270 }
2281 }
2271 assert_response :success
2282 assert_response :success
2272 assert_template 'new'
2283 assert_template 'new'
2273 end
2284 end
2274
2285
2275 assert_select_error /Due date cannot be blank/i
2286 assert_select_error /Due date cannot be blank/i
2276 assert_select_error /Bar cannot be blank/i
2287 assert_select_error /Bar cannot be blank/i
2277 end
2288 end
2278
2289
2279 def test_create_should_validate_required_list_fields
2290 def test_create_should_validate_required_list_fields
2280 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
2291 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => false, :possible_values => ['a', 'b'])
2281 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
2292 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'list', :is_for_all => true, :tracker_ids => [1, 2], :multiple => true, :possible_values => ['a', 'b'])
2282 WorkflowPermission.delete_all
2293 WorkflowPermission.delete_all
2283 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
2294 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf1.id.to_s, :rule => 'required')
2284 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2295 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
2285 @request.session[:user_id] = 2
2296 @request.session[:user_id] = 2
2286
2297
2287 assert_no_difference 'Issue.count' do
2298 assert_no_difference 'Issue.count' do
2288 post :create, :project_id => 1, :issue => {
2299 post :create, :project_id => 1, :issue => {
2289 :tracker_id => 2,
2300 :tracker_id => 2,
2290 :status_id => 1,
2301 :status_id => 1,
2291 :subject => 'Test',
2302 :subject => 'Test',
2292 :start_date => '',
2303 :start_date => '',
2293 :due_date => '',
2304 :due_date => '',
2294 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ['']}
2305 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ['']}
2295 }
2306 }
2296 assert_response :success
2307 assert_response :success
2297 assert_template 'new'
2308 assert_template 'new'
2298 end
2309 end
2299
2310
2300 assert_select_error /Foo cannot be blank/i
2311 assert_select_error /Foo cannot be blank/i
2301 assert_select_error /Bar cannot be blank/i
2312 assert_select_error /Bar cannot be blank/i
2302 end
2313 end
2303
2314
2304 def test_create_should_ignore_readonly_fields
2315 def test_create_should_ignore_readonly_fields
2305 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2316 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2306 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2317 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
2307 WorkflowPermission.delete_all
2318 WorkflowPermission.delete_all
2308 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
2319 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
2309 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
2320 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
2310 @request.session[:user_id] = 2
2321 @request.session[:user_id] = 2
2311
2322
2312 assert_difference 'Issue.count' do
2323 assert_difference 'Issue.count' do
2313 post :create, :project_id => 1, :issue => {
2324 post :create, :project_id => 1, :issue => {
2314 :tracker_id => 2,
2325 :tracker_id => 2,
2315 :status_id => 1,
2326 :status_id => 1,
2316 :subject => 'Test',
2327 :subject => 'Test',
2317 :start_date => '2012-07-14',
2328 :start_date => '2012-07-14',
2318 :due_date => '2012-07-16',
2329 :due_date => '2012-07-16',
2319 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
2330 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
2320 }
2331 }
2321 assert_response 302
2332 assert_response 302
2322 end
2333 end
2323
2334
2324 issue = Issue.order('id DESC').first
2335 issue = Issue.order('id DESC').first
2325 assert_equal Date.parse('2012-07-14'), issue.start_date
2336 assert_equal Date.parse('2012-07-14'), issue.start_date
2326 assert_nil issue.due_date
2337 assert_nil issue.due_date
2327 assert_equal 'value1', issue.custom_field_value(cf1)
2338 assert_equal 'value1', issue.custom_field_value(cf1)
2328 assert_nil issue.custom_field_value(cf2)
2339 assert_nil issue.custom_field_value(cf2)
2329 end
2340 end
2330
2341
2331 def test_post_create_with_watchers
2342 def test_post_create_with_watchers
2332 @request.session[:user_id] = 2
2343 @request.session[:user_id] = 2
2333 ActionMailer::Base.deliveries.clear
2344 ActionMailer::Base.deliveries.clear
2334
2345
2335 with_settings :notified_events => %w(issue_added) do
2346 with_settings :notified_events => %w(issue_added) do
2336 assert_difference 'Watcher.count', 2 do
2347 assert_difference 'Watcher.count', 2 do
2337 post :create, :project_id => 1,
2348 post :create, :project_id => 1,
2338 :issue => {:tracker_id => 1,
2349 :issue => {:tracker_id => 1,
2339 :subject => 'This is a new issue with watchers',
2350 :subject => 'This is a new issue with watchers',
2340 :description => 'This is the description',
2351 :description => 'This is the description',
2341 :priority_id => 5,
2352 :priority_id => 5,
2342 :watcher_user_ids => ['2', '3']}
2353 :watcher_user_ids => ['2', '3']}
2343 end
2354 end
2344 end
2355 end
2345 issue = Issue.find_by_subject('This is a new issue with watchers')
2356 issue = Issue.find_by_subject('This is a new issue with watchers')
2346 assert_not_nil issue
2357 assert_not_nil issue
2347 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
2358 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
2348
2359
2349 # Watchers added
2360 # Watchers added
2350 assert_equal [2, 3], issue.watcher_user_ids.sort
2361 assert_equal [2, 3], issue.watcher_user_ids.sort
2351 assert issue.watched_by?(User.find(3))
2362 assert issue.watched_by?(User.find(3))
2352 # Watchers notified
2363 # Watchers notified
2353 mail = ActionMailer::Base.deliveries.last
2364 mail = ActionMailer::Base.deliveries.last
2354 assert_not_nil mail
2365 assert_not_nil mail
2355 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
2366 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
2356 end
2367 end
2357
2368
2358 def test_post_create_subissue
2369 def test_post_create_subissue
2359 @request.session[:user_id] = 2
2370 @request.session[:user_id] = 2
2360
2371
2361 assert_difference 'Issue.count' do
2372 assert_difference 'Issue.count' do
2362 post :create, :project_id => 1,
2373 post :create, :project_id => 1,
2363 :issue => {:tracker_id => 1,
2374 :issue => {:tracker_id => 1,
2364 :subject => 'This is a child issue',
2375 :subject => 'This is a child issue',
2365 :parent_issue_id => '2'}
2376 :parent_issue_id => '2'}
2366 assert_response 302
2377 assert_response 302
2367 end
2378 end
2368 issue = Issue.order('id DESC').first
2379 issue = Issue.order('id DESC').first
2369 assert_equal Issue.find(2), issue.parent
2380 assert_equal Issue.find(2), issue.parent
2370 end
2381 end
2371
2382
2372 def test_post_create_subissue_with_sharp_parent_id
2383 def test_post_create_subissue_with_sharp_parent_id
2373 @request.session[:user_id] = 2
2384 @request.session[:user_id] = 2
2374
2385
2375 assert_difference 'Issue.count' do
2386 assert_difference 'Issue.count' do
2376 post :create, :project_id => 1,
2387 post :create, :project_id => 1,
2377 :issue => {:tracker_id => 1,
2388 :issue => {:tracker_id => 1,
2378 :subject => 'This is a child issue',
2389 :subject => 'This is a child issue',
2379 :parent_issue_id => '#2'}
2390 :parent_issue_id => '#2'}
2380 assert_response 302
2391 assert_response 302
2381 end
2392 end
2382 issue = Issue.order('id DESC').first
2393 issue = Issue.order('id DESC').first
2383 assert_equal Issue.find(2), issue.parent
2394 assert_equal Issue.find(2), issue.parent
2384 end
2395 end
2385
2396
2386 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
2397 def test_post_create_subissue_with_non_visible_parent_id_should_not_validate
2387 @request.session[:user_id] = 2
2398 @request.session[:user_id] = 2
2388
2399
2389 assert_no_difference 'Issue.count' do
2400 assert_no_difference 'Issue.count' do
2390 post :create, :project_id => 1,
2401 post :create, :project_id => 1,
2391 :issue => {:tracker_id => 1,
2402 :issue => {:tracker_id => 1,
2392 :subject => 'This is a child issue',
2403 :subject => 'This is a child issue',
2393 :parent_issue_id => '4'}
2404 :parent_issue_id => '4'}
2394
2405
2395 assert_response :success
2406 assert_response :success
2396 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2407 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '4'
2397 assert_select_error /Parent task is invalid/i
2408 assert_select_error /Parent task is invalid/i
2398 end
2409 end
2399 end
2410 end
2400
2411
2401 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2412 def test_post_create_subissue_with_non_numeric_parent_id_should_not_validate
2402 @request.session[:user_id] = 2
2413 @request.session[:user_id] = 2
2403
2414
2404 assert_no_difference 'Issue.count' do
2415 assert_no_difference 'Issue.count' do
2405 post :create, :project_id => 1,
2416 post :create, :project_id => 1,
2406 :issue => {:tracker_id => 1,
2417 :issue => {:tracker_id => 1,
2407 :subject => 'This is a child issue',
2418 :subject => 'This is a child issue',
2408 :parent_issue_id => '01ABC'}
2419 :parent_issue_id => '01ABC'}
2409
2420
2410 assert_response :success
2421 assert_response :success
2411 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2422 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', '01ABC'
2412 assert_select_error /Parent task is invalid/i
2423 assert_select_error /Parent task is invalid/i
2413 end
2424 end
2414 end
2425 end
2415
2426
2416 def test_post_create_private
2427 def test_post_create_private
2417 @request.session[:user_id] = 2
2428 @request.session[:user_id] = 2
2418
2429
2419 assert_difference 'Issue.count' do
2430 assert_difference 'Issue.count' do
2420 post :create, :project_id => 1,
2431 post :create, :project_id => 1,
2421 :issue => {:tracker_id => 1,
2432 :issue => {:tracker_id => 1,
2422 :subject => 'This is a private issue',
2433 :subject => 'This is a private issue',
2423 :is_private => '1'}
2434 :is_private => '1'}
2424 end
2435 end
2425 issue = Issue.order('id DESC').first
2436 issue = Issue.order('id DESC').first
2426 assert issue.is_private?
2437 assert issue.is_private?
2427 end
2438 end
2428
2439
2429 def test_post_create_private_with_set_own_issues_private_permission
2440 def test_post_create_private_with_set_own_issues_private_permission
2430 role = Role.find(1)
2441 role = Role.find(1)
2431 role.remove_permission! :set_issues_private
2442 role.remove_permission! :set_issues_private
2432 role.add_permission! :set_own_issues_private
2443 role.add_permission! :set_own_issues_private
2433
2444
2434 @request.session[:user_id] = 2
2445 @request.session[:user_id] = 2
2435
2446
2436 assert_difference 'Issue.count' do
2447 assert_difference 'Issue.count' do
2437 post :create, :project_id => 1,
2448 post :create, :project_id => 1,
2438 :issue => {:tracker_id => 1,
2449 :issue => {:tracker_id => 1,
2439 :subject => 'This is a private issue',
2450 :subject => 'This is a private issue',
2440 :is_private => '1'}
2451 :is_private => '1'}
2441 end
2452 end
2442 issue = Issue.order('id DESC').first
2453 issue = Issue.order('id DESC').first
2443 assert issue.is_private?
2454 assert issue.is_private?
2444 end
2455 end
2445
2456
2446 def test_create_without_project_id
2457 def test_create_without_project_id
2447 @request.session[:user_id] = 2
2458 @request.session[:user_id] = 2
2448
2459
2449 assert_difference 'Issue.count' do
2460 assert_difference 'Issue.count' do
2450 post :create,
2461 post :create,
2451 :issue => {:project_id => 3,
2462 :issue => {:project_id => 3,
2452 :tracker_id => 2,
2463 :tracker_id => 2,
2453 :subject => 'Foo'}
2464 :subject => 'Foo'}
2454 assert_response 302
2465 assert_response 302
2455 end
2466 end
2456 issue = Issue.order('id DESC').first
2467 issue = Issue.order('id DESC').first
2457 assert_equal 3, issue.project_id
2468 assert_equal 3, issue.project_id
2458 assert_equal 2, issue.tracker_id
2469 assert_equal 2, issue.tracker_id
2459 end
2470 end
2460
2471
2461 def test_create_without_project_id_and_continue_should_redirect_without_project_id
2472 def test_create_without_project_id_and_continue_should_redirect_without_project_id
2462 @request.session[:user_id] = 2
2473 @request.session[:user_id] = 2
2463
2474
2464 assert_difference 'Issue.count' do
2475 assert_difference 'Issue.count' do
2465 post :create,
2476 post :create,
2466 :issue => {:project_id => 3,
2477 :issue => {:project_id => 3,
2467 :tracker_id => 2,
2478 :tracker_id => 2,
2468 :subject => 'Foo'},
2479 :subject => 'Foo'},
2469 :continue => '1'
2480 :continue => '1'
2470 assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
2481 assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
2471 end
2482 end
2472 end
2483 end
2473
2484
2474 def test_create_without_project_id_should_be_denied_without_permission
2485 def test_create_without_project_id_should_be_denied_without_permission
2475 Role.non_member.remove_permission! :add_issues
2486 Role.non_member.remove_permission! :add_issues
2476 Role.anonymous.remove_permission! :add_issues
2487 Role.anonymous.remove_permission! :add_issues
2477 @request.session[:user_id] = 2
2488 @request.session[:user_id] = 2
2478
2489
2479 assert_no_difference 'Issue.count' do
2490 assert_no_difference 'Issue.count' do
2480 post :create,
2491 post :create,
2481 :issue => {:project_id => 3,
2492 :issue => {:project_id => 3,
2482 :tracker_id => 2,
2493 :tracker_id => 2,
2483 :subject => 'Foo'}
2494 :subject => 'Foo'}
2484 assert_response 422
2495 assert_response 422
2485 end
2496 end
2486 end
2497 end
2487
2498
2488 def test_create_without_project_id_with_failure
2499 def test_create_without_project_id_with_failure
2489 @request.session[:user_id] = 2
2500 @request.session[:user_id] = 2
2490
2501
2491 post :create,
2502 post :create,
2492 :issue => {:project_id => 3,
2503 :issue => {:project_id => 3,
2493 :tracker_id => 2,
2504 :tracker_id => 2,
2494 :subject => ''}
2505 :subject => ''}
2495 assert_response :success
2506 assert_response :success
2496 assert_nil assigns(:project)
2507 assert_nil assigns(:project)
2497 end
2508 end
2498
2509
2499 def test_post_create_should_send_a_notification
2510 def test_post_create_should_send_a_notification
2500 ActionMailer::Base.deliveries.clear
2511 ActionMailer::Base.deliveries.clear
2501 @request.session[:user_id] = 2
2512 @request.session[:user_id] = 2
2502 with_settings :notified_events => %w(issue_added) do
2513 with_settings :notified_events => %w(issue_added) do
2503 assert_difference 'Issue.count' do
2514 assert_difference 'Issue.count' do
2504 post :create, :project_id => 1,
2515 post :create, :project_id => 1,
2505 :issue => {:tracker_id => 3,
2516 :issue => {:tracker_id => 3,
2506 :subject => 'This is the test_new issue',
2517 :subject => 'This is the test_new issue',
2507 :description => 'This is the description',
2518 :description => 'This is the description',
2508 :priority_id => 5,
2519 :priority_id => 5,
2509 :estimated_hours => '',
2520 :estimated_hours => '',
2510 :custom_field_values => {'2' => 'Value for field 2'}}
2521 :custom_field_values => {'2' => 'Value for field 2'}}
2511 end
2522 end
2512 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2523 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
2513
2524
2514 assert_equal 1, ActionMailer::Base.deliveries.size
2525 assert_equal 1, ActionMailer::Base.deliveries.size
2515 end
2526 end
2516 end
2527 end
2517
2528
2518 def test_post_create_should_preserve_fields_values_on_validation_failure
2529 def test_post_create_should_preserve_fields_values_on_validation_failure
2519 @request.session[:user_id] = 2
2530 @request.session[:user_id] = 2
2520 post :create, :project_id => 1,
2531 post :create, :project_id => 1,
2521 :issue => {:tracker_id => 1,
2532 :issue => {:tracker_id => 1,
2522 # empty subject
2533 # empty subject
2523 :subject => '',
2534 :subject => '',
2524 :description => 'This is a description',
2535 :description => 'This is a description',
2525 :priority_id => 6,
2536 :priority_id => 6,
2526 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2537 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
2527 assert_response :success
2538 assert_response :success
2528 assert_template 'new'
2539 assert_template 'new'
2529
2540
2530 assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
2541 assert_select 'textarea[name=?]', 'issue[description]', :text => 'This is a description'
2531 assert_select 'select[name=?]', 'issue[priority_id]' do
2542 assert_select 'select[name=?]', 'issue[priority_id]' do
2532 assert_select 'option[value="6"][selected=selected]', :text => 'High'
2543 assert_select 'option[value="6"][selected=selected]', :text => 'High'
2533 end
2544 end
2534 # Custom fields
2545 # Custom fields
2535 assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
2546 assert_select 'select[name=?]', 'issue[custom_field_values][1]' do
2536 assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
2547 assert_select 'option[value=Oracle][selected=selected]', :text => 'Oracle'
2537 end
2548 end
2538 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
2549 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', 'Value for field 2'
2539 end
2550 end
2540
2551
2541 def test_post_create_with_failure_should_preserve_watchers
2552 def test_post_create_with_failure_should_preserve_watchers
2542 assert !User.find(8).member_of?(Project.find(1))
2553 assert !User.find(8).member_of?(Project.find(1))
2543
2554
2544 @request.session[:user_id] = 2
2555 @request.session[:user_id] = 2
2545 post :create, :project_id => 1,
2556 post :create, :project_id => 1,
2546 :issue => {:tracker_id => 1,
2557 :issue => {:tracker_id => 1,
2547 :watcher_user_ids => ['3', '8']}
2558 :watcher_user_ids => ['3', '8']}
2548 assert_response :success
2559 assert_response :success
2549 assert_template 'new'
2560 assert_template 'new'
2550
2561
2551 assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
2562 assert_select 'input[name=?][value="2"]:not(checked)', 'issue[watcher_user_ids][]'
2552 assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
2563 assert_select 'input[name=?][value="3"][checked=checked]', 'issue[watcher_user_ids][]'
2553 assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
2564 assert_select 'input[name=?][value="8"][checked=checked]', 'issue[watcher_user_ids][]'
2554 end
2565 end
2555
2566
2556 def test_post_create_should_ignore_non_safe_attributes
2567 def test_post_create_should_ignore_non_safe_attributes
2557 @request.session[:user_id] = 2
2568 @request.session[:user_id] = 2
2558 assert_nothing_raised do
2569 assert_nothing_raised do
2559 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2570 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
2560 end
2571 end
2561 end
2572 end
2562
2573
2563 def test_post_create_with_attachment
2574 def test_post_create_with_attachment
2564 set_tmp_attachments_directory
2575 set_tmp_attachments_directory
2565 @request.session[:user_id] = 2
2576 @request.session[:user_id] = 2
2566
2577
2567 assert_difference 'Issue.count' do
2578 assert_difference 'Issue.count' do
2568 assert_difference 'Attachment.count' do
2579 assert_difference 'Attachment.count' do
2569 assert_no_difference 'Journal.count' do
2580 assert_no_difference 'Journal.count' do
2570 post :create, :project_id => 1,
2581 post :create, :project_id => 1,
2571 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2582 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2572 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2583 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2573 end
2584 end
2574 end
2585 end
2575 end
2586 end
2576
2587
2577 issue = Issue.order('id DESC').first
2588 issue = Issue.order('id DESC').first
2578 attachment = Attachment.order('id DESC').first
2589 attachment = Attachment.order('id DESC').first
2579
2590
2580 assert_equal issue, attachment.container
2591 assert_equal issue, attachment.container
2581 assert_equal 2, attachment.author_id
2592 assert_equal 2, attachment.author_id
2582 assert_equal 'testfile.txt', attachment.filename
2593 assert_equal 'testfile.txt', attachment.filename
2583 assert_equal 'text/plain', attachment.content_type
2594 assert_equal 'text/plain', attachment.content_type
2584 assert_equal 'test file', attachment.description
2595 assert_equal 'test file', attachment.description
2585 assert_equal 59, attachment.filesize
2596 assert_equal 59, attachment.filesize
2586 assert File.exists?(attachment.diskfile)
2597 assert File.exists?(attachment.diskfile)
2587 assert_equal 59, File.size(attachment.diskfile)
2598 assert_equal 59, File.size(attachment.diskfile)
2588 end
2599 end
2589
2600
2590 def test_post_create_with_attachment_should_notify_with_attachments
2601 def test_post_create_with_attachment_should_notify_with_attachments
2591 ActionMailer::Base.deliveries.clear
2602 ActionMailer::Base.deliveries.clear
2592 set_tmp_attachments_directory
2603 set_tmp_attachments_directory
2593 @request.session[:user_id] = 2
2604 @request.session[:user_id] = 2
2594
2605
2595 with_settings :host_name => 'mydomain.foo', :protocol => 'http', :notified_events => %w(issue_added) do
2606 with_settings :host_name => 'mydomain.foo', :protocol => 'http', :notified_events => %w(issue_added) do
2596 assert_difference 'Issue.count' do
2607 assert_difference 'Issue.count' do
2597 post :create, :project_id => 1,
2608 post :create, :project_id => 1,
2598 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2609 :issue => { :tracker_id => '1', :subject => 'With attachment' },
2599 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2610 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2600 end
2611 end
2601 end
2612 end
2602
2613
2603 assert_not_nil ActionMailer::Base.deliveries.last
2614 assert_not_nil ActionMailer::Base.deliveries.last
2604 assert_select_email do
2615 assert_select_email do
2605 assert_select 'a[href^=?]', 'http://mydomain.foo/attachments/download', 'testfile.txt'
2616 assert_select 'a[href^=?]', 'http://mydomain.foo/attachments/download', 'testfile.txt'
2606 end
2617 end
2607 end
2618 end
2608
2619
2609 def test_post_create_with_failure_should_save_attachments
2620 def test_post_create_with_failure_should_save_attachments
2610 set_tmp_attachments_directory
2621 set_tmp_attachments_directory
2611 @request.session[:user_id] = 2
2622 @request.session[:user_id] = 2
2612
2623
2613 assert_no_difference 'Issue.count' do
2624 assert_no_difference 'Issue.count' do
2614 assert_difference 'Attachment.count' do
2625 assert_difference 'Attachment.count' do
2615 post :create, :project_id => 1,
2626 post :create, :project_id => 1,
2616 :issue => { :tracker_id => '1', :subject => '' },
2627 :issue => { :tracker_id => '1', :subject => '' },
2617 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2628 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
2618 assert_response :success
2629 assert_response :success
2619 assert_template 'new'
2630 assert_template 'new'
2620 end
2631 end
2621 end
2632 end
2622
2633
2623 attachment = Attachment.order('id DESC').first
2634 attachment = Attachment.order('id DESC').first
2624 assert_equal 'testfile.txt', attachment.filename
2635 assert_equal 'testfile.txt', attachment.filename
2625 assert File.exists?(attachment.diskfile)
2636 assert File.exists?(attachment.diskfile)
2626 assert_nil attachment.container
2637 assert_nil attachment.container
2627
2638
2628 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2639 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2629 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2640 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2630 end
2641 end
2631
2642
2632 def test_post_create_with_failure_should_keep_saved_attachments
2643 def test_post_create_with_failure_should_keep_saved_attachments
2633 set_tmp_attachments_directory
2644 set_tmp_attachments_directory
2634 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2645 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2635 @request.session[:user_id] = 2
2646 @request.session[:user_id] = 2
2636
2647
2637 assert_no_difference 'Issue.count' do
2648 assert_no_difference 'Issue.count' do
2638 assert_no_difference 'Attachment.count' do
2649 assert_no_difference 'Attachment.count' do
2639 post :create, :project_id => 1,
2650 post :create, :project_id => 1,
2640 :issue => { :tracker_id => '1', :subject => '' },
2651 :issue => { :tracker_id => '1', :subject => '' },
2641 :attachments => {'p0' => {'token' => attachment.token}}
2652 :attachments => {'p0' => {'token' => attachment.token}}
2642 assert_response :success
2653 assert_response :success
2643 assert_template 'new'
2654 assert_template 'new'
2644 end
2655 end
2645 end
2656 end
2646
2657
2647 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2658 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
2648 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2659 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
2649 end
2660 end
2650
2661
2651 def test_post_create_should_attach_saved_attachments
2662 def test_post_create_should_attach_saved_attachments
2652 set_tmp_attachments_directory
2663 set_tmp_attachments_directory
2653 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2664 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
2654 @request.session[:user_id] = 2
2665 @request.session[:user_id] = 2
2655
2666
2656 assert_difference 'Issue.count' do
2667 assert_difference 'Issue.count' do
2657 assert_no_difference 'Attachment.count' do
2668 assert_no_difference 'Attachment.count' do
2658 post :create, :project_id => 1,
2669 post :create, :project_id => 1,
2659 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2670 :issue => { :tracker_id => '1', :subject => 'Saved attachments' },
2660 :attachments => {'p0' => {'token' => attachment.token}}
2671 :attachments => {'p0' => {'token' => attachment.token}}
2661 assert_response 302
2672 assert_response 302
2662 end
2673 end
2663 end
2674 end
2664
2675
2665 issue = Issue.order('id DESC').first
2676 issue = Issue.order('id DESC').first
2666 assert_equal 1, issue.attachments.count
2677 assert_equal 1, issue.attachments.count
2667
2678
2668 attachment.reload
2679 attachment.reload
2669 assert_equal issue, attachment.container
2680 assert_equal issue, attachment.container
2670 end
2681 end
2671
2682
2672 def setup_without_workflow_privilege
2683 def setup_without_workflow_privilege
2673 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2684 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2674 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2685 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2675 end
2686 end
2676 private :setup_without_workflow_privilege
2687 private :setup_without_workflow_privilege
2677
2688
2678 test "without workflow privilege #new should propose default status only" do
2689 test "without workflow privilege #new should propose default status only" do
2679 setup_without_workflow_privilege
2690 setup_without_workflow_privilege
2680 get :new, :project_id => 1
2691 get :new, :project_id => 1
2681 assert_response :success
2692 assert_response :success
2682 assert_template 'new'
2693 assert_template 'new'
2683
2694
2684 issue = assigns(:issue)
2695 issue = assigns(:issue)
2685 assert_not_nil issue.default_status
2696 assert_not_nil issue.default_status
2686
2697
2687 assert_select 'select[name=?]', 'issue[status_id]' do
2698 assert_select 'select[name=?]', 'issue[status_id]' do
2688 assert_select 'option', 1
2699 assert_select 'option', 1
2689 assert_select 'option[value=?]', issue.default_status.id.to_s
2700 assert_select 'option[value=?]', issue.default_status.id.to_s
2690 end
2701 end
2691 end
2702 end
2692
2703
2693 test "without workflow privilege #create should accept default status" do
2704 test "without workflow privilege #create should accept default status" do
2694 setup_without_workflow_privilege
2705 setup_without_workflow_privilege
2695 assert_difference 'Issue.count' do
2706 assert_difference 'Issue.count' do
2696 post :create, :project_id => 1,
2707 post :create, :project_id => 1,
2697 :issue => {:tracker_id => 1,
2708 :issue => {:tracker_id => 1,
2698 :subject => 'This is an issue',
2709 :subject => 'This is an issue',
2699 :status_id => 1}
2710 :status_id => 1}
2700 end
2711 end
2701 issue = Issue.order('id').last
2712 issue = Issue.order('id').last
2702 assert_not_nil issue.default_status
2713 assert_not_nil issue.default_status
2703 assert_equal issue.default_status, issue.status
2714 assert_equal issue.default_status, issue.status
2704 end
2715 end
2705
2716
2706 test "without workflow privilege #create should ignore unauthorized status" do
2717 test "without workflow privilege #create should ignore unauthorized status" do
2707 setup_without_workflow_privilege
2718 setup_without_workflow_privilege
2708 assert_difference 'Issue.count' do
2719 assert_difference 'Issue.count' do
2709 post :create, :project_id => 1,
2720 post :create, :project_id => 1,
2710 :issue => {:tracker_id => 1,
2721 :issue => {:tracker_id => 1,
2711 :subject => 'This is an issue',
2722 :subject => 'This is an issue',
2712 :status_id => 3}
2723 :status_id => 3}
2713 end
2724 end
2714 issue = Issue.order('id').last
2725 issue = Issue.order('id').last
2715 assert_not_nil issue.default_status
2726 assert_not_nil issue.default_status
2716 assert_equal issue.default_status, issue.status
2727 assert_equal issue.default_status, issue.status
2717 end
2728 end
2718
2729
2719 test "without workflow privilege #update should ignore status change" do
2730 test "without workflow privilege #update should ignore status change" do
2720 setup_without_workflow_privilege
2731 setup_without_workflow_privilege
2721 assert_difference 'Journal.count' do
2732 assert_difference 'Journal.count' do
2722 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2733 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2723 end
2734 end
2724 assert_equal 1, Issue.find(1).status_id
2735 assert_equal 1, Issue.find(1).status_id
2725 end
2736 end
2726
2737
2727 test "without workflow privilege #update ignore attributes changes" do
2738 test "without workflow privilege #update ignore attributes changes" do
2728 setup_without_workflow_privilege
2739 setup_without_workflow_privilege
2729 assert_difference 'Journal.count' do
2740 assert_difference 'Journal.count' do
2730 put :update, :id => 1,
2741 put :update, :id => 1,
2731 :issue => {:subject => 'changed', :assigned_to_id => 2,
2742 :issue => {:subject => 'changed', :assigned_to_id => 2,
2732 :notes => 'just trying'}
2743 :notes => 'just trying'}
2733 end
2744 end
2734 issue = Issue.find(1)
2745 issue = Issue.find(1)
2735 assert_equal "Cannot print recipes", issue.subject
2746 assert_equal "Cannot print recipes", issue.subject
2736 assert_nil issue.assigned_to
2747 assert_nil issue.assigned_to
2737 end
2748 end
2738
2749
2739 def setup_with_workflow_privilege
2750 def setup_with_workflow_privilege
2740 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2751 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2741 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2752 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2742 :old_status_id => 1, :new_status_id => 3)
2753 :old_status_id => 1, :new_status_id => 3)
2743 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2754 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1,
2744 :old_status_id => 1, :new_status_id => 4)
2755 :old_status_id => 1, :new_status_id => 4)
2745 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2756 Role.anonymous.add_permission! :add_issues, :add_issue_notes
2746 end
2757 end
2747 private :setup_with_workflow_privilege
2758 private :setup_with_workflow_privilege
2748
2759
2749 def setup_with_workflow_privilege_and_edit_issues_permission
2760 def setup_with_workflow_privilege_and_edit_issues_permission
2750 setup_with_workflow_privilege
2761 setup_with_workflow_privilege
2751 Role.anonymous.add_permission! :add_issues, :edit_issues
2762 Role.anonymous.add_permission! :add_issues, :edit_issues
2752 end
2763 end
2753 private :setup_with_workflow_privilege_and_edit_issues_permission
2764 private :setup_with_workflow_privilege_and_edit_issues_permission
2754
2765
2755 test "with workflow privilege and :edit_issues permission should accept authorized status" do
2766 test "with workflow privilege and :edit_issues permission should accept authorized status" do
2756 setup_with_workflow_privilege_and_edit_issues_permission
2767 setup_with_workflow_privilege_and_edit_issues_permission
2757 assert_difference 'Journal.count' do
2768 assert_difference 'Journal.count' do
2758 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2769 put :update, :id => 1, :issue => {:status_id => 3, :notes => 'just trying'}
2759 end
2770 end
2760 assert_equal 3, Issue.find(1).status_id
2771 assert_equal 3, Issue.find(1).status_id
2761 end
2772 end
2762
2773
2763 test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
2774 test "with workflow privilege and :edit_issues permission should ignore unauthorized status" do
2764 setup_with_workflow_privilege_and_edit_issues_permission
2775 setup_with_workflow_privilege_and_edit_issues_permission
2765 assert_difference 'Journal.count' do
2776 assert_difference 'Journal.count' do
2766 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2777 put :update, :id => 1, :issue => {:status_id => 2, :notes => 'just trying'}
2767 end
2778 end
2768 assert_equal 1, Issue.find(1).status_id
2779 assert_equal 1, Issue.find(1).status_id
2769 end
2780 end
2770
2781
2771 test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
2782 test "with workflow privilege and :edit_issues permission should accept authorized attributes changes" do
2772 setup_with_workflow_privilege_and_edit_issues_permission
2783 setup_with_workflow_privilege_and_edit_issues_permission
2773 assert_difference 'Journal.count' do
2784 assert_difference 'Journal.count' do
2774 put :update, :id => 1,
2785 put :update, :id => 1,
2775 :issue => {:subject => 'changed', :assigned_to_id => 2,
2786 :issue => {:subject => 'changed', :assigned_to_id => 2,
2776 :notes => 'just trying'}
2787 :notes => 'just trying'}
2777 end
2788 end
2778 issue = Issue.find(1)
2789 issue = Issue.find(1)
2779 assert_equal "changed", issue.subject
2790 assert_equal "changed", issue.subject
2780 assert_equal 2, issue.assigned_to_id
2791 assert_equal 2, issue.assigned_to_id
2781 end
2792 end
2782
2793
2783 def test_new_as_copy
2794 def test_new_as_copy
2784 @request.session[:user_id] = 2
2795 @request.session[:user_id] = 2
2785 get :new, :project_id => 1, :copy_from => 1
2796 get :new, :project_id => 1, :copy_from => 1
2786
2797
2787 assert_response :success
2798 assert_response :success
2788 assert_template 'new'
2799 assert_template 'new'
2789
2800
2790 assert_not_nil assigns(:issue)
2801 assert_not_nil assigns(:issue)
2791 orig = Issue.find(1)
2802 orig = Issue.find(1)
2792 assert_equal 1, assigns(:issue).project_id
2803 assert_equal 1, assigns(:issue).project_id
2793 assert_equal orig.subject, assigns(:issue).subject
2804 assert_equal orig.subject, assigns(:issue).subject
2794 assert assigns(:issue).copy?
2805 assert assigns(:issue).copy?
2795
2806
2796 assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
2807 assert_select 'form[id=issue-form][action="/projects/ecookbook/issues"]' do
2797 assert_select 'select[name=?]', 'issue[project_id]' do
2808 assert_select 'select[name=?]', 'issue[project_id]' do
2798 assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
2809 assert_select 'option[value="1"][selected=selected]', :text => 'eCookbook'
2799 assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
2810 assert_select 'option[value="2"]:not([selected])', :text => 'OnlineStore'
2800 end
2811 end
2801 assert_select 'input[name=copy_from][value="1"]'
2812 assert_select 'input[name=copy_from][value="1"]'
2802 end
2813 end
2803
2814
2804 # "New issue" menu item should not link to copy
2815 # "New issue" menu item should not link to copy
2805 assert_select '#main-menu a.new-issue[href="/projects/ecookbook/issues/new"]'
2816 assert_select '#main-menu a.new-issue[href="/projects/ecookbook/issues/new"]'
2806 end
2817 end
2807
2818
2808 def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
2819 def test_new_as_copy_without_add_issues_permission_should_not_propose_current_project_as_target
2809 user = setup_user_with_copy_but_not_add_permission
2820 user = setup_user_with_copy_but_not_add_permission
2810
2821
2811 @request.session[:user_id] = user.id
2822 @request.session[:user_id] = user.id
2812 get :new, :project_id => 1, :copy_from => 1
2823 get :new, :project_id => 1, :copy_from => 1
2813
2824
2814 assert_response :success
2825 assert_response :success
2815 assert_template 'new'
2826 assert_template 'new'
2816 assert_select 'select[name=?]', 'issue[project_id]' do
2827 assert_select 'select[name=?]', 'issue[project_id]' do
2817 assert_select 'option[value="1"]', 0
2828 assert_select 'option[value="1"]', 0
2818 assert_select 'option[value="2"]', :text => 'OnlineStore'
2829 assert_select 'option[value="2"]', :text => 'OnlineStore'
2819 end
2830 end
2820 end
2831 end
2821
2832
2822 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2833 def test_new_as_copy_with_attachments_should_show_copy_attachments_checkbox
2823 @request.session[:user_id] = 2
2834 @request.session[:user_id] = 2
2824 issue = Issue.find(3)
2835 issue = Issue.find(3)
2825 assert issue.attachments.count > 0
2836 assert issue.attachments.count > 0
2826 get :new, :project_id => 1, :copy_from => 3
2837 get :new, :project_id => 1, :copy_from => 3
2827
2838
2828 assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
2839 assert_select 'input[name=copy_attachments][type=checkbox][checked=checked][value="1"]'
2829 end
2840 end
2830
2841
2831 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2842 def test_new_as_copy_without_attachments_should_not_show_copy_attachments_checkbox
2832 @request.session[:user_id] = 2
2843 @request.session[:user_id] = 2
2833 issue = Issue.find(3)
2844 issue = Issue.find(3)
2834 issue.attachments.delete_all
2845 issue.attachments.delete_all
2835 get :new, :project_id => 1, :copy_from => 3
2846 get :new, :project_id => 1, :copy_from => 3
2836
2847
2837 assert_select 'input[name=copy_attachments]', 0
2848 assert_select 'input[name=copy_attachments]', 0
2838 end
2849 end
2839
2850
2840 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2851 def test_new_as_copy_with_subtasks_should_show_copy_subtasks_checkbox
2841 @request.session[:user_id] = 2
2852 @request.session[:user_id] = 2
2842 issue = Issue.generate_with_descendants!
2853 issue = Issue.generate_with_descendants!
2843 get :new, :project_id => 1, :copy_from => issue.id
2854 get :new, :project_id => 1, :copy_from => issue.id
2844
2855
2845 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
2856 assert_select 'input[type=checkbox][name=copy_subtasks][checked=checked][value="1"]'
2846 end
2857 end
2847
2858
2848 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2859 def test_new_as_copy_with_invalid_issue_should_respond_with_404
2849 @request.session[:user_id] = 2
2860 @request.session[:user_id] = 2
2850 get :new, :project_id => 1, :copy_from => 99999
2861 get :new, :project_id => 1, :copy_from => 99999
2851 assert_response 404
2862 assert_response 404
2852 end
2863 end
2853
2864
2854 def test_create_as_copy_on_different_project
2865 def test_create_as_copy_on_different_project
2855 @request.session[:user_id] = 2
2866 @request.session[:user_id] = 2
2856 assert_difference 'Issue.count' do
2867 assert_difference 'Issue.count' do
2857 post :create, :project_id => 1, :copy_from => 1,
2868 post :create, :project_id => 1, :copy_from => 1,
2858 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2869 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
2859
2870
2860 assert_not_nil assigns(:issue)
2871 assert_not_nil assigns(:issue)
2861 assert assigns(:issue).copy?
2872 assert assigns(:issue).copy?
2862 end
2873 end
2863 issue = Issue.order('id DESC').first
2874 issue = Issue.order('id DESC').first
2864 assert_redirected_to "/issues/#{issue.id}"
2875 assert_redirected_to "/issues/#{issue.id}"
2865
2876
2866 assert_equal 2, issue.project_id
2877 assert_equal 2, issue.project_id
2867 assert_equal 3, issue.tracker_id
2878 assert_equal 3, issue.tracker_id
2868 assert_equal 'Copy', issue.subject
2879 assert_equal 'Copy', issue.subject
2869 end
2880 end
2870
2881
2871 def test_create_as_copy_should_allow_status_to_be_set_to_default
2882 def test_create_as_copy_should_allow_status_to_be_set_to_default
2872 copied = Issue.generate! :status_id => 2
2883 copied = Issue.generate! :status_id => 2
2873 assert_equal 2, copied.reload.status_id
2884 assert_equal 2, copied.reload.status_id
2874
2885
2875 @request.session[:user_id] = 2
2886 @request.session[:user_id] = 2
2876 assert_difference 'Issue.count' do
2887 assert_difference 'Issue.count' do
2877 post :create, :project_id => 1, :copy_from => copied.id,
2888 post :create, :project_id => 1, :copy_from => copied.id,
2878 :issue => {:project_id => '1', :tracker_id => '1', :status_id => '1'},
2889 :issue => {:project_id => '1', :tracker_id => '1', :status_id => '1'},
2879 :was_default_status => '1'
2890 :was_default_status => '1'
2880 end
2891 end
2881 issue = Issue.order('id DESC').first
2892 issue = Issue.order('id DESC').first
2882 assert_equal 1, issue.status_id
2893 assert_equal 1, issue.status_id
2883 end
2894 end
2884
2895
2885 def test_create_as_copy_should_copy_attachments
2896 def test_create_as_copy_should_copy_attachments
2886 @request.session[:user_id] = 2
2897 @request.session[:user_id] = 2
2887 issue = Issue.find(3)
2898 issue = Issue.find(3)
2888 count = issue.attachments.count
2899 count = issue.attachments.count
2889 assert count > 0
2900 assert count > 0
2890 assert_difference 'Issue.count' do
2901 assert_difference 'Issue.count' do
2891 assert_difference 'Attachment.count', count do
2902 assert_difference 'Attachment.count', count do
2892 post :create, :project_id => 1, :copy_from => 3,
2903 post :create, :project_id => 1, :copy_from => 3,
2893 :issue => {:project_id => '1', :tracker_id => '3',
2904 :issue => {:project_id => '1', :tracker_id => '3',
2894 :status_id => '1', :subject => 'Copy with attachments'},
2905 :status_id => '1', :subject => 'Copy with attachments'},
2895 :copy_attachments => '1'
2906 :copy_attachments => '1'
2896 end
2907 end
2897 end
2908 end
2898 copy = Issue.order('id DESC').first
2909 copy = Issue.order('id DESC').first
2899 assert_equal count, copy.attachments.count
2910 assert_equal count, copy.attachments.count
2900 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2911 assert_equal issue.attachments.map(&:filename).sort, copy.attachments.map(&:filename).sort
2901 end
2912 end
2902
2913
2903 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2914 def test_create_as_copy_without_copy_attachments_option_should_not_copy_attachments
2904 @request.session[:user_id] = 2
2915 @request.session[:user_id] = 2
2905 issue = Issue.find(3)
2916 issue = Issue.find(3)
2906 count = issue.attachments.count
2917 count = issue.attachments.count
2907 assert count > 0
2918 assert count > 0
2908 assert_difference 'Issue.count' do
2919 assert_difference 'Issue.count' do
2909 assert_no_difference 'Attachment.count' do
2920 assert_no_difference 'Attachment.count' do
2910 post :create, :project_id => 1, :copy_from => 3,
2921 post :create, :project_id => 1, :copy_from => 3,
2911 :issue => {:project_id => '1', :tracker_id => '3',
2922 :issue => {:project_id => '1', :tracker_id => '3',
2912 :status_id => '1', :subject => 'Copy with attachments'}
2923 :status_id => '1', :subject => 'Copy with attachments'}
2913 end
2924 end
2914 end
2925 end
2915 copy = Issue.order('id DESC').first
2926 copy = Issue.order('id DESC').first
2916 assert_equal 0, copy.attachments.count
2927 assert_equal 0, copy.attachments.count
2917 end
2928 end
2918
2929
2919 def test_create_as_copy_with_attachments_should_also_add_new_files
2930 def test_create_as_copy_with_attachments_should_also_add_new_files
2920 @request.session[:user_id] = 2
2931 @request.session[:user_id] = 2
2921 issue = Issue.find(3)
2932 issue = Issue.find(3)
2922 count = issue.attachments.count
2933 count = issue.attachments.count
2923 assert count > 0
2934 assert count > 0
2924 assert_difference 'Issue.count' do
2935 assert_difference 'Issue.count' do
2925 assert_difference 'Attachment.count', count + 1 do
2936 assert_difference 'Attachment.count', count + 1 do
2926 post :create, :project_id => 1, :copy_from => 3,
2937 post :create, :project_id => 1, :copy_from => 3,
2927 :issue => {:project_id => '1', :tracker_id => '3',
2938 :issue => {:project_id => '1', :tracker_id => '3',
2928 :status_id => '1', :subject => 'Copy with attachments'},
2939 :status_id => '1', :subject => 'Copy with attachments'},
2929 :copy_attachments => '1',
2940 :copy_attachments => '1',
2930 :attachments => {'1' =>
2941 :attachments => {'1' =>
2931 {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
2942 {'file' => uploaded_test_file('testfile.txt', 'text/plain'),
2932 'description' => 'test file'}}
2943 'description' => 'test file'}}
2933 end
2944 end
2934 end
2945 end
2935 copy = Issue.order('id DESC').first
2946 copy = Issue.order('id DESC').first
2936 assert_equal count + 1, copy.attachments.count
2947 assert_equal count + 1, copy.attachments.count
2937 end
2948 end
2938
2949
2939 def test_create_as_copy_should_add_relation_with_copied_issue
2950 def test_create_as_copy_should_add_relation_with_copied_issue
2940 @request.session[:user_id] = 2
2951 @request.session[:user_id] = 2
2941 assert_difference 'Issue.count' do
2952 assert_difference 'Issue.count' do
2942 assert_difference 'IssueRelation.count' do
2953 assert_difference 'IssueRelation.count' do
2943 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2954 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2944 :issue => {:project_id => '1', :tracker_id => '3',
2955 :issue => {:project_id => '1', :tracker_id => '3',
2945 :status_id => '1', :subject => 'Copy'}
2956 :status_id => '1', :subject => 'Copy'}
2946 end
2957 end
2947 end
2958 end
2948 copy = Issue.order('id DESC').first
2959 copy = Issue.order('id DESC').first
2949 assert_equal 1, copy.relations.size
2960 assert_equal 1, copy.relations.size
2950 end
2961 end
2951
2962
2952 def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
2963 def test_create_as_copy_should_allow_not_to_add_relation_with_copied_issue
2953 @request.session[:user_id] = 2
2964 @request.session[:user_id] = 2
2954 assert_difference 'Issue.count' do
2965 assert_difference 'Issue.count' do
2955 assert_no_difference 'IssueRelation.count' do
2966 assert_no_difference 'IssueRelation.count' do
2956 post :create, :project_id => 1, :copy_from => 1,
2967 post :create, :project_id => 1, :copy_from => 1,
2957 :issue => {:subject => 'Copy'}
2968 :issue => {:subject => 'Copy'}
2958 end
2969 end
2959 end
2970 end
2960 end
2971 end
2961
2972
2962 def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
2973 def test_create_as_copy_should_always_add_relation_with_copied_issue_by_setting
2963 with_settings :link_copied_issue => 'yes' do
2974 with_settings :link_copied_issue => 'yes' do
2964 @request.session[:user_id] = 2
2975 @request.session[:user_id] = 2
2965 assert_difference 'Issue.count' do
2976 assert_difference 'Issue.count' do
2966 assert_difference 'IssueRelation.count' do
2977 assert_difference 'IssueRelation.count' do
2967 post :create, :project_id => 1, :copy_from => 1,
2978 post :create, :project_id => 1, :copy_from => 1,
2968 :issue => {:subject => 'Copy'}
2979 :issue => {:subject => 'Copy'}
2969 end
2980 end
2970 end
2981 end
2971 end
2982 end
2972 end
2983 end
2973
2984
2974 def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
2985 def test_create_as_copy_should_never_add_relation_with_copied_issue_by_setting
2975 with_settings :link_copied_issue => 'no' do
2986 with_settings :link_copied_issue => 'no' do
2976 @request.session[:user_id] = 2
2987 @request.session[:user_id] = 2
2977 assert_difference 'Issue.count' do
2988 assert_difference 'Issue.count' do
2978 assert_no_difference 'IssueRelation.count' do
2989 assert_no_difference 'IssueRelation.count' do
2979 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2990 post :create, :project_id => 1, :copy_from => 1, :link_copy => '1',
2980 :issue => {:subject => 'Copy'}
2991 :issue => {:subject => 'Copy'}
2981 end
2992 end
2982 end
2993 end
2983 end
2994 end
2984 end
2995 end
2985
2996
2986 def test_create_as_copy_should_copy_subtasks
2997 def test_create_as_copy_should_copy_subtasks
2987 @request.session[:user_id] = 2
2998 @request.session[:user_id] = 2
2988 issue = Issue.generate_with_descendants!
2999 issue = Issue.generate_with_descendants!
2989 count = issue.descendants.count
3000 count = issue.descendants.count
2990 assert_difference 'Issue.count', count + 1 do
3001 assert_difference 'Issue.count', count + 1 do
2991 post :create, :project_id => 1, :copy_from => issue.id,
3002 post :create, :project_id => 1, :copy_from => issue.id,
2992 :issue => {:project_id => '1', :tracker_id => '3',
3003 :issue => {:project_id => '1', :tracker_id => '3',
2993 :status_id => '1', :subject => 'Copy with subtasks'},
3004 :status_id => '1', :subject => 'Copy with subtasks'},
2994 :copy_subtasks => '1'
3005 :copy_subtasks => '1'
2995 end
3006 end
2996 copy = Issue.where(:parent_id => nil).order('id DESC').first
3007 copy = Issue.where(:parent_id => nil).order('id DESC').first
2997 assert_equal count, copy.descendants.count
3008 assert_equal count, copy.descendants.count
2998 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
3009 assert_equal issue.descendants.map(&:subject).sort, copy.descendants.map(&:subject).sort
2999 end
3010 end
3000
3011
3001 def test_create_as_copy_to_a_different_project_should_copy_subtask_custom_fields
3012 def test_create_as_copy_to_a_different_project_should_copy_subtask_custom_fields
3002 issue = Issue.generate! {|i| i.custom_field_values = {'2' => 'Foo'}}
3013 issue = Issue.generate! {|i| i.custom_field_values = {'2' => 'Foo'}}
3003 child = Issue.generate!(:parent_issue_id => issue.id) {|i| i.custom_field_values = {'2' => 'Bar'}}
3014 child = Issue.generate!(:parent_issue_id => issue.id) {|i| i.custom_field_values = {'2' => 'Bar'}}
3004 @request.session[:user_id] = 1
3015 @request.session[:user_id] = 1
3005
3016
3006 assert_difference 'Issue.count', 2 do
3017 assert_difference 'Issue.count', 2 do
3007 post :create, :project_id => 'ecookbook', :copy_from => issue.id,
3018 post :create, :project_id => 'ecookbook', :copy_from => issue.id,
3008 :issue => {:project_id => '2', :tracker_id => 1, :status_id => '1',
3019 :issue => {:project_id => '2', :tracker_id => 1, :status_id => '1',
3009 :subject => 'Copy with subtasks', :custom_field_values => {'2' => 'Foo'}},
3020 :subject => 'Copy with subtasks', :custom_field_values => {'2' => 'Foo'}},
3010 :copy_subtasks => '1'
3021 :copy_subtasks => '1'
3011 end
3022 end
3012
3023
3013 child_copy, issue_copy = Issue.order(:id => :desc).limit(2).to_a
3024 child_copy, issue_copy = Issue.order(:id => :desc).limit(2).to_a
3014 assert_equal 2, issue_copy.project_id
3025 assert_equal 2, issue_copy.project_id
3015 assert_equal 'Foo', issue_copy.custom_field_value(2)
3026 assert_equal 'Foo', issue_copy.custom_field_value(2)
3016 assert_equal 'Bar', child_copy.custom_field_value(2)
3027 assert_equal 'Bar', child_copy.custom_field_value(2)
3017 end
3028 end
3018
3029
3019 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
3030 def test_create_as_copy_without_copy_subtasks_option_should_not_copy_subtasks
3020 @request.session[:user_id] = 2
3031 @request.session[:user_id] = 2
3021 issue = Issue.generate_with_descendants!
3032 issue = Issue.generate_with_descendants!
3022 assert_difference 'Issue.count', 1 do
3033 assert_difference 'Issue.count', 1 do
3023 post :create, :project_id => 1, :copy_from => 3,
3034 post :create, :project_id => 1, :copy_from => 3,
3024 :issue => {:project_id => '1', :tracker_id => '3',
3035 :issue => {:project_id => '1', :tracker_id => '3',
3025 :status_id => '1', :subject => 'Copy with subtasks'}
3036 :status_id => '1', :subject => 'Copy with subtasks'}
3026 end
3037 end
3027 copy = Issue.where(:parent_id => nil).order('id DESC').first
3038 copy = Issue.where(:parent_id => nil).order('id DESC').first
3028 assert_equal 0, copy.descendants.count
3039 assert_equal 0, copy.descendants.count
3029 end
3040 end
3030
3041
3031 def test_create_as_copy_with_failure
3042 def test_create_as_copy_with_failure
3032 @request.session[:user_id] = 2
3043 @request.session[:user_id] = 2
3033 post :create, :project_id => 1, :copy_from => 1,
3044 post :create, :project_id => 1, :copy_from => 1,
3034 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
3045 :issue => {:project_id => '2', :tracker_id => '3', :status_id => '1', :subject => ''}
3035
3046
3036 assert_response :success
3047 assert_response :success
3037 assert_template 'new'
3048 assert_template 'new'
3038
3049
3039 assert_not_nil assigns(:issue)
3050 assert_not_nil assigns(:issue)
3040 assert assigns(:issue).copy?
3051 assert assigns(:issue).copy?
3041
3052
3042 assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
3053 assert_select 'form#issue-form[action="/projects/ecookbook/issues"]' do
3043 assert_select 'select[name=?]', 'issue[project_id]' do
3054 assert_select 'select[name=?]', 'issue[project_id]' do
3044 assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
3055 assert_select 'option[value="1"]:not([selected])', :text => 'eCookbook'
3045 assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
3056 assert_select 'option[value="2"][selected=selected]', :text => 'OnlineStore'
3046 end
3057 end
3047 assert_select 'input[name=copy_from][value="1"]'
3058 assert_select 'input[name=copy_from][value="1"]'
3048 end
3059 end
3049 end
3060 end
3050
3061
3051 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
3062 def test_create_as_copy_on_project_without_permission_should_ignore_target_project
3052 @request.session[:user_id] = 2
3063 @request.session[:user_id] = 2
3053 assert !User.find(2).member_of?(Project.find(4))
3064 assert !User.find(2).member_of?(Project.find(4))
3054
3065
3055 assert_difference 'Issue.count' do
3066 assert_difference 'Issue.count' do
3056 post :create, :project_id => 1, :copy_from => 1,
3067 post :create, :project_id => 1, :copy_from => 1,
3057 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
3068 :issue => {:project_id => '4', :tracker_id => '3', :status_id => '1', :subject => 'Copy'}
3058 end
3069 end
3059 issue = Issue.order('id DESC').first
3070 issue = Issue.order('id DESC').first
3060 assert_equal 1, issue.project_id
3071 assert_equal 1, issue.project_id
3061 end
3072 end
3062
3073
3063 def test_get_edit
3074 def test_get_edit
3064 @request.session[:user_id] = 2
3075 @request.session[:user_id] = 2
3065 get :edit, :id => 1
3076 get :edit, :id => 1
3066 assert_response :success
3077 assert_response :success
3067 assert_template 'edit'
3078 assert_template 'edit'
3068 assert_not_nil assigns(:issue)
3079 assert_not_nil assigns(:issue)
3069 assert_equal Issue.find(1), assigns(:issue)
3080 assert_equal Issue.find(1), assigns(:issue)
3070
3081
3071 # Be sure we don't display inactive IssuePriorities
3082 # Be sure we don't display inactive IssuePriorities
3072 assert ! IssuePriority.find(15).active?
3083 assert ! IssuePriority.find(15).active?
3073 assert_select 'select[name=?]', 'issue[priority_id]' do
3084 assert_select 'select[name=?]', 'issue[priority_id]' do
3074 assert_select 'option[value="15"]', 0
3085 assert_select 'option[value="15"]', 0
3075 end
3086 end
3076 end
3087 end
3077
3088
3078 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
3089 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
3079 @request.session[:user_id] = 2
3090 @request.session[:user_id] = 2
3080 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
3091 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
3081
3092
3082 get :edit, :id => 1
3093 get :edit, :id => 1
3083 assert_select 'input[name=?]', 'time_entry[hours]'
3094 assert_select 'input[name=?]', 'time_entry[hours]'
3084 end
3095 end
3085
3096
3086 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
3097 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
3087 @request.session[:user_id] = 2
3098 @request.session[:user_id] = 2
3088 Role.find_by_name('Manager').remove_permission! :log_time
3099 Role.find_by_name('Manager').remove_permission! :log_time
3089
3100
3090 get :edit, :id => 1
3101 get :edit, :id => 1
3091 assert_select 'input[name=?]', 'time_entry[hours]', 0
3102 assert_select 'input[name=?]', 'time_entry[hours]', 0
3092 end
3103 end
3093
3104
3094 def test_get_edit_with_params
3105 def test_get_edit_with_params
3095 @request.session[:user_id] = 2
3106 @request.session[:user_id] = 2
3096 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
3107 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
3097 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
3108 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => 10 }
3098 assert_response :success
3109 assert_response :success
3099 assert_template 'edit'
3110 assert_template 'edit'
3100
3111
3101 issue = assigns(:issue)
3112 issue = assigns(:issue)
3102 assert_not_nil issue
3113 assert_not_nil issue
3103
3114
3104 assert_equal 5, issue.status_id
3115 assert_equal 5, issue.status_id
3105 assert_select 'select[name=?]', 'issue[status_id]' do
3116 assert_select 'select[name=?]', 'issue[status_id]' do
3106 assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
3117 assert_select 'option[value="5"][selected=selected]', :text => 'Closed'
3107 end
3118 end
3108
3119
3109 assert_equal 7, issue.priority_id
3120 assert_equal 7, issue.priority_id
3110 assert_select 'select[name=?]', 'issue[priority_id]' do
3121 assert_select 'select[name=?]', 'issue[priority_id]' do
3111 assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
3122 assert_select 'option[value="7"][selected=selected]', :text => 'Urgent'
3112 end
3123 end
3113
3124
3114 assert_select 'input[name=?][value="2.5"]', 'time_entry[hours]'
3125 assert_select 'input[name=?][value="2.5"]', 'time_entry[hours]'
3115 assert_select 'select[name=?]', 'time_entry[activity_id]' do
3126 assert_select 'select[name=?]', 'time_entry[activity_id]' do
3116 assert_select 'option[value="10"][selected=selected]', :text => 'Development'
3127 assert_select 'option[value="10"][selected=selected]', :text => 'Development'
3117 end
3128 end
3118 assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
3129 assert_select 'input[name=?][value=test_get_edit_with_params]', 'time_entry[comments]'
3119 end
3130 end
3120
3131
3121 def test_get_edit_with_multi_custom_field
3132 def test_get_edit_with_multi_custom_field
3122 field = CustomField.find(1)
3133 field = CustomField.find(1)
3123 field.update_attribute :multiple, true
3134 field.update_attribute :multiple, true
3124 issue = Issue.find(1)
3135 issue = Issue.find(1)
3125 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3136 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3126 issue.save!
3137 issue.save!
3127
3138
3128 @request.session[:user_id] = 2
3139 @request.session[:user_id] = 2
3129 get :edit, :id => 1
3140 get :edit, :id => 1
3130 assert_response :success
3141 assert_response :success
3131 assert_template 'edit'
3142 assert_template 'edit'
3132
3143
3133 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
3144 assert_select 'select[name=?][multiple=multiple]', 'issue[custom_field_values][1][]' do
3134 assert_select 'option', 3
3145 assert_select 'option', 3
3135 assert_select 'option[value=MySQL][selected=selected]'
3146 assert_select 'option[value=MySQL][selected=selected]'
3136 assert_select 'option[value=Oracle][selected=selected]'
3147 assert_select 'option[value=Oracle][selected=selected]'
3137 assert_select 'option[value=PostgreSQL]:not([selected])'
3148 assert_select 'option[value=PostgreSQL]:not([selected])'
3138 end
3149 end
3139 end
3150 end
3140
3151
3141 def test_update_form_for_existing_issue
3152 def test_update_form_for_existing_issue
3142 @request.session[:user_id] = 2
3153 @request.session[:user_id] = 2
3143 xhr :patch, :edit, :id => 1,
3154 xhr :patch, :edit, :id => 1,
3144 :issue => {:tracker_id => 2,
3155 :issue => {:tracker_id => 2,
3145 :subject => 'This is the test_new issue',
3156 :subject => 'This is the test_new issue',
3146 :description => 'This is the description',
3157 :description => 'This is the description',
3147 :priority_id => 5}
3158 :priority_id => 5}
3148 assert_response :success
3159 assert_response :success
3149 assert_equal 'text/javascript', response.content_type
3160 assert_equal 'text/javascript', response.content_type
3150 assert_template 'edit'
3161 assert_template 'edit'
3151 assert_template :partial => '_form'
3162 assert_template :partial => '_form'
3152
3163
3153 issue = assigns(:issue)
3164 issue = assigns(:issue)
3154 assert_kind_of Issue, issue
3165 assert_kind_of Issue, issue
3155 assert_equal 1, issue.id
3166 assert_equal 1, issue.id
3156 assert_equal 1, issue.project_id
3167 assert_equal 1, issue.project_id
3157 assert_equal 2, issue.tracker_id
3168 assert_equal 2, issue.tracker_id
3158 assert_equal 'This is the test_new issue', issue.subject
3169 assert_equal 'This is the test_new issue', issue.subject
3159 end
3170 end
3160
3171
3161 def test_update_form_for_existing_issue_should_keep_issue_author
3172 def test_update_form_for_existing_issue_should_keep_issue_author
3162 @request.session[:user_id] = 3
3173 @request.session[:user_id] = 3
3163 xhr :patch, :edit, :id => 1, :issue => {:subject => 'Changed'}
3174 xhr :patch, :edit, :id => 1, :issue => {:subject => 'Changed'}
3164 assert_response :success
3175 assert_response :success
3165 assert_equal 'text/javascript', response.content_type
3176 assert_equal 'text/javascript', response.content_type
3166
3177
3167 issue = assigns(:issue)
3178 issue = assigns(:issue)
3168 assert_equal User.find(2), issue.author
3179 assert_equal User.find(2), issue.author
3169 assert_equal 2, issue.author_id
3180 assert_equal 2, issue.author_id
3170 assert_not_equal User.current, issue.author
3181 assert_not_equal User.current, issue.author
3171 end
3182 end
3172
3183
3173 def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
3184 def test_update_form_for_existing_issue_should_propose_transitions_based_on_initial_status
3174 @request.session[:user_id] = 2
3185 @request.session[:user_id] = 2
3175 WorkflowTransition.delete_all
3186 WorkflowTransition.delete_all
3176 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3187 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
3177 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3188 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
3178 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
3189 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
3179
3190
3180 xhr :patch, :edit, :id => 2,
3191 xhr :patch, :edit, :id => 2,
3181 :issue => {:tracker_id => 2,
3192 :issue => {:tracker_id => 2,
3182 :status_id => 5,
3193 :status_id => 5,
3183 :subject => 'This is an issue'}
3194 :subject => 'This is an issue'}
3184
3195
3185 assert_equal 5, assigns(:issue).status_id
3196 assert_equal 5, assigns(:issue).status_id
3186 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
3197 assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
3187 end
3198 end
3188
3199
3189 def test_update_form_for_existing_issue_with_project_change
3200 def test_update_form_for_existing_issue_with_project_change
3190 @request.session[:user_id] = 2
3201 @request.session[:user_id] = 2
3191 xhr :patch, :edit, :id => 1,
3202 xhr :patch, :edit, :id => 1,
3192 :issue => {:project_id => 2,
3203 :issue => {:project_id => 2,
3193 :tracker_id => 2,
3204 :tracker_id => 2,
3194 :subject => 'This is the test_new issue',
3205 :subject => 'This is the test_new issue',
3195 :description => 'This is the description',
3206 :description => 'This is the description',
3196 :priority_id => 5}
3207 :priority_id => 5}
3197 assert_response :success
3208 assert_response :success
3198 assert_template :partial => '_form'
3209 assert_template :partial => '_form'
3199
3210
3200 issue = assigns(:issue)
3211 issue = assigns(:issue)
3201 assert_kind_of Issue, issue
3212 assert_kind_of Issue, issue
3202 assert_equal 1, issue.id
3213 assert_equal 1, issue.id
3203 assert_equal 2, issue.project_id
3214 assert_equal 2, issue.project_id
3204 assert_equal 2, issue.tracker_id
3215 assert_equal 2, issue.tracker_id
3205 assert_equal 'This is the test_new issue', issue.subject
3216 assert_equal 'This is the test_new issue', issue.subject
3206 end
3217 end
3207
3218
3208 def test_update_form_should_keep_category_with_same_when_changing_project
3219 def test_update_form_should_keep_category_with_same_when_changing_project
3209 source = Project.generate!
3220 source = Project.generate!
3210 target = Project.generate!
3221 target = Project.generate!
3211 source_category = IssueCategory.create!(:name => 'Foo', :project => source)
3222 source_category = IssueCategory.create!(:name => 'Foo', :project => source)
3212 target_category = IssueCategory.create!(:name => 'Foo', :project => target)
3223 target_category = IssueCategory.create!(:name => 'Foo', :project => target)
3213 issue = Issue.generate!(:project => source, :category => source_category)
3224 issue = Issue.generate!(:project => source, :category => source_category)
3214
3225
3215 @request.session[:user_id] = 1
3226 @request.session[:user_id] = 1
3216 patch :edit, :id => issue.id,
3227 patch :edit, :id => issue.id,
3217 :issue => {:project_id => target.id, :category_id => source_category.id}
3228 :issue => {:project_id => target.id, :category_id => source_category.id}
3218 assert_response :success
3229 assert_response :success
3219
3230
3220 issue = assigns(:issue)
3231 issue = assigns(:issue)
3221 assert_equal target_category, issue.category
3232 assert_equal target_category, issue.category
3222 end
3233 end
3223
3234
3224 def test_update_form_should_propose_default_status_for_existing_issue
3235 def test_update_form_should_propose_default_status_for_existing_issue
3225 @request.session[:user_id] = 2
3236 @request.session[:user_id] = 2
3226 WorkflowTransition.delete_all
3237 WorkflowTransition.delete_all
3227 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3238 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
3228
3239
3229 xhr :patch, :edit, :id => 2
3240 xhr :patch, :edit, :id => 2
3230 assert_response :success
3241 assert_response :success
3231 assert_equal [2,3], assigns(:allowed_statuses).map(&:id).sort
3242 assert_equal [2,3], assigns(:allowed_statuses).map(&:id).sort
3232 end
3243 end
3233
3244
3234 def test_put_update_without_custom_fields_param
3245 def test_put_update_without_custom_fields_param
3235 @request.session[:user_id] = 2
3246 @request.session[:user_id] = 2
3236
3247
3237 issue = Issue.find(1)
3248 issue = Issue.find(1)
3238 assert_equal '125', issue.custom_value_for(2).value
3249 assert_equal '125', issue.custom_value_for(2).value
3239
3250
3240 assert_difference('Journal.count') do
3251 assert_difference('Journal.count') do
3241 assert_difference('JournalDetail.count') do
3252 assert_difference('JournalDetail.count') do
3242 put :update, :id => 1, :issue => {:subject => 'New subject'}
3253 put :update, :id => 1, :issue => {:subject => 'New subject'}
3243 end
3254 end
3244 end
3255 end
3245 assert_redirected_to :action => 'show', :id => '1'
3256 assert_redirected_to :action => 'show', :id => '1'
3246 issue.reload
3257 issue.reload
3247 assert_equal 'New subject', issue.subject
3258 assert_equal 'New subject', issue.subject
3248 # Make sure custom fields were not cleared
3259 # Make sure custom fields were not cleared
3249 assert_equal '125', issue.custom_value_for(2).value
3260 assert_equal '125', issue.custom_value_for(2).value
3250 end
3261 end
3251
3262
3252 def test_put_update_with_project_change
3263 def test_put_update_with_project_change
3253 @request.session[:user_id] = 2
3264 @request.session[:user_id] = 2
3254 ActionMailer::Base.deliveries.clear
3265 ActionMailer::Base.deliveries.clear
3255
3266
3256 with_settings :notified_events => %w(issue_updated) do
3267 with_settings :notified_events => %w(issue_updated) do
3257 assert_difference('Journal.count') do
3268 assert_difference('Journal.count') do
3258 assert_difference('JournalDetail.count', 3) do
3269 assert_difference('JournalDetail.count', 3) do
3259 put :update, :id => 1, :issue => {:project_id => '2',
3270 put :update, :id => 1, :issue => {:project_id => '2',
3260 :tracker_id => '1', # no change
3271 :tracker_id => '1', # no change
3261 :priority_id => '6',
3272 :priority_id => '6',
3262 :category_id => '3'
3273 :category_id => '3'
3263 }
3274 }
3264 end
3275 end
3265 end
3276 end
3266 end
3277 end
3267 assert_redirected_to :action => 'show', :id => '1'
3278 assert_redirected_to :action => 'show', :id => '1'
3268 issue = Issue.find(1)
3279 issue = Issue.find(1)
3269 assert_equal 2, issue.project_id
3280 assert_equal 2, issue.project_id
3270 assert_equal 1, issue.tracker_id
3281 assert_equal 1, issue.tracker_id
3271 assert_equal 6, issue.priority_id
3282 assert_equal 6, issue.priority_id
3272 assert_equal 3, issue.category_id
3283 assert_equal 3, issue.category_id
3273
3284
3274 mail = ActionMailer::Base.deliveries.last
3285 mail = ActionMailer::Base.deliveries.last
3275 assert_not_nil mail
3286 assert_not_nil mail
3276 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3287 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3277 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
3288 assert_mail_body_match "Project changed from eCookbook to OnlineStore", mail
3278 end
3289 end
3279
3290
3280 def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
3291 def test_put_update_trying_to_move_issue_to_project_without_tracker_should_not_error
3281 target = Project.generate!(:tracker_ids => [])
3292 target = Project.generate!(:tracker_ids => [])
3282 assert target.trackers.empty?
3293 assert target.trackers.empty?
3283 issue = Issue.generate!
3294 issue = Issue.generate!
3284 @request.session[:user_id] = 1
3295 @request.session[:user_id] = 1
3285
3296
3286 put :update, :id => issue.id, :issue => {:project_id => target.id}
3297 put :update, :id => issue.id, :issue => {:project_id => target.id}
3287 assert_response 302
3298 assert_response 302
3288 end
3299 end
3289
3300
3290 def test_put_update_with_tracker_change
3301 def test_put_update_with_tracker_change
3291 @request.session[:user_id] = 2
3302 @request.session[:user_id] = 2
3292 ActionMailer::Base.deliveries.clear
3303 ActionMailer::Base.deliveries.clear
3293
3304
3294 with_settings :notified_events => %w(issue_updated) do
3305 with_settings :notified_events => %w(issue_updated) do
3295 assert_difference('Journal.count') do
3306 assert_difference('Journal.count') do
3296 assert_difference('JournalDetail.count', 2) do
3307 assert_difference('JournalDetail.count', 2) do
3297 put :update, :id => 1, :issue => {:project_id => '1',
3308 put :update, :id => 1, :issue => {:project_id => '1',
3298 :tracker_id => '2',
3309 :tracker_id => '2',
3299 :priority_id => '6'
3310 :priority_id => '6'
3300 }
3311 }
3301 end
3312 end
3302 end
3313 end
3303 end
3314 end
3304 assert_redirected_to :action => 'show', :id => '1'
3315 assert_redirected_to :action => 'show', :id => '1'
3305 issue = Issue.find(1)
3316 issue = Issue.find(1)
3306 assert_equal 1, issue.project_id
3317 assert_equal 1, issue.project_id
3307 assert_equal 2, issue.tracker_id
3318 assert_equal 2, issue.tracker_id
3308 assert_equal 6, issue.priority_id
3319 assert_equal 6, issue.priority_id
3309 assert_equal 1, issue.category_id
3320 assert_equal 1, issue.category_id
3310
3321
3311 mail = ActionMailer::Base.deliveries.last
3322 mail = ActionMailer::Base.deliveries.last
3312 assert_not_nil mail
3323 assert_not_nil mail
3313 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3324 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
3314 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
3325 assert_mail_body_match "Tracker changed from Bug to Feature request", mail
3315 end
3326 end
3316
3327
3317 def test_put_update_with_custom_field_change
3328 def test_put_update_with_custom_field_change
3318 @request.session[:user_id] = 2
3329 @request.session[:user_id] = 2
3319 issue = Issue.find(1)
3330 issue = Issue.find(1)
3320 assert_equal '125', issue.custom_value_for(2).value
3331 assert_equal '125', issue.custom_value_for(2).value
3321
3332
3322 with_settings :notified_events => %w(issue_updated) do
3333 with_settings :notified_events => %w(issue_updated) do
3323 assert_difference('Journal.count') do
3334 assert_difference('Journal.count') do
3324 assert_difference('JournalDetail.count', 3) do
3335 assert_difference('JournalDetail.count', 3) do
3325 put :update, :id => 1, :issue => {:subject => 'Custom field change',
3336 put :update, :id => 1, :issue => {:subject => 'Custom field change',
3326 :priority_id => '6',
3337 :priority_id => '6',
3327 :category_id => '1', # no change
3338 :category_id => '1', # no change
3328 :custom_field_values => { '2' => 'New custom value' }
3339 :custom_field_values => { '2' => 'New custom value' }
3329 }
3340 }
3330 end
3341 end
3331 end
3342 end
3332 end
3343 end
3333 assert_redirected_to :action => 'show', :id => '1'
3344 assert_redirected_to :action => 'show', :id => '1'
3334 issue.reload
3345 issue.reload
3335 assert_equal 'New custom value', issue.custom_value_for(2).value
3346 assert_equal 'New custom value', issue.custom_value_for(2).value
3336
3347
3337 mail = ActionMailer::Base.deliveries.last
3348 mail = ActionMailer::Base.deliveries.last
3338 assert_not_nil mail
3349 assert_not_nil mail
3339 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
3350 assert_mail_body_match "Searchable field changed from 125 to New custom value", mail
3340 end
3351 end
3341
3352
3342 def test_put_update_with_multi_custom_field_change
3353 def test_put_update_with_multi_custom_field_change
3343 field = CustomField.find(1)
3354 field = CustomField.find(1)
3344 field.update_attribute :multiple, true
3355 field.update_attribute :multiple, true
3345 issue = Issue.find(1)
3356 issue = Issue.find(1)
3346 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3357 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
3347 issue.save!
3358 issue.save!
3348
3359
3349 @request.session[:user_id] = 2
3360 @request.session[:user_id] = 2
3350 assert_difference('Journal.count') do
3361 assert_difference('Journal.count') do
3351 assert_difference('JournalDetail.count', 3) do
3362 assert_difference('JournalDetail.count', 3) do
3352 put :update, :id => 1,
3363 put :update, :id => 1,
3353 :issue => {
3364 :issue => {
3354 :subject => 'Custom field change',
3365 :subject => 'Custom field change',
3355 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
3366 :custom_field_values => { '1' => ['', 'Oracle', 'PostgreSQL'] }
3356 }
3367 }
3357 end
3368 end
3358 end
3369 end
3359 assert_redirected_to :action => 'show', :id => '1'
3370 assert_redirected_to :action => 'show', :id => '1'
3360 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
3371 assert_equal ['Oracle', 'PostgreSQL'], Issue.find(1).custom_field_value(1).sort
3361 end
3372 end
3362
3373
3363 def test_put_update_with_status_and_assignee_change
3374 def test_put_update_with_status_and_assignee_change
3364 issue = Issue.find(1)
3375 issue = Issue.find(1)
3365 assert_equal 1, issue.status_id
3376 assert_equal 1, issue.status_id
3366 @request.session[:user_id] = 2
3377 @request.session[:user_id] = 2
3367
3378
3368 with_settings :notified_events => %w(issue_updated) do
3379 with_settings :notified_events => %w(issue_updated) do
3369 assert_difference('TimeEntry.count', 0) do
3380 assert_difference('TimeEntry.count', 0) do
3370 put :update,
3381 put :update,
3371 :id => 1,
3382 :id => 1,
3372 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
3383 :issue => { :status_id => 2, :assigned_to_id => 3, :notes => 'Assigned to dlopper' },
3373 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
3384 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
3374 end
3385 end
3375 end
3386 end
3376 assert_redirected_to :action => 'show', :id => '1'
3387 assert_redirected_to :action => 'show', :id => '1'
3377 issue.reload
3388 issue.reload
3378 assert_equal 2, issue.status_id
3389 assert_equal 2, issue.status_id
3379 j = Journal.order('id DESC').first
3390 j = Journal.order('id DESC').first
3380 assert_equal 'Assigned to dlopper', j.notes
3391 assert_equal 'Assigned to dlopper', j.notes
3381 assert_equal 2, j.details.size
3392 assert_equal 2, j.details.size
3382
3393
3383 mail = ActionMailer::Base.deliveries.last
3394 mail = ActionMailer::Base.deliveries.last
3384 assert_mail_body_match "Status changed from New to Assigned", mail
3395 assert_mail_body_match "Status changed from New to Assigned", mail
3385 # subject should contain the new status
3396 # subject should contain the new status
3386 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
3397 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
3387 end
3398 end
3388
3399
3389 def test_put_update_with_note_only
3400 def test_put_update_with_note_only
3390 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
3401 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
3391
3402
3392 with_settings :notified_events => %w(issue_updated) do
3403 with_settings :notified_events => %w(issue_updated) do
3393 # anonymous user
3404 # anonymous user
3394 put :update,
3405 put :update,
3395 :id => 1,
3406 :id => 1,
3396 :issue => { :notes => notes }
3407 :issue => { :notes => notes }
3397 end
3408 end
3398 assert_redirected_to :action => 'show', :id => '1'
3409 assert_redirected_to :action => 'show', :id => '1'
3399 j = Journal.order('id DESC').first
3410 j = Journal.order('id DESC').first
3400 assert_equal notes, j.notes
3411 assert_equal notes, j.notes
3401 assert_equal 0, j.details.size
3412 assert_equal 0, j.details.size
3402 assert_equal User.anonymous, j.user
3413 assert_equal User.anonymous, j.user
3403
3414
3404 mail = ActionMailer::Base.deliveries.last
3415 mail = ActionMailer::Base.deliveries.last
3405 assert_mail_body_match notes, mail
3416 assert_mail_body_match notes, mail
3406 end
3417 end
3407
3418
3408 def test_put_update_with_private_note_only
3419 def test_put_update_with_private_note_only
3409 notes = 'Private note'
3420 notes = 'Private note'
3410 @request.session[:user_id] = 2
3421 @request.session[:user_id] = 2
3411
3422
3412 assert_difference 'Journal.count' do
3423 assert_difference 'Journal.count' do
3413 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
3424 put :update, :id => 1, :issue => {:notes => notes, :private_notes => '1'}
3414 assert_redirected_to :action => 'show', :id => '1'
3425 assert_redirected_to :action => 'show', :id => '1'
3415 end
3426 end
3416
3427
3417 j = Journal.order('id DESC').first
3428 j = Journal.order('id DESC').first
3418 assert_equal notes, j.notes
3429 assert_equal notes, j.notes
3419 assert_equal true, j.private_notes
3430 assert_equal true, j.private_notes
3420 end
3431 end
3421
3432
3422 def test_put_update_with_private_note_and_changes
3433 def test_put_update_with_private_note_and_changes
3423 notes = 'Private note'
3434 notes = 'Private note'
3424 @request.session[:user_id] = 2
3435 @request.session[:user_id] = 2
3425
3436
3426 assert_difference 'Journal.count', 2 do
3437 assert_difference 'Journal.count', 2 do
3427 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
3438 put :update, :id => 1, :issue => {:subject => 'New subject', :notes => notes, :private_notes => '1'}
3428 assert_redirected_to :action => 'show', :id => '1'
3439 assert_redirected_to :action => 'show', :id => '1'
3429 end
3440 end
3430
3441
3431 j = Journal.order('id DESC').first
3442 j = Journal.order('id DESC').first
3432 assert_equal notes, j.notes
3443 assert_equal notes, j.notes
3433 assert_equal true, j.private_notes
3444 assert_equal true, j.private_notes
3434 assert_equal 0, j.details.count
3445 assert_equal 0, j.details.count
3435
3446
3436 j = Journal.order('id DESC').offset(1).first
3447 j = Journal.order('id DESC').offset(1).first
3437 assert_nil j.notes
3448 assert_nil j.notes
3438 assert_equal false, j.private_notes
3449 assert_equal false, j.private_notes
3439 assert_equal 1, j.details.count
3450 assert_equal 1, j.details.count
3440 end
3451 end
3441
3452
3442 def test_put_update_with_note_and_spent_time
3453 def test_put_update_with_note_and_spent_time
3443 @request.session[:user_id] = 2
3454 @request.session[:user_id] = 2
3444 spent_hours_before = Issue.find(1).spent_hours
3455 spent_hours_before = Issue.find(1).spent_hours
3445 assert_difference('TimeEntry.count') do
3456 assert_difference('TimeEntry.count') do
3446 put :update,
3457 put :update,
3447 :id => 1,
3458 :id => 1,
3448 :issue => { :notes => '2.5 hours added' },
3459 :issue => { :notes => '2.5 hours added' },
3449 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
3460 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
3450 end
3461 end
3451 assert_redirected_to :action => 'show', :id => '1'
3462 assert_redirected_to :action => 'show', :id => '1'
3452
3463
3453 issue = Issue.find(1)
3464 issue = Issue.find(1)
3454
3465
3455 j = Journal.order('id DESC').first
3466 j = Journal.order('id DESC').first
3456 assert_equal '2.5 hours added', j.notes
3467 assert_equal '2.5 hours added', j.notes
3457 assert_equal 0, j.details.size
3468 assert_equal 0, j.details.size
3458
3469
3459 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
3470 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
3460 assert_not_nil t
3471 assert_not_nil t
3461 assert_equal 2.5, t.hours
3472 assert_equal 2.5, t.hours
3462 assert_equal spent_hours_before + 2.5, issue.spent_hours
3473 assert_equal spent_hours_before + 2.5, issue.spent_hours
3463 end
3474 end
3464
3475
3465 def test_put_update_should_preserve_parent_issue_even_if_not_visible
3476 def test_put_update_should_preserve_parent_issue_even_if_not_visible
3466 parent = Issue.generate!(:project_id => 1, :is_private => true)
3477 parent = Issue.generate!(:project_id => 1, :is_private => true)
3467 issue = Issue.generate!(:parent_issue_id => parent.id)
3478 issue = Issue.generate!(:parent_issue_id => parent.id)
3468 assert !parent.visible?(User.find(3))
3479 assert !parent.visible?(User.find(3))
3469 @request.session[:user_id] = 3
3480 @request.session[:user_id] = 3
3470
3481
3471 get :edit, :id => issue.id
3482 get :edit, :id => issue.id
3472 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
3483 assert_select 'input[name=?][value=?]', 'issue[parent_issue_id]', parent.id.to_s
3473
3484
3474 put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
3485 put :update, :id => issue.id, :issue => {:subject => 'New subject', :parent_issue_id => parent.id.to_s}
3475 assert_response 302
3486 assert_response 302
3476 assert_equal parent, issue.parent
3487 assert_equal parent, issue.parent
3477 end
3488 end
3478
3489
3479 def test_put_update_with_attachment_only
3490 def test_put_update_with_attachment_only
3480 set_tmp_attachments_directory
3491 set_tmp_attachments_directory
3481
3492
3482 # Delete all fixtured journals, a race condition can occur causing the wrong
3493 # Delete all fixtured journals, a race condition can occur causing the wrong
3483 # journal to get fetched in the next find.
3494 # journal to get fetched in the next find.
3484 Journal.delete_all
3495 Journal.delete_all
3485
3496
3486 with_settings :notified_events => %w(issue_updated) do
3497 with_settings :notified_events => %w(issue_updated) do
3487 # anonymous user
3498 # anonymous user
3488 assert_difference 'Attachment.count' do
3499 assert_difference 'Attachment.count' do
3489 put :update, :id => 1,
3500 put :update, :id => 1,
3490 :issue => {:notes => ''},
3501 :issue => {:notes => ''},
3491 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3502 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3492 end
3503 end
3493 end
3504 end
3494
3505
3495 assert_redirected_to :action => 'show', :id => '1'
3506 assert_redirected_to :action => 'show', :id => '1'
3496 j = Issue.find(1).journals.reorder('id DESC').first
3507 j = Issue.find(1).journals.reorder('id DESC').first
3497 assert j.notes.blank?
3508 assert j.notes.blank?
3498 assert_equal 1, j.details.size
3509 assert_equal 1, j.details.size
3499 assert_equal 'testfile.txt', j.details.first.value
3510 assert_equal 'testfile.txt', j.details.first.value
3500 assert_equal User.anonymous, j.user
3511 assert_equal User.anonymous, j.user
3501
3512
3502 attachment = Attachment.order('id DESC').first
3513 attachment = Attachment.order('id DESC').first
3503 assert_equal Issue.find(1), attachment.container
3514 assert_equal Issue.find(1), attachment.container
3504 assert_equal User.anonymous, attachment.author
3515 assert_equal User.anonymous, attachment.author
3505 assert_equal 'testfile.txt', attachment.filename
3516 assert_equal 'testfile.txt', attachment.filename
3506 assert_equal 'text/plain', attachment.content_type
3517 assert_equal 'text/plain', attachment.content_type
3507 assert_equal 'test file', attachment.description
3518 assert_equal 'test file', attachment.description
3508 assert_equal 59, attachment.filesize
3519 assert_equal 59, attachment.filesize
3509 assert File.exists?(attachment.diskfile)
3520 assert File.exists?(attachment.diskfile)
3510 assert_equal 59, File.size(attachment.diskfile)
3521 assert_equal 59, File.size(attachment.diskfile)
3511
3522
3512 mail = ActionMailer::Base.deliveries.last
3523 mail = ActionMailer::Base.deliveries.last
3513 assert_mail_body_match 'testfile.txt', mail
3524 assert_mail_body_match 'testfile.txt', mail
3514 end
3525 end
3515
3526
3516 def test_put_update_with_failure_should_save_attachments
3527 def test_put_update_with_failure_should_save_attachments
3517 set_tmp_attachments_directory
3528 set_tmp_attachments_directory
3518 @request.session[:user_id] = 2
3529 @request.session[:user_id] = 2
3519
3530
3520 assert_no_difference 'Journal.count' do
3531 assert_no_difference 'Journal.count' do
3521 assert_difference 'Attachment.count' do
3532 assert_difference 'Attachment.count' do
3522 put :update, :id => 1,
3533 put :update, :id => 1,
3523 :issue => { :subject => '' },
3534 :issue => { :subject => '' },
3524 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3535 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
3525 assert_response :success
3536 assert_response :success
3526 assert_template 'edit'
3537 assert_template 'edit'
3527 end
3538 end
3528 end
3539 end
3529
3540
3530 attachment = Attachment.order('id DESC').first
3541 attachment = Attachment.order('id DESC').first
3531 assert_equal 'testfile.txt', attachment.filename
3542 assert_equal 'testfile.txt', attachment.filename
3532 assert File.exists?(attachment.diskfile)
3543 assert File.exists?(attachment.diskfile)
3533 assert_nil attachment.container
3544 assert_nil attachment.container
3534
3545
3535 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3546 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3536 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3547 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3537 end
3548 end
3538
3549
3539 def test_put_update_with_failure_should_keep_saved_attachments
3550 def test_put_update_with_failure_should_keep_saved_attachments
3540 set_tmp_attachments_directory
3551 set_tmp_attachments_directory
3541 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3552 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3542 @request.session[:user_id] = 2
3553 @request.session[:user_id] = 2
3543
3554
3544 assert_no_difference 'Journal.count' do
3555 assert_no_difference 'Journal.count' do
3545 assert_no_difference 'Attachment.count' do
3556 assert_no_difference 'Attachment.count' do
3546 put :update, :id => 1,
3557 put :update, :id => 1,
3547 :issue => { :subject => '' },
3558 :issue => { :subject => '' },
3548 :attachments => {'p0' => {'token' => attachment.token}}
3559 :attachments => {'p0' => {'token' => attachment.token}}
3549 assert_response :success
3560 assert_response :success
3550 assert_template 'edit'
3561 assert_template 'edit'
3551 end
3562 end
3552 end
3563 end
3553
3564
3554 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3565 assert_select 'input[name=?][value=?]', 'attachments[p0][token]', attachment.token
3555 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3566 assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'testfile.txt'
3556 end
3567 end
3557
3568
3558 def test_put_update_should_attach_saved_attachments
3569 def test_put_update_should_attach_saved_attachments
3559 set_tmp_attachments_directory
3570 set_tmp_attachments_directory
3560 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
3571 attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
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 assert_difference 'JournalDetail.count' do
3575 assert_difference 'JournalDetail.count' do
3565 assert_no_difference 'Attachment.count' do
3576 assert_no_difference 'Attachment.count' do
3566 put :update, :id => 1,
3577 put :update, :id => 1,
3567 :issue => {:notes => 'Attachment added'},
3578 :issue => {:notes => 'Attachment added'},
3568 :attachments => {'p0' => {'token' => attachment.token}}
3579 :attachments => {'p0' => {'token' => attachment.token}}
3569 assert_redirected_to '/issues/1'
3580 assert_redirected_to '/issues/1'
3570 end
3581 end
3571 end
3582 end
3572 end
3583 end
3573
3584
3574 attachment.reload
3585 attachment.reload
3575 assert_equal Issue.find(1), attachment.container
3586 assert_equal Issue.find(1), attachment.container
3576
3587
3577 journal = Journal.order('id DESC').first
3588 journal = Journal.order('id DESC').first
3578 assert_equal 1, journal.details.size
3589 assert_equal 1, journal.details.size
3579 assert_equal 'testfile.txt', journal.details.first.value
3590 assert_equal 'testfile.txt', journal.details.first.value
3580 end
3591 end
3581
3592
3582 def test_put_update_with_attachment_that_fails_to_save
3593 def test_put_update_with_attachment_that_fails_to_save
3583 set_tmp_attachments_directory
3594 set_tmp_attachments_directory
3584
3595
3585 # anonymous user
3596 # anonymous user
3586 with_settings :attachment_max_size => 0 do
3597 with_settings :attachment_max_size => 0 do
3587 put :update,
3598 put :update,
3588 :id => 1,
3599 :id => 1,
3589 :issue => {:notes => ''},
3600 :issue => {:notes => ''},
3590 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3601 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
3591 assert_redirected_to :action => 'show', :id => '1'
3602 assert_redirected_to :action => 'show', :id => '1'
3592 assert_equal '1 file(s) could not be saved.', flash[:warning]
3603 assert_equal '1 file(s) could not be saved.', flash[:warning]
3593 end
3604 end
3594 end
3605 end
3595
3606
3596 def test_put_update_with_no_change
3607 def test_put_update_with_no_change
3597 issue = Issue.find(1)
3608 issue = Issue.find(1)
3598 issue.journals.clear
3609 issue.journals.clear
3599 ActionMailer::Base.deliveries.clear
3610 ActionMailer::Base.deliveries.clear
3600
3611
3601 put :update,
3612 put :update,
3602 :id => 1,
3613 :id => 1,
3603 :issue => {:notes => ''}
3614 :issue => {:notes => ''}
3604 assert_redirected_to :action => 'show', :id => '1'
3615 assert_redirected_to :action => 'show', :id => '1'
3605
3616
3606 issue.reload
3617 issue.reload
3607 assert issue.journals.empty?
3618 assert issue.journals.empty?
3608 # No email should be sent
3619 # No email should be sent
3609 assert ActionMailer::Base.deliveries.empty?
3620 assert ActionMailer::Base.deliveries.empty?
3610 end
3621 end
3611
3622
3612 def test_put_update_should_send_a_notification
3623 def test_put_update_should_send_a_notification
3613 @request.session[:user_id] = 2
3624 @request.session[:user_id] = 2
3614 ActionMailer::Base.deliveries.clear
3625 ActionMailer::Base.deliveries.clear
3615 issue = Issue.find(1)
3626 issue = Issue.find(1)
3616 old_subject = issue.subject
3627 old_subject = issue.subject
3617 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3628 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
3618
3629
3619 with_settings :notified_events => %w(issue_updated) do
3630 with_settings :notified_events => %w(issue_updated) do
3620 put :update, :id => 1, :issue => {:subject => new_subject,
3631 put :update, :id => 1, :issue => {:subject => new_subject,
3621 :priority_id => '6',
3632 :priority_id => '6',
3622 :category_id => '1' # no change
3633 :category_id => '1' # no change
3623 }
3634 }
3624 assert_equal 1, ActionMailer::Base.deliveries.size
3635 assert_equal 1, ActionMailer::Base.deliveries.size
3625 end
3636 end
3626 end
3637 end
3627
3638
3628 def test_put_update_with_invalid_spent_time_hours_only
3639 def test_put_update_with_invalid_spent_time_hours_only
3629 @request.session[:user_id] = 2
3640 @request.session[:user_id] = 2
3630 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3641 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3631
3642
3632 assert_no_difference('Journal.count') do
3643 assert_no_difference('Journal.count') do
3633 put :update,
3644 put :update,
3634 :id => 1,
3645 :id => 1,
3635 :issue => {:notes => notes},
3646 :issue => {:notes => notes},
3636 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3647 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
3637 end
3648 end
3638 assert_response :success
3649 assert_response :success
3639 assert_template 'edit'
3650 assert_template 'edit'
3640
3651
3641 assert_select_error /Activity cannot be blank/
3652 assert_select_error /Activity cannot be blank/
3642 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3653 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3643 assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
3654 assert_select 'input[name=?][value=?]', 'time_entry[hours]', '2z'
3644 end
3655 end
3645
3656
3646 def test_put_update_with_invalid_spent_time_comments_only
3657 def test_put_update_with_invalid_spent_time_comments_only
3647 @request.session[:user_id] = 2
3658 @request.session[:user_id] = 2
3648 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3659 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
3649
3660
3650 assert_no_difference('Journal.count') do
3661 assert_no_difference('Journal.count') do
3651 put :update,
3662 put :update,
3652 :id => 1,
3663 :id => 1,
3653 :issue => {:notes => notes},
3664 :issue => {:notes => notes},
3654 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3665 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
3655 end
3666 end
3656 assert_response :success
3667 assert_response :success
3657 assert_template 'edit'
3668 assert_template 'edit'
3658
3669
3659 assert_select_error /Activity cannot be blank/
3670 assert_select_error /Activity cannot be blank/
3660 assert_select_error /Hours cannot be blank/
3671 assert_select_error /Hours cannot be blank/
3661 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3672 assert_select 'textarea[name=?]', 'issue[notes]', :text => notes
3662 assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
3673 assert_select 'input[name=?][value=?]', 'time_entry[comments]', 'this is my comment'
3663 end
3674 end
3664
3675
3665 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3676 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
3666 issue = Issue.find(2)
3677 issue = Issue.find(2)
3667 @request.session[:user_id] = 2
3678 @request.session[:user_id] = 2
3668
3679
3669 put :update,
3680 put :update,
3670 :id => issue.id,
3681 :id => issue.id,
3671 :issue => {
3682 :issue => {
3672 :fixed_version_id => 4
3683 :fixed_version_id => 4
3673 }
3684 }
3674
3685
3675 assert_response :redirect
3686 assert_response :redirect
3676 issue.reload
3687 issue.reload
3677 assert_equal 4, issue.fixed_version_id
3688 assert_equal 4, issue.fixed_version_id
3678 assert_not_equal issue.project_id, issue.fixed_version.project_id
3689 assert_not_equal issue.project_id, issue.fixed_version.project_id
3679 end
3690 end
3680
3691
3681 def test_put_update_should_redirect_back_using_the_back_url_parameter
3692 def test_put_update_should_redirect_back_using_the_back_url_parameter
3682 issue = Issue.find(2)
3693 issue = Issue.find(2)
3683 @request.session[:user_id] = 2
3694 @request.session[:user_id] = 2
3684
3695
3685 put :update,
3696 put :update,
3686 :id => issue.id,
3697 :id => issue.id,
3687 :issue => {
3698 :issue => {
3688 :fixed_version_id => 4
3699 :fixed_version_id => 4
3689 },
3700 },
3690 :back_url => '/issues'
3701 :back_url => '/issues'
3691
3702
3692 assert_response :redirect
3703 assert_response :redirect
3693 assert_redirected_to '/issues'
3704 assert_redirected_to '/issues'
3694 end
3705 end
3695
3706
3696 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3707 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
3697 issue = Issue.find(2)
3708 issue = Issue.find(2)
3698 @request.session[:user_id] = 2
3709 @request.session[:user_id] = 2
3699
3710
3700 put :update,
3711 put :update,
3701 :id => issue.id,
3712 :id => issue.id,
3702 :issue => {
3713 :issue => {
3703 :fixed_version_id => 4
3714 :fixed_version_id => 4
3704 },
3715 },
3705 :back_url => 'http://google.com'
3716 :back_url => 'http://google.com'
3706
3717
3707 assert_response :redirect
3718 assert_response :redirect
3708 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3719 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
3709 end
3720 end
3710
3721
3711 def test_get_bulk_edit
3722 def test_get_bulk_edit
3712 @request.session[:user_id] = 2
3723 @request.session[:user_id] = 2
3713 get :bulk_edit, :ids => [1, 3]
3724 get :bulk_edit, :ids => [1, 3]
3714 assert_response :success
3725 assert_response :success
3715 assert_template 'bulk_edit'
3726 assert_template 'bulk_edit'
3716
3727
3717 assert_select 'ul#bulk-selection' do
3728 assert_select 'ul#bulk-selection' do
3718 assert_select 'li', 2
3729 assert_select 'li', 2
3719 assert_select 'li a', :text => 'Bug #1'
3730 assert_select 'li a', :text => 'Bug #1'
3720 end
3731 end
3721
3732
3722 assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
3733 assert_select 'form#bulk_edit_form[action=?]', '/issues/bulk_update' do
3723 assert_select 'input[name=?]', 'ids[]', 2
3734 assert_select 'input[name=?]', 'ids[]', 2
3724 assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
3735 assert_select 'input[name=?][value="1"][type=hidden]', 'ids[]'
3725
3736
3726 assert_select 'select[name=?]', 'issue[project_id]'
3737 assert_select 'select[name=?]', 'issue[project_id]'
3727 assert_select 'input[name=?]', 'issue[parent_issue_id]'
3738 assert_select 'input[name=?]', 'issue[parent_issue_id]'
3728
3739
3729 # Project specific custom field, date type
3740 # Project specific custom field, date type
3730 field = CustomField.find(9)
3741 field = CustomField.find(9)
3731 assert !field.is_for_all?
3742 assert !field.is_for_all?
3732 assert_equal 'date', field.field_format
3743 assert_equal 'date', field.field_format
3733 assert_select 'input[name=?]', 'issue[custom_field_values][9]'
3744 assert_select 'input[name=?]', 'issue[custom_field_values][9]'
3734
3745
3735 # System wide custom field
3746 # System wide custom field
3736 assert CustomField.find(1).is_for_all?
3747 assert CustomField.find(1).is_for_all?
3737 assert_select 'select[name=?]', 'issue[custom_field_values][1]'
3748 assert_select 'select[name=?]', 'issue[custom_field_values][1]'
3738
3749
3739 # Be sure we don't display inactive IssuePriorities
3750 # Be sure we don't display inactive IssuePriorities
3740 assert ! IssuePriority.find(15).active?
3751 assert ! IssuePriority.find(15).active?
3741 assert_select 'select[name=?]', 'issue[priority_id]' do
3752 assert_select 'select[name=?]', 'issue[priority_id]' do
3742 assert_select 'option[value="15"]', 0
3753 assert_select 'option[value="15"]', 0
3743 end
3754 end
3744 end
3755 end
3745 end
3756 end
3746
3757
3747 def test_get_bulk_edit_on_different_projects
3758 def test_get_bulk_edit_on_different_projects
3748 @request.session[:user_id] = 2
3759 @request.session[:user_id] = 2
3749 get :bulk_edit, :ids => [1, 2, 6]
3760 get :bulk_edit, :ids => [1, 2, 6]
3750 assert_response :success
3761 assert_response :success
3751 assert_template 'bulk_edit'
3762 assert_template 'bulk_edit'
3752
3763
3753 # Can not set issues from different projects as children of an issue
3764 # Can not set issues from different projects as children of an issue
3754 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
3765 assert_select 'input[name=?]', 'issue[parent_issue_id]', 0
3755
3766
3756 # Project specific custom field, date type
3767 # Project specific custom field, date type
3757 field = CustomField.find(9)
3768 field = CustomField.find(9)
3758 assert !field.is_for_all?
3769 assert !field.is_for_all?
3759 assert !field.project_ids.include?(Issue.find(6).project_id)
3770 assert !field.project_ids.include?(Issue.find(6).project_id)
3760 assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
3771 assert_select 'input[name=?]', 'issue[custom_field_values][9]', 0
3761 end
3772 end
3762
3773
3763 def test_get_bulk_edit_with_user_custom_field
3774 def test_get_bulk_edit_with_user_custom_field
3764 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
3775 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :tracker_ids => [1,2,3])
3765
3776
3766 @request.session[:user_id] = 2
3777 @request.session[:user_id] = 2
3767 get :bulk_edit, :ids => [1, 2]
3778 get :bulk_edit, :ids => [1, 2]
3768 assert_response :success
3779 assert_response :success
3769 assert_template 'bulk_edit'
3780 assert_template 'bulk_edit'
3770
3781
3771 assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3782 assert_select 'select.user_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3772 assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
3783 assert_select 'option', Project.find(1).users.count + 2 # "no change" + "none" options
3773 end
3784 end
3774 end
3785 end
3775
3786
3776 def test_get_bulk_edit_with_version_custom_field
3787 def test_get_bulk_edit_with_version_custom_field
3777 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
3788 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
3778
3789
3779 @request.session[:user_id] = 2
3790 @request.session[:user_id] = 2
3780 get :bulk_edit, :ids => [1, 2]
3791 get :bulk_edit, :ids => [1, 2]
3781 assert_response :success
3792 assert_response :success
3782 assert_template 'bulk_edit'
3793 assert_template 'bulk_edit'
3783
3794
3784 assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3795 assert_select 'select.version_cf[name=?]', "issue[custom_field_values][#{field.id}]" do
3785 assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3796 assert_select 'option', Project.find(1).shared_versions.count + 2 # "no change" + "none" options
3786 end
3797 end
3787 end
3798 end
3788
3799
3789 def test_get_bulk_edit_with_multi_custom_field
3800 def test_get_bulk_edit_with_multi_custom_field
3790 field = CustomField.find(1)
3801 field = CustomField.find(1)
3791 field.update_attribute :multiple, true
3802 field.update_attribute :multiple, true
3792
3803
3793 @request.session[:user_id] = 2
3804 @request.session[:user_id] = 2
3794 get :bulk_edit, :ids => [1, 3]
3805 get :bulk_edit, :ids => [1, 3]
3795 assert_response :success
3806 assert_response :success
3796 assert_template 'bulk_edit'
3807 assert_template 'bulk_edit'
3797
3808
3798 assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
3809 assert_select 'select[name=?]', 'issue[custom_field_values][1][]' do
3799 assert_select 'option', field.possible_values.size + 1 # "none" options
3810 assert_select 'option', field.possible_values.size + 1 # "none" options
3800 end
3811 end
3801 end
3812 end
3802
3813
3803 def test_bulk_edit_should_propose_to_clear_text_custom_fields
3814 def test_bulk_edit_should_propose_to_clear_text_custom_fields
3804 @request.session[:user_id] = 2
3815 @request.session[:user_id] = 2
3805 get :bulk_edit, :ids => [1, 3]
3816 get :bulk_edit, :ids => [1, 3]
3806 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
3817 assert_select 'input[name=?][value=?]', 'issue[custom_field_values][2]', '__none__'
3807 end
3818 end
3808
3819
3809 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3820 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
3810 WorkflowTransition.delete_all
3821 WorkflowTransition.delete_all
3811 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3822 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3812 :old_status_id => 1, :new_status_id => 1)
3823 :old_status_id => 1, :new_status_id => 1)
3813 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3824 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3814 :old_status_id => 1, :new_status_id => 3)
3825 :old_status_id => 1, :new_status_id => 3)
3815 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3826 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1,
3816 :old_status_id => 1, :new_status_id => 4)
3827 :old_status_id => 1, :new_status_id => 4)
3817 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3828 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3818 :old_status_id => 2, :new_status_id => 1)
3829 :old_status_id => 2, :new_status_id => 1)
3819 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3830 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3820 :old_status_id => 2, :new_status_id => 3)
3831 :old_status_id => 2, :new_status_id => 3)
3821 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3832 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2,
3822 :old_status_id => 2, :new_status_id => 5)
3833 :old_status_id => 2, :new_status_id => 5)
3823 @request.session[:user_id] = 2
3834 @request.session[:user_id] = 2
3824 get :bulk_edit, :ids => [1, 2]
3835 get :bulk_edit, :ids => [1, 2]
3825
3836
3826 assert_response :success
3837 assert_response :success
3827 statuses = assigns(:available_statuses)
3838 statuses = assigns(:available_statuses)
3828 assert_not_nil statuses
3839 assert_not_nil statuses
3829 assert_equal [1, 3], statuses.map(&:id).sort
3840 assert_equal [1, 3], statuses.map(&:id).sort
3830
3841
3831 assert_select 'select[name=?]', 'issue[status_id]' do
3842 assert_select 'select[name=?]', 'issue[status_id]' do
3832 assert_select 'option', 3 # 2 statuses + "no change" option
3843 assert_select 'option', 3 # 2 statuses + "no change" option
3833 end
3844 end
3834 end
3845 end
3835
3846
3836 def test_bulk_edit_should_propose_target_project_open_shared_versions
3847 def test_bulk_edit_should_propose_target_project_open_shared_versions
3837 @request.session[:user_id] = 2
3848 @request.session[:user_id] = 2
3838 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3849 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3839 assert_response :success
3850 assert_response :success
3840 assert_template 'bulk_edit'
3851 assert_template 'bulk_edit'
3841 assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort
3852 assert_equal Project.find(1).shared_versions.open.to_a.sort, assigns(:versions).sort
3842
3853
3843 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
3854 assert_select 'select[name=?]', 'issue[fixed_version_id]' do
3844 assert_select 'option', :text => '2.0'
3855 assert_select 'option', :text => '2.0'
3845 end
3856 end
3846 end
3857 end
3847
3858
3848 def test_bulk_edit_should_propose_target_project_categories
3859 def test_bulk_edit_should_propose_target_project_categories
3849 @request.session[:user_id] = 2
3860 @request.session[:user_id] = 2
3850 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3861 post :bulk_edit, :ids => [1, 2, 6], :issue => {:project_id => 1}
3851 assert_response :success
3862 assert_response :success
3852 assert_template 'bulk_edit'
3863 assert_template 'bulk_edit'
3853 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3864 assert_equal Project.find(1).issue_categories.sort, assigns(:categories).sort
3854
3865
3855 assert_select 'select[name=?]', 'issue[category_id]' do
3866 assert_select 'select[name=?]', 'issue[category_id]' do
3856 assert_select 'option', :text => 'Recipes'
3867 assert_select 'option', :text => 'Recipes'
3857 end
3868 end
3858 end
3869 end
3859
3870
3860 def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
3871 def test_bulk_edit_should_only_propose_issues_trackers_custom_fields
3861 IssueCustomField.delete_all
3872 IssueCustomField.delete_all
3862 field = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
3873 field = IssueCustomField.generate!(:tracker_ids => [1], :is_for_all => true)
3863 IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
3874 IssueCustomField.generate!(:tracker_ids => [2], :is_for_all => true)
3864 @request.session[:user_id] = 2
3875 @request.session[:user_id] = 2
3865
3876
3866 issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
3877 issue_ids = Issue.where(:project_id => 1, :tracker_id => 1).limit(2).ids
3867 get :bulk_edit, :ids => issue_ids
3878 get :bulk_edit, :ids => issue_ids
3868 assert_equal [field], assigns(:custom_fields)
3879 assert_equal [field], assigns(:custom_fields)
3869 end
3880 end
3870
3881
3871 def test_bulk_update
3882 def test_bulk_update
3872 @request.session[:user_id] = 2
3883 @request.session[:user_id] = 2
3873 # update issues priority
3884 # update issues priority
3874 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3885 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3875 :issue => {:priority_id => 7,
3886 :issue => {:priority_id => 7,
3876 :assigned_to_id => '',
3887 :assigned_to_id => '',
3877 :custom_field_values => {'2' => ''}}
3888 :custom_field_values => {'2' => ''}}
3878
3889
3879 assert_response 302
3890 assert_response 302
3880 # check that the issues were updated
3891 # check that the issues were updated
3881 assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
3892 assert_equal [7, 7], Issue.where(:id =>[1, 2]).collect {|i| i.priority.id}
3882
3893
3883 issue = Issue.find(1)
3894 issue = Issue.find(1)
3884 journal = issue.journals.reorder('created_on DESC').first
3895 journal = issue.journals.reorder('created_on DESC').first
3885 assert_equal '125', issue.custom_value_for(2).value
3896 assert_equal '125', issue.custom_value_for(2).value
3886 assert_equal 'Bulk editing', journal.notes
3897 assert_equal 'Bulk editing', journal.notes
3887 assert_equal 1, journal.details.size
3898 assert_equal 1, journal.details.size
3888 end
3899 end
3889
3900
3890 def test_bulk_update_with_group_assignee
3901 def test_bulk_update_with_group_assignee
3891 group = Group.find(11)
3902 group = Group.find(11)
3892 project = Project.find(1)
3903 project = Project.find(1)
3893 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3904 project.members << Member.new(:principal => group, :roles => [Role.givable.first])
3894
3905
3895 @request.session[:user_id] = 2
3906 @request.session[:user_id] = 2
3896 # update issues assignee
3907 # update issues assignee
3897 with_settings :issue_group_assignment => '1' do
3908 with_settings :issue_group_assignment => '1' do
3898 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3909 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
3899 :issue => {:priority_id => '',
3910 :issue => {:priority_id => '',
3900 :assigned_to_id => group.id,
3911 :assigned_to_id => group.id,
3901 :custom_field_values => {'2' => ''}}
3912 :custom_field_values => {'2' => ''}}
3902
3913
3903 assert_response 302
3914 assert_response 302
3904 assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
3915 assert_equal [group, group], Issue.where(:id => [1, 2]).collect {|i| i.assigned_to}
3905 end
3916 end
3906 end
3917 end
3907
3918
3908 def test_bulk_update_on_different_projects
3919 def test_bulk_update_on_different_projects
3909 @request.session[:user_id] = 2
3920 @request.session[:user_id] = 2
3910 # update issues priority
3921 # update issues priority
3911 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3922 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
3912 :issue => {:priority_id => 7,
3923 :issue => {:priority_id => 7,
3913 :assigned_to_id => '',
3924 :assigned_to_id => '',
3914 :custom_field_values => {'2' => ''}}
3925 :custom_field_values => {'2' => ''}}
3915
3926
3916 assert_response 302
3927 assert_response 302
3917 # check that the issues were updated
3928 # check that the issues were updated
3918 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3929 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
3919
3930
3920 issue = Issue.find(1)
3931 issue = Issue.find(1)
3921 journal = issue.journals.reorder('created_on DESC').first
3932 journal = issue.journals.reorder('created_on DESC').first
3922 assert_equal '125', issue.custom_value_for(2).value
3933 assert_equal '125', issue.custom_value_for(2).value
3923 assert_equal 'Bulk editing', journal.notes
3934 assert_equal 'Bulk editing', journal.notes
3924 assert_equal 1, journal.details.size
3935 assert_equal 1, journal.details.size
3925 end
3936 end
3926
3937
3927 def test_bulk_update_on_different_projects_without_rights
3938 def test_bulk_update_on_different_projects_without_rights
3928 @request.session[:user_id] = 3
3939 @request.session[:user_id] = 3
3929 user = User.find(3)
3940 user = User.find(3)
3930 action = { :controller => "issues", :action => "bulk_update" }
3941 action = { :controller => "issues", :action => "bulk_update" }
3931 assert user.allowed_to?(action, Issue.find(1).project)
3942 assert user.allowed_to?(action, Issue.find(1).project)
3932 assert ! user.allowed_to?(action, Issue.find(6).project)
3943 assert ! user.allowed_to?(action, Issue.find(6).project)
3933 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3944 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
3934 :issue => {:priority_id => 7,
3945 :issue => {:priority_id => 7,
3935 :assigned_to_id => '',
3946 :assigned_to_id => '',
3936 :custom_field_values => {'2' => ''}}
3947 :custom_field_values => {'2' => ''}}
3937 assert_response 403
3948 assert_response 403
3938 assert_not_equal "Bulk should fail", Journal.last.notes
3949 assert_not_equal "Bulk should fail", Journal.last.notes
3939 end
3950 end
3940
3951
3941 def test_bullk_update_should_send_a_notification
3952 def test_bullk_update_should_send_a_notification
3942 @request.session[:user_id] = 2
3953 @request.session[:user_id] = 2
3943 ActionMailer::Base.deliveries.clear
3954 ActionMailer::Base.deliveries.clear
3944 with_settings :notified_events => %w(issue_updated) do
3955 with_settings :notified_events => %w(issue_updated) do
3945 post(:bulk_update,
3956 post(:bulk_update,
3946 {
3957 {
3947 :ids => [1, 2],
3958 :ids => [1, 2],
3948 :notes => 'Bulk editing',
3959 :notes => 'Bulk editing',
3949 :issue => {
3960 :issue => {
3950 :priority_id => 7,
3961 :priority_id => 7,
3951 :assigned_to_id => '',
3962 :assigned_to_id => '',
3952 :custom_field_values => {'2' => ''}
3963 :custom_field_values => {'2' => ''}
3953 }
3964 }
3954 })
3965 })
3955 assert_response 302
3966 assert_response 302
3956 assert_equal 2, ActionMailer::Base.deliveries.size
3967 assert_equal 2, ActionMailer::Base.deliveries.size
3957 end
3968 end
3958 end
3969 end
3959
3970
3960 def test_bulk_update_project
3971 def test_bulk_update_project
3961 @request.session[:user_id] = 2
3972 @request.session[:user_id] = 2
3962 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3973 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}
3963 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3974 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3964 # Issues moved to project 2
3975 # Issues moved to project 2
3965 assert_equal 2, Issue.find(1).project_id
3976 assert_equal 2, Issue.find(1).project_id
3966 assert_equal 2, Issue.find(2).project_id
3977 assert_equal 2, Issue.find(2).project_id
3967 # No tracker change
3978 # No tracker change
3968 assert_equal 1, Issue.find(1).tracker_id
3979 assert_equal 1, Issue.find(1).tracker_id
3969 assert_equal 2, Issue.find(2).tracker_id
3980 assert_equal 2, Issue.find(2).tracker_id
3970 end
3981 end
3971
3982
3972 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3983 def test_bulk_update_project_on_single_issue_should_follow_when_needed
3973 @request.session[:user_id] = 2
3984 @request.session[:user_id] = 2
3974 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3985 post :bulk_update, :id => 1, :issue => {:project_id => '2'}, :follow => '1'
3975 assert_redirected_to '/issues/1'
3986 assert_redirected_to '/issues/1'
3976 end
3987 end
3977
3988
3978 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3989 def test_bulk_update_project_on_multiple_issues_should_follow_when_needed
3979 @request.session[:user_id] = 2
3990 @request.session[:user_id] = 2
3980 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3991 post :bulk_update, :id => [1, 2], :issue => {:project_id => '2'}, :follow => '1'
3981 assert_redirected_to '/projects/onlinestore/issues'
3992 assert_redirected_to '/projects/onlinestore/issues'
3982 end
3993 end
3983
3994
3984 def test_bulk_update_tracker
3995 def test_bulk_update_tracker
3985 @request.session[:user_id] = 2
3996 @request.session[:user_id] = 2
3986 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3997 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2'}
3987 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3998 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
3988 assert_equal 2, Issue.find(1).tracker_id
3999 assert_equal 2, Issue.find(1).tracker_id
3989 assert_equal 2, Issue.find(2).tracker_id
4000 assert_equal 2, Issue.find(2).tracker_id
3990 end
4001 end
3991
4002
3992 def test_bulk_update_status
4003 def test_bulk_update_status
3993 @request.session[:user_id] = 2
4004 @request.session[:user_id] = 2
3994 # update issues priority
4005 # update issues priority
3995 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
4006 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
3996 :issue => {:priority_id => '',
4007 :issue => {:priority_id => '',
3997 :assigned_to_id => '',
4008 :assigned_to_id => '',
3998 :status_id => '5'}
4009 :status_id => '5'}
3999
4010
4000 assert_response 302
4011 assert_response 302
4001 issue = Issue.find(1)
4012 issue = Issue.find(1)
4002 assert issue.closed?
4013 assert issue.closed?
4003 end
4014 end
4004
4015
4005 def test_bulk_update_priority
4016 def test_bulk_update_priority
4006 @request.session[:user_id] = 2
4017 @request.session[:user_id] = 2
4007 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
4018 post :bulk_update, :ids => [1, 2], :issue => {:priority_id => 6}
4008
4019
4009 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4020 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4010 assert_equal 6, Issue.find(1).priority_id
4021 assert_equal 6, Issue.find(1).priority_id
4011 assert_equal 6, Issue.find(2).priority_id
4022 assert_equal 6, Issue.find(2).priority_id
4012 end
4023 end
4013
4024
4014 def test_bulk_update_with_notes
4025 def test_bulk_update_with_notes
4015 @request.session[:user_id] = 2
4026 @request.session[:user_id] = 2
4016 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
4027 post :bulk_update, :ids => [1, 2], :notes => 'Moving two issues'
4017
4028
4018 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4029 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4019 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
4030 assert_equal 'Moving two issues', Issue.find(1).journals.sort_by(&:id).last.notes
4020 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
4031 assert_equal 'Moving two issues', Issue.find(2).journals.sort_by(&:id).last.notes
4021 end
4032 end
4022
4033
4023 def test_bulk_update_parent_id
4034 def test_bulk_update_parent_id
4024 IssueRelation.delete_all
4035 IssueRelation.delete_all
4025 @request.session[:user_id] = 2
4036 @request.session[:user_id] = 2
4026 post :bulk_update, :ids => [1, 3],
4037 post :bulk_update, :ids => [1, 3],
4027 :notes => 'Bulk editing parent',
4038 :notes => 'Bulk editing parent',
4028 :issue => {:priority_id => '', :assigned_to_id => '',
4039 :issue => {:priority_id => '', :assigned_to_id => '',
4029 :status_id => '', :parent_issue_id => '2'}
4040 :status_id => '', :parent_issue_id => '2'}
4030 assert_response 302
4041 assert_response 302
4031 parent = Issue.find(2)
4042 parent = Issue.find(2)
4032 assert_equal parent.id, Issue.find(1).parent_id
4043 assert_equal parent.id, Issue.find(1).parent_id
4033 assert_equal parent.id, Issue.find(3).parent_id
4044 assert_equal parent.id, Issue.find(3).parent_id
4034 assert_equal [1, 3], parent.children.collect(&:id).sort
4045 assert_equal [1, 3], parent.children.collect(&:id).sort
4035 end
4046 end
4036
4047
4037 def test_bulk_update_estimated_hours
4048 def test_bulk_update_estimated_hours
4038 @request.session[:user_id] = 2
4049 @request.session[:user_id] = 2
4039 post :bulk_update, :ids => [1, 2], :issue => {:estimated_hours => 4.25}
4050 post :bulk_update, :ids => [1, 2], :issue => {:estimated_hours => 4.25}
4040
4051
4041 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4052 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook'
4042 assert_equal 4.25, Issue.find(1).estimated_hours
4053 assert_equal 4.25, Issue.find(1).estimated_hours
4043 assert_equal 4.25, Issue.find(2).estimated_hours
4054 assert_equal 4.25, Issue.find(2).estimated_hours
4044 end
4055 end
4045
4056
4046 def test_bulk_update_custom_field
4057 def test_bulk_update_custom_field
4047 @request.session[:user_id] = 2
4058 @request.session[:user_id] = 2
4048 # update issues priority
4059 # update issues priority
4049 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
4060 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
4050 :issue => {:priority_id => '',
4061 :issue => {:priority_id => '',
4051 :assigned_to_id => '',
4062 :assigned_to_id => '',
4052 :custom_field_values => {'2' => '777'}}
4063 :custom_field_values => {'2' => '777'}}
4053
4064
4054 assert_response 302
4065 assert_response 302
4055
4066
4056 issue = Issue.find(1)
4067 issue = Issue.find(1)
4057 journal = issue.journals.reorder('created_on DESC').first
4068 journal = issue.journals.reorder('created_on DESC').first
4058 assert_equal '777', issue.custom_value_for(2).value
4069 assert_equal '777', issue.custom_value_for(2).value
4059 assert_equal 1, journal.details.size
4070 assert_equal 1, journal.details.size
4060 assert_equal '125', journal.details.first.old_value
4071 assert_equal '125', journal.details.first.old_value
4061 assert_equal '777', journal.details.first.value
4072 assert_equal '777', journal.details.first.value
4062 end
4073 end
4063
4074
4064 def test_bulk_update_custom_field_to_blank
4075 def test_bulk_update_custom_field_to_blank
4065 @request.session[:user_id] = 2
4076 @request.session[:user_id] = 2
4066 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
4077 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
4067 :issue => {:priority_id => '',
4078 :issue => {:priority_id => '',
4068 :assigned_to_id => '',
4079 :assigned_to_id => '',
4069 :custom_field_values => {'1' => '__none__'}}
4080 :custom_field_values => {'1' => '__none__'}}
4070 assert_response 302
4081 assert_response 302
4071 assert_equal '', Issue.find(1).custom_field_value(1)
4082 assert_equal '', Issue.find(1).custom_field_value(1)
4072 assert_equal '', Issue.find(3).custom_field_value(1)
4083 assert_equal '', Issue.find(3).custom_field_value(1)
4073 end
4084 end
4074
4085
4075 def test_bulk_update_multi_custom_field
4086 def test_bulk_update_multi_custom_field
4076 field = CustomField.find(1)
4087 field = CustomField.find(1)
4077 field.update_attribute :multiple, true
4088 field.update_attribute :multiple, true
4078
4089
4079 @request.session[:user_id] = 2
4090 @request.session[:user_id] = 2
4080 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
4091 post :bulk_update, :ids => [1, 2, 3], :notes => 'Bulk editing multi custom field',
4081 :issue => {:priority_id => '',
4092 :issue => {:priority_id => '',
4082 :assigned_to_id => '',
4093 :assigned_to_id => '',
4083 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
4094 :custom_field_values => {'1' => ['MySQL', 'Oracle']}}
4084
4095
4085 assert_response 302
4096 assert_response 302
4086
4097
4087 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
4098 assert_equal ['MySQL', 'Oracle'], Issue.find(1).custom_field_value(1).sort
4088 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
4099 assert_equal ['MySQL', 'Oracle'], Issue.find(3).custom_field_value(1).sort
4089 # the custom field is not associated with the issue tracker
4100 # the custom field is not associated with the issue tracker
4090 assert_nil Issue.find(2).custom_field_value(1)
4101 assert_nil Issue.find(2).custom_field_value(1)
4091 end
4102 end
4092
4103
4093 def test_bulk_update_multi_custom_field_to_blank
4104 def test_bulk_update_multi_custom_field_to_blank
4094 field = CustomField.find(1)
4105 field = CustomField.find(1)
4095 field.update_attribute :multiple, true
4106 field.update_attribute :multiple, true
4096
4107
4097 @request.session[:user_id] = 2
4108 @request.session[:user_id] = 2
4098 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
4109 post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
4099 :issue => {:priority_id => '',
4110 :issue => {:priority_id => '',
4100 :assigned_to_id => '',
4111 :assigned_to_id => '',
4101 :custom_field_values => {'1' => ['__none__']}}
4112 :custom_field_values => {'1' => ['__none__']}}
4102 assert_response 302
4113 assert_response 302
4103 assert_equal [''], Issue.find(1).custom_field_value(1)
4114 assert_equal [''], Issue.find(1).custom_field_value(1)
4104 assert_equal [''], Issue.find(3).custom_field_value(1)
4115 assert_equal [''], Issue.find(3).custom_field_value(1)
4105 end
4116 end
4106
4117
4107 def test_bulk_update_unassign
4118 def test_bulk_update_unassign
4108 assert_not_nil Issue.find(2).assigned_to
4119 assert_not_nil Issue.find(2).assigned_to
4109 @request.session[:user_id] = 2
4120 @request.session[:user_id] = 2
4110 # unassign issues
4121 # unassign issues
4111 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
4122 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
4112 assert_response 302
4123 assert_response 302
4113 # check that the issues were updated
4124 # check that the issues were updated
4114 assert_nil Issue.find(2).assigned_to
4125 assert_nil Issue.find(2).assigned_to
4115 end
4126 end
4116
4127
4117 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
4128 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
4118 @request.session[:user_id] = 2
4129 @request.session[:user_id] = 2
4119
4130
4120 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
4131 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
4121
4132
4122 assert_response :redirect
4133 assert_response :redirect
4123 issues = Issue.find([1,2])
4134 issues = Issue.find([1,2])
4124 issues.each do |issue|
4135 issues.each do |issue|
4125 assert_equal 4, issue.fixed_version_id
4136 assert_equal 4, issue.fixed_version_id
4126 assert_not_equal issue.project_id, issue.fixed_version.project_id
4137 assert_not_equal issue.project_id, issue.fixed_version.project_id
4127 end
4138 end
4128 end
4139 end
4129
4140
4130 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
4141 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
4131 @request.session[:user_id] = 2
4142 @request.session[:user_id] = 2
4132 post :bulk_update, :ids => [1,2], :back_url => '/issues'
4143 post :bulk_update, :ids => [1,2], :back_url => '/issues'
4133
4144
4134 assert_response :redirect
4145 assert_response :redirect
4135 assert_redirected_to '/issues'
4146 assert_redirected_to '/issues'
4136 end
4147 end
4137
4148
4138 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
4149 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
4139 @request.session[:user_id] = 2
4150 @request.session[:user_id] = 2
4140 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
4151 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
4141
4152
4142 assert_response :redirect
4153 assert_response :redirect
4143 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
4154 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
4144 end
4155 end
4145
4156
4146 def test_bulk_update_with_all_failures_should_show_errors
4157 def test_bulk_update_with_all_failures_should_show_errors
4147 @request.session[:user_id] = 2
4158 @request.session[:user_id] = 2
4148 post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
4159 post :bulk_update, :ids => [1, 2], :issue => {:start_date => 'foo'}
4149
4160
4150 assert_response :success
4161 assert_response :success
4151 assert_template 'bulk_edit'
4162 assert_template 'bulk_edit'
4152 assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
4163 assert_select '#errorExplanation span', :text => 'Failed to save 2 issue(s) on 2 selected: #1, #2.'
4153 assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
4164 assert_select '#errorExplanation ul li', :text => 'Start date is not a valid date: #1, #2'
4154
4165
4155 assert_equal [1, 2], assigns[:issues].map(&:id)
4166 assert_equal [1, 2], assigns[:issues].map(&:id)
4156 end
4167 end
4157
4168
4158 def test_bulk_update_with_some_failures_should_show_errors
4169 def test_bulk_update_with_some_failures_should_show_errors
4159 issue1 = Issue.generate!(:start_date => '2013-05-12')
4170 issue1 = Issue.generate!(:start_date => '2013-05-12')
4160 issue2 = Issue.generate!(:start_date => '2013-05-15')
4171 issue2 = Issue.generate!(:start_date => '2013-05-15')
4161 issue3 = Issue.generate!
4172 issue3 = Issue.generate!
4162 @request.session[:user_id] = 2
4173 @request.session[:user_id] = 2
4163 post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id],
4174 post :bulk_update, :ids => [issue1.id, issue2.id, issue3.id],
4164 :issue => {:due_date => '2013-05-01'}
4175 :issue => {:due_date => '2013-05-01'}
4165 assert_response :success
4176 assert_response :success
4166 assert_template 'bulk_edit'
4177 assert_template 'bulk_edit'
4167 assert_select '#errorExplanation span',
4178 assert_select '#errorExplanation span',
4168 :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
4179 :text => "Failed to save 2 issue(s) on 3 selected: ##{issue1.id}, ##{issue2.id}."
4169 assert_select '#errorExplanation ul li',
4180 assert_select '#errorExplanation ul li',
4170 :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
4181 :text => "Due date must be greater than start date: ##{issue1.id}, ##{issue2.id}"
4171 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
4182 assert_equal [issue1.id, issue2.id], assigns[:issues].map(&:id)
4172 end
4183 end
4173
4184
4174 def test_bulk_update_with_failure_should_preserved_form_values
4185 def test_bulk_update_with_failure_should_preserved_form_values
4175 @request.session[:user_id] = 2
4186 @request.session[:user_id] = 2
4176 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
4187 post :bulk_update, :ids => [1, 2], :issue => {:tracker_id => '2', :start_date => 'foo'}
4177
4188
4178 assert_response :success
4189 assert_response :success
4179 assert_template 'bulk_edit'
4190 assert_template 'bulk_edit'
4180 assert_select 'select[name=?]', 'issue[tracker_id]' do
4191 assert_select 'select[name=?]', 'issue[tracker_id]' do
4181 assert_select 'option[value="2"][selected=selected]'
4192 assert_select 'option[value="2"][selected=selected]'
4182 end
4193 end
4183 assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
4194 assert_select 'input[name=?][value=?]', 'issue[start_date]', 'foo'
4184 end
4195 end
4185
4196
4186 def test_get_bulk_copy
4197 def test_get_bulk_copy
4187 @request.session[:user_id] = 2
4198 @request.session[:user_id] = 2
4188 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4199 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4189 assert_response :success
4200 assert_response :success
4190 assert_template 'bulk_edit'
4201 assert_template 'bulk_edit'
4191
4202
4192 issues = assigns(:issues)
4203 issues = assigns(:issues)
4193 assert_not_nil issues
4204 assert_not_nil issues
4194 assert_equal [1, 2, 3], issues.map(&:id).sort
4205 assert_equal [1, 2, 3], issues.map(&:id).sort
4195
4206
4196 assert_select 'select[name=?]', 'issue[project_id]' do
4207 assert_select 'select[name=?]', 'issue[project_id]' do
4197 assert_select 'option[value=""]'
4208 assert_select 'option[value=""]'
4198 end
4209 end
4199 assert_select 'input[name=copy_attachments]'
4210 assert_select 'input[name=copy_attachments]'
4200 end
4211 end
4201
4212
4202 def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
4213 def test_get_bulk_copy_without_add_issues_permission_should_not_propose_current_project_as_target
4203 user = setup_user_with_copy_but_not_add_permission
4214 user = setup_user_with_copy_but_not_add_permission
4204 @request.session[:user_id] = user.id
4215 @request.session[:user_id] = user.id
4205
4216
4206 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4217 get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
4207 assert_response :success
4218 assert_response :success
4208 assert_template 'bulk_edit'
4219 assert_template 'bulk_edit'
4209
4220
4210 assert_select 'select[name=?]', 'issue[project_id]' do
4221 assert_select 'select[name=?]', 'issue[project_id]' do
4211 assert_select 'option[value=""]', 0
4222 assert_select 'option[value=""]', 0
4212 assert_select 'option[value="2"]'
4223 assert_select 'option[value="2"]'
4213 end
4224 end
4214 end
4225 end
4215
4226
4216 def test_bulk_copy_to_another_project
4227 def test_bulk_copy_to_another_project
4217 @request.session[:user_id] = 2
4228 @request.session[:user_id] = 2
4218 assert_difference 'Issue.count', 2 do
4229 assert_difference 'Issue.count', 2 do
4219 assert_no_difference 'Project.find(1).issues.count' do
4230 assert_no_difference 'Project.find(1).issues.count' do
4220 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
4231 post :bulk_update, :ids => [1, 2], :issue => {:project_id => '2'}, :copy => '1'
4221 end
4232 end
4222 end
4233 end
4223 assert_redirected_to '/projects/ecookbook/issues'
4234 assert_redirected_to '/projects/ecookbook/issues'
4224
4235
4225 copies = Issue.order('id DESC').limit(issues.size)
4236 copies = Issue.order('id DESC').limit(issues.size)
4226 copies.each do |copy|
4237 copies.each do |copy|
4227 assert_equal 2, copy.project_id
4238 assert_equal 2, copy.project_id
4228 end
4239 end
4229 end
4240 end
4230
4241
4231 def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
4242 def test_bulk_copy_without_add_issues_permission_should_be_allowed_on_project_with_permission
4232 user = setup_user_with_copy_but_not_add_permission
4243 user = setup_user_with_copy_but_not_add_permission
4233 @request.session[:user_id] = user.id
4244 @request.session[:user_id] = user.id
4234
4245
4235 assert_difference 'Issue.count', 3 do
4246 assert_difference 'Issue.count', 3 do
4236 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '2'}, :copy => '1'
4247 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '2'}, :copy => '1'
4237 assert_response 302
4248 assert_response 302
4238 end
4249 end
4239 end
4250 end
4240
4251
4241 def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
4252 def test_bulk_copy_on_same_project_without_add_issues_permission_should_be_denied
4242 user = setup_user_with_copy_but_not_add_permission
4253 user = setup_user_with_copy_but_not_add_permission
4243 @request.session[:user_id] = user.id
4254 @request.session[:user_id] = user.id
4244
4255
4245 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => ''}, :copy => '1'
4256 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => ''}, :copy => '1'
4246 assert_response 403
4257 assert_response 403
4247 end
4258 end
4248
4259
4249 def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
4260 def test_bulk_copy_on_different_project_without_add_issues_permission_should_be_denied
4250 user = setup_user_with_copy_but_not_add_permission
4261 user = setup_user_with_copy_but_not_add_permission
4251 @request.session[:user_id] = user.id
4262 @request.session[:user_id] = user.id
4252
4263
4253 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '1'}, :copy => '1'
4264 post :bulk_update, :ids => [1, 2, 3], :issue => {:project_id => '1'}, :copy => '1'
4254 assert_response 403
4265 assert_response 403
4255 end
4266 end
4256
4267
4257 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
4268 def test_bulk_copy_should_allow_not_changing_the_issue_attributes
4258 @request.session[:user_id] = 2
4269 @request.session[:user_id] = 2
4259 issues = [
4270 issues = [
4260 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
4271 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
4261 :priority_id => 2, :subject => 'issue 1', :author_id => 1,
4272 :priority_id => 2, :subject => 'issue 1', :author_id => 1,
4262 :assigned_to_id => nil),
4273 :assigned_to_id => nil),
4263 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
4274 Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2,
4264 :priority_id => 1, :subject => 'issue 2', :author_id => 2,
4275 :priority_id => 1, :subject => 'issue 2', :author_id => 2,
4265 :assigned_to_id => 3)
4276 :assigned_to_id => 3)
4266 ]
4277 ]
4267 assert_difference 'Issue.count', issues.size do
4278 assert_difference 'Issue.count', issues.size do
4268 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
4279 post :bulk_update, :ids => issues.map(&:id), :copy => '1',
4269 :issue => {
4280 :issue => {
4270 :project_id => '', :tracker_id => '', :assigned_to_id => '',
4281 :project_id => '', :tracker_id => '', :assigned_to_id => '',
4271 :status_id => '', :start_date => '', :due_date => ''
4282 :status_id => '', :start_date => '', :due_date => ''
4272 }
4283 }
4273 end
4284 end
4274
4285
4275 copies = Issue.order('id DESC').limit(issues.size)
4286 copies = Issue.order('id DESC').limit(issues.size)
4276 issues.each do |orig|
4287 issues.each do |orig|
4277 copy = copies.detect {|c| c.subject == orig.subject}
4288 copy = copies.detect {|c| c.subject == orig.subject}
4278 assert_not_nil copy
4289 assert_not_nil copy
4279 assert_equal orig.project_id, copy.project_id
4290 assert_equal orig.project_id, copy.project_id
4280 assert_equal orig.tracker_id, copy.tracker_id
4291 assert_equal orig.tracker_id, copy.tracker_id
4281 assert_equal orig.status_id, copy.status_id
4292 assert_equal orig.status_id, copy.status_id
4282 assert_equal orig.assigned_to_id, copy.assigned_to_id
4293 assert_equal orig.assigned_to_id, copy.assigned_to_id
4283 assert_equal orig.priority_id, copy.priority_id
4294 assert_equal orig.priority_id, copy.priority_id
4284 end
4295 end
4285 end
4296 end
4286
4297
4287 def test_bulk_copy_should_allow_changing_the_issue_attributes
4298 def test_bulk_copy_should_allow_changing_the_issue_attributes
4288 # Fixes random test failure with Mysql
4299 # Fixes random test failure with Mysql
4289 # where Issue.where(:project_id => 2).limit(2).order('id desc')
4300 # where Issue.where(:project_id => 2).limit(2).order('id desc')
4290 # doesn't return the expected results
4301 # doesn't return the expected results
4291 Issue.delete_all("project_id=2")
4302 Issue.delete_all("project_id=2")
4292
4303
4293 @request.session[:user_id] = 2
4304 @request.session[:user_id] = 2
4294 assert_difference 'Issue.count', 2 do
4305 assert_difference 'Issue.count', 2 do
4295 assert_no_difference 'Project.find(1).issues.count' do
4306 assert_no_difference 'Project.find(1).issues.count' do
4296 post :bulk_update, :ids => [1, 2], :copy => '1',
4307 post :bulk_update, :ids => [1, 2], :copy => '1',
4297 :issue => {
4308 :issue => {
4298 :project_id => '2', :tracker_id => '', :assigned_to_id => '2',
4309 :project_id => '2', :tracker_id => '', :assigned_to_id => '2',
4299 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
4310 :status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
4300 }
4311 }
4301 end
4312 end
4302 end
4313 end
4303
4314
4304 copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
4315 copied_issues = Issue.where(:project_id => 2).limit(2).order('id desc').to_a
4305 assert_equal 2, copied_issues.size
4316 assert_equal 2, copied_issues.size
4306 copied_issues.each do |issue|
4317 copied_issues.each do |issue|
4307 assert_equal 2, issue.project_id, "Project is incorrect"
4318 assert_equal 2, issue.project_id, "Project is incorrect"
4308 assert_equal 2, issue.assigned_to_id, "Assigned to is incorrect"
4319 assert_equal 2, issue.assigned_to_id, "Assigned to is incorrect"
4309 assert_equal 1, issue.status_id, "Status is incorrect"
4320 assert_equal 1, issue.status_id, "Status is incorrect"
4310 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
4321 assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
4311 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
4322 assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
4312 end
4323 end
4313 end
4324 end
4314
4325
4315 def test_bulk_copy_should_allow_adding_a_note
4326 def test_bulk_copy_should_allow_adding_a_note
4316 @request.session[:user_id] = 2
4327 @request.session[:user_id] = 2
4317 assert_difference 'Issue.count', 1 do
4328 assert_difference 'Issue.count', 1 do
4318 post :bulk_update, :ids => [1], :copy => '1',
4329 post :bulk_update, :ids => [1], :copy => '1',
4319 :notes => 'Copying one issue',
4330 :notes => 'Copying one issue',
4320 :issue => {
4331 :issue => {
4321 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
4332 :project_id => '', :tracker_id => '', :assigned_to_id => '4',
4322 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
4333 :status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
4323 }
4334 }
4324 end
4335 end
4325 issue = Issue.order('id DESC').first
4336 issue = Issue.order('id DESC').first
4326 assert_equal 1, issue.journals.size
4337 assert_equal 1, issue.journals.size
4327 journal = issue.journals.first
4338 journal = issue.journals.first
4328 assert_equal 'Copying one issue', journal.notes
4339 assert_equal 'Copying one issue', journal.notes
4329 end
4340 end
4330
4341
4331 def test_bulk_copy_should_allow_not_copying_the_attachments
4342 def test_bulk_copy_should_allow_not_copying_the_attachments
4332 attachment_count = Issue.find(3).attachments.size
4343 attachment_count = Issue.find(3).attachments.size
4333 assert attachment_count > 0
4344 assert attachment_count > 0
4334 @request.session[:user_id] = 2
4345 @request.session[:user_id] = 2
4335
4346
4336 assert_difference 'Issue.count', 1 do
4347 assert_difference 'Issue.count', 1 do
4337 assert_no_difference 'Attachment.count' do
4348 assert_no_difference 'Attachment.count' do
4338 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '0',
4349 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '0',
4339 :issue => {
4350 :issue => {
4340 :project_id => ''
4351 :project_id => ''
4341 }
4352 }
4342 end
4353 end
4343 end
4354 end
4344 end
4355 end
4345
4356
4346 def test_bulk_copy_should_allow_copying_the_attachments
4357 def test_bulk_copy_should_allow_copying_the_attachments
4347 attachment_count = Issue.find(3).attachments.size
4358 attachment_count = Issue.find(3).attachments.size
4348 assert attachment_count > 0
4359 assert attachment_count > 0
4349 @request.session[:user_id] = 2
4360 @request.session[:user_id] = 2
4350
4361
4351 assert_difference 'Issue.count', 1 do
4362 assert_difference 'Issue.count', 1 do
4352 assert_difference 'Attachment.count', attachment_count do
4363 assert_difference 'Attachment.count', attachment_count do
4353 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
4364 post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
4354 :issue => {
4365 :issue => {
4355 :project_id => ''
4366 :project_id => ''
4356 }
4367 }
4357 end
4368 end
4358 end
4369 end
4359 end
4370 end
4360
4371
4361 def test_bulk_copy_should_add_relations_with_copied_issues
4372 def test_bulk_copy_should_add_relations_with_copied_issues
4362 @request.session[:user_id] = 2
4373 @request.session[:user_id] = 2
4363
4374
4364 assert_difference 'Issue.count', 2 do
4375 assert_difference 'Issue.count', 2 do
4365 assert_difference 'IssueRelation.count', 2 do
4376 assert_difference 'IssueRelation.count', 2 do
4366 post :bulk_update, :ids => [1, 3], :copy => '1', :link_copy => '1',
4377 post :bulk_update, :ids => [1, 3], :copy => '1', :link_copy => '1',
4367 :issue => {
4378 :issue => {
4368 :project_id => '1'
4379 :project_id => '1'
4369 }
4380 }
4370 end
4381 end
4371 end
4382 end
4372 end
4383 end
4373
4384
4374 def test_bulk_copy_should_allow_not_copying_the_subtasks
4385 def test_bulk_copy_should_allow_not_copying_the_subtasks
4375 issue = Issue.generate_with_descendants!
4386 issue = Issue.generate_with_descendants!
4376 @request.session[:user_id] = 2
4387 @request.session[:user_id] = 2
4377
4388
4378 assert_difference 'Issue.count', 1 do
4389 assert_difference 'Issue.count', 1 do
4379 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '0',
4390 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '0',
4380 :issue => {
4391 :issue => {
4381 :project_id => ''
4392 :project_id => ''
4382 }
4393 }
4383 end
4394 end
4384 end
4395 end
4385
4396
4386 def test_bulk_copy_should_allow_copying_the_subtasks
4397 def test_bulk_copy_should_allow_copying_the_subtasks
4387 issue = Issue.generate_with_descendants!
4398 issue = Issue.generate_with_descendants!
4388 count = issue.descendants.count
4399 count = issue.descendants.count
4389 @request.session[:user_id] = 2
4400 @request.session[:user_id] = 2
4390
4401
4391 assert_difference 'Issue.count', count+1 do
4402 assert_difference 'Issue.count', count+1 do
4392 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
4403 post :bulk_update, :ids => [issue.id], :copy => '1', :copy_subtasks => '1',
4393 :issue => {
4404 :issue => {
4394 :project_id => ''
4405 :project_id => ''
4395 }
4406 }
4396 end
4407 end
4397 copy = Issue.where(:parent_id => nil).order("id DESC").first
4408 copy = Issue.where(:parent_id => nil).order("id DESC").first
4398 assert_equal count, copy.descendants.count
4409 assert_equal count, copy.descendants.count
4399 end
4410 end
4400
4411
4401 def test_bulk_copy_should_not_copy_selected_subtasks_twice
4412 def test_bulk_copy_should_not_copy_selected_subtasks_twice
4402 issue = Issue.generate_with_descendants!
4413 issue = Issue.generate_with_descendants!
4403 count = issue.descendants.count
4414 count = issue.descendants.count
4404 @request.session[:user_id] = 2
4415 @request.session[:user_id] = 2
4405
4416
4406 assert_difference 'Issue.count', count+1 do
4417 assert_difference 'Issue.count', count+1 do
4407 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
4418 post :bulk_update, :ids => issue.self_and_descendants.map(&:id), :copy => '1', :copy_subtasks => '1',
4408 :issue => {
4419 :issue => {
4409 :project_id => ''
4420 :project_id => ''
4410 }
4421 }
4411 end
4422 end
4412 copy = Issue.where(:parent_id => nil).order("id DESC").first
4423 copy = Issue.where(:parent_id => nil).order("id DESC").first
4413 assert_equal count, copy.descendants.count
4424 assert_equal count, copy.descendants.count
4414 end
4425 end
4415
4426
4416 def test_bulk_copy_to_another_project_should_follow_when_needed
4427 def test_bulk_copy_to_another_project_should_follow_when_needed
4417 @request.session[:user_id] = 2
4428 @request.session[:user_id] = 2
4418 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
4429 post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
4419 issue = Issue.order('id DESC').first
4430 issue = Issue.order('id DESC').first
4420 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
4431 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
4421 end
4432 end
4422
4433
4423 def test_bulk_copy_with_all_failures_should_display_errors
4434 def test_bulk_copy_with_all_failures_should_display_errors
4424 @request.session[:user_id] = 2
4435 @request.session[:user_id] = 2
4425 post :bulk_update, :ids => [1, 2], :copy => '1', :issue => {:start_date => 'foo'}
4436 post :bulk_update, :ids => [1, 2], :copy => '1', :issue => {:start_date => 'foo'}
4426
4437
4427 assert_response :success
4438 assert_response :success
4428 end
4439 end
4429
4440
4430 def test_destroy_issue_with_no_time_entries
4441 def test_destroy_issue_with_no_time_entries
4431 assert_nil TimeEntry.find_by_issue_id(2)
4442 assert_nil TimeEntry.find_by_issue_id(2)
4432 @request.session[:user_id] = 2
4443 @request.session[:user_id] = 2
4433
4444
4434 assert_difference 'Issue.count', -1 do
4445 assert_difference 'Issue.count', -1 do
4435 delete :destroy, :id => 2
4446 delete :destroy, :id => 2
4436 end
4447 end
4437 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4448 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4438 assert_nil Issue.find_by_id(2)
4449 assert_nil Issue.find_by_id(2)
4439 end
4450 end
4440
4451
4441 def test_destroy_issues_with_time_entries
4452 def test_destroy_issues_with_time_entries
4442 @request.session[:user_id] = 2
4453 @request.session[:user_id] = 2
4443
4454
4444 assert_no_difference 'Issue.count' do
4455 assert_no_difference 'Issue.count' do
4445 delete :destroy, :ids => [1, 3]
4456 delete :destroy, :ids => [1, 3]
4446 end
4457 end
4447 assert_response :success
4458 assert_response :success
4448 assert_template 'destroy'
4459 assert_template 'destroy'
4449 assert_not_nil assigns(:hours)
4460 assert_not_nil assigns(:hours)
4450 assert Issue.find_by_id(1) && Issue.find_by_id(3)
4461 assert Issue.find_by_id(1) && Issue.find_by_id(3)
4451
4462
4452 assert_select 'form' do
4463 assert_select 'form' do
4453 assert_select 'input[name=_method][value=delete]'
4464 assert_select 'input[name=_method][value=delete]'
4454 end
4465 end
4455 end
4466 end
4456
4467
4457 def test_destroy_issues_and_destroy_time_entries
4468 def test_destroy_issues_and_destroy_time_entries
4458 @request.session[:user_id] = 2
4469 @request.session[:user_id] = 2
4459
4470
4460 assert_difference 'Issue.count', -2 do
4471 assert_difference 'Issue.count', -2 do
4461 assert_difference 'TimeEntry.count', -3 do
4472 assert_difference 'TimeEntry.count', -3 do
4462 delete :destroy, :ids => [1, 3], :todo => 'destroy'
4473 delete :destroy, :ids => [1, 3], :todo => 'destroy'
4463 end
4474 end
4464 end
4475 end
4465 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4476 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4466 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4477 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4467 assert_nil TimeEntry.find_by_id([1, 2])
4478 assert_nil TimeEntry.find_by_id([1, 2])
4468 end
4479 end
4469
4480
4470 def test_destroy_issues_and_assign_time_entries_to_project
4481 def test_destroy_issues_and_assign_time_entries_to_project
4471 @request.session[:user_id] = 2
4482 @request.session[:user_id] = 2
4472
4483
4473 assert_difference 'Issue.count', -2 do
4484 assert_difference 'Issue.count', -2 do
4474 assert_no_difference 'TimeEntry.count' do
4485 assert_no_difference 'TimeEntry.count' do
4475 delete :destroy, :ids => [1, 3], :todo => 'nullify'
4486 delete :destroy, :ids => [1, 3], :todo => 'nullify'
4476 end
4487 end
4477 end
4488 end
4478 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4489 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4479 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4490 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4480 assert_nil TimeEntry.find(1).issue_id
4491 assert_nil TimeEntry.find(1).issue_id
4481 assert_nil TimeEntry.find(2).issue_id
4492 assert_nil TimeEntry.find(2).issue_id
4482 end
4493 end
4483
4494
4484 def test_destroy_issues_and_reassign_time_entries_to_another_issue
4495 def test_destroy_issues_and_reassign_time_entries_to_another_issue
4485 @request.session[:user_id] = 2
4496 @request.session[:user_id] = 2
4486
4497
4487 assert_difference 'Issue.count', -2 do
4498 assert_difference 'Issue.count', -2 do
4488 assert_no_difference 'TimeEntry.count' do
4499 assert_no_difference 'TimeEntry.count' do
4489 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
4500 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
4490 end
4501 end
4491 end
4502 end
4492 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4503 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
4493 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4504 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
4494 assert_equal 2, TimeEntry.find(1).issue_id
4505 assert_equal 2, TimeEntry.find(1).issue_id
4495 assert_equal 2, TimeEntry.find(2).issue_id
4506 assert_equal 2, TimeEntry.find(2).issue_id
4496 end
4507 end
4497
4508
4498 def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
4509 def test_destroy_issues_and_reassign_time_entries_to_an_invalid_issue_should_fail
4499 @request.session[:user_id] = 2
4510 @request.session[:user_id] = 2
4500
4511
4501 assert_no_difference 'Issue.count' do
4512 assert_no_difference 'Issue.count' do
4502 assert_no_difference 'TimeEntry.count' do
4513 assert_no_difference 'TimeEntry.count' do
4503 # try to reassign time to an issue of another project
4514 # try to reassign time to an issue of another project
4504 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 4
4515 delete :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 4
4505 end
4516 end
4506 end
4517 end
4507 assert_response :success
4518 assert_response :success
4508 assert_template 'destroy'
4519 assert_template 'destroy'
4509 end
4520 end
4510
4521
4511 def test_destroy_issues_from_different_projects
4522 def test_destroy_issues_from_different_projects
4512 @request.session[:user_id] = 2
4523 @request.session[:user_id] = 2
4513
4524
4514 assert_difference 'Issue.count', -3 do
4525 assert_difference 'Issue.count', -3 do
4515 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
4526 delete :destroy, :ids => [1, 2, 6], :todo => 'destroy'
4516 end
4527 end
4517 assert_redirected_to :controller => 'issues', :action => 'index'
4528 assert_redirected_to :controller => 'issues', :action => 'index'
4518 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
4529 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
4519 end
4530 end
4520
4531
4521 def test_destroy_parent_and_child_issues
4532 def test_destroy_parent_and_child_issues
4522 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
4533 parent = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Parent Issue')
4523 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
4534 child = Issue.create!(:project_id => 1, :author_id => 1, :tracker_id => 1, :subject => 'Child Issue', :parent_issue_id => parent.id)
4524 assert child.is_descendant_of?(parent.reload)
4535 assert child.is_descendant_of?(parent.reload)
4525
4536
4526 @request.session[:user_id] = 2
4537 @request.session[:user_id] = 2
4527 assert_difference 'Issue.count', -2 do
4538 assert_difference 'Issue.count', -2 do
4528 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
4539 delete :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
4529 end
4540 end
4530 assert_response 302
4541 assert_response 302
4531 end
4542 end
4532
4543
4533 def test_destroy_invalid_should_respond_with_404
4544 def test_destroy_invalid_should_respond_with_404
4534 @request.session[:user_id] = 2
4545 @request.session[:user_id] = 2
4535 assert_no_difference 'Issue.count' do
4546 assert_no_difference 'Issue.count' do
4536 delete :destroy, :id => 999
4547 delete :destroy, :id => 999
4537 end
4548 end
4538 assert_response 404
4549 assert_response 404
4539 end
4550 end
4540
4551
4541 def test_default_search_scope
4552 def test_default_search_scope
4542 get :index
4553 get :index
4543
4554
4544 assert_select 'div#quick-search form' do
4555 assert_select 'div#quick-search form' do
4545 assert_select 'input[name=issues][value="1"][type=hidden]'
4556 assert_select 'input[name=issues][value="1"][type=hidden]'
4546 end
4557 end
4547 end
4558 end
4548
4559
4549 def setup_user_with_copy_but_not_add_permission
4560 def setup_user_with_copy_but_not_add_permission
4550 Role.all.each {|r| r.remove_permission! :add_issues}
4561 Role.all.each {|r| r.remove_permission! :add_issues}
4551 Role.find_by_name('Manager').add_permission! :add_issues
4562 Role.find_by_name('Manager').add_permission! :add_issues
4552 user = User.generate!
4563 user = User.generate!
4553 User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
4564 User.add_to_project(user, Project.find(1), Role.find_by_name('Developer'))
4554 User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
4565 User.add_to_project(user, Project.find(2), Role.find_by_name('Manager'))
4555 user
4566 user
4556 end
4567 end
4557 end
4568 end
General Comments 0
You need to be logged in to leave comments. Login now