Как я могу указать спецификациям контроллера использование подписанного запроса OAuth - PullRequest
7 голосов
/ 06 февраля 2012

Я строю двухстороннего OAuth-провайдера для моего API.Все подключено правильно, и я могу делать подписанные звонки с консоли rails.У меня проблема в том, что у меня проблемы с интеграцией OAuth в controller_spec.

Вот пример рабочего вызова на моем сервере:

coneybeare $ rails c test
Loading test environment (Rails 3.2.0)
rails test: main 
>> consumer = OAuth::Consumer.new("one_key", "MyString", :site => [REDACTED])
# => #<OAuth::Consumer:0x007f9d01252268 @key="one_key", @secret="MyString", @options={:signature_method=>"HMAC-SHA1", :request_token_path=>"/oauth/request_token", :authorize_path=>"/oauth/authorize", :access_token_path=>"/oauth/access_token", :proxy=>nil, :scheme=>:header, :http_method=>:post, :oauth_version=>"1.0", :site=>[REDACTED]}>  

ruby: main 
>> req = consumer.create_signed_request(:get, "/api/v1/client_applications.json", nil)
# => #<Net::HTTP::Get GET>  

ruby: main 
>> res = Net::HTTP.start([REDACTED]) {|http| http.request(req) }
# => #<Net::HTTPOK 200 OK readbody=true>  

ruby: main 
>> puts res.body
{"client_applications":[{"id":119059960,"name":"FooBar1","url":"http://test1.com"},{"id":504489040,"name":"FooBar2","url":"http://test2.com"}]}
# => nil  

И вот что яЯ делаю в моем контроллере тесты:

require 'oauth/client/action_controller_request'
describe Api::ClientApplicationsController do
  include OAuthControllerSpecHelper
  …
  … 
    it "assigns all client_applications as @client_applications" do
      consumer = OAuth::Consumer.new("one_key", "MyString", :site => [REDACTED])
      ActionController::TestRequest.use_oauth=true
      @request.configure_oauth(consumer)
      @request.apply_oauth!
      puts "request.env['Authorization'] = #{@request.env['Authorization']}"
      get :index, {:api_version => 'v1', :format => :json}
      response.should be_success # Just this for now until I can get authorization, then proper controller testing
    end
end

Вывод этого теста:

request.env['Authorization'] = OAuth oauth_consumer_key="one_key", oauth_nonce="gzAbvBSWyFtIYKfuokMAdu6VnH39EHeXvebbH2qUtE", oauth_signature="juBkJo5K0WLu9mYqHVC3Ar%2FATUs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1328474800", oauth_version="1.0"
1) Api::ClientApplicationsController GET index assigns all client_applications as @client_applications
   Failure/Error: response.should be_success
     expected success? to return true, got false

И соответствующий вызов сервера из журнала rails:

Processing by Api::ClientApplicationsController#index as JSON
  Parameters: {"api_version"=>1}
  Rendered text template (0.0ms)
Filter chain halted as #<OAuth::Controllers::ApplicationControllerMethods::Filter:0x007f85a51a8858 @options={:interactive=>false, :strategies=>:two_legged}, @strategies=[:two_legged]> rendered or redirected
Completed 401 Unauthorized in 15ms (Views: 14.1ms | ActiveRecord: 0.0ms)
   (0.2ms)  ROLLBACK

Я просто не могу понять, почему это не работает: / Я делаю очевидную ошибку?

Ответы [ 3 ]

1 голос
/ 10 октября 2012

Если вы хотите протестировать его в спецификации запроса и действительно хотите выполнить тестирование без использования заглушки, вы можете создать потребителя OAuth и подписать запрос следующим образом:

    @access_token = FactoryGirl.create :access_token
    @consumer = OAuth::Consumer.new(@access_token.app.key, @access_token.app.secret, :site => "http://www.example.com/")
    @path = "/path/to/request"
    @request = @consumer.create_signed_request(:get, @path, OAuth::AccessToken.new(@consumer, @access_token.token, @access_token.secret))
    get @path, nil, { 'HTTP_AUTHORIZATION' => @request.get_fields('authorization').first }
0 голосов
/ 15 февраля 2012

Оказывается, что лучший способ проверить мой контроллер был самым простым. Вместо того чтобы пытаться подписать каждый тест, чтобы контроллер получал правильную информацию (что-то, что действительно принадлежит спецификации запроса, а не спецификации контроллера), я решил, что могу просто предоставить контроллеру необходимую ему информацию вручную.

Для этого мне просто пришлось заглушить 2 метода:

fixtures :client_applications
before(:each) do
  @client_application1 = client_applications(:client_application1)
  Api::ClientApplicationsController::Authenticator.any_instance.stub(:allow?).and_return(true)
  controller.stub(:client_application).and_return(@client_application1)
end

Заглушка метода allow? привела к тому, что аутентификация стойки заставила себя думать, что она аутентифицирована. allow? также установил client_application на основе учетных данных, поэтому мне пришлось также заглушить это. Теперь, когда аутентификации нет, я могу правильно проверить свой контроллер.

0 голосов
/ 14 февраля 2012

Я хотел бы взглянуть на то, как работают помощники по тестированию Omniauth, а именно на эти файлы: https://github.com/intridea/omniauth/tree/master/lib/omniauth/test. См. Их вики-страницу по интеграционному тестированию , чтобы узнать, как это настроить.Я понимаю, что вы создаете поставщика, а не клиента, но это может быть хорошей отправной точкой.Кроме того, как уже говорили некоторые комментаторы, я не знаю, сможете ли вы сделать это с помощью теста контроллера;вам может потребоваться запрос или интеграционный тест, чтобы полностью имитировать среду стойки.

...