Search code examples
ruby-on-railsrubymodel-view-controllerrspec

Processing before user authentication in RSpec


I am making an application with rails.

and I am writing tests with rspec.I got an error.

I'll show you the error first.

Failure/Error: expect(response).to redirect_to user_path(user)
     
       Expected response to be a redirect to <http://www.example.com/users/1> but was a redirect to <http://www.example.com/login>.
       Expected "http://www.example.com/users/1" to be === "http://www.example.com/login".
     # ./spec/requests/users_request_spec.rb:28:in `block (3 levels) in <top (required)>'

I'll show you the test next.


require 'rails_helper'

RSpec.describe "Users", type: :request do

  describe "PATCH /users/:id" do
    let(:user) { FactoryBot.create(:user) }

    before { log_in_as(user) }

it 'Successful edit with valid information entered' do
      patch user_path(user), params: { user: {
        name: "Foo Bar",
        email: "[email protected]",
        password: "",
        password_confirmation: "",
      } }
      expect(response).to redirect_to user_path(user)
    end
  end
end

Show the log_in_as(user) method at the beginning of the test.

spec/support/integration_helpers.rb

module IntegrationHelpers
    def is_logged_in?
      !session[:user_id].nil?
    end

    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

I have built a system that uses email to activate accounts.

This is a session controller to log in only those who have authenticated their account by email.

app/controllers/sessions_controller.rb


class SessionsController < ApplicationController
  def new
  end

  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      if user.activated?
        forwarding_url = session[:forwarding_url]
        reset_session
        params[:session][:remember_me] == '1' ? remember(user) : forget(user)
        log_in user
        redirect_to forwarding_url || user
      else
        message  = "Account not activated. "
        message += "Check your email for the activation link."
        flash[:warning] = message
        redirect_to root_url
      end
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new', status: :unprocessable_entity
    end
  end

  def destroy
    log_out if logged_in?
    redirect_to root_url, status: :see_other
  end
end


Before introducing account activation, the first test passed. I think you probably need to pre-authenticate the test user like the log_in_as method of the test helper. But I didn't know how.


before { log_in_as(user) } 

I think I should write something like, but if anyone knows, please give me some advice. Thanks for reading this far.


Solution

  • solved. It was cured by setting the user model to "activated" with factorybot. Thanks for your comment.