vcr 3.0.3 → 4.0.0
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.
- checksums.yaml +4 -4
- data/lib/vcr.rb +18 -1
- data/lib/vcr/cassette.rb +11 -3
- data/lib/vcr/cassette/persisters/file_system.rb +1 -1
- data/lib/vcr/configuration.rb +3 -5
- data/lib/vcr/deprecations.rb +0 -62
- data/lib/vcr/errors.rb +16 -0
- data/lib/vcr/library_hooks/typhoeus.rb +37 -8
- data/lib/vcr/middleware/faraday.rb +5 -1
- data/lib/vcr/structs.rb +1 -1
- data/lib/vcr/util/hooks.rb +1 -0
- data/lib/vcr/version.rb +1 -1
- metadata +9 -249
- data/features/CHANGELOG.md +0 -710
- data/features/CONTRIBUTING.md +0 -26
- data/features/LICENSE.md +0 -20
- data/features/README.md +0 -339
- data/features/Upgrade.md +0 -289
- data/features/about_these_examples.md +0 -18
- data/features/cassettes/allow_unused_http_interactions.feature +0 -100
- data/features/cassettes/automatic_re_recording.feature +0 -72
- data/features/cassettes/decompress.feature +0 -74
- data/features/cassettes/dynamic_erb.feature +0 -100
- data/features/cassettes/exclusive.feature +0 -126
- data/features/cassettes/format.feature +0 -411
- data/features/cassettes/freezing_time.feature +0 -68
- data/features/cassettes/naming.feature +0 -28
- data/features/cassettes/no_cassette.feature +0 -152
- data/features/cassettes/update_content_length_header.feature +0 -112
- data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
- data/features/configuration/cassette_library_dir.feature +0 -31
- data/features/configuration/debug_logging.feature +0 -58
- data/features/configuration/default_cassette_options.feature +0 -100
- data/features/configuration/filter_sensitive_data.feature +0 -153
- data/features/configuration/hook_into.feature +0 -172
- data/features/configuration/ignore_request.feature +0 -192
- data/features/configuration/preserve_exact_body_bytes.feature +0 -108
- data/features/configuration/query_parser.feature +0 -84
- data/features/configuration/uri_parser.feature +0 -93
- data/features/getting_started.md +0 -82
- data/features/hooks/after_http_request.feature +0 -58
- data/features/hooks/around_http_request.feature +0 -57
- data/features/hooks/before_http_request.feature +0 -63
- data/features/hooks/before_playback.feature +0 -184
- data/features/hooks/before_record.feature +0 -172
- data/features/http_libraries/em_http_request.feature +0 -250
- data/features/http_libraries/net_http.feature +0 -179
- data/features/middleware/faraday.feature +0 -56
- data/features/middleware/rack.feature +0 -92
- data/features/record_modes/all.feature +0 -82
- data/features/record_modes/new_episodes.feature +0 -79
- data/features/record_modes/none.feature +0 -72
- data/features/record_modes/once.feature +0 -95
- data/features/request_matching/README.md +0 -30
- data/features/request_matching/body.feature +0 -91
- data/features/request_matching/body_as_json.feature +0 -90
- data/features/request_matching/custom_matcher.feature +0 -135
- data/features/request_matching/headers.feature +0 -85
- data/features/request_matching/host.feature +0 -95
- data/features/request_matching/identical_request_sequence.feature +0 -89
- data/features/request_matching/method.feature +0 -96
- data/features/request_matching/path.feature +0 -96
- data/features/request_matching/playback_repeats.feature +0 -98
- data/features/request_matching/query.feature +0 -97
- data/features/request_matching/uri.feature +0 -94
- data/features/request_matching/uri_without_param.feature +0 -101
- data/features/step_definitions/cli_steps.rb +0 -199
- data/features/support/env.rb +0 -46
- data/features/support/http_lib_filters.rb +0 -46
- data/features/test_frameworks/cucumber.feature +0 -211
- data/features/test_frameworks/rspec_macro.feature +0 -81
- data/features/test_frameworks/rspec_metadata.feature +0 -150
- data/features/test_frameworks/test_unit.feature +0 -49
- data/lib/vcr/extensions/net_http_response.rb +0 -36
- data/lib/vcr/library_hooks/fakeweb.rb +0 -197
- data/spec/acceptance/concurrency_spec.rb +0 -51
- data/spec/acceptance/threading_spec.rb +0 -34
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +0 -111
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
- data/spec/fixtures/fake_example_responses.yml +0 -110
- data/spec/fixtures/match_requests_on.yml +0 -187
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
- data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
- data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
- data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
- data/spec/lib/vcr/cassette_spec.rb +0 -618
- data/spec/lib/vcr/configuration_spec.rb +0 -326
- data/spec/lib/vcr/deprecations_spec.rb +0 -85
- data/spec/lib/vcr/errors_spec.rb +0 -178
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
- data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
- data/spec/lib/vcr/library_hooks_spec.rb +0 -51
- data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
- data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
- data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
- data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
- data/spec/lib/vcr/structs_spec.rb +0 -732
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
- data/spec/lib/vcr/util/hooks_spec.rb +0 -158
- data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
- data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
- data/spec/lib/vcr/version_spec.rb +0 -27
- data/spec/lib/vcr_spec.rb +0 -354
- data/spec/monkey_patches.rb +0 -186
- data/spec/spec_helper.rb +0 -63
- data/spec/support/configuration_stubbing.rb +0 -8
- data/spec/support/cucumber_helpers.rb +0 -39
- data/spec/support/fixnum_extension.rb +0 -10
- data/spec/support/http_library_adapters.rb +0 -289
- data/spec/support/limited_uri.rb +0 -21
- data/spec/support/ruby_interpreter.rb +0 -7
- data/spec/support/shared_example_groups/excon.rb +0 -63
- data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
- data/spec/support/shared_example_groups/request_hooks.rb +0 -59
- data/spec/support/sinatra_app.rb +0 -86
- data/spec/support/vcr_localhost_server.rb +0 -76
- data/spec/support/vcr_stub_helpers.rb +0 -17
@@ -1,594 +0,0 @@
|
|
1
|
-
require 'cgi'
|
2
|
-
|
3
|
-
NET_CONNECT_NOT_ALLOWED_ERROR = /An HTTP request has been made that VCR does not know how to handle/
|
4
|
-
|
5
|
-
shared_examples_for "a hook into an HTTP library" do |library_hook_name, library, *other|
|
6
|
-
include HeaderDowncaser
|
7
|
-
include VCRStubHelpers
|
8
|
-
|
9
|
-
unless adapter_module = HTTP_LIBRARY_ADAPTERS[library]
|
10
|
-
raise ArgumentError.new("No http library adapter module could be found for #{library}")
|
11
|
-
end
|
12
|
-
|
13
|
-
http_lib_unsupported = (RUBY_INTERPRETER != :mri && library =~ /(typhoeus|curb|patron|em-http)/)
|
14
|
-
|
15
|
-
describe "using #{adapter_module.http_library_name}", :unless => http_lib_unsupported do
|
16
|
-
include adapter_module
|
17
|
-
|
18
|
-
# Necessary for ruby 1.9.2. On 1.9.2 we get an error when we use super,
|
19
|
-
# so this gives us another alias we can use for the original method.
|
20
|
-
alias make_request make_http_request
|
21
|
-
|
22
|
-
1.upto(2) do |header_count|
|
23
|
-
describe "making an HTTP request that responds with #{header_count} Set-Cookie header(s)" do
|
24
|
-
define_method :get_set_cookie_header do
|
25
|
-
VCR.use_cassette('header_test', :record => :once) do
|
26
|
-
get_header 'Set-Cookie', make_http_request(:get, "http://localhost:#{VCR::SinatraApp.port}/set-cookie-headers/#{header_count}")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'returns the same header value when recording and replaying' do
|
31
|
-
expect((recorded_val = get_set_cookie_header)).not_to be_nil
|
32
|
-
replayed_val = get_set_cookie_header
|
33
|
-
expect(replayed_val).to eq(recorded_val)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.test_record_and_playback(description, query)
|
39
|
-
describe "a request to a URL #{description}" do
|
40
|
-
define_method :get_body do
|
41
|
-
VCR.use_cassette('record_and_playback', :record => :once) do
|
42
|
-
get_body_string make_http_request(:get, "http://localhost:#{VCR::SinatraApp.port}/record-and-playback?#{query}")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
it "properly records and playsback a request with a URL #{description}" do
|
47
|
-
recorded_body = get_body
|
48
|
-
played_back_body = get_body
|
49
|
-
expect(played_back_body).to eq(recorded_body)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
test_record_and_playback "with spaces encoded as +", "q=a+b"
|
55
|
-
test_record_and_playback "with spaces encoded as %20", "q=a%20b"
|
56
|
-
test_record_and_playback "with a complex escaped query param", "q=#{CGI.escape("A&(! 234k !@ kasdj232\#$ kjw35")}"
|
57
|
-
|
58
|
-
it 'plays back an empty body response exactly as it was recorded (e.g. nil vs empty string)' do
|
59
|
-
pending "awaiting an external fix" if library_hook_name == :fakeweb
|
60
|
-
skip "Faraday 0.8 may return nil bodies" if library_hook_name == :faraday && !defined?(::Faraday::RackBuilder)
|
61
|
-
get_body = lambda do
|
62
|
-
VCR.use_cassette('empty_body', :record => :once) do
|
63
|
-
get_body_object make_http_request(:get, "http://localhost:#{VCR::SinatraApp.port}/204")
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
recorded = get_body.call
|
68
|
-
played_back = get_body.call
|
69
|
-
expect(played_back).to eq(recorded)
|
70
|
-
end
|
71
|
-
|
72
|
-
describe 'making an HTTP request' do
|
73
|
-
let(:status) { VCR::ResponseStatus.new(200, 'OK') }
|
74
|
-
let(:interaction) { VCR::HTTPInteraction.new(request, response) }
|
75
|
-
let(:response_body) { "The response body" }
|
76
|
-
|
77
|
-
before(:each) do
|
78
|
-
stub_requests([interaction], [:method, :uri])
|
79
|
-
end
|
80
|
-
|
81
|
-
context "when the the stubbed request and response has no headers" do
|
82
|
-
let(:request) { VCR::Request.new(:get, 'http://example.com:80/') }
|
83
|
-
let(:response) { VCR::Response.new(status, nil, response_body, '1.1') }
|
84
|
-
|
85
|
-
it 'returns the response for a matching request' do
|
86
|
-
expect(get_body_string(make_http_request(:get, 'http://example.com/'))).to eq(response_body)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.test_playback(description, url)
|
91
|
-
context "when a URL #{description} has been stubbed" do
|
92
|
-
let(:request) { VCR::Request.new(:get, url) }
|
93
|
-
let(:response) { VCR::Response.new(status, nil, response_body, '1.1') }
|
94
|
-
|
95
|
-
it 'returns the expected response for the same request' do
|
96
|
-
expect(get_body_string(make_http_request(:get, url))).to eq(response_body)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
test_playback "using https and no explicit port", "https://example.com/foo"
|
102
|
-
test_playback "using https and port 443", "https://example.com:443/foo"
|
103
|
-
test_playback "using https and some other port", "https://example.com:5190/foo"
|
104
|
-
test_playback "that has query params", "http://example.com/search?q=param"
|
105
|
-
test_playback "with an encoded ampersand", "http://example.com:80/search?q=#{CGI.escape("Q&A")}"
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'does not query the http interaction list excessively' do
|
109
|
-
call_count = 0
|
110
|
-
[:has_interaction_matching?, :response_for].each do |method_name|
|
111
|
-
orig_meth = VCR.http_interactions.method(method_name)
|
112
|
-
allow(VCR.http_interactions).to receive(method_name) do |*args|
|
113
|
-
call_count += 1
|
114
|
-
orig_meth.call(*args)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
VCR.insert_cassette('foo')
|
119
|
-
make_http_request(:get, "http://localhost:#{VCR::SinatraApp.port}/foo")
|
120
|
-
|
121
|
-
expect(call_count).to eq(1)
|
122
|
-
end
|
123
|
-
|
124
|
-
describe "using the library's stubbing/disconnection APIs" do
|
125
|
-
let!(:request_url) { "http://localhost:#{VCR::SinatraApp.port}/foo" }
|
126
|
-
|
127
|
-
if method_defined?(:disable_real_connections)
|
128
|
-
it 'can make a real request when VCR is turned off' do
|
129
|
-
enable_real_connections
|
130
|
-
VCR.turn_off!
|
131
|
-
expect(get_body_string(make_http_request(:get, request_url))).to eq("FOO!")
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'does not mess with VCR when real connections are disabled' do
|
135
|
-
VCR.insert_cassette('example')
|
136
|
-
disable_real_connections
|
137
|
-
|
138
|
-
expect(VCR).to receive(:record_http_interaction) do |interaction|
|
139
|
-
expect(interaction.request.uri).to eq(request_url)
|
140
|
-
end
|
141
|
-
|
142
|
-
make_http_request(:get, request_url)
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'can disable real connections when VCR is turned off' do
|
146
|
-
VCR.turn_off!
|
147
|
-
expected_error = disable_real_connections
|
148
|
-
|
149
|
-
expect {
|
150
|
-
make_http_request(:get, request_url)
|
151
|
-
}.to raise_error(expected_error)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
if method_defined?(:directly_stub_request)
|
156
|
-
it 'can directly stub the request when VCR is turned off' do
|
157
|
-
VCR.turn_off!
|
158
|
-
directly_stub_request(:get, request_url, "stubbed response")
|
159
|
-
expect(get_body_string(make_http_request(:get, request_url))).to eq("stubbed response")
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'can directly stub the request when VCR is turned on and no cassette is in use' do
|
163
|
-
directly_stub_request(:get, request_url, "stubbed response")
|
164
|
-
expect(get_body_string(make_http_request(:get, request_url))).to eq("stubbed response")
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'can directly stub the request when VCR is turned on and a cassette is in use' do
|
168
|
-
VCR.use_cassette("temp") do
|
169
|
-
directly_stub_request(:get, request_url, "stubbed response")
|
170
|
-
expect(get_body_string(make_http_request(:get, request_url))).to eq("stubbed response")
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'does not record requests that are directly stubbed' do
|
175
|
-
expect(VCR).to respond_to(:record_http_interaction)
|
176
|
-
expect(VCR).not_to receive(:record_http_interaction)
|
177
|
-
|
178
|
-
VCR.use_cassette("temp") do
|
179
|
-
directly_stub_request(:get, request_url, "stubbed response")
|
180
|
-
expect(get_body_string(make_http_request(:get, request_url))).to eq("stubbed response")
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
describe "request hooks" do
|
187
|
-
context 'when there is an around_http_request hook' do
|
188
|
-
let(:request_url) { "http://localhost:#{VCR::SinatraApp.port}/foo" }
|
189
|
-
|
190
|
-
it 'yields the request to the block' do
|
191
|
-
yielded_request = nil
|
192
|
-
VCR.configuration.around_http_request do |request|
|
193
|
-
yielded_request = request
|
194
|
-
request.proceed
|
195
|
-
end
|
196
|
-
|
197
|
-
VCR.use_cassette('new_cassette') do
|
198
|
-
make_http_request(:get, request_url)
|
199
|
-
end
|
200
|
-
|
201
|
-
expect(yielded_request.method).to eq(:get)
|
202
|
-
expect(yielded_request.uri).to eq(request_url)
|
203
|
-
end
|
204
|
-
|
205
|
-
it 'returns the response from request.proceed' do
|
206
|
-
response = nil
|
207
|
-
VCR.configuration.around_http_request do |request|
|
208
|
-
response = request.proceed
|
209
|
-
end
|
210
|
-
|
211
|
-
VCR.use_cassette('new_cassette') do
|
212
|
-
make_http_request(:get, request_url)
|
213
|
-
end
|
214
|
-
|
215
|
-
expect(response.body).to eq("FOO!")
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'can be used to use a cassette for a request' do
|
219
|
-
VCR.configuration.around_http_request do |request|
|
220
|
-
VCR.use_cassette('new_cassette', &request)
|
221
|
-
end
|
222
|
-
|
223
|
-
expect(VCR).to receive(:record_http_interaction) do
|
224
|
-
expect(VCR.current_cassette.name).to eq('new_cassette')
|
225
|
-
end
|
226
|
-
|
227
|
-
expect(VCR.current_cassette).to be_nil
|
228
|
-
make_http_request(:get, request_url)
|
229
|
-
expect(VCR.current_cassette).to be_nil
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'nests them inside each other, making the first declared hook the outermost' do
|
233
|
-
order = []
|
234
|
-
|
235
|
-
VCR.configure do |c|
|
236
|
-
c.ignore_request { |r| true }
|
237
|
-
c.around_http_request do |request|
|
238
|
-
order << :before_1
|
239
|
-
request.proceed
|
240
|
-
order << :after_1
|
241
|
-
end
|
242
|
-
|
243
|
-
c.around_http_request do |request|
|
244
|
-
order << :before_2
|
245
|
-
request.proceed
|
246
|
-
order << :after_2
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
make_http_request(:get, request_url)
|
251
|
-
|
252
|
-
expect(order).to eq([:before_1, :before_2, :after_2, :after_1])
|
253
|
-
end
|
254
|
-
|
255
|
-
it 'raises an appropriate error if the hook does not call request.proceed' do
|
256
|
-
VCR.configuration.ignore_request { |r| true }
|
257
|
-
hook_declaration = "#{__FILE__}:#{__LINE__ + 1}"
|
258
|
-
VCR.configuration.around_http_request { |r| }
|
259
|
-
|
260
|
-
expect {
|
261
|
-
make_http_request(:get, request_url)
|
262
|
-
}.to raise_error { |error|
|
263
|
-
expect(error.message).to include('must call #proceed on the yielded request')
|
264
|
-
expect(error.message).to include(hook_declaration)
|
265
|
-
}
|
266
|
-
end
|
267
|
-
|
268
|
-
it 'does not get a dead fiber error when multiple requests are made' do
|
269
|
-
VCR.configuration.around_http_request do |request|
|
270
|
-
VCR.use_cassette('new_cassette', &request)
|
271
|
-
end
|
272
|
-
|
273
|
-
3.times { make_http_request(:get, request_url) }
|
274
|
-
end
|
275
|
-
|
276
|
-
it 'allows the hook to be filtered' do
|
277
|
-
order = []
|
278
|
-
VCR.configure do |c|
|
279
|
-
c.ignore_request { |r| true }
|
280
|
-
c.around_http_request(lambda { |r| r.uri =~ /foo/}) do |request|
|
281
|
-
order << :before_foo
|
282
|
-
request.proceed
|
283
|
-
order << :after_foo
|
284
|
-
end
|
285
|
-
|
286
|
-
c.around_http_request(lambda { |r| r.uri !~ /foo/}) do |request|
|
287
|
-
order << :before_not_foo
|
288
|
-
request.proceed
|
289
|
-
order << :after_not_foo
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
make_http_request(:get, request_url)
|
294
|
-
expect(order).to eq([:before_foo, :after_foo])
|
295
|
-
end
|
296
|
-
|
297
|
-
it 'ensures that both around/before are invoked or neither' do
|
298
|
-
order = []
|
299
|
-
allow_1, allow_2 = false, true
|
300
|
-
VCR.configure do |c|
|
301
|
-
c.ignore_request { |r| true }
|
302
|
-
c.around_http_request(lambda { |r| allow_1 = !allow_1 }) do |request|
|
303
|
-
order << :before_1
|
304
|
-
request.proceed
|
305
|
-
order << :after_1
|
306
|
-
end
|
307
|
-
|
308
|
-
c.around_http_request(lambda { |r| allow_2 = !allow_2 }) do |request|
|
309
|
-
order << :before_2
|
310
|
-
request.proceed
|
311
|
-
order << :after_2
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
make_http_request(:get, request_url)
|
316
|
-
expect(order).to eq([:before_1, :after_1])
|
317
|
-
end
|
318
|
-
end if RUBY_VERSION >= '1.9'
|
319
|
-
|
320
|
-
it 'correctly assigns the correct type to both before and after request hooks, even if they are different' do
|
321
|
-
before_type = after_type = nil
|
322
|
-
VCR.configuration.before_http_request do |request|
|
323
|
-
before_type = request.type
|
324
|
-
VCR.insert_cassette('example')
|
325
|
-
end
|
326
|
-
|
327
|
-
VCR.configuration.after_http_request do |request|
|
328
|
-
after_type = request.type
|
329
|
-
VCR.eject_cassette
|
330
|
-
end
|
331
|
-
|
332
|
-
make_http_request(:get, "http://localhost:#{VCR::SinatraApp.port}/foo")
|
333
|
-
expect(before_type).to be(:unhandled)
|
334
|
-
expect(after_type).to be(:recordable)
|
335
|
-
end
|
336
|
-
|
337
|
-
context "when the request is ignored" do
|
338
|
-
before(:each) do
|
339
|
-
VCR.configuration.ignore_request { |r| true }
|
340
|
-
end
|
341
|
-
|
342
|
-
it_behaves_like "request hooks", library_hook_name, :ignored
|
343
|
-
end
|
344
|
-
|
345
|
-
context "when the request is directly stubbed" do
|
346
|
-
before(:each) do
|
347
|
-
directly_stub_request(:get, request_url, "FOO!")
|
348
|
-
end
|
349
|
-
|
350
|
-
it_behaves_like "request hooks", library_hook_name, :externally_stubbed
|
351
|
-
end if method_defined?(:directly_stub_request)
|
352
|
-
|
353
|
-
context 'when the request is recorded' do
|
354
|
-
let!(:inserted_cassette) { VCR.insert_cassette('new_cassette') }
|
355
|
-
|
356
|
-
it_behaves_like "request hooks", library_hook_name, :recordable do
|
357
|
-
let(:string_in_cassette) { 'example.com get response 1 with path=foo' }
|
358
|
-
|
359
|
-
it 'plays back the cassette when a request is made' do
|
360
|
-
VCR.eject_cassette
|
361
|
-
VCR.configure do |c|
|
362
|
-
c.cassette_library_dir = File.join(VCR::SPEC_ROOT, 'fixtures')
|
363
|
-
c.before_http_request do |request|
|
364
|
-
VCR.insert_cassette('fake_example_responses', :record => :none)
|
365
|
-
end
|
366
|
-
end
|
367
|
-
expect(get_body_string(make_http_request(:get, 'http://example.com/foo'))).to eq(string_in_cassette)
|
368
|
-
end
|
369
|
-
|
370
|
-
specify 'the after_http_request hook can be used to eject a cassette after the request is recorded' do
|
371
|
-
VCR.configuration.after_http_request { |request| VCR.eject_cassette }
|
372
|
-
|
373
|
-
expect(VCR).to receive(:record_http_interaction) do |interaction|
|
374
|
-
expect(VCR.current_cassette).to be(inserted_cassette)
|
375
|
-
end
|
376
|
-
|
377
|
-
make_request
|
378
|
-
expect(VCR.current_cassette).to be_nil
|
379
|
-
end
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
context 'when a stubbed response is played back for the request' do
|
384
|
-
before(:each) do
|
385
|
-
stub_requests([http_interaction(request_url)], [:method, :uri])
|
386
|
-
end
|
387
|
-
|
388
|
-
it_behaves_like "request hooks", library_hook_name, :stubbed_by_vcr
|
389
|
-
end
|
390
|
-
|
391
|
-
context 'when the request is not allowed' do
|
392
|
-
it_behaves_like "request hooks", library_hook_name, :unhandled do
|
393
|
-
undef assert_expected_response
|
394
|
-
def assert_expected_response(response)
|
395
|
-
expect(response).to be_nil
|
396
|
-
end
|
397
|
-
|
398
|
-
undef make_request
|
399
|
-
def make_request(disabled = false)
|
400
|
-
if disabled
|
401
|
-
make_http_request(:get, request_url)
|
402
|
-
else
|
403
|
-
expect { make_http_request(:get, request_url) }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
|
404
|
-
end
|
405
|
-
end
|
406
|
-
end
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
describe '.stub_requests using specific match_attributes' do
|
411
|
-
before(:each) { allow(VCR).to receive(:real_http_connections_allowed?).and_return(false) }
|
412
|
-
let(:interactions) { interactions_from('match_requests_on.yml') }
|
413
|
-
|
414
|
-
let(:normalized_interactions) do
|
415
|
-
interactions.each do |i|
|
416
|
-
i.request.headers = normalize_request_headers(i.request.headers)
|
417
|
-
end
|
418
|
-
interactions
|
419
|
-
end
|
420
|
-
|
421
|
-
def self.matching_on(attribute, valid, invalid, &block)
|
422
|
-
describe ":#{attribute}" do
|
423
|
-
let(:perform_stubbing) { stub_requests(normalized_interactions, [attribute]) }
|
424
|
-
|
425
|
-
before(:each) { perform_stubbing }
|
426
|
-
module_eval(&block)
|
427
|
-
|
428
|
-
valid.each do |val, response|
|
429
|
-
it "returns the expected response for a #{val.inspect} request" do
|
430
|
-
expect(get_body_string(make_http_request(val))).to eq(response)
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
it "raises an error for a request with a different #{attribute}" do
|
435
|
-
expect { make_http_request(invalid) }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
matching_on :method, { :get => "get method response", :post => "post method response" }, :put do
|
441
|
-
def make_http_request(http_method)
|
442
|
-
make_request(http_method, 'http://some-wrong-domain.com/', nil, {})
|
443
|
-
end
|
444
|
-
end
|
445
|
-
|
446
|
-
matching_on :host, { 'example1.com' => 'example1.com host response', 'example2.com' => 'example2.com host response' }, 'example3.com' do
|
447
|
-
def make_http_request(host)
|
448
|
-
make_request(:get, "http://#{host}/some/wrong/path", nil, {})
|
449
|
-
end
|
450
|
-
end
|
451
|
-
|
452
|
-
matching_on :path, { '/path1' => 'path1 response', '/path2' => 'path2 response' }, '/path3' do
|
453
|
-
def make_http_request(path)
|
454
|
-
make_request(:get, "http://some.wrong.domain.com#{path}?p=q", nil, {})
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
|
-
matching_on :uri, { 'http://example.com/uri1' => 'uri1 response', 'http://example.com/uri2' => 'uri2 response' }, 'http://example.com/uri3' do
|
459
|
-
def make_http_request(uri)
|
460
|
-
make_request(:get, uri, nil, {})
|
461
|
-
end
|
462
|
-
end
|
463
|
-
|
464
|
-
matching_on :body, { 'param=val1' => 'val1 body response', 'param=val2' => 'val2 body response' }, 'param=val3' do
|
465
|
-
def make_http_request(body)
|
466
|
-
make_request(:put, "http://wrong-domain.com/wrong/path", body, {})
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
matching_on :headers, {{ 'X-Http-Header1' => 'val1' } => 'val1 header response', { 'X-Http-Header1' => 'val2' } => 'val2 header response' }, { 'X-Http-Header1' => 'val3' } do
|
471
|
-
def make_http_request(headers)
|
472
|
-
make_request(:get, "http://wrong-domain.com/wrong/path", nil, headers)
|
473
|
-
end
|
474
|
-
end
|
475
|
-
end
|
476
|
-
|
477
|
-
def self.test_real_http_request(http_allowed, *other)
|
478
|
-
let(:url) { "http://localhost:#{VCR::SinatraApp.port}/foo" }
|
479
|
-
|
480
|
-
if http_allowed
|
481
|
-
|
482
|
-
it 'allows real http requests' do
|
483
|
-
expect(get_body_string(make_http_request(:get, url))).to eq('FOO!')
|
484
|
-
end
|
485
|
-
|
486
|
-
describe 'recording new http requests' do
|
487
|
-
let(:recorded_interaction) do
|
488
|
-
interaction = nil
|
489
|
-
expect(VCR).to receive(:record_http_interaction) { |i| interaction = i }
|
490
|
-
make_http_request(:post, url, "the body", { 'X-Http-Foo' => 'bar' })
|
491
|
-
interaction
|
492
|
-
end
|
493
|
-
|
494
|
-
it 'does not record the request if the hook is disabled' do
|
495
|
-
VCR.library_hooks.exclusively_enabled :something_else do
|
496
|
-
expect(VCR).not_to receive(:record_http_interaction)
|
497
|
-
make_http_request(:get, url)
|
498
|
-
end
|
499
|
-
end
|
500
|
-
|
501
|
-
it 'records the request uri' do
|
502
|
-
expect(recorded_interaction.request.uri).to eq(url)
|
503
|
-
end
|
504
|
-
|
505
|
-
it 'records the request method' do
|
506
|
-
expect(recorded_interaction.request.method).to eq(:post)
|
507
|
-
end
|
508
|
-
|
509
|
-
it 'records the request body' do
|
510
|
-
expect(recorded_interaction.request.body).to eq("the body")
|
511
|
-
end
|
512
|
-
|
513
|
-
it 'records the request headers' do
|
514
|
-
headers = downcase_headers(recorded_interaction.request.headers)
|
515
|
-
expect(headers).to include('x-http-foo' => ['bar'])
|
516
|
-
end
|
517
|
-
|
518
|
-
it 'records the response status code' do
|
519
|
-
expect(recorded_interaction.response.status.code).to eq(200)
|
520
|
-
end
|
521
|
-
|
522
|
-
it 'records the response status message' do
|
523
|
-
expect(recorded_interaction.response.status.message.strip).to eq('OK')
|
524
|
-
end unless other.include?(:status_message_not_exposed)
|
525
|
-
|
526
|
-
it 'records the response body' do
|
527
|
-
expect(recorded_interaction.response.body).to eq('FOO!')
|
528
|
-
end
|
529
|
-
|
530
|
-
it 'records the response headers' do
|
531
|
-
headers = downcase_headers(recorded_interaction.response.headers)
|
532
|
-
expect(headers).to include('content-type' => ["text/html;charset=utf-8"])
|
533
|
-
end
|
534
|
-
end
|
535
|
-
else
|
536
|
-
it 'does not allow real HTTP requests or record them' do
|
537
|
-
expect(VCR).to receive(:record_http_interaction).never
|
538
|
-
expect { make_http_request(:get, url) }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
|
539
|
-
end
|
540
|
-
end
|
541
|
-
end
|
542
|
-
|
543
|
-
[true, false].each do |http_allowed|
|
544
|
-
context "when VCR.real_http_connections_allowed? is returning #{http_allowed}" do
|
545
|
-
before(:each) { allow(VCR).to receive(:real_http_connections_allowed?).and_return(http_allowed) }
|
546
|
-
|
547
|
-
test_real_http_request(http_allowed, *other)
|
548
|
-
|
549
|
-
unless http_allowed
|
550
|
-
localhost_response = "Localhost response"
|
551
|
-
|
552
|
-
context 'when ignore_hosts is configured to "127.0.0.1", "localhost"' do
|
553
|
-
before(:each) do
|
554
|
-
VCR.configure { |c| c.ignore_hosts "127.0.0.1", "localhost" }
|
555
|
-
end
|
556
|
-
|
557
|
-
%w[ 127.0.0.1 localhost ].each do |localhost_alias|
|
558
|
-
it "allows requests to #{localhost_alias}" do
|
559
|
-
expect(get_body_string(make_http_request(:get, "http://#{localhost_alias}:#{VCR::SinatraApp.port}/localhost_test"))).to eq(localhost_response)
|
560
|
-
end
|
561
|
-
end
|
562
|
-
|
563
|
-
it 'does not allow requests to 0.0.0.0' do
|
564
|
-
expect { make_http_request(:get, "http://0.0.0.0:#{VCR::SinatraApp.port}/localhost_test") }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
|
565
|
-
end
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
context 'when some requests are stubbed' do
|
570
|
-
let(:interactions) { interactions_from('fake_example_responses.yml') }
|
571
|
-
before(:each) do
|
572
|
-
stub_requests(interactions, VCR::RequestMatcherRegistry::DEFAULT_MATCHERS)
|
573
|
-
end
|
574
|
-
|
575
|
-
it 'gets the stubbed responses when requests are made to http://example.com/foo, and does not record them' do
|
576
|
-
expect(VCR).to receive(:record_http_interaction).never
|
577
|
-
expect(get_body_string(make_http_request(:get, 'http://example.com/foo'))).to match(/example\.com get response \d with path=foo/)
|
578
|
-
end
|
579
|
-
|
580
|
-
it 'rotates through multiple responses for the same request' do
|
581
|
-
expect(get_body_string(make_http_request(:get, 'http://example.com/foo'))).to eq('example.com get response 1 with path=foo')
|
582
|
-
expect(get_body_string(make_http_request(:get, 'http://example.com/foo'))).to eq('example.com get response 2 with path=foo')
|
583
|
-
end unless other.include?(:does_not_support_rotating_responses)
|
584
|
-
|
585
|
-
it "correctly handles stubbing multiple values for the same header" do
|
586
|
-
header = get_header('Set-Cookie', make_http_request(:get, 'http://example.com/two_set_cookie_headers'))
|
587
|
-
header = header.split(', ') if header.respond_to?(:split)
|
588
|
-
expect(header).to match_array ['bar=bazz', 'foo=bar']
|
589
|
-
end
|
590
|
-
end
|
591
|
-
end
|
592
|
-
end
|
593
|
-
end
|
594
|
-
end
|