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