vcr 3.0.3 → 6.2.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 +5 -5
- data/lib/vcr/cassette/erb_renderer.rb +4 -2
- data/lib/vcr/cassette/http_interaction_list.rb +14 -9
- data/lib/vcr/cassette/migrator.rb +5 -6
- data/lib/vcr/cassette/persisters/file_system.rb +9 -1
- data/lib/vcr/cassette/serializers/compressed.rb +2 -2
- data/lib/vcr/cassette/serializers/json.rb +14 -8
- data/lib/vcr/cassette/serializers/psych.rb +10 -2
- data/lib/vcr/cassette/serializers/syck.rb +7 -1
- data/lib/vcr/cassette/serializers/yaml.rb +14 -2
- data/lib/vcr/cassette/serializers.rb +10 -0
- data/lib/vcr/cassette.rb +63 -16
- data/lib/vcr/configuration.rb +21 -8
- data/lib/vcr/deprecations.rb +0 -62
- data/lib/vcr/errors.rb +17 -12
- data/lib/vcr/library_hooks/excon.rb +8 -0
- data/lib/vcr/library_hooks/typhoeus.rb +91 -79
- data/lib/vcr/library_hooks/webmock.rb +2 -11
- data/lib/vcr/linked_cassette.rb +4 -4
- data/lib/vcr/middleware/excon.rb +1 -1
- data/lib/vcr/middleware/faraday.rb +29 -2
- data/lib/vcr/request_ignorer.rb +8 -1
- data/lib/vcr/request_matcher_registry.rb +3 -3
- data/lib/vcr/structs.rb +48 -32
- data/lib/vcr/test_frameworks/cucumber.rb +16 -5
- data/lib/vcr/test_frameworks/rspec.rb +34 -22
- data/lib/vcr/util/hooks.rb +1 -0
- data/lib/vcr/util/internet_connection.rb +15 -21
- data/lib/vcr/version.rb +2 -2
- data/lib/vcr.rb +52 -2
- metadata +45 -272
- 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/lib/vcr/library_hooks/typhoeus_0.4.rb +0 -103
- 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,618 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe VCR::Cassette do
|
|
4
|
-
def http_interaction
|
|
5
|
-
request = VCR::Request.new(:get)
|
|
6
|
-
response = VCR::Response.new
|
|
7
|
-
response.status = VCR::ResponseStatus.new
|
|
8
|
-
VCR::HTTPInteraction.new(request, response).tap { |i| yield i if block_given? }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def stub_old_interactions(interactions)
|
|
12
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
13
|
-
|
|
14
|
-
hashes = interactions.map(&:to_hash)
|
|
15
|
-
allow(VCR.cassette_serializers[:yaml]).to receive(:deserialize).and_return({ 'http_interactions' => hashes })
|
|
16
|
-
allow(VCR::HTTPInteraction).to receive(:from_hash) do |hash|
|
|
17
|
-
interactions[hashes.index(hash)]
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe '#file' do
|
|
22
|
-
it 'delegates the file resolution to the FileSystem persister' do
|
|
23
|
-
fs = VCR::Cassette::Persisters::FileSystem
|
|
24
|
-
expect(fs).to respond_to(:absolute_path_to_file).with(1).argument
|
|
25
|
-
expect(fs).to receive(:absolute_path_to_file).with("cassette name.yml") { "f.yml" }
|
|
26
|
-
expect(VCR::Cassette.new("cassette name").file).to eq("f.yml")
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it 'raises a NotImplementedError when a different persister is used' do
|
|
30
|
-
VCR.cassette_persisters[:a] = double
|
|
31
|
-
cassette = VCR::Cassette.new("f", :persist_with => :a)
|
|
32
|
-
expect { cassette.file }.to raise_error(NotImplementedError)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe '#tags' do
|
|
37
|
-
it 'returns a blank array if no tag has been set' do
|
|
38
|
-
expect(VCR::Cassette.new("name").tags).to eq([])
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'converts a single :tag to an array' do
|
|
42
|
-
expect(VCR::Cassette.new("name", :tag => :foo).tags).to eq([:foo])
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it 'accepts an array as the :tags option' do
|
|
46
|
-
expect(VCR::Cassette.new("name", :tags => [:foo]).tags).to eq([:foo])
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
describe '#record_http_interaction' do
|
|
51
|
-
let(:the_interaction) { double(:request => double(:method => :get).as_null_object).as_null_object }
|
|
52
|
-
|
|
53
|
-
it 'adds the interaction to #new_recorded_interactions' do
|
|
54
|
-
cassette = VCR::Cassette.new(:test_cassette)
|
|
55
|
-
expect(cassette.new_recorded_interactions).to eq([])
|
|
56
|
-
cassette.record_http_interaction(the_interaction)
|
|
57
|
-
expect(cassette.new_recorded_interactions).to eq([the_interaction])
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
describe "#serializable_hash" do
|
|
62
|
-
subject { VCR::Cassette.new("foo") }
|
|
63
|
-
let(:interaction_1) { http_interaction { |i| i.request.body = 'req body 1'; i.response.body = 'res body 1' } }
|
|
64
|
-
let(:interaction_2) { http_interaction { |i| i.request.body = 'req body 2'; i.response.body = 'res body 2' } }
|
|
65
|
-
let(:interactions) { [interaction_1, interaction_2] }
|
|
66
|
-
|
|
67
|
-
before(:each) do
|
|
68
|
-
interactions.each do |i|
|
|
69
|
-
subject.record_http_interaction(i)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
let(:metadata) { subject.serializable_hash.reject { |k,v| k == "http_interactions" } }
|
|
74
|
-
|
|
75
|
-
it 'includes the hash form of all recorded interactions' do
|
|
76
|
-
hash_1 = interaction_1.to_hash
|
|
77
|
-
hash_2 = interaction_2.to_hash
|
|
78
|
-
expect(subject.serializable_hash).to include('http_interactions' => [hash_1, hash_2])
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
it 'includes additional metadata about the cassette' do
|
|
82
|
-
expect(metadata).to eq("recorded_with" => "VCR #{VCR.version}")
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it 'does not allow the interactions to be mutated by configured hooks' do
|
|
86
|
-
VCR.configure do |c|
|
|
87
|
-
c.define_cassette_placeholder('<BODY>') { 'body' }
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
expect {
|
|
91
|
-
subject.serializable_hash
|
|
92
|
-
}.not_to change { interaction_1.response.body }
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
describe "#recording?" do
|
|
97
|
-
[:all, :new_episodes].each do |mode|
|
|
98
|
-
it "returns true when the record mode is :#{mode}" do
|
|
99
|
-
cassette = VCR::Cassette.new("foo", :record => mode)
|
|
100
|
-
expect(cassette).to be_recording
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
it "returns false when the record mode is :none" do
|
|
105
|
-
cassette = VCR::Cassette.new("foo", :record => :none)
|
|
106
|
-
expect(cassette).not_to be_recording
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
context 'when the record mode is :once' do
|
|
110
|
-
before(:each) do
|
|
111
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
it 'returns false when there is an existing cassette file with content' do
|
|
115
|
-
cassette = VCR::Cassette.new("example", :record => :once)
|
|
116
|
-
expect(::File).to exist(cassette.file)
|
|
117
|
-
expect(::File.size?(cassette.file)).to be_truthy
|
|
118
|
-
expect(cassette).not_to be_recording
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
it 'returns true when there is an empty existing cassette file' do
|
|
122
|
-
cassette = VCR::Cassette.new("empty", :record => :once)
|
|
123
|
-
expect(::File).to exist(cassette.file)
|
|
124
|
-
expect(::File.size?(cassette.file)).to be_falsey
|
|
125
|
-
expect(cassette).to be_recording
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
it 'returns true when there is no existing cassette file' do
|
|
129
|
-
cassette = VCR::Cassette.new("non_existant_file", :record => :once)
|
|
130
|
-
expect(::File).not_to exist(cassette.file)
|
|
131
|
-
expect(cassette).to be_recording
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
describe '#match_requests_on' do
|
|
137
|
-
before(:each) { VCR.configuration.default_cassette_options.merge!(:match_requests_on => [:uri, :method]) }
|
|
138
|
-
|
|
139
|
-
it "returns the provided options" do
|
|
140
|
-
c = VCR::Cassette.new('example', :match_requests_on => [:uri])
|
|
141
|
-
expect(c.match_requests_on).to eq([:uri])
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "returns a the default #match_requests_on when it has not been specified for the cassette" do
|
|
145
|
-
c = VCR::Cassette.new('example')
|
|
146
|
-
expect(c.match_requests_on).to eq([:uri, :method])
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
describe "reading the file from disk" do
|
|
151
|
-
let(:empty_cassette_yaml) { YAML.dump("http_interactions" => []) }
|
|
152
|
-
|
|
153
|
-
it 'optionally renders the file as ERB using the ERBRenderer' do
|
|
154
|
-
allow(VCR::Cassette::Persisters::FileSystem).to receive(:[]).and_return(empty_cassette_yaml)
|
|
155
|
-
|
|
156
|
-
expect(VCR::Cassette::ERBRenderer).to receive(:new).with(
|
|
157
|
-
empty_cassette_yaml, anything, "foo"
|
|
158
|
-
).and_return(double('renderer', :render => empty_cassette_yaml))
|
|
159
|
-
|
|
160
|
-
VCR::Cassette.new('foo', :record => :new_episodes).http_interactions
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
[true, false, nil, { }].each do |erb|
|
|
164
|
-
it "passes #{erb.inspect} to the VCR::Cassette::ERBRenderer when given as the :erb option" do
|
|
165
|
-
# test that it overrides the default
|
|
166
|
-
VCR.configuration.default_cassette_options = { :erb => true }
|
|
167
|
-
|
|
168
|
-
expect(VCR::Cassette::ERBRenderer).to receive(:new).with(
|
|
169
|
-
anything, erb, anything
|
|
170
|
-
).and_return(double('renderer', :render => empty_cassette_yaml))
|
|
171
|
-
|
|
172
|
-
VCR::Cassette.new('foo', :record => :new_episodes, :erb => erb).http_interactions
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
it "passes #{erb.inspect} to the VCR::Cassette::ERBRenderer when it is the default :erb option and none is given" do
|
|
176
|
-
VCR.configuration.default_cassette_options = { :erb => erb }
|
|
177
|
-
|
|
178
|
-
expect(VCR::Cassette::ERBRenderer).to receive(:new).with(
|
|
179
|
-
anything, erb, anything
|
|
180
|
-
).and_return(double('renderer', :render => empty_cassette_yaml))
|
|
181
|
-
|
|
182
|
-
VCR::Cassette.new('foo', :record => :new_episodes).http_interactions
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
it 'raises a friendly error when the cassette file is in the old VCR 1.x format' do
|
|
187
|
-
VCR.configuration.cassette_library_dir = 'spec/fixtures/cassette_spec'
|
|
188
|
-
expect {
|
|
189
|
-
VCR::Cassette.new('1_x_cassette').http_interactions
|
|
190
|
-
}.to raise_error(VCR::Errors::InvalidCassetteFormatError)
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
describe '.new' do
|
|
195
|
-
it "raises an error if given an invalid record mode" do
|
|
196
|
-
expect { VCR::Cassette.new(:test, :record => :not_a_record_mode) }.to raise_error(ArgumentError)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
it 'raises an error if given invalid options' do
|
|
200
|
-
expect {
|
|
201
|
-
VCR::Cassette.new(:test, :invalid => :option)
|
|
202
|
-
}.to raise_error(ArgumentError)
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
it 'does not raise an error in the case of an empty file' do
|
|
206
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
207
|
-
expect(VCR::Cassette.new('empty', :record => :none).send(:previously_recorded_interactions)).to eq([])
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
let(:custom_persister) { double("custom persister") }
|
|
211
|
-
|
|
212
|
-
it 'reads from the configured persister' do
|
|
213
|
-
VCR.configuration.cassette_library_dir = nil
|
|
214
|
-
VCR.cassette_persisters[:foo] = custom_persister
|
|
215
|
-
expect(custom_persister).to receive(:[]).with("abc.yml") { "" }
|
|
216
|
-
VCR::Cassette.new("abc", :persist_with => :foo).http_interactions
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
VCR::Cassette::VALID_RECORD_MODES.each do |record_mode|
|
|
220
|
-
stub_requests = (record_mode != :all)
|
|
221
|
-
|
|
222
|
-
context "when VCR.configuration.default_cassette_options[:record] is :#{record_mode}" do
|
|
223
|
-
before(:each) { VCR.configuration.default_cassette_options = { :record => record_mode } }
|
|
224
|
-
|
|
225
|
-
it "defaults the record mode to #{record_mode} when VCR.configuration.default_cassette_options[:record] is #{record_mode}" do
|
|
226
|
-
cassette = VCR::Cassette.new(:test)
|
|
227
|
-
expect(cassette.record_mode).to eq(record_mode)
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
context "when :#{record_mode} is passed as the record option" do
|
|
232
|
-
unless record_mode == :all
|
|
233
|
-
let(:interaction_1) { http_interaction { |i| i.request.uri = 'http://example.com/foo' } }
|
|
234
|
-
let(:interaction_2) { http_interaction { |i| i.request.uri = 'http://example.com/bar' } }
|
|
235
|
-
let(:interactions) { [interaction_1, interaction_2] }
|
|
236
|
-
|
|
237
|
-
it 'updates the content_length headers when given :update_content_length_header => true' do
|
|
238
|
-
stub_old_interactions(interactions)
|
|
239
|
-
expect(interaction_1.response).to receive(:update_content_length_header)
|
|
240
|
-
expect(interaction_2.response).to receive(:update_content_length_header)
|
|
241
|
-
|
|
242
|
-
VCR::Cassette.new('example', :record => record_mode, :update_content_length_header => true).http_interactions
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
[nil, false].each do |val|
|
|
246
|
-
it "does not update the content_lenth headers when given :update_content_length_header => #{val.inspect}" do
|
|
247
|
-
stub_old_interactions(interactions)
|
|
248
|
-
expect(interaction_1.response).not_to receive(:update_content_length_header)
|
|
249
|
-
expect(interaction_2.response).not_to receive(:update_content_length_header)
|
|
250
|
-
|
|
251
|
-
VCR::Cassette.new('example', :record => record_mode, :update_content_length_header => val).http_interactions
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
context "and re_record_interval is 7.days" do
|
|
256
|
-
let(:file_name) { ::File.join(VCR.configuration.cassette_library_dir, "cassette_name.yml") }
|
|
257
|
-
subject { VCR::Cassette.new(::File.basename(file_name).gsub('.yml', ''), :record => record_mode, :re_record_interval => 7.days) }
|
|
258
|
-
|
|
259
|
-
context 'when the cassette file does not exist' do
|
|
260
|
-
before(:each) { allow(::File).to receive(:exist?).with(file_name).and_return(false) }
|
|
261
|
-
|
|
262
|
-
it "has :#{record_mode} for the record mode" do
|
|
263
|
-
expect(subject.record_mode).to eq(record_mode)
|
|
264
|
-
end
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
context 'when the cassette file does exist' do
|
|
268
|
-
before(:each) do
|
|
269
|
-
interactions = timestamps.map do |ts|
|
|
270
|
-
http_interaction { |i| i.recorded_at = ts }.to_hash
|
|
271
|
-
end
|
|
272
|
-
yaml = YAML.dump("http_interactions" => interactions)
|
|
273
|
-
|
|
274
|
-
allow(::File).to receive(:exist?).with(file_name).and_return(true)
|
|
275
|
-
allow(::File).to receive(:size?).with(file_name).and_return(true)
|
|
276
|
-
allow(::File).to receive(:binread).with(file_name).and_return(yaml)
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
context 'and the earliest recorded interaction was recorded less than 7 days ago' do
|
|
280
|
-
let(:timestamps) do [
|
|
281
|
-
Time.now - 6.days + 60,
|
|
282
|
-
Time.now - 7.days + 60,
|
|
283
|
-
Time.now - 5.days + 60
|
|
284
|
-
] end
|
|
285
|
-
|
|
286
|
-
it "has :#{record_mode} for the record mode" do
|
|
287
|
-
expect(subject.record_mode).to eq(record_mode)
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
context 'and the earliest recorded interaction was recorded more than 7 days ago' do
|
|
292
|
-
let(:timestamps) do [
|
|
293
|
-
Time.now - 6.days - 60,
|
|
294
|
-
Time.now - 7.days - 60,
|
|
295
|
-
Time.now - 5.days - 60
|
|
296
|
-
] end
|
|
297
|
-
|
|
298
|
-
it "has :all for the record mode when there is an internet connection available" do
|
|
299
|
-
allow(VCR::InternetConnection).to receive(:available?).and_return(true)
|
|
300
|
-
expect(subject.record_mode).to eq(:all)
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
it "has :#{record_mode} for the record mode when there is no internet connection available" do
|
|
304
|
-
allow(VCR::InternetConnection).to receive(:available?).and_return(false)
|
|
305
|
-
expect(subject.record_mode).to eq(record_mode)
|
|
306
|
-
end
|
|
307
|
-
end
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
end
|
|
311
|
-
|
|
312
|
-
it 'does not load ignored interactions' do
|
|
313
|
-
allow(VCR.request_ignorer).to receive(:ignore?) do |request|
|
|
314
|
-
request.uri !~ /example\.com/
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
318
|
-
cassette = VCR::Cassette.new('with_localhost_requests', :record => record_mode)
|
|
319
|
-
expect(cassette.send(:previously_recorded_interactions).map { |i| URI.parse(i.request.uri).host }).to eq(%w[example.com])
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
it "loads the recorded interactions from the library yml file" do
|
|
323
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
324
|
-
cassette = VCR::Cassette.new('example', :record => record_mode)
|
|
325
|
-
|
|
326
|
-
expect(cassette.send(:previously_recorded_interactions).size).to eq(3)
|
|
327
|
-
|
|
328
|
-
i1, i2, i3 = *cassette.send(:previously_recorded_interactions)
|
|
329
|
-
|
|
330
|
-
expect(i1.request.method).to eq(:get)
|
|
331
|
-
expect(i1.request.uri).to eq('http://example.com/')
|
|
332
|
-
expect(i1.response.body).to match(/You have reached this web page by typing.+example\.com/)
|
|
333
|
-
|
|
334
|
-
expect(i2.request.method).to eq(:get)
|
|
335
|
-
expect(i2.request.uri).to eq('http://example.com/foo')
|
|
336
|
-
expect(i2.response.body).to match(/foo was not found on this server/)
|
|
337
|
-
|
|
338
|
-
expect(i3.request.method).to eq(:get)
|
|
339
|
-
expect(i3.request.uri).to eq('http://example.com/')
|
|
340
|
-
expect(i3.response.body).to match(/Another example\.com response/)
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
[true, false].each do |value|
|
|
344
|
-
it "instantiates the http_interactions with allow_playback_repeats = #{value} if given :allow_playback_repeats => #{value}" do
|
|
345
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
346
|
-
cassette = VCR::Cassette.new('example', :record => record_mode, :allow_playback_repeats => value)
|
|
347
|
-
expect(cassette.http_interactions.allow_playback_repeats).to eq(value)
|
|
348
|
-
end
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
it "instantiates the http_interactions with parent_list set to a null list if given :exclusive => true" do
|
|
352
|
-
allow(VCR).to receive(:http_interactions).and_return(double)
|
|
353
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
354
|
-
cassette = VCR::Cassette.new('example', :record => record_mode, :exclusive => true)
|
|
355
|
-
expect(cassette.http_interactions.parent_list).to be(VCR::Cassette::HTTPInteractionList::NullList)
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
it "instantiates the http_interactions with parent_list set to VCR.http_interactions if given :exclusive => false" do
|
|
359
|
-
allow(VCR).to receive(:http_interactions).and_return(double)
|
|
360
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
361
|
-
cassette = VCR::Cassette.new('example', :record => record_mode, :exclusive => false)
|
|
362
|
-
expect(cassette.http_interactions.parent_list).to be(VCR.http_interactions)
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
if stub_requests
|
|
366
|
-
it 'invokes the before_playback hooks' do
|
|
367
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
368
|
-
|
|
369
|
-
expect(VCR.configuration).to receive(:invoke_hook).with(
|
|
370
|
-
:before_playback,
|
|
371
|
-
an_instance_of(VCR::HTTPInteraction::HookAware),
|
|
372
|
-
an_instance_of(VCR::Cassette)
|
|
373
|
-
).exactly(3).times
|
|
374
|
-
|
|
375
|
-
cassette = VCR::Cassette.new('example', :record => record_mode)
|
|
376
|
-
expect(cassette.send(:previously_recorded_interactions).size).to eq(3)
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
it 'does not playback any interactions that are ignored in a before_playback hook' do
|
|
380
|
-
VCR.configure do |c|
|
|
381
|
-
c.before_playback { |i| i.ignore! if i.request.uri =~ /foo/ }
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
385
|
-
cassette = VCR::Cassette.new('example', :record => record_mode)
|
|
386
|
-
expect(cassette.send(:previously_recorded_interactions).size).to eq(2)
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
it 'instantiates the http_interactions with the loaded interactions and the request matchers' do
|
|
390
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
391
|
-
cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
|
|
392
|
-
expect(cassette.http_interactions.interactions.size).to eq(3)
|
|
393
|
-
expect(cassette.http_interactions.request_matchers).to eq([:body, :headers])
|
|
394
|
-
end
|
|
395
|
-
else
|
|
396
|
-
it 'instantiates the http_interactions with the no interactions and the request matchers' do
|
|
397
|
-
VCR.configuration.cassette_library_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
398
|
-
cassette = VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:body, :headers])
|
|
399
|
-
expect(cassette.http_interactions.interactions.size).to eq(0)
|
|
400
|
-
expect(cassette.http_interactions.request_matchers).to eq([:body, :headers])
|
|
401
|
-
end
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
end
|
|
405
|
-
end
|
|
406
|
-
|
|
407
|
-
describe ".originally_recorded_at" do
|
|
408
|
-
it 'returns the earliest `recorded_at` timestamp' do
|
|
409
|
-
i1 = http_interaction { |i| i.recorded_at = Time.now - 1000 }
|
|
410
|
-
i2 = http_interaction { |i| i.recorded_at = Time.now - 10000 }
|
|
411
|
-
i3 = http_interaction { |i| i.recorded_at = Time.now - 100 }
|
|
412
|
-
|
|
413
|
-
stub_old_interactions([i1, i2, i3])
|
|
414
|
-
|
|
415
|
-
cassette = VCR::Cassette.new("example")
|
|
416
|
-
expect(cassette.originally_recorded_at).to eq(i2.recorded_at)
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
it 'records nil for a cassette that has no prior recorded interactions' do
|
|
420
|
-
stub_old_interactions([])
|
|
421
|
-
cassette = VCR::Cassette.new("example")
|
|
422
|
-
expect(cassette.originally_recorded_at).to be_nil
|
|
423
|
-
end
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
describe '#eject' do
|
|
427
|
-
let(:custom_persister) { double("custom persister", :[] => nil) }
|
|
428
|
-
|
|
429
|
-
context "when :allow_unused_http_interactions is set to false" do
|
|
430
|
-
it 'asserts that there are no unused interactions' do
|
|
431
|
-
cassette = VCR.insert_cassette("foo", :allow_unused_http_interactions => false)
|
|
432
|
-
|
|
433
|
-
interaction_list = cassette.http_interactions
|
|
434
|
-
expect(interaction_list).to respond_to(:assert_no_unused_interactions!).with(0).arguments
|
|
435
|
-
expect(interaction_list).to receive(:assert_no_unused_interactions!)
|
|
436
|
-
|
|
437
|
-
cassette.eject
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
it 'does not assert no unused interactions if there is an existing error' do
|
|
441
|
-
cassette = VCR.insert_cassette("foo", :allow_unused_http_interactions => false)
|
|
442
|
-
interaction_list = cassette.http_interactions
|
|
443
|
-
allow(interaction_list).to receive(:assert_no_unused_interactions!)
|
|
444
|
-
|
|
445
|
-
expect {
|
|
446
|
-
begin
|
|
447
|
-
raise "boom"
|
|
448
|
-
ensure
|
|
449
|
-
cassette.eject
|
|
450
|
-
end
|
|
451
|
-
}.to raise_error(/boom/)
|
|
452
|
-
|
|
453
|
-
expect(interaction_list).not_to have_received(:assert_no_unused_interactions!)
|
|
454
|
-
end
|
|
455
|
-
|
|
456
|
-
it 'does not assert no unused interactions if :skip_no_unused_interactions_assertion is passed' do
|
|
457
|
-
cassette = VCR.insert_cassette("foo", :allow_unused_http_interactions => false)
|
|
458
|
-
|
|
459
|
-
interaction_list = cassette.http_interactions
|
|
460
|
-
expect(interaction_list).not_to receive(:assert_no_unused_interactions!)
|
|
461
|
-
|
|
462
|
-
cassette.eject(:skip_no_unused_interactions_assertion => true)
|
|
463
|
-
end
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
it 'does not assert that there are no unused interactions if allow_unused_http_interactions is set to true' do
|
|
467
|
-
cassette = VCR.insert_cassette("foo", :allow_unused_http_interactions => true)
|
|
468
|
-
|
|
469
|
-
interaction_list = cassette.http_interactions
|
|
470
|
-
expect(interaction_list).to respond_to(:assert_no_unused_interactions!)
|
|
471
|
-
expect(interaction_list).not_to receive(:assert_no_unused_interactions!)
|
|
472
|
-
|
|
473
|
-
cassette.eject
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
it 'stores the cassette content using the configured persister' do
|
|
477
|
-
VCR.configuration.cassette_library_dir = nil
|
|
478
|
-
VCR.cassette_persisters[:foo] = custom_persister
|
|
479
|
-
cassette = VCR.insert_cassette("foo", :persist_with => :foo)
|
|
480
|
-
cassette.record_http_interaction http_interaction
|
|
481
|
-
|
|
482
|
-
expect(custom_persister).to receive(:[]=).with("foo.yml", /http_interactions/)
|
|
483
|
-
|
|
484
|
-
cassette.eject
|
|
485
|
-
end
|
|
486
|
-
|
|
487
|
-
it "writes the serializable_hash to disk as yaml" do
|
|
488
|
-
cassette = VCR::Cassette.new(:eject_test)
|
|
489
|
-
cassette.record_http_interaction http_interaction # so it has one
|
|
490
|
-
expect(cassette).to respond_to(:serializable_hash)
|
|
491
|
-
allow(cassette).to receive(:serializable_hash).and_return({ "http_interactions" => [1, 3, 5] })
|
|
492
|
-
|
|
493
|
-
expect { cassette.eject }.to change { ::File.exist?(cassette.file) }.from(false).to(true)
|
|
494
|
-
saved_stuff = YAML.load_file(cassette.file)
|
|
495
|
-
expect(saved_stuff).to eq("http_interactions" => [1, 3, 5])
|
|
496
|
-
end
|
|
497
|
-
|
|
498
|
-
it 'invokes the appropriately tagged before_record hooks' do
|
|
499
|
-
interactions = [
|
|
500
|
-
http_interaction { |i| i.request.uri = 'http://foo.com/'; i.response.body = 'res 1' },
|
|
501
|
-
http_interaction { |i| i.request.uri = 'http://bar.com/'; i.response.body = 'res 2' }
|
|
502
|
-
]
|
|
503
|
-
|
|
504
|
-
cassette = VCR::Cassette.new('example', :tag => :foo)
|
|
505
|
-
allow(cassette).to receive(:new_recorded_interactions).and_return(interactions)
|
|
506
|
-
|
|
507
|
-
allow(VCR.configuration).to receive(:invoke_hook).and_return([false])
|
|
508
|
-
|
|
509
|
-
interactions.each do |i|
|
|
510
|
-
expect(VCR.configuration).to receive(:invoke_hook).with(
|
|
511
|
-
:before_record,
|
|
512
|
-
an_instance_of(VCR::HTTPInteraction::HookAware),
|
|
513
|
-
cassette
|
|
514
|
-
).ordered
|
|
515
|
-
end
|
|
516
|
-
|
|
517
|
-
cassette.eject
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
it 'does not record interactions that have been ignored' do
|
|
521
|
-
VCR.configure do |c|
|
|
522
|
-
c.before_record { |i| i.ignore! if i.request.uri =~ /foo/ }
|
|
523
|
-
end
|
|
524
|
-
|
|
525
|
-
interaction_1 = http_interaction { |i| i.request.uri = 'http://foo.com/'; i.response.body = 'res 1' }
|
|
526
|
-
interaction_2 = http_interaction { |i| i.request.uri = 'http://bar.com/'; i.response.body = 'res 2' }
|
|
527
|
-
|
|
528
|
-
cassette = VCR::Cassette.new('test_cassette')
|
|
529
|
-
allow(cassette).to receive(:new_recorded_interactions).and_return([interaction_1, interaction_2])
|
|
530
|
-
cassette.eject
|
|
531
|
-
|
|
532
|
-
saved_recorded_interactions = ::YAML.load_file(cassette.file)
|
|
533
|
-
expect(saved_recorded_interactions["http_interactions"]).to eq([interaction_2.to_hash])
|
|
534
|
-
end
|
|
535
|
-
|
|
536
|
-
it 'does not write the cassette to disk if all interactions have been ignored' do
|
|
537
|
-
VCR.configure do |c|
|
|
538
|
-
c.before_record { |i| i.ignore! }
|
|
539
|
-
end
|
|
540
|
-
|
|
541
|
-
interaction_1 = http_interaction { |i| i.request.uri = 'http://foo.com/'; i.response.body = 'res 1' }
|
|
542
|
-
|
|
543
|
-
cassette = VCR::Cassette.new('test_cassette')
|
|
544
|
-
allow(cassette).to receive(:new_recorded_interactions).and_return([interaction_1])
|
|
545
|
-
cassette.eject
|
|
546
|
-
|
|
547
|
-
expect(::File).not_to exist(cassette.file)
|
|
548
|
-
end
|
|
549
|
-
|
|
550
|
-
it "writes the recorded interactions to a subdirectory if the cassette name includes a directory" do
|
|
551
|
-
recorded_interactions = [http_interaction { |i| i.response.body = "subdirectory response" }]
|
|
552
|
-
cassette = VCR::Cassette.new('subdirectory/test_cassette')
|
|
553
|
-
allow(cassette).to receive(:new_recorded_interactions).and_return(recorded_interactions)
|
|
554
|
-
|
|
555
|
-
expect { cassette.eject }.to change { ::File.exist?(cassette.file) }.from(false).to(true)
|
|
556
|
-
saved_recorded_interactions = YAML.load_file(cassette.file)
|
|
557
|
-
expect(saved_recorded_interactions["http_interactions"]).to eq(recorded_interactions.map(&:to_hash))
|
|
558
|
-
end
|
|
559
|
-
|
|
560
|
-
[:all, :none, :new_episodes].each do |record_mode|
|
|
561
|
-
context "for a :record => :#{record_mode} cassette with previously recorded interactions" do
|
|
562
|
-
subject { VCR::Cassette.new('example', :record => record_mode, :match_requests_on => [:uri]) }
|
|
563
|
-
|
|
564
|
-
before(:each) do
|
|
565
|
-
base_dir = "#{VCR::SPEC_ROOT}/fixtures/cassette_spec"
|
|
566
|
-
FileUtils.cp(base_dir + "/example.yml", VCR.configuration.cassette_library_dir + "/example.yml")
|
|
567
|
-
end
|
|
568
|
-
|
|
569
|
-
it "does not re-write to disk the previously recorded interactions if there are no new ones" do
|
|
570
|
-
yaml_file = subject.file
|
|
571
|
-
expect(::File).not_to receive(:open).with(subject.file, 'w')
|
|
572
|
-
expect { subject.eject }.to_not change { ::File.mtime(yaml_file) }
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
context 'when some new interactions have been recorded' do
|
|
576
|
-
def interaction(response_body, request_attributes)
|
|
577
|
-
http_interaction do |interaction|
|
|
578
|
-
interaction.response.body = response_body
|
|
579
|
-
request_attributes.each do |key, value|
|
|
580
|
-
interaction.request.send("#{key}=", value)
|
|
581
|
-
end
|
|
582
|
-
end
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
let(:interaction_foo_1) { interaction("foo 1", :uri => 'http://foo.com/') }
|
|
586
|
-
let(:interaction_foo_2) { interaction("foo 2", :uri => 'http://foo.com/') }
|
|
587
|
-
let(:interaction_bar) { interaction("bar", :uri => 'http://bar.com/') }
|
|
588
|
-
|
|
589
|
-
let(:saved_recorded_interactions) { YAML.load_file(subject.file)['http_interactions'].map { |h| VCR::HTTPInteraction.from_hash(h) } }
|
|
590
|
-
let(:now) { Time.utc(2011, 6, 11, 12, 30) }
|
|
591
|
-
|
|
592
|
-
before(:each) do
|
|
593
|
-
allow(Time).to receive(:now).and_return(now)
|
|
594
|
-
allow(subject).to receive(:previously_recorded_interactions).and_return([interaction_foo_1])
|
|
595
|
-
subject.record_http_interaction(interaction_foo_2)
|
|
596
|
-
subject.record_http_interaction(interaction_bar)
|
|
597
|
-
subject.eject
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
if record_mode == :all
|
|
601
|
-
it 'replaces previously recorded interactions with new ones when the requests match' do
|
|
602
|
-
expect(saved_recorded_interactions.first).to eq(interaction_foo_2)
|
|
603
|
-
expect(saved_recorded_interactions).not_to include(interaction_foo_1)
|
|
604
|
-
end
|
|
605
|
-
|
|
606
|
-
it 'appends new recorded interactions that do not match existing ones' do
|
|
607
|
-
expect(saved_recorded_interactions.last).to eq(interaction_bar)
|
|
608
|
-
end
|
|
609
|
-
else
|
|
610
|
-
it 'appends new recorded interactions after existing ones' do
|
|
611
|
-
expect(saved_recorded_interactions).to eq([interaction_foo_1, interaction_foo_2, interaction_bar])
|
|
612
|
-
end
|
|
613
|
-
end
|
|
614
|
-
end
|
|
615
|
-
end
|
|
616
|
-
end
|
|
617
|
-
end
|
|
618
|
-
end
|