DEV Community

Discussion on: Authentication and Authorization à la Rails bcrypt

Collapse
 
guledali profile image
guledali • Edited
require "minitest/reporters"
Minitest::Reporters.use!

class ActiveSupport::TestCase
  fixtures :all


  # Log in as a particular user.
  def log_in_as(user)
    session[:user_id] = user.id
  end
end

# Below you have to monkeypatch open up the class ActionDispatch check the link below
# https://stackoverflow.com/questions/44461101/accessing-session-in-integration-test

class ActionDispatch::IntegrationTest

  # Log in as a particular user.
  def log_in_as(user, password: 'password')
    post login_path, params: { session: { email: user.email, password: password }
  end
end

Enter fullscreen mode Exit fullscreen mode

this how you would use the test-helper

class UsersEditTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:joe)
  end

  test "unsuccessful edit" do
    log_in_as(@user)          # HERE we are using the helper
    get edit_user_path(@user) # localhost:3000/users/1/edit 
    assert_response :success

    patch user_path(@user), params: { user: { name:  "",
                                              email: "invalid@invalid",
                                              password:              "password",
                                              password_confirmation: "password" } }

    assert_redirect_to edit_user_path(@user)
  end
Enter fullscreen mode Exit fullscreen mode

Also think this could be rewritten from

 if @user && @user.authenticate(params[:password])

Enter fullscreen mode Exit fullscreen mode

into

if @user.try!(:authenticate, params[:password])
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cristiano profile image
cristiano

Thanks for providing such a detailed example guledali! 🙏

Did this run okay for you? It doesn't really work for me sadly, the test still thinks the user is not authenticated, perhaps I'm thinking about building the test the wrong way but have found examples similar to these.

Not sure what I'm missing here, but I don't think it is wrong to think that it's worth testing that a controller action can be accessed and ran when the user is logged in right? 🤔

Thread Thread
 
cristiano profile image
cristiano

I got it working now, the mistake I was doing was to add the credentials to a :sessions hash when passing them to :params, which isn't required because of how the form is structured:

# 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

  # Add more helper methods to be used by all tests here...
  def sign_in_as(user, password)
    post sessions_url, params: { email: user.email, password: password }
  end
end
Enter fullscreen mode Exit fullscreen mode

An example of a controller test looks like:

test "should show user" do
  sign_in_as(@user, 'password')

  get user_url(@user)
  assert_response :success
end
Enter fullscreen mode Exit fullscreen mode

The way I was doing it wrong (adding :session or :sessions):

def sign_in_as(user, password)
  post sessions_url, params: { session: {email: user.email, password: password} }
end
Enter fullscreen mode Exit fullscreen mode