3

I don't have much experience with stubbing and am having issues with requests to Braintree using webmock and braintree-rails.

spec/spec_helper.rb

RSpec.configure do |config|
  config.include(ConnectionHelper)

  config.before(:each) do
    stub_request(:post, /.*braintree.*/).
    with(braintree_hash).to_return(gzipped_response)
  end
end

spec/support/connection_helper.rb

def gzipped_response
  {
    status: 200,
    body: "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0",
    headers: {}
  } 
end

def braintree_hash
  { :body => /.*/,
    :headers => {'Accept'=>'application/xml', 'Content-Type'=>'application/xml',
    'User-Agent'=>'Braintree Ruby Gem 2.42.0 (braintree-rails-1.4.0)',
    'X-Apiversion'=>'4'}
  }
end

Rspec error:

2) Content: when ordering content show page has relevant information 
     Failure/Error: click_button "Order"
     Braintree::UnexpectedError:
       expected a gzipped response
     # ./app/classes/payment.rb:13:in `generate_token'
     # ./app/controllers/posts_controller.rb:44:in `pay'
     # ./spec/features/content_spec.rb:251:in `block (4 levels) in <top (required)>'

I'm trying to test the page, not the payments themselves, however when rendering the page a token needs to be retrieved first and so I'm getting this error.

How would I go about faking a gzipped response, or alternatively skip anything to do with Braintree requests in my tests?

app/controllers/posts_controller.rb

def pay
  @post = Post.find(params[:id])
  @client_token = Payment.new(current_user).generate_token
end

app/classes/payment.rb

class Payment    
  def initialize(customer)
    @customer = customer
    @customer_id = @customer.id
  end

  def generate_token
    Braintree::ClientToken.generate(customer_id: @customer_id)
  end   
end
mind.blank
  • 4,820
  • 3
  • 22
  • 49
  • Could you add `PostsController#pay`? – max May 04 '15 at 12:19
  • @papirtiger I've added the code for the `controller`, however there are other `Payment` methods I will use here and there like `create_customer` and `customer_subscription` which will probably throw the same error due to the `gzipped response`. – mind.blank May 04 '15 at 13:01

1 Answers1

2

I work at Braintree. If you have any questions specifically about our API and client libraries, you can always reach out to our support team.

Your stubbed response body needs to be gzipped. You can create an empty gzipped string like this:

irb(main):010:0> require 'stringio' 
=> false
irb(main):011:0> require 'zlib'
=> false
irb(main):012:0> Zlib::GzipWriter.new(StringIO.new("w")).close.string
=> "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0"

So try this for your status_ok method:

def status_ok
  {
    status: 200,
    body: "\u001F\x8B\b\0:\x87GU\0\u0003\u0003\0\0\0\0\0\0\0\0\0",
    headers: {"Content-Encoding" => "gzip"}
  } 
end
mind.blank
  • 4,820
  • 3
  • 22
  • 49
agf
  • 171,228
  • 44
  • 289
  • 238
  • thanks for your reply, I've tried with the code above but still getting the same error, updating my question now. – mind.blank May 05 '15 at 08:33
  • @mind.blank My mistake. I've updated my answer; you also need to set a content-encoding header. – agf May 06 '15 at 17:05
  • @mind.blank If you're looking to skip generating a client token for your controller specs, why not stub `Braintree::ClientToken.generate`? – agf May 06 '15 at 17:07