require 'spec_helper' describe "FakeWeb hook", :with_monkey_patches => :fakeweb do after(:each) do ::FakeWeb.clean_registry end def disable_real_connections ::FakeWeb.allow_net_connect = false ::FakeWeb::NetConnectNotAllowedError end def enable_real_connections ::FakeWeb.allow_net_connect = true end def directly_stub_request(method, url, response_body) ::FakeWeb.register_uri(method, url, :body => response_body) end it_behaves_like 'a hook into an HTTP library', :fakeweb, 'net/http' do before(:each) do VCR::LibraryHooks::FakeWeb::RequestHandler.already_seen_requests.clear end after(:each) do # assert that we are cleaning up the global state after every request VCR::LibraryHooks::FakeWeb::RequestHandler.already_seen_requests.to_a.should eq([]) end end it_performs('version checking', 'FakeWeb', :valid => %w[ 1.3.0 1.3.1 1.3.99 ], :too_low => %w[ 1.2.8 1.1.30 0.30.30 ], :too_high => %w[ 1.4.0 1.10.0 2.0.0 ] ) do before(:each) { @orig_version = FakeWeb::VERSION } after(:each) { FakeWeb::VERSION = @orig_version } # Cannot be regular method def as that raises a "dynamic constant assignment" error define_method :stub_version do |version| FakeWeb::VERSION = version end end describe "some specific Net::HTTP edge cases" do before(:each) do VCR.stub(:real_http_connections_allowed? => true) end it "does not record headers for which Net::HTTP sets defaults near the end of the real request" do VCR.should_receive(:record_http_interaction) do |interaction| interaction.request.headers.should_not have_key('content-type') interaction.request.headers.should_not have_key('host') end Net::HTTP.new('localhost', VCR::SinatraApp.port).send_request('POST', '/', '', { 'x-http-user' => 'me' }) end it "records headers for which Net::HTTP usually sets defaults when the user manually sets their values" do VCR.should_receive(:record_http_interaction) do |interaction| interaction.request.headers['content-type'].should eq(['foo/bar']) interaction.request.headers['host'].should eq(['my-example.com']) end Net::HTTP.new('localhost', VCR::SinatraApp.port).send_request('POST', '/', '', { 'Content-Type' => 'foo/bar', 'Host' => 'my-example.com' }) end def perform_get_with_returning_block Net::HTTP.new('localhost', VCR::SinatraApp.port).request(Net::HTTP::Get.new('/', {})) do |response| return response end end it 'records the interaction when Net::HTTP#request is called with a block with a return statement' do VCR.should_receive(:record_http_interaction).once perform_get_with_returning_block.body.should eq("GET to root") end def make_post_request Net::HTTP.new('localhost', VCR::SinatraApp.port).post('/record-and-playback', '') end it 'records the interaction only once, even when Net::HTTP internally recursively calls #request' do VCR.should_receive(:record_http_interaction).once make_post_request end it 'properly returns the response body for a post request when recording, stubbing or ignoring the request' do recorded_body = nil VCR.use_cassette("new_cassette", :record => :once) do recorded_body = make_post_request.body recorded_body.should match(/Response \d+/) end VCR.use_cassette("new_cassette", :record => :once) do make_post_request.body.should eq(recorded_body) end VCR.configuration.ignore_request { |r| true } ignored_body = make_post_request.body ignored_body.should_not eq(recorded_body) ignored_body.should match(/Response \d+/) end end describe "VCR.configuration.after_library_hooks_loaded hook", :disable_warnings do before(:each) do load "vcr/library_hooks/fakeweb.rb" # to re-add the hook since it's cleared by each test end let(:run_hook) { VCR.configuration.invoke_hook(:after_library_hooks_loaded) } context 'when WebMock has been loaded' do before(:each) { defined?(WebMock).should be_true } it 'raises an error since FakeWeb and WebMock cannot both be used simultaneously' do expect { run_hook }.to raise_error(ArgumentError, /cannot use both/) end end context 'when WebMock has not been loaded' do let!(:orig_webmock_constant) { ::WebMock } before(:each) { Object.send(:remove_const, :WebMock) } after(:each) { ::WebMock = orig_webmock_constant } it 'does not raise an error' do run_hook # should not raise an error end end end describe "when a SocketError occurs" do before(:each) do VCR.configuration.ignore_request { |r| true } end it_behaves_like "request hooks", :fakeweb do undef assert_expected_response def assert_expected_response(response) response.should be_nil end undef make_request def make_request(disabled = false) ::Net::HTTP.any_instance.stub(:request_without_vcr).and_raise(SocketError) expect { ::Net::HTTP.get_response(URI(request_url)) }.to raise_error(SocketError) end end end end