0
votes

I am trying to write a rspec for sessions controller. But i am not able to do so.

I wanted to test controller for valid and invalid valid attributes. Tests should pass if valid attributes are passed for a particular user and should fail if invalid attributes are passed for a given user.

require 'rails_helper'

RSpec.describe SessionsController, type: :controller do

   let(:user)  { User.create(name: "some",email: '[email protected]', password: 'rous',password_confirmation: "some") } 

     describe "get login path" do
        it "login page" do
            get :new
            expect(response).to render_template('sessions/new')
        end
     end

         describe "valid attributes" do
   it "create a session" do 
        post :create, session: { email: user.email, password: user.password }
        expect(response.status).to render_template('/users/@user.id')
   end
 end

 describe "invalid attributes" do
    it "does not create a session" do 
        post :create, session: { email: user.email, password: "12345" }
        expect(response.status).to render_template('sessions/new')
    end
 end


     describe "does not create a session" do

        it "if email is empty" do 
            post :create, session: {password: "some"}
            expect(response.status).to render_template('sessions/new')
        end

        it "if password is empty" do 
            post :create, session: {email: "[email protected]"}
            expect(response.status).to render_template('sessions/new')
        end

     end
end

Describe "invalid attributes" and "valid attributes" are not working fine.

If email/password are wrong, user redirected to session#new page.

If email & password are correct, user should to redirected to user_path i.e., users show page.

1
What is the error that you're getting?Vasfed

1 Answers

0
votes

You should really use a request or feature spec instead here as they drive the full stack. You not only want to test that your controller redirects somewhere - you really want to test that redirects somewhere and signs a user in. Preferably without poking inside the internals or mocking the actual authentication process that you're supposed to be testing in the first place.

Both the RSpec and Rails teams disencourage writing controller tests/specs for new applications. Test the behaviour of your application. Not how it does its job.

require "rails_helper"

RSpec.feature "User sign in", type: :feature do

  let!(:user) { FactoryBot.create(:user) }

  scenario "User signs in with valid crentials" do
    visit "/sessions/new"
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Sign In"
    expect(page).to have_text "You have been signed in"
  end

  scenario "User signs in with invalid crentials" do
    visit "/sessions/new"
    fill_in "Email", with: user.email
    fill_in "Password", with: "nottherightpassword"
    click_button "Sign In"
    expect(page).to_not have_text "You have been signed in"
    expect(page).to have_text "Invalid email or password"
  end
end

Or as a lower level request spec:

require "rails_helper"

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

  let!(:user) { FactoryBot.create(:user) }

  describe "POST /sessions" do

    context "with valid credentials" do
      it "redirects the user" do
        post '/sessions', 
          params: { session: { email: user.email, password: user.password } }
        expect(response).to redirect_to user_path(user)
        follow_redirect!
        expect(response.body).to include("You have been signed in")
      end
    end

    context "with invalid credentials" do
      it "does not redirect the user" do
        post '/sessions', 
          params: { session: { email: user.email, password: "nottherightpassword" } }
        expect(response).to_not redirect_to user_path(user)
        expect(response.body).to include("Invalid email or password")
      end
    end
  end
end