0

Rails 3.2.3 に組み込まれている基本的な http 認証メカニズムをテストしたいと考えています。RSpec と Cucumber の両方で http 認証をテストしようとしましたが、両方のツールでステップが失敗しました。Cucumber では、フィーチャーの実行時に次のメッセージが表示されます。

When I perform HTTP authentication as "admin" with "test" # features/step_definitions/web_steps.rb:1
  undefined method `env' for nil:NilClass (NoMethodError)
  ./features/step_definitions/web_steps.rb:3:in `/^I perform HTTP authentication as "([^\"]*)" with "([^\"]*)"$/'
  features/sign_in_http.feature:4:in `When I perform HTTP authentication as "admin" with "test"'

ここに私の ApplicationController クラスがあります:

class ApplicationController < ActionController::Base
  protect_from_forgery

  http_basic_authenticate_with :name => "admin", :password => "test"
end

Cucumber のステップ定義:

When /^I perform HTTP authentication as "([^\"]*)" with "([^\"]*)"$/ do |username, password|
  @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("username:password")
  visit '/'
end

きゅうりの特徴:

Feature: Signing in via http

Scenario: HTTP sign-in
  When I perform HTTP authentication as "admin" with "test"
  Then I should see "Welcome to the app."

RSpec では、http 認証ステップはパスしたように見えますが、次のステップから、「アクセスが拒否された」ため、ページに期待されるコンテンツが見つからないというメッセージが表示されます。

1) ApplicationController sign in via http should be successful
 Failure/Error: page.should have_content("Welcome to the app.")
   expected there to be content "Welcome to the app." in "HTTP Basic: Access denied.\n"
 # ./spec/controllers/application_controller_spec.rb:12:in `block (3 levels) in <top (required)>'

これが私の関連する仕様です:

require 'spec_helper'

describe ApplicationController do

  describe "sign in via http" do
    it "should be successful" do
      @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("admin:test")
      visit '/'
      response.should be_success
      page.should have_content("Welcome to the app.")
    end
  end
end

また、キュウリのステップで http 認証行の前にルート パスにアクセスしようとしましたが、これにより @request の NilClass に関する同じメッセージが表示されました。定義された「admin:test」資格情報を使用してブラウザ経由でログインしても問題はなく、アプリのルート ページを表示できます。

何か提案があればよろしくお願いします。

4

2 に答える 2

3

これが私がそれを機能させる方法です。重要なのは、ページにアクセスする前に認証ステップを実行することです。そうしないと、すでに認証に失敗しています。

私の機能では、次のように入力しました。

Background:
    Given I perform HTTP authentication as "<id>/<password>"
    When I go to the homepage
    Then I should see "Text-that-you-should-see-on-your-home-page"

HTTP 認証のステップ定義は次のとおりです (このコードは別の場所で見つけ、puts ステートメントを追加して何が起こっているかを確認しました)。

Given /^I perform HTTP authentication as "([^\"]*)\/([^\"]*)"$/ do |username, password|
    puts "id/pswd: #{username}/#{password}"
    ### Following works ONLY if performed first before even going to a page!!!
    if page.driver.respond_to?(:basic_auth)
        puts 'Responds to basic_auth'
        page.driver.basic_auth(username, password)
    elsif page.driver.respond_to?(:basic_authorize)
        puts 'Responds to basic_authorize'
        page.driver.basic_authorize(username, password)
    elsif page.driver.respond_to?(:browser) && page.driver.browser.respond_to?(:basic_authorize)
        puts 'Responds to browser_basic_authorize'
        page.driver.browser.basic_authorize(username, password)
    else
        raise "I don't know how to log in!"
    end
end
于 2012-08-29T14:41:33.580 に答える
0

今ではもっと簡単な解決策があります。いつ実装されたのかはわかりませんが、Cucumber にはこれをbasic_authorize処理するメソッドがあります。これが私が使用したステップです:

Given /^I perform basic HTTP authentication with username "([^"]*)" and password "([^"]*)"$/ do |username, password|
  basic_authorize(username, password)
end

ユースケースの例を次に示します。

Given I perform basic HTTP authentication with username "cool_user" and password "hunter22"

JESii の回答と同様に、ページにアクセスする前にこの手順を実行する必要があります。

これが他の誰かの時間を節約できることを願っています。私はこれにかなりの時間を費やしました。

于 2020-06-23T14:22:06.423 に答える