I am following tutorials mentioned https://www.railstutorial.org/book/log_in_log_out.
While I am executing a test with given command :
bundle exec rake test TEST=test/helpers/sessions_helper_test.rb
I am encountering Errors given below :
1) Error:
ApplicationHelperTest#test_current_user_returns_nil_when_remember_digest_is_wrong:
NoMethodError: undefined method remember' for #<ApplicationHelperTest:0x000000075bf4d0>
test/helpers/sessions_helper_test.rb:7:insetup'
2) Error:
ApplicationHelperTest#test_Current_user_returns_right_user_with_session_is_nill:
NoMethodError: undefined method remember' for #<ApplicationHelperTest:0x00000007702400>
test/helpers/sessions_helper_test.rb:7:insetup'
I have a helper class methods defined in /apps/helpers/session_helper.rd.
--remember method is part of this class .. still the /test/helpers/sessions_helper_test is unable to find that method.
Code for /test/helpers/sessions_helper_test.rb file is
require 'test_helper'
class ApplicationHelperTest < ActionView::TestCase
def setup
#user = users(:michael)
remember(#user)
end
test "Current_user returns right user with session is nill" do
assert_equal #user, current_user
assert is_logged_in?
end
test "current_user returns nil when remember digest is wrong" do
#user.update_attribute(:remember_digest, User.digest(User.new_token))
assert_nil current_user
end
end
This is a code for module SessionsHelper
module SessionsHelper
# Logs in the given user.
def log_in(user)
session[:user_id] = user.id
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 the current logged-in user (if any).
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?(cookies[:remember_token]) #here is an Evaluation Magic for a given Method
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. # Actions (Set digest to Nill) (Delete the Cookie) (Delete the Session) (Set current_user variable to nill)
def log_out
forget(current_user)
session.delete(:user_id)
#current_user = nil
end
def forget(user)
user.forget # is to forget the user .. means set th remember_digest to nill -- Go to User Model
cookies.delete(:user_id)
cookies.delete(:remember_token)
end
end
Users.yml file is :
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
michael:
name: Michael Example
email: michael#example.com
password_digest: <%= User.digest('password') %>
archer:
name: Sterling Archer
email: duchess#example.gov
password_digest: <%= User.digest('password') %>
-----------------Got the Solution -------------------
you need to include HelperModule to test Module ..
after fix code for test/helpers/sessions_helper_test.rb will look like
require 'test_helper'
class ApplicationHelperTest < ActionView::TestCase
include SessionsHelper # This line is added to code.
def setup
#user = users(:michael)
remember(#user)
end
test "Current_user returns right user with session is nill" do
assert_equal #user, current_user
assert is_logged_in?
end
test "current_user returns nil when remember digest is wrong" do
#user.update_attribute(:remember_digest, User.digest(User.new_token))
assert_nil current_user
end
end
Following the tutorial as well and had a similar issue. You can avoid using include by updating your class from:
class ApplicationHelperTest < ActionView::TestCase
to:
class SessionsHelperTest < ActionView::TestCase
Related
I have an integration test where I need to call the log_in function (defined in Session Helper) whose parameter is a user created within a fixture.
app/helpers/sessions_helper
module SessionsHelper
def log_in(user)
session[:user_id] = user.id
end
.
.
.
end
Then I have the following fixture test/fixtures/user.yml
johndoe:
first_name: John
last_name: Doe
email: john#doe.com
password_digest: <%= User.digest('password') %>
And then the following integration test test/integration/user_navigation_test
require 'test_helper'
class UserNavigationTest < ActionDispatch::IntegrationTest
def setup
#user = users(:johndoe)
end
test "login with invalid information" do
log_in #user
end
end
When I run the test, I have the following error.
ERROR["test_login_with_invalid_information", UserNavigationTest, 1.2090159619983751]
test_login_with_invalid_information#UserNavigationTest (1.21s)
NoMethodError: NoMethodError: undefined method `log_in' for #<UserNavigationTest:0x000000065cb3f8>
test/integration/user_navigation_test.rb:10:in `block in <class:UserNavigationTest>'
I've tried to declare the log_in function within the test_helper but it didn't work either ; something to do with the configuration apparently.
How can I handle this?
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 "example#example.com"
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 => 'user#example.com'
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.
I am currently having trouble testing for destroying users generated with devise.
require 'test_helper'
class UserTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
def setup
#user = User.new(email: "user#example.com")
end
test "Should delete User"do
#user.save
assert_difference 'User.count', -1 do
#user.destroy
end
end
end
Currently the tests
fail and show that the difference was 0. I was wondering how I could test this (even though I know user.destroy works when I run it in a rails console).
All the best
D
I think, there is problem with saving the user #user.save. This is due the validation error. Default Devises User has a password as a mandatory field.
Try changing:
def setup
#user = User.new(email: "user#example.com")
end
to:
def setup
#user = User.new(email: "user#example.com",
password: "SuperS3cret")
end
The #user should be properly saved, and it make #user.destroy to work, and assert_difference to pass.
Good luck!
I'm having trouble finding examples of valid_session in RSpec, and now all my scaffolded tests are broken after having added authorization.
Going through Michael Hartl's Rails Tutorial, I'm using the authentication which is described here, except I'm requiring login for all pages and use 'skip_before_filter' for signin etc.
I've added a user fixture, which I've verified gets loaded:
userexample:
id: 1
name: Example Name
email: examplename#example.com
password_digest: $2a$10$NuWL8f2X0bXaCof3/caiiOwlF2rago7hH10JECmw1p75kEpf0mkie
remember_token: YXjPrFfsK8SFQOQDEa90ow
Then in the controller spec
def valid_session
{ remember_token: "YXjPrFfsK8SFQOQDEa90ow" }
end
The code of the Session Helper
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def signed_in?
return !current_user.nil?
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
end
Am I using valid_session as intended? Will supplying a remember_token with the session even work without explicitly signing in the user with sign_in? Could this be solved in some other way?
This should work for you...
def valid_session
controller.stub!(:signed_in?).and_return(true)
end
...based on something similar that worked for me :D
def valid_session
controller.stub!(:authorize).and_return(User)
end
I have a simple user login system:
module SessionsHelper
def logged_in?
current_user.present?
end
def current_user
#current_user ||= begin
if session[:current_user_id]
User.find(session[:current_user_id]) rescue nil
end
end
end
end
which I include in ApplicationController:
class ApplicationController < ActionController::Base
include SessionsHelper
helper SessionsHelper
I am trying to test the banners controller:
require 'spec_helper'
describe Admin::BannersController do
describe 'POST create' do
let(:user){ create(:user_admin) }
before do
controller.stub(:current_user){ user }
end
it "create action should render new template when model is invalid" do
Banner.any_instance.stubs(:valid?).returns(false)
post :create
response.should render_template(:new)
end
:user_admin is the properly set up Factory Girl admin user.
However the test still says: You are not authorized to access this page.
This is from Cancan.
Did I not stub it properly? Thanks.
def fake_user
user = FactoryGirl.build(:user, :id => 100000 + rand(100000))
stub(controller).current_user { user }
user
end