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