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