问题
I'm trying to test a controller that's using an http token authentication in the before filter. My problem is that it works ok wheh I use curl to pass the token, but in my tests it always fails (I'm using rspec btw). Tried a simple test to see if the token was being passed at all, but it seems like it's not doing so. Am I missing anything to get the test to actually pass the token to the controller?
Here's my before filter:
def restrict_access
authenticate_or_request_with_http_token do |token, options|
api_key = ApiKey.find_by_access_token(token)
@user = api_key.user unless api_key.nil?
@token = token #set just for the sake of testing
!api_key.nil?
end
end
And here is my test:
it "passes the token" do
get :new, nil,
:authorization => ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
assigns(:token).should be "test_access1"
end
回答1:
I'm assuming ApiKey is an ActiveRecord model, correct? curl command runs against development database, and tests go against test db. I can't see anything that sets up ApiKey in your snippets. Unless you have it somewhere else, try adding something along these lines:
it "passes the token" do
# use factory or just create record with AR:
ApiKey.create!(:access_token => 'test_access1', ... rest of required attributes ...)
# this part remains unchanged
get :new, nil,
:authorization => ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
assigns(:token).should be "test_access1"
end
You can later move it to before :each
block or support module.
UPDATE:
After seeing your comment I had to look deeper. Here's another guess. This form of get
get '/path', nil, :authorization => 'string'
should work only in integration tests. And for controller tests auth preparation should look like this:
it "passes the token" do
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
get :new
assigns(:token).should be "test_access1"
end
Reasons behind this come from method signatures for respective test modules:
# for action_controller/test_case.rb
def get(action, parameters = nil, session = nil, flash = nil)
# for action_dispatch/testing/integration.rb
def get(path, parameters = nil, headers = nil)
来源:https://stackoverflow.com/questions/12041091/ror-testing-an-action-that-uses-http-token-authentication