vcr 3.0.3 → 6.1.0

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