74 votes

Rails/Rspec Faire passer les tests avec l'authentification de base http

Voici mon authentification de base http dans le fichier du contrôleur d'application (application_controller.rb)

before_filter :authenticate

protected

def authenticate
  authenticate_or_request_with_http_basic do |username, password|
    username == "username" && password == "password"  
  end
end

et le test par défaut pour l'action index de mon contrôleur maison (spec/controllers/home_controller_spec.rb)

require 'spec_helper'

describe HomeController do

describe "GET 'index'" do
  it "should be successful" do
    get 'index'
    response.should be_success
  end
end

Le test ne fonctionne pas à cause de la méthode d'authentification. Je pourrais commenter "before_filter :authenticate" pour les exécuter mais j'aimerais savoir s'il existe un moyen de les faire fonctionner avec la méthode.

Merci !

0 votes

A partir de Rails 6, cela ressemble à cette réponse est celui qui fonctionne.

141voto

iWasRobbed Points 26926

Mise à jour (2013) : Matt Connolly a fourni un GIST qui fonctionne également pour les spécifications des requêtes et des contrôleurs : http://gist.github.com/4158961


Une autre façon de procéder si vous avez de nombreux tests à exécuter et que vous ne voulez pas l'inclure à chaque fois (code plus DRY) :

Créez un fichier /spec/support/auth_helper.rb :

module AuthHelper
  def http_login
    user = 'username'
    pw = 'password'
    request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
  end  
end

Dans votre fichier de spécification de test :

describe HomeController do
  render_views

  # login to http basic auth
  include AuthHelper
  before(:each) do
    http_login
  end

  describe "GET 'index'" do
    it "should be successful" do
      get 'index'
      response.should be_success
    end
  end

end

Crédit aquí

1 votes

Il montre que la demande est nulle pour moi. une idée sur la façon d'obtenir une solution de contournement ?

6 votes

Pour les spécifications de demande, vous pouvez avoir plusieurs demandes, donc request es nil . Au lieu de cela, vous devez créer un hash env env = {} mettez-le à jour dans votre méthode http_login, et passez ensuite l'env explicitement comme dans get '/', {}, env .

6 votes

En développant ce qui précède, qui fonctionne pour la demande et les spécifications du contrôleur : gist.github.com/4158961

20voto

benoitr Points 1855

Désolé, je n'ai pas assez cherché, la solution semble être la suivante :

describe "GET 'index'" do
  it "should be successful" do
    @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("username:password")
    get 'index'
    response.should be_success
  end
end

8voto

Dan Key Points 2255

Certaines réponses suggèrent de mettre request.env ce qui n'est pas sûr, car la demande peut être nil et vous vous retrouverez avec private method env' called for nil:NilClass surtout lorsqu'on exécute des tests uniques avec rspec -e

L'approche correcte sera :

def http_login
  user = 'user'
  password = 'passw'
  {
    HTTP_AUTHORIZATION: ActionController::HttpAuthentication::Basic.encode_credentials(user,password)
  }
end

get 'index', nil, http_login

post 'index', {data: 'post-data'}, http_login

5voto

Ratanachai S. Points 911

Pour moi, avec Rails 6, j'ai besoin d'arguments sous forme de mots-clés pour la méthode rspec get comme . get route, params: params, headers: headers

Méthode Auth Helper

module AuthHelper
  def headers(options = {})
    user = ENV['BASIC_AUTH_USER']
    pw = ENV['BASIC_AUTH_PASSWORD']

    { HTTP_AUTHORIZATION: ActionController::HttpAuthentication::Basic.encode_credentials(user,pw) }
  end
  def auth_get(route, params = {})
    get route, params: params, headers: headers
  end
end

et le test de demande de rspec.

describe HomeController, type: :request do    
  include AuthHelper

  describe "GET 'index'" do
    it "should be successful" do
      auth_get 'index'
      expect(response).to be_successful
    end
  end

end

4voto

deepwinter Points 1280

Lorsque vous utilisez Rspec pour tester les API de Grape, la syntaxe suivante fonctionne

        post :create, {:entry => valid_attributes}, valid_session

où valid_session est

{'HTTP_AUTHORIZATION' => credentials}

et

credentials = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X