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
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