##// END OF EJS Templates
Refactor: convert VersionsController to a REST resource....
Eric Davis -
r3983:bd193a026df0
parent child
Show More
@@ -1,155 +1,155
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class VersionsController < ApplicationController
19 19 menu_item :roadmap
20 20 model_object Version
21 21 before_filter :find_model_object, :except => [:index, :new, :create, :close_completed]
22 22 before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed]
23 23 before_filter :find_project, :only => [:index, :new, :create, :close_completed]
24 24 before_filter :authorize
25 25
26 26 helper :custom_fields
27 27 helper :projects
28 28
29 29 def index
30 30 @trackers = @project.trackers.find(:all, :order => 'position')
31 31 retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
32 32 @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
33 33 project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id]
34 34
35 35 @versions = @project.shared_versions || []
36 36 @versions += @project.rolled_up_versions.visible if @with_subprojects
37 37 @versions = @versions.uniq.sort
38 38 @versions.reject! {|version| version.closed? || version.completed? } unless params[:completed]
39 39
40 40 @issues_by_version = {}
41 41 unless @selected_tracker_ids.empty?
42 42 @versions.each do |version|
43 43 issues = version.fixed_issues.visible.find(:all,
44 44 :include => [:project, :status, :tracker, :priority],
45 45 :conditions => {:tracker_id => @selected_tracker_ids, :project_id => project_ids},
46 46 :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id")
47 47 @issues_by_version[version] = issues
48 48 end
49 49 end
50 50 @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?}
51 51 end
52 52
53 53 def show
54 54 @issues = @version.fixed_issues.visible.find(:all,
55 55 :include => [:status, :tracker, :priority],
56 56 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id")
57 57 end
58 58
59 59 def new
60 60 @version = @project.versions.build
61 61 if params[:version]
62 62 attributes = params[:version].dup
63 63 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
64 64 @version.attributes = attributes
65 65 end
66 66 end
67 67
68 68 def create
69 69 # TODO: refactor with code above in #new
70 70 @version = @project.versions.build
71 71 if params[:version]
72 72 attributes = params[:version].dup
73 73 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
74 74 @version.attributes = attributes
75 75 end
76 76
77 77 if request.post?
78 78 if @version.save
79 79 respond_to do |format|
80 80 format.html do
81 81 flash[:notice] = l(:notice_successful_create)
82 82 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
83 83 end
84 84 format.js do
85 85 # IE doesn't support the replace_html rjs method for select box options
86 86 render(:update) {|page| page.replace "issue_fixed_version_id",
87 87 content_tag('select', '<option></option>' + version_options_for_select(@project.shared_versions.open, @version), :id => 'issue_fixed_version_id', :name => 'issue[fixed_version_id]')
88 88 }
89 89 end
90 90 end
91 91 else
92 92 respond_to do |format|
93 93 format.html { render :action => 'new' }
94 94 format.js do
95 95 render(:update) {|page| page.alert(@version.errors.full_messages.join('\n')) }
96 96 end
97 97 end
98 98 end
99 99 end
100 100 end
101 101
102 102 def edit
103 103 end
104 104
105 105 def update
106 if request.post? && params[:version]
106 if request.put? && params[:version]
107 107 attributes = params[:version].dup
108 108 attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
109 109 if @version.update_attributes(attributes)
110 110 flash[:notice] = l(:notice_successful_update)
111 111 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
112 112 end
113 113 end
114 114 end
115 115
116 116 def close_completed
117 if request.post?
117 if request.put?
118 118 @project.close_completed_versions
119 119 end
120 120 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
121 121 end
122 122
123 123 def destroy
124 124 if @version.fixed_issues.empty?
125 125 @version.destroy
126 126 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
127 127 else
128 128 flash[:error] = l(:notice_unable_delete_version)
129 129 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
130 130 end
131 131 end
132 132
133 133 def status_by
134 134 respond_to do |format|
135 135 format.html { render :action => 'show' }
136 136 format.js { render(:update) {|page| page.replace_html 'status_by', render_issue_status_by(@version, params[:status_by])} }
137 137 end
138 138 end
139 139
140 140 private
141 141 def find_project
142 142 @project = Project.find(params[:project_id])
143 143 rescue ActiveRecord::RecordNotFound
144 144 render_404
145 145 end
146 146
147 147 def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil)
148 148 if ids = params[:tracker_ids]
149 149 @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
150 150 else
151 151 @selected_tracker_ids = (default_trackers || selectable_trackers).collect {|t| t.id.to_s }
152 152 end
153 153 end
154 154
155 155 end
@@ -1,41 +1,41
1 1 <% if @project.shared_versions.any? %>
2 2 <table class="list versions">
3 3 <thead><tr>
4 4 <th><%= l(:label_version) %></th>
5 5 <th><%= l(:field_effective_date) %></th>
6 6 <th><%= l(:field_description) %></th>
7 7 <th><%= l(:field_status) %></th>
8 8 <th><%= l(:field_sharing) %></th>
9 9 <th><%= l(:label_wiki_page) unless @project.wiki.nil? %></th>
10 10 <th style="width:15%"></th>
11 11 </tr></thead>
12 12 <tbody>
13 13 <% for version in @project.shared_versions.sort %>
14 14 <tr class="version <%= cycle 'odd', 'even' %> <%=h version.status %> <%= 'shared' if version.project != @project %>">
15 15 <td class="name"><%= link_to_version version %></td>
16 16 <td class="date"><%= format_date(version.effective_date) %></td>
17 17 <td class="description"><%=h version.description %></td>
18 18 <td class="status"><%= l("version_status_#{version.status}") %></td>
19 19 <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
20 20 <td><%= link_to(h(version.wiki_page_title), :controller => 'wiki', :page => Wiki.titleize(version.wiki_page_title)) unless version.wiki_page_title.blank? || @project.wiki.nil? %></td>
21 21 <td class="buttons">
22 22 <% if version.project == @project %>
23 23 <%= link_to_if_authorized l(:button_edit), {:controller => 'versions', :action => 'edit', :id => version }, :class => 'icon icon-edit' %>
24 <%= link_to_if_authorized l(:button_delete), {:controller => 'versions', :action => 'destroy', :id => version}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
24 <%= link_to_if_authorized l(:button_delete), {:controller => 'versions', :action => 'destroy', :id => version}, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
25 25 <% end %>
26 26 </td>
27 27 </tr>
28 28 <% end; reset_cycle %>
29 29 </tbody>
30 30 </table>
31 31 <% else %>
32 32 <p class="nodata"><%= l(:label_no_data) %></p>
33 33 <% end %>
34 34
35 35 <div class="contextual">
36 36 <% if @project.versions.any? %>
37 <%= link_to l(:label_close_versions), {:controller => 'versions', :action => 'close_completed', :project_id => @project}, :method => :post %>
37 <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %>
38 38 <% end %>
39 39 </div>
40 40
41 41 <p><%= link_to_if_authorized l(:label_version_new), :controller => 'versions', :action => 'new', :project_id => @project %></p>
@@ -1,7 +1,7
1 1 <h2><%=l(:label_version)%></h2>
2 2
3 <% labelled_tabular_form_for :version, @version, :url => { :action => 'update', :id => @version } do |f| %>
3 <% labelled_tabular_form_for :version, @version, :url => project_version_path(@project, @version), :html => {:method => :put} do |f| %>
4 4 <%= render :partial => 'form', :locals => { :f => f } %>
5 5 <%= submit_tag l(:button_save) %>
6 6 <% end %>
7 7
@@ -1,6 +1,6
1 1 <h2><%=l(:label_version_new)%></h2>
2 2
3 <% labelled_tabular_form_for :version, @version, :url => { :action => 'create', :project_id => @project } do |f| %>
3 <% labelled_tabular_form_for :version, @version, :url => project_versions_path(@project) do |f| %>
4 4 <%= render :partial => 'versions/form', :locals => { :f => f } %>
5 5 <%= submit_tag l(:button_create) %>
6 6 <% end %>
@@ -1,276 +1,269
1 1 ActionController::Routing::Routes.draw do |map|
2 2 # Add your own custom routes here.
3 3 # The priority is based upon order of creation: first created -> highest priority.
4 4
5 5 # Here's a sample route:
6 6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 7 # Keep in mind you can assign values other than :controller and :action
8 8
9 9 map.home '', :controller => 'welcome'
10 10
11 11 map.signin 'login', :controller => 'account', :action => 'login'
12 12 map.signout 'logout', :controller => 'account', :action => 'logout'
13 13
14 14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
15 15 map.connect 'help/:ctrl/:page', :controller => 'help'
16 16
17 17 map.connect 'time_entries/:id/edit', :action => 'edit', :controller => 'timelog'
18 18 map.connect 'projects/:project_id/time_entries/new', :action => 'edit', :controller => 'timelog'
19 19 map.connect 'projects/:project_id/issues/:issue_id/time_entries/new', :action => 'edit', :controller => 'timelog'
20 20
21 21 map.with_options :controller => 'timelog' do |timelog|
22 22 timelog.connect 'projects/:project_id/time_entries', :action => 'details'
23 23
24 24 timelog.with_options :action => 'details', :conditions => {:method => :get} do |time_details|
25 25 time_details.connect 'time_entries'
26 26 time_details.connect 'time_entries.:format'
27 27 time_details.connect 'issues/:issue_id/time_entries'
28 28 time_details.connect 'issues/:issue_id/time_entries.:format'
29 29 time_details.connect 'projects/:project_id/time_entries.:format'
30 30 time_details.connect 'projects/:project_id/issues/:issue_id/time_entries'
31 31 time_details.connect 'projects/:project_id/issues/:issue_id/time_entries.:format'
32 32 end
33 33 timelog.connect 'projects/:project_id/time_entries/report', :action => 'report'
34 34 timelog.with_options :action => 'report',:conditions => {:method => :get} do |time_report|
35 35 time_report.connect 'time_entries/report'
36 36 time_report.connect 'time_entries/report.:format'
37 37 time_report.connect 'projects/:project_id/time_entries/report.:format'
38 38 end
39 39
40 40 timelog.with_options :action => 'edit', :conditions => {:method => :get} do |time_edit|
41 41 time_edit.connect 'issues/:issue_id/time_entries/new'
42 42 end
43 43
44 44 timelog.connect 'time_entries/:id/destroy', :action => 'destroy', :conditions => {:method => :post}
45 45 end
46 46
47 47 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
48 48 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
49 49 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
50 50 map.with_options :controller => 'wiki' do |wiki_routes|
51 51 wiki_routes.with_options :conditions => {:method => :get} do |wiki_views|
52 52 wiki_views.connect 'projects/:id/wiki/:page', :action => 'special', :page => /page_index|date_index|export/i
53 53 wiki_views.connect 'projects/:id/wiki/:page', :action => 'index', :page => nil
54 54 wiki_views.connect 'projects/:id/wiki/:page/edit', :action => 'edit'
55 55 wiki_views.connect 'projects/:id/wiki/:page/rename', :action => 'rename'
56 56 wiki_views.connect 'projects/:id/wiki/:page/history', :action => 'history'
57 57 wiki_views.connect 'projects/:id/wiki/:page/diff/:version/vs/:version_from', :action => 'diff'
58 58 wiki_views.connect 'projects/:id/wiki/:page/annotate/:version', :action => 'annotate'
59 59 end
60 60
61 61 wiki_routes.connect 'projects/:id/wiki/:page/:action',
62 62 :action => /edit|rename|destroy|preview|protect/,
63 63 :conditions => {:method => :post}
64 64 end
65 65
66 66 map.with_options :controller => 'messages' do |messages_routes|
67 67 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
68 68 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
69 69 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
70 70 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
71 71 end
72 72 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
73 73 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
74 74 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
75 75 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
76 76 end
77 77 end
78 78
79 79 map.with_options :controller => 'boards' do |board_routes|
80 80 board_routes.with_options :conditions => {:method => :get} do |board_views|
81 81 board_views.connect 'projects/:project_id/boards', :action => 'index'
82 82 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
83 83 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
84 84 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
85 85 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
86 86 end
87 87 board_routes.with_options :conditions => {:method => :post} do |board_actions|
88 88 board_actions.connect 'projects/:project_id/boards', :action => 'new'
89 89 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
90 90 end
91 91 end
92 92
93 93 map.with_options :controller => 'documents' do |document_routes|
94 94 document_routes.with_options :conditions => {:method => :get} do |document_views|
95 95 document_views.connect 'projects/:project_id/documents', :action => 'index'
96 96 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
97 97 document_views.connect 'documents/:id', :action => 'show'
98 98 document_views.connect 'documents/:id/edit', :action => 'edit'
99 99 end
100 100 document_routes.with_options :conditions => {:method => :post} do |document_actions|
101 101 document_actions.connect 'projects/:project_id/documents', :action => 'new'
102 102 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
103 103 end
104 104 end
105 105
106 106 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
107 107
108 108 # Misc issue routes. TODO: move into resources
109 109 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
110 110 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
111 111 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
112 112 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
113 113 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
114 114 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
115 115 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
116 116 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
117 117
118 118 map.resource :gantt, :path_prefix => '/issues', :controller => 'gantts', :only => [:show, :update]
119 119 map.resource :gantt, :path_prefix => '/projects/:project_id/issues', :controller => 'gantts', :only => [:show, :update]
120 120 map.resource :calendar, :path_prefix => '/issues', :controller => 'calendars', :only => [:show, :update]
121 121 map.resource :calendar, :path_prefix => '/projects/:project_id/issues', :controller => 'calendars', :only => [:show, :update]
122 122
123 123 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
124 124 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
125 125 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
126 126 end
127 127
128 128 # Following two routes conflict with the resources because #index allows POST
129 129 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
130 130 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
131 131
132 132 map.resources :issues, :member => { :edit => :post }, :collection => {}
133 133 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post }
134 134
135 135 map.with_options :controller => 'issue_relations', :conditions => {:method => :post} do |relations|
136 136 relations.connect 'issues/:issue_id/relations/:id', :action => 'new'
137 137 relations.connect 'issues/:issue_id/relations/:id/destroy', :action => 'destroy'
138 138 end
139 139
140 140 map.with_options :controller => 'news' do |news_routes|
141 141 news_routes.with_options :conditions => {:method => :get} do |news_views|
142 142 news_views.connect 'news', :action => 'index'
143 143 news_views.connect 'projects/:project_id/news', :action => 'index'
144 144 news_views.connect 'projects/:project_id/news.:format', :action => 'index'
145 145 news_views.connect 'news.:format', :action => 'index'
146 146 news_views.connect 'projects/:project_id/news/new', :action => 'new'
147 147 news_views.connect 'news/:id', :action => 'show'
148 148 news_views.connect 'news/:id/edit', :action => 'edit'
149 149 end
150 150 news_routes.with_options do |news_actions|
151 151 news_actions.connect 'projects/:project_id/news', :action => 'new'
152 152 news_actions.connect 'news/:id/edit', :action => 'edit'
153 153 news_actions.connect 'news/:id/destroy', :action => 'destroy'
154 154 end
155 155 end
156 156
157 157 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
158 158
159 159 map.with_options :controller => 'users' do |users|
160 160 users.with_options :conditions => {:method => :get} do |user_views|
161 161 user_views.connect 'users', :action => 'index'
162 162 user_views.connect 'users/:id', :action => 'show', :id => /\d+/
163 163 user_views.connect 'users/new', :action => 'add'
164 164 user_views.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil
165 165 end
166 166 users.with_options :conditions => {:method => :post} do |user_actions|
167 167 user_actions.connect 'users', :action => 'add'
168 168 user_actions.connect 'users/new', :action => 'add'
169 169 user_actions.connect 'users/:id/edit', :action => 'edit'
170 170 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
171 171 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
172 172 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
173 173 end
174 174 end
175 175
176 # For nice "roadmap" in the url for the index action
177 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
178
176 179 map.resources :projects, :member => {
177 180 :copy => [:get, :post],
178 181 :settings => :get,
179 182 :modules => :post,
180 183 :archive => :post,
181 184 :unarchive => :post
182 185 } do |project|
183 186 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
184 187 project.resources :files, :only => [:index, :new, :create]
188 project.resources :versions, :collection => {:close_completed => :put}
185 189 end
186 190
187 191 # Destroy uses a get request to prompt the user before the actual DELETE request
188 192 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
189 193
190 194 # TODO: port to be part of the resources route(s)
191 195 map.with_options :controller => 'projects' do |project_mapper|
192 196 project_mapper.with_options :conditions => {:method => :get} do |project_views|
193 197 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
194 198 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
195 199 end
196 200 end
197 201
198 202 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
199 203 activity.connect 'projects/:id/activity'
200 204 activity.connect 'projects/:id/activity.:format'
201 205 activity.connect 'activity', :id => nil
202 206 activity.connect 'activity.:format', :id => nil
203 207 end
208
204 209
205 map.with_options :controller => 'versions' do |versions|
206 versions.connect 'projects/:project_id/versions/new', :action => 'new'
207 versions.connect 'projects/:project_id/roadmap', :action => 'index'
208 versions.connect 'versions/:action/:id', :conditions => {:method => :get}
209
210 versions.with_options :conditions => {:method => :post} do |version_actions|
211 version_actions.connect 'projects/:project_id/versions', :action => 'create'
212 version_actions.connect 'versions/update/:id', :action => 'update'
213 version_actions.connect 'projects/:project_id/versions/close_completed', :action => 'close_completed'
214 end
215 end
216
217 210 map.with_options :controller => 'issue_categories' do |categories|
218 211 categories.connect 'projects/:project_id/issue_categories/new', :action => 'new'
219 212 end
220 213
221 214 map.with_options :controller => 'repositories' do |repositories|
222 215 repositories.with_options :conditions => {:method => :get} do |repository_views|
223 216 repository_views.connect 'projects/:id/repository', :action => 'show'
224 217 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
225 218 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
226 219 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
227 220 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
228 221 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
229 222 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
230 223 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
231 224 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
232 225 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
233 226 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
234 227 # TODO: why the following route is required?
235 228 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
236 229 repository_views.connect 'projects/:id/repository/:action/*path'
237 230 end
238 231
239 232 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
240 233 end
241 234
242 235 map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/
243 236 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
244 237 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
245 238
246 239 map.resources :groups
247 240
248 241 #left old routes at the bottom for backwards compat
249 242 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
250 243 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
251 244 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
252 245 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
253 246 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
254 247 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
255 248 map.connect 'projects/:project_id/news/:action', :controller => 'news'
256 249 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
257 250 map.with_options :controller => 'repositories' do |omap|
258 251 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
259 252 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
260 253 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
261 254 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
262 255 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
263 256 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
264 257 end
265 258
266 259 map.with_options :controller => 'sys' do |sys|
267 260 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
268 261 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
269 262 end
270 263
271 264 # Install the default route as the lowest priority.
272 265 map.connect ':controller/:action/:id'
273 266 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
274 267 # Used for OpenID
275 268 map.root :controller => 'account', :action => 'login'
276 269 end
@@ -1,139 +1,139
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.dirname(__FILE__) + '/../test_helper'
19 19 require 'versions_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class VersionsController; def rescue_action(e) raise e end; end
23 23
24 24 class VersionsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :versions, :issues, :users, :roles, :members, :member_roles, :enabled_modules
26 26
27 27 def setup
28 28 @controller = VersionsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_index
35 35 get :index, :project_id => 1
36 36 assert_response :success
37 37 assert_template 'index'
38 38 assert_not_nil assigns(:versions)
39 39 # Version with no date set appears
40 40 assert assigns(:versions).include?(Version.find(3))
41 41 # Completed version doesn't appear
42 42 assert !assigns(:versions).include?(Version.find(1))
43 43 # Context menu on issues
44 44 assert_select "script", :text => Regexp.new(Regexp.escape("new ContextMenu('/issues/context_menu')"))
45 45 end
46 46
47 47 def test_index_with_completed_versions
48 48 get :index, :project_id => 1, :completed => 1
49 49 assert_response :success
50 50 assert_template 'index'
51 51 assert_not_nil assigns(:versions)
52 52 # Version with no date set appears
53 53 assert assigns(:versions).include?(Version.find(3))
54 54 # Completed version appears
55 55 assert assigns(:versions).include?(Version.find(1))
56 56 end
57 57
58 58 def test_index_showing_subprojects_versions
59 59 @subproject_version = Version.generate!(:project => Project.find(3))
60 60 get :index, :project_id => 1, :with_subprojects => 1
61 61 assert_response :success
62 62 assert_template 'index'
63 63 assert_not_nil assigns(:versions)
64 64
65 65 assert assigns(:versions).include?(Version.find(4)), "Shared version not found"
66 66 assert assigns(:versions).include?(@subproject_version), "Subproject version not found"
67 67 end
68 68
69 69 def test_show
70 70 get :show, :id => 2
71 71 assert_response :success
72 72 assert_template 'show'
73 73 assert_not_nil assigns(:version)
74 74
75 75 assert_tag :tag => 'h2', :content => /1.0/
76 76 end
77 77
78 78 def test_create
79 79 @request.session[:user_id] = 2 # manager
80 80 assert_difference 'Version.count' do
81 81 post :create, :project_id => '1', :version => {:name => 'test_add_version'}
82 82 end
83 83 assert_redirected_to '/projects/ecookbook/settings/versions'
84 84 version = Version.find_by_name('test_add_version')
85 85 assert_not_nil version
86 86 assert_equal 1, version.project_id
87 87 end
88 88
89 89 def test_create_from_issue_form
90 90 @request.session[:user_id] = 2 # manager
91 91 assert_difference 'Version.count' do
92 92 xhr :post, :create, :project_id => '1', :version => {:name => 'test_add_version_from_issue_form'}
93 93 end
94 94 assert_response :success
95 95 assert_select_rjs :replace, 'issue_fixed_version_id'
96 96 version = Version.find_by_name('test_add_version_from_issue_form')
97 97 assert_not_nil version
98 98 assert_equal 1, version.project_id
99 99 end
100 100
101 101 def test_get_edit
102 102 @request.session[:user_id] = 2
103 103 get :edit, :id => 2
104 104 assert_response :success
105 105 assert_template 'edit'
106 106 end
107 107
108 108 def test_close_completed
109 109 Version.update_all("status = 'open'")
110 110 @request.session[:user_id] = 2
111 post :close_completed, :project_id => 'ecookbook'
111 put :close_completed, :project_id => 'ecookbook'
112 112 assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
113 113 assert_not_nil Version.find_by_status('closed')
114 114 end
115 115
116 116 def test_post_update
117 117 @request.session[:user_id] = 2
118 post :update, :id => 2,
118 put :update, :id => 2,
119 119 :version => { :name => 'New version name',
120 120 :effective_date => Date.today.strftime("%Y-%m-%d")}
121 121 assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
122 122 version = Version.find(2)
123 123 assert_equal 'New version name', version.name
124 124 assert_equal Date.today, version.effective_date
125 125 end
126 126
127 127 def test_destroy
128 128 @request.session[:user_id] = 2
129 post :destroy, :id => 3
129 delete :destroy, :id => 3
130 130 assert_redirected_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => 'ecookbook'
131 131 assert_nil Version.find_by_id(3)
132 132 end
133 133
134 134 def test_issue_status_by
135 135 xhr :get, :status_by, :id => 2
136 136 assert_response :success
137 137 assert_template '_issue_counts'
138 138 end
139 139 end
General Comments 0
You need to be logged in to leave comments. Login now