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.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vcr.rb +18 -1
  3. data/lib/vcr/cassette.rb +11 -3
  4. data/lib/vcr/cassette/persisters/file_system.rb +1 -1
  5. data/lib/vcr/configuration.rb +3 -5
  6. data/lib/vcr/deprecations.rb +0 -62
  7. data/lib/vcr/errors.rb +16 -0
  8. data/lib/vcr/library_hooks/typhoeus.rb +37 -8
  9. data/lib/vcr/middleware/faraday.rb +5 -1
  10. data/lib/vcr/structs.rb +1 -1
  11. data/lib/vcr/util/hooks.rb +1 -0
  12. data/lib/vcr/version.rb +1 -1
  13. metadata +9 -249
  14. data/features/CHANGELOG.md +0 -710
  15. data/features/CONTRIBUTING.md +0 -26
  16. data/features/LICENSE.md +0 -20
  17. data/features/README.md +0 -339
  18. data/features/Upgrade.md +0 -289
  19. data/features/about_these_examples.md +0 -18
  20. data/features/cassettes/allow_unused_http_interactions.feature +0 -100
  21. data/features/cassettes/automatic_re_recording.feature +0 -72
  22. data/features/cassettes/decompress.feature +0 -74
  23. data/features/cassettes/dynamic_erb.feature +0 -100
  24. data/features/cassettes/exclusive.feature +0 -126
  25. data/features/cassettes/format.feature +0 -411
  26. data/features/cassettes/freezing_time.feature +0 -68
  27. data/features/cassettes/naming.feature +0 -28
  28. data/features/cassettes/no_cassette.feature +0 -152
  29. data/features/cassettes/update_content_length_header.feature +0 -112
  30. data/features/configuration/allow_http_connections_when_no_cassette.feature +0 -55
  31. data/features/configuration/cassette_library_dir.feature +0 -31
  32. data/features/configuration/debug_logging.feature +0 -58
  33. data/features/configuration/default_cassette_options.feature +0 -100
  34. data/features/configuration/filter_sensitive_data.feature +0 -153
  35. data/features/configuration/hook_into.feature +0 -172
  36. data/features/configuration/ignore_request.feature +0 -192
  37. data/features/configuration/preserve_exact_body_bytes.feature +0 -108
  38. data/features/configuration/query_parser.feature +0 -84
  39. data/features/configuration/uri_parser.feature +0 -93
  40. data/features/getting_started.md +0 -82
  41. data/features/hooks/after_http_request.feature +0 -58
  42. data/features/hooks/around_http_request.feature +0 -57
  43. data/features/hooks/before_http_request.feature +0 -63
  44. data/features/hooks/before_playback.feature +0 -184
  45. data/features/hooks/before_record.feature +0 -172
  46. data/features/http_libraries/em_http_request.feature +0 -250
  47. data/features/http_libraries/net_http.feature +0 -179
  48. data/features/middleware/faraday.feature +0 -56
  49. data/features/middleware/rack.feature +0 -92
  50. data/features/record_modes/all.feature +0 -82
  51. data/features/record_modes/new_episodes.feature +0 -79
  52. data/features/record_modes/none.feature +0 -72
  53. data/features/record_modes/once.feature +0 -95
  54. data/features/request_matching/README.md +0 -30
  55. data/features/request_matching/body.feature +0 -91
  56. data/features/request_matching/body_as_json.feature +0 -90
  57. data/features/request_matching/custom_matcher.feature +0 -135
  58. data/features/request_matching/headers.feature +0 -85
  59. data/features/request_matching/host.feature +0 -95
  60. data/features/request_matching/identical_request_sequence.feature +0 -89
  61. data/features/request_matching/method.feature +0 -96
  62. data/features/request_matching/path.feature +0 -96
  63. data/features/request_matching/playback_repeats.feature +0 -98
  64. data/features/request_matching/query.feature +0 -97
  65. data/features/request_matching/uri.feature +0 -94
  66. data/features/request_matching/uri_without_param.feature +0 -101
  67. data/features/step_definitions/cli_steps.rb +0 -199
  68. data/features/support/env.rb +0 -46
  69. data/features/support/http_lib_filters.rb +0 -46
  70. data/features/test_frameworks/cucumber.feature +0 -211
  71. data/features/test_frameworks/rspec_macro.feature +0 -81
  72. data/features/test_frameworks/rspec_metadata.feature +0 -150
  73. data/features/test_frameworks/test_unit.feature +0 -49
  74. data/lib/vcr/extensions/net_http_response.rb +0 -36
  75. data/lib/vcr/library_hooks/fakeweb.rb +0 -197
  76. data/spec/acceptance/concurrency_spec.rb +0 -51
  77. data/spec/acceptance/threading_spec.rb +0 -34
  78. data/spec/fixtures/cassette_spec/1_x_cassette.yml +0 -110
  79. data/spec/fixtures/cassette_spec/empty.yml +0 -0
  80. data/spec/fixtures/cassette_spec/example.yml +0 -111
  81. data/spec/fixtures/cassette_spec/with_localhost_requests.yml +0 -111
  82. data/spec/fixtures/fake_example_responses.yml +0 -110
  83. data/spec/fixtures/match_requests_on.yml +0 -187
  84. data/spec/lib/vcr/cassette/erb_renderer_spec.rb +0 -53
  85. data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +0 -295
  86. data/spec/lib/vcr/cassette/migrator_spec.rb +0 -196
  87. data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +0 -75
  88. data/spec/lib/vcr/cassette/persisters_spec.rb +0 -39
  89. data/spec/lib/vcr/cassette/serializers_spec.rb +0 -182
  90. data/spec/lib/vcr/cassette_spec.rb +0 -618
  91. data/spec/lib/vcr/configuration_spec.rb +0 -326
  92. data/spec/lib/vcr/deprecations_spec.rb +0 -85
  93. data/spec/lib/vcr/errors_spec.rb +0 -178
  94. data/spec/lib/vcr/extensions/net_http_response_spec.rb +0 -86
  95. data/spec/lib/vcr/library_hooks/excon_spec.rb +0 -104
  96. data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +0 -169
  97. data/spec/lib/vcr/library_hooks/faraday_spec.rb +0 -68
  98. data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +0 -36
  99. data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +0 -162
  100. data/spec/lib/vcr/library_hooks/webmock_spec.rb +0 -117
  101. data/spec/lib/vcr/library_hooks_spec.rb +0 -51
  102. data/spec/lib/vcr/middleware/faraday_spec.rb +0 -181
  103. data/spec/lib/vcr/middleware/rack_spec.rb +0 -115
  104. data/spec/lib/vcr/request_ignorer_spec.rb +0 -70
  105. data/spec/lib/vcr/request_matcher_registry_spec.rb +0 -345
  106. data/spec/lib/vcr/structs_spec.rb +0 -732
  107. data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +0 -107
  108. data/spec/lib/vcr/test_frameworks/rspec_spec.rb +0 -94
  109. data/spec/lib/vcr/util/hooks_spec.rb +0 -158
  110. data/spec/lib/vcr/util/internet_connection_spec.rb +0 -37
  111. data/spec/lib/vcr/util/version_checker_spec.rb +0 -31
  112. data/spec/lib/vcr/version_spec.rb +0 -27
  113. data/spec/lib/vcr_spec.rb +0 -354
  114. data/spec/monkey_patches.rb +0 -186
  115. data/spec/spec_helper.rb +0 -63
  116. data/spec/support/configuration_stubbing.rb +0 -8
  117. data/spec/support/cucumber_helpers.rb +0 -39
  118. data/spec/support/fixnum_extension.rb +0 -10
  119. data/spec/support/http_library_adapters.rb +0 -289
  120. data/spec/support/limited_uri.rb +0 -21
  121. data/spec/support/ruby_interpreter.rb +0 -7
  122. data/spec/support/shared_example_groups/excon.rb +0 -63
  123. data/spec/support/shared_example_groups/hook_into_http_library.rb +0 -594
  124. data/spec/support/shared_example_groups/request_hooks.rb +0 -59
  125. data/spec/support/sinatra_app.rb +0 -86
  126. data/spec/support/vcr_localhost_server.rb +0 -76
  127. 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