mustwin-vcr 2.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. checksums.yaml +7 -0
  2. data/features/about_these_examples.md +18 -0
  3. data/features/cassettes/allow_unused_http_interactions.feature +100 -0
  4. data/features/cassettes/automatic_re_recording.feature +72 -0
  5. data/features/cassettes/decompress.feature +74 -0
  6. data/features/cassettes/dynamic_erb.feature +100 -0
  7. data/features/cassettes/exclusive.feature +126 -0
  8. data/features/cassettes/format.feature +323 -0
  9. data/features/cassettes/freezing_time.feature +68 -0
  10. data/features/cassettes/naming.feature +28 -0
  11. data/features/cassettes/no_cassette.feature +152 -0
  12. data/features/cassettes/update_content_length_header.feature +112 -0
  13. data/features/configuration/allow_http_connections_when_no_cassette.feature +55 -0
  14. data/features/configuration/cassette_library_dir.feature +31 -0
  15. data/features/configuration/debug_logging.feature +59 -0
  16. data/features/configuration/default_cassette_options.feature +100 -0
  17. data/features/configuration/filter_sensitive_data.feature +153 -0
  18. data/features/configuration/hook_into.feature +172 -0
  19. data/features/configuration/ignore_request.feature +192 -0
  20. data/features/configuration/preserve_exact_body_bytes.feature +108 -0
  21. data/features/configuration/query_parser.feature +84 -0
  22. data/features/configuration/uri_parser.feature +89 -0
  23. data/features/getting_started.md +82 -0
  24. data/features/hooks/after_http_request.feature +58 -0
  25. data/features/hooks/around_http_request.feature +57 -0
  26. data/features/hooks/before_http_request.feature +63 -0
  27. data/features/hooks/before_playback.feature +184 -0
  28. data/features/hooks/before_record.feature +172 -0
  29. data/features/http_libraries/em_http_request.feature +250 -0
  30. data/features/http_libraries/net_http.feature +179 -0
  31. data/features/middleware/faraday.feature +56 -0
  32. data/features/middleware/rack.feature +92 -0
  33. data/features/record_modes/all.feature +82 -0
  34. data/features/record_modes/new_episodes.feature +79 -0
  35. data/features/record_modes/none.feature +72 -0
  36. data/features/record_modes/once.feature +95 -0
  37. data/features/request_matching/README.md +30 -0
  38. data/features/request_matching/body.feature +91 -0
  39. data/features/request_matching/body_as_json.feature +90 -0
  40. data/features/request_matching/custom_matcher.feature +135 -0
  41. data/features/request_matching/headers.feature +85 -0
  42. data/features/request_matching/host.feature +95 -0
  43. data/features/request_matching/identical_request_sequence.feature +89 -0
  44. data/features/request_matching/method.feature +96 -0
  45. data/features/request_matching/path.feature +96 -0
  46. data/features/request_matching/playback_repeats.feature +98 -0
  47. data/features/request_matching/query.feature +97 -0
  48. data/features/request_matching/uri.feature +94 -0
  49. data/features/request_matching/uri_without_param.feature +101 -0
  50. data/features/step_definitions/cli_steps.rb +193 -0
  51. data/features/support/env.rb +44 -0
  52. data/features/support/http_lib_filters.rb +53 -0
  53. data/features/test_frameworks/cucumber.feature +211 -0
  54. data/features/test_frameworks/rspec_macro.feature +81 -0
  55. data/features/test_frameworks/rspec_metadata.feature +150 -0
  56. data/features/test_frameworks/test_unit.feature +49 -0
  57. data/lib/vcr.rb +347 -0
  58. data/lib/vcr/cassette.rb +291 -0
  59. data/lib/vcr/cassette/erb_renderer.rb +55 -0
  60. data/lib/vcr/cassette/http_interaction_list.rb +108 -0
  61. data/lib/vcr/cassette/migrator.rb +118 -0
  62. data/lib/vcr/cassette/persisters.rb +42 -0
  63. data/lib/vcr/cassette/persisters/file_system.rb +64 -0
  64. data/lib/vcr/cassette/serializers.rb +57 -0
  65. data/lib/vcr/cassette/serializers/json.rb +48 -0
  66. data/lib/vcr/cassette/serializers/psych.rb +48 -0
  67. data/lib/vcr/cassette/serializers/syck.rb +61 -0
  68. data/lib/vcr/cassette/serializers/yaml.rb +50 -0
  69. data/lib/vcr/configuration.rb +555 -0
  70. data/lib/vcr/deprecations.rb +109 -0
  71. data/lib/vcr/errors.rb +266 -0
  72. data/lib/vcr/extensions/net_http_response.rb +36 -0
  73. data/lib/vcr/library_hooks.rb +18 -0
  74. data/lib/vcr/library_hooks/excon.rb +27 -0
  75. data/lib/vcr/library_hooks/fakeweb.rb +196 -0
  76. data/lib/vcr/library_hooks/faraday.rb +51 -0
  77. data/lib/vcr/library_hooks/typhoeus.rb +120 -0
  78. data/lib/vcr/library_hooks/typhoeus_0.4.rb +103 -0
  79. data/lib/vcr/library_hooks/webmock.rb +164 -0
  80. data/lib/vcr/middleware/excon.rb +221 -0
  81. data/lib/vcr/middleware/excon/legacy_methods.rb +33 -0
  82. data/lib/vcr/middleware/faraday.rb +118 -0
  83. data/lib/vcr/middleware/rack.rb +79 -0
  84. data/lib/vcr/request_handler.rb +114 -0
  85. data/lib/vcr/request_ignorer.rb +43 -0
  86. data/lib/vcr/request_matcher_registry.rb +149 -0
  87. data/lib/vcr/structs.rb +578 -0
  88. data/lib/vcr/tasks/vcr.rake +9 -0
  89. data/lib/vcr/test_frameworks/cucumber.rb +64 -0
  90. data/lib/vcr/test_frameworks/rspec.rb +47 -0
  91. data/lib/vcr/util/hooks.rb +61 -0
  92. data/lib/vcr/util/internet_connection.rb +43 -0
  93. data/lib/vcr/util/logger.rb +59 -0
  94. data/lib/vcr/util/variable_args_block_caller.rb +13 -0
  95. data/lib/vcr/util/version_checker.rb +48 -0
  96. data/lib/vcr/version.rb +34 -0
  97. data/spec/acceptance/threading_spec.rb +34 -0
  98. data/spec/fixtures/cassette_spec/1_x_cassette.yml +110 -0
  99. data/spec/fixtures/cassette_spec/empty.yml +0 -0
  100. data/spec/fixtures/cassette_spec/example.yml +111 -0
  101. data/spec/fixtures/cassette_spec/with_localhost_requests.yml +111 -0
  102. data/spec/fixtures/fake_example_responses.yml +110 -0
  103. data/spec/fixtures/match_requests_on.yml +187 -0
  104. data/spec/lib/vcr/cassette/erb_renderer_spec.rb +53 -0
  105. data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +295 -0
  106. data/spec/lib/vcr/cassette/migrator_spec.rb +195 -0
  107. data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +69 -0
  108. data/spec/lib/vcr/cassette/persisters_spec.rb +39 -0
  109. data/spec/lib/vcr/cassette/serializers_spec.rb +176 -0
  110. data/spec/lib/vcr/cassette_spec.rb +618 -0
  111. data/spec/lib/vcr/configuration_spec.rb +326 -0
  112. data/spec/lib/vcr/deprecations_spec.rb +85 -0
  113. data/spec/lib/vcr/errors_spec.rb +162 -0
  114. data/spec/lib/vcr/extensions/net_http_response_spec.rb +86 -0
  115. data/spec/lib/vcr/library_hooks/excon_spec.rb +104 -0
  116. data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +169 -0
  117. data/spec/lib/vcr/library_hooks/faraday_spec.rb +68 -0
  118. data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +36 -0
  119. data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +162 -0
  120. data/spec/lib/vcr/library_hooks/webmock_spec.rb +118 -0
  121. data/spec/lib/vcr/library_hooks_spec.rb +51 -0
  122. data/spec/lib/vcr/middleware/faraday_spec.rb +182 -0
  123. data/spec/lib/vcr/middleware/rack_spec.rb +115 -0
  124. data/spec/lib/vcr/request_ignorer_spec.rb +70 -0
  125. data/spec/lib/vcr/request_matcher_registry_spec.rb +345 -0
  126. data/spec/lib/vcr/structs_spec.rb +732 -0
  127. data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +107 -0
  128. data/spec/lib/vcr/test_frameworks/rspec_spec.rb +83 -0
  129. data/spec/lib/vcr/util/hooks_spec.rb +158 -0
  130. data/spec/lib/vcr/util/internet_connection_spec.rb +37 -0
  131. data/spec/lib/vcr/util/version_checker_spec.rb +31 -0
  132. data/spec/lib/vcr/version_spec.rb +27 -0
  133. data/spec/lib/vcr_spec.rb +349 -0
  134. data/spec/monkey_patches.rb +182 -0
  135. data/spec/spec_helper.rb +62 -0
  136. data/spec/support/configuration_stubbing.rb +8 -0
  137. data/spec/support/cucumber_helpers.rb +35 -0
  138. data/spec/support/fixnum_extension.rb +10 -0
  139. data/spec/support/http_library_adapters.rb +289 -0
  140. data/spec/support/limited_uri.rb +21 -0
  141. data/spec/support/ruby_interpreter.rb +7 -0
  142. data/spec/support/shared_example_groups/excon.rb +63 -0
  143. data/spec/support/shared_example_groups/hook_into_http_library.rb +594 -0
  144. data/spec/support/shared_example_groups/request_hooks.rb +59 -0
  145. data/spec/support/sinatra_app.rb +86 -0
  146. data/spec/support/vcr_localhost_server.rb +76 -0
  147. data/spec/support/vcr_stub_helpers.rb +17 -0
  148. metadata +677 -0
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Typhoeus hook", :with_monkey_patches => :typhoeus do
4
+ after(:each) do
5
+ ::Typhoeus::Expectation.clear
6
+ end
7
+
8
+ def disable_real_connections
9
+ ::Typhoeus::Config.block_connection = true
10
+ ::Typhoeus::Errors::NoStub
11
+ end
12
+
13
+ def enable_real_connections
14
+ ::Typhoeus::Config.block_connection = false
15
+ end
16
+
17
+ def directly_stub_request(method, url, response_body)
18
+ response = ::Typhoeus::Response.new(:code => 200, :body => response_body)
19
+ ::Typhoeus.stub(url, :method => method).and_return(response)
20
+ end
21
+
22
+ it_behaves_like 'a hook into an HTTP library', :typhoeus, 'typhoeus'
23
+
24
+ describe "VCR.configuration.after_library_hooks_loaded hook" do
25
+ it 'disables the webmock typhoeus adapter so it does not conflict with our typhoeus hook' do
26
+ expect(::WebMock::HttpLibAdapters::TyphoeusAdapter).to receive(:disable!)
27
+ $typhoeus_after_loaded_hook.conditionally_invoke
28
+ end
29
+ end
30
+
31
+ context 'when there are nested hydra queues' do
32
+ def make_requests
33
+ VCR.use_cassette("nested") do
34
+ response_1 = response_2 = nil
35
+
36
+ hydra = Typhoeus::Hydra.new
37
+ request = Typhoeus::Request.new("http://localhost:#{VCR::SinatraApp.port}/")
38
+
39
+ request.on_success do |r1|
40
+ response_1 = r1
41
+
42
+ nested = Typhoeus::Request.new("http://localhost:#{VCR::SinatraApp.port}/foo")
43
+ nested.on_success { |r2| response_2 = r2 }
44
+
45
+ hydra.queue(nested)
46
+ end
47
+
48
+ hydra.queue(request)
49
+ hydra.run
50
+
51
+ return body_for(response_1), body_for(response_2)
52
+ end
53
+ end
54
+
55
+ def body_for(response)
56
+ return :no_response if response.nil?
57
+ response.body
58
+ end
59
+
60
+ it 'records and plays back properly' do
61
+ recorded = make_requests
62
+ played_back = make_requests
63
+
64
+ expect(played_back).to eq(recorded)
65
+ end
66
+ end
67
+
68
+ context "when used with a typhoeus-based faraday connection" do
69
+ let(:base_url) { "http://localhost:#{VCR::SinatraApp.port}" }
70
+
71
+ let(:conn) do
72
+ Faraday.new(:url => base_url) do |faraday|
73
+ faraday.adapter :typhoeus
74
+ end
75
+ end
76
+
77
+ def get_response
78
+ # Ensure faraday hook doesn't handle the request.
79
+ VCR.library_hooks.exclusively_enabled(:typhoeus) do
80
+ VCR.use_cassette("faraday") do
81
+ conn.get("/")
82
+ end
83
+ end
84
+ end
85
+
86
+ it 'records and replays headers correctly' do
87
+ recorded = get_response
88
+ played_back = get_response
89
+
90
+ expect(played_back.headers).to eq(recorded.headers)
91
+ end
92
+ end
93
+
94
+ context 'when a request is made with a hash for the POST body' do
95
+ def make_request
96
+ VCR.use_cassette("hash_body") do
97
+ Typhoeus::Request.post(
98
+ "http://localhost:#{VCR::SinatraApp.port}/return-request-body",
99
+ :body => { :foo => "17" }
100
+ )
101
+ end
102
+ end
103
+
104
+ it 'records and replays correctly' do
105
+ recorded = make_request
106
+ played_back = make_request
107
+
108
+ expect(recorded.body).to eq("foo=17")
109
+ expect(played_back.body).to eq(recorded.body)
110
+ end
111
+ end
112
+
113
+ context '#effective_url' do
114
+ ResponseValues = Struct.new(:status, :body, :effective_url)
115
+
116
+ def url_for(path)
117
+ "http://localhost:#{VCR::SinatraApp.port}#{path}"
118
+ end
119
+
120
+ def make_single_request(path, options = {})
121
+ VCR.use_cassette('single') do |cassette|
122
+ response = Typhoeus::Request.new(url_for(path), options).run
123
+
124
+ yield cassette if block_given?
125
+
126
+ ResponseValues.new(
127
+ response.code,
128
+ response.body,
129
+ response.effective_url
130
+ )
131
+ end
132
+ end
133
+
134
+ it 'records and plays back properly' do
135
+ recorded = make_single_request('/')
136
+ played_back = make_single_request('/')
137
+
138
+ expect(recorded.effective_url).to eq(url_for('/'))
139
+ expect(played_back).to eq(recorded)
140
+ end
141
+
142
+ it 'falls back to the request url when it was not recorded (e.g. on VCR <= 2.5.0)' do
143
+ make_single_request('/') do |cassette|
144
+ cassette.new_recorded_interactions.each { |i| i.response.adapter_metadata.clear }
145
+ end
146
+
147
+ played_back = make_single_request('/')
148
+ expect(played_back.effective_url).to eq(url_for('/'))
149
+ end
150
+
151
+ context "when following redirects" do
152
+ it 'records and plays back properly' do
153
+ recorded = make_single_request('/redirect-to-root', :followlocation => true)
154
+ played_back = make_single_request('/redirect-to-root', :followlocation => true)
155
+
156
+ expect(recorded.effective_url).to eq(url_for('/'))
157
+ expect(played_back).to eq(recorded)
158
+ end
159
+ end
160
+ end
161
+ end
162
+
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+ require 'support/shared_example_groups/excon'
3
+
4
+ describe "WebMock hook", :with_monkey_patches => :webmock do
5
+ after(:each) do
6
+ ::WebMock.reset!
7
+ end
8
+
9
+ def disable_real_connections(options = {})
10
+ ::WebMock.disable_net_connect!(options)
11
+ ::WebMock::NetConnectNotAllowedError
12
+ end
13
+
14
+ def enable_real_connections
15
+ ::WebMock.allow_net_connect!
16
+ end
17
+
18
+ def directly_stub_request(method, url, response_body)
19
+ ::WebMock.stub_request(method, url).to_return(:body => response_body)
20
+ end
21
+
22
+ describe "our WebMock.after_request hook" do
23
+ let(:webmock_request) { ::WebMock::RequestSignature.new(:get, "http://foo.com/", :body => "", :headers => {}) }
24
+ let(:webmock_response) { ::WebMock::Response.new(:body => 'OK', :status => [200, '']) }
25
+
26
+ def run_after_request_callback
27
+ ::WebMock::CallbackRegistry.invoke_callbacks(
28
+ { :real_request => true },
29
+ webmock_request,
30
+ webmock_response)
31
+ end
32
+
33
+ it 'removes the @__typed_vcr_request instance variable so as not to pollute the webmock object' do
34
+ request = VCR::Request::Typed.new(VCR::Request, :ignored?)
35
+ webmock_request.instance_variable_set(:@__typed_vcr_request, request)
36
+
37
+ run_after_request_callback
38
+ expect(webmock_request.instance_variables.map(&:to_sym)).not_to include(:@__typed_vcr_request)
39
+ end
40
+
41
+ context "when there'ss a bug and the request does not have the @__typed_vcr_request in the after_request callbacks" do
42
+ let(:warner) { VCR::LibraryHooks::WebMock }
43
+ before { allow(warner).to receive(:warn) }
44
+
45
+ it 'records the HTTP interaction properly' do
46
+ expect(VCR).to receive(:record_http_interaction) do |i|
47
+ expect(i.request.uri).to eq("http://foo.com/")
48
+ expect(i.response.body).to eq("OK")
49
+ end
50
+
51
+ run_after_request_callback
52
+ end
53
+
54
+ it 'invokes the after_http_request hook with an :unknown request' do
55
+ request = nil
56
+ VCR.configuration.after_http_request do |req, res|
57
+ request = req
58
+ end
59
+
60
+ run_after_request_callback
61
+ expect(request.uri).to eq("http://foo.com/")
62
+ expect(request.type).to eq(:unknown)
63
+ end
64
+
65
+ it 'prints a warning' do
66
+ expect(warner).to receive(:warn).at_least(:once).with(/bug.*after_request/)
67
+
68
+ run_after_request_callback
69
+ end
70
+ end
71
+ end
72
+
73
+ http_libs = %w[net/http patron httpclient em-http-request curb typhoeus excon]
74
+ http_libs.delete('patron') if RUBY_VERSION == '1.8.7'
75
+ http_libs.each do |lib|
76
+ other = []
77
+ other << :status_message_not_exposed if lib == 'excon'
78
+ it_behaves_like 'a hook into an HTTP library', :webmock, lib, *other do
79
+ if lib == 'net/http'
80
+ def normalize_request_headers(headers)
81
+ headers.merge(DEFAULT_REQUEST_HEADERS)
82
+ end
83
+ end
84
+ end
85
+
86
+ http_lib_unsupported = (RUBY_INTERPRETER != :mri && lib =~ /(typhoeus|curb|patron|em-http)/)
87
+
88
+ adapter_module = HTTP_LIBRARY_ADAPTERS.fetch(lib)
89
+ describe "using #{adapter_module.http_library_name}", :unless => http_lib_unsupported do
90
+ include adapter_module
91
+
92
+ let!(:request_url) { "http://localhost:#{VCR::SinatraApp.port}/foo" }
93
+
94
+ context 'when real connections are disabled and VCR is turned off' do
95
+ it 'can allow connections to localhost' do
96
+ VCR.turn_off!
97
+ disable_real_connections(:allow_localhost => true)
98
+
99
+ expect {
100
+ make_http_request(:get, request_url)
101
+ }.to_not raise_error
102
+ end
103
+
104
+ it 'can allow connections to matching urls' do
105
+ VCR.turn_off!
106
+ disable_real_connections(:allow => /foo/)
107
+
108
+ expect {
109
+ make_http_request(:get, request_url)
110
+ }.to_not raise_error
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ it_behaves_like "Excon streaming"
117
+ end
118
+
@@ -0,0 +1,51 @@
1
+ require 'vcr/library_hooks'
2
+
3
+ module VCR
4
+ describe LibraryHooks do
5
+ describe '#disabled?' do
6
+ it 'returns false by default for any argument given' do
7
+ expect(subject.disabled?(:foo)).to be false
8
+ expect(subject.disabled?(:bar)).to be false
9
+ end
10
+
11
+ context 'when a library hook is exclusively enabled' do
12
+ it 'returns false for the exclusively enabled hook' do
13
+ faraday_disabled = nil
14
+
15
+ subject.exclusively_enabled :faraday do
16
+ faraday_disabled = subject.disabled?(:faraday)
17
+ end
18
+
19
+ expect(faraday_disabled).to eq(false)
20
+ end
21
+
22
+ it 'returns true for every other argument given' do
23
+ foo_disabled = bar_disabled = nil
24
+
25
+ subject.exclusively_enabled :faraday do
26
+ foo_disabled = subject.disabled?(:foo)
27
+ bar_disabled = subject.disabled?(:bar)
28
+ end
29
+
30
+ expect(foo_disabled).to be true
31
+ expect(bar_disabled).to be true
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#exclusively_enabled' do
37
+ it 'restores all hook to being enabled when the block completes' do
38
+ subject.exclusively_enabled(:faraday) { }
39
+ expect(subject.disabled?(:foo)).to be false
40
+ expect(subject.disabled?(:faraday)).to be false
41
+ end
42
+
43
+ it 'restores all hooks to being enabled when the block completes, even if there is an error' do
44
+ subject.exclusively_enabled(:faraday) { raise "boom" } rescue
45
+ expect(subject.disabled?(:foo)).to be false
46
+ expect(subject.disabled?(:faraday)).to be false
47
+ end
48
+ end
49
+ end
50
+ end
51
+
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+ require 'vcr/library_hooks/faraday'
3
+
4
+ describe VCR::Middleware::Faraday do
5
+ http_libs = %w[ typhoeus net_http patron ]
6
+ http_libs.delete('patron') if RUBY_VERSION == '1.8.7'
7
+ http_libs.each do |lib|
8
+ it_behaves_like 'a hook into an HTTP library', :faraday, "faraday (w/ #{lib})",
9
+ :status_message_not_exposed,
10
+ :does_not_support_rotating_responses
11
+ end
12
+
13
+ context 'when performing a multipart upload' do
14
+ let(:connection) do
15
+ ::Faraday.new("http://localhost:#{VCR::SinatraApp.port}/") do |b|
16
+ b.request :multipart
17
+ end
18
+ end
19
+
20
+ def self.test_recording
21
+ it 'records the request body correctly' do
22
+ payload = { :file => Faraday::UploadIO.new(__FILE__, 'text/plain') }
23
+
24
+ expect(VCR).to receive(:record_http_interaction) do |i|
25
+ expect(i.request.headers['Content-Type'].first).to include("multipart")
26
+ expect(i.request.body).to include(File.read(__FILE__))
27
+ end
28
+
29
+ VCR.use_cassette("upload") do
30
+ connection.post '/files', payload
31
+ end
32
+ end
33
+ end
34
+
35
+ context 'when the net_http adapter is used' do
36
+ before { connection.builder.adapter :net_http }
37
+ test_recording
38
+ end
39
+
40
+ context 'when no adapter is used' do
41
+ test_recording
42
+ end
43
+ end
44
+
45
+ context 'when extending the response body with an extension module' do
46
+ let(:connection) { ::Faraday.new("http://localhost:#{VCR::SinatraApp.port}/") }
47
+
48
+ def process_response(response)
49
+ response.body.extend Module.new { attr_accessor :_response }
50
+ response.body._response = response
51
+ end
52
+
53
+ it 'does not record the body extensions to the cassette' do
54
+ 3.times do |i|
55
+ VCR.use_cassette("hack", :record => :new_episodes) do
56
+ response = connection.get("/foo")
57
+ process_response(response)
58
+
59
+ # Do something different after the first time to
60
+ # ensure new interactions are added to an existing
61
+ # cassette.
62
+ if i > 1
63
+ response = connection.get("/")
64
+ process_response(response)
65
+ end
66
+ end
67
+ end
68
+
69
+ contents = VCR::Cassette.new("hack").send(:raw_cassette_bytes)
70
+ expect(contents).not_to include("ruby/object:Faraday::Response")
71
+ end
72
+ end
73
+
74
+ context 'when making parallel requests' do
75
+ include VCRStubHelpers
76
+ let(:connection) { ::Faraday.new { |b| b.adapter :typhoeus } }
77
+ let(:request_url) { "http://localhost:#{VCR::SinatraApp.port}/" }
78
+
79
+ it 'works correctly with multiple parallel requests' do
80
+ recorded, played_back = [1, 2].map do
81
+ responses = []
82
+
83
+ VCR.use_cassette("multiple_parallel") do
84
+ connection.in_parallel do
85
+ responses << connection.get(request_url)
86
+ responses << connection.get(request_url)
87
+ end
88
+ end
89
+
90
+ responses.map(&:body)
91
+ end
92
+
93
+ # there should be no blanks
94
+ expect(recorded.select { |r| r.to_s == '' }).to eq([])
95
+ expect(played_back).to eq(recorded)
96
+ end
97
+
98
+ shared_examples_for "exclusive library hook" do
99
+ def make_request
100
+ connection.in_parallel { connection.get(request_url) }
101
+ end
102
+
103
+ it 'makes the faraday middleware exclusively enabled for the duration of the request' do
104
+ expect(VCR.library_hooks).not_to be_disabled(:fakeweb)
105
+
106
+ hook_called = false
107
+ VCR.configuration.after_http_request do
108
+ hook_called = true
109
+ expect(VCR.library_hooks).to be_disabled(:fakeweb)
110
+ end
111
+
112
+ make_request
113
+ expect(VCR.library_hooks).not_to be_disabled(:fakeweb)
114
+ expect(hook_called).to be true
115
+ end
116
+ end
117
+
118
+ context 'for an ignored request' do
119
+ before(:each) { VCR.configuration.ignore_request { true } }
120
+ it_behaves_like "exclusive library hook"
121
+ end
122
+
123
+ context 'for a stubbed request' do
124
+ it_behaves_like "exclusive library hook" do
125
+ before(:each) do
126
+ stub_requests([http_interaction(request_url)], [:method, :uri])
127
+ end
128
+ end
129
+ end
130
+
131
+ context "when another adapter is exclusive" do
132
+ it 'still makes requests properly' do
133
+ response = VCR.library_hooks.exclusively_enabled(:typhoeus) do
134
+ Faraday.get("http://localhost:#{VCR::SinatraApp.port}/")
135
+ end
136
+
137
+ expect(response.body).to eq("GET to root")
138
+ end
139
+ end
140
+
141
+ context 'for a recorded request' do
142
+ let!(:inserted_cassette) { VCR.insert_cassette('new_cassette') }
143
+ before(:each) { expect(VCR).to receive(:record_http_interaction) }
144
+ it_behaves_like "exclusive library hook"
145
+ end
146
+
147
+ context 'for a disallowed request' do
148
+ it_behaves_like "exclusive library hook" do
149
+ undef make_request
150
+ def make_request
151
+ expect {
152
+ connection.in_parallel { connection.get(request_url) }
153
+ }.to raise_error(VCR::Errors::UnhandledHTTPRequestError)
154
+ end
155
+ end
156
+ end
157
+
158
+ it_behaves_like "request hooks", :faraday, :recordable do
159
+ let!(:inserted_cassette) { VCR.insert_cassette('new_cassette') }
160
+
161
+ undef make_request
162
+ def make_request(disabled = false)
163
+ response = nil
164
+ connection.in_parallel do
165
+ response = connection.get(request_url)
166
+ end
167
+ response
168
+ end
169
+
170
+ it 'can be used to eject a cassette after the request is recorded' do
171
+ VCR.configuration.after_http_request { |request| VCR.eject_cassette }
172
+
173
+ expect(VCR).to receive(:record_http_interaction) do |interaction|
174
+ expect(VCR.current_cassette).to be(inserted_cassette)
175
+ end
176
+
177
+ make_request
178
+ expect(VCR.current_cassette).to be_nil
179
+ end
180
+ end
181
+ end if defined?(::Typhoeus)
182
+ end