Remove SslRequirement and associated logic
[gitorious:mainline.git] / test / functional / users_controller_test.rb
1 # encoding: utf-8
2 #--
3 #   Copyright (C) 2012 Gitorious AS
4 #   Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
5 #   Copyright (C) 2007 Johan Sørensen <johan@johansorensen.com>
6 #
7 #   This program is free software: you can redistribute it and/or modify
8 #   it under the terms of the GNU Affero General Public License as published by
9 #   the Free Software Foundation, either version 3 of the License, or
10 #   (at your option) any later version.
11 #
12 #   This program is distributed in the hope that it will be useful,
13 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #   GNU Affero General Public License for more details.
16 #
17 #   You should have received a copy of the GNU Affero General Public License
18 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #++
20
21 require "test_helper"
22
23 class UsersControllerTest < ActionController::TestCase
24   should_render_in_global_context
25
26   def setup
27     setup_ssl_from_config
28   end
29
30   should "show pending activation" do
31     get :pending_activation
32     assert_response :success
33   end
34
35   should "redirect from pending activation if logged in" do
36     login_as :johan
37     get :pending_activation
38     assert_response :redirect
39   end
40
41   should "activate user" do
42     assert_nil User.authenticate("moe", "test")
43     get :activate, :activation_code => users(:moe).activation_code
44     assert_redirected_to("/")
45     assert_not_nil flash[:notice]
46     assert_equal users(:moe), User.authenticate("moe@example.com", "test")
47   end
48
49   should "flashes a message when the activation code is invalid" do
50     get :activate, :activation_code => "fubar"
51     assert_redirected_to("/")
52     assert_nil flash[:notice]
53     assert_equal "Invalid activation code", flash[:error]
54     assert_nil User.authenticate("moe@example.com", "test")
55   end
56
57   def create_user(options = {})
58     post :create, :user => { :login => "quire", :email => "quire@example.com",
59       :password => "quire", :password_confirmation => "quire",
60       :terms_of_use => "1" }.merge(options)
61   end
62
63   should "allow signups" do
64     assert_difference("User.count") do
65       create_user
66       assert_redirected_to :action => "pending_activation"
67     end
68   end
69
70   should "require login on signup" do
71     assert_no_difference("User.count") do
72       create_user(:login => nil)
73       assert_not_nil assigns(:user).errors[:login]
74       assert_template("users/new")
75     end
76   end
77
78   should "require password on signup" do
79     assert_no_difference("User.count") do
80       create_user(:password => nil)
81       assert !assigns(:user).errors[:password].empty?
82       assert_template(("users/new"))
83     end
84   end
85
86   should "require password confirmation on signup" do
87     assert_no_difference("User.count") do
88       create_user(:password_confirmation => nil)
89       assert !assigns(:user).errors[:password_confirmation].empty?
90       assert_template(("users/new"))
91     end
92   end
93
94   should "require email on signup" do
95     assert_no_difference("User.count") do
96       create_user(:email => nil)
97       assert !assigns(:user).errors[:email].empty?, "empty? should be false"
98       assert_template(("users/new"))
99     end
100   end
101
102   should "require acceptance of end user license agreement" do
103     assert_no_difference("User.count") do
104       create_user(:terms_of_use => nil)
105     end
106   end
107
108   should "be successful with valid data" do
109     assert_difference("User.count") do
110       create_user
111     end
112   end
113
114   should "requires the user to activate himself after posting valid data" do
115     create_user
116     assert_equal nil, User.authenticate("quire@example.com", "quire")
117     assert !@controller.send(:logged_in?)
118   end
119
120   should "shows the user" do
121     get :show, :id => users(:johan).login
122     assert_response :success
123     assert_equal users(:johan), assigns(:user)
124   end
125
126   should "not display the users email if he decides so" do
127     user = users(:johan)
128     user.update_attribute(:public_email, false)
129     get :show, :id => user.to_param
130     assert_response :success
131     assert_select "#sidebar ul li.email", 0
132   end
133
134   context "GET show" do
135     should "#show sets atom feed autodiscovery" do
136       user = users(:johan)
137       get :show, :id => user.login
138       assert_equal user_feed_path(user, :format => :atom), assigns(:atom_auto_discovery_url)
139     end
140
141     should "not display inactive users" do
142       user = users(:johan)
143       user.update_attribute(:activation_code, "123")
144       assert !user.activated?
145
146       get :show, :id => user.to_param
147       assert_response :redirect
148       assert_match(/is not public/, flash[:notice])
149     end
150
151     context "paginating user events" do
152       setup { @params = { :id => users(:johan).login } }
153       should_scope_pagination_to(:show, Event)
154     end
155   end
156
157   should "has an atom feed" do
158     user = users(:johan)
159     get :feed, :id => user.login, :format => "atom"
160     assert_response :success
161     assert_equal user, assigns(:user)
162     assert_equal user.events.limit(30).order("created_at desc").all, assigns(:events)
163   end
164
165   context "#forgot_password" do
166     should "GETs the page fine for everyone" do
167       get :forgot_password
168       assert_response :success
169       assert_template(("forgot_password"))
170     end
171   end
172
173   context "#reset" do
174     setup do
175       @user = users(:johan)
176       @user.update_attribute(:password_key, "s3kr1t")
177     end
178
179     should "redirect if the token is invalid" do
180       get :reset_password, :token => "invalid"
181       assert_response :redirect
182       assert_redirected_to forgot_password_users_path
183       assert_not_nil flash[:error]
184     end
185
186     should "render the form if the token is valid" do
187       get :reset_password, :token => "s3kr1t"
188       assert_response :success
189       assert_equal @user, assigns(:user)
190       assert_nil flash[:error]
191     end
192
193     should "re-render if password confirmation does not match" do
194       put :reset_password, :token => "s3kr1t", :user => {
195         :password => "qwertyasdf",
196         :password_confirmation => "asdf"
197       }
198       assert_response :success
199       assert !assigns(:user).valid?
200       assert_nil User.authenticate(@user.email, "qwertyasdf")
201     end
202
203     should "update the password" do
204       put :reset_password, :token => "s3kr1t", :user => {
205         :password => "qwertyasdf",
206         :password_confirmation => "qwertyasdf"
207       }
208       assert_response :redirect
209       assert_redirected_to new_sessions_path
210       assert User.authenticate(@user.email, "qwertyasdf")
211       assert_match(/Password updated/i, flash[:success])
212     end
213   end
214
215   context "#forgot_password_create" do
216     should "redirects to forgot_password if nothing was found" do
217       post :forgot_password_create, :user => {:email => "xxx"}
218       assert_redirected_to(forgot_password_users_path)
219       assert_match(/invalid email/i, flash[:error])
220     end
221
222     should "sends a new password if email was found" do
223       u = users(:johan)
224       User.expects(:generate_reset_password_key).returns("secret")
225       Mailer.expects(:forgotten_password).with(u, "secret").returns(FakeMail.new)
226       post :forgot_password_create, :user => {:email => u.email}
227       assert_redirected_to(root_path)
228       assert_match(/A password confirmation link has been sent/, flash[:success])
229     end
230
231     should "notify non-activated users that they need to activate their accounts before resetting the password" do
232       user = users(:johan)
233       user.expects(:activated?).returns(false)
234       User.expects(:find_by_email).returns(user)
235       post :forgot_password_create, :user => {:email => user.email}
236       assert_redirected_to forgot_password_users_path
237       assert_match(/activated yet/, flash[:error])
238     end
239   end
240
241   context "in Private Mode" do
242     setup do
243       @test_settings = Gitorious::Configuration.prepend("public_mode" => false)
244     end
245
246     teardown do
247       Gitorious::Configuration.prune(@test_settings)
248     end
249
250     should "activate user" do
251       assert_nil User.authenticate("moe", "test")
252       get :activate, :activation_code => users(:moe).activation_code
253
254       assert_redirected_to("/")
255       assert !flash[:notice].nil?
256       assert_equal users(:moe), User.authenticate("moe@example.com", "test")
257     end
258
259     should "flashes a message when the activation code is invalid" do
260       get :activate, :activation_code => "fubar"
261       assert_redirected_to("/")
262       assert_nil flash[:notice]
263       assert_equal "Invalid activation code", flash[:error]
264       assert_nil User.authenticate("moe@example.com", "test")
265     end
266
267     should "GET /users/johan" do
268       get :show, :id => users(:johan).to_param
269       assert_redirected_to(root_path)
270       assert_match(/Action requires login/, flash[:error])
271     end
272
273     should "GET /users/new" do
274       get :new
275       assert_redirected_to(root_path)
276       assert_match(/Action requires login/, flash[:error])
277     end
278
279     should "GET /users/forgot_password" do
280       get :forgot_password
281       assert_response :success
282     end
283   end
284
285   context "account-related tests" do
286     setup do
287       login_as :johan
288     end
289
290     should "require current_user" do
291       login_as :moe
292       get :edit, :id => users(:johan).to_param
293       assert_response :redirect
294       assert_redirected_to user_path(users(:moe))
295     end
296
297     should "GET /users/johan/edit is successful" do
298       get :edit, :id => users(:johan).to_param
299       assert_response :success
300     end
301
302     should "render the field for favorite notifications" do
303       get :edit, :id => users(:johan).to_param
304
305       assert_select "input#user_default_favorite_notifications"
306     end
307
308     should "PUT /users/create with valid data is successful" do
309       put :update, :id => users(:johan).to_param, :user => {
310         :password => "fubar",
311         :password_confirmation => "fubar"
312       }
313       assert !flash[:success].nil?
314       assert_redirected_to(user_path(assigns(:user)))
315     end
316
317     should "GET require current_user" do
318       login_as :moe
319       get :password, :id => users(:johan).to_param
320       assert_response :redirect
321       assert_redirected_to user_path(users(:moe))
322     end
323
324     should "GET /users/johan/password is a-ok" do
325       get :password, :id => users(:johan).to_param
326       assert_response :success
327       assert_equal users(:johan), assigns(:user)
328     end
329
330     should "PUT requires current_user" do
331       login_as :moe
332       put :update_password, :id => users(:johan).to_param, :user => {
333         :current_password => "test",
334         :password => "fubar",
335         :password_confirmation => "fubar" }
336       assert_response :redirect
337       assert_redirected_to user_path(users(:moe))
338     end
339
340     should "PUT /users/joan/update_password updates password if old one matches" do
341       user = users(:johan)
342       put :update_password, :id => user.to_param, :user => {
343         :current_password => "test",
344         :password => "fubar",
345         :password_confirmation => "fubar" }
346       assert_redirected_to(user_path(user))
347       assert_match(/Your password has been changed/i, flash[:success])
348       assert_equal user, User.authenticate(user.email, "fubar")
349     end
350
351     should "PUT /users/johan/update_password does not update password if old one is wrong" do
352       put :update_password, :id => users(:johan).to_param, :user => {
353         :current_password => "notthecurrentpassword",
354         :password => "fubar",
355         :password_confirmation => "fubar" }
356       assert_nil flash[:notice]
357       assert_match(/does not seem to match/, flash[:error])
358       assert_template("users/password")
359       assert_equal users(:johan), User.authenticate(users(:johan).email, "test")
360       assert_nil User.authenticate(users(:johan).email, "fubar")
361     end
362
363     should "PUT /users/johan/update should not update password" do
364       user = users(:johan)
365       put :update, :id => user.to_param, :user => {
366         :password => "fubar",
367         :password_confirmation => "fubar" }
368
369       assert_nil User.authenticate(user.email, "fubar")
370       assert_equal user, User.authenticate(user.email, "test")
371     end
372
373     should "be able to update password, even if user is openid enabled" do
374       user = users(:johan)
375       user.update_attribute(:identity_url, "http://johan.someprovider.com/")
376       put :update_password, :id => user.to_param, :user => {
377         :current_password => "test",
378         :password => "fubar",
379         :password_confirmation => "fubar" }
380       assert_match(/Your password has been changed/i, flash[:success])
381       assert_equal users(:johan), User.authenticate(users(:johan).email, "fubar")
382     end
383
384     should "be able to update password, even if user created his account with openid" do
385       user = create_open_id_user("mropenid", "open@id.com", "http://myauth")
386       login_as user
387       put :update_password, :id => user.to_param, :user => {
388         :password => "fubar",
389         :password_confirmation => "fubar" }
390       assert_redirected_to user_path(user)
391       assert_match(/Your password has been changed/i, flash[:success])
392       assert_equal user, User.authenticate("open@id.com", "fubar")
393     end
394
395     should "be able to delete his avatar" do
396       user = users(:johan)
397       user.update_attribute(:avatar_file_name, "foo.png")
398       assert user.avatar?
399       delete :avatar, :id => user.to_param
400       assert_redirected_to user_path(user)
401       assert !user.reload.avatar?
402     end
403   end
404
405   context "deleting your own account" do
406     should "be allowed if you don't own any projects or repos" do
407       user = create_open_id_user("thomas", "thomas@openid.com", "http://myauth")
408       login_as user
409       assert_response :success
410       assert user.deletable?
411       get :delete_current, :id => user.id
412       assert_match(/Account deleted/i, flash[:success])
413       assert_redirected_to root_path
414       assert_nil User.find_by_login "thomas"
415     end
416
417     should "be prevented, with feedback message, if repos or projects present" do
418       user = users(:moe) # has projects and repos
419       login_as user
420       assert_response :success
421       assert !user.deletable?
422       get :delete_current, :id => user.id
423       assert_redirected_to user_path(user)
424       assert_match(/Please delete or change ownership of your projects/i, flash[:error])
425       assert_not_nil User.find_by_login(user.login)
426     end
427   end
428
429   context "Viewing ones own favorites" do
430     setup {
431       login_as(:johan)
432       @user = users(:johan)
433       @merge_request = merge_requests(:moes_to_johans)
434       @user.favorites.create(:watchable => @merge_request)
435       @project = projects(:johans)
436       @user.favorites.create(:watchable => @project)
437     }
438
439     should "render all" do
440       get :show, :id => @user.login
441       assert_response :success
442     end
443   end
444
445   context "Watchlist" do
446     setup { @user = users(:johan) }
447     teardown { Rails.cache.clear }
448
449     should "render activities watched by the user" do
450       get :watchlist, :id => @user.to_param, :format => "atom"
451       assert_response :success
452     end
453
454     should "not fail rendering feed when an event's user is nil" do
455       repository = repositories(:johans)
456       repository.project.events.create!({
457         :action => Action::DELETE_TAG,
458         :target => repository,
459         :user => nil,
460         :user_email => "marius@gitorious.com",
461         :body => "Bla bla",
462         :data => "A string of some kind"
463       })
464
465       get :watchlist, :id => @user.to_param, :format => "atom"
466
467       assert_response :success
468     end
469   end
470
471   context "Message privacy" do
472     setup {@username = :johan}
473
474     should "not expose messages unless current user" do
475       login_as :moe
476       get :show, :id => @username.to_s
477       assert_nil assigns(:messages)
478     end
479
480     should "expose messages if current user" do
481       login_as @username
482       get :show, :id => @username.to_s
483       assert_not_nil assigns(:messages)
484     end
485   end
486
487   context "Creation from OpenID" do
488     setup do
489       @valid_session_options = {:openid_url => "http://moe.example/", :openid_nickname => "schmoe"}
490     end
491
492     should "deny access unless OpenID information is present in the session" do
493       get :openid_build
494       assert_response :redirect
495     end
496
497     should "build a user from the OpenID information and render the form" do
498       get :openid_build, {}, @valid_session_options
499       user = assigns(:user)
500       assert_not_nil user
501       assert_equal "http://moe.example/", user.identity_url
502       assert_response :success
503     end
504
505     should "render the form unless all required fields have been filled" do
506       post :openid_create, {:user => {}}, @valid_session_options
507       user = assigns(:user)
508       assert_response :success
509       assert_template "users/openid_build"
510     end
511
512     should "create a user with the provided credentials and openid url on success" do
513       assert_incremented_by(ActionMailer::Base.deliveries, :size, 1) do
514         post :openid_create, {:user => {
515           :fullname => "Moe Schmoe",
516           :email => "moe@schmoe.example",
517           :login => "schmoe",
518           :terms_of_use => "1"
519           }
520         }, @valid_session_options
521       end
522
523       user = assigns(:user)
524       assert user.activated?
525       assert user.terms_accepted?
526       assert_nil session[:openid_url]
527       assert_equal user, @controller.send(:current_user)
528       assert_response :redirect
529     end
530
531     should "redirect to the dashboard on successful creation" do
532       post :openid_create, { :user => {
533           :fullname => "Moe Schmoe",
534           :email => "moe@schmoe.example",
535           :login => "schmoe",
536           :terms_of_use => "1"
537         }
538       }, @valid_session_options
539
540       assert_redirected_to "/"
541     end
542   end
543
544   context "With private repositories" do
545     setup do
546       @user = users(:johan)
547       @project = @user.projects.first
548       enable_private_repositories
549     end
550
551     should "filter projects" do
552       get :show, :id => @user.to_param
553       assert assigns(:projects).none? { |p| p == @project }
554     end
555
556     should "show authorized projects" do
557       login_as :johan
558       get :show, :id => @user.to_param
559       assert assigns(:projects).any? { |p| p == @project }
560     end
561
562     should "filter commit repositories" do
563       get :show, :id => @user.to_param
564       assert assigns(:repositories).none? { |r| r.project == @project }
565     end
566
567     should "show authorized commit repositories" do
568       login_as :johan
569       get :show, :id => @user.to_param
570       assert assigns(:repositories).any? { |r| r.project == @project }
571     end
572
573     should "filter events" do
574       create_event(projects(:moes), @project.repositories.first)
575       create_event(@project, @project.repositories.first)
576       create_event(projects(:moes), projects(:moes).repositories.first)
577
578       get :show, :id => @user.to_param
579       assert_equal 1, assigns(:events).length
580       assert assigns(:events).none? { |e| e.project == @project }
581     end
582
583     should "show authorized events" do
584       create_event(projects(:moes), @project.repositories.first)
585       create_event(@project, @project.repositories.first)
586       create_event(projects(:moes), projects(:moes).repositories.first)
587
588       login_as :johan
589       get :show, :id => @user.to_param
590       assert_equal 3, assigns(:events).length
591     end
592
593     should "filter favorites" do
594       get :show, :id => @user.to_param
595       assert assigns(:favorites).none? { |f| f.project == @project }
596     end
597
598     should "show authorized favorites" do
599       login_as :johan
600       get :show, :id => @user.to_param
601       assert assigns(:favorites).any? { |f| f.project == @project }
602     end
603
604     should "exclude unauthorized events from atom feed" do
605       create_event(projects(:moes), @project.repositories.first)
606       create_event(@project, @project.repositories.first)
607       create_event(projects(:moes), projects(:moes).repositories.first)
608
609       get :feed, :id => @user.to_param, :format => "atom"
610
611       assert_equal 1, assigns(:events).length
612     end
613
614     should "include authorized events in atom feed" do
615       create_event(projects(:moes), @project.repositories.first)
616       create_event(@project, @project.repositories.first)
617       create_event(projects(:moes), projects(:moes).repositories.first)
618
619       login_as :johan
620       get :feed, :id => @user.to_param, :format => "atom"
621
622       assert_equal 3, assigns(:events).length
623     end
624   end
625
626   private
627   def create_event(project, target)
628     e = Event.new({ :target => target,
629                     :data => "master",
630                     :action => Action::CREATE_BRANCH })
631     e.user = @user
632     e.project = project
633     e.save!
634   end
635
636   def create_open_id_user(login, email, identity_url)
637     user = User.new
638     user.login = login
639     user.email = email
640     user.identity_url = identity_url
641     user.terms_of_use = "1"
642     user.accept_terms
643     user.activate
644     user.save!
645     user
646   end
647 end