brodney
brodney

Reputation: 1176

Test oauth2 get_token with rspec

I'm creating a controller spec for the get_token part of an oauth2 authentication. At this point the user has authorized my app and I need to generate and save the token and other information. Rspec fails with a somewhat cryptic error.

Failure/Error: get :auth, { code: "auth_code", scope: "read_write" }
     OAuth2::Error:
       {:token_type=>"bearer", 
        :stripe_publishable_key=>"PUBLISHABLE_KEY", 
        :scope=>"read_write", 
        :livemode=>"false", 
        :stripe_user_id=>"USER_ID",  
        :refresh_token=>"REFRESH_TOKEN", 
        :access_token=>"ACCESS_TOKEN"}

Here's the controller code. Rspec says it fails on get_token.

require 'oauth2'

def auth
  code = params[:code]
  client = oauth_client
  token_response = client.auth_code.get_token(code, params: { scope: 'read_write' })
  token = token_response.token

And here's the test. The webmock should be intercepting get_token. It is the autogenerated webmock suggeted by rspec that I filled in the body with the appropriate request and response body.

before do
  stub_request(:post, "https://connect.stripe.com/oauth/token").
    with(:body => {"client_id"=>"CLIENT_ID",
                   "client_secret"=>"SOME_SECRET",
                   "code"=>"auth_code",
                   "grant_type"=>"authorization_code",
                   "params"=>{"scope"=>"read_write"}},
         :headers => {'Accept'=>'*/*',
                      'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
                      'Content-Type'=>'application/x-www-form-urlencoded',
                      'User-Agent'=>'Faraday v0.9.0'}).
    to_return(:status => 200,
              :body => {token_type: "bearer",
                        stripe_publishable_key: "PUBLISHABLE_KEY",
                        scope: "read_write",
                        livemode: "false",
                        stripe_user_id: "USER_ID",
                        refresh_token: "REFRESH_TOKEN",
                        access_token: "ACCESS_TOKEN"},
              :headers => {})
end

describe "#auth" do
  it "creates a payment gateway" do
    get :auth, { code: "auth_code", scope: "read_write" 
  end
end

This process already works in practice so at least the controller code is not to blame. What am I doing wrong?

Upvotes: 3

Views: 3241

Answers (2)

Amaury González
Amaury González

Reputation: 51

After work hard having the same problem I have a solution. Is the header returned in the stub request, you have it blank. The oauth2 gem use the Content-Type to define how to parse the body. Try the stub putting the header in this way:

stub_request(:post, "https://connect.stripe.com/oauth/token").
    with(:body => {"client_id"=>"CLIENT_ID",
                   "client_secret"=>"SOME_SECRET",
                   "code"=>"auth_code",
                   "grant_type"=>"authorization_code",
                   "params"=>{"scope"=>"read_write"}},
         :headers => {'Accept'=>'*/*',
                      'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
                      'Content-Type'=>'application/x-www-form-urlencoded',
                      'User-Agent'=>'Faraday v0.9.0'}).
    to_return(:status => 200,
              :body => {token_type: "bearer",
                        stripe_publishable_key: "PUBLISHABLE_KEY",
                        scope: "read_write",
                        livemode: "false",
                        stripe_user_id: "USER_ID",
                        refresh_token: "REFRESH_TOKEN",
                        access_token: "ACCESS_TOKEN"},
              :headers => { 'Content-Type'=> 'application/json;charset=UTF-8'})

Upvotes: 3

Aleksey Shein
Aleksey Shein

Reputation: 7482

I think you're getting this error, because you've stubbed only part of oauth session, i.e. you're trying to send a stale token (or something like that) that has been provided by webmock.

Instead of manual stubbing of these requests, I'd suggest to use special tool: stripe-ruby-mock gem, which has been designed exactly for testing Stripe API.

As an alternative, you may use VCR gem (here are the docs), which allows to write on disk all your http session and play it as it was live. Great tool, highly recommended.

Upvotes: 0

Related Questions