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,75 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'vcr/cassette/persisters/file_system'
|
3
|
-
|
4
|
-
module VCR
|
5
|
-
class Cassette
|
6
|
-
class Persisters
|
7
|
-
describe FileSystem do
|
8
|
-
before { FileSystem.storage_location = VCR.configuration.cassette_library_dir }
|
9
|
-
|
10
|
-
describe "#[]" do
|
11
|
-
it 'reads from the given file, relative to the configured storage location' do
|
12
|
-
File.open(FileSystem.storage_location + '/foo.txt', 'w') { |f| f.write('1234') }
|
13
|
-
expect(FileSystem["foo.txt"]).to eq("1234")
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'handles directories in the given file name' do
|
17
|
-
FileUtils.mkdir_p FileSystem.storage_location + '/a'
|
18
|
-
File.open(FileSystem.storage_location + '/a/b', 'w') { |f| f.write('1234') }
|
19
|
-
expect(FileSystem["a/b"]).to eq("1234")
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'returns nil if the file does not exist' do
|
23
|
-
expect(FileSystem["non_existant_file"]).to be_nil
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe "#[]=" do
|
28
|
-
context 'with a simple file_name and binary content' do
|
29
|
-
let(:file_name) { 'foo.txt' }
|
30
|
-
let(:content) { SecureRandom.random_bytes(20) }
|
31
|
-
let(:location) { FileSystem.storage_location + '/' + file_name }
|
32
|
-
|
33
|
-
it 'writes the given file contents to the given file name' do
|
34
|
-
expect(File.exist?(location)).to be false
|
35
|
-
FileSystem[file_name] = content
|
36
|
-
expect(File.binread(location)).to eq(content)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'creates any needed intermediary directories' do
|
41
|
-
expect(File.exist?(FileSystem.storage_location + '/a')).to be false
|
42
|
-
FileSystem["a/b"] = "bar"
|
43
|
-
expect(File.read(FileSystem.storage_location + '/a/b')).to eq("bar")
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "#absolute_path_to_file" do
|
48
|
-
it "returns the absolute path to the given relative file based on the storage location" do
|
49
|
-
expected = File.join(FileSystem.storage_location, "bar/bazz.json")
|
50
|
-
expect(FileSystem.absolute_path_to_file("bar/bazz.json")).to eq(expected)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "returns nil if the storage_location is not set" do
|
54
|
-
FileSystem.storage_location = nil
|
55
|
-
expect(FileSystem.absolute_path_to_file("bar/bazz.json")).to be_nil
|
56
|
-
end
|
57
|
-
|
58
|
-
it "sanitizes the file name" do
|
59
|
-
expected = File.join(FileSystem.storage_location, "_t_i-t_1_2_f_n.json")
|
60
|
-
expect(FileSystem.absolute_path_to_file("\nt \t! i-t_1.2_f n.json")).to eq(expected)
|
61
|
-
|
62
|
-
expected = File.join(FileSystem.storage_location, "a_1/b")
|
63
|
-
expect(FileSystem.absolute_path_to_file("a 1/b")).to eq(expected)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'handles files with no extensions (even when there is a dot in the path)' do
|
67
|
-
expected = File.join(FileSystem.storage_location, "/foo_bar/baz_qux")
|
68
|
-
expect(FileSystem.absolute_path_to_file("/foo.bar/baz qux")).to eq(expected)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'vcr/cassette/persisters'
|
2
|
-
|
3
|
-
module VCR
|
4
|
-
class Cassette
|
5
|
-
describe Persisters do
|
6
|
-
describe "#[]=" do
|
7
|
-
context 'when there is already a persister registered for the given name' do
|
8
|
-
before(:each) do
|
9
|
-
subject[:foo] = :old_persister
|
10
|
-
allow(subject).to receive :warn
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'overrides the existing persister' do
|
14
|
-
subject[:foo] = :new_persister
|
15
|
-
expect(subject[:foo]).to be(:new_persister)
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'warns that there is a name collision' do
|
19
|
-
expect(subject).to receive(:warn).with(
|
20
|
-
/WARNING: There is already a VCR cassette persister registered for :foo\. Overriding it/
|
21
|
-
)
|
22
|
-
subject[:foo] = :new_persister
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
describe "#[]" do
|
28
|
-
it 'raises an error when given an unrecognized persister name' do
|
29
|
-
expect { subject[:foo] }.to raise_error(ArgumentError)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'returns the named persister' do
|
33
|
-
expect(subject[:file_system]).to be(VCR::Cassette::Persisters::FileSystem)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
@@ -1,182 +0,0 @@
|
|
1
|
-
require 'support/ruby_interpreter'
|
2
|
-
require 'vcr/cassette/serializers'
|
3
|
-
require 'multi_json'
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'psych' # ensure psych is loaded for these tests if its available
|
7
|
-
rescue LoadError
|
8
|
-
end
|
9
|
-
|
10
|
-
module VCR
|
11
|
-
class Cassette
|
12
|
-
describe Serializers do
|
13
|
-
shared_examples_for "encoding error handling" do |name, error_class|
|
14
|
-
context "the #{name} serializer" do
|
15
|
-
it 'appends info about the :preserve_exact_body_bytes option to the error' do
|
16
|
-
expect {
|
17
|
-
result = serializer.serialize("a" => string)
|
18
|
-
serializer.deserialize(result)
|
19
|
-
}.to raise_error(error_class, /preserve_exact_body_bytes/)
|
20
|
-
end unless (RUBY_INTERPRETER == :rubinius && RUBY_VERSION =~ /^1.9/)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
shared_examples_for "a serializer" do |name, file_extension, lazily_loaded|
|
25
|
-
let(:serializer) { subject[name] }
|
26
|
-
|
27
|
-
context "the #{name} serializer" do
|
28
|
-
it 'lazily loads the serializer' do
|
29
|
-
serializers = subject.instance_variable_get(:@serializers)
|
30
|
-
expect(serializers).not_to have_key(name)
|
31
|
-
expect(subject[name]).not_to be_nil
|
32
|
-
expect(serializers).to have_key(name)
|
33
|
-
end if lazily_loaded
|
34
|
-
|
35
|
-
it "returns '#{file_extension}' as the file extension" do
|
36
|
-
expect(serializer.file_extension).to eq(file_extension)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "can serialize and deserialize a hash" do
|
40
|
-
hash = { "a" => 7, "nested" => { "hash" => [1, 2, 3] }}
|
41
|
-
serialized = serializer.serialize(hash)
|
42
|
-
expect(serialized).not_to eq(hash)
|
43
|
-
expect(serialized).to be_a(String)
|
44
|
-
deserialized = serializer.deserialize(serialized)
|
45
|
-
expect(deserialized).to eq(hash)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it_behaves_like "a serializer", :yaml, "yml", :lazily_loaded do
|
51
|
-
it_behaves_like "encoding error handling", :yaml, ArgumentError do
|
52
|
-
let(:string) { "\xFA".force_encoding("UTF-8") }
|
53
|
-
before { ::YAML::ENGINE.yamler = 'psych' if defined?(::YAML::ENGINE) }
|
54
|
-
end if ''.respond_to?(:encoding)
|
55
|
-
end
|
56
|
-
|
57
|
-
it_behaves_like "a serializer", :syck, "yml", :lazily_loaded do
|
58
|
-
it_behaves_like "encoding error handling", :syck, ArgumentError do
|
59
|
-
let(:string) { "\xFA".force_encoding("UTF-8") }
|
60
|
-
end if ''.respond_to?(:encoding)
|
61
|
-
end
|
62
|
-
|
63
|
-
it_behaves_like "a serializer", :psych, "yml", :lazily_loaded do
|
64
|
-
it_behaves_like "encoding error handling", :psych, ArgumentError do
|
65
|
-
let(:string) { "\xFA".force_encoding("UTF-8") }
|
66
|
-
end if ''.respond_to?(:encoding)
|
67
|
-
end if RUBY_VERSION =~ /1.9/
|
68
|
-
|
69
|
-
it_behaves_like "a serializer", :compressed, "gz", :lazily_loaded do
|
70
|
-
it_behaves_like "encoding error handling", :compressed, ArgumentError do
|
71
|
-
let(:string) { "\xFA".force_encoding("UTF-8") }
|
72
|
-
end if ''.respond_to?(:encoding)
|
73
|
-
end
|
74
|
-
|
75
|
-
it_behaves_like "a serializer", :json, "json", :lazily_loaded do
|
76
|
-
engines = {}
|
77
|
-
|
78
|
-
if RUBY_INTERPRETER == :jruby
|
79
|
-
# don't test yajl on jruby
|
80
|
-
else
|
81
|
-
engines[:yajl] = MultiJson::LoadError
|
82
|
-
end
|
83
|
-
|
84
|
-
if RUBY_VERSION =~ /1.9/
|
85
|
-
engines[:json_gem] = EncodingError
|
86
|
-
|
87
|
-
# Disable json_pure for now due to this bug:
|
88
|
-
# https://github.com/flori/json/issues/186
|
89
|
-
# engines[:json_pure] = EncodingError
|
90
|
-
end
|
91
|
-
|
92
|
-
engines.each do |engine, error|
|
93
|
-
context "when MultiJson is configured to use #{engine.inspect}", :unless => (RUBY_INTERPRETER == :jruby) do
|
94
|
-
before { MultiJson.engine = engine }
|
95
|
-
it_behaves_like "encoding error handling", :json, error do
|
96
|
-
let(:string) { "\xFA" }
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context "a custom :ruby serializer" do
|
103
|
-
let(:custom_serializer) do
|
104
|
-
Object.new.tap do |obj|
|
105
|
-
def obj.file_extension
|
106
|
-
"rb"
|
107
|
-
end
|
108
|
-
|
109
|
-
def obj.serialize(hash)
|
110
|
-
hash.inspect
|
111
|
-
end
|
112
|
-
|
113
|
-
def obj.deserialize(string)
|
114
|
-
eval(string)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
before(:each) do
|
120
|
-
subject[:ruby] = custom_serializer
|
121
|
-
end
|
122
|
-
|
123
|
-
it_behaves_like "a serializer", :ruby, "rb", false
|
124
|
-
end
|
125
|
-
|
126
|
-
describe "#[]=" do
|
127
|
-
context 'when there is already a serializer registered for the given name' do
|
128
|
-
before(:each) do
|
129
|
-
subject[:foo] = :old_serializer
|
130
|
-
allow(subject).to receive :warn
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'overrides the existing serializer' do
|
134
|
-
subject[:foo] = :new_serializer
|
135
|
-
expect(subject[:foo]).to be(:new_serializer)
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'warns that there is a name collision' do
|
139
|
-
expect(subject).to receive(:warn).with(
|
140
|
-
/WARNING: There is already a VCR cassette serializer registered for :foo\. Overriding it/
|
141
|
-
)
|
142
|
-
subject[:foo] = :new_serializer
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
describe "#[]" do
|
148
|
-
it 'raises an error when given an unrecognized serializer name' do
|
149
|
-
expect { subject[:foo] }.to raise_error(ArgumentError)
|
150
|
-
end
|
151
|
-
|
152
|
-
it 'returns the named serializer' do
|
153
|
-
expect(subject[:yaml]).to be(VCR::Cassette::Serializers::YAML)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# see https://gist.github.com/815769
|
158
|
-
problematic_syck_string = "1\n \n2"
|
159
|
-
|
160
|
-
describe "psych serializer" do
|
161
|
-
it 'serializes things using pysch even if syck is configured as the default YAML engine' do
|
162
|
-
::YAML::ENGINE.yamler = 'syck'
|
163
|
-
serialized = subject[:psych].serialize(problematic_syck_string)
|
164
|
-
expect(subject[:psych].deserialize(serialized)).to eq(problematic_syck_string)
|
165
|
-
end if defined?(::Psych) && RUBY_VERSION.to_f < 2.0
|
166
|
-
|
167
|
-
it 'raises an error if psych cannot be loaded' do
|
168
|
-
expect { subject[:psych] }.to raise_error(LoadError)
|
169
|
-
end unless defined?(::Psych)
|
170
|
-
end
|
171
|
-
|
172
|
-
describe "syck serializer" do
|
173
|
-
it 'forcibly serializes things using syck even if psych is the currently configured YAML engine' do
|
174
|
-
::YAML::ENGINE.yamler = 'psych'
|
175
|
-
serialized = subject[:syck].serialize(problematic_syck_string)
|
176
|
-
expect(subject[:syck].deserialize(serialized)).not_to eq(problematic_syck_string)
|
177
|
-
end if defined?(::Psych) && (RUBY_INTERPRETER != :jruby) && (RUBY_VERSION.to_f < 2.0)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
@@ -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
|