web-dev-qa-db-fra.com

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 d'index de mon contrôleur domestique (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 s'exécute pas en raison de la méthode d'authentification. Je pourrais commenter "before_filter: authenticate" pour les exécuter mais je voudrais savoir s'il existe un moyen de les faire fonctionner avec la méthode.

Je vous remercie!

66
benoitr

Mise à jour (2013): Matt Connolly a fourni un Gist qui fonctionne également pour les spécifications de demande et de contrôleur: http: //Gist.github. com/4158961


Une autre façon de le faire si vous avez de nombreux tests à exécuter et que vous ne souhaitez pas l'inclure à chaque fois (code DRYer):

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écifications 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 ici

134
iwasrobbed

Désolé je n'ai pas cherché assez, 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
17
benoitr

Certaines réponses suggèrent de définir 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, en particulier lors de l'exécution de 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
5
Daniel Garmoshka

Lorsque vous utilisez Rspec pour tester les API 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")
4
deepwinter

Ce sont d'excellentes solutions pour le contrôleur et les spécifications de demande.

Pour les tests de fonctionnalités utilisant Capybara, voici une solution pour faire fonctionner l'authentification HTTP Basic:

spec/support/when_authenticated.rb

RSpec.shared_context 'When authenticated' do
  background do
    authenticate
  end

  def authenticate
    if page.driver.browser.respond_to?(:authorize)
      # When headless
      page.driver.browser.authorize(username, password)
    else
      # When javascript test
      visit "http://#{username}:#{password}@#{Host}:#{port}/"     
     end
  end

  def username
    # Your value here. Replace with string or config location
    Rails.application.secrets.http_auth_username
  end

  def password
    # Your value here. Replace with string or config location
    Rails.application.secrets.http_auth_password
  end

  def Host
    Capybara.current_session.server.Host
  end

  def port
    Capybara.current_session.server.port
  end
end

Ensuite, dans vos spécifications:

feature 'User does something' do
  include_context 'When authenticated'

  # test examples
end
3
madcow