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