##// END OF EJS Templates
Merged r8113 from trunk (#9738)....
Jean-Philippe Lang -
r8039:65a7c7e96c9b
parent child
Show More
@@ -1,102 +1,103
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 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 module QueriesHelper
18 module QueriesHelper
19
19
20 def operators_for_select(filter_type)
20 def operators_for_select(filter_type)
21 Query.operators_by_filter_type[filter_type].collect {|o| [l(Query.operators[o]), o]}
21 Query.operators_by_filter_type[filter_type].collect {|o| [l(Query.operators[o]), o]}
22 end
22 end
23
23
24 def column_header(column)
24 def column_header(column)
25 column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
25 column.sortable ? sort_header_tag(column.name.to_s, :caption => column.caption,
26 :default_order => column.default_order) :
26 :default_order => column.default_order) :
27 content_tag('th', h(column.caption))
27 content_tag('th', h(column.caption))
28 end
28 end
29
29
30 def column_content(column, issue)
30 def column_content(column, issue)
31 value = column.value(issue)
31 value = column.value(issue)
32
32
33 case value.class.name
33 case value.class.name
34 when 'String'
34 when 'String'
35 if column.name == :subject
35 if column.name == :subject
36 link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
36 link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
37 else
37 else
38 h(value)
38 h(value)
39 end
39 end
40 when 'Time'
40 when 'Time'
41 format_time(value)
41 format_time(value)
42 when 'Date'
42 when 'Date'
43 format_date(value)
43 format_date(value)
44 when 'Fixnum', 'Float'
44 when 'Fixnum', 'Float'
45 if column.name == :done_ratio
45 if column.name == :done_ratio
46 progress_bar(value, :width => '80px')
46 progress_bar(value, :width => '80px')
47 else
47 else
48 h(value.to_s)
48 h(value.to_s)
49 end
49 end
50 when 'User'
50 when 'User'
51 link_to_user value
51 link_to_user value
52 when 'Project'
52 when 'Project'
53 link_to_project value
53 link_to_project value
54 when 'Version'
54 when 'Version'
55 link_to(h(value), :controller => 'versions', :action => 'show', :id => value)
55 link_to(h(value), :controller => 'versions', :action => 'show', :id => value)
56 when 'TrueClass'
56 when 'TrueClass'
57 l(:general_text_Yes)
57 l(:general_text_Yes)
58 when 'FalseClass'
58 when 'FalseClass'
59 l(:general_text_No)
59 l(:general_text_No)
60 when 'Issue'
60 when 'Issue'
61 link_to_issue(value, :subject => false)
61 link_to_issue(value, :subject => false)
62 else
62 else
63 h(value)
63 h(value)
64 end
64 end
65 end
65 end
66
66
67 # Retrieve query from session or build a new query
67 # Retrieve query from session or build a new query
68 def retrieve_query
68 def retrieve_query
69 if !params[:query_id].blank?
69 if !params[:query_id].blank?
70 cond = "project_id IS NULL"
70 cond = "project_id IS NULL"
71 cond << " OR project_id = #{@project.id}" if @project
71 cond << " OR project_id = #{@project.id}" if @project
72 @query = Query.find(params[:query_id], :conditions => cond)
72 @query = Query.find(params[:query_id], :conditions => cond)
73 raise ::Unauthorized unless @query.visible?
73 raise ::Unauthorized unless @query.visible?
74 @query.project = @project
74 @query.project = @project
75 session[:query] = {:id => @query.id, :project_id => @query.project_id}
75 session[:query] = {:id => @query.id, :project_id => @query.project_id}
76 sort_clear
76 sort_clear
77 elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
77 elsif api_request? || params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
78 # Give it a name, required to be valid
78 # Give it a name, required to be valid
79 @query = Query.new(:name => "_")
79 @query = Query.new(:name => "_")
80 @query.project = @project
80 @query.project = @project
81 build_query_from_params
81 build_query_from_params
82 session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
82 session[:query] = {:project_id => @query.project_id, :filters => @query.filters, :group_by => @query.group_by, :column_names => @query.column_names}
83 else
83 else
84 # retrieve from session
84 # retrieve from session
85 @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
85 @query = Query.find_by_id(session[:query][:id]) if session[:query][:id]
86 @query ||= Query.new(:name => "_", :project => @project, :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
86 @query ||= Query.new(:name => "_", :filters => session[:query][:filters], :group_by => session[:query][:group_by], :column_names => session[:query][:column_names])
87 @query.project = @project
87 end
88 end
88 end
89 end
89
90
90 def build_query_from_params
91 def build_query_from_params
91 if params[:fields] || params[:f]
92 if params[:fields] || params[:f]
92 @query.filters = {}
93 @query.filters = {}
93 @query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
94 @query.add_filters(params[:fields] || params[:f], params[:operators] || params[:op], params[:values] || params[:v])
94 else
95 else
95 @query.available_filters.keys.each do |field|
96 @query.available_filters.keys.each do |field|
96 @query.add_short_filter(field, params[field]) if params[field]
97 @query.add_short_filter(field, params[field]) if params[field]
97 end
98 end
98 end
99 end
99 @query.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
100 @query.group_by = params[:group_by] || (params[:query] && params[:query][:group_by])
100 @query.column_names = params[:c] || (params[:query] && params[:query][:column_names])
101 @query.column_names = params[:c] || (params[:query] && params[:query][:column_names])
101 end
102 end
102 end
103 end
@@ -1,1999 +1,2021
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19 require 'issues_controller'
19 require 'issues_controller'
20
20
21 class IssuesControllerTest < ActionController::TestCase
21 class IssuesControllerTest < ActionController::TestCase
22 fixtures :projects,
22 fixtures :projects,
23 :users,
23 :users,
24 :roles,
24 :roles,
25 :members,
25 :members,
26 :member_roles,
26 :member_roles,
27 :issues,
27 :issues,
28 :issue_statuses,
28 :issue_statuses,
29 :versions,
29 :versions,
30 :trackers,
30 :trackers,
31 :projects_trackers,
31 :projects_trackers,
32 :issue_categories,
32 :issue_categories,
33 :enabled_modules,
33 :enabled_modules,
34 :enumerations,
34 :enumerations,
35 :attachments,
35 :attachments,
36 :workflows,
36 :workflows,
37 :custom_fields,
37 :custom_fields,
38 :custom_values,
38 :custom_values,
39 :custom_fields_projects,
39 :custom_fields_projects,
40 :custom_fields_trackers,
40 :custom_fields_trackers,
41 :time_entries,
41 :time_entries,
42 :journals,
42 :journals,
43 :journal_details,
43 :journal_details,
44 :queries
44 :queries
45
45
46 include Redmine::I18n
46 include Redmine::I18n
47
47
48 def setup
48 def setup
49 @controller = IssuesController.new
49 @controller = IssuesController.new
50 @request = ActionController::TestRequest.new
50 @request = ActionController::TestRequest.new
51 @response = ActionController::TestResponse.new
51 @response = ActionController::TestResponse.new
52 User.current = nil
52 User.current = nil
53 end
53 end
54
54
55 def test_index
55 def test_index
56 Setting.default_language = 'en'
56 Setting.default_language = 'en'
57
57
58 get :index
58 get :index
59 assert_response :success
59 assert_response :success
60 assert_template 'index'
60 assert_template 'index'
61 assert_not_nil assigns(:issues)
61 assert_not_nil assigns(:issues)
62 assert_nil assigns(:project)
62 assert_nil assigns(:project)
63 assert_tag :tag => 'a', :content => /Can't print recipes/
63 assert_tag :tag => 'a', :content => /Can't print recipes/
64 assert_tag :tag => 'a', :content => /Subproject issue/
64 assert_tag :tag => 'a', :content => /Subproject issue/
65 # private projects hidden
65 # private projects hidden
66 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
66 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
67 assert_no_tag :tag => 'a', :content => /Issue on project 2/
67 assert_no_tag :tag => 'a', :content => /Issue on project 2/
68 # project column
68 # project column
69 assert_tag :tag => 'th', :content => /Project/
69 assert_tag :tag => 'th', :content => /Project/
70 end
70 end
71
71
72 def test_index_should_not_list_issues_when_module_disabled
72 def test_index_should_not_list_issues_when_module_disabled
73 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
73 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
74 get :index
74 get :index
75 assert_response :success
75 assert_response :success
76 assert_template 'index'
76 assert_template 'index'
77 assert_not_nil assigns(:issues)
77 assert_not_nil assigns(:issues)
78 assert_nil assigns(:project)
78 assert_nil assigns(:project)
79 assert_no_tag :tag => 'a', :content => /Can't print recipes/
79 assert_no_tag :tag => 'a', :content => /Can't print recipes/
80 assert_tag :tag => 'a', :content => /Subproject issue/
80 assert_tag :tag => 'a', :content => /Subproject issue/
81 end
81 end
82
82
83 def test_index_should_list_visible_issues_only
83 def test_index_should_list_visible_issues_only
84 get :index, :per_page => 100
84 get :index, :per_page => 100
85 assert_response :success
85 assert_response :success
86 assert_not_nil assigns(:issues)
86 assert_not_nil assigns(:issues)
87 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
87 assert_nil assigns(:issues).detect {|issue| !issue.visible?}
88 end
88 end
89
89
90 def test_index_with_project
90 def test_index_with_project
91 Setting.display_subprojects_issues = 0
91 Setting.display_subprojects_issues = 0
92 get :index, :project_id => 1
92 get :index, :project_id => 1
93 assert_response :success
93 assert_response :success
94 assert_template 'index'
94 assert_template 'index'
95 assert_not_nil assigns(:issues)
95 assert_not_nil assigns(:issues)
96 assert_tag :tag => 'a', :content => /Can't print recipes/
96 assert_tag :tag => 'a', :content => /Can't print recipes/
97 assert_no_tag :tag => 'a', :content => /Subproject issue/
97 assert_no_tag :tag => 'a', :content => /Subproject issue/
98 end
98 end
99
99
100 def test_index_with_project_and_subprojects
100 def test_index_with_project_and_subprojects
101 Setting.display_subprojects_issues = 1
101 Setting.display_subprojects_issues = 1
102 get :index, :project_id => 1
102 get :index, :project_id => 1
103 assert_response :success
103 assert_response :success
104 assert_template 'index'
104 assert_template 'index'
105 assert_not_nil assigns(:issues)
105 assert_not_nil assigns(:issues)
106 assert_tag :tag => 'a', :content => /Can't print recipes/
106 assert_tag :tag => 'a', :content => /Can't print recipes/
107 assert_tag :tag => 'a', :content => /Subproject issue/
107 assert_tag :tag => 'a', :content => /Subproject issue/
108 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
108 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
109 end
109 end
110
110
111 def test_index_with_project_and_subprojects_should_show_private_subprojects
111 def test_index_with_project_and_subprojects_should_show_private_subprojects
112 @request.session[:user_id] = 2
112 @request.session[:user_id] = 2
113 Setting.display_subprojects_issues = 1
113 Setting.display_subprojects_issues = 1
114 get :index, :project_id => 1
114 get :index, :project_id => 1
115 assert_response :success
115 assert_response :success
116 assert_template 'index'
116 assert_template 'index'
117 assert_not_nil assigns(:issues)
117 assert_not_nil assigns(:issues)
118 assert_tag :tag => 'a', :content => /Can't print recipes/
118 assert_tag :tag => 'a', :content => /Can't print recipes/
119 assert_tag :tag => 'a', :content => /Subproject issue/
119 assert_tag :tag => 'a', :content => /Subproject issue/
120 assert_tag :tag => 'a', :content => /Issue of a private subproject/
120 assert_tag :tag => 'a', :content => /Issue of a private subproject/
121 end
121 end
122
122
123 def test_index_with_project_and_default_filter
123 def test_index_with_project_and_default_filter
124 get :index, :project_id => 1, :set_filter => 1
124 get :index, :project_id => 1, :set_filter => 1
125 assert_response :success
125 assert_response :success
126 assert_template 'index'
126 assert_template 'index'
127 assert_not_nil assigns(:issues)
127 assert_not_nil assigns(:issues)
128
128
129 query = assigns(:query)
129 query = assigns(:query)
130 assert_not_nil query
130 assert_not_nil query
131 # default filter
131 # default filter
132 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
132 assert_equal({'status_id' => {:operator => 'o', :values => ['']}}, query.filters)
133 end
133 end
134
134
135 def test_index_with_project_and_filter
135 def test_index_with_project_and_filter
136 get :index, :project_id => 1, :set_filter => 1,
136 get :index, :project_id => 1, :set_filter => 1,
137 :f => ['tracker_id'],
137 :f => ['tracker_id'],
138 :op => {'tracker_id' => '='},
138 :op => {'tracker_id' => '='},
139 :v => {'tracker_id' => ['1']}
139 :v => {'tracker_id' => ['1']}
140 assert_response :success
140 assert_response :success
141 assert_template 'index'
141 assert_template 'index'
142 assert_not_nil assigns(:issues)
142 assert_not_nil assigns(:issues)
143
143
144 query = assigns(:query)
144 query = assigns(:query)
145 assert_not_nil query
145 assert_not_nil query
146 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
146 assert_equal({'tracker_id' => {:operator => '=', :values => ['1']}}, query.filters)
147 end
147 end
148
148
149 def test_index_with_short_filters
149 def test_index_with_short_filters
150
150
151 to_test = {
151 to_test = {
152 'status_id' => {
152 'status_id' => {
153 'o' => { :op => 'o', :values => [''] },
153 'o' => { :op => 'o', :values => [''] },
154 'c' => { :op => 'c', :values => [''] },
154 'c' => { :op => 'c', :values => [''] },
155 '7' => { :op => '=', :values => ['7'] },
155 '7' => { :op => '=', :values => ['7'] },
156 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
156 '7|3|4' => { :op => '=', :values => ['7', '3', '4'] },
157 '=7' => { :op => '=', :values => ['7'] },
157 '=7' => { :op => '=', :values => ['7'] },
158 '!3' => { :op => '!', :values => ['3'] },
158 '!3' => { :op => '!', :values => ['3'] },
159 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
159 '!7|3|4' => { :op => '!', :values => ['7', '3', '4'] }},
160 'subject' => {
160 'subject' => {
161 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
161 'This is a subject' => { :op => '=', :values => ['This is a subject'] },
162 'o' => { :op => '=', :values => ['o'] },
162 'o' => { :op => '=', :values => ['o'] },
163 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
163 '~This is part of a subject' => { :op => '~', :values => ['This is part of a subject'] },
164 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
164 '!~This is part of a subject' => { :op => '!~', :values => ['This is part of a subject'] }},
165 'tracker_id' => {
165 'tracker_id' => {
166 '3' => { :op => '=', :values => ['3'] },
166 '3' => { :op => '=', :values => ['3'] },
167 '=3' => { :op => '=', :values => ['3'] }},
167 '=3' => { :op => '=', :values => ['3'] }},
168 'start_date' => {
168 'start_date' => {
169 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
169 '2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
170 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
170 '=2011-10-12' => { :op => '=', :values => ['2011-10-12'] },
171 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
171 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
172 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
172 '<=2011-10-12' => { :op => '<=', :values => ['2011-10-12'] },
173 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
173 '><2011-10-01|2011-10-30' => { :op => '><', :values => ['2011-10-01', '2011-10-30'] },
174 '<t+2' => { :op => '<t+', :values => ['2'] },
174 '<t+2' => { :op => '<t+', :values => ['2'] },
175 '>t+2' => { :op => '>t+', :values => ['2'] },
175 '>t+2' => { :op => '>t+', :values => ['2'] },
176 't+2' => { :op => 't+', :values => ['2'] },
176 't+2' => { :op => 't+', :values => ['2'] },
177 't' => { :op => 't', :values => [''] },
177 't' => { :op => 't', :values => [''] },
178 'w' => { :op => 'w', :values => [''] },
178 'w' => { :op => 'w', :values => [''] },
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-2' => { :op => 't-', :values => ['2'] }},
181 't-2' => { :op => 't-', :values => ['2'] }},
182 'created_on' => {
182 'created_on' => {
183 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
183 '>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
184 '<t+2' => { :op => '=', :values => ['<t+2'] },
184 '<t+2' => { :op => '=', :values => ['<t+2'] },
185 '>t+2' => { :op => '=', :values => ['>t+2'] },
185 '>t+2' => { :op => '=', :values => ['>t+2'] },
186 't+2' => { :op => 't', :values => ['+2'] }},
186 't+2' => { :op => 't', :values => ['+2'] }},
187 'cf_1' => {
187 'cf_1' => {
188 'c' => { :op => '=', :values => ['c'] },
188 'c' => { :op => '=', :values => ['c'] },
189 '!c' => { :op => '!', :values => ['c'] },
189 '!c' => { :op => '!', :values => ['c'] },
190 '!*' => { :op => '!*', :values => [''] },
190 '!*' => { :op => '!*', :values => [''] },
191 '*' => { :op => '*', :values => [''] }},
191 '*' => { :op => '*', :values => [''] }},
192 'estimated_hours' => {
192 'estimated_hours' => {
193 '=13.4' => { :op => '=', :values => ['13.4'] },
193 '=13.4' => { :op => '=', :values => ['13.4'] },
194 '>=45' => { :op => '>=', :values => ['45'] },
194 '>=45' => { :op => '>=', :values => ['45'] },
195 '<=125' => { :op => '<=', :values => ['125'] },
195 '<=125' => { :op => '<=', :values => ['125'] },
196 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
196 '><10.5|20.5' => { :op => '><', :values => ['10.5', '20.5'] },
197 '!*' => { :op => '!*', :values => [''] },
197 '!*' => { :op => '!*', :values => [''] },
198 '*' => { :op => '*', :values => [''] }}
198 '*' => { :op => '*', :values => [''] }}
199 }
199 }
200
200
201 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
201 default_filter = { 'status_id' => {:operator => 'o', :values => [''] }}
202
202
203 to_test.each do |field, expression_and_expected|
203 to_test.each do |field, expression_and_expected|
204 expression_and_expected.each do |filter_expression, expected|
204 expression_and_expected.each do |filter_expression, expected|
205
205
206 get :index, :set_filter => 1, field => filter_expression
206 get :index, :set_filter => 1, field => filter_expression
207
207
208 assert_response :success
208 assert_response :success
209 assert_template 'index'
209 assert_template 'index'
210 assert_not_nil assigns(:issues)
210 assert_not_nil assigns(:issues)
211
211
212 query = assigns(:query)
212 query = assigns(:query)
213 assert_not_nil query
213 assert_not_nil query
214 assert query.has_filter?(field)
214 assert query.has_filter?(field)
215 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
215 assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
216 end
216 end
217 end
217 end
218
218
219 end
219 end
220
220
221 def test_index_with_project_and_empty_filters
221 def test_index_with_project_and_empty_filters
222 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
222 get :index, :project_id => 1, :set_filter => 1, :fields => ['']
223 assert_response :success
223 assert_response :success
224 assert_template 'index'
224 assert_template 'index'
225 assert_not_nil assigns(:issues)
225 assert_not_nil assigns(:issues)
226
226
227 query = assigns(:query)
227 query = assigns(:query)
228 assert_not_nil query
228 assert_not_nil query
229 # no filter
229 # no filter
230 assert_equal({}, query.filters)
230 assert_equal({}, query.filters)
231 end
231 end
232
232
233 def test_index_with_query
233 def test_index_with_query
234 get :index, :project_id => 1, :query_id => 5
234 get :index, :project_id => 1, :query_id => 5
235 assert_response :success
235 assert_response :success
236 assert_template 'index'
236 assert_template 'index'
237 assert_not_nil assigns(:issues)
237 assert_not_nil assigns(:issues)
238 assert_nil assigns(:issue_count_by_group)
238 assert_nil assigns(:issue_count_by_group)
239 end
239 end
240
240
241 def test_index_with_query_grouped_by_tracker
241 def test_index_with_query_grouped_by_tracker
242 get :index, :project_id => 1, :query_id => 6
242 get :index, :project_id => 1, :query_id => 6
243 assert_response :success
243 assert_response :success
244 assert_template 'index'
244 assert_template 'index'
245 assert_not_nil assigns(:issues)
245 assert_not_nil assigns(:issues)
246 assert_not_nil assigns(:issue_count_by_group)
246 assert_not_nil assigns(:issue_count_by_group)
247 end
247 end
248
248
249 def test_index_with_query_grouped_by_list_custom_field
249 def test_index_with_query_grouped_by_list_custom_field
250 get :index, :project_id => 1, :query_id => 9
250 get :index, :project_id => 1, :query_id => 9
251 assert_response :success
251 assert_response :success
252 assert_template 'index'
252 assert_template 'index'
253 assert_not_nil assigns(:issues)
253 assert_not_nil assigns(:issues)
254 assert_not_nil assigns(:issue_count_by_group)
254 assert_not_nil assigns(:issue_count_by_group)
255 end
255 end
256
256
257 def test_index_with_query_id_and_project_id_should_set_session_query
258 get :index, :project_id => 1, :query_id => 4
259 assert_response :success
260 assert_kind_of Hash, session[:query]
261 assert_equal 4, session[:query][:id]
262 assert_equal 1, session[:query][:project_id]
263 end
264
265 def test_index_with_cross_project_query_in_session_should_show_project_issues
266 q = Query.create!(:name => "test", :user_id => 2, :is_public => false, :project => nil)
267 @request.session[:query] = {:id => q.id, :project_id => 1}
268
269 with_settings :display_subprojects_issues => '0' do
270 get :index, :project_id => 1
271 end
272 assert_response :success
273 assert_not_nil assigns(:query)
274 assert_equal q.id, assigns(:query).id
275 assert_equal 1, assigns(:query).project_id
276 assert_equal [1], assigns(:issues).map(&:project_id).uniq
277 end
278
257 def test_private_query_should_not_be_available_to_other_users
279 def test_private_query_should_not_be_available_to_other_users
258 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
280 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
259 @request.session[:user_id] = 3
281 @request.session[:user_id] = 3
260
282
261 get :index, :query_id => q.id
283 get :index, :query_id => q.id
262 assert_response 403
284 assert_response 403
263 end
285 end
264
286
265 def test_private_query_should_be_available_to_its_user
287 def test_private_query_should_be_available_to_its_user
266 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
288 q = Query.create!(:name => "private", :user => User.find(2), :is_public => false, :project => nil)
267 @request.session[:user_id] = 2
289 @request.session[:user_id] = 2
268
290
269 get :index, :query_id => q.id
291 get :index, :query_id => q.id
270 assert_response :success
292 assert_response :success
271 end
293 end
272
294
273 def test_public_query_should_be_available_to_other_users
295 def test_public_query_should_be_available_to_other_users
274 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
296 q = Query.create!(:name => "private", :user => User.find(2), :is_public => true, :project => nil)
275 @request.session[:user_id] = 3
297 @request.session[:user_id] = 3
276
298
277 get :index, :query_id => q.id
299 get :index, :query_id => q.id
278 assert_response :success
300 assert_response :success
279 end
301 end
280
302
281 def test_index_csv
303 def test_index_csv
282 get :index, :format => 'csv'
304 get :index, :format => 'csv'
283 assert_response :success
305 assert_response :success
284 assert_not_nil assigns(:issues)
306 assert_not_nil assigns(:issues)
285 assert_equal 'text/csv', @response.content_type
307 assert_equal 'text/csv', @response.content_type
286 assert @response.body.starts_with?("#,")
308 assert @response.body.starts_with?("#,")
287 lines = @response.body.chomp.split("\n")
309 lines = @response.body.chomp.split("\n")
288 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
310 assert_equal assigns(:query).columns.size + 1, lines[0].split(',').size
289 end
311 end
290
312
291 def test_index_csv_with_project
313 def test_index_csv_with_project
292 get :index, :project_id => 1, :format => 'csv'
314 get :index, :project_id => 1, :format => 'csv'
293 assert_response :success
315 assert_response :success
294 assert_not_nil assigns(:issues)
316 assert_not_nil assigns(:issues)
295 assert_equal 'text/csv', @response.content_type
317 assert_equal 'text/csv', @response.content_type
296 end
318 end
297
319
298 def test_index_csv_with_description
320 def test_index_csv_with_description
299 get :index, :format => 'csv', :description => '1'
321 get :index, :format => 'csv', :description => '1'
300 assert_response :success
322 assert_response :success
301 assert_not_nil assigns(:issues)
323 assert_not_nil assigns(:issues)
302 assert_equal 'text/csv', @response.content_type
324 assert_equal 'text/csv', @response.content_type
303 assert @response.body.starts_with?("#,")
325 assert @response.body.starts_with?("#,")
304 lines = @response.body.chomp.split("\n")
326 lines = @response.body.chomp.split("\n")
305 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
327 assert_equal assigns(:query).columns.size + 2, lines[0].split(',').size
306 end
328 end
307
329
308 def test_index_csv_with_all_columns
330 def test_index_csv_with_all_columns
309 get :index, :format => 'csv', :columns => 'all'
331 get :index, :format => 'csv', :columns => 'all'
310 assert_response :success
332 assert_response :success
311 assert_not_nil assigns(:issues)
333 assert_not_nil assigns(:issues)
312 assert_equal 'text/csv', @response.content_type
334 assert_equal 'text/csv', @response.content_type
313 assert @response.body.starts_with?("#,")
335 assert @response.body.starts_with?("#,")
314 lines = @response.body.chomp.split("\n")
336 lines = @response.body.chomp.split("\n")
315 assert_equal assigns(:query).available_columns.size + 1, lines[0].split(',').size
337 assert_equal assigns(:query).available_columns.size + 1, lines[0].split(',').size
316 end
338 end
317
339
318 def test_index_csv_big_5
340 def test_index_csv_big_5
319 with_settings :default_language => "zh-TW" do
341 with_settings :default_language => "zh-TW" do
320 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
342 str_utf8 = "\xe4\xb8\x80\xe6\x9c\x88"
321 str_big5 = "\xa4@\xa4\xeb"
343 str_big5 = "\xa4@\xa4\xeb"
322 if str_utf8.respond_to?(:force_encoding)
344 if str_utf8.respond_to?(:force_encoding)
323 str_utf8.force_encoding('UTF-8')
345 str_utf8.force_encoding('UTF-8')
324 str_big5.force_encoding('Big5')
346 str_big5.force_encoding('Big5')
325 end
347 end
326 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
348 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
327 :status_id => 1, :priority => IssuePriority.all.first,
349 :status_id => 1, :priority => IssuePriority.all.first,
328 :subject => str_utf8)
350 :subject => str_utf8)
329 assert issue.save
351 assert issue.save
330
352
331 get :index, :project_id => 1,
353 get :index, :project_id => 1,
332 :f => ['subject'],
354 :f => ['subject'],
333 :op => '=', :values => [str_utf8],
355 :op => '=', :values => [str_utf8],
334 :format => 'csv'
356 :format => 'csv'
335 assert_equal 'text/csv', @response.content_type
357 assert_equal 'text/csv', @response.content_type
336 lines = @response.body.chomp.split("\n")
358 lines = @response.body.chomp.split("\n")
337 s1 = "\xaa\xac\xbaA"
359 s1 = "\xaa\xac\xbaA"
338 if str_utf8.respond_to?(:force_encoding)
360 if str_utf8.respond_to?(:force_encoding)
339 s1.force_encoding('Big5')
361 s1.force_encoding('Big5')
340 end
362 end
341 assert lines[0].include?(s1)
363 assert lines[0].include?(s1)
342 assert lines[1].include?(str_big5)
364 assert lines[1].include?(str_big5)
343 end
365 end
344 end
366 end
345
367
346 def test_index_csv_cannot_convert_should_be_replaced_big_5
368 def test_index_csv_cannot_convert_should_be_replaced_big_5
347 with_settings :default_language => "zh-TW" do
369 with_settings :default_language => "zh-TW" do
348 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
370 str_utf8 = "\xe4\xbb\xa5\xe5\x86\x85"
349 if str_utf8.respond_to?(:force_encoding)
371 if str_utf8.respond_to?(:force_encoding)
350 str_utf8.force_encoding('UTF-8')
372 str_utf8.force_encoding('UTF-8')
351 end
373 end
352 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
374 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
353 :status_id => 1, :priority => IssuePriority.all.first,
375 :status_id => 1, :priority => IssuePriority.all.first,
354 :subject => str_utf8)
376 :subject => str_utf8)
355 assert issue.save
377 assert issue.save
356
378
357 get :index, :project_id => 1,
379 get :index, :project_id => 1,
358 :f => ['subject'],
380 :f => ['subject'],
359 :op => '=', :values => [str_utf8],
381 :op => '=', :values => [str_utf8],
360 :c => ['status', 'subject'],
382 :c => ['status', 'subject'],
361 :format => 'csv',
383 :format => 'csv',
362 :set_filter => 1
384 :set_filter => 1
363 assert_equal 'text/csv', @response.content_type
385 assert_equal 'text/csv', @response.content_type
364 lines = @response.body.chomp.split("\n")
386 lines = @response.body.chomp.split("\n")
365 s1 = "\xaa\xac\xbaA" # status
387 s1 = "\xaa\xac\xbaA" # status
366 if str_utf8.respond_to?(:force_encoding)
388 if str_utf8.respond_to?(:force_encoding)
367 s1.force_encoding('Big5')
389 s1.force_encoding('Big5')
368 end
390 end
369 assert lines[0].include?(s1)
391 assert lines[0].include?(s1)
370 s2 = lines[1].split(",")[2]
392 s2 = lines[1].split(",")[2]
371 if s1.respond_to?(:force_encoding)
393 if s1.respond_to?(:force_encoding)
372 s3 = "\xa5H?" # subject
394 s3 = "\xa5H?" # subject
373 s3.force_encoding('Big5')
395 s3.force_encoding('Big5')
374 assert_equal s3, s2
396 assert_equal s3, s2
375 elsif RUBY_PLATFORM == 'java'
397 elsif RUBY_PLATFORM == 'java'
376 assert_equal "??", s2
398 assert_equal "??", s2
377 else
399 else
378 assert_equal "\xa5H???", s2
400 assert_equal "\xa5H???", s2
379 end
401 end
380 end
402 end
381 end
403 end
382
404
383 def test_index_csv_tw
405 def test_index_csv_tw
384 with_settings :default_language => "zh-TW" do
406 with_settings :default_language => "zh-TW" do
385 str1 = "test_index_csv_tw"
407 str1 = "test_index_csv_tw"
386 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
408 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
387 :status_id => 1, :priority => IssuePriority.all.first,
409 :status_id => 1, :priority => IssuePriority.all.first,
388 :subject => str1, :estimated_hours => '1234.5')
410 :subject => str1, :estimated_hours => '1234.5')
389 assert issue.save
411 assert issue.save
390 assert_equal 1234.5, issue.estimated_hours
412 assert_equal 1234.5, issue.estimated_hours
391
413
392 get :index, :project_id => 1,
414 get :index, :project_id => 1,
393 :f => ['subject'],
415 :f => ['subject'],
394 :op => '=', :values => [str1],
416 :op => '=', :values => [str1],
395 :c => ['estimated_hours', 'subject'],
417 :c => ['estimated_hours', 'subject'],
396 :format => 'csv',
418 :format => 'csv',
397 :set_filter => 1
419 :set_filter => 1
398 assert_equal 'text/csv', @response.content_type
420 assert_equal 'text/csv', @response.content_type
399 lines = @response.body.chomp.split("\n")
421 lines = @response.body.chomp.split("\n")
400 assert_equal "#{issue.id},1234.5,#{str1}", lines[1]
422 assert_equal "#{issue.id},1234.5,#{str1}", lines[1]
401
423
402 str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
424 str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)"
403 if str_tw.respond_to?(:force_encoding)
425 if str_tw.respond_to?(:force_encoding)
404 str_tw.force_encoding('UTF-8')
426 str_tw.force_encoding('UTF-8')
405 end
427 end
406 assert_equal str_tw, l(:general_lang_name)
428 assert_equal str_tw, l(:general_lang_name)
407 assert_equal ',', l(:general_csv_separator)
429 assert_equal ',', l(:general_csv_separator)
408 assert_equal '.', l(:general_csv_decimal_separator)
430 assert_equal '.', l(:general_csv_decimal_separator)
409 end
431 end
410 end
432 end
411
433
412 def test_index_csv_fr
434 def test_index_csv_fr
413 with_settings :default_language => "fr" do
435 with_settings :default_language => "fr" do
414 str1 = "test_index_csv_fr"
436 str1 = "test_index_csv_fr"
415 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
437 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
416 :status_id => 1, :priority => IssuePriority.all.first,
438 :status_id => 1, :priority => IssuePriority.all.first,
417 :subject => str1, :estimated_hours => '1234.5')
439 :subject => str1, :estimated_hours => '1234.5')
418 assert issue.save
440 assert issue.save
419 assert_equal 1234.5, issue.estimated_hours
441 assert_equal 1234.5, issue.estimated_hours
420
442
421 get :index, :project_id => 1,
443 get :index, :project_id => 1,
422 :f => ['subject'],
444 :f => ['subject'],
423 :op => '=', :values => [str1],
445 :op => '=', :values => [str1],
424 :c => ['estimated_hours', 'subject'],
446 :c => ['estimated_hours', 'subject'],
425 :format => 'csv',
447 :format => 'csv',
426 :set_filter => 1
448 :set_filter => 1
427 assert_equal 'text/csv', @response.content_type
449 assert_equal 'text/csv', @response.content_type
428 lines = @response.body.chomp.split("\n")
450 lines = @response.body.chomp.split("\n")
429 assert_equal "#{issue.id};1234,5;#{str1}", lines[1]
451 assert_equal "#{issue.id};1234,5;#{str1}", lines[1]
430
452
431 str_fr = "Fran\xc3\xa7ais"
453 str_fr = "Fran\xc3\xa7ais"
432 if str_fr.respond_to?(:force_encoding)
454 if str_fr.respond_to?(:force_encoding)
433 str_fr.force_encoding('UTF-8')
455 str_fr.force_encoding('UTF-8')
434 end
456 end
435 assert_equal str_fr, l(:general_lang_name)
457 assert_equal str_fr, l(:general_lang_name)
436 assert_equal ';', l(:general_csv_separator)
458 assert_equal ';', l(:general_csv_separator)
437 assert_equal ',', l(:general_csv_decimal_separator)
459 assert_equal ',', l(:general_csv_decimal_separator)
438 end
460 end
439 end
461 end
440
462
441 def test_index_pdf
463 def test_index_pdf
442 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
464 ["en", "zh", "zh-TW", "ja", "ko"].each do |lang|
443 with_settings :default_language => lang do
465 with_settings :default_language => lang do
444
466
445 get :index
467 get :index
446 assert_response :success
468 assert_response :success
447 assert_template 'index'
469 assert_template 'index'
448
470
449 if lang == "ja"
471 if lang == "ja"
450 if RUBY_PLATFORM != 'java'
472 if RUBY_PLATFORM != 'java'
451 assert_equal "CP932", l(:general_pdf_encoding)
473 assert_equal "CP932", l(:general_pdf_encoding)
452 end
474 end
453 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
475 if RUBY_PLATFORM == 'java' && l(:general_pdf_encoding) == "CP932"
454 next
476 next
455 end
477 end
456 end
478 end
457
479
458 get :index, :format => 'pdf'
480 get :index, :format => 'pdf'
459 assert_response :success
481 assert_response :success
460 assert_not_nil assigns(:issues)
482 assert_not_nil assigns(:issues)
461 assert_equal 'application/pdf', @response.content_type
483 assert_equal 'application/pdf', @response.content_type
462
484
463 get :index, :project_id => 1, :format => 'pdf'
485 get :index, :project_id => 1, :format => 'pdf'
464 assert_response :success
486 assert_response :success
465 assert_not_nil assigns(:issues)
487 assert_not_nil assigns(:issues)
466 assert_equal 'application/pdf', @response.content_type
488 assert_equal 'application/pdf', @response.content_type
467
489
468 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
490 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
469 assert_response :success
491 assert_response :success
470 assert_not_nil assigns(:issues)
492 assert_not_nil assigns(:issues)
471 assert_equal 'application/pdf', @response.content_type
493 assert_equal 'application/pdf', @response.content_type
472 end
494 end
473 end
495 end
474 end
496 end
475
497
476 def test_index_pdf_with_query_grouped_by_list_custom_field
498 def test_index_pdf_with_query_grouped_by_list_custom_field
477 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
499 get :index, :project_id => 1, :query_id => 9, :format => 'pdf'
478 assert_response :success
500 assert_response :success
479 assert_not_nil assigns(:issues)
501 assert_not_nil assigns(:issues)
480 assert_not_nil assigns(:issue_count_by_group)
502 assert_not_nil assigns(:issue_count_by_group)
481 assert_equal 'application/pdf', @response.content_type
503 assert_equal 'application/pdf', @response.content_type
482 end
504 end
483
505
484 def test_index_sort
506 def test_index_sort
485 get :index, :sort => 'tracker,id:desc'
507 get :index, :sort => 'tracker,id:desc'
486 assert_response :success
508 assert_response :success
487
509
488 sort_params = @request.session['issues_index_sort']
510 sort_params = @request.session['issues_index_sort']
489 assert sort_params.is_a?(String)
511 assert sort_params.is_a?(String)
490 assert_equal 'tracker,id:desc', sort_params
512 assert_equal 'tracker,id:desc', sort_params
491
513
492 issues = assigns(:issues)
514 issues = assigns(:issues)
493 assert_not_nil issues
515 assert_not_nil issues
494 assert !issues.empty?
516 assert !issues.empty?
495 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
517 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
496 end
518 end
497
519
498 def test_index_sort_by_field_not_included_in_columns
520 def test_index_sort_by_field_not_included_in_columns
499 Setting.issue_list_default_columns = %w(subject author)
521 Setting.issue_list_default_columns = %w(subject author)
500 get :index, :sort => 'tracker'
522 get :index, :sort => 'tracker'
501 end
523 end
502
524
503 def test_index_sort_by_assigned_to
525 def test_index_sort_by_assigned_to
504 get :index, :sort => 'assigned_to'
526 get :index, :sort => 'assigned_to'
505 assert_response :success
527 assert_response :success
506 assignees = assigns(:issues).collect(&:assigned_to).compact
528 assignees = assigns(:issues).collect(&:assigned_to).compact
507 assert_equal assignees.sort, assignees
529 assert_equal assignees.sort, assignees
508 end
530 end
509
531
510 def test_index_sort_by_assigned_to_desc
532 def test_index_sort_by_assigned_to_desc
511 get :index, :sort => 'assigned_to:desc'
533 get :index, :sort => 'assigned_to:desc'
512 assert_response :success
534 assert_response :success
513 assignees = assigns(:issues).collect(&:assigned_to).compact
535 assignees = assigns(:issues).collect(&:assigned_to).compact
514 assert_equal assignees.sort.reverse, assignees
536 assert_equal assignees.sort.reverse, assignees
515 end
537 end
516
538
517 def test_index_group_by_assigned_to
539 def test_index_group_by_assigned_to
518 get :index, :group_by => 'assigned_to', :sort => 'priority'
540 get :index, :group_by => 'assigned_to', :sort => 'priority'
519 assert_response :success
541 assert_response :success
520 end
542 end
521
543
522 def test_index_sort_by_author
544 def test_index_sort_by_author
523 get :index, :sort => 'author'
545 get :index, :sort => 'author'
524 assert_response :success
546 assert_response :success
525 authors = assigns(:issues).collect(&:author)
547 authors = assigns(:issues).collect(&:author)
526 assert_equal authors.sort, authors
548 assert_equal authors.sort, authors
527 end
549 end
528
550
529 def test_index_sort_by_author_desc
551 def test_index_sort_by_author_desc
530 get :index, :sort => 'author:desc'
552 get :index, :sort => 'author:desc'
531 assert_response :success
553 assert_response :success
532 authors = assigns(:issues).collect(&:author)
554 authors = assigns(:issues).collect(&:author)
533 assert_equal authors.sort.reverse, authors
555 assert_equal authors.sort.reverse, authors
534 end
556 end
535
557
536 def test_index_group_by_author
558 def test_index_group_by_author
537 get :index, :group_by => 'author', :sort => 'priority'
559 get :index, :group_by => 'author', :sort => 'priority'
538 assert_response :success
560 assert_response :success
539 end
561 end
540
562
541 def test_index_with_columns
563 def test_index_with_columns
542 columns = ['tracker', 'subject', 'assigned_to']
564 columns = ['tracker', 'subject', 'assigned_to']
543 get :index, :set_filter => 1, :c => columns
565 get :index, :set_filter => 1, :c => columns
544 assert_response :success
566 assert_response :success
545
567
546 # query should use specified columns
568 # query should use specified columns
547 query = assigns(:query)
569 query = assigns(:query)
548 assert_kind_of Query, query
570 assert_kind_of Query, query
549 assert_equal columns, query.column_names.map(&:to_s)
571 assert_equal columns, query.column_names.map(&:to_s)
550
572
551 # columns should be stored in session
573 # columns should be stored in session
552 assert_kind_of Hash, session[:query]
574 assert_kind_of Hash, session[:query]
553 assert_kind_of Array, session[:query][:column_names]
575 assert_kind_of Array, session[:query][:column_names]
554 assert_equal columns, session[:query][:column_names].map(&:to_s)
576 assert_equal columns, session[:query][:column_names].map(&:to_s)
555
577
556 # ensure only these columns are kept in the selected columns list
578 # ensure only these columns are kept in the selected columns list
557 assert_tag :tag => 'select', :attributes => { :id => 'selected_columns' },
579 assert_tag :tag => 'select', :attributes => { :id => 'selected_columns' },
558 :children => { :count => 3 }
580 :children => { :count => 3 }
559 assert_no_tag :tag => 'option', :attributes => { :value => 'project' },
581 assert_no_tag :tag => 'option', :attributes => { :value => 'project' },
560 :parent => { :tag => 'select', :attributes => { :id => "selected_columns" } }
582 :parent => { :tag => 'select', :attributes => { :id => "selected_columns" } }
561 end
583 end
562
584
563 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
585 def test_index_without_project_should_implicitly_add_project_column_to_default_columns
564 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
586 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
565 get :index, :set_filter => 1
587 get :index, :set_filter => 1
566
588
567 # query should use specified columns
589 # query should use specified columns
568 query = assigns(:query)
590 query = assigns(:query)
569 assert_kind_of Query, query
591 assert_kind_of Query, query
570 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
592 assert_equal [:project, :tracker, :subject, :assigned_to], query.columns.map(&:name)
571 end
593 end
572
594
573 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
595 def test_index_without_project_and_explicit_default_columns_should_not_add_project_column
574 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
596 Setting.issue_list_default_columns = ['tracker', 'subject', 'assigned_to']
575 columns = ['tracker', 'subject', 'assigned_to']
597 columns = ['tracker', 'subject', 'assigned_to']
576 get :index, :set_filter => 1, :c => columns
598 get :index, :set_filter => 1, :c => columns
577
599
578 # query should use specified columns
600 # query should use specified columns
579 query = assigns(:query)
601 query = assigns(:query)
580 assert_kind_of Query, query
602 assert_kind_of Query, query
581 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
603 assert_equal columns.map(&:to_sym), query.columns.map(&:name)
582 end
604 end
583
605
584 def test_index_with_custom_field_column
606 def test_index_with_custom_field_column
585 columns = %w(tracker subject cf_2)
607 columns = %w(tracker subject cf_2)
586 get :index, :set_filter => 1, :c => columns
608 get :index, :set_filter => 1, :c => columns
587 assert_response :success
609 assert_response :success
588
610
589 # query should use specified columns
611 # query should use specified columns
590 query = assigns(:query)
612 query = assigns(:query)
591 assert_kind_of Query, query
613 assert_kind_of Query, query
592 assert_equal columns, query.column_names.map(&:to_s)
614 assert_equal columns, query.column_names.map(&:to_s)
593
615
594 assert_tag :td,
616 assert_tag :td,
595 :attributes => {:class => 'cf_2 string'},
617 :attributes => {:class => 'cf_2 string'},
596 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
618 :ancestor => {:tag => 'table', :attributes => {:class => /issues/}}
597 end
619 end
598
620
599 def test_index_with_date_column
621 def test_index_with_date_column
600 Issue.find(1).update_attribute :start_date, '1987-08-24'
622 Issue.find(1).update_attribute :start_date, '1987-08-24'
601
623
602 with_settings :date_format => '%d/%m/%Y' do
624 with_settings :date_format => '%d/%m/%Y' do
603 get :index, :set_filter => 1, :c => %w(start_date)
625 get :index, :set_filter => 1, :c => %w(start_date)
604 assert_tag 'td', :attributes => {:class => /start_date/}, :content => '24/08/1987'
626 assert_tag 'td', :attributes => {:class => /start_date/}, :content => '24/08/1987'
605 end
627 end
606 end
628 end
607
629
608 def test_index_with_done_ratio
630 def test_index_with_done_ratio
609 Issue.find(1).update_attribute :done_ratio, 40
631 Issue.find(1).update_attribute :done_ratio, 40
610
632
611 get :index, :set_filter => 1, :c => %w(done_ratio)
633 get :index, :set_filter => 1, :c => %w(done_ratio)
612 assert_tag 'td', :attributes => {:class => /done_ratio/},
634 assert_tag 'td', :attributes => {:class => /done_ratio/},
613 :child => {:tag => 'table', :attributes => {:class => 'progress'},
635 :child => {:tag => 'table', :attributes => {:class => 'progress'},
614 :descendant => {:tag => 'td', :attributes => {:class => 'closed', :style => 'width: 40%;'}}
636 :descendant => {:tag => 'td', :attributes => {:class => 'closed', :style => 'width: 40%;'}}
615 }
637 }
616 end
638 end
617
639
618 def test_index_with_fixed_version
640 def test_index_with_fixed_version
619 get :index, :set_filter => 1, :c => %w(fixed_version)
641 get :index, :set_filter => 1, :c => %w(fixed_version)
620 assert_tag 'td', :attributes => {:class => /fixed_version/},
642 assert_tag 'td', :attributes => {:class => /fixed_version/},
621 :child => {:tag => 'a', :content => '1.0', :attributes => {:href => '/versions/2'}}
643 :child => {:tag => 'a', :content => '1.0', :attributes => {:href => '/versions/2'}}
622 end
644 end
623
645
624 def test_index_send_html_if_query_is_invalid
646 def test_index_send_html_if_query_is_invalid
625 get :index, :f => ['start_date'], :op => {:start_date => '='}
647 get :index, :f => ['start_date'], :op => {:start_date => '='}
626 assert_equal 'text/html', @response.content_type
648 assert_equal 'text/html', @response.content_type
627 assert_template 'index'
649 assert_template 'index'
628 end
650 end
629
651
630 def test_index_send_nothing_if_query_is_invalid
652 def test_index_send_nothing_if_query_is_invalid
631 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
653 get :index, :f => ['start_date'], :op => {:start_date => '='}, :format => 'csv'
632 assert_equal 'text/csv', @response.content_type
654 assert_equal 'text/csv', @response.content_type
633 assert @response.body.blank?
655 assert @response.body.blank?
634 end
656 end
635
657
636 def test_show_by_anonymous
658 def test_show_by_anonymous
637 get :show, :id => 1
659 get :show, :id => 1
638 assert_response :success
660 assert_response :success
639 assert_template 'show'
661 assert_template 'show'
640 assert_not_nil assigns(:issue)
662 assert_not_nil assigns(:issue)
641 assert_equal Issue.find(1), assigns(:issue)
663 assert_equal Issue.find(1), assigns(:issue)
642
664
643 # anonymous role is allowed to add a note
665 # anonymous role is allowed to add a note
644 assert_tag :tag => 'form',
666 assert_tag :tag => 'form',
645 :descendant => { :tag => 'fieldset',
667 :descendant => { :tag => 'fieldset',
646 :child => { :tag => 'legend',
668 :child => { :tag => 'legend',
647 :content => /Notes/ } }
669 :content => /Notes/ } }
648 assert_tag :tag => 'title',
670 assert_tag :tag => 'title',
649 :content => "Bug #1: Can't print recipes - eCookbook - Redmine"
671 :content => "Bug #1: Can't print recipes - eCookbook - Redmine"
650 end
672 end
651
673
652 def test_show_by_manager
674 def test_show_by_manager
653 @request.session[:user_id] = 2
675 @request.session[:user_id] = 2
654 get :show, :id => 1
676 get :show, :id => 1
655 assert_response :success
677 assert_response :success
656
678
657 assert_tag :tag => 'a',
679 assert_tag :tag => 'a',
658 :content => /Quote/
680 :content => /Quote/
659
681
660 assert_tag :tag => 'form',
682 assert_tag :tag => 'form',
661 :descendant => { :tag => 'fieldset',
683 :descendant => { :tag => 'fieldset',
662 :child => { :tag => 'legend',
684 :child => { :tag => 'legend',
663 :content => /Change properties/ } },
685 :content => /Change properties/ } },
664 :descendant => { :tag => 'fieldset',
686 :descendant => { :tag => 'fieldset',
665 :child => { :tag => 'legend',
687 :child => { :tag => 'legend',
666 :content => /Log time/ } },
688 :content => /Log time/ } },
667 :descendant => { :tag => 'fieldset',
689 :descendant => { :tag => 'fieldset',
668 :child => { :tag => 'legend',
690 :child => { :tag => 'legend',
669 :content => /Notes/ } }
691 :content => /Notes/ } }
670 end
692 end
671
693
672 def test_update_form_should_not_display_inactive_enumerations
694 def test_update_form_should_not_display_inactive_enumerations
673 @request.session[:user_id] = 2
695 @request.session[:user_id] = 2
674 get :show, :id => 1
696 get :show, :id => 1
675 assert_response :success
697 assert_response :success
676
698
677 assert ! IssuePriority.find(15).active?
699 assert ! IssuePriority.find(15).active?
678 assert_no_tag :option, :attributes => {:value => '15'},
700 assert_no_tag :option, :attributes => {:value => '15'},
679 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
701 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
680 end
702 end
681
703
682 def test_update_form_should_allow_attachment_upload
704 def test_update_form_should_allow_attachment_upload
683 @request.session[:user_id] = 2
705 @request.session[:user_id] = 2
684 get :show, :id => 1
706 get :show, :id => 1
685
707
686 assert_tag :tag => 'form',
708 assert_tag :tag => 'form',
687 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
709 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
688 :descendant => {
710 :descendant => {
689 :tag => 'input',
711 :tag => 'input',
690 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
712 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
691 }
713 }
692 end
714 end
693
715
694 def test_show_should_deny_anonymous_access_without_permission
716 def test_show_should_deny_anonymous_access_without_permission
695 Role.anonymous.remove_permission!(:view_issues)
717 Role.anonymous.remove_permission!(:view_issues)
696 get :show, :id => 1
718 get :show, :id => 1
697 assert_response :redirect
719 assert_response :redirect
698 end
720 end
699
721
700 def test_show_should_deny_anonymous_access_to_private_issue
722 def test_show_should_deny_anonymous_access_to_private_issue
701 Issue.update_all(["is_private = ?", true], "id = 1")
723 Issue.update_all(["is_private = ?", true], "id = 1")
702 get :show, :id => 1
724 get :show, :id => 1
703 assert_response :redirect
725 assert_response :redirect
704 end
726 end
705
727
706 def test_show_should_deny_non_member_access_without_permission
728 def test_show_should_deny_non_member_access_without_permission
707 Role.non_member.remove_permission!(:view_issues)
729 Role.non_member.remove_permission!(:view_issues)
708 @request.session[:user_id] = 9
730 @request.session[:user_id] = 9
709 get :show, :id => 1
731 get :show, :id => 1
710 assert_response 403
732 assert_response 403
711 end
733 end
712
734
713 def test_show_should_deny_non_member_access_to_private_issue
735 def test_show_should_deny_non_member_access_to_private_issue
714 Issue.update_all(["is_private = ?", true], "id = 1")
736 Issue.update_all(["is_private = ?", true], "id = 1")
715 @request.session[:user_id] = 9
737 @request.session[:user_id] = 9
716 get :show, :id => 1
738 get :show, :id => 1
717 assert_response 403
739 assert_response 403
718 end
740 end
719
741
720 def test_show_should_deny_member_access_without_permission
742 def test_show_should_deny_member_access_without_permission
721 Role.find(1).remove_permission!(:view_issues)
743 Role.find(1).remove_permission!(:view_issues)
722 @request.session[:user_id] = 2
744 @request.session[:user_id] = 2
723 get :show, :id => 1
745 get :show, :id => 1
724 assert_response 403
746 assert_response 403
725 end
747 end
726
748
727 def test_show_should_deny_member_access_to_private_issue_without_permission
749 def test_show_should_deny_member_access_to_private_issue_without_permission
728 Issue.update_all(["is_private = ?", true], "id = 1")
750 Issue.update_all(["is_private = ?", true], "id = 1")
729 @request.session[:user_id] = 3
751 @request.session[:user_id] = 3
730 get :show, :id => 1
752 get :show, :id => 1
731 assert_response 403
753 assert_response 403
732 end
754 end
733
755
734 def test_show_should_allow_author_access_to_private_issue
756 def test_show_should_allow_author_access_to_private_issue
735 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
757 Issue.update_all(["is_private = ?, author_id = 3", true], "id = 1")
736 @request.session[:user_id] = 3
758 @request.session[:user_id] = 3
737 get :show, :id => 1
759 get :show, :id => 1
738 assert_response :success
760 assert_response :success
739 end
761 end
740
762
741 def test_show_should_allow_assignee_access_to_private_issue
763 def test_show_should_allow_assignee_access_to_private_issue
742 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
764 Issue.update_all(["is_private = ?, assigned_to_id = 3", true], "id = 1")
743 @request.session[:user_id] = 3
765 @request.session[:user_id] = 3
744 get :show, :id => 1
766 get :show, :id => 1
745 assert_response :success
767 assert_response :success
746 end
768 end
747
769
748 def test_show_should_allow_member_access_to_private_issue_with_permission
770 def test_show_should_allow_member_access_to_private_issue_with_permission
749 Issue.update_all(["is_private = ?", true], "id = 1")
771 Issue.update_all(["is_private = ?", true], "id = 1")
750 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
772 User.find(3).roles_for_project(Project.find(1)).first.update_attribute :issues_visibility, 'all'
751 @request.session[:user_id] = 3
773 @request.session[:user_id] = 3
752 get :show, :id => 1
774 get :show, :id => 1
753 assert_response :success
775 assert_response :success
754 end
776 end
755
777
756 def test_show_should_not_disclose_relations_to_invisible_issues
778 def test_show_should_not_disclose_relations_to_invisible_issues
757 Setting.cross_project_issue_relations = '1'
779 Setting.cross_project_issue_relations = '1'
758 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
780 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
759 # Relation to a private project issue
781 # Relation to a private project issue
760 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
782 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
761
783
762 get :show, :id => 1
784 get :show, :id => 1
763 assert_response :success
785 assert_response :success
764
786
765 assert_tag :div, :attributes => { :id => 'relations' },
787 assert_tag :div, :attributes => { :id => 'relations' },
766 :descendant => { :tag => 'a', :content => /#2$/ }
788 :descendant => { :tag => 'a', :content => /#2$/ }
767 assert_no_tag :div, :attributes => { :id => 'relations' },
789 assert_no_tag :div, :attributes => { :id => 'relations' },
768 :descendant => { :tag => 'a', :content => /#4$/ }
790 :descendant => { :tag => 'a', :content => /#4$/ }
769 end
791 end
770
792
771 def test_show_atom
793 def test_show_atom
772 get :show, :id => 2, :format => 'atom'
794 get :show, :id => 2, :format => 'atom'
773 assert_response :success
795 assert_response :success
774 assert_template 'journals/index'
796 assert_template 'journals/index'
775 # Inline image
797 # Inline image
776 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
798 assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10'))
777 end
799 end
778
800
779 def test_show_export_to_pdf
801 def test_show_export_to_pdf
780 get :show, :id => 3, :format => 'pdf'
802 get :show, :id => 3, :format => 'pdf'
781 assert_response :success
803 assert_response :success
782 assert_equal 'application/pdf', @response.content_type
804 assert_equal 'application/pdf', @response.content_type
783 assert @response.body.starts_with?('%PDF')
805 assert @response.body.starts_with?('%PDF')
784 assert_not_nil assigns(:issue)
806 assert_not_nil assigns(:issue)
785 end
807 end
786
808
787 def test_get_new
809 def test_get_new
788 @request.session[:user_id] = 2
810 @request.session[:user_id] = 2
789 get :new, :project_id => 1, :tracker_id => 1
811 get :new, :project_id => 1, :tracker_id => 1
790 assert_response :success
812 assert_response :success
791 assert_template 'new'
813 assert_template 'new'
792
814
793 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
815 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
794 :value => 'Default string' }
816 :value => 'Default string' }
795
817
796 # Be sure we don't display inactive IssuePriorities
818 # Be sure we don't display inactive IssuePriorities
797 assert ! IssuePriority.find(15).active?
819 assert ! IssuePriority.find(15).active?
798 assert_no_tag :option, :attributes => {:value => '15'},
820 assert_no_tag :option, :attributes => {:value => '15'},
799 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
821 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
800 end
822 end
801
823
802 def test_get_new_without_default_start_date_is_creation_date
824 def test_get_new_without_default_start_date_is_creation_date
803 Setting.default_issue_start_date_to_creation_date = 0
825 Setting.default_issue_start_date_to_creation_date = 0
804
826
805 @request.session[:user_id] = 2
827 @request.session[:user_id] = 2
806 get :new, :project_id => 1, :tracker_id => 1
828 get :new, :project_id => 1, :tracker_id => 1
807 assert_response :success
829 assert_response :success
808 assert_template 'new'
830 assert_template 'new'
809
831
810 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
832 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
811 :value => nil }
833 :value => nil }
812 end
834 end
813
835
814 def test_get_new_with_default_start_date_is_creation_date
836 def test_get_new_with_default_start_date_is_creation_date
815 Setting.default_issue_start_date_to_creation_date = 1
837 Setting.default_issue_start_date_to_creation_date = 1
816
838
817 @request.session[:user_id] = 2
839 @request.session[:user_id] = 2
818 get :new, :project_id => 1, :tracker_id => 1
840 get :new, :project_id => 1, :tracker_id => 1
819 assert_response :success
841 assert_response :success
820 assert_template 'new'
842 assert_template 'new'
821
843
822 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
844 assert_tag :tag => 'input', :attributes => { :name => 'issue[start_date]',
823 :value => Date.today.to_s }
845 :value => Date.today.to_s }
824 end
846 end
825
847
826 def test_get_new_form_should_allow_attachment_upload
848 def test_get_new_form_should_allow_attachment_upload
827 @request.session[:user_id] = 2
849 @request.session[:user_id] = 2
828 get :new, :project_id => 1, :tracker_id => 1
850 get :new, :project_id => 1, :tracker_id => 1
829
851
830 assert_tag :tag => 'form',
852 assert_tag :tag => 'form',
831 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
853 :attributes => {:id => 'issue-form', :method => 'post', :enctype => 'multipart/form-data'},
832 :descendant => {
854 :descendant => {
833 :tag => 'input',
855 :tag => 'input',
834 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
856 :attributes => {:type => 'file', :name => 'attachments[1][file]'}
835 }
857 }
836 end
858 end
837
859
838 def test_get_new_without_tracker_id
860 def test_get_new_without_tracker_id
839 @request.session[:user_id] = 2
861 @request.session[:user_id] = 2
840 get :new, :project_id => 1
862 get :new, :project_id => 1
841 assert_response :success
863 assert_response :success
842 assert_template 'new'
864 assert_template 'new'
843
865
844 issue = assigns(:issue)
866 issue = assigns(:issue)
845 assert_not_nil issue
867 assert_not_nil issue
846 assert_equal Project.find(1).trackers.first, issue.tracker
868 assert_equal Project.find(1).trackers.first, issue.tracker
847 end
869 end
848
870
849 def test_get_new_with_no_default_status_should_display_an_error
871 def test_get_new_with_no_default_status_should_display_an_error
850 @request.session[:user_id] = 2
872 @request.session[:user_id] = 2
851 IssueStatus.delete_all
873 IssueStatus.delete_all
852
874
853 get :new, :project_id => 1
875 get :new, :project_id => 1
854 assert_response 500
876 assert_response 500
855 assert_error_tag :content => /No default issue/
877 assert_error_tag :content => /No default issue/
856 end
878 end
857
879
858 def test_get_new_with_no_tracker_should_display_an_error
880 def test_get_new_with_no_tracker_should_display_an_error
859 @request.session[:user_id] = 2
881 @request.session[:user_id] = 2
860 Tracker.delete_all
882 Tracker.delete_all
861
883
862 get :new, :project_id => 1
884 get :new, :project_id => 1
863 assert_response 500
885 assert_response 500
864 assert_error_tag :content => /No tracker/
886 assert_error_tag :content => /No tracker/
865 end
887 end
866
888
867 def test_update_new_form
889 def test_update_new_form
868 @request.session[:user_id] = 2
890 @request.session[:user_id] = 2
869 xhr :post, :new, :project_id => 1,
891 xhr :post, :new, :project_id => 1,
870 :issue => {:tracker_id => 2,
892 :issue => {:tracker_id => 2,
871 :subject => 'This is the test_new issue',
893 :subject => 'This is the test_new issue',
872 :description => 'This is the description',
894 :description => 'This is the description',
873 :priority_id => 5}
895 :priority_id => 5}
874 assert_response :success
896 assert_response :success
875 assert_template 'attributes'
897 assert_template 'attributes'
876
898
877 issue = assigns(:issue)
899 issue = assigns(:issue)
878 assert_kind_of Issue, issue
900 assert_kind_of Issue, issue
879 assert_equal 1, issue.project_id
901 assert_equal 1, issue.project_id
880 assert_equal 2, issue.tracker_id
902 assert_equal 2, issue.tracker_id
881 assert_equal 'This is the test_new issue', issue.subject
903 assert_equal 'This is the test_new issue', issue.subject
882 end
904 end
883
905
884 def test_post_create
906 def test_post_create
885 @request.session[:user_id] = 2
907 @request.session[:user_id] = 2
886 assert_difference 'Issue.count' do
908 assert_difference 'Issue.count' do
887 post :create, :project_id => 1,
909 post :create, :project_id => 1,
888 :issue => {:tracker_id => 3,
910 :issue => {:tracker_id => 3,
889 :status_id => 2,
911 :status_id => 2,
890 :subject => 'This is the test_new issue',
912 :subject => 'This is the test_new issue',
891 :description => 'This is the description',
913 :description => 'This is the description',
892 :priority_id => 5,
914 :priority_id => 5,
893 :start_date => '2010-11-07',
915 :start_date => '2010-11-07',
894 :estimated_hours => '',
916 :estimated_hours => '',
895 :custom_field_values => {'2' => 'Value for field 2'}}
917 :custom_field_values => {'2' => 'Value for field 2'}}
896 end
918 end
897 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
919 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
898
920
899 issue = Issue.find_by_subject('This is the test_new issue')
921 issue = Issue.find_by_subject('This is the test_new issue')
900 assert_not_nil issue
922 assert_not_nil issue
901 assert_equal 2, issue.author_id
923 assert_equal 2, issue.author_id
902 assert_equal 3, issue.tracker_id
924 assert_equal 3, issue.tracker_id
903 assert_equal 2, issue.status_id
925 assert_equal 2, issue.status_id
904 assert_equal Date.parse('2010-11-07'), issue.start_date
926 assert_equal Date.parse('2010-11-07'), issue.start_date
905 assert_nil issue.estimated_hours
927 assert_nil issue.estimated_hours
906 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
928 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
907 assert_not_nil v
929 assert_not_nil v
908 assert_equal 'Value for field 2', v.value
930 assert_equal 'Value for field 2', v.value
909 end
931 end
910
932
911 def test_post_new_with_group_assignment
933 def test_post_new_with_group_assignment
912 group = Group.find(11)
934 group = Group.find(11)
913 project = Project.find(1)
935 project = Project.find(1)
914 project.members << Member.new(:principal => group, :roles => [Role.first])
936 project.members << Member.new(:principal => group, :roles => [Role.first])
915
937
916 with_settings :issue_group_assignment => '1' do
938 with_settings :issue_group_assignment => '1' do
917 @request.session[:user_id] = 2
939 @request.session[:user_id] = 2
918 assert_difference 'Issue.count' do
940 assert_difference 'Issue.count' do
919 post :create, :project_id => project.id,
941 post :create, :project_id => project.id,
920 :issue => {:tracker_id => 3,
942 :issue => {:tracker_id => 3,
921 :status_id => 1,
943 :status_id => 1,
922 :subject => 'This is the test_new_with_group_assignment issue',
944 :subject => 'This is the test_new_with_group_assignment issue',
923 :assigned_to_id => group.id}
945 :assigned_to_id => group.id}
924 end
946 end
925 end
947 end
926 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
948 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
927
949
928 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
950 issue = Issue.find_by_subject('This is the test_new_with_group_assignment issue')
929 assert_not_nil issue
951 assert_not_nil issue
930 assert_equal group, issue.assigned_to
952 assert_equal group, issue.assigned_to
931 end
953 end
932
954
933 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
955 def test_post_create_without_start_date_and_default_start_date_is_not_creation_date
934 Setting.default_issue_start_date_to_creation_date = 0
956 Setting.default_issue_start_date_to_creation_date = 0
935
957
936 @request.session[:user_id] = 2
958 @request.session[:user_id] = 2
937 assert_difference 'Issue.count' do
959 assert_difference 'Issue.count' do
938 post :create, :project_id => 1,
960 post :create, :project_id => 1,
939 :issue => {:tracker_id => 3,
961 :issue => {:tracker_id => 3,
940 :status_id => 2,
962 :status_id => 2,
941 :subject => 'This is the test_new issue',
963 :subject => 'This is the test_new issue',
942 :description => 'This is the description',
964 :description => 'This is the description',
943 :priority_id => 5,
965 :priority_id => 5,
944 :estimated_hours => '',
966 :estimated_hours => '',
945 :custom_field_values => {'2' => 'Value for field 2'}}
967 :custom_field_values => {'2' => 'Value for field 2'}}
946 end
968 end
947 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
969 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
948
970
949 issue = Issue.find_by_subject('This is the test_new issue')
971 issue = Issue.find_by_subject('This is the test_new issue')
950 assert_not_nil issue
972 assert_not_nil issue
951 assert_nil issue.start_date
973 assert_nil issue.start_date
952 end
974 end
953
975
954 def test_post_create_without_start_date_and_default_start_date_is_creation_date
976 def test_post_create_without_start_date_and_default_start_date_is_creation_date
955 Setting.default_issue_start_date_to_creation_date = 1
977 Setting.default_issue_start_date_to_creation_date = 1
956
978
957 @request.session[:user_id] = 2
979 @request.session[:user_id] = 2
958 assert_difference 'Issue.count' do
980 assert_difference 'Issue.count' do
959 post :create, :project_id => 1,
981 post :create, :project_id => 1,
960 :issue => {:tracker_id => 3,
982 :issue => {:tracker_id => 3,
961 :status_id => 2,
983 :status_id => 2,
962 :subject => 'This is the test_new issue',
984 :subject => 'This is the test_new issue',
963 :description => 'This is the description',
985 :description => 'This is the description',
964 :priority_id => 5,
986 :priority_id => 5,
965 :estimated_hours => '',
987 :estimated_hours => '',
966 :custom_field_values => {'2' => 'Value for field 2'}}
988 :custom_field_values => {'2' => 'Value for field 2'}}
967 end
989 end
968 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
990 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
969
991
970 issue = Issue.find_by_subject('This is the test_new issue')
992 issue = Issue.find_by_subject('This is the test_new issue')
971 assert_not_nil issue
993 assert_not_nil issue
972 assert_equal Date.today, issue.start_date
994 assert_equal Date.today, issue.start_date
973 end
995 end
974
996
975 def test_post_create_and_continue
997 def test_post_create_and_continue
976 @request.session[:user_id] = 2
998 @request.session[:user_id] = 2
977 assert_difference 'Issue.count' do
999 assert_difference 'Issue.count' do
978 post :create, :project_id => 1,
1000 post :create, :project_id => 1,
979 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
1001 :issue => {:tracker_id => 3, :subject => 'This is first issue', :priority_id => 5},
980 :continue => ''
1002 :continue => ''
981 end
1003 end
982
1004
983 issue = Issue.first(:order => 'id DESC')
1005 issue = Issue.first(:order => 'id DESC')
984 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
1006 assert_redirected_to :controller => 'issues', :action => 'new', :project_id => 'ecookbook', :issue => {:tracker_id => 3}
985 assert_not_nil flash[:notice], "flash was not set"
1007 assert_not_nil flash[:notice], "flash was not set"
986 assert flash[:notice].include?("<a href='/issues/#{issue.id}'>##{issue.id}</a>"), "issue link not found in flash: #{flash[:notice]}"
1008 assert flash[:notice].include?("<a href='/issues/#{issue.id}'>##{issue.id}</a>"), "issue link not found in flash: #{flash[:notice]}"
987 end
1009 end
988
1010
989 def test_post_create_without_custom_fields_param
1011 def test_post_create_without_custom_fields_param
990 @request.session[:user_id] = 2
1012 @request.session[:user_id] = 2
991 assert_difference 'Issue.count' do
1013 assert_difference 'Issue.count' do
992 post :create, :project_id => 1,
1014 post :create, :project_id => 1,
993 :issue => {:tracker_id => 1,
1015 :issue => {:tracker_id => 1,
994 :subject => 'This is the test_new issue',
1016 :subject => 'This is the test_new issue',
995 :description => 'This is the description',
1017 :description => 'This is the description',
996 :priority_id => 5}
1018 :priority_id => 5}
997 end
1019 end
998 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1020 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
999 end
1021 end
1000
1022
1001 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1023 def test_post_create_with_required_custom_field_and_without_custom_fields_param
1002 field = IssueCustomField.find_by_name('Database')
1024 field = IssueCustomField.find_by_name('Database')
1003 field.update_attribute(:is_required, true)
1025 field.update_attribute(:is_required, true)
1004
1026
1005 @request.session[:user_id] = 2
1027 @request.session[:user_id] = 2
1006 post :create, :project_id => 1,
1028 post :create, :project_id => 1,
1007 :issue => {:tracker_id => 1,
1029 :issue => {:tracker_id => 1,
1008 :subject => 'This is the test_new issue',
1030 :subject => 'This is the test_new issue',
1009 :description => 'This is the description',
1031 :description => 'This is the description',
1010 :priority_id => 5}
1032 :priority_id => 5}
1011 assert_response :success
1033 assert_response :success
1012 assert_template 'new'
1034 assert_template 'new'
1013 issue = assigns(:issue)
1035 issue = assigns(:issue)
1014 assert_not_nil issue
1036 assert_not_nil issue
1015 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
1037 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
1016 end
1038 end
1017
1039
1018 def test_post_create_with_watchers
1040 def test_post_create_with_watchers
1019 @request.session[:user_id] = 2
1041 @request.session[:user_id] = 2
1020 ActionMailer::Base.deliveries.clear
1042 ActionMailer::Base.deliveries.clear
1021
1043
1022 assert_difference 'Watcher.count', 2 do
1044 assert_difference 'Watcher.count', 2 do
1023 post :create, :project_id => 1,
1045 post :create, :project_id => 1,
1024 :issue => {:tracker_id => 1,
1046 :issue => {:tracker_id => 1,
1025 :subject => 'This is a new issue with watchers',
1047 :subject => 'This is a new issue with watchers',
1026 :description => 'This is the description',
1048 :description => 'This is the description',
1027 :priority_id => 5,
1049 :priority_id => 5,
1028 :watcher_user_ids => ['2', '3']}
1050 :watcher_user_ids => ['2', '3']}
1029 end
1051 end
1030 issue = Issue.find_by_subject('This is a new issue with watchers')
1052 issue = Issue.find_by_subject('This is a new issue with watchers')
1031 assert_not_nil issue
1053 assert_not_nil issue
1032 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1054 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
1033
1055
1034 # Watchers added
1056 # Watchers added
1035 assert_equal [2, 3], issue.watcher_user_ids.sort
1057 assert_equal [2, 3], issue.watcher_user_ids.sort
1036 assert issue.watched_by?(User.find(3))
1058 assert issue.watched_by?(User.find(3))
1037 # Watchers notified
1059 # Watchers notified
1038 mail = ActionMailer::Base.deliveries.last
1060 mail = ActionMailer::Base.deliveries.last
1039 assert_kind_of TMail::Mail, mail
1061 assert_kind_of TMail::Mail, mail
1040 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1062 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
1041 end
1063 end
1042
1064
1043 def test_post_create_subissue
1065 def test_post_create_subissue
1044 @request.session[:user_id] = 2
1066 @request.session[:user_id] = 2
1045
1067
1046 assert_difference 'Issue.count' do
1068 assert_difference 'Issue.count' do
1047 post :create, :project_id => 1,
1069 post :create, :project_id => 1,
1048 :issue => {:tracker_id => 1,
1070 :issue => {:tracker_id => 1,
1049 :subject => 'This is a child issue',
1071 :subject => 'This is a child issue',
1050 :parent_issue_id => 2}
1072 :parent_issue_id => 2}
1051 end
1073 end
1052 issue = Issue.find_by_subject('This is a child issue')
1074 issue = Issue.find_by_subject('This is a child issue')
1053 assert_not_nil issue
1075 assert_not_nil issue
1054 assert_equal Issue.find(2), issue.parent
1076 assert_equal Issue.find(2), issue.parent
1055 end
1077 end
1056
1078
1057 def test_post_create_subissue_with_non_numeric_parent_id
1079 def test_post_create_subissue_with_non_numeric_parent_id
1058 @request.session[:user_id] = 2
1080 @request.session[:user_id] = 2
1059
1081
1060 assert_difference 'Issue.count' do
1082 assert_difference 'Issue.count' do
1061 post :create, :project_id => 1,
1083 post :create, :project_id => 1,
1062 :issue => {:tracker_id => 1,
1084 :issue => {:tracker_id => 1,
1063 :subject => 'This is a child issue',
1085 :subject => 'This is a child issue',
1064 :parent_issue_id => 'ABC'}
1086 :parent_issue_id => 'ABC'}
1065 end
1087 end
1066 issue = Issue.find_by_subject('This is a child issue')
1088 issue = Issue.find_by_subject('This is a child issue')
1067 assert_not_nil issue
1089 assert_not_nil issue
1068 assert_nil issue.parent
1090 assert_nil issue.parent
1069 end
1091 end
1070
1092
1071 def test_post_create_private
1093 def test_post_create_private
1072 @request.session[:user_id] = 2
1094 @request.session[:user_id] = 2
1073
1095
1074 assert_difference 'Issue.count' do
1096 assert_difference 'Issue.count' do
1075 post :create, :project_id => 1,
1097 post :create, :project_id => 1,
1076 :issue => {:tracker_id => 1,
1098 :issue => {:tracker_id => 1,
1077 :subject => 'This is a private issue',
1099 :subject => 'This is a private issue',
1078 :is_private => '1'}
1100 :is_private => '1'}
1079 end
1101 end
1080 issue = Issue.first(:order => 'id DESC')
1102 issue = Issue.first(:order => 'id DESC')
1081 assert issue.is_private?
1103 assert issue.is_private?
1082 end
1104 end
1083
1105
1084 def test_post_create_private_with_set_own_issues_private_permission
1106 def test_post_create_private_with_set_own_issues_private_permission
1085 role = Role.find(1)
1107 role = Role.find(1)
1086 role.remove_permission! :set_issues_private
1108 role.remove_permission! :set_issues_private
1087 role.add_permission! :set_own_issues_private
1109 role.add_permission! :set_own_issues_private
1088
1110
1089 @request.session[:user_id] = 2
1111 @request.session[:user_id] = 2
1090
1112
1091 assert_difference 'Issue.count' do
1113 assert_difference 'Issue.count' do
1092 post :create, :project_id => 1,
1114 post :create, :project_id => 1,
1093 :issue => {:tracker_id => 1,
1115 :issue => {:tracker_id => 1,
1094 :subject => 'This is a private issue',
1116 :subject => 'This is a private issue',
1095 :is_private => '1'}
1117 :is_private => '1'}
1096 end
1118 end
1097 issue = Issue.first(:order => 'id DESC')
1119 issue = Issue.first(:order => 'id DESC')
1098 assert issue.is_private?
1120 assert issue.is_private?
1099 end
1121 end
1100
1122
1101 def test_post_create_should_send_a_notification
1123 def test_post_create_should_send_a_notification
1102 ActionMailer::Base.deliveries.clear
1124 ActionMailer::Base.deliveries.clear
1103 @request.session[:user_id] = 2
1125 @request.session[:user_id] = 2
1104 assert_difference 'Issue.count' do
1126 assert_difference 'Issue.count' do
1105 post :create, :project_id => 1,
1127 post :create, :project_id => 1,
1106 :issue => {:tracker_id => 3,
1128 :issue => {:tracker_id => 3,
1107 :subject => 'This is the test_new issue',
1129 :subject => 'This is the test_new issue',
1108 :description => 'This is the description',
1130 :description => 'This is the description',
1109 :priority_id => 5,
1131 :priority_id => 5,
1110 :estimated_hours => '',
1132 :estimated_hours => '',
1111 :custom_field_values => {'2' => 'Value for field 2'}}
1133 :custom_field_values => {'2' => 'Value for field 2'}}
1112 end
1134 end
1113 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1135 assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
1114
1136
1115 assert_equal 1, ActionMailer::Base.deliveries.size
1137 assert_equal 1, ActionMailer::Base.deliveries.size
1116 end
1138 end
1117
1139
1118 def test_post_create_should_preserve_fields_values_on_validation_failure
1140 def test_post_create_should_preserve_fields_values_on_validation_failure
1119 @request.session[:user_id] = 2
1141 @request.session[:user_id] = 2
1120 post :create, :project_id => 1,
1142 post :create, :project_id => 1,
1121 :issue => {:tracker_id => 1,
1143 :issue => {:tracker_id => 1,
1122 # empty subject
1144 # empty subject
1123 :subject => '',
1145 :subject => '',
1124 :description => 'This is a description',
1146 :description => 'This is a description',
1125 :priority_id => 6,
1147 :priority_id => 6,
1126 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
1148 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
1127 assert_response :success
1149 assert_response :success
1128 assert_template 'new'
1150 assert_template 'new'
1129
1151
1130 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
1152 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
1131 :content => 'This is a description'
1153 :content => 'This is a description'
1132 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1154 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1133 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1155 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1134 :value => '6' },
1156 :value => '6' },
1135 :content => 'High' }
1157 :content => 'High' }
1136 # Custom fields
1158 # Custom fields
1137 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
1159 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
1138 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1160 :child => { :tag => 'option', :attributes => { :selected => 'selected',
1139 :value => 'Oracle' },
1161 :value => 'Oracle' },
1140 :content => 'Oracle' }
1162 :content => 'Oracle' }
1141 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
1163 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
1142 :value => 'Value for field 2'}
1164 :value => 'Value for field 2'}
1143 end
1165 end
1144
1166
1145 def test_post_create_should_ignore_non_safe_attributes
1167 def test_post_create_should_ignore_non_safe_attributes
1146 @request.session[:user_id] = 2
1168 @request.session[:user_id] = 2
1147 assert_nothing_raised do
1169 assert_nothing_raised do
1148 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
1170 post :create, :project_id => 1, :issue => { :tracker => "A param can not be a Tracker" }
1149 end
1171 end
1150 end
1172 end
1151
1173
1152 def test_post_create_with_attachment
1174 def test_post_create_with_attachment
1153 set_tmp_attachments_directory
1175 set_tmp_attachments_directory
1154 @request.session[:user_id] = 2
1176 @request.session[:user_id] = 2
1155
1177
1156 assert_difference 'Issue.count' do
1178 assert_difference 'Issue.count' do
1157 assert_difference 'Attachment.count' do
1179 assert_difference 'Attachment.count' do
1158 post :create, :project_id => 1,
1180 post :create, :project_id => 1,
1159 :issue => { :tracker_id => '1', :subject => 'With attachment' },
1181 :issue => { :tracker_id => '1', :subject => 'With attachment' },
1160 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1182 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1161 end
1183 end
1162 end
1184 end
1163
1185
1164 issue = Issue.first(:order => 'id DESC')
1186 issue = Issue.first(:order => 'id DESC')
1165 attachment = Attachment.first(:order => 'id DESC')
1187 attachment = Attachment.first(:order => 'id DESC')
1166
1188
1167 assert_equal issue, attachment.container
1189 assert_equal issue, attachment.container
1168 assert_equal 2, attachment.author_id
1190 assert_equal 2, attachment.author_id
1169 assert_equal 'testfile.txt', attachment.filename
1191 assert_equal 'testfile.txt', attachment.filename
1170 assert_equal 'text/plain', attachment.content_type
1192 assert_equal 'text/plain', attachment.content_type
1171 assert_equal 'test file', attachment.description
1193 assert_equal 'test file', attachment.description
1172 assert_equal 59, attachment.filesize
1194 assert_equal 59, attachment.filesize
1173 assert File.exists?(attachment.diskfile)
1195 assert File.exists?(attachment.diskfile)
1174 assert_equal 59, File.size(attachment.diskfile)
1196 assert_equal 59, File.size(attachment.diskfile)
1175 end
1197 end
1176
1198
1177 context "without workflow privilege" do
1199 context "without workflow privilege" do
1178 setup do
1200 setup do
1179 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1201 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1180 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1202 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1181 end
1203 end
1182
1204
1183 context "#new" do
1205 context "#new" do
1184 should "propose default status only" do
1206 should "propose default status only" do
1185 get :new, :project_id => 1
1207 get :new, :project_id => 1
1186 assert_response :success
1208 assert_response :success
1187 assert_template 'new'
1209 assert_template 'new'
1188 assert_tag :tag => 'select',
1210 assert_tag :tag => 'select',
1189 :attributes => {:name => 'issue[status_id]'},
1211 :attributes => {:name => 'issue[status_id]'},
1190 :children => {:count => 1},
1212 :children => {:count => 1},
1191 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
1213 :child => {:tag => 'option', :attributes => {:value => IssueStatus.default.id.to_s}}
1192 end
1214 end
1193
1215
1194 should "accept default status" do
1216 should "accept default status" do
1195 assert_difference 'Issue.count' do
1217 assert_difference 'Issue.count' do
1196 post :create, :project_id => 1,
1218 post :create, :project_id => 1,
1197 :issue => {:tracker_id => 1,
1219 :issue => {:tracker_id => 1,
1198 :subject => 'This is an issue',
1220 :subject => 'This is an issue',
1199 :status_id => 1}
1221 :status_id => 1}
1200 end
1222 end
1201 issue = Issue.last(:order => 'id')
1223 issue = Issue.last(:order => 'id')
1202 assert_equal IssueStatus.default, issue.status
1224 assert_equal IssueStatus.default, issue.status
1203 end
1225 end
1204
1226
1205 should "ignore unauthorized status" do
1227 should "ignore unauthorized status" do
1206 assert_difference 'Issue.count' do
1228 assert_difference 'Issue.count' do
1207 post :create, :project_id => 1,
1229 post :create, :project_id => 1,
1208 :issue => {:tracker_id => 1,
1230 :issue => {:tracker_id => 1,
1209 :subject => 'This is an issue',
1231 :subject => 'This is an issue',
1210 :status_id => 3}
1232 :status_id => 3}
1211 end
1233 end
1212 issue = Issue.last(:order => 'id')
1234 issue = Issue.last(:order => 'id')
1213 assert_equal IssueStatus.default, issue.status
1235 assert_equal IssueStatus.default, issue.status
1214 end
1236 end
1215 end
1237 end
1216
1238
1217 context "#update" do
1239 context "#update" do
1218 should "ignore status change" do
1240 should "ignore status change" do
1219 assert_difference 'Journal.count' do
1241 assert_difference 'Journal.count' do
1220 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1242 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1221 end
1243 end
1222 assert_equal 1, Issue.find(1).status_id
1244 assert_equal 1, Issue.find(1).status_id
1223 end
1245 end
1224
1246
1225 should "ignore attributes changes" do
1247 should "ignore attributes changes" do
1226 assert_difference 'Journal.count' do
1248 assert_difference 'Journal.count' do
1227 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1249 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1228 end
1250 end
1229 issue = Issue.find(1)
1251 issue = Issue.find(1)
1230 assert_equal "Can't print recipes", issue.subject
1252 assert_equal "Can't print recipes", issue.subject
1231 assert_nil issue.assigned_to
1253 assert_nil issue.assigned_to
1232 end
1254 end
1233 end
1255 end
1234 end
1256 end
1235
1257
1236 context "with workflow privilege" do
1258 context "with workflow privilege" do
1237 setup do
1259 setup do
1238 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1260 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1239 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1261 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1240 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1262 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1241 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1263 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1242 end
1264 end
1243
1265
1244 context "#update" do
1266 context "#update" do
1245 should "accept authorized status" do
1267 should "accept authorized status" do
1246 assert_difference 'Journal.count' do
1268 assert_difference 'Journal.count' do
1247 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1269 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1248 end
1270 end
1249 assert_equal 3, Issue.find(1).status_id
1271 assert_equal 3, Issue.find(1).status_id
1250 end
1272 end
1251
1273
1252 should "ignore unauthorized status" do
1274 should "ignore unauthorized status" do
1253 assert_difference 'Journal.count' do
1275 assert_difference 'Journal.count' do
1254 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1276 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1255 end
1277 end
1256 assert_equal 1, Issue.find(1).status_id
1278 assert_equal 1, Issue.find(1).status_id
1257 end
1279 end
1258
1280
1259 should "accept authorized attributes changes" do
1281 should "accept authorized attributes changes" do
1260 assert_difference 'Journal.count' do
1282 assert_difference 'Journal.count' do
1261 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
1283 put :update, :id => 1, :notes => 'just trying', :issue => {:assigned_to_id => 2}
1262 end
1284 end
1263 issue = Issue.find(1)
1285 issue = Issue.find(1)
1264 assert_equal 2, issue.assigned_to_id
1286 assert_equal 2, issue.assigned_to_id
1265 end
1287 end
1266
1288
1267 should "ignore unauthorized attributes changes" do
1289 should "ignore unauthorized attributes changes" do
1268 assert_difference 'Journal.count' do
1290 assert_difference 'Journal.count' do
1269 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
1291 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed'}
1270 end
1292 end
1271 issue = Issue.find(1)
1293 issue = Issue.find(1)
1272 assert_equal "Can't print recipes", issue.subject
1294 assert_equal "Can't print recipes", issue.subject
1273 end
1295 end
1274 end
1296 end
1275
1297
1276 context "and :edit_issues permission" do
1298 context "and :edit_issues permission" do
1277 setup do
1299 setup do
1278 Role.anonymous.add_permission! :add_issues, :edit_issues
1300 Role.anonymous.add_permission! :add_issues, :edit_issues
1279 end
1301 end
1280
1302
1281 should "accept authorized status" do
1303 should "accept authorized status" do
1282 assert_difference 'Journal.count' do
1304 assert_difference 'Journal.count' do
1283 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1305 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 3}
1284 end
1306 end
1285 assert_equal 3, Issue.find(1).status_id
1307 assert_equal 3, Issue.find(1).status_id
1286 end
1308 end
1287
1309
1288 should "ignore unauthorized status" do
1310 should "ignore unauthorized status" do
1289 assert_difference 'Journal.count' do
1311 assert_difference 'Journal.count' do
1290 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1312 put :update, :id => 1, :notes => 'just trying', :issue => {:status_id => 2}
1291 end
1313 end
1292 assert_equal 1, Issue.find(1).status_id
1314 assert_equal 1, Issue.find(1).status_id
1293 end
1315 end
1294
1316
1295 should "accept authorized attributes changes" do
1317 should "accept authorized attributes changes" do
1296 assert_difference 'Journal.count' do
1318 assert_difference 'Journal.count' do
1297 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1319 put :update, :id => 1, :notes => 'just trying', :issue => {:subject => 'changed', :assigned_to_id => 2}
1298 end
1320 end
1299 issue = Issue.find(1)
1321 issue = Issue.find(1)
1300 assert_equal "changed", issue.subject
1322 assert_equal "changed", issue.subject
1301 assert_equal 2, issue.assigned_to_id
1323 assert_equal 2, issue.assigned_to_id
1302 end
1324 end
1303 end
1325 end
1304 end
1326 end
1305
1327
1306 def test_copy_issue
1328 def test_copy_issue
1307 @request.session[:user_id] = 2
1329 @request.session[:user_id] = 2
1308 get :new, :project_id => 1, :copy_from => 1
1330 get :new, :project_id => 1, :copy_from => 1
1309 assert_template 'new'
1331 assert_template 'new'
1310 assert_not_nil assigns(:issue)
1332 assert_not_nil assigns(:issue)
1311 orig = Issue.find(1)
1333 orig = Issue.find(1)
1312 assert_equal orig.subject, assigns(:issue).subject
1334 assert_equal orig.subject, assigns(:issue).subject
1313 end
1335 end
1314
1336
1315 def test_get_edit
1337 def test_get_edit
1316 @request.session[:user_id] = 2
1338 @request.session[:user_id] = 2
1317 get :edit, :id => 1
1339 get :edit, :id => 1
1318 assert_response :success
1340 assert_response :success
1319 assert_template 'edit'
1341 assert_template 'edit'
1320 assert_not_nil assigns(:issue)
1342 assert_not_nil assigns(:issue)
1321 assert_equal Issue.find(1), assigns(:issue)
1343 assert_equal Issue.find(1), assigns(:issue)
1322
1344
1323 # Be sure we don't display inactive IssuePriorities
1345 # Be sure we don't display inactive IssuePriorities
1324 assert ! IssuePriority.find(15).active?
1346 assert ! IssuePriority.find(15).active?
1325 assert_no_tag :option, :attributes => {:value => '15'},
1347 assert_no_tag :option, :attributes => {:value => '15'},
1326 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1348 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1327 end
1349 end
1328
1350
1329 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
1351 def test_get_edit_should_display_the_time_entry_form_with_log_time_permission
1330 @request.session[:user_id] = 2
1352 @request.session[:user_id] = 2
1331 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
1353 Role.find_by_name('Manager').update_attribute :permissions, [:view_issues, :edit_issues, :log_time]
1332
1354
1333 get :edit, :id => 1
1355 get :edit, :id => 1
1334 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
1356 assert_tag 'input', :attributes => {:name => 'time_entry[hours]'}
1335 end
1357 end
1336
1358
1337 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
1359 def test_get_edit_should_not_display_the_time_entry_form_without_log_time_permission
1338 @request.session[:user_id] = 2
1360 @request.session[:user_id] = 2
1339 Role.find_by_name('Manager').remove_permission! :log_time
1361 Role.find_by_name('Manager').remove_permission! :log_time
1340
1362
1341 get :edit, :id => 1
1363 get :edit, :id => 1
1342 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
1364 assert_no_tag 'input', :attributes => {:name => 'time_entry[hours]'}
1343 end
1365 end
1344
1366
1345 def test_get_edit_with_params
1367 def test_get_edit_with_params
1346 @request.session[:user_id] = 2
1368 @request.session[:user_id] = 2
1347 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
1369 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 },
1348 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
1370 :time_entry => { :hours => '2.5', :comments => 'test_get_edit_with_params', :activity_id => TimeEntryActivity.first.id }
1349 assert_response :success
1371 assert_response :success
1350 assert_template 'edit'
1372 assert_template 'edit'
1351
1373
1352 issue = assigns(:issue)
1374 issue = assigns(:issue)
1353 assert_not_nil issue
1375 assert_not_nil issue
1354
1376
1355 assert_equal 5, issue.status_id
1377 assert_equal 5, issue.status_id
1356 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
1378 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
1357 :child => { :tag => 'option',
1379 :child => { :tag => 'option',
1358 :content => 'Closed',
1380 :content => 'Closed',
1359 :attributes => { :selected => 'selected' } }
1381 :attributes => { :selected => 'selected' } }
1360
1382
1361 assert_equal 7, issue.priority_id
1383 assert_equal 7, issue.priority_id
1362 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1384 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
1363 :child => { :tag => 'option',
1385 :child => { :tag => 'option',
1364 :content => 'Urgent',
1386 :content => 'Urgent',
1365 :attributes => { :selected => 'selected' } }
1387 :attributes => { :selected => 'selected' } }
1366
1388
1367 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
1389 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => '2.5' }
1368 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
1390 assert_tag :select, :attributes => { :name => 'time_entry[activity_id]' },
1369 :child => { :tag => 'option',
1391 :child => { :tag => 'option',
1370 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
1392 :attributes => { :selected => 'selected', :value => TimeEntryActivity.first.id } }
1371 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
1393 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => 'test_get_edit_with_params' }
1372 end
1394 end
1373
1395
1374 def test_update_edit_form
1396 def test_update_edit_form
1375 @request.session[:user_id] = 2
1397 @request.session[:user_id] = 2
1376 xhr :post, :new, :project_id => 1,
1398 xhr :post, :new, :project_id => 1,
1377 :id => 1,
1399 :id => 1,
1378 :issue => {:tracker_id => 2,
1400 :issue => {:tracker_id => 2,
1379 :subject => 'This is the test_new issue',
1401 :subject => 'This is the test_new issue',
1380 :description => 'This is the description',
1402 :description => 'This is the description',
1381 :priority_id => 5}
1403 :priority_id => 5}
1382 assert_response :success
1404 assert_response :success
1383 assert_template 'attributes'
1405 assert_template 'attributes'
1384
1406
1385 issue = assigns(:issue)
1407 issue = assigns(:issue)
1386 assert_kind_of Issue, issue
1408 assert_kind_of Issue, issue
1387 assert_equal 1, issue.id
1409 assert_equal 1, issue.id
1388 assert_equal 1, issue.project_id
1410 assert_equal 1, issue.project_id
1389 assert_equal 2, issue.tracker_id
1411 assert_equal 2, issue.tracker_id
1390 assert_equal 'This is the test_new issue', issue.subject
1412 assert_equal 'This is the test_new issue', issue.subject
1391 end
1413 end
1392
1414
1393 def test_update_using_invalid_http_verbs
1415 def test_update_using_invalid_http_verbs
1394 @request.session[:user_id] = 2
1416 @request.session[:user_id] = 2
1395 subject = 'Updated by an invalid http verb'
1417 subject = 'Updated by an invalid http verb'
1396
1418
1397 get :update, :id => 1, :issue => {:subject => subject}
1419 get :update, :id => 1, :issue => {:subject => subject}
1398 assert_not_equal subject, Issue.find(1).subject
1420 assert_not_equal subject, Issue.find(1).subject
1399
1421
1400 post :update, :id => 1, :issue => {:subject => subject}
1422 post :update, :id => 1, :issue => {:subject => subject}
1401 assert_not_equal subject, Issue.find(1).subject
1423 assert_not_equal subject, Issue.find(1).subject
1402
1424
1403 delete :update, :id => 1, :issue => {:subject => subject}
1425 delete :update, :id => 1, :issue => {:subject => subject}
1404 assert_not_equal subject, Issue.find(1).subject
1426 assert_not_equal subject, Issue.find(1).subject
1405 end
1427 end
1406
1428
1407 def test_put_update_without_custom_fields_param
1429 def test_put_update_without_custom_fields_param
1408 @request.session[:user_id] = 2
1430 @request.session[:user_id] = 2
1409 ActionMailer::Base.deliveries.clear
1431 ActionMailer::Base.deliveries.clear
1410
1432
1411 issue = Issue.find(1)
1433 issue = Issue.find(1)
1412 assert_equal '125', issue.custom_value_for(2).value
1434 assert_equal '125', issue.custom_value_for(2).value
1413 old_subject = issue.subject
1435 old_subject = issue.subject
1414 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
1436 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
1415
1437
1416 assert_difference('Journal.count') do
1438 assert_difference('Journal.count') do
1417 assert_difference('JournalDetail.count', 2) do
1439 assert_difference('JournalDetail.count', 2) do
1418 put :update, :id => 1, :issue => {:subject => new_subject,
1440 put :update, :id => 1, :issue => {:subject => new_subject,
1419 :priority_id => '6',
1441 :priority_id => '6',
1420 :category_id => '1' # no change
1442 :category_id => '1' # no change
1421 }
1443 }
1422 end
1444 end
1423 end
1445 end
1424 assert_redirected_to :action => 'show', :id => '1'
1446 assert_redirected_to :action => 'show', :id => '1'
1425 issue.reload
1447 issue.reload
1426 assert_equal new_subject, issue.subject
1448 assert_equal new_subject, issue.subject
1427 # Make sure custom fields were not cleared
1449 # Make sure custom fields were not cleared
1428 assert_equal '125', issue.custom_value_for(2).value
1450 assert_equal '125', issue.custom_value_for(2).value
1429
1451
1430 mail = ActionMailer::Base.deliveries.last
1452 mail = ActionMailer::Base.deliveries.last
1431 assert_kind_of TMail::Mail, mail
1453 assert_kind_of TMail::Mail, mail
1432 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
1454 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
1433 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
1455 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
1434 end
1456 end
1435
1457
1436 def test_put_update_with_custom_field_change
1458 def test_put_update_with_custom_field_change
1437 @request.session[:user_id] = 2
1459 @request.session[:user_id] = 2
1438 issue = Issue.find(1)
1460 issue = Issue.find(1)
1439 assert_equal '125', issue.custom_value_for(2).value
1461 assert_equal '125', issue.custom_value_for(2).value
1440
1462
1441 assert_difference('Journal.count') do
1463 assert_difference('Journal.count') do
1442 assert_difference('JournalDetail.count', 3) do
1464 assert_difference('JournalDetail.count', 3) do
1443 put :update, :id => 1, :issue => {:subject => 'Custom field change',
1465 put :update, :id => 1, :issue => {:subject => 'Custom field change',
1444 :priority_id => '6',
1466 :priority_id => '6',
1445 :category_id => '1', # no change
1467 :category_id => '1', # no change
1446 :custom_field_values => { '2' => 'New custom value' }
1468 :custom_field_values => { '2' => 'New custom value' }
1447 }
1469 }
1448 end
1470 end
1449 end
1471 end
1450 assert_redirected_to :action => 'show', :id => '1'
1472 assert_redirected_to :action => 'show', :id => '1'
1451 issue.reload
1473 issue.reload
1452 assert_equal 'New custom value', issue.custom_value_for(2).value
1474 assert_equal 'New custom value', issue.custom_value_for(2).value
1453
1475
1454 mail = ActionMailer::Base.deliveries.last
1476 mail = ActionMailer::Base.deliveries.last
1455 assert_kind_of TMail::Mail, mail
1477 assert_kind_of TMail::Mail, mail
1456 assert mail.body.include?("Searchable field changed from 125 to New custom value")
1478 assert mail.body.include?("Searchable field changed from 125 to New custom value")
1457 end
1479 end
1458
1480
1459 def test_put_update_with_status_and_assignee_change
1481 def test_put_update_with_status_and_assignee_change
1460 issue = Issue.find(1)
1482 issue = Issue.find(1)
1461 assert_equal 1, issue.status_id
1483 assert_equal 1, issue.status_id
1462 @request.session[:user_id] = 2
1484 @request.session[:user_id] = 2
1463 assert_difference('TimeEntry.count', 0) do
1485 assert_difference('TimeEntry.count', 0) do
1464 put :update,
1486 put :update,
1465 :id => 1,
1487 :id => 1,
1466 :issue => { :status_id => 2, :assigned_to_id => 3 },
1488 :issue => { :status_id => 2, :assigned_to_id => 3 },
1467 :notes => 'Assigned to dlopper',
1489 :notes => 'Assigned to dlopper',
1468 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
1490 :time_entry => { :hours => '', :comments => '', :activity_id => TimeEntryActivity.first }
1469 end
1491 end
1470 assert_redirected_to :action => 'show', :id => '1'
1492 assert_redirected_to :action => 'show', :id => '1'
1471 issue.reload
1493 issue.reload
1472 assert_equal 2, issue.status_id
1494 assert_equal 2, issue.status_id
1473 j = Journal.find(:first, :order => 'id DESC')
1495 j = Journal.find(:first, :order => 'id DESC')
1474 assert_equal 'Assigned to dlopper', j.notes
1496 assert_equal 'Assigned to dlopper', j.notes
1475 assert_equal 2, j.details.size
1497 assert_equal 2, j.details.size
1476
1498
1477 mail = ActionMailer::Base.deliveries.last
1499 mail = ActionMailer::Base.deliveries.last
1478 assert mail.body.include?("Status changed from New to Assigned")
1500 assert mail.body.include?("Status changed from New to Assigned")
1479 # subject should contain the new status
1501 # subject should contain the new status
1480 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
1502 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
1481 end
1503 end
1482
1504
1483 def test_put_update_with_note_only
1505 def test_put_update_with_note_only
1484 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
1506 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
1485 # anonymous user
1507 # anonymous user
1486 put :update,
1508 put :update,
1487 :id => 1,
1509 :id => 1,
1488 :notes => notes
1510 :notes => notes
1489 assert_redirected_to :action => 'show', :id => '1'
1511 assert_redirected_to :action => 'show', :id => '1'
1490 j = Journal.find(:first, :order => 'id DESC')
1512 j = Journal.find(:first, :order => 'id DESC')
1491 assert_equal notes, j.notes
1513 assert_equal notes, j.notes
1492 assert_equal 0, j.details.size
1514 assert_equal 0, j.details.size
1493 assert_equal User.anonymous, j.user
1515 assert_equal User.anonymous, j.user
1494
1516
1495 mail = ActionMailer::Base.deliveries.last
1517 mail = ActionMailer::Base.deliveries.last
1496 assert mail.body.include?(notes)
1518 assert mail.body.include?(notes)
1497 end
1519 end
1498
1520
1499 def test_put_update_with_note_and_spent_time
1521 def test_put_update_with_note_and_spent_time
1500 @request.session[:user_id] = 2
1522 @request.session[:user_id] = 2
1501 spent_hours_before = Issue.find(1).spent_hours
1523 spent_hours_before = Issue.find(1).spent_hours
1502 assert_difference('TimeEntry.count') do
1524 assert_difference('TimeEntry.count') do
1503 put :update,
1525 put :update,
1504 :id => 1,
1526 :id => 1,
1505 :notes => '2.5 hours added',
1527 :notes => '2.5 hours added',
1506 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
1528 :time_entry => { :hours => '2.5', :comments => 'test_put_update_with_note_and_spent_time', :activity_id => TimeEntryActivity.first.id }
1507 end
1529 end
1508 assert_redirected_to :action => 'show', :id => '1'
1530 assert_redirected_to :action => 'show', :id => '1'
1509
1531
1510 issue = Issue.find(1)
1532 issue = Issue.find(1)
1511
1533
1512 j = Journal.find(:first, :order => 'id DESC')
1534 j = Journal.find(:first, :order => 'id DESC')
1513 assert_equal '2.5 hours added', j.notes
1535 assert_equal '2.5 hours added', j.notes
1514 assert_equal 0, j.details.size
1536 assert_equal 0, j.details.size
1515
1537
1516 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
1538 t = issue.time_entries.find_by_comments('test_put_update_with_note_and_spent_time')
1517 assert_not_nil t
1539 assert_not_nil t
1518 assert_equal 2.5, t.hours
1540 assert_equal 2.5, t.hours
1519 assert_equal spent_hours_before + 2.5, issue.spent_hours
1541 assert_equal spent_hours_before + 2.5, issue.spent_hours
1520 end
1542 end
1521
1543
1522 def test_put_update_with_attachment_only
1544 def test_put_update_with_attachment_only
1523 set_tmp_attachments_directory
1545 set_tmp_attachments_directory
1524
1546
1525 # Delete all fixtured journals, a race condition can occur causing the wrong
1547 # Delete all fixtured journals, a race condition can occur causing the wrong
1526 # journal to get fetched in the next find.
1548 # journal to get fetched in the next find.
1527 Journal.delete_all
1549 Journal.delete_all
1528
1550
1529 # anonymous user
1551 # anonymous user
1530 assert_difference 'Attachment.count' do
1552 assert_difference 'Attachment.count' do
1531 put :update, :id => 1,
1553 put :update, :id => 1,
1532 :notes => '',
1554 :notes => '',
1533 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1555 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}}
1534 end
1556 end
1535
1557
1536 assert_redirected_to :action => 'show', :id => '1'
1558 assert_redirected_to :action => 'show', :id => '1'
1537 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
1559 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
1538 assert j.notes.blank?
1560 assert j.notes.blank?
1539 assert_equal 1, j.details.size
1561 assert_equal 1, j.details.size
1540 assert_equal 'testfile.txt', j.details.first.value
1562 assert_equal 'testfile.txt', j.details.first.value
1541 assert_equal User.anonymous, j.user
1563 assert_equal User.anonymous, j.user
1542
1564
1543 attachment = Attachment.first(:order => 'id DESC')
1565 attachment = Attachment.first(:order => 'id DESC')
1544 assert_equal Issue.find(1), attachment.container
1566 assert_equal Issue.find(1), attachment.container
1545 assert_equal User.anonymous, attachment.author
1567 assert_equal User.anonymous, attachment.author
1546 assert_equal 'testfile.txt', attachment.filename
1568 assert_equal 'testfile.txt', attachment.filename
1547 assert_equal 'text/plain', attachment.content_type
1569 assert_equal 'text/plain', attachment.content_type
1548 assert_equal 'test file', attachment.description
1570 assert_equal 'test file', attachment.description
1549 assert_equal 59, attachment.filesize
1571 assert_equal 59, attachment.filesize
1550 assert File.exists?(attachment.diskfile)
1572 assert File.exists?(attachment.diskfile)
1551 assert_equal 59, File.size(attachment.diskfile)
1573 assert_equal 59, File.size(attachment.diskfile)
1552
1574
1553 mail = ActionMailer::Base.deliveries.last
1575 mail = ActionMailer::Base.deliveries.last
1554 assert mail.body.include?('testfile.txt')
1576 assert mail.body.include?('testfile.txt')
1555 end
1577 end
1556
1578
1557 def test_put_update_with_attachment_that_fails_to_save
1579 def test_put_update_with_attachment_that_fails_to_save
1558 set_tmp_attachments_directory
1580 set_tmp_attachments_directory
1559
1581
1560 # Delete all fixtured journals, a race condition can occur causing the wrong
1582 # Delete all fixtured journals, a race condition can occur causing the wrong
1561 # journal to get fetched in the next find.
1583 # journal to get fetched in the next find.
1562 Journal.delete_all
1584 Journal.delete_all
1563
1585
1564 # Mock out the unsaved attachment
1586 # Mock out the unsaved attachment
1565 Attachment.any_instance.stubs(:create).returns(Attachment.new)
1587 Attachment.any_instance.stubs(:create).returns(Attachment.new)
1566
1588
1567 # anonymous user
1589 # anonymous user
1568 put :update,
1590 put :update,
1569 :id => 1,
1591 :id => 1,
1570 :notes => '',
1592 :notes => '',
1571 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
1593 :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
1572 assert_redirected_to :action => 'show', :id => '1'
1594 assert_redirected_to :action => 'show', :id => '1'
1573 assert_equal '1 file(s) could not be saved.', flash[:warning]
1595 assert_equal '1 file(s) could not be saved.', flash[:warning]
1574
1596
1575 end if Object.const_defined?(:Mocha)
1597 end if Object.const_defined?(:Mocha)
1576
1598
1577 def test_put_update_with_no_change
1599 def test_put_update_with_no_change
1578 issue = Issue.find(1)
1600 issue = Issue.find(1)
1579 issue.journals.clear
1601 issue.journals.clear
1580 ActionMailer::Base.deliveries.clear
1602 ActionMailer::Base.deliveries.clear
1581
1603
1582 put :update,
1604 put :update,
1583 :id => 1,
1605 :id => 1,
1584 :notes => ''
1606 :notes => ''
1585 assert_redirected_to :action => 'show', :id => '1'
1607 assert_redirected_to :action => 'show', :id => '1'
1586
1608
1587 issue.reload
1609 issue.reload
1588 assert issue.journals.empty?
1610 assert issue.journals.empty?
1589 # No email should be sent
1611 # No email should be sent
1590 assert ActionMailer::Base.deliveries.empty?
1612 assert ActionMailer::Base.deliveries.empty?
1591 end
1613 end
1592
1614
1593 def test_put_update_should_send_a_notification
1615 def test_put_update_should_send_a_notification
1594 @request.session[:user_id] = 2
1616 @request.session[:user_id] = 2
1595 ActionMailer::Base.deliveries.clear
1617 ActionMailer::Base.deliveries.clear
1596 issue = Issue.find(1)
1618 issue = Issue.find(1)
1597 old_subject = issue.subject
1619 old_subject = issue.subject
1598 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
1620 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
1599
1621
1600 put :update, :id => 1, :issue => {:subject => new_subject,
1622 put :update, :id => 1, :issue => {:subject => new_subject,
1601 :priority_id => '6',
1623 :priority_id => '6',
1602 :category_id => '1' # no change
1624 :category_id => '1' # no change
1603 }
1625 }
1604 assert_equal 1, ActionMailer::Base.deliveries.size
1626 assert_equal 1, ActionMailer::Base.deliveries.size
1605 end
1627 end
1606
1628
1607 def test_put_update_with_invalid_spent_time_hours_only
1629 def test_put_update_with_invalid_spent_time_hours_only
1608 @request.session[:user_id] = 2
1630 @request.session[:user_id] = 2
1609 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1631 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1610
1632
1611 assert_no_difference('Journal.count') do
1633 assert_no_difference('Journal.count') do
1612 put :update,
1634 put :update,
1613 :id => 1,
1635 :id => 1,
1614 :notes => notes,
1636 :notes => notes,
1615 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
1637 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
1616 end
1638 end
1617 assert_response :success
1639 assert_response :success
1618 assert_template 'edit'
1640 assert_template 'edit'
1619
1641
1620 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1642 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1621 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1643 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1622 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
1644 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
1623 end
1645 end
1624
1646
1625 def test_put_update_with_invalid_spent_time_comments_only
1647 def test_put_update_with_invalid_spent_time_comments_only
1626 @request.session[:user_id] = 2
1648 @request.session[:user_id] = 2
1627 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1649 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
1628
1650
1629 assert_no_difference('Journal.count') do
1651 assert_no_difference('Journal.count') do
1630 put :update,
1652 put :update,
1631 :id => 1,
1653 :id => 1,
1632 :notes => notes,
1654 :notes => notes,
1633 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
1655 :time_entry => {"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""}
1634 end
1656 end
1635 assert_response :success
1657 assert_response :success
1636 assert_template 'edit'
1658 assert_template 'edit'
1637
1659
1638 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1660 assert_error_tag :descendant => {:content => /Activity can't be blank/}
1639 assert_error_tag :descendant => {:content => /Hours can't be blank/}
1661 assert_error_tag :descendant => {:content => /Hours can't be blank/}
1640 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1662 assert_tag :textarea, :attributes => { :name => 'notes' }, :content => notes
1641 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
1663 assert_tag :input, :attributes => { :name => 'time_entry[comments]', :value => "this is my comment" }
1642 end
1664 end
1643
1665
1644 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
1666 def test_put_update_should_allow_fixed_version_to_be_set_to_a_subproject
1645 issue = Issue.find(2)
1667 issue = Issue.find(2)
1646 @request.session[:user_id] = 2
1668 @request.session[:user_id] = 2
1647
1669
1648 put :update,
1670 put :update,
1649 :id => issue.id,
1671 :id => issue.id,
1650 :issue => {
1672 :issue => {
1651 :fixed_version_id => 4
1673 :fixed_version_id => 4
1652 }
1674 }
1653
1675
1654 assert_response :redirect
1676 assert_response :redirect
1655 issue.reload
1677 issue.reload
1656 assert_equal 4, issue.fixed_version_id
1678 assert_equal 4, issue.fixed_version_id
1657 assert_not_equal issue.project_id, issue.fixed_version.project_id
1679 assert_not_equal issue.project_id, issue.fixed_version.project_id
1658 end
1680 end
1659
1681
1660 def test_put_update_should_redirect_back_using_the_back_url_parameter
1682 def test_put_update_should_redirect_back_using_the_back_url_parameter
1661 issue = Issue.find(2)
1683 issue = Issue.find(2)
1662 @request.session[:user_id] = 2
1684 @request.session[:user_id] = 2
1663
1685
1664 put :update,
1686 put :update,
1665 :id => issue.id,
1687 :id => issue.id,
1666 :issue => {
1688 :issue => {
1667 :fixed_version_id => 4
1689 :fixed_version_id => 4
1668 },
1690 },
1669 :back_url => '/issues'
1691 :back_url => '/issues'
1670
1692
1671 assert_response :redirect
1693 assert_response :redirect
1672 assert_redirected_to '/issues'
1694 assert_redirected_to '/issues'
1673 end
1695 end
1674
1696
1675 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1697 def test_put_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1676 issue = Issue.find(2)
1698 issue = Issue.find(2)
1677 @request.session[:user_id] = 2
1699 @request.session[:user_id] = 2
1678
1700
1679 put :update,
1701 put :update,
1680 :id => issue.id,
1702 :id => issue.id,
1681 :issue => {
1703 :issue => {
1682 :fixed_version_id => 4
1704 :fixed_version_id => 4
1683 },
1705 },
1684 :back_url => 'http://google.com'
1706 :back_url => 'http://google.com'
1685
1707
1686 assert_response :redirect
1708 assert_response :redirect
1687 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
1709 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue.id
1688 end
1710 end
1689
1711
1690 def test_get_bulk_edit
1712 def test_get_bulk_edit
1691 @request.session[:user_id] = 2
1713 @request.session[:user_id] = 2
1692 get :bulk_edit, :ids => [1, 2]
1714 get :bulk_edit, :ids => [1, 2]
1693 assert_response :success
1715 assert_response :success
1694 assert_template 'bulk_edit'
1716 assert_template 'bulk_edit'
1695
1717
1696 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1718 assert_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1697
1719
1698 # Project specific custom field, date type
1720 # Project specific custom field, date type
1699 field = CustomField.find(9)
1721 field = CustomField.find(9)
1700 assert !field.is_for_all?
1722 assert !field.is_for_all?
1701 assert_equal 'date', field.field_format
1723 assert_equal 'date', field.field_format
1702 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1724 assert_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1703
1725
1704 # System wide custom field
1726 # System wide custom field
1705 assert CustomField.find(1).is_for_all?
1727 assert CustomField.find(1).is_for_all?
1706 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
1728 assert_tag :select, :attributes => {:name => 'issue[custom_field_values][1]'}
1707
1729
1708 # Be sure we don't display inactive IssuePriorities
1730 # Be sure we don't display inactive IssuePriorities
1709 assert ! IssuePriority.find(15).active?
1731 assert ! IssuePriority.find(15).active?
1710 assert_no_tag :option, :attributes => {:value => '15'},
1732 assert_no_tag :option, :attributes => {:value => '15'},
1711 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1733 :parent => {:tag => 'select', :attributes => {:id => 'issue_priority_id'} }
1712 end
1734 end
1713
1735
1714 def test_get_bulk_edit_on_different_projects
1736 def test_get_bulk_edit_on_different_projects
1715 @request.session[:user_id] = 2
1737 @request.session[:user_id] = 2
1716 get :bulk_edit, :ids => [1, 2, 6]
1738 get :bulk_edit, :ids => [1, 2, 6]
1717 assert_response :success
1739 assert_response :success
1718 assert_template 'bulk_edit'
1740 assert_template 'bulk_edit'
1719
1741
1720 # Can not set issues from different projects as children of an issue
1742 # Can not set issues from different projects as children of an issue
1721 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1743 assert_no_tag :input, :attributes => {:name => 'issue[parent_issue_id]'}
1722
1744
1723 # Project specific custom field, date type
1745 # Project specific custom field, date type
1724 field = CustomField.find(9)
1746 field = CustomField.find(9)
1725 assert !field.is_for_all?
1747 assert !field.is_for_all?
1726 assert !field.project_ids.include?(Issue.find(6).project_id)
1748 assert !field.project_ids.include?(Issue.find(6).project_id)
1727 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1749 assert_no_tag :input, :attributes => {:name => 'issue[custom_field_values][9]'}
1728 end
1750 end
1729
1751
1730 def test_get_bulk_edit_with_user_custom_field
1752 def test_get_bulk_edit_with_user_custom_field
1731 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
1753 field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true)
1732
1754
1733 @request.session[:user_id] = 2
1755 @request.session[:user_id] = 2
1734 get :bulk_edit, :ids => [1, 2]
1756 get :bulk_edit, :ids => [1, 2]
1735 assert_response :success
1757 assert_response :success
1736 assert_template 'bulk_edit'
1758 assert_template 'bulk_edit'
1737
1759
1738 assert_tag :select,
1760 assert_tag :select,
1739 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1761 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1740 :children => {
1762 :children => {
1741 :only => {:tag => 'option'},
1763 :only => {:tag => 'option'},
1742 :count => Project.find(1).users.count + 1
1764 :count => Project.find(1).users.count + 1
1743 }
1765 }
1744 end
1766 end
1745
1767
1746 def test_get_bulk_edit_with_version_custom_field
1768 def test_get_bulk_edit_with_version_custom_field
1747 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
1769 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true)
1748
1770
1749 @request.session[:user_id] = 2
1771 @request.session[:user_id] = 2
1750 get :bulk_edit, :ids => [1, 2]
1772 get :bulk_edit, :ids => [1, 2]
1751 assert_response :success
1773 assert_response :success
1752 assert_template 'bulk_edit'
1774 assert_template 'bulk_edit'
1753
1775
1754 assert_tag :select,
1776 assert_tag :select,
1755 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1777 :attributes => {:name => "issue[custom_field_values][#{field.id}]"},
1756 :children => {
1778 :children => {
1757 :only => {:tag => 'option'},
1779 :only => {:tag => 'option'},
1758 :count => Project.find(1).shared_versions.count + 1
1780 :count => Project.find(1).shared_versions.count + 1
1759 }
1781 }
1760 end
1782 end
1761
1783
1762 def test_bulk_update
1784 def test_bulk_update
1763 @request.session[:user_id] = 2
1785 @request.session[:user_id] = 2
1764 # update issues priority
1786 # update issues priority
1765 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1787 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1766 :issue => {:priority_id => 7,
1788 :issue => {:priority_id => 7,
1767 :assigned_to_id => '',
1789 :assigned_to_id => '',
1768 :custom_field_values => {'2' => ''}}
1790 :custom_field_values => {'2' => ''}}
1769
1791
1770 assert_response 302
1792 assert_response 302
1771 # check that the issues were updated
1793 # check that the issues were updated
1772 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
1794 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
1773
1795
1774 issue = Issue.find(1)
1796 issue = Issue.find(1)
1775 journal = issue.journals.find(:first, :order => 'created_on DESC')
1797 journal = issue.journals.find(:first, :order => 'created_on DESC')
1776 assert_equal '125', issue.custom_value_for(2).value
1798 assert_equal '125', issue.custom_value_for(2).value
1777 assert_equal 'Bulk editing', journal.notes
1799 assert_equal 'Bulk editing', journal.notes
1778 assert_equal 1, journal.details.size
1800 assert_equal 1, journal.details.size
1779 end
1801 end
1780
1802
1781 def test_bulk_update_with_group_assignee
1803 def test_bulk_update_with_group_assignee
1782 group = Group.find(11)
1804 group = Group.find(11)
1783 project = Project.find(1)
1805 project = Project.find(1)
1784 project.members << Member.new(:principal => group, :roles => [Role.first])
1806 project.members << Member.new(:principal => group, :roles => [Role.first])
1785
1807
1786 @request.session[:user_id] = 2
1808 @request.session[:user_id] = 2
1787 # update issues assignee
1809 # update issues assignee
1788 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1810 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing',
1789 :issue => {:priority_id => '',
1811 :issue => {:priority_id => '',
1790 :assigned_to_id => group.id,
1812 :assigned_to_id => group.id,
1791 :custom_field_values => {'2' => ''}}
1813 :custom_field_values => {'2' => ''}}
1792
1814
1793 assert_response 302
1815 assert_response 302
1794 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
1816 assert_equal [group, group], Issue.find_all_by_id([1, 2]).collect {|i| i.assigned_to}
1795 end
1817 end
1796
1818
1797 def test_bulk_update_on_different_projects
1819 def test_bulk_update_on_different_projects
1798 @request.session[:user_id] = 2
1820 @request.session[:user_id] = 2
1799 # update issues priority
1821 # update issues priority
1800 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
1822 post :bulk_update, :ids => [1, 2, 6], :notes => 'Bulk editing',
1801 :issue => {:priority_id => 7,
1823 :issue => {:priority_id => 7,
1802 :assigned_to_id => '',
1824 :assigned_to_id => '',
1803 :custom_field_values => {'2' => ''}}
1825 :custom_field_values => {'2' => ''}}
1804
1826
1805 assert_response 302
1827 assert_response 302
1806 # check that the issues were updated
1828 # check that the issues were updated
1807 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
1829 assert_equal [7, 7, 7], Issue.find([1,2,6]).map(&:priority_id)
1808
1830
1809 issue = Issue.find(1)
1831 issue = Issue.find(1)
1810 journal = issue.journals.find(:first, :order => 'created_on DESC')
1832 journal = issue.journals.find(:first, :order => 'created_on DESC')
1811 assert_equal '125', issue.custom_value_for(2).value
1833 assert_equal '125', issue.custom_value_for(2).value
1812 assert_equal 'Bulk editing', journal.notes
1834 assert_equal 'Bulk editing', journal.notes
1813 assert_equal 1, journal.details.size
1835 assert_equal 1, journal.details.size
1814 end
1836 end
1815
1837
1816 def test_bulk_update_on_different_projects_without_rights
1838 def test_bulk_update_on_different_projects_without_rights
1817 @request.session[:user_id] = 3
1839 @request.session[:user_id] = 3
1818 user = User.find(3)
1840 user = User.find(3)
1819 action = { :controller => "issues", :action => "bulk_update" }
1841 action = { :controller => "issues", :action => "bulk_update" }
1820 assert user.allowed_to?(action, Issue.find(1).project)
1842 assert user.allowed_to?(action, Issue.find(1).project)
1821 assert ! user.allowed_to?(action, Issue.find(6).project)
1843 assert ! user.allowed_to?(action, Issue.find(6).project)
1822 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
1844 post :bulk_update, :ids => [1, 6], :notes => 'Bulk should fail',
1823 :issue => {:priority_id => 7,
1845 :issue => {:priority_id => 7,
1824 :assigned_to_id => '',
1846 :assigned_to_id => '',
1825 :custom_field_values => {'2' => ''}}
1847 :custom_field_values => {'2' => ''}}
1826 assert_response 403
1848 assert_response 403
1827 assert_not_equal "Bulk should fail", Journal.last.notes
1849 assert_not_equal "Bulk should fail", Journal.last.notes
1828 end
1850 end
1829
1851
1830 def test_bullk_update_should_send_a_notification
1852 def test_bullk_update_should_send_a_notification
1831 @request.session[:user_id] = 2
1853 @request.session[:user_id] = 2
1832 ActionMailer::Base.deliveries.clear
1854 ActionMailer::Base.deliveries.clear
1833 post(:bulk_update,
1855 post(:bulk_update,
1834 {
1856 {
1835 :ids => [1, 2],
1857 :ids => [1, 2],
1836 :notes => 'Bulk editing',
1858 :notes => 'Bulk editing',
1837 :issue => {
1859 :issue => {
1838 :priority_id => 7,
1860 :priority_id => 7,
1839 :assigned_to_id => '',
1861 :assigned_to_id => '',
1840 :custom_field_values => {'2' => ''}
1862 :custom_field_values => {'2' => ''}
1841 }
1863 }
1842 })
1864 })
1843
1865
1844 assert_response 302
1866 assert_response 302
1845 assert_equal 2, ActionMailer::Base.deliveries.size
1867 assert_equal 2, ActionMailer::Base.deliveries.size
1846 end
1868 end
1847
1869
1848 def test_bulk_update_status
1870 def test_bulk_update_status
1849 @request.session[:user_id] = 2
1871 @request.session[:user_id] = 2
1850 # update issues priority
1872 # update issues priority
1851 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
1873 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing status',
1852 :issue => {:priority_id => '',
1874 :issue => {:priority_id => '',
1853 :assigned_to_id => '',
1875 :assigned_to_id => '',
1854 :status_id => '5'}
1876 :status_id => '5'}
1855
1877
1856 assert_response 302
1878 assert_response 302
1857 issue = Issue.find(1)
1879 issue = Issue.find(1)
1858 assert issue.closed?
1880 assert issue.closed?
1859 end
1881 end
1860
1882
1861 def test_bulk_update_parent_id
1883 def test_bulk_update_parent_id
1862 @request.session[:user_id] = 2
1884 @request.session[:user_id] = 2
1863 post :bulk_update, :ids => [1, 3],
1885 post :bulk_update, :ids => [1, 3],
1864 :notes => 'Bulk editing parent',
1886 :notes => 'Bulk editing parent',
1865 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
1887 :issue => {:priority_id => '', :assigned_to_id => '', :status_id => '', :parent_issue_id => '2'}
1866
1888
1867 assert_response 302
1889 assert_response 302
1868 parent = Issue.find(2)
1890 parent = Issue.find(2)
1869 assert_equal parent.id, Issue.find(1).parent_id
1891 assert_equal parent.id, Issue.find(1).parent_id
1870 assert_equal parent.id, Issue.find(3).parent_id
1892 assert_equal parent.id, Issue.find(3).parent_id
1871 assert_equal [1, 3], parent.children.collect(&:id).sort
1893 assert_equal [1, 3], parent.children.collect(&:id).sort
1872 end
1894 end
1873
1895
1874 def test_bulk_update_custom_field
1896 def test_bulk_update_custom_field
1875 @request.session[:user_id] = 2
1897 @request.session[:user_id] = 2
1876 # update issues priority
1898 # update issues priority
1877 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
1899 post :bulk_update, :ids => [1, 2], :notes => 'Bulk editing custom field',
1878 :issue => {:priority_id => '',
1900 :issue => {:priority_id => '',
1879 :assigned_to_id => '',
1901 :assigned_to_id => '',
1880 :custom_field_values => {'2' => '777'}}
1902 :custom_field_values => {'2' => '777'}}
1881
1903
1882 assert_response 302
1904 assert_response 302
1883
1905
1884 issue = Issue.find(1)
1906 issue = Issue.find(1)
1885 journal = issue.journals.find(:first, :order => 'created_on DESC')
1907 journal = issue.journals.find(:first, :order => 'created_on DESC')
1886 assert_equal '777', issue.custom_value_for(2).value
1908 assert_equal '777', issue.custom_value_for(2).value
1887 assert_equal 1, journal.details.size
1909 assert_equal 1, journal.details.size
1888 assert_equal '125', journal.details.first.old_value
1910 assert_equal '125', journal.details.first.old_value
1889 assert_equal '777', journal.details.first.value
1911 assert_equal '777', journal.details.first.value
1890 end
1912 end
1891
1913
1892 def test_bulk_update_unassign
1914 def test_bulk_update_unassign
1893 assert_not_nil Issue.find(2).assigned_to
1915 assert_not_nil Issue.find(2).assigned_to
1894 @request.session[:user_id] = 2
1916 @request.session[:user_id] = 2
1895 # unassign issues
1917 # unassign issues
1896 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1918 post :bulk_update, :ids => [1, 2], :notes => 'Bulk unassigning', :issue => {:assigned_to_id => 'none'}
1897 assert_response 302
1919 assert_response 302
1898 # check that the issues were updated
1920 # check that the issues were updated
1899 assert_nil Issue.find(2).assigned_to
1921 assert_nil Issue.find(2).assigned_to
1900 end
1922 end
1901
1923
1902 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
1924 def test_post_bulk_update_should_allow_fixed_version_to_be_set_to_a_subproject
1903 @request.session[:user_id] = 2
1925 @request.session[:user_id] = 2
1904
1926
1905 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
1927 post :bulk_update, :ids => [1,2], :issue => {:fixed_version_id => 4}
1906
1928
1907 assert_response :redirect
1929 assert_response :redirect
1908 issues = Issue.find([1,2])
1930 issues = Issue.find([1,2])
1909 issues.each do |issue|
1931 issues.each do |issue|
1910 assert_equal 4, issue.fixed_version_id
1932 assert_equal 4, issue.fixed_version_id
1911 assert_not_equal issue.project_id, issue.fixed_version.project_id
1933 assert_not_equal issue.project_id, issue.fixed_version.project_id
1912 end
1934 end
1913 end
1935 end
1914
1936
1915 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
1937 def test_post_bulk_update_should_redirect_back_using_the_back_url_parameter
1916 @request.session[:user_id] = 2
1938 @request.session[:user_id] = 2
1917 post :bulk_update, :ids => [1,2], :back_url => '/issues'
1939 post :bulk_update, :ids => [1,2], :back_url => '/issues'
1918
1940
1919 assert_response :redirect
1941 assert_response :redirect
1920 assert_redirected_to '/issues'
1942 assert_redirected_to '/issues'
1921 end
1943 end
1922
1944
1923 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1945 def test_post_bulk_update_should_not_redirect_back_using_the_back_url_parameter_off_the_host
1924 @request.session[:user_id] = 2
1946 @request.session[:user_id] = 2
1925 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
1947 post :bulk_update, :ids => [1,2], :back_url => 'http://google.com'
1926
1948
1927 assert_response :redirect
1949 assert_response :redirect
1928 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1950 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1929 end
1951 end
1930
1952
1931 def test_destroy_issue_with_no_time_entries
1953 def test_destroy_issue_with_no_time_entries
1932 assert_nil TimeEntry.find_by_issue_id(2)
1954 assert_nil TimeEntry.find_by_issue_id(2)
1933 @request.session[:user_id] = 2
1955 @request.session[:user_id] = 2
1934 post :destroy, :id => 2
1956 post :destroy, :id => 2
1935 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1957 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1936 assert_nil Issue.find_by_id(2)
1958 assert_nil Issue.find_by_id(2)
1937 end
1959 end
1938
1960
1939 def test_destroy_issues_with_time_entries
1961 def test_destroy_issues_with_time_entries
1940 @request.session[:user_id] = 2
1962 @request.session[:user_id] = 2
1941 post :destroy, :ids => [1, 3]
1963 post :destroy, :ids => [1, 3]
1942 assert_response :success
1964 assert_response :success
1943 assert_template 'destroy'
1965 assert_template 'destroy'
1944 assert_not_nil assigns(:hours)
1966 assert_not_nil assigns(:hours)
1945 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1967 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1946 end
1968 end
1947
1969
1948 def test_destroy_issues_and_destroy_time_entries
1970 def test_destroy_issues_and_destroy_time_entries
1949 @request.session[:user_id] = 2
1971 @request.session[:user_id] = 2
1950 post :destroy, :ids => [1, 3], :todo => 'destroy'
1972 post :destroy, :ids => [1, 3], :todo => 'destroy'
1951 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1973 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1952 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1974 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1953 assert_nil TimeEntry.find_by_id([1, 2])
1975 assert_nil TimeEntry.find_by_id([1, 2])
1954 end
1976 end
1955
1977
1956 def test_destroy_issues_and_assign_time_entries_to_project
1978 def test_destroy_issues_and_assign_time_entries_to_project
1957 @request.session[:user_id] = 2
1979 @request.session[:user_id] = 2
1958 post :destroy, :ids => [1, 3], :todo => 'nullify'
1980 post :destroy, :ids => [1, 3], :todo => 'nullify'
1959 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1981 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1960 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1982 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1961 assert_nil TimeEntry.find(1).issue_id
1983 assert_nil TimeEntry.find(1).issue_id
1962 assert_nil TimeEntry.find(2).issue_id
1984 assert_nil TimeEntry.find(2).issue_id
1963 end
1985 end
1964
1986
1965 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1987 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1966 @request.session[:user_id] = 2
1988 @request.session[:user_id] = 2
1967 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1989 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1968 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1990 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1969 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1991 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1970 assert_equal 2, TimeEntry.find(1).issue_id
1992 assert_equal 2, TimeEntry.find(1).issue_id
1971 assert_equal 2, TimeEntry.find(2).issue_id
1993 assert_equal 2, TimeEntry.find(2).issue_id
1972 end
1994 end
1973
1995
1974 def test_destroy_issues_from_different_projects
1996 def test_destroy_issues_from_different_projects
1975 @request.session[:user_id] = 2
1997 @request.session[:user_id] = 2
1976 post :destroy, :ids => [1, 2, 6], :todo => 'destroy'
1998 post :destroy, :ids => [1, 2, 6], :todo => 'destroy'
1977 assert_redirected_to :controller => 'issues', :action => 'index'
1999 assert_redirected_to :controller => 'issues', :action => 'index'
1978 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
2000 assert !(Issue.find_by_id(1) || Issue.find_by_id(2) || Issue.find_by_id(6))
1979 end
2001 end
1980
2002
1981 def test_destroy_parent_and_child_issues
2003 def test_destroy_parent_and_child_issues
1982 parent = Issue.generate!(:project_id => 1, :tracker_id => 1)
2004 parent = Issue.generate!(:project_id => 1, :tracker_id => 1)
1983 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id)
2005 child = Issue.generate!(:project_id => 1, :tracker_id => 1, :parent_issue_id => parent.id)
1984 assert child.is_descendant_of?(parent.reload)
2006 assert child.is_descendant_of?(parent.reload)
1985
2007
1986 @request.session[:user_id] = 2
2008 @request.session[:user_id] = 2
1987 assert_difference 'Issue.count', -2 do
2009 assert_difference 'Issue.count', -2 do
1988 post :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
2010 post :destroy, :ids => [parent.id, child.id], :todo => 'destroy'
1989 end
2011 end
1990 assert_response 302
2012 assert_response 302
1991 end
2013 end
1992
2014
1993 def test_default_search_scope
2015 def test_default_search_scope
1994 get :index
2016 get :index
1995 assert_tag :div, :attributes => {:id => 'quick-search'},
2017 assert_tag :div, :attributes => {:id => 'quick-search'},
1996 :child => {:tag => 'form',
2018 :child => {:tag => 'form',
1997 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
2019 :child => {:tag => 'input', :attributes => {:name => 'issues', :type => 'hidden', :value => '1'}}}
1998 end
2020 end
1999 end
2021 end
General Comments 0
You need to be logged in to leave comments. Login now