How To: sign in and out a user in Request type specs (specs tagged with type: :request)
Pedro Schlickmann Mendes edited this page May 30, 2023
·
10 revisions
There are two approaches by which you can do this: (i) A Simple Approach and (ii) A More Complicated approach:
spec/rails_helper.rb
RSpec.configure do |config|
# ...
config.include Devise::Test::IntegrationHelpers, type: :request
end
And just use sign_in
in your request spec. This is the equivalent of declaring include Devise::Test::IntegrationHelpers
in an system/feature spec or Rails system/controller test.
A quick and dirty sessions test:
#./spec/requests/sessions_spec.rb
require 'rails_helper'
RSpec.describe "Sessions" do
it "signs user in and out" do
# user = create(:user) ## uncomment if using FactoryBot
# user = User.create(email: 'test@test.com', password: "password", password_confirmation: "password") ## uncomment if not using FactoryBot
sign_in user
get root_path
expect(response).to render_template(:index) # add gem 'rails-controller-testing' to your Gemfile first.
sign_out user
get root_path
expect(response).not_to render_template(:index) # add gem 'rails-controller-testing' to your Gemfile first.
end
end
ps: in case you have the confirmable module enabled, you will need to call user.confirm
before sign_in user
.
And you're off to the races!
Tested example code with the following environment:
rails 4.2.5.1
ruby-2.2.3p173
devise 3.5.4
rspec-core 3.4.2
rspec-rails 3.4.1
spec/support/request_spec_helper.rb
module RequestSpecHelper
include Warden::Test::Helpers
def self.included(base)
base.before(:each) { Warden.test_mode! }
base.after(:each) { Warden.test_reset! }
end
def sign_in(resource)
login_as(resource, scope: warden_scope(resource))
end
def sign_out(resource)
logout(warden_scope(resource))
end
private
def warden_scope(resource)
resource.class.name.underscore.to_sym
end
end
spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
RSpec.configure do |config|
# ...
config.include RequestSpecHelper, type: :request
# ...
end
config/routes.rb
Rails.application.routes.draw do
devise_for :users
authenticated do
root to: "secret#index", as: :authenticated_root
end
root to: "home#index"
# ...
end
spec/requests/sessions_spec.rb
require 'rails_helper'
RSpec.describe "Sessions" do
it "signs user in and out" do
user = User.create!(email: "user@example.org", password: "very-secret")
user.confirm
sign_in user
get authenticated_root_path
expect(controller.current_user).to eq(user)
sign_out user
get authenticated_root_path
expect(controller.current_user).to be_nil
end
end
- The code above was influenced by a solution at Stack Overflow