mr_muscle
mr_muscle

Reputation: 2900

RSpec sessions controllers - user with invalid params without devise

I've got a simple message app to learn RSpec where one user can create message to another user (only logged users can write messages). I didn't used devise or FactoryBot, this app is as simple as possible just for rspec learning.

I wanted to run these tests for sessions controller, but the second one (when user has invalid params) gives me an error Expected response to be a <3XX: redirect>, but was a <200: OK> and I don't understand why since hours.

RSpec.describe SessionsController, type: :controller do
  let(:create_user) { @user = User.create(username: 'John', password: 'test123') }

  describe 'POST #create' do

    context 'when user is logged in' do
      it 'loads correct user details and redirect to the root path' do
        create_user
        post :create, params: { session: { username: @user.username, password: @user.password } }
        expect(response).to redirect_to(root_path)
      end
    end

    context 'when user has invalid params' do
      before do
        create_user
        post :create, params: { session: { username: @user.username, password: 'somepass' } }
      end

      it 'render new action' do
        expect(assigns(:user)).not_to eq create_user
        expect(response).to redirect_to(action: 'new')
      end
    end
  end
end

Sessions Controller

class SessionsController < ApplicationController
  before_action :logged_in_redirect, only: %i[new create]

  def new; end

  def create
    user = User.find_by(username: params[:session][:username])
    if user && user.authenticate(params[:session][:password])
      session[:user_id] = user.id
      flash[:success] = 'You have successfully logged in'
      redirect_to root_path
    else
      flash.now[:error] = 'There was something wrong with your login'
      render 'new'
    end
  end
end

I'm not quite sure if line expect(assigns(:user)).not_to eq create_user is in line with convention but it doesn't matter for result.

Upvotes: 0

Views: 224

Answers (1)

mrzasa
mrzasa

Reputation: 23307

In your test you expect redirect response:

expect(response).to redirect_to(action: 'new')

And in the controller you just render new template:

render 'new'

I think it's a good approach to render new, you should change your spec to expect this.

expect(response).to render_template(:new)

Upvotes: 1

Related Questions