Reputation: 35219
I have a SearchesController that requires a user to be logged in before it will do its thing.
I'd like to write an rspec helper function login
to emulate logging in for controller tests. (NB: I will handle integration / requests specs separately.) My attempts so haven't worked: the logged_in?
method in ApplicationController returns false.
The question: how do I write the 'login' helper?
Here's the RSpec controller test:
# file: spec/controllers/searches_controller_spec.rb
require 'spec_helper'
require 'controllers_helper'
describe SearchesController do
include ControllersHelper
describe "GET index" do
it 'without login renders login page' do
get :index
response.should redirect_to(login_path)
end
it 'with login finds searches belonging to user' do
me = FactoryGirl.create(:user)
my_searches = FactoryGirl.create_list(:search, 2, :user => me)
not_me = FactoryGirl.create(:user)
not_my_searches = FactoryGirl.create_list(:search, 2, :user => not_me)
login(me) # want to define this in spec/controllers_helper.rb
get :index
assigns(:searches).should =~ my_searches
end
end
end
Here's the Controller:
# file: app/controllers/searches_controller.rb
class SearchesController < ApplicationController
def index
unless logged_in?
redirect_to login_path, :alert => "You must be logged in to access this page."
else
@searches = Search.where(:user_id => current_user.id)
respond_to do |format|
format.html
format.json { render json: @searches }
end
end
end
end
And here's the ApplicationController code. Note that current_user = x
has the effect of logging x in, and it's rather simple: it sets @current_user and session[:user_id].
# file: app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
force_ssl
protected
def current_user
@current_user ||= User.find_by_id(session[:user_id])
end
def current_user=(user)
@current_user = user
session[:user_id] = user && user.id
end
def logged_in?
!!@current_user
end
def require_login
unless logged_in?
redirect_to login_path, :alert => "You must be logged in to access this page."
end
end
helper_method :current_user, :logged_in?, :require_login
end
Upvotes: 1
Views: 91
Reputation: 35219
I may have said this before, but if Stack Overflow gave badges answering one's own questions, I'd have a LOT of badges! :)
Okay, to answer this question you need to look at the documentation for ActionController::TestCase. When you do so, you'll find that it sets up bindings for:
@controller
@request
@response
So for the specific controller given in the OP, writing the login
method is trivial:
# file: spec/controllers_helper.rb
module ControllersHelper
def login(user)
@controller.send(:current_user=, user)
end
end
(Did I hear someone say RTFM again? I thought so...)
Upvotes: 1