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