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?
Related
Devise test helpers with Rails 6 without Rspec doesn't seem to work. Here is the code, any idea why it might be getting errors?
Controller:
class VehiclesController < ApplicationController
before_action :authenticate_user!, only: [:new]
def index
#vehicles = Vehicle.all
end
def new
#vehicle = Vehicle.new
end
end
test/test_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require_relative "../config/environment"
require "rails/test_help"
class ActiveSupport::TestCase
# Run tests in parallel with specified workers
parallelize(workers: :number_of_processors)
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
include Devise::Test::IntegrationHelpers
end
user fixture:
valid_user:
first_name: "Toseef"
last_name: "zafar"
email: "exampleuser#gmail.com"
encrypted_password: <%= Devise::Encryptor.digest(User, '12345678') %>
controller test:
require "test_helper"
class VehiclesControllerTest < ActionDispatch::IntegrationTest
test "should be able to get to new form page" do
sign_in users(:valid_user)
get new_vehicles_url
assert_response :success
end
end
and this is the error I get:
Failure:
VehiclesControllerTest#test_should_be_able_to_get_to_new_form_page [/test/controllers/vehicles_controller_test.rb:12]:
Expected response to be a <2XX: success>, but was a <302: Found> redirect to <http://www.example.com/users/sign_in>
Response body: <html><body>You are being redirected.</body></html>
rails test test/controllers/vehicles_controller_test.rb:9
Also, I don't know why it would point to http://www.example.com
The devise user model has got confirmable hence when we do sign_in users(:valid_user) devise creates a user but because the user is not confirmed (i.e. no confirmation email link clicking is involved) when we go to a secured URL it takes us back to login because user hasn't confirmed through clicking on the link from the email.
The solution to this is to set confirmed_at value to Time.now before sign_in
e.g.
#user = users(:valid_user)
#user.confirmed_at = Time.now
sign_in #user
after doing that the tests passed! :)
I'm going through Michael Hartl's Ruby tutorial and have been stuck for a day on a failing test
I get this when I run:
Error:
UsersControllerTest#test_should_redirect_edit_when_logged_in_as_wrong_user:
NoMethodError: undefined method `session' for nil:NilClass
test/test_helper.rb:19:in `log_in_as'
test/controllers/users_controller_test.rb:37:in `block in <class:UsersControllerTest>'
Here is the calling code:
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
def setup
#user = users(:michael)
#otheruser = users(:archer)
end
test "should redirect update when logged in as wrong user" do
log_in_as(#other_user)
patch user_path(#user), params: { user: { name: #user.name,
email: #user.email } }
assert flash.empty?
assert_redirected_to root_url
end
*And here is the method I'm trying to call from the **test_helper** class:*
# Log in as a particular user
def log_in_as(user)
session[:user_id] = user.id
end
I was missing a part in my test_helper.rb class:
class ActionDispatch::IntegrationTest
# Log in as a particular user.
def log_in_as(user, password: 'password', remember_me: '1')
post login_path, params: { session: { email: user.email,
password: password,
remember_me: remember_me } }
end
end
Thank you for taking a look!
Did you include this line of code: include SessionsHelper in your application_controller.rb?
You have typo in setup method from the code above: #otheruser = users(:archer) should be #other_user = users(:archer)
Check again the code from the test file: test / controllers / users_controller_test.rb
especially this part of the code:
test "should redirect edit when logged in as wrong user" do
log_in_as(#other_user)
get edit_user_path(#user)
assert flash.empty?
assert_redirected_to root_url
end
Hope it helps!
I'm trying to test user model, for which I've devise authentication.
The problem I'm facing is,
1. Having 'password'/'password_confirmation' fields in fixtures is giving me invalid column 'password'/'password_confirmation' error.
If I remove these columns from fixture and add in user_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
#user = User.new(name: "example user",
email: "example#example.com",
password: "Test123",
work_number: '1234567890',
cell_number: '1234567890')
end
test "should be valid" do
assert #user.valid?
end
test "name should be present" do
#user.name = "Example Name "
assert #user.valid?
end
end
The error I'm getting is:
test_0001_should be valid FAIL (0.74s)
Minitest::Assertion: Failed assertion, no message given.
test/models/user_test.rb:49:in `block in <class:UserTest>'
test_0002_name should be present FAIL (0.01s)
Minitest::Assertion: Failed assertion, no message given.
test/models/user_test.rb:54:in `block in <class:UserTest>'
Fabulous run in 0.75901s
2 tests, 2 assertions, 2 failures, 0 errors, 0 skips
I'm wondering why my user object is not valid?
Thanks
I got a work around after some investigation like below:
Add a helper method for fixture:
# test/helpers/fixture_file_helpers.rb
module FixtureFileHelpers
def encrypted_password(password = 'password123')
User.new.send(:password_digest, password)
end
end
# test/test_helper.rb
require './helpers/fixture_file_helpers.rb'
ActiveRecord::FixtureSet.context_class.send :include, FixtureFileHelpers
And make fixture like this:
default:
email: 'default#example.com'
name: "User name"
encrypted_password: <%= encrypted_password %>
work_number: '(911) 235-9871'
cell_number: '(911) 235-9871'
And use this fixture as user object in user test.
def setup
#user = users(:default)
end
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 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