Robs Robs - 2 months ago 22
Ruby Question

devise redirects instead of json response in rspec

I had overridden default responding in devise which renders json instead of html template. It works fine when I test it with curl or postman, but when it comes to test it with rspec. I have read infos how to test controllers with devise from readme.md, so that it works fine with logging into, but does not work when I want to test unauthenticated request.

Response received:

<html><body>You are being <a href=\"http://test.host/users/sign_in\">redirected</a>.</body></html>


instead of:

{"error":"You need to sign in or sign up before continuing."}


app/controllers/playlists_controller.rb:

class PlaylistsController < ApplicationController
before_action :authenticate_user!

def index
render json: Playlist.all
end
end


app/controllers/sessions_controller.rb:

class SessionsController < Devise::SessionsController
clear_respond_to
respond_to :json
end


spec/controllers/playlists_controller_spec.rb:

require 'rails_helper'

describe PlaylistsController do
context 'when user is not signed in' do
it 'returns authorization error message' do
get :index
expect(response.body).to eq 'some message here'
end
end
end


spec/support/devise.rb

RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
end

Answer

The reason it doesn't work in your controller test and does work in curl is because you aren't hitting the :index with format of :json (which you've written logic to respond_to :json).

Change this

it 'returns authorization error message' do
  get :index
  ...
end

to this

it 'returns authorization error message' do
  get :index, format: :json
  ...
end