Reputation: 41
Devise: 4.20
Rails: 5.0.1
Rspec: 3.5
I had used this link https://github.com/plataformatec/devise/wiki/How-To:-Use-HTTP-Basic-Authentication, but I havproblems to test the http basic auth for my api using rspec for requests tests. Below is the example the error:
module Api
class BaseController < ApplicationController
before_action :authenticate_user!
protected
def authenticate_user!
authenticate_or_request_with_http_basic do |username, password|
resource = User.find_by_username(username)
if resource
sign_in :user, resource if resource.valid_password?(password)
else
request_http_basic_authentication
end
end
end
end
end
module Api
module V1
class CarController < Api::BaseController
respond_to :json
def index
@cars = Car.all
render :json => {:content => @cars}, :status => 200
end
end
end
end
require 'rails_helper'
RSpec.describe "Servers API", :type => :request do
it 'sends a list of servers' do
admin = FactoryGirl.create(:admin)
@env = {}
@env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(admin.username, admin.password)
get "/api/cars", :params => {}, :headers => @env
# test for the 200 status-code
expect(response.status).to eq(200)
end
end
When I run the spec, I have the below error:
# --- Caused by: ---
# NoMethodError:
# undefined method `sign_in' for #<Api::V1::CarController:0x0000000609ef12>
# ./app/controllers/api/base_controller.rb:10 in block in authenticate_user!
Anyone can help me? Thanks.
Upvotes: 2
Views: 987
Reputation: 421
I have similar setup where my specs are passing, would you also show your spec_helper
content, looks like you are not including Devise::TestHelpers
.
spec_helper
RSpec.configure do |config|
config.include Devise::TestHelpers
config.include Warden::Test::Helpers
config.before { Warden.test_mode! }
config.after { Warden.test_reset! }
config.before(:each) do
@headers = { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' }
end
end
and my test looks something like this:
RSpec.describe 'Users' do
context 'when client is authorized' do
let(:user) { FactoryGirl.create(:user) }
it 'gets user' do
@headers['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.
encode_credentials(
user.authentication_token,
email: user.email
)
get api_v1_user_url(id: user.id), {}, @headers
expect(response.status).to eq(200)
end
end
end
Upvotes: 1