##// END OF EJS Templates
Fixes repository user mapping submission when a repository username is blank (#2339, Conflicting types for parameter containers)....
Jean-Philippe Lang -
r2135:7cea286c2344
parent child
Show More
@@ -1,324 +1,325
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'SVG/Graph/Bar'
18 require 'SVG/Graph/Bar'
19 require 'SVG/Graph/BarHorizontal'
19 require 'SVG/Graph/BarHorizontal'
20 require 'digest/sha1'
20 require 'digest/sha1'
21
21
22 class ChangesetNotFound < Exception; end
22 class ChangesetNotFound < Exception; end
23 class InvalidRevisionParam < Exception; end
23 class InvalidRevisionParam < Exception; end
24
24
25 class RepositoriesController < ApplicationController
25 class RepositoriesController < ApplicationController
26 menu_item :repository
26 menu_item :repository
27 before_filter :find_repository, :except => :edit
27 before_filter :find_repository, :except => :edit
28 before_filter :find_project, :only => :edit
28 before_filter :find_project, :only => :edit
29 before_filter :authorize
29 before_filter :authorize
30 accept_key_auth :revisions
30 accept_key_auth :revisions
31
31
32 rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
32 rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed
33
33
34 def edit
34 def edit
35 @repository = @project.repository
35 @repository = @project.repository
36 if !@repository
36 if !@repository
37 @repository = Repository.factory(params[:repository_scm])
37 @repository = Repository.factory(params[:repository_scm])
38 @repository.project = @project if @repository
38 @repository.project = @project if @repository
39 end
39 end
40 if request.post? && @repository
40 if request.post? && @repository
41 @repository.attributes = params[:repository]
41 @repository.attributes = params[:repository]
42 @repository.save
42 @repository.save
43 end
43 end
44 render(:update) {|page| page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'}
44 render(:update) {|page| page.replace_html "tab-content-repository", :partial => 'projects/settings/repository'}
45 end
45 end
46
46
47 def committers
47 def committers
48 @committers = @repository.committers
48 @committers = @repository.committers
49 @users = @project.users
49 @users = @project.users
50 additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
50 additional_user_ids = @committers.collect(&:last).collect(&:to_i) - @users.collect(&:id)
51 @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
51 @users += User.find_all_by_id(additional_user_ids) unless additional_user_ids.empty?
52 @users.compact!
52 @users.compact!
53 @users.sort!
53 @users.sort!
54 if request.post?
54 if request.post? && params[:committers].is_a?(Hash)
55 @repository.committer_ids = params[:committers]
55 # Build a hash with repository usernames as keys and corresponding user ids as values
56 @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h}
56 flash[:notice] = l(:notice_successful_update)
57 flash[:notice] = l(:notice_successful_update)
57 redirect_to :action => 'committers', :id => @project
58 redirect_to :action => 'committers', :id => @project
58 end
59 end
59 end
60 end
60
61
61 def destroy
62 def destroy
62 @repository.destroy
63 @repository.destroy
63 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
64 redirect_to :controller => 'projects', :action => 'settings', :id => @project, :tab => 'repository'
64 end
65 end
65
66
66 def show
67 def show
67 # check if new revisions have been committed in the repository
68 # check if new revisions have been committed in the repository
68 @repository.fetch_changesets if Setting.autofetch_changesets?
69 @repository.fetch_changesets if Setting.autofetch_changesets?
69 # root entries
70 # root entries
70 @entries = @repository.entries('', @rev)
71 @entries = @repository.entries('', @rev)
71 # latest changesets
72 # latest changesets
72 @changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
73 @changesets = @repository.changesets.find(:all, :limit => 10, :order => "committed_on DESC")
73 show_error_not_found unless @entries || @changesets.any?
74 show_error_not_found unless @entries || @changesets.any?
74 end
75 end
75
76
76 def browse
77 def browse
77 @entries = @repository.entries(@path, @rev)
78 @entries = @repository.entries(@path, @rev)
78 if request.xhr?
79 if request.xhr?
79 @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
80 @entries ? render(:partial => 'dir_list_content') : render(:nothing => true)
80 else
81 else
81 show_error_not_found and return unless @entries
82 show_error_not_found and return unless @entries
82 @properties = @repository.properties(@path, @rev)
83 @properties = @repository.properties(@path, @rev)
83 render :action => 'browse'
84 render :action => 'browse'
84 end
85 end
85 end
86 end
86
87
87 def changes
88 def changes
88 @entry = @repository.entry(@path, @rev)
89 @entry = @repository.entry(@path, @rev)
89 show_error_not_found and return unless @entry
90 show_error_not_found and return unless @entry
90 @changesets = @repository.changesets_for_path(@path)
91 @changesets = @repository.changesets_for_path(@path)
91 @properties = @repository.properties(@path, @rev)
92 @properties = @repository.properties(@path, @rev)
92 end
93 end
93
94
94 def revisions
95 def revisions
95 @changeset_count = @repository.changesets.count
96 @changeset_count = @repository.changesets.count
96 @changeset_pages = Paginator.new self, @changeset_count,
97 @changeset_pages = Paginator.new self, @changeset_count,
97 per_page_option,
98 per_page_option,
98 params['page']
99 params['page']
99 @changesets = @repository.changesets.find(:all,
100 @changesets = @repository.changesets.find(:all,
100 :limit => @changeset_pages.items_per_page,
101 :limit => @changeset_pages.items_per_page,
101 :offset => @changeset_pages.current.offset,
102 :offset => @changeset_pages.current.offset,
102 :include => :user)
103 :include => :user)
103
104
104 respond_to do |format|
105 respond_to do |format|
105 format.html { render :layout => false if request.xhr? }
106 format.html { render :layout => false if request.xhr? }
106 format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
107 format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") }
107 end
108 end
108 end
109 end
109
110
110 def entry
111 def entry
111 @entry = @repository.entry(@path, @rev)
112 @entry = @repository.entry(@path, @rev)
112 show_error_not_found and return unless @entry
113 show_error_not_found and return unless @entry
113
114
114 # If the entry is a dir, show the browser
115 # If the entry is a dir, show the browser
115 browse and return if @entry.is_dir?
116 browse and return if @entry.is_dir?
116
117
117 @content = @repository.cat(@path, @rev)
118 @content = @repository.cat(@path, @rev)
118 show_error_not_found and return unless @content
119 show_error_not_found and return unless @content
119 if 'raw' == params[:format] || @content.is_binary_data?
120 if 'raw' == params[:format] || @content.is_binary_data?
120 # Force the download if it's a binary file
121 # Force the download if it's a binary file
121 send_data @content, :filename => @path.split('/').last
122 send_data @content, :filename => @path.split('/').last
122 else
123 else
123 # Prevent empty lines when displaying a file with Windows style eol
124 # Prevent empty lines when displaying a file with Windows style eol
124 @content.gsub!("\r\n", "\n")
125 @content.gsub!("\r\n", "\n")
125 end
126 end
126 end
127 end
127
128
128 def annotate
129 def annotate
129 @annotate = @repository.scm.annotate(@path, @rev)
130 @annotate = @repository.scm.annotate(@path, @rev)
130 render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
131 render_error l(:error_scm_annotate) and return if @annotate.nil? || @annotate.empty?
131 end
132 end
132
133
133 def revision
134 def revision
134 @changeset = @repository.changesets.find_by_revision(@rev)
135 @changeset = @repository.changesets.find_by_revision(@rev)
135 raise ChangesetNotFound unless @changeset
136 raise ChangesetNotFound unless @changeset
136
137
137 respond_to do |format|
138 respond_to do |format|
138 format.html
139 format.html
139 format.js {render :layout => false}
140 format.js {render :layout => false}
140 end
141 end
141 rescue ChangesetNotFound
142 rescue ChangesetNotFound
142 show_error_not_found
143 show_error_not_found
143 end
144 end
144
145
145 def diff
146 def diff
146 if params[:format] == 'diff'
147 if params[:format] == 'diff'
147 @diff = @repository.diff(@path, @rev, @rev_to)
148 @diff = @repository.diff(@path, @rev, @rev_to)
148 show_error_not_found and return unless @diff
149 show_error_not_found and return unless @diff
149 filename = "changeset_r#{@rev}"
150 filename = "changeset_r#{@rev}"
150 filename << "_r#{@rev_to}" if @rev_to
151 filename << "_r#{@rev_to}" if @rev_to
151 send_data @diff.join, :filename => "#{filename}.diff",
152 send_data @diff.join, :filename => "#{filename}.diff",
152 :type => 'text/x-patch',
153 :type => 'text/x-patch',
153 :disposition => 'attachment'
154 :disposition => 'attachment'
154 else
155 else
155 @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
156 @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
156 @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
157 @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
157
158
158 # Save diff type as user preference
159 # Save diff type as user preference
159 if User.current.logged? && @diff_type != User.current.pref[:diff_type]
160 if User.current.logged? && @diff_type != User.current.pref[:diff_type]
160 User.current.pref[:diff_type] = @diff_type
161 User.current.pref[:diff_type] = @diff_type
161 User.current.preference.save
162 User.current.preference.save
162 end
163 end
163
164
164 @cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
165 @cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
165 unless read_fragment(@cache_key)
166 unless read_fragment(@cache_key)
166 @diff = @repository.diff(@path, @rev, @rev_to)
167 @diff = @repository.diff(@path, @rev, @rev_to)
167 show_error_not_found unless @diff
168 show_error_not_found unless @diff
168 end
169 end
169 end
170 end
170 end
171 end
171
172
172 def stats
173 def stats
173 end
174 end
174
175
175 def graph
176 def graph
176 data = nil
177 data = nil
177 case params[:graph]
178 case params[:graph]
178 when "commits_per_month"
179 when "commits_per_month"
179 data = graph_commits_per_month(@repository)
180 data = graph_commits_per_month(@repository)
180 when "commits_per_author"
181 when "commits_per_author"
181 data = graph_commits_per_author(@repository)
182 data = graph_commits_per_author(@repository)
182 end
183 end
183 if data
184 if data
184 headers["Content-Type"] = "image/svg+xml"
185 headers["Content-Type"] = "image/svg+xml"
185 send_data(data, :type => "image/svg+xml", :disposition => "inline")
186 send_data(data, :type => "image/svg+xml", :disposition => "inline")
186 else
187 else
187 render_404
188 render_404
188 end
189 end
189 end
190 end
190
191
191 private
192 private
192 def find_project
193 def find_project
193 @project = Project.find(params[:id])
194 @project = Project.find(params[:id])
194 rescue ActiveRecord::RecordNotFound
195 rescue ActiveRecord::RecordNotFound
195 render_404
196 render_404
196 end
197 end
197
198
198 REV_PARAM_RE = %r{^[a-f0-9]*$}
199 REV_PARAM_RE = %r{^[a-f0-9]*$}
199
200
200 def find_repository
201 def find_repository
201 @project = Project.find(params[:id])
202 @project = Project.find(params[:id])
202 @repository = @project.repository
203 @repository = @project.repository
203 render_404 and return false unless @repository
204 render_404 and return false unless @repository
204 @path = params[:path].join('/') unless params[:path].nil?
205 @path = params[:path].join('/') unless params[:path].nil?
205 @path ||= ''
206 @path ||= ''
206 @rev = params[:rev]
207 @rev = params[:rev]
207 @rev_to = params[:rev_to]
208 @rev_to = params[:rev_to]
208 raise InvalidRevisionParam unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE)
209 raise InvalidRevisionParam unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE)
209 rescue ActiveRecord::RecordNotFound
210 rescue ActiveRecord::RecordNotFound
210 render_404
211 render_404
211 rescue InvalidRevisionParam
212 rescue InvalidRevisionParam
212 show_error_not_found
213 show_error_not_found
213 end
214 end
214
215
215 def show_error_not_found
216 def show_error_not_found
216 render_error l(:error_scm_not_found)
217 render_error l(:error_scm_not_found)
217 end
218 end
218
219
219 # Handler for Redmine::Scm::Adapters::CommandFailed exception
220 # Handler for Redmine::Scm::Adapters::CommandFailed exception
220 def show_error_command_failed(exception)
221 def show_error_command_failed(exception)
221 render_error l(:error_scm_command_failed, exception.message)
222 render_error l(:error_scm_command_failed, exception.message)
222 end
223 end
223
224
224 def graph_commits_per_month(repository)
225 def graph_commits_per_month(repository)
225 @date_to = Date.today
226 @date_to = Date.today
226 @date_from = @date_to << 11
227 @date_from = @date_to << 11
227 @date_from = Date.civil(@date_from.year, @date_from.month, 1)
228 @date_from = Date.civil(@date_from.year, @date_from.month, 1)
228 commits_by_day = repository.changesets.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
229 commits_by_day = repository.changesets.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
229 commits_by_month = [0] * 12
230 commits_by_month = [0] * 12
230 commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
231 commits_by_day.each {|c| commits_by_month[c.first.to_date.months_ago] += c.last }
231
232
232 changes_by_day = repository.changes.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
233 changes_by_day = repository.changes.count(:all, :group => :commit_date, :conditions => ["commit_date BETWEEN ? AND ?", @date_from, @date_to])
233 changes_by_month = [0] * 12
234 changes_by_month = [0] * 12
234 changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
235 changes_by_day.each {|c| changes_by_month[c.first.to_date.months_ago] += c.last }
235
236
236 fields = []
237 fields = []
237 month_names = l(:actionview_datehelper_select_month_names_abbr).split(',')
238 month_names = l(:actionview_datehelper_select_month_names_abbr).split(',')
238 12.times {|m| fields << month_names[((Date.today.month - 1 - m) % 12)]}
239 12.times {|m| fields << month_names[((Date.today.month - 1 - m) % 12)]}
239
240
240 graph = SVG::Graph::Bar.new(
241 graph = SVG::Graph::Bar.new(
241 :height => 300,
242 :height => 300,
242 :width => 800,
243 :width => 800,
243 :fields => fields.reverse,
244 :fields => fields.reverse,
244 :stack => :side,
245 :stack => :side,
245 :scale_integers => true,
246 :scale_integers => true,
246 :step_x_labels => 2,
247 :step_x_labels => 2,
247 :show_data_values => false,
248 :show_data_values => false,
248 :graph_title => l(:label_commits_per_month),
249 :graph_title => l(:label_commits_per_month),
249 :show_graph_title => true
250 :show_graph_title => true
250 )
251 )
251
252
252 graph.add_data(
253 graph.add_data(
253 :data => commits_by_month[0..11].reverse,
254 :data => commits_by_month[0..11].reverse,
254 :title => l(:label_revision_plural)
255 :title => l(:label_revision_plural)
255 )
256 )
256
257
257 graph.add_data(
258 graph.add_data(
258 :data => changes_by_month[0..11].reverse,
259 :data => changes_by_month[0..11].reverse,
259 :title => l(:label_change_plural)
260 :title => l(:label_change_plural)
260 )
261 )
261
262
262 graph.burn
263 graph.burn
263 end
264 end
264
265
265 def graph_commits_per_author(repository)
266 def graph_commits_per_author(repository)
266 commits_by_author = repository.changesets.count(:all, :group => :committer)
267 commits_by_author = repository.changesets.count(:all, :group => :committer)
267 commits_by_author.sort! {|x, y| x.last <=> y.last}
268 commits_by_author.sort! {|x, y| x.last <=> y.last}
268
269
269 changes_by_author = repository.changes.count(:all, :group => :committer)
270 changes_by_author = repository.changes.count(:all, :group => :committer)
270 h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
271 h = changes_by_author.inject({}) {|o, i| o[i.first] = i.last; o}
271
272
272 fields = commits_by_author.collect {|r| r.first}
273 fields = commits_by_author.collect {|r| r.first}
273 commits_data = commits_by_author.collect {|r| r.last}
274 commits_data = commits_by_author.collect {|r| r.last}
274 changes_data = commits_by_author.collect {|r| h[r.first] || 0}
275 changes_data = commits_by_author.collect {|r| h[r.first] || 0}
275
276
276 fields = fields + [""]*(10 - fields.length) if fields.length<10
277 fields = fields + [""]*(10 - fields.length) if fields.length<10
277 commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
278 commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
278 changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
279 changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
279
280
280 # Remove email adress in usernames
281 # Remove email adress in usernames
281 fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
282 fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
282
283
283 graph = SVG::Graph::BarHorizontal.new(
284 graph = SVG::Graph::BarHorizontal.new(
284 :height => 400,
285 :height => 400,
285 :width => 800,
286 :width => 800,
286 :fields => fields,
287 :fields => fields,
287 :stack => :side,
288 :stack => :side,
288 :scale_integers => true,
289 :scale_integers => true,
289 :show_data_values => false,
290 :show_data_values => false,
290 :rotate_y_labels => false,
291 :rotate_y_labels => false,
291 :graph_title => l(:label_commits_per_author),
292 :graph_title => l(:label_commits_per_author),
292 :show_graph_title => true
293 :show_graph_title => true
293 )
294 )
294
295
295 graph.add_data(
296 graph.add_data(
296 :data => commits_data,
297 :data => commits_data,
297 :title => l(:label_revision_plural)
298 :title => l(:label_revision_plural)
298 )
299 )
299
300
300 graph.add_data(
301 graph.add_data(
301 :data => changes_data,
302 :data => changes_data,
302 :title => l(:label_change_plural)
303 :title => l(:label_change_plural)
303 )
304 )
304
305
305 graph.burn
306 graph.burn
306 end
307 end
307
308
308 end
309 end
309
310
310 class Date
311 class Date
311 def months_ago(date = Date.today)
312 def months_ago(date = Date.today)
312 (date.year - self.year)*12 + (date.month - self.month)
313 (date.year - self.year)*12 + (date.month - self.month)
313 end
314 end
314
315
315 def weeks_ago(date = Date.today)
316 def weeks_ago(date = Date.today)
316 (date.year - self.year)*52 + (date.cweek - self.cweek)
317 (date.year - self.year)*52 + (date.cweek - self.cweek)
317 end
318 end
318 end
319 end
319
320
320 class String
321 class String
321 def with_leading_slash
322 def with_leading_slash
322 starts_with?('/') ? self : "/#{self}"
323 starts_with?('/') ? self : "/#{self}"
323 end
324 end
324 end
325 end
@@ -1,29 +1,34
1 <h2><%= l(:label_repository) %></h2>
1 <h2><%= l(:label_repository) %></h2>
2
2
3 <%= simple_format(l(:text_repository_usernames_mapping)) %>
3 <%= simple_format(l(:text_repository_usernames_mapping)) %>
4
4
5 <% if @committers.empty? %>
5 <% if @committers.empty? %>
6 <p class="nodata"><%= l(:label_no_data) %></p>
6 <p class="nodata"><%= l(:label_no_data) %></p>
7 <% else %>
7 <% else %>
8
8
9 <% form_tag({}) do %>
9 <% form_tag({}) do %>
10 <table class="list">
10 <table class="list">
11 <thead>
11 <thead>
12 <tr>
12 <tr>
13 <th><%= l(:field_login) %></th>
13 <th><%= l(:field_login) %></th>
14 <th><%= l(:label_user) %></th>
14 <th><%= l(:label_user) %></th>
15 </tr>
15 </tr>
16 </thead>
16 </thead>
17 <tbody>
17 <tbody>
18 <% i = 0 -%>
18 <% @committers.each do |committer, user_id| -%>
19 <% @committers.each do |committer, user_id| -%>
19 <tr class="<%= cycle 'odd', 'even' %>">
20 <tr class="<%= cycle 'odd', 'even' %>">
20 <td><%=h committer %></td>
21 <td><%=h committer %></td>
21 <td><%= select_tag "committers[#{committer}]", content_tag('option', "-- #{l :actionview_instancetag_blank_option} --", :value => '') + options_from_collection_for_select(@users, 'id', 'name', user_id.to_i) %></td>
22 <td>
23 <%= hidden_field_tag "committers[#{i}][]", committer %>
24 <%= select_tag "committers[#{i}][]", content_tag('option', "-- #{l :actionview_instancetag_blank_option} --", :value => '') + options_from_collection_for_select(@users, 'id', 'name', user_id.to_i) %>
25 </td>
22 </tr>
26 </tr>
27 <% i += 1 -%>
23 <% end -%>
28 <% end -%>
24 </tbody>
29 </tbody>
25 </table>
30 </table>
26 <p><%= submit_tag(l(:button_update)) %></p>
31 <p><%= submit_tag(l(:button_update)) %></p>
27 <% end %>
32 <% end %>
28
33
29 <% end %> No newline at end of file
34 <% end %>
@@ -1,98 +1,98
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19 require 'repositories_controller'
19 require 'repositories_controller'
20
20
21 # Re-raise errors caught by the controller.
21 # Re-raise errors caught by the controller.
22 class RepositoriesController; def rescue_action(e) raise e end; end
22 class RepositoriesController; def rescue_action(e) raise e end; end
23
23
24 class RepositoriesControllerTest < Test::Unit::TestCase
24 class RepositoriesControllerTest < Test::Unit::TestCase
25 fixtures :projects, :users, :roles, :members, :repositories, :issues, :issue_statuses, :changesets, :changes, :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
25 fixtures :projects, :users, :roles, :members, :repositories, :issues, :issue_statuses, :changesets, :changes, :issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
26
26
27 def setup
27 def setup
28 @controller = RepositoriesController.new
28 @controller = RepositoriesController.new
29 @request = ActionController::TestRequest.new
29 @request = ActionController::TestRequest.new
30 @response = ActionController::TestResponse.new
30 @response = ActionController::TestResponse.new
31 User.current = nil
31 User.current = nil
32 end
32 end
33
33
34 def test_revisions
34 def test_revisions
35 get :revisions, :id => 1
35 get :revisions, :id => 1
36 assert_response :success
36 assert_response :success
37 assert_template 'revisions'
37 assert_template 'revisions'
38 assert_not_nil assigns(:changesets)
38 assert_not_nil assigns(:changesets)
39 end
39 end
40
40
41 def test_revision_with_before_nil_and_afer_normal
41 def test_revision_with_before_nil_and_afer_normal
42 get :revision, {:id => 1, :rev => 1}
42 get :revision, {:id => 1, :rev => 1}
43 assert_response :success
43 assert_response :success
44 assert_template 'revision'
44 assert_template 'revision'
45 assert_no_tag :tag => "div", :attributes => { :class => "contextual" },
45 assert_no_tag :tag => "div", :attributes => { :class => "contextual" },
46 :child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook/0'}
46 :child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook/0'}
47 }
47 }
48 assert_tag :tag => "div", :attributes => { :class => "contextual" },
48 assert_tag :tag => "div", :attributes => { :class => "contextual" },
49 :child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook/2'}
49 :child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook/2'}
50 }
50 }
51 end
51 end
52
52
53 def test_graph_commits_per_month
53 def test_graph_commits_per_month
54 get :graph, :id => 1, :graph => 'commits_per_month'
54 get :graph, :id => 1, :graph => 'commits_per_month'
55 assert_response :success
55 assert_response :success
56 assert_equal 'image/svg+xml', @response.content_type
56 assert_equal 'image/svg+xml', @response.content_type
57 end
57 end
58
58
59 def test_graph_commits_per_author
59 def test_graph_commits_per_author
60 get :graph, :id => 1, :graph => 'commits_per_author'
60 get :graph, :id => 1, :graph => 'commits_per_author'
61 assert_response :success
61 assert_response :success
62 assert_equal 'image/svg+xml', @response.content_type
62 assert_equal 'image/svg+xml', @response.content_type
63 end
63 end
64
64
65 def test_committers
65 def test_committers
66 @request.session[:user_id] = 2
66 @request.session[:user_id] = 2
67 # add a commit with an unknown user
67 # add a commit with an unknown user
68 Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
68 Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
69
69
70 get :committers, :id => 1
70 get :committers, :id => 1
71 assert_response :success
71 assert_response :success
72 assert_template 'committers'
72 assert_template 'committers'
73
73
74 assert_tag :td, :content => 'dlopper',
74 assert_tag :td, :content => 'dlopper',
75 :sibling => { :tag => 'td',
75 :sibling => { :tag => 'td',
76 :child => { :tag => 'select', :attributes => { :name => 'committers[dlopper]' },
76 :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} },
77 :child => { :tag => 'option', :content => 'Dave Lopper',
77 :child => { :tag => 'option', :content => 'Dave Lopper',
78 :attributes => { :value => '3', :selected => 'selected' }}}}
78 :attributes => { :value => '3', :selected => 'selected' }}}}
79 assert_tag :td, :content => 'foo',
79 assert_tag :td, :content => 'foo',
80 :sibling => { :tag => 'td',
80 :sibling => { :tag => 'td',
81 :child => { :tag => 'select', :attributes => { :name => 'committers[foo]' }}}
81 :child => { :tag => 'select', :attributes => { :name => %r{^committers\[\d+\]\[\]$} }}}
82 assert_no_tag :td, :content => 'foo',
82 assert_no_tag :td, :content => 'foo',
83 :sibling => { :tag => 'td',
83 :sibling => { :tag => 'td',
84 :descendant => { :tag => 'option', :attributes => { :selected => 'selected' }}}
84 :descendant => { :tag => 'option', :attributes => { :selected => 'selected' }}}
85 end
85 end
86
86
87 def test_map_committers
87 def test_map_committers
88 @request.session[:user_id] = 2
88 @request.session[:user_id] = 2
89 # add a commit with an unknown user
89 # add a commit with an unknown user
90 c = Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
90 c = Changeset.create!(:repository => Project.find(1).repository, :committer => 'foo', :committed_on => Time.now, :revision => 100, :comments => 'Committed by foo.')
91
91
92 assert_no_difference "Changeset.count(:conditions => 'user_id = 3')" do
92 assert_no_difference "Changeset.count(:conditions => 'user_id = 3')" do
93 post :committers, :id => 1, :committers => { 'foo' => '2', 'dlopper' => '3'}
93 post :committers, :id => 1, :committers => { '0' => ['foo', '2'], '1' => ['dlopper', '3']}
94 assert_redirected_to '/repositories/committers/ecookbook'
94 assert_redirected_to '/repositories/committers/ecookbook'
95 assert_equal User.find(2), c.reload.user
95 assert_equal User.find(2), c.reload.user
96 end
96 end
97 end
97 end
98 end
98 end
General Comments 0
You need to be logged in to leave comments. Login now