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