Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

305 lines (245 sloc) 13.216 kb
require 'cgi'
NET_CONNECT_NOT_ALLOWED_ERROR = /You can use VCR to automatically record this request and replay it later/
shared_examples_for "an http library" do |library, supported_request_match_attributes, *other|
unless adapter_module = HTTP_LIBRARY_ADAPTERS[library]
raise ArgumentError.new("No http library adapter module could be found for #{library}")
end
describe "using #{adapter_module.http_library_name}", :unless => (RUBY_INTERPRETER != :mri && library =~ /(typhoeus|curb|patron|em-http)/) do
include adapter_module
# Necessary for ruby 1.9.2. On 1.9.2 we get an error when we use super,
# so this gives us another alias we can use for the original method.
alias make_request make_http_request
describe 'making an HTTP request' do
let(:status) { VCR::ResponseStatus.new(200, 'OK') }
let(:interaction) { VCR::HTTPInteraction.new(request, response) }
let(:response_body) { "The response body" }
let(:match_requests_on) { [:method, :uri] }
let(:record_mode) { :none }
before(:each) do
subject.stub_requests([interaction], match_requests_on)
end
context "when the the stubbed request and response has no headers" do
let(:request) { VCR::Request.new(:get, 'http://example.com:80/') }
let(:response) { VCR::Response.new(status, nil, response_body, '1.1') }
it 'returns the response for a matching request' do
get_body_string(make_http_request(:get, 'http://example.com/')).should == response_body
end
end
def self.test_url(description, url)
context "when a URL #{description} has been stubbed" do
let(:request) { VCR::Request.new(:get, url) }
let(:response) { VCR::Response.new(status, nil, response_body, '1.1') }
def should_be_pending?
return false unless described_class == VCR::HttpStubbingAdapters::WebMock
return false unless request.uri.include?(CGI.escape('&'))
self.class.included_modules.first.http_library_name == 'EM HTTP Request'
end
it 'returns the expected response for the same request' do
pending "WebMock/EM-HTTP bug", :if => should_be_pending? do
get_body_string(make_http_request(:get, url)).should == response_body
end
end
end
end
test_url "that has query params", "http://example.com/search?q=param"
test_url "with spaces encoded as +", "http://example.com/search?q=a+b"
test_url "with spaces encoded as %20", "http://example.com/search?q=a%20b"
test_url "with an encoded ampersand", "http://example.com:80/search?q=#{CGI.escape("Q&A")}"
test_url "with a complex escaped query param", "http://example.com:80/search?q=#{CGI.escape("A&(! 234k !@ kasdj232\#$ kjw35")}"
end
describe '.stub_requests using specific match_attributes' do
before(:each) { subject.http_connections_allowed = false }
let(:interactions) { VCR::YAML.load_file(File.join(VCR::SPEC_ROOT, 'fixtures', YAML_SERIALIZATION_VERSION, 'match_requests_on.yml')) }
@supported_request_match_attributes = supported_request_match_attributes
def self.matching_on(attribute, valid, invalid, &block)
supported_request_match_attributes = @supported_request_match_attributes
describe ":#{attribute}" do
let(:perform_stubbing) { subject.stub_requests(interactions, match_requests_on) }
let(:match_requests_on) { [attribute] }
let(:record_mode) { :none }
if supported_request_match_attributes.include?(attribute)
before(:each) { perform_stubbing }
module_eval(&block)
valid.each do |val, response|
it "returns the expected response for a #{val.inspect} request" do
get_body_string(make_http_request(val)).should == response
end
end
it "raises an error for a request with a different #{attribute}" do
expect { make_http_request(invalid) }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
end
else
it 'raises an error indicating matching requests on this attribute is not supported' do
expect { perform_stubbing }.to raise_error(/does not support matching requests on #{attribute}/)
end
end
end
end
matching_on :method, { :get => "get method response", :post => "post method response" }, :put do
def make_http_request(http_method)
make_request(http_method, 'http://some-wrong-domain.com/', nil, {})
end
end
matching_on :host, { 'example1.com' => 'example1.com host response', 'example2.com' => 'example2.com host response' }, 'example3.com' do
def make_http_request(host)
make_request(:get, "http://#{host}/some/wrong/path", nil, {})
end
end
matching_on :path, { '/path1' => 'path1 response', '/path2' => 'path2 response' }, '/path3' do
def make_http_request(path)
make_request(:get, "http://some.wrong.domain.com#{path}?p=q", nil, {})
end
end
matching_on :uri, { 'http://example.com/uri1' => 'uri1 response', 'http://example.com/uri2' => 'uri2 response' }, 'http://example.com/uri3' do
def make_http_request(uri)
make_request(:get, uri, nil, {})
end
end
matching_on :body, { 'param=val1' => 'val1 body response', 'param=val2' => 'val2 body response' }, 'param=val3' do
def make_http_request(body)
make_request(:put, "http://wrong-domain.com/wrong/path", body, {})
end
end
matching_on :headers, {{ 'X-HTTP-HEADER1' => 'val1' } => 'val1 header response', { 'X-HTTP-HEADER1' => 'val2' } => 'val2 header response' }, { 'X-HTTP-HEADER1' => 'val3' } do
def make_http_request(headers)
make_request(:get, "http://wrong-domain.com/wrong/path", nil, headers)
end
end
end
def self.test_real_http_request(http_allowed, *other)
let(:url) { "http://localhost:#{VCR::SinatraApp.port}/foo" }
if http_allowed
it 'allows real http requests' do
get_body_string(make_http_request(:get, url)).should == 'FOO!'
end
describe 'recording new http requests' do
let(:recorded_interaction) do
interaction = nil
VCR.should_receive(:record_http_interaction) { |i| interaction = i }
make_http_request(:get, url)
interaction
end
it 'does not record the request if the adapter is disabled' do
subject.stub(:enabled?).and_return(false)
VCR.should_not_receive(:record_http_interaction)
make_http_request(:get, url)
end
it 'records the request uri' do
recorded_interaction.request.uri.should == url
end
it 'records the request method' do
recorded_interaction.request.method.should == :get
end
it 'records the request body' do
recorded_interaction.request.body.should be_nil
end
it 'records the request headers' do
recorded_interaction.request.headers.should be_nil
end
it 'records the response status code' do
recorded_interaction.response.status.code.should == 200
end
it 'records the response status message' do
recorded_interaction.response.status.message.should == 'OK'
end unless other.include?(:status_message_not_exposed)
it 'records the response body' do
recorded_interaction.response.body.should == 'FOO!'
end
it 'records the response headers' do
recorded_interaction.response.headers['content-type'].should == ["text/html;charset=utf-8"]
end
end
else
let(:record_mode) { :none }
it 'does not allow real HTTP requests or record them' do
VCR.should_receive(:record_http_interaction).never
expect { make_http_request(:get, url) }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
end
end
end
def test_request_stubbed(method, url, expected)
subject.request_stubbed?(VCR::Request.new(method, url), [:method, :uri]).should == expected
end
it "returns false from #http_connections_allowed? when http_connections_allowed is set to nil" do
subject.http_connections_allowed = nil
subject.http_connections_allowed?.should == false
end
describe '.restore_stubs_checkpoint' do
it 'raises an appropriate error when there is no matching checkpoint' do
expect {
subject.restore_stubs_checkpoint(:some_crazy_checkpoint_that_doesnt_exist)
}.to raise_error(ArgumentError, /no checkpoint .* could be found/i)
end
end
[true, false].each do |http_allowed|
context "when http_connections_allowed is set to #{http_allowed}" do
before(:each) { subject.http_connections_allowed = http_allowed }
it "returns #{http_allowed} for #http_connections_allowed?" do
subject.http_connections_allowed?.should == http_allowed
end
test_real_http_request(http_allowed, *other)
unless http_allowed
localhost_response = "Localhost response"
describe '.ignore_hosts' do
let(:record_mode) { :none }
context 'when set to ["127.0.0.1", "localhost"]' do
before(:each) do
subject.ignored_hosts = ["127.0.0.1", "localhost"]
end
%w[ 127.0.0.1 localhost ].each do |localhost_alias|
it "allows requests to #{localhost_alias}" do
get_body_string(make_http_request(:get, "http://#{localhost_alias}:#{VCR::SinatraApp.port}/localhost_test")).should == localhost_response
end
end
it 'does not allow requests to 0.0.0.0' do
expect { make_http_request(:get, "http://0.0.0.0:#{VCR::SinatraApp.port}/localhost_test") }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
end
end
end
end
context 'when some requests are stubbed, after setting a checkpoint' do
before(:each) do
subject.create_stubs_checkpoint(:my_checkpoint)
@recorded_interactions = VCR::YAML.load_file(File.join(VCR::SPEC_ROOT, 'fixtures', YAML_SERIALIZATION_VERSION, 'fake_example.com_responses.yml'))
subject.stub_requests(@recorded_interactions, VCR::RequestMatcher::DEFAULT_MATCH_ATTRIBUTES)
end
if other.include?(:needs_net_http_extension)
it 'returns true from #request_stubbed? for the requests that are stubbed' do
test_request_stubbed(:post, 'http://example.com', true)
test_request_stubbed(:get, 'http://example.com/foo', true)
end
it 'returns false from #request_stubbed? for requests that are not stubbed' do
test_request_stubbed(:post, 'http://example.com/foo', false)
test_request_stubbed(:get, 'http://google.com', false)
end
end
it 'gets the stubbed responses when requests are made to http://example.com/foo, and does not record them' do
VCR.should_receive(:record_http_interaction).never
get_body_string(make_http_request(:get, 'http://example.com/foo')).should =~ /example\.com get response \d with path=foo/
end
it 'rotates through multiple responses for the same request' do
get_body_string(make_http_request(:get, 'http://example.com/foo')).should == 'example.com get response 1 with path=foo'
get_body_string(make_http_request(:get, 'http://example.com/foo')).should == 'example.com get response 2 with path=foo'
# subsequent requests keep getting the last one
get_body_string(make_http_request(:get, 'http://example.com/foo')).should == 'example.com get response 2 with path=foo'
get_body_string(make_http_request(:get, 'http://example.com/foo')).should == 'example.com get response 2 with path=foo'
end unless other.include?(:does_not_support_rotating_responses)
it "correctly handles stubbing multiple values for the same header" do
get_header('Set-Cookie', make_http_request(:get, 'http://example.com/two_set_cookie_headers')).should =~ ['bar=bazz', 'foo=bar']
end
context 'when we restore our previous check point' do
before(:each) { subject.restore_stubs_checkpoint(:my_checkpoint) }
test_real_http_request(http_allowed, *other)
if other.include?(:needs_net_http_extension)
it 'returns false from #request_stubbed?' do
test_request_stubbed(:get, 'http://example.com/foo', false)
test_request_stubbed(:post, 'http://example.com', false)
test_request_stubbed(:get, 'http://google.com', false)
end
end
end
end
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.