##// END OF EJS Templates
ProjectsController#list_issues, #export_issues_csv and #export_issues_pdf merged into IssuesController#index...
Jean-Philippe Lang -
r874:8509cf80f009
parent child
Show More
@@ -0,0 +1,30
1 xml.instruct!
2 xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3 xml.title @title
4 xml.link "rel" => "self", "href" => url_for(:controller => 'feeds', :action => 'history', :format => 'atom', :only_path => false)
5 xml.link "rel" => "alternate", "href" => url_for(:controller => 'welcome', :only_path => false)
6 xml.id url_for(:controller => 'welcome', :only_path => false)
7 xml.updated((@changes.first ? @changes.first.event_datetime : Time.now).xmlschema)
8 xml.author { xml.name "#{Setting.app_title}" }
9 @changes.each do |change|
10 issue = change.issue
11 xml.entry do
12 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
13 xml.link "rel" => "alternate", "href" => url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
14 xml.id url_for(:controller => 'issues' , :action => 'show', :id => issue, :journal_id => change, :only_path => false)
15 xml.updated change.created_on.xmlschema
16 xml.author do
17 xml.name change.user.name
18 xml.email(change.user.mail)
19 end
20 xml.content "type" => "html" do
21 xml.text! '<ul>'
22 change.details.each do |detail|
23 xml.text! '<li>' + show_detail(detail, false) + '</li>'
24 end
25 xml.text! '</ul>'
26 xml.text! textilizable(change.notes) unless change.notes.blank?
27 end
28 end
29 end
30 end No newline at end of file
@@ -0,0 +1,86
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
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
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.dirname(__FILE__) + '/../test_helper'
19 require 'issues_controller'
20
21 # Re-raise errors caught by the controller.
22 class IssuesController; def rescue_action(e) raise e end; end
23
24 class IssuesControllerTest < Test::Unit::TestCase
25 fixtures :projects, :users, :roles, :members, :issues, :enabled_modules, :enumerations
26
27 def setup
28 @controller = IssuesController.new
29 @request = ActionController::TestRequest.new
30 @response = ActionController::TestResponse.new
31 User.current = nil
32 end
33
34 def test_index
35 get :index
36 assert_response :success
37 assert_template 'index.rhtml'
38 assert_not_nil assigns(:issues)
39 assert_nil assigns(:project)
40 end
41
42 def test_index_with_project
43 get :index, :project_id => 1
44 assert_response :success
45 assert_template 'index.rhtml'
46 assert_not_nil assigns(:issues)
47 end
48
49 def test_index_with_project_and_filter
50 get :index, :project_id => 1, :set_filter => 1
51 assert_response :success
52 assert_template 'index.rhtml'
53 assert_not_nil assigns(:issues)
54 end
55
56 def test_index_csv_with_project
57 get :index, :format => 'csv'
58 assert_response :success
59 assert_not_nil assigns(:issues)
60 assert_equal 'text/csv', @response.content_type
61
62 get :index, :project_id => 1, :format => 'csv'
63 assert_response :success
64 assert_not_nil assigns(:issues)
65 assert_equal 'text/csv', @response.content_type
66 end
67
68 def test_index_pdf
69 get :index, :format => 'pdf'
70 assert_response :success
71 assert_not_nil assigns(:issues)
72 assert_equal 'application/pdf', @response.content_type
73
74 get :index, :project_id => 1, :format => 'pdf'
75 assert_response :success
76 assert_not_nil assigns(:issues)
77 assert_equal 'application/pdf', @response.content_type
78 end
79
80 def test_changes
81 get :changes, :project_id => 1
82 assert_response :success
83 assert_not_nil assigns(:changes)
84 assert_equal 'application/atom+xml', @response.content_type
85 end
86 end
@@ -16,9 +16,10
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 layout 'base', :except => :export_pdf
19 layout 'base'
20 before_filter :find_project, :authorize, :except => [:index, :preview]
20 before_filter :find_project, :authorize, :except => [:index, :changes, :preview]
21 accept_key_auth :index
21 before_filter :find_optional_project, :only => [:index, :changes]
22 accept_key_auth :index, :changes
22
23
23 cache_sweeper :issue_sweeper, :only => [ :edit, :change_status, :destroy ]
24 cache_sweeper :issue_sweeper, :only => [ :edit, :change_status, :destroy ]
24
25
@@ -37,37 +38,54 class IssuesController < ApplicationController
37 helper :queries
38 helper :queries
38 helper :sort
39 helper :sort
39 include SortHelper
40 include SortHelper
41 include IssuesHelper
40
42
41 def index
43 def index
42 sort_init "#{Issue.table_name}.id", "desc"
44 sort_init "#{Issue.table_name}.id", "desc"
43 sort_update
45 sort_update
44 retrieve_query
46 retrieve_query
45 if @query.valid?
47 if @query.valid?
48 limit = %w(pdf csv).include?(params[:format]) ? Setting.issues_export_limit.to_i : 25
46 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
49 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
47 @issue_pages = Paginator.new self, @issue_count, 25, params['page']
50 @issue_pages = Paginator.new self, @issue_count, limit, params['page']
48 @issues = Issue.find :all, :order => sort_clause,
51 @issues = Issue.find :all, :order => sort_clause,
49 :include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
52 :include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
50 :conditions => @query.statement,
53 :conditions => @query.statement,
51 :limit => @issue_pages.items_per_page,
54 :limit => limit,
52 :offset => @issue_pages.current.offset
55 :offset => @issue_pages.current.offset
53 end
54 respond_to do |format|
56 respond_to do |format|
55 format.html { render :layout => false if request.xhr? }
57 format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
56 format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
58 format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
59 format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
60 format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
61 end
62 else
63 # Send html if the query is not valid
64 render(:template => 'issues/index.rhtml', :layout => !request.xhr?)
65 end
66 end
67
68 def changes
69 sort_init "#{Issue.table_name}.id", "desc"
70 sort_update
71 retrieve_query
72 if @query.valid?
73 @changes = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
74 :conditions => @query.statement,
75 :limit => 25,
76 :order => "#{Journal.table_name}.created_on DESC"
57 end
77 end
78 @title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
79 render :layout => false, :content_type => 'application/atom+xml'
58 end
80 end
59
81
60 def show
82 def show
61 @custom_values = @issue.custom_values.find(:all, :include => :custom_field)
83 @custom_values = @issue.custom_values.find(:all, :include => :custom_field)
62 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
84 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
63
64 if params[:format]=='pdf'
65 @options_for_rfpdf ||= {}
66 @options_for_rfpdf[:file_name] = "#{@project.identifier}-#{@issue.id}.pdf"
67 render :template => 'issues/show.rfpdf', :layout => false
68 else
69 @status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
85 @status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
70 render :template => 'issues/show.rhtml'
86 respond_to do |format|
87 format.html { render :template => 'issues/show.rhtml' }
88 format.pdf { send_data(render(:template => 'issues/show.rfpdf', :layout => false), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") }
71 end
89 end
72 end
90 end
73
91
@@ -152,7 +170,7 class IssuesController < ApplicationController
152
170
153 def destroy
171 def destroy
154 @issue.destroy
172 @issue.destroy
155 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
173 redirect_to :action => 'index', :project_id => @project
156 end
174 end
157
175
158 def destroy_attachment
176 def destroy_attachment
@@ -195,11 +213,25 private
195 render_404
213 render_404
196 end
214 end
197
215
216 def find_optional_project
217 return true unless params[:project_id]
218 @project = Project.find(params[:project_id])
219 authorize
220 rescue ActiveRecord::RecordNotFound
221 render_404
222 end
223
198 # Retrieve query from session or build a new query
224 # Retrieve query from session or build a new query
199 def retrieve_query
225 def retrieve_query
200 if params[:set_filter] or !session[:query] or session[:query].project_id
226 if params[:query_id]
227 @query = Query.find(params[:query_id], :conditions => {:project_id => (@project ? @project.id : nil)})
228 @query.executed_by = logged_in_user
229 session[:query] = @query
230 else
231 if params[:set_filter] or !session[:query] or session[:query].project != @project
201 # Give it a name, required to be valid
232 # Give it a name, required to be valid
202 @query = Query.new(:name => "_", :executed_by => logged_in_user)
233 @query = Query.new(:name => "_", :executed_by => logged_in_user)
234 @query.project = @project
203 if params[:fields] and params[:fields].is_a? Array
235 if params[:fields] and params[:fields].is_a? Array
204 params[:fields].each do |field|
236 params[:fields].each do |field|
205 @query.add_filter(field, params[:operators][field], params[:values][field])
237 @query.add_filter(field, params[:operators][field], params[:values][field])
@@ -215,3 +247,4 private
215 end
247 end
216 end
248 end
217 end
249 end
250 end
@@ -15,8 +15,6
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 'csv'
19
20 class ProjectsController < ApplicationController
18 class ProjectsController < ApplicationController
21 layout 'base'
19 layout 'base'
22 before_filter :find_project, :except => [ :index, :list, :add ]
20 before_filter :find_project, :except => [ :index, :list, :add ]
@@ -238,118 +236,13 class ProjectsController < ApplicationController
238 end
236 end
239 flash[:notice] = l(:notice_successful_create)
237 flash[:notice] = l(:notice_successful_create)
240 Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
238 Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
241 redirect_to :action => 'list_issues', :id => @project
239 redirect_to :controller => 'issues', :action => 'index', :project_id => @project
242 return
240 return
243 end
241 end
244 end
242 end
245 @priorities = Enumeration::get_values('IPRI')
243 @priorities = Enumeration::get_values('IPRI')
246 end
244 end
247
245
248 # Show filtered/sorted issues list of @project
249 def list_issues
250 sort_init "#{Issue.table_name}.id", "desc"
251 sort_update
252
253 retrieve_query
254
255 @results_per_page_options = [ 15, 25, 50, 100 ]
256 if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
257 @results_per_page = params[:per_page].to_i
258 session[:results_per_page] = @results_per_page
259 else
260 @results_per_page = session[:results_per_page] || 25
261 end
262
263 if @query.valid?
264 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
265 @issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
266 @issues = Issue.find :all, :order => sort_clause,
267 :include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
268 :conditions => @query.statement,
269 :limit => @issue_pages.items_per_page,
270 :offset => @issue_pages.current.offset
271 end
272
273 render :layout => false if request.xhr?
274 end
275
276 # Export filtered/sorted issues list to CSV
277 def export_issues_csv
278 sort_init "#{Issue.table_name}.id", "desc"
279 sort_update
280
281 retrieve_query
282 render :action => 'list_issues' and return unless @query.valid?
283
284 @issues = Issue.find :all, :order => sort_clause,
285 :include => [ :assigned_to, :author, :status, :tracker, :priority, :project, {:custom_values => :custom_field} ],
286 :conditions => @query.statement,
287 :limit => Setting.issues_export_limit.to_i
288
289 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
290 export = StringIO.new
291 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
292 # csv header fields
293 headers = [ "#", l(:field_status),
294 l(:field_project),
295 l(:field_tracker),
296 l(:field_priority),
297 l(:field_subject),
298 l(:field_assigned_to),
299 l(:field_author),
300 l(:field_start_date),
301 l(:field_due_date),
302 l(:field_done_ratio),
303 l(:field_created_on),
304 l(:field_updated_on)
305 ]
306 for custom_field in @project.all_custom_fields
307 headers << custom_field.name
308 end
309 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
310 # csv lines
311 @issues.each do |issue|
312 fields = [issue.id, issue.status.name,
313 issue.project.name,
314 issue.tracker.name,
315 issue.priority.name,
316 issue.subject,
317 (issue.assigned_to ? issue.assigned_to.name : ""),
318 issue.author.name,
319 issue.start_date ? l_date(issue.start_date) : nil,
320 issue.due_date ? l_date(issue.due_date) : nil,
321 issue.done_ratio,
322 l_datetime(issue.created_on),
323 l_datetime(issue.updated_on)
324 ]
325 for custom_field in @project.all_custom_fields
326 fields << (show_value issue.custom_value_for(custom_field))
327 end
328 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
329 end
330 end
331 export.rewind
332 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
333 end
334
335 # Export filtered/sorted issues to PDF
336 def export_issues_pdf
337 sort_init "#{Issue.table_name}.id", "desc"
338 sort_update
339
340 retrieve_query
341 render :action => 'list_issues' and return unless @query.valid?
342
343 @issues = Issue.find :all, :order => sort_clause,
344 :include => [ :author, :status, :tracker, :priority, :project ],
345 :conditions => @query.statement,
346 :limit => Setting.issues_export_limit.to_i
347
348 @options_for_rfpdf ||= {}
349 @options_for_rfpdf[:file_name] = "export.pdf"
350 render :layout => false
351 end
352
353 # Bulk edit issues
246 # Bulk edit issues
354 def bulk_edit_issues
247 def bulk_edit_issues
355 if request.post?
248 if request.post?
@@ -383,7 +276,7 class ProjectsController < ApplicationController
383 else
276 else
384 flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, issues.size, '#' + unsaved_issue_ids.join(', #'))
277 flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, issues.size, '#' + unsaved_issue_ids.join(', #'))
385 end
278 end
386 redirect_to :action => 'list_issues', :id => @project
279 redirect_to :controller => 'issues', :action => 'index', :project_id => @project
387 return
280 return
388 end
281 end
389 if current_role && User.current.allowed_to?(:change_issue_status, @project)
282 if current_role && User.current.allowed_to?(:change_issue_status, @project)
@@ -399,7 +292,7 class ProjectsController < ApplicationController
399
292
400 def move_issues
293 def move_issues
401 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
294 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
402 redirect_to :action => 'list_issues', :id => @project and return unless @issues
295 redirect_to :controller => 'issues', :action => 'index', :project_id => @project and return unless @issues
403 @projects = []
296 @projects = []
404 # find projects to which the user is allowed to move the issue
297 # find projects to which the user is allowed to move the issue
405 User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:controller => 'projects', :action => 'move_issues')}
298 User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:controller => 'projects', :action => 'move_issues')}
@@ -424,7 +317,7 class ProjectsController < ApplicationController
424 i.save
317 i.save
425 end
318 end
426 flash[:notice] = l(:notice_successful_update)
319 flash[:notice] = l(:notice_successful_update)
427 redirect_to :action => 'list_issues', :id => @project
320 redirect_to :controller => 'issues', :action => 'index', :project_id => @project
428 end
321 end
429 end
322 end
430
323
@@ -659,31 +552,4 private
659 @selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
552 @selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
660 end
553 end
661 end
554 end
662
663 # Retrieve query from session or build a new query
664 def retrieve_query
665 if params[:query_id]
666 @query = @project.queries.find(params[:query_id])
667 @query.executed_by = logged_in_user
668 session[:query] = @query
669 else
670 if params[:set_filter] or !session[:query] or session[:query].project_id != @project.id
671 # Give it a name, required to be valid
672 @query = Query.new(:name => "_", :executed_by => logged_in_user)
673 @query.project = @project
674 if params[:fields] and params[:fields].is_a? Array
675 params[:fields].each do |field|
676 @query.add_filter(field, params[:operators][field], params[:values][field])
677 end
678 else
679 @query.available_filters.keys.each do |field|
680 @query.add_short_filter(field, params[field]) if params[field]
681 end
682 end
683 session[:query] = @query
684 else
685 @query = session[:query]
686 end
687 end
688 end
689 end
555 end
@@ -39,7 +39,7 class QueriesController < ApplicationController
39
39
40 if request.post? && params[:confirm] && @query.save
40 if request.post? && params[:confirm] && @query.save
41 flash[:notice] = l(:notice_successful_create)
41 flash[:notice] = l(:notice_successful_create)
42 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
42 redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
43 return
43 return
44 end
44 end
45 render :layout => false if request.xhr?
45 render :layout => false if request.xhr?
@@ -57,7 +57,7 class QueriesController < ApplicationController
57
57
58 if @query.save
58 if @query.save
59 flash[:notice] = l(:notice_successful_update)
59 flash[:notice] = l(:notice_successful_update)
60 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
60 redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
61 end
61 end
62 end
62 end
63 end
63 end
@@ -15,6 +15,8
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 'csv'
19
18 module IssuesHelper
20 module IssuesHelper
19
21
20 def render_issue_tooltip(issue)
22 def render_issue_tooltip(issue)
@@ -101,4 +103,54 module IssuesHelper
101 end
103 end
102 end
104 end
103 end
105 end
106
107 def issues_to_csv(issues, project = nil)
108 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
109 export = StringIO.new
110 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
111 # csv header fields
112 headers = [ "#",
113 l(:field_status),
114 l(:field_project),
115 l(:field_tracker),
116 l(:field_priority),
117 l(:field_subject),
118 l(:field_assigned_to),
119 l(:field_author),
120 l(:field_start_date),
121 l(:field_due_date),
122 l(:field_done_ratio),
123 l(:field_created_on),
124 l(:field_updated_on)
125 ]
126 # only export custom fields if project is given
127 for custom_field in project.all_custom_fields
128 headers << custom_field.name
129 end if project
130 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
131 # csv lines
132 issues.each do |issue|
133 fields = [issue.id,
134 issue.status.name,
135 issue.project.name,
136 issue.tracker.name,
137 issue.priority.name,
138 issue.subject,
139 (issue.assigned_to ? issue.assigned_to.name : ""),
140 issue.author.name,
141 issue.start_date ? l_date(issue.start_date) : nil,
142 issue.due_date ? l_date(issue.due_date) : nil,
143 issue.done_ratio,
144 l_datetime(issue.created_on),
145 l_datetime(issue.updated_on)
146 ]
147 for custom_field in project.all_custom_fields
148 fields << (show_value issue.custom_value_for(custom_field))
149 end if project
150 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
151 end
152 end
153 export.rewind
154 export
155 end
104 end
156 end
@@ -29,6 +29,10 class Journal < ActiveRecord::Base
29 :project_key => "#{Issue.table_name}.project_id",
29 :project_key => "#{Issue.table_name}.project_id",
30 :date_column => "#{Issue.table_name}.created_on"
30 :date_column => "#{Issue.table_name}.created_on"
31
31
32 acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}"},
33 :description => :notes,
34 :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}}
35
32 def save
36 def save
33 # Do not save an empty journal
37 # Do not save an empty journal
34 (details.empty? && notes.blank?) ? false : super
38 (details.empty? && notes.blank?) ? false : super
@@ -4,7 +4,7
4 <% end %>
4 <% end %>
5
5
6 <h3><%= l(:label_issue_plural) %></h3>
6 <h3><%= l(:label_issue_plural) %></h3>
7 <%= link_to l(:label_issue_view_all), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %><br />
7 <%= link_to l(:label_issue_view_all), { :set_filter => 1 } %><br />
8 <%= link_to l(:field_summary), :controller => 'reports', :action => 'issue_report', :id => @project %><br />
8 <%= link_to l(:field_summary), :controller => 'reports', :action => 'issue_report', :id => @project %><br />
9 <%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %>
9 <%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %>
10
10
@@ -14,5 +14,5
14 :order => "name ASC",
14 :order => "name ASC",
15 :conditions => ["is_public = ? or user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
15 :conditions => ["is_public = ? or user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
16 queries.each do |query| %>
16 queries.each do |query| %>
17 <%= link_to query.name, :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => query %><br />
17 <%= link_to query.name, :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %><br />
18 <% end %>
18 <% end %>
@@ -1,4 +1,4
1 <% back_to = url_for(:controller => 'projects', :action => 'list_issues', :id => @project) %>
1 <% back_to = url_for(:controller => 'issues', :action => 'index', :project_id => @project) %>
2 <ul>
2 <ul>
3 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
3 <li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
4 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
4 :class => 'icon-edit', :disabled => !@can[:edit] %></li>
@@ -1,5 +1,6
1 <% pdf=IfpdfHelper::IFPDF.new(current_language)
1 <% pdf=IfpdfHelper::IFPDF.new(current_language)
2 pdf.SetTitle("#{@project.name} - #{l(:label_issue_plural)}")
2 title = @project ? "#{@project.name} - #{l(:label_issue_plural)}" : "#{l(:label_issue_plural)}"
3 pdf.SetTitle(title)
3 pdf.AliasNbPages
4 pdf.AliasNbPages
4 pdf.footer_date = format_date(Date.today)
5 pdf.footer_date = format_date(Date.today)
5 pdf.AddPage("L")
6 pdf.AddPage("L")
@@ -9,7 +10,7
9 # title
10 # title
10 #
11 #
11 pdf.SetFontStyle('B',11)
12 pdf.SetFontStyle('B',11)
12 pdf.Cell(190,10, "#{@project.name} - #{l(:label_issue_plural)}")
13 pdf.Cell(190,10, title)
13 pdf.Ln
14 pdf.Ln
14
15
15 #
16 #
@@ -21,7 +22,7
21 pdf.Cell(30, row_height, l(:field_tracker), 0, 0, 'L', 1)
22 pdf.Cell(30, row_height, l(:field_tracker), 0, 0, 'L', 1)
22 pdf.Cell(30, row_height, l(:field_status), 0, 0, 'L', 1)
23 pdf.Cell(30, row_height, l(:field_status), 0, 0, 'L', 1)
23 pdf.Cell(30, row_height, l(:field_priority), 0, 0, 'L', 1)
24 pdf.Cell(30, row_height, l(:field_priority), 0, 0, 'L', 1)
24 pdf.Cell(40, row_height, l(:field_author), 0, 0, 'L', 1)
25 pdf.Cell(40, row_height, l(:field_assigned_to), 0, 0, 'L', 1)
25 pdf.Cell(25, row_height, l(:field_updated_on), 0, 0, 'L', 1)
26 pdf.Cell(25, row_height, l(:field_updated_on), 0, 0, 'L', 1)
26 pdf.Cell(0, row_height, l(:field_subject), 0, 0, 'L', 1)
27 pdf.Cell(0, row_height, l(:field_subject), 0, 0, 'L', 1)
27 pdf.Line(10, pdf.GetY, 287, pdf.GetY)
28 pdf.Line(10, pdf.GetY, 287, pdf.GetY)
@@ -39,7 +40,7
39 pdf.Cell(30, row_height, issue.tracker.name, 0, 0, 'L', 1)
40 pdf.Cell(30, row_height, issue.tracker.name, 0, 0, 'L', 1)
40 pdf.Cell(30, row_height, issue.status.name, 0, 0, 'L', 1)
41 pdf.Cell(30, row_height, issue.status.name, 0, 0, 'L', 1)
41 pdf.Cell(30, row_height, issue.priority.name, 0, 0, 'L', 1)
42 pdf.Cell(30, row_height, issue.priority.name, 0, 0, 'L', 1)
42 pdf.Cell(40, row_height, issue.author.name, 0, 0, 'L', 1)
43 pdf.Cell(40, row_height, issue.assigned_to ? issue.assigned_to.name : '', 0, 0, 'L', 1)
43 pdf.Cell(25, row_height, format_date(issue.updated_on), 0, 0, 'L', 1)
44 pdf.Cell(25, row_height, format_date(issue.updated_on), 0, 0, 'L', 1)
44 pdf.MultiCell(0, row_height, (@project == issue.project ? issue.subject : "#{issue.project.name} - #{issue.subject}"))
45 pdf.MultiCell(0, row_height, (@project == issue.project ? issue.subject : "#{issue.project.name} - #{issue.subject}"))
45 pdf.Line(10, pdf.GetY, 287, pdf.GetY)
46 pdf.Line(10, pdf.GetY, 287, pdf.GetY)
@@ -1,8 +1,9
1 <% if @query.new_record? %>
1 <h2><%=l(:label_issue_plural)%></h2>
2 <h2><%=l(:label_issue_plural)%></h2>
3 <% set_html_title l(:label_issue_plural) %>
2
4
3 <% form_tag({}, :id => 'query_form') do %>
5 <% form_tag({ :controller => 'queries', :action => 'new', :project_id => @project }, :id => 'query_form') do %>
4 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
6 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
5 <% end %>
6 <div class="contextual">
7 <div class="contextual">
7 <%= link_to_remote l(:button_apply),
8 <%= link_to_remote l(:button_apply),
8 { :url => { :set_filter => 1 },
9 { :url => { :set_filter => 1 },
@@ -14,22 +15,58
14 { :url => { :set_filter => 1 },
15 { :url => { :set_filter => 1 },
15 :update => "content",
16 :update => "content",
16 }, :class => 'icon icon-reload' %>
17 }, :class => 'icon icon-reload' %>
18
19 <% if current_role && current_role.allowed_to?(:save_queries) %>
20 <%= link_to l(:button_save), {}, :onclick => "$('query_form').submit(); return false;", :class => 'icon icon-save' %>
21 <% end %>
22 </div>
23 <br />
24 &nbsp;
25 <% end %>
26 <% else %>
27 <div class="contextual">
28 <% if @query.editable_by?(User.current) %>
29 <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %>
30 <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
31 <% end %>
17 </div>
32 </div>
18 <br />&nbsp;
19
33
34 <h2><%= @query.name %></h2>
35 <div id="query_form"></div>
36 <% set_html_title @query.name %>
37 <% end %>
20 <%= error_messages_for 'query' %>
38 <%= error_messages_for 'query' %>
21 <% if @query.valid? %>
39 <% if @query.valid? %>
22 <% if @issues.empty? %>
40 <% if @issues.empty? %>
23 <p><i><%= l(:label_no_data) %></i></p>
41 <p class="nodata"><%= l(:label_no_data) %></p>
24 <% else %>
42 <% else %>
25 &nbsp;
43 <% form_tag({:controller => 'projects', :action => 'bulk_edit_issues', :id => @project}, :id => 'issues_form', :onsubmit => "if (!checkBulkEdit(this)) {alert('#{l(:notice_no_issue_selected)}'); return false;}" ) do %>
26 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
44 <%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
27
45 <div class="contextual">
46 <%= l(:label_export_to) %>
47 <%= link_to 'CSV', {:format => 'csv'}, :class => 'icon icon-csv' %>,
48 <%= link_to 'PDF', {:format => 'pdf'}, :class => 'icon icon-pdf' %>
49 </div>
28 <p><%= pagination_links_full @issue_pages %>
50 <p><%= pagination_links_full @issue_pages %>
29 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]</p>
51 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]</p>
30 <% end %>
52 <% end %>
31 <% end %>
53 <% end %>
54 <% end %>
55
56 <% content_for :sidebar do %>
57 <%= render :partial => 'issues/sidebar' %>
58 <% end if @project%>
32
59
33 <% content_for :header_tags do %>
60 <% content_for :header_tags do %>
34 <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
61 <%= auto_discovery_link_tag(:atom, {:query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_issue_plural)) %>
62 <%= auto_discovery_link_tag(:atom, {:action => 'changes', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
63 <%= javascript_include_tag 'calendar/calendar' %>
64 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
65 <%= javascript_include_tag 'calendar/calendar-setup' %>
66 <%= stylesheet_link_tag 'calendar' %>
67 <%= javascript_include_tag 'context_menu' %>
68 <%= stylesheet_link_tag 'context_menu' %>
35 <% end %>
69 <% end %>
70
71 <div id="context-menu" style="display: none;"></div>
72 <%= javascript_tag 'new ContextMenu({})' %>
@@ -34,8 +34,8
34 <% end %>
34 <% end %>
35 </tr>
35 </tr>
36 </table>
36 </table>
37 <em><%= link_to(complete, :controller => 'projects', :action => 'list_issues', :id => @project, :status_id => 'c', :fixed_version_id => version, :set_filter => 1) %> <%= lwr(:label_closed_issues, complete) %> (<%= percentComplete %>%) &#160;
37 <em><%= link_to(complete, :controller => 'issues', :action => 'index', :project_id => @project, :status_id => 'c', :fixed_version_id => version, :set_filter => 1) %> <%= lwr(:label_closed_issues, complete) %> (<%= percentComplete %>%) &#160;
38 <%= link_to((total - complete), :controller => 'projects', :action => 'list_issues', :id => @project, :status_id => 'o', :fixed_version_id => version, :set_filter => 1) %> <%= lwr(:label_open_issues, total - complete)%> (<%= percentIncomplete %>%)</em>
38 <%= link_to((total - complete), :controller => 'issues', :action => 'index', :project_id => @project, :status_id => 'o', :fixed_version_id => version, :set_filter => 1) %> <%= lwr(:label_open_issues, total - complete)%> (<%= percentIncomplete %>%)</em>
39 <br />
39 <br />
40 <br />
40 <br />
41 <%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
41 <%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %>
@@ -22,14 +22,14
22 <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
22 <h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3>
23 <ul>
23 <ul>
24 <% for tracker in @trackers %>
24 <% for tracker in @trackers %>
25 <li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project,
25 <li><%= link_to tracker.name, :controller => 'issues', :action => 'index', :project_id => @project,
26 :set_filter => 1,
26 :set_filter => 1,
27 "tracker_id" => tracker.id %>:
27 "tracker_id" => tracker.id %>:
28 <%= @open_issues_by_tracker[tracker] || 0 %> <%= lwr(:label_open_issues, @open_issues_by_tracker[tracker] || 0) %>
28 <%= @open_issues_by_tracker[tracker] || 0 %> <%= lwr(:label_open_issues, @open_issues_by_tracker[tracker] || 0) %>
29 <%= l(:label_on) %> <%= @total_issues_by_tracker[tracker] || 0 %></li>
29 <%= l(:label_on) %> <%= @total_issues_by_tracker[tracker] || 0 %></li>
30 <% end %>
30 <% end %>
31 </ul>
31 </ul>
32 <p><%= link_to l(:label_issue_view_all), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %></p>
32 <p><%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %></p>
33 </div>
33 </div>
34 <% end %>
34 <% end %>
35 </div>
35 </div>
@@ -11,7 +11,7
11 <% @queries.each do |query| %>
11 <% @queries.each do |query| %>
12 <tr class="<%= cycle('odd', 'even') %>">
12 <tr class="<%= cycle('odd', 'even') %>">
13 <td>
13 <td>
14 <%= link_to query.name, :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => query %>
14 <%= link_to query.name, :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %>
15 </td>
15 </td>
16 <td align="right">
16 <td align="right">
17 <small>
17 <small>
@@ -15,28 +15,28
15 <tbody>
15 <tbody>
16 <% for row in rows %>
16 <% for row in rows %>
17 <tr class="<%= cycle("odd", "even") %>">
17 <tr class="<%= cycle("odd", "even") %>">
18 <td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
18 <td><%= link_to row.name, :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
19 :set_filter => 1,
19 :set_filter => 1,
20 "#{field_name}" => row.id %></td>
20 "#{field_name}" => row.id %></td>
21 <% for status in @statuses %>
21 <% for status in @statuses %>
22 <td align="center"><%= aggregate_link data, { field_name => row.id, "status_id" => status.id },
22 <td align="center"><%= aggregate_link data, { field_name => row.id, "status_id" => status.id },
23 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
23 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
24 :set_filter => 1,
24 :set_filter => 1,
25 "status_id" => status.id,
25 "status_id" => status.id,
26 "#{field_name}" => row.id %></td>
26 "#{field_name}" => row.id %></td>
27 <% end %>
27 <% end %>
28 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 },
28 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 },
29 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
29 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
30 :set_filter => 1,
30 :set_filter => 1,
31 "#{field_name}" => row.id,
31 "#{field_name}" => row.id,
32 "status_id" => "o" %></td>
32 "status_id" => "o" %></td>
33 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 },
33 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 },
34 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
34 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
35 :set_filter => 1,
35 :set_filter => 1,
36 "#{field_name}" => row.id,
36 "#{field_name}" => row.id,
37 "status_id" => "c" %></td>
37 "status_id" => "c" %></td>
38 <td align="center"><%= aggregate_link data, { field_name => row.id },
38 <td align="center"><%= aggregate_link data, { field_name => row.id },
39 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
39 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
40 :set_filter => 1,
40 :set_filter => 1,
41 "#{field_name}" => row.id,
41 "#{field_name}" => row.id,
42 "status_id" => "*" %></td>
42 "status_id" => "*" %></td>
@@ -11,21 +11,21
11 <tbody>
11 <tbody>
12 <% for row in rows %>
12 <% for row in rows %>
13 <tr class="<%= cycle("odd", "even") %>">
13 <tr class="<%= cycle("odd", "even") %>">
14 <td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
14 <td><%= link_to row.name, :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
15 :set_filter => 1,
15 :set_filter => 1,
16 "#{field_name}" => row.id %></td>
16 "#{field_name}" => row.id %></td>
17 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 },
17 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 0 },
18 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
18 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
19 :set_filter => 1,
19 :set_filter => 1,
20 "#{field_name}" => row.id,
20 "#{field_name}" => row.id,
21 "status_id" => "o" %></td>
21 "status_id" => "o" %></td>
22 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 },
22 <td align="center"><%= aggregate_link data, { field_name => row.id, "closed" => 1 },
23 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
23 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
24 :set_filter => 1,
24 :set_filter => 1,
25 "#{field_name}" => row.id,
25 "#{field_name}" => row.id,
26 "status_id" => "c" %></td>
26 "status_id" => "c" %></td>
27 <td align="center"><%= aggregate_link data, { field_name => row.id },
27 <td align="center"><%= aggregate_link data, { field_name => row.id },
28 :controller => 'projects', :action => 'list_issues', :id => ((row.is_a?(Project) ? row : @project)),
28 :controller => 'issues', :action => 'index', :project_id => ((row.is_a?(Project) ? row : @project)),
29 :set_filter => 1,
29 :set_filter => 1,
30 "#{field_name}" => row.id,
30 "#{field_name}" => row.id,
31 "status_id" => "*" %></td>
31 "status_id" => "*" %></td>
@@ -78,6 +78,9 ActiveRecord::Errors.default_error_messages = {
78
78
79 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
79 ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" }
80
80
81 Mime::Type.register 'text/csv', :csv
82 Mime::Type.register 'application/pdf', :pdf
83
81 GLoc.set_config :default_language => :en
84 GLoc.set_config :default_language => :en
82 GLoc.clear_strings
85 GLoc.clear_strings
83 GLoc.set_kcode
86 GLoc.set_kcode
@@ -14,6 +14,7 ActionController::Routing::Routes.draw do |map|
14 #map.connect ':controller/:action/:id/:sort_key/:sort_order'
14 #map.connect ':controller/:action/:id/:sort_key/:sort_order'
15
15
16 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
16 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
17 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
17 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
18 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
18 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
19 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
19
20
@@ -25,8 +25,8 Redmine::AccessControl.map do |map|
25 # Issue categories
25 # Issue categories
26 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
26 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
27 # Issues
27 # Issues
28 map.permission :view_issues, {:projects => [:list_issues, :export_issues_csv, :export_issues_pdf, :changelog, :roadmap],
28 map.permission :view_issues, {:projects => [:changelog, :roadmap],
29 :issues => [:show, :context_menu],
29 :issues => [:index, :changes, :show, :context_menu],
30 :queries => :index,
30 :queries => :index,
31 :reports => :issue_report}, :public => true
31 :reports => :issue_report}, :public => true
32 map.permission :add_issues, {:projects => :add_issue}, :require => :loggedin
32 map.permission :add_issues, {:projects => :add_issue}, :require => :loggedin
@@ -92,7 +92,7 Redmine::MenuManager.map :project_menu do |menu|
92 menu.push :label_overview, :controller => 'projects', :action => 'show'
92 menu.push :label_overview, :controller => 'projects', :action => 'show'
93 menu.push :label_activity, :controller => 'projects', :action => 'activity'
93 menu.push :label_activity, :controller => 'projects', :action => 'activity'
94 menu.push :label_roadmap, :controller => 'projects', :action => 'roadmap'
94 menu.push :label_roadmap, :controller => 'projects', :action => 'roadmap'
95 menu.push :label_issue_plural, :controller => 'projects', :action => 'list_issues'
95 menu.push :label_issue_plural, { :controller => 'issues', :action => 'index' }, :param => :project_id
96 menu.push :label_news_plural, :controller => 'projects', :action => 'list_news'
96 menu.push :label_news_plural, :controller => 'projects', :action => 'list_news'
97 menu.push :label_document_plural, :controller => 'projects', :action => 'list_documents'
97 menu.push :label_document_plural, :controller => 'projects', :action => 'list_documents'
98 menu.push :label_wiki, { :controller => 'wiki', :action => 'index', :page => nil }, :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
98 menu.push :label_wiki, { :controller => 'wiki', :action => 'index', :page => nil }, :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
@@ -57,33 +57,6 class ProjectsControllerTest < Test::Unit::TestCase
57 assert_not_nil assigns(:grouped)
57 assert_not_nil assigns(:grouped)
58 end
58 end
59
59
60 def test_list_issues
61 get :list_issues, :id => 1
62 assert_response :success
63 assert_template 'list_issues'
64 assert_not_nil assigns(:issues)
65 end
66
67 def test_list_issues_with_filter
68 get :list_issues, :id => 1, :set_filter => 1
69 assert_response :success
70 assert_template 'list_issues'
71 assert_not_nil assigns(:issues)
72 end
73
74 def test_list_issues_reset_filter
75 post :list_issues, :id => 1
76 assert_response :success
77 assert_template 'list_issues'
78 assert_not_nil assigns(:issues)
79 end
80
81 def test_export_issues_csv
82 get :export_issues_csv, :id => 1
83 assert_response :success
84 assert_not_nil assigns(:issues)
85 end
86
87 def test_bulk_edit_issues
60 def test_bulk_edit_issues
88 @request.session[:user_id] = 2
61 @request.session[:user_id] = 2
89 # update issues priority
62 # update issues priority
@@ -150,7 +123,7 class ProjectsControllerTest < Test::Unit::TestCase
150 assert_response :success
123 assert_response :success
151 assert_template 'add_issue'
124 assert_template 'add_issue'
152 post :add_issue, :id => 1, :issue => {:tracker_id => 1, :subject => 'This is the test_add_issue issue', :description => 'This is the description', :priority_id => 5}
125 post :add_issue, :id => 1, :issue => {:tracker_id => 1, :subject => 'This is the test_add_issue issue', :description => 'This is the description', :priority_id => 5}
153 assert_redirected_to 'projects/list_issues'
126 assert_redirected_to 'projects/1/issues'
154 assert Issue.find_by_subject('This is the test_add_issue issue')
127 assert Issue.find_by_subject('This is the test_add_issue issue')
155 end
128 end
156
129
@@ -24,7 +24,7 class IssuesTest < ActionController::IntegrationTest
24 assert_kind_of Issue, issue
24 assert_kind_of Issue, issue
25
25
26 # check redirection
26 # check redirection
27 assert_redirected_to "projects/list_issues/1"
27 assert_redirected_to "projects/1/issues"
28 follow_redirect!
28 follow_redirect!
29 assert assigns(:issues).include?(issue)
29 assert assigns(:issues).include?(issue)
30
30
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now