##// END OF EJS Templates
Enable ability for administrators to delete users (#7296)....
Jean-Philippe Lang -
r4609:e9f62d1209bf
parent child
Show More
@@ -1,225 +1,234
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 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 UsersController < ApplicationController
19 19 layout 'admin'
20 20
21 21 before_filter :require_admin, :except => :show
22 before_filter :find_user, :only => [:show, :edit, :update, :edit_membership, :destroy_membership]
23 accept_key_auth :index, :show, :create, :update
22 before_filter :find_user, :only => [:show, :edit, :update, :destroy, :edit_membership, :destroy_membership]
23 accept_key_auth :index, :show, :create, :update, :destroy
24 24
25 25 helper :sort
26 26 include SortHelper
27 27 helper :custom_fields
28 28 include CustomFieldsHelper
29 29
30 30 def index
31 31 sort_init 'login', 'asc'
32 32 sort_update %w(login firstname lastname mail admin created_on last_login_on)
33 33
34 34 case params[:format]
35 35 when 'xml', 'json'
36 36 @offset, @limit = api_offset_and_limit
37 37 else
38 38 @limit = per_page_option
39 39 end
40 40
41 41 @status = params[:status] ? params[:status].to_i : 1
42 42 c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status])
43 43
44 44 unless params[:name].blank?
45 45 name = "%#{params[:name].strip.downcase}%"
46 46 c << ["LOWER(login) LIKE ? OR LOWER(firstname) LIKE ? OR LOWER(lastname) LIKE ? OR LOWER(mail) LIKE ?", name, name, name, name]
47 47 end
48 48
49 49 @user_count = User.count(:conditions => c.conditions)
50 50 @user_pages = Paginator.new self, @user_count, @limit, params['page']
51 51 @offset ||= @user_pages.current.offset
52 52 @users = User.find :all,
53 53 :order => sort_clause,
54 54 :conditions => c.conditions,
55 55 :limit => @limit,
56 56 :offset => @offset
57 57
58 58 respond_to do |format|
59 59 format.html { render :layout => !request.xhr? }
60 60 format.api
61 61 end
62 62 end
63 63
64 64 def show
65 65 # show projects based on current user visibility
66 66 @memberships = @user.memberships.all(:conditions => Project.visible_by(User.current))
67 67
68 68 events = Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 10)
69 69 @events_by_day = events.group_by(&:event_date)
70 70
71 71 unless User.current.admin?
72 72 if !@user.active? || (@user != User.current && @memberships.empty? && events.empty?)
73 73 render_404
74 74 return
75 75 end
76 76 end
77 77
78 78 respond_to do |format|
79 79 format.html { render :layout => 'base' }
80 80 format.api
81 81 end
82 82 end
83 83
84 84 def new
85 85 @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
86 86 @auth_sources = AuthSource.find(:all)
87 87 end
88 88
89 89 verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
90 90 def create
91 91 @user = User.new(:language => Setting.default_language, :mail_notification => Setting.default_notification_option)
92 92 @user.safe_attributes = params[:user]
93 93 @user.admin = params[:user][:admin] || false
94 94 @user.login = params[:user][:login]
95 95 @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation] unless @user.auth_source_id
96 96
97 97 # TODO: Similar to My#account
98 98 @user.pref.attributes = params[:pref]
99 99 @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
100 100
101 101 if @user.save
102 102 @user.pref.save
103 103 @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
104 104
105 105 Mailer.deliver_account_information(@user, params[:user][:password]) if params[:send_information]
106 106
107 107 respond_to do |format|
108 108 format.html {
109 109 flash[:notice] = l(:notice_successful_create)
110 110 redirect_to(params[:continue] ?
111 111 {:controller => 'users', :action => 'new'} :
112 112 {:controller => 'users', :action => 'edit', :id => @user}
113 113 )
114 114 }
115 115 format.api { render :action => 'show', :status => :created, :location => user_url(@user) }
116 116 end
117 117 else
118 118 @auth_sources = AuthSource.find(:all)
119 119 # Clear password input
120 120 @user.password = @user.password_confirmation = nil
121 121
122 122 respond_to do |format|
123 123 format.html { render :action => 'new' }
124 124 format.api { render_validation_errors(@user) }
125 125 end
126 126 end
127 127 end
128 128
129 129 def edit
130 130 @auth_sources = AuthSource.find(:all)
131 131 @membership ||= Member.new
132 132 end
133 133
134 134 verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
135 135 def update
136 136 @user.admin = params[:user][:admin] if params[:user][:admin]
137 137 @user.login = params[:user][:login] if params[:user][:login]
138 138 if params[:user][:password].present? && (@user.auth_source_id.nil? || params[:user][:auth_source_id].blank?)
139 139 @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation]
140 140 end
141 141 @user.safe_attributes = params[:user]
142 142 # Was the account actived ? (do it before User#save clears the change)
143 143 was_activated = (@user.status_change == [User::STATUS_REGISTERED, User::STATUS_ACTIVE])
144 144 # TODO: Similar to My#account
145 145 @user.pref.attributes = params[:pref]
146 146 @user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
147 147
148 148 if @user.save
149 149 @user.pref.save
150 150 @user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
151 151
152 152 if was_activated
153 153 Mailer.deliver_account_activated(@user)
154 154 elsif @user.active? && params[:send_information] && !params[:user][:password].blank? && @user.auth_source_id.nil?
155 155 Mailer.deliver_account_information(@user, params[:user][:password])
156 156 end
157 157
158 158 respond_to do |format|
159 159 format.html {
160 160 flash[:notice] = l(:notice_successful_update)
161 161 redirect_to :back
162 162 }
163 163 format.api { head :ok }
164 164 end
165 165 else
166 166 @auth_sources = AuthSource.find(:all)
167 167 @membership ||= Member.new
168 168 # Clear password input
169 169 @user.password = @user.password_confirmation = nil
170 170
171 171 respond_to do |format|
172 172 format.html { render :action => :edit }
173 173 format.api { render_validation_errors(@user) }
174 174 end
175 175 end
176 176 rescue ::ActionController::RedirectBackError
177 177 redirect_to :controller => 'users', :action => 'edit', :id => @user
178 178 end
179 179
180 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
181 def destroy
182 @user.destroy
183 respond_to do |format|
184 format.html { redirect_to(users_url) }
185 format.api { head :ok }
186 end
187 end
188
180 189 def edit_membership
181 190 @membership = Member.edit_membership(params[:membership_id], params[:membership], @user)
182 191 @membership.save if request.post?
183 192 respond_to do |format|
184 193 if @membership.valid?
185 194 format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
186 195 format.js {
187 196 render(:update) {|page|
188 197 page.replace_html "tab-content-memberships", :partial => 'users/memberships'
189 198 page.visual_effect(:highlight, "member-#{@membership.id}")
190 199 }
191 200 }
192 201 else
193 202 format.js {
194 203 render(:update) {|page|
195 204 page.alert(l(:notice_failed_to_save_members, :errors => @membership.errors.full_messages.join(', ')))
196 205 }
197 206 }
198 207 end
199 208 end
200 209 end
201 210
202 211 def destroy_membership
203 212 @membership = Member.find(params[:membership_id])
204 213 if request.post? && @membership.deletable?
205 214 @membership.destroy
206 215 end
207 216 respond_to do |format|
208 217 format.html { redirect_to :controller => 'users', :action => 'edit', :id => @user, :tab => 'memberships' }
209 218 format.js { render(:update) {|page| page.replace_html "tab-content-memberships", :partial => 'users/memberships'} }
210 219 end
211 220 end
212 221
213 222 private
214 223
215 224 def find_user
216 225 if params[:id] == 'current'
217 226 require_login || return
218 227 @user = User.current
219 228 else
220 229 @user = User.find(params[:id])
221 230 end
222 231 rescue ActiveRecord::RecordNotFound
223 232 render_404
224 233 end
225 234 end
@@ -1,10 +1,11
1 1 <div class="contextual">
2 2 <%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
3 3 <%= change_status_link(@user) %>
4 <%= link_to(l(:button_delete), @user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current != @user %>
4 5 </div>
5 6
6 7 <h2><%= link_to l(:label_user_plural), :controller => 'users', :action => 'index' %> &#187; <%=h @user.login %></h2>
7 8
8 9 <%= render_tabs user_settings_tabs %>
9 10
10 11 <% html_title(l(:label_user), @user.login, l(:label_administration)) -%>
@@ -1,48 +1,51
1 1 <div class="contextual">
2 2 <%= link_to l(:label_user_new), {:action => 'new'}, :class => 'icon icon-add' %>
3 3 </div>
4 4
5 5 <h2><%=l(:label_user_plural)%></h2>
6 6
7 7 <% form_tag({}, :method => :get) do %>
8 8 <fieldset><legend><%= l(:label_filter_plural) %></legend>
9 9 <label><%= l(:field_status) %>:</label>
10 10 <%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
11 11 <label><%= l(:label_user) %>:</label>
12 12 <%= text_field_tag 'name', params[:name], :size => 30 %>
13 13 <%= submit_tag l(:button_apply), :class => "small", :name => nil %>
14 14 </fieldset>
15 15 <% end %>
16 16 &nbsp;
17 17
18 18 <div class="autoscroll">
19 19 <table class="list">
20 20 <thead><tr>
21 21 <%= sort_header_tag('login', :caption => l(:field_login)) %>
22 22 <%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
23 23 <%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
24 24 <%= sort_header_tag('mail', :caption => l(:field_mail)) %>
25 25 <%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
26 26 <%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
27 27 <%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
28 28 <th></th>
29 29 </tr></thead>
30 30 <tbody>
31 31 <% for user in @users -%>
32 32 <tr class="user <%= cycle("odd", "even") %> <%= %w(anon active registered locked)[user.status] %>">
33 33 <td class="username"><%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
34 34 <td class="firstname"><%= h(user.firstname) %></td>
35 35 <td class="lastname"><%= h(user.lastname) %></td>
36 36 <td class="email"><%= mail_to(h(user.mail)) %></td>
37 37 <td align="center"><%= checked_image user.admin? %></td>
38 38 <td class="created_on" align="center"><%= format_time(user.created_on) %></td>
39 39 <td class="last_login_on" align="center"><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
40 <td><small><%= change_status_link(user) %></small></td>
40 <td class="buttons">
41 <%= change_status_link(user) %>
42 <%= link_to(l(:button_delete), user, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') unless User.current == user %>
43 </td>
41 44 </tr>
42 45 <% end -%>
43 46 </tbody>
44 47 </table>
45 48 </div>
46 49 <p class="pagination"><%= pagination_links_full @user_pages, @user_count %></p>
47 50
48 51 <% html_title(l(:label_user_plural)) -%>
@@ -1,246 +1,245
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 'projects/:project_id/time_entries/report', :controller => 'time_entry_reports', :action => 'report'
18 18 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
19 19 time_report.connect 'time_entries/report'
20 20 time_report.connect 'time_entries/report.:format'
21 21 time_report.connect 'projects/:project_id/time_entries/report.:format'
22 22 end
23 23
24 24 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
25 25 map.resources :time_entries, :controller => 'timelog'
26 26
27 27 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
28 28 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
29 29 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
30 30
31 31 map.with_options :controller => 'messages' do |messages_routes|
32 32 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
33 33 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
34 34 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
35 35 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
36 36 end
37 37 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
38 38 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
39 39 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
40 40 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
41 41 end
42 42 end
43 43
44 44 map.with_options :controller => 'boards' do |board_routes|
45 45 board_routes.with_options :conditions => {:method => :get} do |board_views|
46 46 board_views.connect 'projects/:project_id/boards', :action => 'index'
47 47 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
48 48 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
49 49 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
50 50 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
51 51 end
52 52 board_routes.with_options :conditions => {:method => :post} do |board_actions|
53 53 board_actions.connect 'projects/:project_id/boards', :action => 'new'
54 54 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
55 55 end
56 56 end
57 57
58 58 map.with_options :controller => 'documents' do |document_routes|
59 59 document_routes.with_options :conditions => {:method => :get} do |document_views|
60 60 document_views.connect 'projects/:project_id/documents', :action => 'index'
61 61 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
62 62 document_views.connect 'documents/:id', :action => 'show'
63 63 document_views.connect 'documents/:id/edit', :action => 'edit'
64 64 end
65 65 document_routes.with_options :conditions => {:method => :post} do |document_actions|
66 66 document_actions.connect 'projects/:project_id/documents', :action => 'new'
67 67 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
68 68 end
69 69 end
70 70
71 71 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
72 72
73 73 # Misc issue routes. TODO: move into resources
74 74 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
75 75 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
76 76 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
77 77 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
78 78 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
79 79 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
80 80 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
81 81 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
82 82
83 83 map.resource :gantt, :path_prefix => '/issues', :controller => 'gantts', :only => [:show, :update]
84 84 map.resource :gantt, :path_prefix => '/projects/:project_id/issues', :controller => 'gantts', :only => [:show, :update]
85 85 map.resource :calendar, :path_prefix => '/issues', :controller => 'calendars', :only => [:show, :update]
86 86 map.resource :calendar, :path_prefix => '/projects/:project_id/issues', :controller => 'calendars', :only => [:show, :update]
87 87
88 88 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
89 89 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
90 90 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
91 91 end
92 92
93 93 # Following two routes conflict with the resources because #index allows POST
94 94 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
95 95 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
96 96
97 97 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
98 98 issues.resources :time_entries, :controller => 'timelog'
99 99 end
100 100
101 101 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
102 102 issues.resources :time_entries, :controller => 'timelog'
103 103 end
104 104
105 105 map.with_options :controller => 'issue_relations', :conditions => {:method => :post} do |relations|
106 106 relations.connect 'issues/:issue_id/relations/:id', :action => 'new'
107 107 relations.connect 'issues/:issue_id/relations/:id/destroy', :action => 'destroy'
108 108 end
109 109
110 110 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
111 111
112 112 map.with_options :controller => 'users' do |users|
113 113 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
114 114
115 115 users.with_options :conditions => {:method => :post} do |user_actions|
116 116 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
117 117 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
118 118 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
119 119 end
120 120 end
121 121
122 122 map.resources :users, :member => {
123 123 :edit_membership => :post,
124 124 :destroy_membership => :post
125 },
126 :except => [:destroy]
125 }
127 126
128 127 # For nice "roadmap" in the url for the index action
129 128 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
130 129
131 130 map.all_news 'news', :controller => 'news', :action => 'index'
132 131 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
133 132 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
134 133 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
135 134 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
136 135
137 136 map.resources :projects, :member => {
138 137 :copy => [:get, :post],
139 138 :settings => :get,
140 139 :modules => :post,
141 140 :archive => :post,
142 141 :unarchive => :post
143 142 } do |project|
144 143 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
145 144 project.resources :files, :only => [:index, :new, :create]
146 145 project.resources :versions, :collection => {:close_completed => :put}, :member => {:status_by => :post}
147 146 project.resources :news, :shallow => true
148 147 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
149 148
150 149 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
151 150 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
152 151 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
153 152 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
154 153 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
155 154 project.resources :wiki, :except => [:new, :create], :member => {
156 155 :rename => [:get, :post],
157 156 :history => :get,
158 157 :preview => :any,
159 158 :protect => :post,
160 159 :add_attachment => :post
161 160 }, :collection => {
162 161 :export => :get,
163 162 :date_index => :get
164 163 }
165 164
166 165 end
167 166
168 167 # Destroy uses a get request to prompt the user before the actual DELETE request
169 168 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
170 169
171 170 # TODO: port to be part of the resources route(s)
172 171 map.with_options :controller => 'projects' do |project_mapper|
173 172 project_mapper.with_options :conditions => {:method => :get} do |project_views|
174 173 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
175 174 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
176 175 end
177 176 end
178 177
179 178 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
180 179 activity.connect 'projects/:id/activity'
181 180 activity.connect 'projects/:id/activity.:format'
182 181 activity.connect 'activity', :id => nil
183 182 activity.connect 'activity.:format', :id => nil
184 183 end
185 184
186 185
187 186 map.with_options :controller => 'issue_categories' do |categories|
188 187 categories.connect 'projects/:project_id/issue_categories/new', :action => 'new'
189 188 end
190 189
191 190 map.with_options :controller => 'repositories' do |repositories|
192 191 repositories.with_options :conditions => {:method => :get} do |repository_views|
193 192 repository_views.connect 'projects/:id/repository', :action => 'show'
194 193 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
195 194 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
196 195 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
197 196 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
198 197 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
199 198 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
200 199 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
201 200 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
202 201 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
203 202 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
204 203 # TODO: why the following route is required?
205 204 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
206 205 repository_views.connect 'projects/:id/repository/:action/*path'
207 206 end
208 207
209 208 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
210 209 end
211 210
212 211 map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/
213 212 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
214 213 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
215 214
216 215 map.resources :groups
217 216
218 217 #left old routes at the bottom for backwards compat
219 218 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
220 219 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
221 220 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
222 221 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
223 222 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
224 223 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
225 224 map.connect 'projects/:project_id/news/:action', :controller => 'news'
226 225 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
227 226 map.with_options :controller => 'repositories' do |omap|
228 227 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
229 228 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
230 229 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
231 230 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
232 231 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
233 232 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
234 233 end
235 234
236 235 map.with_options :controller => 'sys' do |sys|
237 236 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
238 237 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
239 238 end
240 239
241 240 # Install the default route as the lowest priority.
242 241 map.connect ':controller/:action/:id'
243 242 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
244 243 # Used for OpenID
245 244 map.root :controller => 'account', :action => 'login'
246 245 end
@@ -1,279 +1,303
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.expand_path('../../test_helper', __FILE__)
19 19 require 'users_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class UsersController; def rescue_action(e) raise e end; end
23 23
24 24 class UsersControllerTest < ActionController::TestCase
25 25 include Redmine::I18n
26 26
27 27 fixtures :users, :projects, :members, :member_roles, :roles, :auth_sources, :custom_fields, :custom_values
28 28
29 29 def setup
30 30 @controller = UsersController.new
31 31 @request = ActionController::TestRequest.new
32 32 @response = ActionController::TestResponse.new
33 33 User.current = nil
34 34 @request.session[:user_id] = 1 # admin
35 35 end
36 36
37 37 def test_index
38 38 get :index
39 39 assert_response :success
40 40 assert_template 'index'
41 41 end
42 42
43 43 def test_index
44 44 get :index
45 45 assert_response :success
46 46 assert_template 'index'
47 47 assert_not_nil assigns(:users)
48 48 # active users only
49 49 assert_nil assigns(:users).detect {|u| !u.active?}
50 50 end
51 51
52 52 def test_index_with_name_filter
53 53 get :index, :name => 'john'
54 54 assert_response :success
55 55 assert_template 'index'
56 56 users = assigns(:users)
57 57 assert_not_nil users
58 58 assert_equal 1, users.size
59 59 assert_equal 'John', users.first.firstname
60 60 end
61 61
62 62 def test_show
63 63 @request.session[:user_id] = nil
64 64 get :show, :id => 2
65 65 assert_response :success
66 66 assert_template 'show'
67 67 assert_not_nil assigns(:user)
68 68
69 69 assert_tag 'li', :content => /Phone number/
70 70 end
71 71
72 72 def test_show_should_not_display_hidden_custom_fields
73 73 @request.session[:user_id] = nil
74 74 UserCustomField.find_by_name('Phone number').update_attribute :visible, false
75 75 get :show, :id => 2
76 76 assert_response :success
77 77 assert_template 'show'
78 78 assert_not_nil assigns(:user)
79 79
80 80 assert_no_tag 'li', :content => /Phone number/
81 81 end
82 82
83 83 def test_show_should_not_fail_when_custom_values_are_nil
84 84 user = User.find(2)
85 85
86 86 # Create a custom field to illustrate the issue
87 87 custom_field = CustomField.create!(:name => 'Testing', :field_format => 'text')
88 88 custom_value = user.custom_values.build(:custom_field => custom_field).save!
89 89
90 90 get :show, :id => 2
91 91 assert_response :success
92 92 end
93 93
94 94 def test_show_inactive
95 95 @request.session[:user_id] = nil
96 96 get :show, :id => 5
97 97 assert_response 404
98 98 end
99 99
100 100 def test_show_should_not_reveal_users_with_no_visible_activity_or_project
101 101 @request.session[:user_id] = nil
102 102 get :show, :id => 9
103 103 assert_response 404
104 104 end
105 105
106 106 def test_show_inactive_by_admin
107 107 @request.session[:user_id] = 1
108 108 get :show, :id => 5
109 109 assert_response 200
110 110 assert_not_nil assigns(:user)
111 111 end
112 112
113 113 def test_show_displays_memberships_based_on_project_visibility
114 114 @request.session[:user_id] = 1
115 115 get :show, :id => 2
116 116 assert_response :success
117 117 memberships = assigns(:memberships)
118 118 assert_not_nil memberships
119 119 project_ids = memberships.map(&:project_id)
120 120 assert project_ids.include?(2) #private project admin can see
121 121 end
122 122
123 123 def test_show_current_should_require_authentication
124 124 @request.session[:user_id] = nil
125 125 get :show, :id => 'current'
126 126 assert_response 302
127 127 end
128 128
129 129 def test_show_current
130 130 @request.session[:user_id] = 2
131 131 get :show, :id => 'current'
132 132 assert_response :success
133 133 assert_template 'show'
134 134 assert_equal User.find(2), assigns(:user)
135 135 end
136 136
137 137 def test_new
138 138 get :new
139 139
140 140 assert_response :success
141 141 assert_template :new
142 142 assert assigns(:user)
143 143 end
144 144
145 145 def test_create
146 146 Setting.bcc_recipients = '1'
147 147
148 148 assert_difference 'User.count' do
149 149 assert_difference 'ActionMailer::Base.deliveries.size' do
150 150 post :create,
151 151 :user => {
152 152 :firstname => 'John',
153 153 :lastname => 'Doe',
154 154 :login => 'jdoe',
155 155 :password => 'secret',
156 156 :password_confirmation => 'secret',
157 157 :mail => 'jdoe@gmail.com',
158 158 :mail_notification => 'none'
159 159 },
160 160 :send_information => '1'
161 161 end
162 162 end
163 163
164 164 user = User.first(:order => 'id DESC')
165 165 assert_redirected_to :controller => 'users', :action => 'edit', :id => user.id
166 166
167 167 assert_equal 'John', user.firstname
168 168 assert_equal 'Doe', user.lastname
169 169 assert_equal 'jdoe', user.login
170 170 assert_equal 'jdoe@gmail.com', user.mail
171 171 assert_equal 'none', user.mail_notification
172 172 assert user.check_password?('secret')
173 173
174 174 mail = ActionMailer::Base.deliveries.last
175 175 assert_not_nil mail
176 176 assert_equal [user.mail], mail.bcc
177 177 assert mail.body.include?('secret')
178 178 end
179 179
180 180 def test_create_with_failure
181 181 assert_no_difference 'User.count' do
182 182 post :create, :user => {}
183 183 end
184 184
185 185 assert_response :success
186 186 assert_template 'new'
187 187 end
188 188
189 189 def test_edit
190 190 get :edit, :id => 2
191 191
192 192 assert_response :success
193 193 assert_template 'edit'
194 194 assert_equal User.find(2), assigns(:user)
195 195 end
196 196
197 197 def test_update
198 198 ActionMailer::Base.deliveries.clear
199 199 put :update, :id => 2, :user => {:firstname => 'Changed', :mail_notification => 'only_assigned'}, :pref => {:hide_mail => '1', :comments_sorting => 'desc'}
200 200
201 201 user = User.find(2)
202 202 assert_equal 'Changed', user.firstname
203 203 assert_equal 'only_assigned', user.mail_notification
204 204 assert_equal true, user.pref[:hide_mail]
205 205 assert_equal 'desc', user.pref[:comments_sorting]
206 206 assert ActionMailer::Base.deliveries.empty?
207 207 end
208 208
209 209 def test_update_with_failure
210 210 assert_no_difference 'User.count' do
211 211 put :update, :id => 2, :user => {:firstname => ''}
212 212 end
213 213
214 214 assert_response :success
215 215 assert_template 'edit'
216 216 end
217 217
218 218 def test_update_with_group_ids_should_assign_groups
219 219 put :update, :id => 2, :user => {:group_ids => ['10']}
220 220
221 221 user = User.find(2)
222 222 assert_equal [10], user.group_ids
223 223 end
224 224
225 225 def test_update_with_activation_should_send_a_notification
226 226 u = User.new(:firstname => 'Foo', :lastname => 'Bar', :mail => 'foo.bar@somenet.foo', :language => 'fr')
227 227 u.login = 'foo'
228 228 u.status = User::STATUS_REGISTERED
229 229 u.save!
230 230 ActionMailer::Base.deliveries.clear
231 231 Setting.bcc_recipients = '1'
232 232
233 233 put :update, :id => u.id, :user => {:status => User::STATUS_ACTIVE}
234 234 assert u.reload.active?
235 235 mail = ActionMailer::Base.deliveries.last
236 236 assert_not_nil mail
237 237 assert_equal ['foo.bar@somenet.foo'], mail.bcc
238 238 assert mail.body.include?(ll('fr', :notice_account_activated))
239 239 end
240 240
241 241 def test_update_with_password_change_should_send_a_notification
242 242 ActionMailer::Base.deliveries.clear
243 243 Setting.bcc_recipients = '1'
244 244
245 245 put :update, :id => 2, :user => {:password => 'newpass', :password_confirmation => 'newpass'}, :send_information => '1'
246 246 u = User.find(2)
247 247 assert u.check_password?('newpass')
248 248
249 249 mail = ActionMailer::Base.deliveries.last
250 250 assert_not_nil mail
251 251 assert_equal [u.mail], mail.bcc
252 252 assert mail.body.include?('newpass')
253 253 end
254 254
255 255 test "put :update with a password change to an AuthSource user switching to Internal authentication" do
256 256 # Configure as auth source
257 257 u = User.find(2)
258 258 u.auth_source = AuthSource.find(1)
259 259 u.save!
260 260
261 261 put :update, :id => u.id, :user => {:auth_source_id => '', :password => 'newpass'}, :password_confirmation => 'newpass'
262 262
263 263 assert_equal nil, u.reload.auth_source
264 264 assert u.check_password?('newpass')
265 265 end
266 266
267 def test_destroy
268 assert_difference 'User.count', -1 do
269 delete :destroy, :id => 2
270 end
271 assert_redirected_to '/users'
272 assert_nil User.find_by_id(2)
273 end
274
275 def test_destroy_should_not_accept_get_requests
276 assert_no_difference 'User.count' do
277 get :destroy, :id => 2
278 end
279 assert_response 405
280 end
281
282 def test_destroy_should_be_denied_for_non_admin_users
283 @request.session[:user_id] = 3
284
285 assert_no_difference 'User.count' do
286 get :destroy, :id => 2
287 end
288 assert_response 403
289 end
290
267 291 def test_edit_membership
268 292 post :edit_membership, :id => 2, :membership_id => 1,
269 293 :membership => { :role_ids => [2]}
270 294 assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
271 295 assert_equal [2], Member.find(1).role_ids
272 296 end
273 297
274 298 def test_destroy_membership
275 299 post :destroy_membership, :id => 2, :membership_id => 1
276 300 assert_redirected_to :action => 'edit', :id => '2', :tab => 'memberships'
277 301 assert_nil Member.find_by_id(1)
278 302 end
279 303 end
@@ -1,275 +1,285
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 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.expand_path('../../../test_helper', __FILE__)
19 19 require 'pp'
20 20 class ApiTest::UsersTest < ActionController::IntegrationTest
21 21 fixtures :users
22 22
23 23 def setup
24 24 Setting.rest_api_enabled = '1'
25 25 end
26 26
27 27 context "GET /users" do
28 28 should_allow_api_authentication(:get, "/users.xml")
29 29 should_allow_api_authentication(:get, "/users.json")
30 30 end
31 31
32 32 context "GET /users/2" do
33 33 context ".xml" do
34 34 should "return requested user" do
35 35 get '/users/2.xml'
36 36
37 37 assert_tag :tag => 'user',
38 38 :child => {:tag => 'id', :content => '2'}
39 39 end
40 40 end
41 41
42 42 context ".json" do
43 43 should "return requested user" do
44 44 get '/users/2.json'
45 45
46 46 json = ActiveSupport::JSON.decode(response.body)
47 47 assert_kind_of Hash, json
48 48 assert_kind_of Hash, json['user']
49 49 assert_equal 2, json['user']['id']
50 50 end
51 51 end
52 52 end
53 53
54 54 context "GET /users/current" do
55 55 context ".xml" do
56 56 should "require authentication" do
57 57 get '/users/current.xml'
58 58
59 59 assert_response 401
60 60 end
61 61
62 62 should "return current user" do
63 63 get '/users/current.xml', {}, :authorization => credentials('jsmith')
64 64
65 65 assert_tag :tag => 'user',
66 66 :child => {:tag => 'id', :content => '2'}
67 67 end
68 68 end
69 69 end
70 70
71 71 context "POST /users" do
72 72 context "with valid parameters" do
73 73 setup do
74 74 @parameters = {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net', :password => 'secret', :mail_notification => 'only_assigned'}}
75 75 end
76 76
77 77 context ".xml" do
78 78 should_allow_api_authentication(:post,
79 79 '/users.xml',
80 80 {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net', :password => 'secret'}},
81 81 {:success_code => :created})
82 82
83 83 should "create a user with the attributes" do
84 84 assert_difference('User.count') do
85 85 post '/users.xml', @parameters, :authorization => credentials('admin')
86 86 end
87 87
88 88 user = User.first(:order => 'id DESC')
89 89 assert_equal 'foo', user.login
90 90 assert_equal 'Firstname', user.firstname
91 91 assert_equal 'Lastname', user.lastname
92 92 assert_equal 'foo@example.net', user.mail
93 93 assert_equal 'only_assigned', user.mail_notification
94 94 assert !user.admin?
95 95 assert user.check_password?('secret')
96 96
97 97 assert_response :created
98 98 assert_equal 'application/xml', @response.content_type
99 99 assert_tag 'user', :child => {:tag => 'id', :content => user.id.to_s}
100 100 end
101 101 end
102 102
103 103 context ".json" do
104 104 should_allow_api_authentication(:post,
105 105 '/users.json',
106 106 {:user => {:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname', :mail => 'foo@example.net'}},
107 107 {:success_code => :created})
108 108
109 109 should "create a user with the attributes" do
110 110 assert_difference('User.count') do
111 111 post '/users.json', @parameters, :authorization => credentials('admin')
112 112 end
113 113
114 114 user = User.first(:order => 'id DESC')
115 115 assert_equal 'foo', user.login
116 116 assert_equal 'Firstname', user.firstname
117 117 assert_equal 'Lastname', user.lastname
118 118 assert_equal 'foo@example.net', user.mail
119 119 assert !user.admin?
120 120
121 121 assert_response :created
122 122 assert_equal 'application/json', @response.content_type
123 123 json = ActiveSupport::JSON.decode(response.body)
124 124 assert_kind_of Hash, json
125 125 assert_kind_of Hash, json['user']
126 126 assert_equal user.id, json['user']['id']
127 127 end
128 128 end
129 129 end
130 130
131 131 context "with invalid parameters" do
132 132 setup do
133 133 @parameters = {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}
134 134 end
135 135
136 136 context ".xml" do
137 137 should "return errors" do
138 138 assert_no_difference('User.count') do
139 139 post '/users.xml', @parameters, :authorization => credentials('admin')
140 140 end
141 141
142 142 assert_response :unprocessable_entity
143 143 assert_equal 'application/xml', @response.content_type
144 144 assert_tag 'errors', :child => {:tag => 'error', :content => "Firstname can't be blank"}
145 145 end
146 146 end
147 147
148 148 context ".json" do
149 149 should "return errors" do
150 150 assert_no_difference('User.count') do
151 151 post '/users.json', @parameters, :authorization => credentials('admin')
152 152 end
153 153
154 154 assert_response :unprocessable_entity
155 155 assert_equal 'application/json', @response.content_type
156 156 json = ActiveSupport::JSON.decode(response.body)
157 157 assert_kind_of Hash, json
158 158 assert json.has_key?('errors')
159 159 assert_kind_of Array, json['errors']
160 160 end
161 161 end
162 162 end
163 163 end
164 164
165 165 context "PUT /users/2" do
166 166 context "with valid parameters" do
167 167 setup do
168 168 @parameters = {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}}
169 169 end
170 170
171 171 context ".xml" do
172 172 should_allow_api_authentication(:put,
173 173 '/users/2.xml',
174 174 {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}},
175 175 {:success_code => :ok})
176 176
177 177 should "update user with the attributes" do
178 178 assert_no_difference('User.count') do
179 179 put '/users/2.xml', @parameters, :authorization => credentials('admin')
180 180 end
181 181
182 182 user = User.find(2)
183 183 assert_equal 'jsmith', user.login
184 184 assert_equal 'John', user.firstname
185 185 assert_equal 'Renamed', user.lastname
186 186 assert_equal 'jsmith@somenet.foo', user.mail
187 187 assert !user.admin?
188 188
189 189 assert_response :ok
190 190 end
191 191 end
192 192
193 193 context ".json" do
194 194 should_allow_api_authentication(:put,
195 195 '/users/2.json',
196 196 {:user => {:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed', :mail => 'jsmith@somenet.foo'}},
197 197 {:success_code => :ok})
198 198
199 199 should "update user with the attributes" do
200 200 assert_no_difference('User.count') do
201 201 put '/users/2.json', @parameters, :authorization => credentials('admin')
202 202 end
203 203
204 204 user = User.find(2)
205 205 assert_equal 'jsmith', user.login
206 206 assert_equal 'John', user.firstname
207 207 assert_equal 'Renamed', user.lastname
208 208 assert_equal 'jsmith@somenet.foo', user.mail
209 209 assert !user.admin?
210 210
211 211 assert_response :ok
212 212 end
213 213 end
214 214 end
215 215
216 216 context "with invalid parameters" do
217 217 setup do
218 218 @parameters = {:user => {:login => 'jsmith', :firstname => '', :lastname => 'Lastname', :mail => 'foo'}}
219 219 end
220 220
221 221 context ".xml" do
222 222 should "return errors" do
223 223 assert_no_difference('User.count') do
224 224 put '/users/2.xml', @parameters, :authorization => credentials('admin')
225 225 end
226 226
227 227 assert_response :unprocessable_entity
228 228 assert_equal 'application/xml', @response.content_type
229 229 assert_tag 'errors', :child => {:tag => 'error', :content => "Firstname can't be blank"}
230 230 end
231 231 end
232 232
233 233 context ".json" do
234 234 should "return errors" do
235 235 assert_no_difference('User.count') do
236 236 put '/users/2.json', @parameters, :authorization => credentials('admin')
237 237 end
238 238
239 239 assert_response :unprocessable_entity
240 240 assert_equal 'application/json', @response.content_type
241 241 json = ActiveSupport::JSON.decode(response.body)
242 242 assert_kind_of Hash, json
243 243 assert json.has_key?('errors')
244 244 assert_kind_of Array, json['errors']
245 245 end
246 246 end
247 247 end
248 end
248 249
249 context "DELETE /users/2" do
250 context ".xml" do
251 should "not be allowed" do
252 assert_no_difference('User.count') do
253 delete '/users/2.xml'
254 end
255
256 assert_response :method_not_allowed
250 context "DELETE /users/2" do
251 context ".xml" do
252 should_allow_api_authentication(:delete,
253 '/users/2.xml',
254 {},
255 {:success_code => :ok})
256
257 should "delete user" do
258 assert_difference('User.count', -1) do
259 delete '/users/2.xml', {}, :authorization => credentials('admin')
257 260 end
261
262 assert_response :ok
258 263 end
259
260 context ".json" do
261 should "not be allowed" do
262 assert_no_difference('User.count') do
263 delete '/users/2.json'
264 end
264 end
265
266 context ".json" do
267 should_allow_api_authentication(:delete,
268 '/users/2.xml',
269 {},
270 {:success_code => :ok})
265 271
266 assert_response :method_not_allowed
272 should "delete user" do
273 assert_difference('User.count', -1) do
274 delete '/users/2.json', {}, :authorization => credentials('admin')
267 275 end
276
277 assert_response :ok
268 278 end
269 279 end
270 280 end
271 281
272 282 def credentials(user, password=nil)
273 283 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
274 284 end
275 285 end
@@ -1,353 +1,356
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2010 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.expand_path('../../test_helper', __FILE__)
19 19
20 20 class RoutingTest < ActionController::IntegrationTest
21 21 context "activities" do
22 22 should_route :get, "/activity", :controller => 'activities', :action => 'index', :id => nil
23 23 should_route :get, "/activity.atom", :controller => 'activities', :action => 'index', :id => nil, :format => 'atom'
24 24 end
25 25
26 26 context "attachments" do
27 27 should_route :get, "/attachments/1", :controller => 'attachments', :action => 'show', :id => '1'
28 28 should_route :get, "/attachments/1/filename.ext", :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'
29 29 should_route :get, "/attachments/download/1", :controller => 'attachments', :action => 'download', :id => '1'
30 30 should_route :get, "/attachments/download/1/filename.ext", :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'
31 31 end
32 32
33 33 context "boards" do
34 34 should_route :get, "/projects/world_domination/boards", :controller => 'boards', :action => 'index', :project_id => 'world_domination'
35 35 should_route :get, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
36 36 should_route :get, "/projects/world_domination/boards/44", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44'
37 37 should_route :get, "/projects/world_domination/boards/44.atom", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44', :format => 'atom'
38 38 should_route :get, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
39 39
40 40 should_route :post, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
41 41 should_route :post, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
42 42 should_route :post, "/projects/world_domination/boards/44/destroy", :controller => 'boards', :action => 'destroy', :project_id => 'world_domination', :id => '44'
43 43
44 44 end
45 45
46 46 context "documents" do
47 47 should_route :get, "/projects/567/documents", :controller => 'documents', :action => 'index', :project_id => '567'
48 48 should_route :get, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
49 49 should_route :get, "/documents/22", :controller => 'documents', :action => 'show', :id => '22'
50 50 should_route :get, "/documents/22/edit", :controller => 'documents', :action => 'edit', :id => '22'
51 51
52 52 should_route :post, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
53 53 should_route :post, "/documents/567/edit", :controller => 'documents', :action => 'edit', :id => '567'
54 54 should_route :post, "/documents/567/destroy", :controller => 'documents', :action => 'destroy', :id => '567'
55 55 end
56 56
57 57 context "issues" do
58 58 # REST actions
59 59 should_route :get, "/issues", :controller => 'issues', :action => 'index'
60 60 should_route :get, "/issues.pdf", :controller => 'issues', :action => 'index', :format => 'pdf'
61 61 should_route :get, "/issues.atom", :controller => 'issues', :action => 'index', :format => 'atom'
62 62 should_route :get, "/issues.xml", :controller => 'issues', :action => 'index', :format => 'xml'
63 63 should_route :get, "/projects/23/issues", :controller => 'issues', :action => 'index', :project_id => '23'
64 64 should_route :get, "/projects/23/issues.pdf", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
65 65 should_route :get, "/projects/23/issues.atom", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
66 66 should_route :get, "/projects/23/issues.xml", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'xml'
67 67 should_route :get, "/issues/64", :controller => 'issues', :action => 'show', :id => '64'
68 68 should_route :get, "/issues/64.pdf", :controller => 'issues', :action => 'show', :id => '64', :format => 'pdf'
69 69 should_route :get, "/issues/64.atom", :controller => 'issues', :action => 'show', :id => '64', :format => 'atom'
70 70 should_route :get, "/issues/64.xml", :controller => 'issues', :action => 'show', :id => '64', :format => 'xml'
71 71
72 72 should_route :get, "/projects/23/issues/new", :controller => 'issues', :action => 'new', :project_id => '23'
73 73 should_route :post, "/projects/23/issues", :controller => 'issues', :action => 'create', :project_id => '23'
74 74 should_route :post, "/issues.xml", :controller => 'issues', :action => 'create', :format => 'xml'
75 75
76 76 should_route :get, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
77 77 # TODO: Should use PUT
78 78 should_route :post, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
79 79 should_route :put, "/issues/1.xml", :controller => 'issues', :action => 'update', :id => '1', :format => 'xml'
80 80
81 81 # TODO: Should use DELETE
82 82 should_route :post, "/issues/64/destroy", :controller => 'issues', :action => 'destroy', :id => '64'
83 83 should_route :delete, "/issues/1.xml", :controller => 'issues', :action => 'destroy', :id => '1', :format => 'xml'
84 84
85 85 # Extra actions
86 86 should_route :get, "/projects/23/issues/64/copy", :controller => 'issues', :action => 'new', :project_id => '23', :copy_from => '64'
87 87
88 88 should_route :get, "/issues/move/new", :controller => 'issue_moves', :action => 'new'
89 89 should_route :post, "/issues/move", :controller => 'issue_moves', :action => 'create'
90 90
91 91 should_route :post, "/issues/1/quoted", :controller => 'journals', :action => 'new', :id => '1'
92 92
93 93 should_route :get, "/issues/calendar", :controller => 'calendars', :action => 'show'
94 94 should_route :put, "/issues/calendar", :controller => 'calendars', :action => 'update'
95 95 should_route :get, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'show', :project_id => 'project-name'
96 96 should_route :put, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'update', :project_id => 'project-name'
97 97
98 98 should_route :get, "/issues/gantt", :controller => 'gantts', :action => 'show'
99 99 should_route :put, "/issues/gantt", :controller => 'gantts', :action => 'update'
100 100 should_route :get, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'show', :project_id => 'project-name'
101 101 should_route :put, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'update', :project_id => 'project-name'
102 102
103 103 should_route :get, "/issues/auto_complete", :controller => 'auto_completes', :action => 'issues'
104 104
105 105 should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
106 106 should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
107 107 should_route :get, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
108 108 should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
109 109
110 110 should_route :get, "/issues/changes", :controller => 'journals', :action => 'index'
111 111
112 112 should_route :get, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_edit'
113 113 should_route :post, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_update'
114 114 end
115 115
116 116 context "issue categories" do
117 117 should_route :get, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
118 118
119 119 should_route :post, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
120 120 end
121 121
122 122 context "issue relations" do
123 123 should_route :post, "/issues/1/relations", :controller => 'issue_relations', :action => 'new', :issue_id => '1'
124 124 should_route :post, "/issues/1/relations/23/destroy", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23'
125 125 end
126 126
127 127 context "issue reports" do
128 128 should_route :get, "/projects/567/issues/report", :controller => 'reports', :action => 'issue_report', :id => '567'
129 129 should_route :get, "/projects/567/issues/report/assigned_to", :controller => 'reports', :action => 'issue_report_details', :id => '567', :detail => 'assigned_to'
130 130 end
131 131
132 132 context "members" do
133 133 should_route :post, "/projects/5234/members/new", :controller => 'members', :action => 'new', :id => '5234'
134 134 end
135 135
136 136 context "messages" do
137 137 should_route :get, "/boards/22/topics/2", :controller => 'messages', :action => 'show', :id => '2', :board_id => '22'
138 138 should_route :get, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
139 139 should_route :get, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
140 140
141 141 should_route :post, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
142 142 should_route :post, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
143 143 should_route :post, "/boards/22/topics/555/replies", :controller => 'messages', :action => 'reply', :id => '555', :board_id => '22'
144 144 should_route :post, "/boards/22/topics/555/destroy", :controller => 'messages', :action => 'destroy', :id => '555', :board_id => '22'
145 145 end
146 146
147 147 context "news" do
148 148 should_route :get, "/news", :controller => 'news', :action => 'index'
149 149 should_route :get, "/news.atom", :controller => 'news', :action => 'index', :format => 'atom'
150 150 should_route :get, "/news.xml", :controller => 'news', :action => 'index', :format => 'xml'
151 151 should_route :get, "/news.json", :controller => 'news', :action => 'index', :format => 'json'
152 152 should_route :get, "/projects/567/news", :controller => 'news', :action => 'index', :project_id => '567'
153 153 should_route :get, "/projects/567/news.atom", :controller => 'news', :action => 'index', :format => 'atom', :project_id => '567'
154 154 should_route :get, "/projects/567/news.xml", :controller => 'news', :action => 'index', :format => 'xml', :project_id => '567'
155 155 should_route :get, "/projects/567/news.json", :controller => 'news', :action => 'index', :format => 'json', :project_id => '567'
156 156 should_route :get, "/news/2", :controller => 'news', :action => 'show', :id => '2'
157 157 should_route :get, "/projects/567/news/new", :controller => 'news', :action => 'new', :project_id => '567'
158 158 should_route :get, "/news/234", :controller => 'news', :action => 'show', :id => '234'
159 159 should_route :get, "/news/567/edit", :controller => 'news', :action => 'edit', :id => '567'
160 160 should_route :get, "/news/preview", :controller => 'previews', :action => 'news'
161 161
162 162 should_route :post, "/projects/567/news", :controller => 'news', :action => 'create', :project_id => '567'
163 163 should_route :post, "/news/567/comments", :controller => 'comments', :action => 'create', :id => '567'
164 164
165 165 should_route :put, "/news/567", :controller => 'news', :action => 'update', :id => '567'
166 166
167 167 should_route :delete, "/news/567", :controller => 'news', :action => 'destroy', :id => '567'
168 168 should_route :delete, "/news/567/comments/15", :controller => 'comments', :action => 'destroy', :id => '567', :comment_id => '15'
169 169 end
170 170
171 171 context "projects" do
172 172 should_route :get, "/projects", :controller => 'projects', :action => 'index'
173 173 should_route :get, "/projects.atom", :controller => 'projects', :action => 'index', :format => 'atom'
174 174 should_route :get, "/projects.xml", :controller => 'projects', :action => 'index', :format => 'xml'
175 175 should_route :get, "/projects/new", :controller => 'projects', :action => 'new'
176 176 should_route :get, "/projects/test", :controller => 'projects', :action => 'show', :id => 'test'
177 177 should_route :get, "/projects/1.xml", :controller => 'projects', :action => 'show', :id => '1', :format => 'xml'
178 178 should_route :get, "/projects/4223/settings", :controller => 'projects', :action => 'settings', :id => '4223'
179 179 should_route :get, "/projects/4223/settings/members", :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
180 180 should_route :get, "/projects/33/files", :controller => 'files', :action => 'index', :project_id => '33'
181 181 should_route :get, "/projects/33/files/new", :controller => 'files', :action => 'new', :project_id => '33'
182 182 should_route :get, "/projects/33/roadmap", :controller => 'versions', :action => 'index', :project_id => '33'
183 183 should_route :get, "/projects/33/activity", :controller => 'activities', :action => 'index', :id => '33'
184 184 should_route :get, "/projects/33/activity.atom", :controller => 'activities', :action => 'index', :id => '33', :format => 'atom'
185 185
186 186 should_route :post, "/projects", :controller => 'projects', :action => 'create'
187 187 should_route :post, "/projects.xml", :controller => 'projects', :action => 'create', :format => 'xml'
188 188 should_route :post, "/projects/33/files", :controller => 'files', :action => 'create', :project_id => '33'
189 189 should_route :post, "/projects/64/archive", :controller => 'projects', :action => 'archive', :id => '64'
190 190 should_route :post, "/projects/64/unarchive", :controller => 'projects', :action => 'unarchive', :id => '64'
191 191
192 192 should_route :put, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'update', :project_id => '64'
193 193 should_route :put, "/projects/4223", :controller => 'projects', :action => 'update', :id => '4223'
194 194 should_route :put, "/projects/1.xml", :controller => 'projects', :action => 'update', :id => '1', :format => 'xml'
195 195
196 196 should_route :delete, "/projects/64", :controller => 'projects', :action => 'destroy', :id => '64'
197 197 should_route :delete, "/projects/1.xml", :controller => 'projects', :action => 'destroy', :id => '1', :format => 'xml'
198 198 should_route :delete, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'destroy', :project_id => '64'
199 199 end
200 200
201 201 context "repositories" do
202 202 should_route :get, "/projects/redmine/repository", :controller => 'repositories', :action => 'show', :id => 'redmine'
203 203 should_route :get, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
204 204 should_route :get, "/projects/redmine/repository/revisions", :controller => 'repositories', :action => 'revisions', :id => 'redmine'
205 205 should_route :get, "/projects/redmine/repository/revisions.atom", :controller => 'repositories', :action => 'revisions', :id => 'redmine', :format => 'atom'
206 206 should_route :get, "/projects/redmine/repository/revisions/2457", :controller => 'repositories', :action => 'revision', :id => 'redmine', :rev => '2457'
207 207 should_route :get, "/projects/redmine/repository/revisions/2457/diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457'
208 208 should_route :get, "/projects/redmine/repository/revisions/2457/diff.diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457', :format => 'diff'
209 209 should_route :get, "/projects/redmine/repository/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c]
210 210 should_route :get, "/projects/redmine/repository/revisions/2/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
211 211 should_route :get, "/projects/redmine/repository/browse/path/to/file.c", :controller => 'repositories', :action => 'browse', :id => 'redmine', :path => %w[path to file.c]
212 212 should_route :get, "/projects/redmine/repository/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c]
213 213 should_route :get, "/projects/redmine/repository/revisions/2/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
214 214 should_route :get, "/projects/redmine/repository/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :format => 'raw'
215 215 should_route :get, "/projects/redmine/repository/revisions/2/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2', :format => 'raw'
216 216 should_route :get, "/projects/redmine/repository/annotate/path/to/file.c", :controller => 'repositories', :action => 'annotate', :id => 'redmine', :path => %w[path to file.c]
217 217 should_route :get, "/projects/redmine/repository/changes/path/to/file.c", :controller => 'repositories', :action => 'changes', :id => 'redmine', :path => %w[path to file.c]
218 218 should_route :get, "/projects/redmine/repository/statistics", :controller => 'repositories', :action => 'stats', :id => 'redmine'
219 219
220 220
221 221 should_route :post, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
222 222 end
223 223
224 224 context "timelogs (global)" do
225 225 should_route :get, "/time_entries", :controller => 'timelog', :action => 'index'
226 226 should_route :get, "/time_entries.csv", :controller => 'timelog', :action => 'index', :format => 'csv'
227 227 should_route :get, "/time_entries.atom", :controller => 'timelog', :action => 'index', :format => 'atom'
228 228 should_route :get, "/time_entries/new", :controller => 'timelog', :action => 'new'
229 229 should_route :get, "/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22'
230 230
231 231 should_route :post, "/time_entries", :controller => 'timelog', :action => 'create'
232 232
233 233 should_route :put, "/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22'
234 234
235 235 should_route :delete, "/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55'
236 236 end
237 237
238 238 context "timelogs (scoped under project)" do
239 239 should_route :get, "/projects/567/time_entries", :controller => 'timelog', :action => 'index', :project_id => '567'
240 240 should_route :get, "/projects/567/time_entries.csv", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'csv'
241 241 should_route :get, "/projects/567/time_entries.atom", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'atom'
242 242 should_route :get, "/projects/567/time_entries/new", :controller => 'timelog', :action => 'new', :project_id => '567'
243 243 should_route :get, "/projects/567/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :project_id => '567'
244 244
245 245 should_route :post, "/projects/567/time_entries", :controller => 'timelog', :action => 'create', :project_id => '567'
246 246
247 247 should_route :put, "/projects/567/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :project_id => '567'
248 248
249 249 should_route :delete, "/projects/567/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :project_id => '567'
250 250 end
251 251
252 252 context "timelogs (scoped under issues)" do
253 253 should_route :get, "/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234'
254 254 should_route :get, "/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'csv'
255 255 should_route :get, "/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'atom'
256 256 should_route :get, "/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234'
257 257 should_route :get, "/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234'
258 258
259 259 should_route :post, "/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234'
260 260
261 261 should_route :put, "/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234'
262 262
263 263 should_route :delete, "/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234'
264 264 end
265 265
266 266 context "timelogs (scoped under project and issues)" do
267 267 should_route :get, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook'
268 268 should_route :get, "/projects/ecookbook/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'csv'
269 269 should_route :get, "/projects/ecookbook/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'atom'
270 270 should_route :get, "/projects/ecookbook/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234', :project_id => 'ecookbook'
271 271 should_route :get, "/projects/ecookbook/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
272 272
273 273 should_route :post, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234', :project_id => 'ecookbook'
274 274
275 275 should_route :put, "/projects/ecookbook/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
276 276
277 277 should_route :delete, "/projects/ecookbook/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234', :project_id => 'ecookbook'
278 278 end
279 279
280 280 context "time_entry_reports" do
281 281 should_route :get, "/time_entries/report", :controller => 'time_entry_reports', :action => 'report'
282 282 should_route :get, "/projects/567/time_entries/report", :controller => 'time_entry_reports', :action => 'report', :project_id => '567'
283 283 should_route :get, "/projects/567/time_entries/report.csv", :controller => 'time_entry_reports', :action => 'report', :project_id => '567', :format => 'csv'
284 284 end
285 285
286 286 context "users" do
287 287 should_route :get, "/users", :controller => 'users', :action => 'index'
288 288 should_route :get, "/users.xml", :controller => 'users', :action => 'index', :format => 'xml'
289 289 should_route :get, "/users/44", :controller => 'users', :action => 'show', :id => '44'
290 290 should_route :get, "/users/44.xml", :controller => 'users', :action => 'show', :id => '44', :format => 'xml'
291 291 should_route :get, "/users/current", :controller => 'users', :action => 'show', :id => 'current'
292 292 should_route :get, "/users/current.xml", :controller => 'users', :action => 'show', :id => 'current', :format => 'xml'
293 293 should_route :get, "/users/new", :controller => 'users', :action => 'new'
294 294 should_route :get, "/users/444/edit", :controller => 'users', :action => 'edit', :id => '444'
295 295 should_route :get, "/users/222/edit/membership", :controller => 'users', :action => 'edit', :id => '222', :tab => 'membership'
296 296
297 297 should_route :post, "/users", :controller => 'users', :action => 'create'
298 298 should_route :post, "/users.xml", :controller => 'users', :action => 'create', :format => 'xml'
299 299 should_route :post, "/users/123/memberships", :controller => 'users', :action => 'edit_membership', :id => '123'
300 300 should_route :post, "/users/123/memberships/55", :controller => 'users', :action => 'edit_membership', :id => '123', :membership_id => '55'
301 301 should_route :post, "/users/567/memberships/12/destroy", :controller => 'users', :action => 'destroy_membership', :id => '567', :membership_id => '12'
302 302
303 303 should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444'
304 304 should_route :put, "/users/444.xml", :controller => 'users', :action => 'update', :id => '444', :format => 'xml'
305
306 should_route :delete, "/users/44", :controller => 'users', :action => 'destroy', :id => '44'
307 should_route :delete, "/users/44.xml", :controller => 'users', :action => 'destroy', :id => '44', :format => 'xml'
305 308 end
306 309
307 310 # TODO: should they all be scoped under /projects/:project_id ?
308 311 context "versions" do
309 312 should_route :get, "/projects/foo/versions/new", :controller => 'versions', :action => 'new', :project_id => 'foo'
310 313 should_route :get, "/versions/show/1", :controller => 'versions', :action => 'show', :id => '1'
311 314 should_route :get, "/versions/edit/1", :controller => 'versions', :action => 'edit', :id => '1'
312 315
313 316 should_route :post, "/projects/foo/versions", :controller => 'versions', :action => 'create', :project_id => 'foo'
314 317 should_route :post, "/versions/update/1", :controller => 'versions', :action => 'update', :id => '1'
315 318
316 319 should_route :delete, "/versions/destroy/1", :controller => 'versions', :action => 'destroy', :id => '1'
317 320 end
318 321
319 322 context "wiki (singular, project's pages)" do
320 323 should_route :get, "/projects/567/wiki", :controller => 'wiki', :action => 'show', :project_id => '567'
321 324 should_route :get, "/projects/567/wiki/lalala", :controller => 'wiki', :action => 'show', :project_id => '567', :id => 'lalala'
322 325 should_route :get, "/projects/567/wiki/my_page/edit", :controller => 'wiki', :action => 'edit', :project_id => '567', :id => 'my_page'
323 326 should_route :get, "/projects/1/wiki/CookBook_documentation/history", :controller => 'wiki', :action => 'history', :project_id => '1', :id => 'CookBook_documentation'
324 327 should_route :get, "/projects/1/wiki/CookBook_documentation/diff", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation'
325 328 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
326 329 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2/vs/1", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2', :version_from => '1'
327 330 should_route :get, "/projects/1/wiki/CookBook_documentation/annotate/2", :controller => 'wiki', :action => 'annotate', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
328 331 should_route :get, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
329 332 should_route :get, "/projects/567/wiki/index", :controller => 'wiki', :action => 'index', :project_id => '567'
330 333 should_route :get, "/projects/567/wiki/date_index", :controller => 'wiki', :action => 'date_index', :project_id => '567'
331 334 should_route :get, "/projects/567/wiki/export", :controller => 'wiki', :action => 'export', :project_id => '567'
332 335
333 336 should_route :post, "/projects/567/wiki/CookBook_documentation/preview", :controller => 'wiki', :action => 'preview', :project_id => '567', :id => 'CookBook_documentation'
334 337 should_route :post, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
335 338 should_route :post, "/projects/22/wiki/ladida/protect", :controller => 'wiki', :action => 'protect', :project_id => '22', :id => 'ladida'
336 339 should_route :post, "/projects/22/wiki/ladida/add_attachment", :controller => 'wiki', :action => 'add_attachment', :project_id => '22', :id => 'ladida'
337 340
338 341 should_route :put, "/projects/567/wiki/my_page", :controller => 'wiki', :action => 'update', :project_id => '567', :id => 'my_page'
339 342
340 343 should_route :delete, "/projects/22/wiki/ladida", :controller => 'wiki', :action => 'destroy', :project_id => '22', :id => 'ladida'
341 344 end
342 345
343 346 context "wikis (plural, admin setup)" do
344 347 should_route :get, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
345 348
346 349 should_route :post, "/projects/ladida/wiki", :controller => 'wikis', :action => 'edit', :id => 'ladida'
347 350 should_route :post, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
348 351 end
349 352
350 353 context "administration panel" do
351 354 should_route :get, "/admin/projects", :controller => 'admin', :action => 'projects'
352 355 end
353 356 end
General Comments 0
You need to be logged in to leave comments. Login now