Hello i have a Rspec/Capybara test im trying to make.
Im a logged in user that as admin user should be the only user to add Sizes to my app.
I just can't get the test to Login the user. Can anyone see why?
Please look at the sessions controller below. I do have a log_in method.
Error is
Failures:
1) adding size allow a admin user to add a size
Failure/Error: log_in(admin)
NoMethodError:
undefined method `log_in' for #<RSpec::ExampleGroups::AddingSize:0x007f8e4fa828e0>
# ./spec/features/sizes_features.rb:9:in `block (2 levels) in <top (required)>'
Test
require "rails_helper"
RSpec.feature "adding size" do
let(:size01) { FactoryGirl.build :size01 }
let(:user) { FactoryGirl.build :user }
let(:admin) { FactoryGirl.create(:user, admin: true) }
scenario "allow a admin user to add a size" do
log_in(admin)
size = create(:size01)
visit new_size_path
fill_in 'Title', with: "example"
click_button 'Create Size'
expect(current_path).to eql(sizes_path)
expect(page).to have_content("example")
end
scenario "user can't add size" do
log_in(user)
visit sizes_path
expect(current_path).to eql(root_path)
expect(page).to have_content("Rescricted Web Page")
end
scenario "vistor can't add size" do
visit sizes_path
expect(current_path).to eql(root_path)
end
end
FactoryGirl
FactoryGirl.define do
factory :user, :class => User do
username "example"
email "[email protected]"
admin "false"
password_digest "<%= User.digest('password') %>"
activated "true"
activated_at "<%= Time.zone.now %>"
end
end
Sessions controller.
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
end
# Returns the user corresponding to the remember token cookie.
def current_user
if (user_id = session[:user_id])
@current_user ||= User.find_by(id: user_id)
elsif (user_id = cookies.signed[:user_id])
user = User.find_by(id: user_id)
if user && user.authenticated?(:remember, cookies[:remember_token])
log_in user
@current_user = user
end
end
end
# Returns true if the user is logged in, false otherwise.
def logged_in?
!current_user.nil?
end
# Logs out the current user.
def log_out
session.delete(:user_id)
@current_user = nil
end
# Remembers a user in a persistent session.
def remember(user)
user.remember
cookies.permanent.signed[:user_id] = user.id
cookies.permanent[:remember_token] = user.remember_token
end
# Returns true if the given user is the current user.
def current_user?(user)
user == current_user
end
# Forgets a persistent session.
def forget(user)
user.forget
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
# Logs out the current user.
def log_out
forget(current_user)
session.delete(:user_id)
@current_user = nil
end
# Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(session[:forwarding_url] || default)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.url if request.get?
end
end
Here is why it's not working:
Access to session and request is not possible from the test, Access to response is limited. Some drivers allow access to response headers and HTTP status code, but this kind of functionality is not provided by some drivers, such as Selenium.
source: Capybara documentation
You have two options:
If you're using Devise for authentication, Devise provides authentication helpers you should use.
Otherwise, here's how I would approach your situation:
Instead of trying to directly manipulate the session, create a shared context or a helper that logs in the user by interacting with the login form in the same way a user browsing your site would.
Here is one approach:
spec/support/when_authenticated.rb
RSpec.shared_context 'When authenticated' do
background do
authenticate
end
def authenticate
visit '/sessions/new'
within('form#session') do
fill_in 'Email', :with => '[email protected]'
fill_in 'Password', :with => 'password'
end
click_button 'Sign in'
end
end
Then, in your feature spec:
RSpec.feature 'User does something' do
include_context 'When authenticated'
# examples
end
This has the effect of running the authentication procedure before each example in your spec.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With