Import a helper function within an integration test - ruby-on-rails

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

Rails 6 Devise test helpers without RSpec

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! :)

NoMethodError error in Rails

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!

Testing User Model (Devise Authentication) with MiniTest

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

Testing for destroyed users in devise

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!

undefined method `remember' for #<ApplicationHelperTest:0x000000075bf4d0>

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

Resources