Add functional test for weird but allowed characters in tags
[gitorious:yousource.git] / test / functional / commits_controller_test.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
4 #
5 #   This program is free software: you can redistribute it and/or modify
6 #   it under the terms of the GNU Affero General Public License as published by
7 #   the Free Software Foundation, either version 3 of the License, or
8 #   (at your option) any later version.
9 #
10 #   This program is distributed in the hope that it will be useful,
11 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 #   GNU Affero General Public License for more details.
14 #
15 #   You should have received a copy of the GNU Affero General Public License
16 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #++
18
19
20 require File.dirname(__FILE__) + '/../test_helper'
21
22 class CommitsControllerTest < ActionController::TestCase
23
24   context "showing a single commit" do
25     setup do
26       @project = projects(:johans)
27       @repository = @project.repositories.mainlines.first
28       @repository.update_attribute(:ready, true)
29           
30       Repository.any_instance.stubs(:full_repository_path).returns(grit_test_repo("dot_git"))
31       @grit = Grit::Repo.new(grit_test_repo("dot_git"), :is_bare => true)
32       Repository.any_instance.stubs(:git).returns(@grit)
33       @sha = "3fa4e130fa18c92e3030d4accb5d3e0cadd40157"
34     end
35     
36     should "get the correct project and repository" do
37       get :show, {:project_id => @project.to_param, 
38           :repository_id => @repository.to_param, :id => @sha}
39       assert_equal @project, assigns(:project)
40       assert_equal @repository, assigns(:repository)
41     end
42     
43     should "gets the commit data" do
44       get :show, {:project_id => @project.slug, 
45           :repository_id => @repository.name, :id => @sha}
46       assert_response :success
47       assert_equal @repository.git, assigns(:git)
48       assert_equal @repository.git.commit(@sha), assigns(:commit)
49       assert_not_nil assigns(:diffs)
50     end
51   
52     should "gets the comments for the commit" do
53       get :show, {:project_id => @project.slug, 
54           :repository_id => @repository.name, :id => @sha}
55       assert_equal 0, assigns(:comment_count)
56     end
57   
58     should "defaults to 'inline' diffmode" do
59       get :show, {:project_id => @project.slug, 
60           :repository_id => @repository.name, :id => @sha}
61       assert_equal "inline", assigns(:diffmode)
62     end
63   
64     should "sets sidebyside diffmode" do
65       get :show, {:project_id => @project.slug, 
66           :repository_id => @repository.name, :id => @sha, :diffmode => "sidebyside" }
67       assert_equal "sidebyside", assigns(:diffmode)
68     end
69     
70     should "get it in diff format" do
71       get :show, :project_id => @project.slug, 
72           :repository_id => @repository.name, :id => @sha, :format => "diff"
73       assert_response :success
74       assert_equal "text/plain", @response.content_type
75       assert_equal @repository.git.commit(@sha).diffs.map{|d| d.diff}.join("\n"), @response.body
76     end
77     
78     should "get it in patch format" do
79       get :show, :project_id => @project.slug, 
80           :repository_id => @repository.name, :id => @sha, :format => "patch"
81       assert_response :success
82       assert_equal "text/plain", @response.content_type
83       assert_equal @repository.git.commit(@sha).to_patch, @response.body
84     end
85     
86     should "redirect to the commit log with a msg if the SHA1 was not found" do
87       @grit.expects(:commit).with("123").returns(nil)
88       get :show, :project_id => @project.slug, 
89           :repository_id => @repository.name, :id => "123"
90       assert_response :redirect
91       assert_match(/no such sha/i, flash[:error])
92       assert_redirected_to project_repository_commits_path(@project, @repository)
93     end
94     
95     should "not show diffs for the initial commit" do
96       commit = @grit.commit(@sha)
97       commit.stubs(:parents).returns([])
98       @grit.expects(:commit).returns(commit)
99       get :show, {:project_id => @project.to_param, 
100           :repository_id => @repository.to_param, :id => @sha}
101       assert_equal [], assigns(:diffs)
102       assert_select "#content p", /This is the initial commit in this repository/
103     end
104
105     should "have a different last-modified if there's a comment" do
106       Comment.create!({
107           :user => users(:johan),
108           :body => "foo",
109           :sha1 => @sha,
110           :target => @repository,
111           :project => @repository.project,
112       })
113       get :show, :project_id => @project.slug,
114           :repository_id => @repository.name, :id => @sha
115       assert_response :success
116       assert_not_equal "Fri, 18 Apr 2008 23:26:07 GMT", @response.headers["Last-Modified"]
117     end
118   end
119   
120   context "Routing" do
121     setup do
122       @project = projects(:johans)
123       @repository = @project.repositories.first
124       @repository.update_attribute(:ready, true)
125       @sha = "3fa4e130fa18c92e3030d4accb5d3e0cadd40157"
126       @weird_id = '!"#$%&\'()+,-.0123456789;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ]_`abcdefghijklmnopqrstuvwxyz{|}'
127     end
128     
129     should "route commits format" do
130       assert_recognizes({
131         :controller => "commits", 
132         :action => "show", 
133         :project_id => @project.to_param,
134         :repository_id => @repository.to_param,
135         :id => @sha,
136       }, {:path => "/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}", :method => :get})
137       assert_generates("/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}", {
138         :controller => "commits", 
139         :action => "show", 
140         :project_id => @project.to_param,
141         :repository_id => @repository.to_param,
142         :id => @sha,
143       })
144     end
145     
146     should "route user-namespaced commits index, with dots in the username" do
147       assert_recognizes({
148         :controller => "commits", 
149         :action => "show", 
150         :user_id => "mc.hammer",
151         :project_id => @project.to_param,
152         :repository_id => @repository.to_param,
153         :id => @sha,
154       }, {:path => "/~mc.hammer/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}", :method => :get})
155       assert_generates("/~mc.hammer/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}", {
156         :controller => "commits", 
157         :action => "show", 
158         :user_id => "mc.hammer",
159         :project_id => @project.to_param,
160         :repository_id => @repository.to_param,
161         :id => @sha,
162       })
163     end
164
165     should "route tags with dots in the id" do
166       assert_recognizes({
167         :controller => "commits",
168         :action => "show",
169         :project_id => @project.to_param,
170         :repository_id => @repository.to_param,
171         :id => "v0.7.0",
172       }, {:path => "/#{@project.to_param}/#{@repository.to_param}/commit/v0.7.0", :method => :get})
173       assert_generates("/#{@project.to_param}/#{@repository.to_param}/commit/v0.7.0", {
174         :controller => "commits",
175         :action => "show",
176         :project_id => @project.to_param,
177         :repository_id => @repository.to_param,
178         :id => "v0.7.0",
179       })
180     end
181
182     should "route branches with weird characters in the id" do
183       assert_recognizes({
184         :controller => "commits",
185         :action => "show",
186         :project_id => @project.to_param,
187         :repository_id => @repository.to_param,
188         :id => @weird_id,
189       }, {:path => "/#{@project.to_param}/#{@repository.to_param}/commit/#{@weird_id}", :method => :get})
190       assert_generates("/#{@project.to_param}/#{@repository.to_param}/commit/#{URI.escape(@weird_id, ActionController::Routing::Segment::UNSAFE_PCHAR)}",
191         :controller => "commits",
192         :action => "show",
193         :project_id => @project.to_param,
194         :repository_id => @repository.to_param,
195         :id => @weird_id,
196       })
197     end
198
199     should "route diff format" do
200       assert_recognizes({
201         :controller => "commits", 
202         :action => "show", 
203         :project_id => @project.to_param,
204         :repository_id => @repository.to_param,
205         :id => @sha,
206         :format => "diff",
207       }, {
208         :path => "/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}",
209         :method => :get
210       }, {
211         :format => "diff",
212       })
213       assert_generates("/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}", {
214         :controller => "commits", 
215         :action => "show", 
216         :project_id => @project.to_param,
217         :repository_id => @repository.to_param,
218         :id => @sha,
219         :format => "diff"
220       }, {}, {
221         :format => "diff",
222       })
223     end
224     
225     should "route patch format" do
226       assert_recognizes({
227         :controller => "commits", 
228         :action => "show", 
229         :project_id => @project.to_param,
230         :repository_id => @repository.to_param,
231         :id => @sha,
232         :format => "patch",
233       }, {
234         :path => "/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}",
235         :method => :get
236       }, {
237         :format => "patch",
238       })
239       assert_generates("/#{@project.to_param}/#{@repository.to_param}/commit/#{@sha}", {
240         :controller => "commits", 
241         :action => "show", 
242         :project_id => @project.to_param,
243         :repository_id => @repository.to_param,
244         :id => @sha,
245         :format => "patch"
246       }, {}, {
247         :format => "patch",
248       })
249     end
250   end
251
252
253   context "listing commits" do
254     setup do
255       @project = projects(:johans)
256       @repository = @project.repositories.first
257       @repository.update_attribute(:ready, true)
258       Project.expects(:find_by_slug!).with(@project.slug) \
259         .returns(@project)
260       Repository.expects(:find_by_name_and_project_id!) \
261           .with(@repository.name, @project.id).returns(@repository)
262       
263       Repository.any_instance.stubs(:full_repository_path).returns(grit_test_repo("dot_git"))
264       @git = Grit::Repo.new(grit_test_repo("dot_git"), :is_bare => true)
265       Repository.any_instance.stubs(:git).returns(@git)
266     end
267
268     context "#index" do
269       should "GETs page 1 successfully" do
270         get :index, {:project_id => @project.slug, 
271           :repository_id => @repository.name, :page => nil, :branch => ["master"]}
272         assert_response :success
273         assert_equal @repository.git.commits("master", 30, 0), assigns(:commits)
274       end
275
276       should "GETs page 3 successfully" do
277         get :index, {:project_id => @project.slug, 
278           :repository_id => @repository.name, :page => nil, :branch => ["master"],
279           :page => 3}
280         assert_response :success
281         assert_equal @repository.git.commits("master", 30, 60), assigns(:commits)
282       end
283
284       should "GETs the commits successfully" do
285         get :index, {:project_id => @project.slug, 
286           :repository_id => @repository.name, :page => nil, :branch => ["master"]}
287         assert_response :success
288         assert_equal "master", assigns(:root).title
289         assert_equal @repository.git, assigns(:git)
290         assert_equal @repository.git.commits("master", 30, 0), assigns(:commits)
291       end
292       
293       should "GET the commits of a namedspaced branch successfully" do
294         get :index, {:project_id => @project.slug, 
295           :repository_id => @repository.name, :page => nil, :branch => ["test", "master"]}
296         assert_response :success
297         assert_equal "test/master", assigns(:ref)
298         assert_equal "test/master", assigns(:root).title
299         assert_equal @repository.git, assigns(:git)
300         assert_equal @repository.git.commits("test/master", 30, 0), assigns(:commits)
301       end
302       
303       should "deal gracefully if HEAD file refers to a non-existant ref" do
304         @git.expects(:get_head).with("master").returns(nil)
305         @git.expects(:commit).with("master").returns(nil)
306         get :index, {:project_id => @project.slug, 
307           :repository_id => @repository.name, :page => nil, :branch => ["master"]}
308         assert_response :redirect
309         assert_redirected_to project_repository_commits_in_ref_path(@project, 
310                               @repository, @git.heads.first.name)
311         assert_match(/not a valid ref/, flash[:error])
312       end
313       
314       should "have a proper id in the atom feed" do
315         #(repo, id, parents, tree, author, authored_date, committer, committed_date, message)
316         commit = Grit::Commit.new(mock("repo"), "mycommitid", [], stub_everything("tree"), 
317                       stub_everything("author"), Time.now, 
318                       stub_everything("comitter"), Time.now, 
319                       "my commit message".split(" "))
320         @repository.git.expects(:commits).twice.returns([commit])
321       
322         get :feed, {:project_id => @project.slug, 
323           :repository_id => @repository.name, :id => "master", :format => "atom"}
324         assert @response.body.include?(%Q{<id>tag:test.host,2005:Grit::Commit/mycommitid</id>})
325       end
326       
327       should "not explode when there's no commits" do
328         @repository.git.expects(:commits).returns([])
329         get :feed, {:project_id => @project.slug,
330           :repository_id => @repository.name, :id => "master", :format => "atom"}
331         assert_response :success
332         assert_select "feed title", /#{@repository.gitdir}/
333       end
334       
335       should "show branches with a # in them with great success" do
336         git_repo = Grit::Repo.new(grit_test_repo("dot_git"), :is_bare => true)
337         @repository.git.expects(:commit).with("ticket-#42") \
338           .returns(git_repo.commit("master"))
339         get :index, :project_id => @project.to_param, :repository_id => @repository.to_param,
340           :branch => ["ticket-%2342"]
341         assert_response :success
342         assert_equal "ticket-#42", assigns(:ref)
343       end
344     end
345   end
346 end