vcr 1.3.3 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/CHANGELOG.md +16 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +23 -4
- data/Guardfile +6 -0
- data/README.md +5 -4
- data/Rakefile +1 -3
- data/TODO.md +3 -0
- data/cucumber.yml +3 -3
- data/features/cassettes/no_cassette.feature +67 -0
- data/features/configuration/allow_http_connections_when_no_cassette.feature +54 -0
- data/features/configuration/ignore_localhost.feature +2 -2
- data/features/configuration/stub_with.feature +40 -16
- data/features/http_libraries/em_http_request.feature +217 -0
- data/features/middleware/faraday.feature +89 -0
- data/features/middleware/rack.feature +95 -0
- data/features/step_definitions/cli_steps.rb +7 -0
- data/lib/vcr.rb +48 -4
- data/lib/vcr/config.rb +11 -2
- data/lib/vcr/extensions/net_http.rb +4 -0
- data/lib/vcr/http_stubbing_adapters/common.rb +35 -4
- data/lib/vcr/http_stubbing_adapters/faraday.rb +80 -0
- data/lib/vcr/http_stubbing_adapters/typhoeus.rb +1 -1
- data/lib/vcr/http_stubbing_adapters/webmock.rb +18 -16
- data/lib/vcr/middleware/cassette_arguments.rb +18 -0
- data/lib/vcr/middleware/common.rb +22 -0
- data/lib/vcr/middleware/faraday.rb +79 -0
- data/lib/vcr/middleware/rack.rb +13 -0
- data/lib/vcr/request_matcher.rb +16 -1
- data/lib/vcr/version.rb +1 -1
- data/spec/config_spec.rb +27 -2
- data/spec/fixtures/1.9.1/fake_example.com_responses.yml +0 -29
- data/spec/fixtures/1.9.1/match_requests_on.yml +2 -2
- data/spec/fixtures/not_1.9.1/fake_example.com_responses.yml +0 -29
- data/spec/http_stubbing_adapters/faraday_spec.rb +84 -0
- data/spec/middleware/cassette_arguments_spec.rb +32 -0
- data/spec/middleware/faraday_spec.rb +52 -0
- data/spec/middleware/rack_spec.rb +54 -0
- data/spec/monkey_patches.rb +1 -0
- data/spec/request_matcher_spec.rb +36 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/http_library_adapters.rb +113 -25
- data/spec/support/http_stubbing_adapter.rb +55 -16
- data/spec/vcr_spec.rb +92 -4
- data/vcr.gemspec +1 -0
- metadata +72 -34
@@ -1,33 +1,4 @@
|
|
1
1
|
---
|
2
|
-
- !ruby/struct:VCR::HTTPInteraction
|
3
|
-
:request: !ruby/struct:VCR::Request
|
4
|
-
:method: :post
|
5
|
-
:uri: http://example.com:80/
|
6
|
-
:body:
|
7
|
-
:headers:
|
8
|
-
:response: !ruby/struct:VCR::Response
|
9
|
-
:status: !ruby/struct:VCR::ResponseStatus
|
10
|
-
:code: 200
|
11
|
-
:message: OK
|
12
|
-
:headers:
|
13
|
-
etag:
|
14
|
-
- "\"24ec5-1b6-4059a80bfd280\""
|
15
|
-
last-modified:
|
16
|
-
- Tue, 15 Nov 2005 13:24:10 GMT
|
17
|
-
content-type:
|
18
|
-
- text/html; charset=UTF-8
|
19
|
-
connection:
|
20
|
-
- close
|
21
|
-
server:
|
22
|
-
- Apache/2.2.3 (CentOS)
|
23
|
-
date:
|
24
|
-
- Wed, 31 Mar 2010 02:43:26 GMT
|
25
|
-
content-length:
|
26
|
-
- "438"
|
27
|
-
accept-ranges:
|
28
|
-
- bytes
|
29
|
-
:body: example.com post response with id=7
|
30
|
-
:http_version: "1.1"
|
31
2
|
- !ruby/struct:VCR::HTTPInteraction
|
32
3
|
:request: !ruby/struct:VCR::Request
|
33
4
|
:method: :get
|
@@ -155,7 +155,7 @@
|
|
155
155
|
:uri: http://example.com:80/
|
156
156
|
:body:
|
157
157
|
:headers:
|
158
|
-
|
158
|
+
x-http-header1:
|
159
159
|
- val1
|
160
160
|
:response: !ruby/struct:VCR::Response
|
161
161
|
:status: !ruby/struct:VCR::ResponseStatus
|
@@ -172,7 +172,7 @@
|
|
172
172
|
:uri: http://example.com:80/
|
173
173
|
:body:
|
174
174
|
:headers:
|
175
|
-
|
175
|
+
x-http-header1:
|
176
176
|
- val2
|
177
177
|
:response: !ruby/struct:VCR::Response
|
178
178
|
:status: !ruby/struct:VCR::ResponseStatus
|
@@ -1,33 +1,4 @@
|
|
1
1
|
---
|
2
|
-
- !ruby/struct:VCR::HTTPInteraction
|
3
|
-
request: !ruby/struct:VCR::Request
|
4
|
-
method: :post
|
5
|
-
uri: http://example.com:80/
|
6
|
-
body:
|
7
|
-
headers:
|
8
|
-
response: !ruby/struct:VCR::Response
|
9
|
-
status: !ruby/struct:VCR::ResponseStatus
|
10
|
-
code: 200
|
11
|
-
message: OK
|
12
|
-
headers:
|
13
|
-
last-modified:
|
14
|
-
- Tue, 15 Nov 2005 13:24:10 GMT
|
15
|
-
connection:
|
16
|
-
- close
|
17
|
-
etag:
|
18
|
-
- "\"24ec5-1b6-4059a80bfd280\""
|
19
|
-
content-type:
|
20
|
-
- text/html; charset=UTF-8
|
21
|
-
date:
|
22
|
-
- Wed, 31 Mar 2010 02:43:26 GMT
|
23
|
-
server:
|
24
|
-
- Apache/2.2.3 (CentOS)
|
25
|
-
content-length:
|
26
|
-
- "438"
|
27
|
-
accept-ranges:
|
28
|
-
- bytes
|
29
|
-
body: example.com post response with id=7
|
30
|
-
http_version: "1.1"
|
31
2
|
- !ruby/struct:VCR::HTTPInteraction
|
32
3
|
request: !ruby/struct:VCR::Request
|
33
4
|
method: :get
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VCR::HttpStubbingAdapters::Faraday do
|
4
|
+
without_monkey_patches :all
|
5
|
+
|
6
|
+
it_behaves_like 'an http stubbing adapter',
|
7
|
+
%w[ faraday-typhoeus faraday-net_http faraday-patron ],
|
8
|
+
[:method, :uri, :host, :path, :body, :headers],
|
9
|
+
:status_message_not_exposed, :does_not_support_rotating_responses
|
10
|
+
|
11
|
+
it_performs('version checking',
|
12
|
+
:valid => %w[ 0.5.3 0.5.10 ],
|
13
|
+
:too_low => %w[ 0.5.2 0.4.99 ],
|
14
|
+
:too_high => %w[ 0.6.0 1.0.0 ]
|
15
|
+
) do
|
16
|
+
disable_warnings
|
17
|
+
before(:each) { @orig_version = Faraday::VERSION }
|
18
|
+
after(:each) { Faraday::VERSION = @orig_version }
|
19
|
+
|
20
|
+
# Cannot be regular method def as that raises a "dynamic constant assignment" error
|
21
|
+
define_method :stub_version do |version|
|
22
|
+
::Faraday::VERSION = version
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when some request have been stubbed' do
|
27
|
+
subject { described_class }
|
28
|
+
let(:request_1) { VCR::Request.new(:get, 'http://foo.com') }
|
29
|
+
let(:request_2) { VCR::Request.new(:get, 'http://bazz.com') }
|
30
|
+
let(:match_attributes) { [:method, :uri] }
|
31
|
+
|
32
|
+
def stubbed_response_for(request)
|
33
|
+
matcher = VCR::RequestMatcher.new(request, match_attributes)
|
34
|
+
subject.stubbed_response_for(matcher)
|
35
|
+
end
|
36
|
+
|
37
|
+
before(:each) do
|
38
|
+
subject.stub_requests(
|
39
|
+
[
|
40
|
+
VCR::HTTPInteraction.new(request_1, :response_1),
|
41
|
+
VCR::HTTPInteraction.new(request_1, :response_2),
|
42
|
+
], match_attributes
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_stubbed_responses
|
47
|
+
stubbed_response_for(request_1).should == :response_1
|
48
|
+
stubbed_response_for(request_1).should == :response_2
|
49
|
+
stubbed_response_for(request_1).should == :response_2
|
50
|
+
stubbed_response_for(request_1).should == :response_2
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '.stubbed_response_for' do
|
54
|
+
it 'returns nil when there is no matching response' do
|
55
|
+
stubbed_response_for(request_2).should be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'dequeues each response and continues to return the last one' do
|
59
|
+
test_stubbed_responses
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '.restore_stubs_checkpoints' do
|
64
|
+
before(:each) do
|
65
|
+
subject.create_stubs_checkpoint(:checkpoint_1)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'restores the queues to the checkpoint state when a queue has additional responses' do
|
69
|
+
subject.stub_requests( [
|
70
|
+
VCR::HTTPInteraction.new(request_1, :response_3),
|
71
|
+
], match_attributes)
|
72
|
+
|
73
|
+
subject.restore_stubs_checkpoint(:checkpoint_1)
|
74
|
+
test_stubbed_responses
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'restores the queues to the checkpoint state when a queue has been used' do
|
78
|
+
stubbed_response_for(request_1)
|
79
|
+
subject.restore_stubs_checkpoint(:checkpoint_1)
|
80
|
+
test_stubbed_responses
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VCR::Middleware::CassetteArguments do
|
4
|
+
describe '#name' do
|
5
|
+
it 'initially returns nil' do
|
6
|
+
subject.name.should be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'stores the given value, returning it when no arg is given' do
|
10
|
+
subject.name :value1
|
11
|
+
subject.name.should == :value1
|
12
|
+
|
13
|
+
subject.name :value2
|
14
|
+
subject.name.should == :value2
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#options' do
|
19
|
+
it 'initially returns an empty hash' do
|
20
|
+
subject.options.should == {}
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'merges the given hash options, returning them when no arg is given' do
|
24
|
+
subject.options :record => :new_episodes
|
25
|
+
subject.options.should == { :record => :new_episodes }
|
26
|
+
|
27
|
+
subject.options :erb => true
|
28
|
+
subject.options.should == { :record => :new_episodes, :erb => true }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VCR::Middleware::Faraday do
|
4
|
+
describe '.new' do
|
5
|
+
it 'raises an error if no cassette arguments block is provided' do
|
6
|
+
expect {
|
7
|
+
described_class.new(lambda { |env| })
|
8
|
+
}.to raise_error(ArgumentError)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#call' do
|
13
|
+
let(:env_hash) { { :url => 'http://localhost:3000/' } }
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
VCR::HttpStubbingAdapters::Faraday.ignore_localhost = true
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'uses a cassette when the app is called' do
|
20
|
+
VCR.current_cassette.should be_nil
|
21
|
+
app = lambda { |env| VCR.current_cassette.should_not be_nil }
|
22
|
+
instance = described_class.new(app) { |c| c.name 'cassette_name' }
|
23
|
+
instance.call(env_hash)
|
24
|
+
VCR.current_cassette.should be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'sets the cassette name based on the provided block' do
|
28
|
+
app = lambda { |env| VCR.current_cassette.name.should == 'rack_cassette' }
|
29
|
+
instance = described_class.new(app) { |c| c.name 'rack_cassette' }
|
30
|
+
instance.call(env_hash)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'sets the cassette options based on the provided block' do
|
34
|
+
app = lambda { |env| VCR.current_cassette.erb.should == { :foo => :bar } }
|
35
|
+
instance = described_class.new(app) do |c|
|
36
|
+
c.name 'c'
|
37
|
+
c.options :erb => { :foo => :bar }
|
38
|
+
end
|
39
|
+
|
40
|
+
instance.call(env_hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'yields the env to the provided block when the block accepts 2 arguments' do
|
44
|
+
instance = described_class.new(lambda { |env| }) do |c, env|
|
45
|
+
env.should == env_hash
|
46
|
+
c.name 'c'
|
47
|
+
end
|
48
|
+
|
49
|
+
instance.call(env_hash)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VCR::Middleware::Rack do
|
4
|
+
describe '.new' do
|
5
|
+
it 'raises an error if no cassette arguments block is provided' do
|
6
|
+
expect {
|
7
|
+
described_class.new(lambda { |env| })
|
8
|
+
}.to raise_error(ArgumentError)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#call' do
|
13
|
+
let(:env_hash) { { :env => :hash } }
|
14
|
+
it 'calls the provided rack app and returns its response' do
|
15
|
+
rack_app = mock
|
16
|
+
rack_app.should_receive(:call).with(env_hash).and_return(:response)
|
17
|
+
instance = described_class.new(rack_app) { |c| c.name 'cassette_name' }
|
18
|
+
instance.call(env_hash).should == :response
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'uses a cassette when the rack app is called' do
|
22
|
+
VCR.current_cassette.should be_nil
|
23
|
+
rack_app = lambda { |env| VCR.current_cassette.should_not be_nil }
|
24
|
+
instance = described_class.new(rack_app) { |c| c.name 'cassette_name' }
|
25
|
+
instance.call({})
|
26
|
+
VCR.current_cassette.should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets the cassette name based on the provided block' do
|
30
|
+
rack_app = lambda { |env| VCR.current_cassette.name.should == 'rack_cassette' }
|
31
|
+
instance = described_class.new(rack_app) { |c| c.name 'rack_cassette' }
|
32
|
+
instance.call({})
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'sets the cassette options based on the provided block' do
|
36
|
+
rack_app = lambda { |env| VCR.current_cassette.erb.should == { :foo => :bar } }
|
37
|
+
instance = described_class.new(rack_app) do |c|
|
38
|
+
c.name 'c'
|
39
|
+
c.options :erb => { :foo => :bar }
|
40
|
+
end
|
41
|
+
|
42
|
+
instance.call({})
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'yields the rack env to the provided block when the block accepts 2 arguments' do
|
46
|
+
instance = described_class.new(lambda { |env| }) do |c, env|
|
47
|
+
env.should == env_hash
|
48
|
+
c.name 'c'
|
49
|
+
end
|
50
|
+
|
51
|
+
instance.call(env_hash)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/monkey_patches.rb
CHANGED
@@ -145,6 +145,10 @@ describe VCR::RequestMatcher do
|
|
145
145
|
return matcher, matcher(attribute)
|
146
146
|
end
|
147
147
|
|
148
|
+
def matcher_with_headers(headers)
|
149
|
+
VCR::RequestMatcher.new(VCR::Request.new(:get, 'http://foo.com/', nil, headers), [:method, :uri, :headers])
|
150
|
+
end
|
151
|
+
|
148
152
|
describe '#hash' do
|
149
153
|
it 'returns the same code for two objects when #match_attributes, #method, #uri, #body and #headers are the same, even when the request object is different' do
|
150
154
|
m1, m2 = matchers_varying_on(:request)
|
@@ -164,6 +168,38 @@ describe VCR::RequestMatcher do
|
|
164
168
|
m1.hash.should_not == m2.hash
|
165
169
|
end
|
166
170
|
end
|
171
|
+
|
172
|
+
context 'for headers' do
|
173
|
+
it 'returns the same code for the same headers' do
|
174
|
+
m1 = matcher_with_headers('x-http-header' => ['val1'])
|
175
|
+
m2 = matcher_with_headers('x-http-header' => ['val1'])
|
176
|
+
m1.hash.should == m2.hash
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'returns the same code when the header keys are ordered differently' do
|
180
|
+
m1 = matcher_with_headers('x-http-header1' => ['val1'], 'x-http-header2' => ['val2'])
|
181
|
+
m2 = matcher_with_headers('x-http-header2' => ['val2'], 'x-http-header1' => ['val1'])
|
182
|
+
m1.hash.should == m2.hash
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'returns the same code when the header value arrays are ordered differently' do
|
186
|
+
m1 = matcher_with_headers('x-http-header' => ['val1', 'val2'])
|
187
|
+
m2 = matcher_with_headers('x-http-header' => ['val2', 'val1'])
|
188
|
+
m1.hash.should == m2.hash
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'returns a different code when the header values are different' do
|
192
|
+
m1 = matcher_with_headers('x-http-header' => ['val1'])
|
193
|
+
m2 = matcher_with_headers('x-http-header' => ['val2'])
|
194
|
+
m1.hash.should_not == m2.hash
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'returns a different code when the header keys are different' do
|
198
|
+
m1 = matcher_with_headers('x-http-header1' => ['val1'])
|
199
|
+
m2 = matcher_with_headers('x-http-header2' => ['val1'])
|
200
|
+
m1.hash.should_not == m2.hash
|
201
|
+
end
|
202
|
+
end
|
167
203
|
end
|
168
204
|
|
169
205
|
[:eql?, :==].each do |equality_method|
|
data/spec/spec_helper.rb
CHANGED
@@ -24,6 +24,9 @@ RSpec.configure do |config|
|
|
24
24
|
config.debug = RUBY_INTERPRETER == :mri
|
25
25
|
|
26
26
|
config.before(:each) do
|
27
|
+
VCR.turn_on! unless VCR.turned_on?
|
28
|
+
VCR.eject_cassette while VCR.current_cassette
|
29
|
+
|
27
30
|
VCR::Config.default_cassette_options = { :record => :new_episodes }
|
28
31
|
VCR::Config.stub_with :fakeweb
|
29
32
|
|
@@ -32,6 +35,8 @@ RSpec.configure do |config|
|
|
32
35
|
|
33
36
|
FakeWeb.allow_net_connect = true
|
34
37
|
FakeWeb.clean_registry
|
38
|
+
|
39
|
+
VCR::HttpStubbingAdapters::Faraday.reset!
|
35
40
|
end
|
36
41
|
|
37
42
|
config.filter_run :focus => true
|
@@ -40,3 +45,8 @@ RSpec.configure do |config|
|
|
40
45
|
config.alias_it_should_behave_like_to :it_performs, 'it performs'
|
41
46
|
end
|
42
47
|
|
48
|
+
http_stubbing_dir = File.join(File.dirname(__FILE__), '..', 'lib', 'vcr', 'http_stubbing_adapters')
|
49
|
+
Dir[File.join(http_stubbing_dir, '*.rb')].each do |file|
|
50
|
+
next if RUBY_INTERPRETER != :mri && file =~ /(typhoeus)/
|
51
|
+
require "vcr/http_stubbing_adapters/#{File.basename(file)}"
|
52
|
+
end
|
@@ -112,12 +112,68 @@ HTTP_LIBRARY_ADAPTERS['typhoeus'] = Module.new do
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
+
%w[ net_http typhoeus patron ].each do |_faraday_adapter|
|
116
|
+
HTTP_LIBRARY_ADAPTERS["faraday-#{_faraday_adapter}"] = Module.new do
|
117
|
+
class << self; self; end.class_eval do
|
118
|
+
define_method(:http_library_name) do
|
119
|
+
"Faraday (#{_faraday_adapter})"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
define_method(:faraday_adapter) { _faraday_adapter.to_sym }
|
124
|
+
|
125
|
+
def get_body_string(response)
|
126
|
+
response.body
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_header(header_key, response)
|
130
|
+
response.headers[header_key]
|
131
|
+
end
|
132
|
+
|
133
|
+
def make_http_request(method, url, body = nil, headers = {})
|
134
|
+
url_root, url_rest = split_url(url)
|
135
|
+
|
136
|
+
faraday_connection(url_root).send(method) do |req|
|
137
|
+
req.url url_rest
|
138
|
+
headers.each { |k, v| req[k] = v }
|
139
|
+
req.body = body if body
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def split_url(url)
|
144
|
+
uri = URI.parse(url)
|
145
|
+
url_root = "#{uri.scheme}://#{uri.host}:#{uri.port}"
|
146
|
+
rest = url.sub(url_root, '')
|
147
|
+
|
148
|
+
[url_root, rest]
|
149
|
+
end
|
150
|
+
|
151
|
+
def faraday_connection(url_root)
|
152
|
+
Faraday::Connection.new(:url => url_root) do |builder|
|
153
|
+
builder.use VCR::Middleware::Faraday do |cassette|
|
154
|
+
cassette.name 'faraday_example'
|
155
|
+
|
156
|
+
if respond_to?(:match_requests_on)
|
157
|
+
cassette.options :match_requests_on => match_requests_on
|
158
|
+
end
|
159
|
+
|
160
|
+
if respond_to?(:record_mode)
|
161
|
+
cassette.options :record => record_mode
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
builder.adapter faraday_adapter
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
115
171
|
NET_CONNECT_NOT_ALLOWED_ERROR = /You can use VCR to automatically record this request and replay it later/
|
116
172
|
|
117
173
|
module HttpLibrarySpecs
|
118
174
|
def test_http_library(library, supported_request_match_attributes, *other)
|
119
|
-
#
|
120
|
-
return if
|
175
|
+
# skip libs that only work on MRI
|
176
|
+
return if RUBY_INTERPRETER != :mri && library =~ /(typhoeus|curb|patron|em-http)/
|
121
177
|
|
122
178
|
unless adapter_module = HTTP_LIBRARY_ADAPTERS[library]
|
123
179
|
raise ArgumentError.new("No http library adapter module could be found for #{library}")
|
@@ -139,7 +195,9 @@ module HttpLibrarySpecs
|
|
139
195
|
supported_request_match_attributes = @supported_request_match_attributes
|
140
196
|
|
141
197
|
describe ":#{attribute}" do
|
142
|
-
let(:perform_stubbing) { subject.stub_requests(interactions,
|
198
|
+
let(:perform_stubbing) { subject.stub_requests(interactions, match_requests_on) }
|
199
|
+
let(:match_requests_on) { [attribute] }
|
200
|
+
let(:record_mode) { :none }
|
143
201
|
|
144
202
|
if supported_request_match_attributes.include?(attribute)
|
145
203
|
before(:each) { perform_stubbing }
|
@@ -199,7 +257,7 @@ module HttpLibrarySpecs
|
|
199
257
|
end
|
200
258
|
end
|
201
259
|
|
202
|
-
def self.test_real_http_request(http_allowed)
|
260
|
+
def self.test_real_http_request(http_allowed, *other)
|
203
261
|
let(:url) { "http://localhost:#{VCR::SinatraApp.port}/foo" }
|
204
262
|
|
205
263
|
if http_allowed
|
@@ -208,20 +266,55 @@ module HttpLibrarySpecs
|
|
208
266
|
get_body_string(make_http_request(:get, url)).should == 'FOO!'
|
209
267
|
end
|
210
268
|
|
211
|
-
|
212
|
-
|
213
|
-
interaction
|
214
|
-
|
215
|
-
|
216
|
-
interaction
|
217
|
-
interaction.response.body.should == 'FOO!'
|
218
|
-
interaction.response.headers['content-type'].should == ["text/html;charset=utf-8"]
|
269
|
+
describe 'recording new http requests' do
|
270
|
+
let(:recorded_interaction) do
|
271
|
+
interaction = nil
|
272
|
+
VCR.should_receive(:record_http_interaction) { |i| interaction = i }
|
273
|
+
make_http_request(:get, url)
|
274
|
+
interaction
|
219
275
|
end
|
220
276
|
|
221
|
-
|
222
|
-
|
277
|
+
it 'does not record the request if the adapter is disabled' do
|
278
|
+
subject.stub(:enabled?).and_return(false)
|
279
|
+
VCR.should_not_receive(:record_http_interaction)
|
280
|
+
make_http_request(:get, url)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'records the request uri' do
|
284
|
+
recorded_interaction.request.uri.should == url
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'records the request method' do
|
288
|
+
recorded_interaction.request.method.should == :get
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'records the request body' do
|
292
|
+
recorded_interaction.request.body.should be_nil
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'records the request headers' do
|
296
|
+
recorded_interaction.request.headers.should be_nil
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'records the response status code' do
|
300
|
+
recorded_interaction.response.status.code.should == 200
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'records the response status message' do
|
304
|
+
recorded_interaction.response.status.message.should == 'OK'
|
305
|
+
end unless other.include?(:status_message_not_exposed)
|
306
|
+
|
307
|
+
it 'records the response body' do
|
308
|
+
recorded_interaction.response.body.should == 'FOO!'
|
309
|
+
end
|
223
310
|
|
311
|
+
it 'records the response headers' do
|
312
|
+
recorded_interaction.response.headers['content-type'].should == ["text/html;charset=utf-8"]
|
313
|
+
end
|
314
|
+
end
|
224
315
|
else
|
316
|
+
let(:record_mode) { :none }
|
317
|
+
|
225
318
|
it 'does not allow real HTTP requests or record them' do
|
226
319
|
VCR.should_receive(:record_http_interaction).never
|
227
320
|
expect { make_http_request(:get, url) }.to raise_error(NET_CONNECT_NOT_ALLOWED_ERROR)
|
@@ -246,11 +339,12 @@ module HttpLibrarySpecs
|
|
246
339
|
subject.http_connections_allowed?.should == http_allowed
|
247
340
|
end
|
248
341
|
|
249
|
-
test_real_http_request(http_allowed)
|
342
|
+
test_real_http_request(http_allowed, *other)
|
250
343
|
|
251
344
|
unless http_allowed
|
252
345
|
describe '.ignore_localhost =' do
|
253
346
|
localhost_response = "Localhost response"
|
347
|
+
let(:record_mode) { :none }
|
254
348
|
|
255
349
|
VCR::LOCALHOST_ALIASES.each do |localhost_alias|
|
256
350
|
describe 'when set to true' do
|
@@ -291,15 +385,9 @@ module HttpLibrarySpecs
|
|
291
385
|
end
|
292
386
|
end
|
293
387
|
|
294
|
-
it 'gets the stubbed responses when multiple post requests are made to http://example.com, and does not record them' do
|
295
|
-
VCR.should_receive(:record_http_interaction).never
|
296
|
-
get_body_string(make_http_request(:post, 'http://example.com/', { 'id' => '7' })).should == 'example.com post response with id=7'
|
297
|
-
get_body_string(make_http_request(:post, 'http://example.com/', { 'id' => '3' })).should == 'example.com post response with id=3'
|
298
|
-
end
|
299
|
-
|
300
388
|
it 'gets the stubbed responses when requests are made to http://example.com/foo, and does not record them' do
|
301
389
|
VCR.should_receive(:record_http_interaction).never
|
302
|
-
get_body_string(make_http_request(:get, 'http://example.com/foo')).should
|
390
|
+
get_body_string(make_http_request(:get, 'http://example.com/foo')).should =~ /example\.com get response \d with path=foo/
|
303
391
|
end
|
304
392
|
|
305
393
|
it 'rotates through multiple responses for the same request' do
|
@@ -309,16 +397,16 @@ module HttpLibrarySpecs
|
|
309
397
|
# subsequent requests keep getting the last one
|
310
398
|
get_body_string(make_http_request(:get, 'http://example.com/foo')).should == 'example.com get response 2 with path=foo'
|
311
399
|
get_body_string(make_http_request(:get, 'http://example.com/foo')).should == 'example.com get response 2 with path=foo'
|
312
|
-
end
|
400
|
+
end unless other.include?(:does_not_support_rotating_responses)
|
313
401
|
|
314
402
|
it "correctly handles stubbing multiple values for the same header" do
|
315
|
-
|
403
|
+
get_header('Set-Cookie', make_http_request(:get, 'http://example.com/two_set_cookie_headers')).should =~ ['bar=bazz', 'foo=bar']
|
316
404
|
end
|
317
405
|
|
318
406
|
context 'when we restore our previous check point' do
|
319
407
|
before(:each) { subject.restore_stubs_checkpoint(:my_checkpoint) }
|
320
408
|
|
321
|
-
test_real_http_request(http_allowed)
|
409
|
+
test_real_http_request(http_allowed, *other)
|
322
410
|
|
323
411
|
if other.include?(:needs_net_http_extension)
|
324
412
|
it 'returns false from #request_stubbed?' do
|