# coding: utf-8 require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') # XXX Use route_for or params_from to check /c/ links better # http://rspec.rubyforge.org/rspec-rails/1.1.12/classes/Spec/Rails/Example/ControllerExampleGroup.html describe UserController, "when redirecting a show request to a canonical url" do it "should redirect to lower case name if given one with capital letters" do get :show, :url_name => "Bob_Smith" response.should redirect_to(:controller => 'user', :action => 'show', :url_name => "bob_smith") end it 'should redirect a long non-canonical name that has a numerical suffix, retaining the suffix' do get :show, :url_name => 'Bob_SmithBob_SmithBob_SmithBob_S_2' response.should redirect_to(:controller => 'user', :action => 'show', :url_name => 'bob_smithbob_smithbob_smithbob_s_2') end it 'should not redirect a long canonical name that has a numerical suffix' do User.stub!(:find).with(:first, anything()).and_return(mock_model(User, :url_name => 'bob_smithbob_smithbob_smithbob_s_2', :name => 'Bob Smith Bob Smith Bob Smith Bob Smith')) User.stub!(:find).with(:all, anything()).and_return([]) get :show, :url_name => 'bob_smithbob_smithbob_smithbob_s_2' response.should be_success end end describe UserController, "when showing a user" do render_views before(:each) do load_raw_emails_data get_fixtures_xapian_index end it "should be successful" do get :show, :url_name => "bob_smith" response.should be_success end it "should render with 'show' template" do get :show, :url_name => "bob_smith" response.should render_template('show') end it "should distinguish between 'my profile' and 'my requests' for logged in users" do session[:user_id] = users(:bob_smith_user).id get :show, :url_name => "bob_smith", :view => 'requests' response.body.should_not include("Change your password") response.body.should match(/Your [0-9]+ Freedom of Information requests/) get :show, :url_name => "bob_smith", :view => 'profile' response.body.should include("Change your password") response.body.should_not match(/Your [0-9]+ Freedom of Information requests/) end it "should assign the user" do get :show, :url_name => "bob_smith" assigns[:display_user].should == users(:bob_smith_user) end it "should search the user's contributions" do get :show, :url_name => "bob_smith" assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all( :conditions => "user_id = #{users(:bob_smith_user).id}") get :show, :url_name => "bob_smith", :user_query => "money" assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [ info_requests(:naughty_chicken_request), info_requests(:another_boring_request), ] end it "should not show unconfirmed users" do begin get :show, :url_name => "unconfirmed_user" rescue => e end e.should be_an_instance_of(ActiveRecord::RecordNotFound) end end describe UserController, "when signing in" do render_views before do # Don't call out to external url during tests controller.stub!(:country_from_ip).and_return('gb') end def get_last_postredirect post_redirects = PostRedirect.find_by_sql("select * from post_redirects order by id desc limit 1") post_redirects.size.should == 1 post_redirects[0] end it "should show sign in / sign up page" do get :signin response.should have_selector("input#signin_token") end it "should create post redirect to / when you just go to /signin" do get :signin post_redirect = get_last_postredirect post_redirect.uri.should == "/" end it "should create post redirect to /list when you click signin on /list" do get :signin, :r => "/list" post_redirect = get_last_postredirect post_redirect.uri.should == "/list" end it "should show you the sign in page again if you get the password wrong" do get :signin, :r => "/list" response.should render_template('sign') post_redirect = get_last_postredirect post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'NOTRIGHTPASSWORD' }, :token => post_redirect.token } response.should render_template('sign') end it "should log in when you give right email/password, and redirect to where you were" do get :signin, :r => "/list" response.should render_template('sign') post_redirect = get_last_postredirect post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'jonespassword' }, :token => post_redirect.token } session[:user_id].should == users(:bob_smith_user).id # response doesn't contain /en/ but redirect_to does... response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1) ActionMailer::Base.deliveries.should be_empty end it "should not log you in if you use an invalid PostRedirect token, and shouldn't give 500 error either" do post_redirect = "something invalid" lambda { post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'jonespassword' }, :token => post_redirect } }.should_not raise_error(NoMethodError) post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'jonespassword' }, :token => post_redirect } response.should render_template('sign') assigns[:post_redirect].should == nil end # No idea how to test this in the test framework :( # it "should have set a long lived cookie if they picked remember me, session cookie if they didn't" do # get :signin, :r => "/list" # response.should render_template('sign') # post :signin, { :user_signin => { :email => 'bob@localhost', :password => 'jonespassword' } } # session[:user_id].should == users(:bob_smith_user).id # raise session.options.to_yaml # check cookie lasts a month # end it "should ask you to confirm your email if it isn't confirmed, after log in" do get :signin, :r => "/list" response.should render_template('sign') post_redirect = get_last_postredirect post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' }, :token => post_redirect.token } response.should render_template('confirm') ActionMailer::Base.deliveries.should_not be_empty end it "should confirm your email, log you in and redirect you to where you were after you click an email link" do get :signin, :r => "/list" post_redirect = get_last_postredirect post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' }, :token => post_redirect.token } ActionMailer::Base.deliveries.should_not be_empty deliveries = ActionMailer::Base.deliveries deliveries.size.should == 1 mail = deliveries[0] mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/ mail_url = $1 mail_path = $2 mail_token = $3 # check is right confirmation URL mail_token.should == post_redirect.email_token Rails.application.routes.recognize_path(mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token } # check confirmation URL works session[:user_id].should be_nil get :confirm, :email_token => post_redirect.email_token session[:user_id].should == users(:unconfirmed_user).id response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1) end it "should keep you logged in if you click a confirmation link and are already logged in as an admin" do get :signin, :r => "/list" post_redirect = get_last_postredirect post :signin, { :user_signin => { :email => 'unconfirmed@localhost', :password => 'jonespassword' }, :token => post_redirect.token } ActionMailer::Base.deliveries.should_not be_empty deliveries = ActionMailer::Base.deliveries deliveries.size.should == 1 mail = deliveries[0] mail.body.to_s =~ /(http:\/\/.*(\/c\/(.*)))/ mail_url = $1 mail_path = $2 mail_token = $3 # check is right confirmation URL mail_token.should == post_redirect.email_token Rails.application.routes.recognize_path(mail_path).should == { :controller => 'user', :action => 'confirm', :email_token => mail_token } # Log in as an admin session[:user_id] = users(:admin_user).id # Get the confirmation URL, and check we’re still Joe get :confirm, :email_token => post_redirect.email_token session[:user_id].should == users(:admin_user).id # And the redirect should still work, of course response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1) end end describe UserController, "when signing up" do render_views before do # Don't call out to external url during tests controller.stub!(:country_from_ip).and_return('gb') end it "should be an error if you type the password differently each time" do post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person', :password => 'sillypassword', :password_confirmation => 'sillypasswordtwo' } } assigns[:user_signup].errors[:password].should == ['Please enter the same password twice'] end it "should be an error to sign up with a misformatted email" do post :signup, { :user_signup => { :email => 'malformed-email', :name => 'Mr Malformed', :password => 'sillypassword', :password_confirmation => 'sillypassword' } } assigns[:user_signup].errors[:email].should_not be_nil end it "should send confirmation mail if you fill in the form right" do post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person', :password => 'sillypassword', :password_confirmation => 'sillypassword' } } response.should render_template('confirm') deliveries = ActionMailer::Base.deliveries deliveries.size.should == 1 deliveries[0].body.should include("not reveal your email") end it "should send confirmation mail in other languages or different locales" do session[:locale] = "es" post :signup, {:user_signup => { :email => 'new@localhost', :name => 'New Person', :password => 'sillypassword', :password_confirmation => 'sillypassword', } } response.should render_template('confirm') deliveries = ActionMailer::Base.deliveries deliveries.size.should == 1 deliveries[0].body.should include("No revelaremos") end it "should send special 'already signed up' mail if you fill the form in with existing registered email" do post :signup, { :user_signup => { :email => 'silly@localhost', :name => 'New Person', :password => 'sillypassword', :password_confirmation => 'sillypassword' } } response.should render_template('confirm') deliveries = ActionMailer::Base.deliveries deliveries.size.should == 1 # This text may span a line break, depending on the length of the SITE_NAME deliveries[0].body.should match(/when\s+you\s+already\s+have\s+an/) end # XXX need to do bob@localhost signup and check that sends different email end describe UserController, "when signing out" do