Created
April 10, 2010 19:01
-
-
Save myronmarston/362227 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Rack::Test doesn't support hitting external webservers. However, when a user enters their credit card info, | |
# it is submitted directly to braintree, so we need to intregration test with hitting an external server. | |
# This hack enabled this, by swapping out the Rack::Test's rack app with a Rack::Client instance. | |
# Rack::Client acts just like a rack app, but under the covers it delegates to Net::HTTP. | |
require 'rack/client' | |
module RackTestHack | |
def new(*a, &b) | |
super.extend Extension | |
end | |
module Extension | |
def __remote_host?(uri) | |
# ignore subdomains... | |
uri_domain = uri.host.split('.')[-2, 2] | |
default_domain = default_host.split('.')[-2, 2] | |
uri_domain != default_domain && uri_domain.first != 'example' | |
end | |
def __fix_env(uri, env) | |
# Braintree depends on the query string being in an exact order, but rack-test rearranges the query string a bit. | |
# So, we fix it here by re-setting the query string if the params are the ones needed by braintree. | |
if Rack::Request.new(env).params.keys.sort == %w( hash http_status id ) | |
env['QUERY_STRING'] = uri.query | |
end | |
end | |
def request(uri, env) | |
orig_app = @app | |
@app = Rack::Client.new if __remote_host?(uri) | |
__fix_env(uri, env) | |
begin | |
super | |
ensure | |
@app = orig_app | |
end | |
end | |
end | |
end | |
Rack::MockSession.extend RackTestHack |
Myron, thanks for sharing this! Have you found more clean solution since then?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think __remote_host? method needs to check for localhost
def __remote_host?(uri)
return false if uri.host=="localhost"
uri_domain = uri.host.split('.')[-2, 2]
default_domain = default_host.split('.')[-2, 2]
uri_domain != default_domain && uri_domain.first != 'example'
end