简体   繁体   English

Rspec Rails 4.2.5使用基本的HTTP身份验证请求测试通过

[英]Rspec Rails 4.2.5 Request test pass with basic http auth

The setup is the following. 设置如下。 For each http request the manager sends his credentials in the header(name,pw). 对于每个http请求,管理器都会在标头(name,pw)中发送其凭据。 These get checked against the entries in the db and if they succeed return the desired user object. 将对照db中的条目检查这些条目,如果它们成功返回了所需的用户对象。 How is it possible to implement basic http_auth in the request tests? 在请求测试中如何实现基本的http_auth? I would like to add only the password and username and test the return value? 我只想添加密码和用户名并测试返回值? Which is the goal of request tests,right? 请求测试的目标是什么? I tried the following without much success: 我尝试了以下方法,但没有获得很大的成功:

I created an AuthHelper module in spec/support/auth_helper.rb with 我在spec/support/auth_helper.rb使用以下方法创建了AuthHelper模块:

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

and use it in the requests/api/user_spec.rb as follows 并按如下所示在requests/api/user_spec.rb使用它

include AuthHelper
 describe "User API get 1 user object" do     
      before(:each) do
               http_login 
       end

but i receive this error message. 但我收到此错误消息。 How can i fix this and enable my tests to pass http_auth? 如何解决此问题并使我的测试通过http_auth? I read lot of similar topis and questions also here but they apply mostly to older versions of rspec and rails and are not applying to my case 我在这里也阅读了很多类似的topis和问题,但它们主要适用于rspec和rails的较旧版本,不适用于我的情况

Thanks in advance! 提前致谢!

Failure/Error: request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)

 NoMethodError:
   undefined method `env' for nil:NilClass# ./spec/support

 # ./spec/support/auth_helper.rb:5:in `http_login'
 # ./spec/requests/api/user_spec.rb:8:in `block (2 levels) in <top (required)>'

Update 更新

I moved the header generation inside a request. 我在请求中移动了标头生成。 I looked up the Auth verb, so i think the assignment should work. 我查了一下Auth动词,所以我认为该分配应该有效。 I tested the ActionController call in rails console and received a string. 我在Rails控制台中测试了ActionController调用,并收到了一个字符串。 I suppose this is also correct.My whole test now looks like this: 我想这也是正确的,我的整个测试现在看起来像这样:

describe "User API get 1 user object", type: :request do  
      it 'Get sends back one User object ' do             
              headers = {   
                            "AUTHORIZATION" =>ActionController::HttpAuthentication::Basic.encode_credentials("test","test")
   #                        "AUTHORIZATION" =>ActionController::HttpAuthentication::Token.encode_credentials("test","test")
              }
              FactoryGirl.create(:user)
              get "/api/1/user", headers
              #json = JSON.parse(response.body)
              expect(response).to be_success
      #       expect(response.content_type).to eq("application/json")
      end     
  end     

receiving the following error: 收到以下错误:

which incudles the line @buf=["HTTP Basic: Access denied.\\n"] so access is still denied. 包含@buf @buf=["HTTP Basic: Access denied.\\n"]因此仍然拒绝访问。

Failure/Error: expect(response).to be_success
   expected `#<ActionDispatch::TestResponse:0x000000070d1d38 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x000000070d1c98>, @stream=#<ActionDispatch::Response::Buffer:0x000000070d1c48 @response=#<ActionDispatch::TestResponse:0x000000070d1d38 ...>, 
 @buf=["HTTP Basic: Access denied.\n"], @closed=false>, @header={"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "WWW-Authenticate"=>"Basic realm=\"Application\"", "Content-Type"=>"text/html; charset=utf-8", "Cache-Control"=>"no-cache", "X-Request-Id"=>"9c27d4e9-84c0-4ef3-82ed-cccfb19876a0", "X-Runtime"=>"0.134230", "Content-Length"=>"27"}, @status=401, @sending_file=false, @blank=false, 
@cv=#<MonitorMixin::ConditionVariable:0x000000070d1bf8 @monitor=#<ActionDispatch::TestResponse:0x000000070d1d38 ...>, @cond=#<Thread::ConditionVariable:0x000000070d1bd0>>, @committed=false, @sending=false, @sent=false, @content_type=#<Mime::Type:0x00000002af78f8 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, @charset="utf-8", @cache_control={:no_cache=>true}, @etag=nil>.success?` 
to return true, got false

SOLUTION This test is not polished (yet) but at least it passes now. 解决方案:该测试尚未打磨(但尚未完成),但至少现在可以通过。

describe "User API get 1 user object", type: :request do  
    it 'Get sends back one User object ' do             
        @env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
              FactoryGirl.create(:user)

        get "/api/1/user", {}, @env

        JSON.parse(response.body)
        expect(response).to be_success
        expect(response.status).to eq 200
    end     
end     

Read the error carefully: undefined method `env' for nil:NilClass means request is nil. 请仔细阅读错误: undefined method `env' for nil:NilClass表示request为nil。 Are you trying to set the header before a test while you are defining the request later on in the test? 在稍后测试中定义请求时是否要尝试测试设置标头?

You might want to look at the documentation for an example on how to set headers. 您可能需要查看文档,以获取有关如何设置标题的示例

If you're still stuck, post one of your tests as well. 如果仍然遇到问题,请同时发布其中一项测试。

This line looks suspicious: 这行看起来很可疑:

request.ENV['HTTP_AUTHORIZATION'] =ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)

Are you sure that "ENV" should be capitalized? 您确定"ENV"应大写吗? I think it should be written like "env" . 我认为应该将其写为"env"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM