mustwin-vcr 2.9.3
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 +7 -0
- data/features/about_these_examples.md +18 -0
- data/features/cassettes/allow_unused_http_interactions.feature +100 -0
- data/features/cassettes/automatic_re_recording.feature +72 -0
- data/features/cassettes/decompress.feature +74 -0
- data/features/cassettes/dynamic_erb.feature +100 -0
- data/features/cassettes/exclusive.feature +126 -0
- data/features/cassettes/format.feature +323 -0
- data/features/cassettes/freezing_time.feature +68 -0
- data/features/cassettes/naming.feature +28 -0
- data/features/cassettes/no_cassette.feature +152 -0
- data/features/cassettes/update_content_length_header.feature +112 -0
- data/features/configuration/allow_http_connections_when_no_cassette.feature +55 -0
- data/features/configuration/cassette_library_dir.feature +31 -0
- data/features/configuration/debug_logging.feature +59 -0
- data/features/configuration/default_cassette_options.feature +100 -0
- data/features/configuration/filter_sensitive_data.feature +153 -0
- data/features/configuration/hook_into.feature +172 -0
- data/features/configuration/ignore_request.feature +192 -0
- data/features/configuration/preserve_exact_body_bytes.feature +108 -0
- data/features/configuration/query_parser.feature +84 -0
- data/features/configuration/uri_parser.feature +89 -0
- data/features/getting_started.md +82 -0
- data/features/hooks/after_http_request.feature +58 -0
- data/features/hooks/around_http_request.feature +57 -0
- data/features/hooks/before_http_request.feature +63 -0
- data/features/hooks/before_playback.feature +184 -0
- data/features/hooks/before_record.feature +172 -0
- data/features/http_libraries/em_http_request.feature +250 -0
- data/features/http_libraries/net_http.feature +179 -0
- data/features/middleware/faraday.feature +56 -0
- data/features/middleware/rack.feature +92 -0
- data/features/record_modes/all.feature +82 -0
- data/features/record_modes/new_episodes.feature +79 -0
- data/features/record_modes/none.feature +72 -0
- data/features/record_modes/once.feature +95 -0
- data/features/request_matching/README.md +30 -0
- data/features/request_matching/body.feature +91 -0
- data/features/request_matching/body_as_json.feature +90 -0
- data/features/request_matching/custom_matcher.feature +135 -0
- data/features/request_matching/headers.feature +85 -0
- data/features/request_matching/host.feature +95 -0
- data/features/request_matching/identical_request_sequence.feature +89 -0
- data/features/request_matching/method.feature +96 -0
- data/features/request_matching/path.feature +96 -0
- data/features/request_matching/playback_repeats.feature +98 -0
- data/features/request_matching/query.feature +97 -0
- data/features/request_matching/uri.feature +94 -0
- data/features/request_matching/uri_without_param.feature +101 -0
- data/features/step_definitions/cli_steps.rb +193 -0
- data/features/support/env.rb +44 -0
- data/features/support/http_lib_filters.rb +53 -0
- data/features/test_frameworks/cucumber.feature +211 -0
- data/features/test_frameworks/rspec_macro.feature +81 -0
- data/features/test_frameworks/rspec_metadata.feature +150 -0
- data/features/test_frameworks/test_unit.feature +49 -0
- data/lib/vcr.rb +347 -0
- data/lib/vcr/cassette.rb +291 -0
- data/lib/vcr/cassette/erb_renderer.rb +55 -0
- data/lib/vcr/cassette/http_interaction_list.rb +108 -0
- data/lib/vcr/cassette/migrator.rb +118 -0
- data/lib/vcr/cassette/persisters.rb +42 -0
- data/lib/vcr/cassette/persisters/file_system.rb +64 -0
- data/lib/vcr/cassette/serializers.rb +57 -0
- data/lib/vcr/cassette/serializers/json.rb +48 -0
- data/lib/vcr/cassette/serializers/psych.rb +48 -0
- data/lib/vcr/cassette/serializers/syck.rb +61 -0
- data/lib/vcr/cassette/serializers/yaml.rb +50 -0
- data/lib/vcr/configuration.rb +555 -0
- data/lib/vcr/deprecations.rb +109 -0
- data/lib/vcr/errors.rb +266 -0
- data/lib/vcr/extensions/net_http_response.rb +36 -0
- data/lib/vcr/library_hooks.rb +18 -0
- data/lib/vcr/library_hooks/excon.rb +27 -0
- data/lib/vcr/library_hooks/fakeweb.rb +196 -0
- data/lib/vcr/library_hooks/faraday.rb +51 -0
- data/lib/vcr/library_hooks/typhoeus.rb +120 -0
- data/lib/vcr/library_hooks/typhoeus_0.4.rb +103 -0
- data/lib/vcr/library_hooks/webmock.rb +164 -0
- data/lib/vcr/middleware/excon.rb +221 -0
- data/lib/vcr/middleware/excon/legacy_methods.rb +33 -0
- data/lib/vcr/middleware/faraday.rb +118 -0
- data/lib/vcr/middleware/rack.rb +79 -0
- data/lib/vcr/request_handler.rb +114 -0
- data/lib/vcr/request_ignorer.rb +43 -0
- data/lib/vcr/request_matcher_registry.rb +149 -0
- data/lib/vcr/structs.rb +578 -0
- data/lib/vcr/tasks/vcr.rake +9 -0
- data/lib/vcr/test_frameworks/cucumber.rb +64 -0
- data/lib/vcr/test_frameworks/rspec.rb +47 -0
- data/lib/vcr/util/hooks.rb +61 -0
- data/lib/vcr/util/internet_connection.rb +43 -0
- data/lib/vcr/util/logger.rb +59 -0
- data/lib/vcr/util/variable_args_block_caller.rb +13 -0
- data/lib/vcr/util/version_checker.rb +48 -0
- data/lib/vcr/version.rb +34 -0
- data/spec/acceptance/threading_spec.rb +34 -0
- data/spec/fixtures/cassette_spec/1_x_cassette.yml +110 -0
- data/spec/fixtures/cassette_spec/empty.yml +0 -0
- data/spec/fixtures/cassette_spec/example.yml +111 -0
- data/spec/fixtures/cassette_spec/with_localhost_requests.yml +111 -0
- data/spec/fixtures/fake_example_responses.yml +110 -0
- data/spec/fixtures/match_requests_on.yml +187 -0
- data/spec/lib/vcr/cassette/erb_renderer_spec.rb +53 -0
- data/spec/lib/vcr/cassette/http_interaction_list_spec.rb +295 -0
- data/spec/lib/vcr/cassette/migrator_spec.rb +195 -0
- data/spec/lib/vcr/cassette/persisters/file_system_spec.rb +69 -0
- data/spec/lib/vcr/cassette/persisters_spec.rb +39 -0
- data/spec/lib/vcr/cassette/serializers_spec.rb +176 -0
- data/spec/lib/vcr/cassette_spec.rb +618 -0
- data/spec/lib/vcr/configuration_spec.rb +326 -0
- data/spec/lib/vcr/deprecations_spec.rb +85 -0
- data/spec/lib/vcr/errors_spec.rb +162 -0
- data/spec/lib/vcr/extensions/net_http_response_spec.rb +86 -0
- data/spec/lib/vcr/library_hooks/excon_spec.rb +104 -0
- data/spec/lib/vcr/library_hooks/fakeweb_spec.rb +169 -0
- data/spec/lib/vcr/library_hooks/faraday_spec.rb +68 -0
- data/spec/lib/vcr/library_hooks/typhoeus_0.4_spec.rb +36 -0
- data/spec/lib/vcr/library_hooks/typhoeus_spec.rb +162 -0
- data/spec/lib/vcr/library_hooks/webmock_spec.rb +118 -0
- data/spec/lib/vcr/library_hooks_spec.rb +51 -0
- data/spec/lib/vcr/middleware/faraday_spec.rb +182 -0
- data/spec/lib/vcr/middleware/rack_spec.rb +115 -0
- data/spec/lib/vcr/request_ignorer_spec.rb +70 -0
- data/spec/lib/vcr/request_matcher_registry_spec.rb +345 -0
- data/spec/lib/vcr/structs_spec.rb +732 -0
- data/spec/lib/vcr/test_frameworks/cucumber_spec.rb +107 -0
- data/spec/lib/vcr/test_frameworks/rspec_spec.rb +83 -0
- data/spec/lib/vcr/util/hooks_spec.rb +158 -0
- data/spec/lib/vcr/util/internet_connection_spec.rb +37 -0
- data/spec/lib/vcr/util/version_checker_spec.rb +31 -0
- data/spec/lib/vcr/version_spec.rb +27 -0
- data/spec/lib/vcr_spec.rb +349 -0
- data/spec/monkey_patches.rb +182 -0
- data/spec/spec_helper.rb +62 -0
- data/spec/support/configuration_stubbing.rb +8 -0
- data/spec/support/cucumber_helpers.rb +35 -0
- data/spec/support/fixnum_extension.rb +10 -0
- data/spec/support/http_library_adapters.rb +289 -0
- data/spec/support/limited_uri.rb +21 -0
- data/spec/support/ruby_interpreter.rb +7 -0
- data/spec/support/shared_example_groups/excon.rb +63 -0
- data/spec/support/shared_example_groups/hook_into_http_library.rb +594 -0
- data/spec/support/shared_example_groups/request_hooks.rb +59 -0
- data/spec/support/sinatra_app.rb +86 -0
- data/spec/support/vcr_localhost_server.rb +76 -0
- data/spec/support/vcr_stub_helpers.rb +17 -0
- metadata +677 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Feature: Update content_length header
|
|
2
|
+
|
|
3
|
+
When the `:update_content_length_header` option is set to a truthy value,
|
|
4
|
+
VCR will ensure that the `Content-Length` header will have the correct
|
|
5
|
+
value. This is useful in several situations:
|
|
6
|
+
|
|
7
|
+
- When you manually edit the cassette file and change the resonse body
|
|
8
|
+
length. You can use this option so you don't have to manually calculate
|
|
9
|
+
and update the body length.
|
|
10
|
+
- When you use ERB, the response body length may vary. This will ensure
|
|
11
|
+
it is always correct.
|
|
12
|
+
- Syck, the default YAML engine for ruby 1.8 (and 1.9, unless you compile
|
|
13
|
+
it to use Psych), has a bug where it sometimes will remove some
|
|
14
|
+
whitespace strings when you serialize them. This may cause the
|
|
15
|
+
`Content-Length` header to have the wrong value.
|
|
16
|
+
|
|
17
|
+
This is especially important when you use a client that checks the
|
|
18
|
+
`Content-Length` header. Mechanize, for example, will raise an `EOFError`
|
|
19
|
+
when the header value does not match the actual body length.
|
|
20
|
+
|
|
21
|
+
Background:
|
|
22
|
+
Given a previously recorded cassette file "cassettes/example.yml" with:
|
|
23
|
+
"""
|
|
24
|
+
---
|
|
25
|
+
http_interactions:
|
|
26
|
+
- request:
|
|
27
|
+
method: get
|
|
28
|
+
uri: http://example.com/
|
|
29
|
+
body:
|
|
30
|
+
encoding: UTF-8
|
|
31
|
+
string: ""
|
|
32
|
+
headers: {}
|
|
33
|
+
response:
|
|
34
|
+
status:
|
|
35
|
+
code: 200
|
|
36
|
+
message: OK
|
|
37
|
+
headers:
|
|
38
|
+
Content-Type:
|
|
39
|
+
- text/html;charset=utf-8
|
|
40
|
+
Content-Length:
|
|
41
|
+
- "11"
|
|
42
|
+
body:
|
|
43
|
+
encoding: UTF-8
|
|
44
|
+
string: Hello <modified>
|
|
45
|
+
http_version: "1.1"
|
|
46
|
+
recorded_at: Tue, 01 Nov 2011 04:58:44 GMT
|
|
47
|
+
recorded_with: VCR 2.0.0
|
|
48
|
+
"""
|
|
49
|
+
And a file named "common_stuff.rb" with:
|
|
50
|
+
"""ruby
|
|
51
|
+
require 'vcr'
|
|
52
|
+
|
|
53
|
+
VCR.configure do |c|
|
|
54
|
+
c.cassette_library_dir = 'cassettes'
|
|
55
|
+
c.hook_into :webmock
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def make_request_and_print_results
|
|
59
|
+
response = Net::HTTP.get_response('example.com', '/')
|
|
60
|
+
puts "Body length: #{response.body.length}"
|
|
61
|
+
puts "Header value: #{response['Content-Length']}"
|
|
62
|
+
end
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
Scenario: Default :update_content_length_header setting
|
|
66
|
+
Given a file named "default.rb" with:
|
|
67
|
+
"""ruby
|
|
68
|
+
require 'common_stuff'
|
|
69
|
+
|
|
70
|
+
VCR.use_cassette('example') do
|
|
71
|
+
make_request_and_print_results
|
|
72
|
+
end
|
|
73
|
+
"""
|
|
74
|
+
When I run `ruby default.rb`
|
|
75
|
+
Then the output should contain:
|
|
76
|
+
"""
|
|
77
|
+
Body length: 16
|
|
78
|
+
Header value: 11
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
Scenario: :update_content_length_header => false
|
|
82
|
+
Given a file named "false.rb" with:
|
|
83
|
+
"""ruby
|
|
84
|
+
require 'common_stuff'
|
|
85
|
+
|
|
86
|
+
VCR.use_cassette('example', :update_content_length_header => false) do
|
|
87
|
+
make_request_and_print_results
|
|
88
|
+
end
|
|
89
|
+
"""
|
|
90
|
+
When I run `ruby false.rb`
|
|
91
|
+
Then the output should contain:
|
|
92
|
+
"""
|
|
93
|
+
Body length: 16
|
|
94
|
+
Header value: 11
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
Scenario: :update_content_length_header => true
|
|
98
|
+
Given a file named "true.rb" with:
|
|
99
|
+
"""ruby
|
|
100
|
+
require 'common_stuff'
|
|
101
|
+
|
|
102
|
+
VCR.use_cassette('example', :update_content_length_header => true) do
|
|
103
|
+
make_request_and_print_results
|
|
104
|
+
end
|
|
105
|
+
"""
|
|
106
|
+
When I run `ruby true.rb`
|
|
107
|
+
Then the output should contain:
|
|
108
|
+
"""
|
|
109
|
+
Body length: 16
|
|
110
|
+
Header value: 16
|
|
111
|
+
"""
|
|
112
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Feature: Allow HTTP connections when no cassette
|
|
2
|
+
|
|
3
|
+
Usually, HTTP requests made when no cassette is inserted will [result in an
|
|
4
|
+
error](../cassettes/error-for-http-request-made-when-no-cassette-is-in-use).
|
|
5
|
+
You can set the `allow_http_connections_when_no_cassette` configuration option
|
|
6
|
+
to true to allow requests, if you do not want to use VCR for everything.
|
|
7
|
+
|
|
8
|
+
Background:
|
|
9
|
+
Given a file named "vcr_setup.rb" with:
|
|
10
|
+
"""ruby
|
|
11
|
+
if ARGV.include?('--with-server')
|
|
12
|
+
$server = start_sinatra_app do
|
|
13
|
+
get('/') { "Hello" }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
require 'vcr'
|
|
18
|
+
|
|
19
|
+
VCR.configure do |c|
|
|
20
|
+
c.allow_http_connections_when_no_cassette = true
|
|
21
|
+
c.hook_into :webmock
|
|
22
|
+
c.cassette_library_dir = 'cassettes'
|
|
23
|
+
c.default_cassette_options = {
|
|
24
|
+
:match_requests_on => [:method, :host, :path]
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
"""
|
|
28
|
+
And the directory "vcr/cassettes" does not exist
|
|
29
|
+
|
|
30
|
+
Scenario: Allow HTTP connections when no cassette
|
|
31
|
+
Given a file named "no_cassette.rb" with:
|
|
32
|
+
"""ruby
|
|
33
|
+
require 'vcr_setup.rb'
|
|
34
|
+
|
|
35
|
+
puts "Response: " + Net::HTTP.get_response('localhost', '/', $server ? $server.port : 0).body
|
|
36
|
+
"""
|
|
37
|
+
When I run `ruby no_cassette.rb --with-server`
|
|
38
|
+
Then the output should contain "Response: Hello"
|
|
39
|
+
|
|
40
|
+
Scenario: Cassettes record and replay as normal
|
|
41
|
+
Given a file named "record_replay_cassette.rb" with:
|
|
42
|
+
"""ruby
|
|
43
|
+
require 'vcr_setup.rb'
|
|
44
|
+
|
|
45
|
+
VCR.use_cassette('localhost') do
|
|
46
|
+
puts "Response: " + Net::HTTP.get_response('localhost', '/', $server ? $server.port : 0).body
|
|
47
|
+
end
|
|
48
|
+
"""
|
|
49
|
+
When I run `ruby record_replay_cassette.rb --with-server`
|
|
50
|
+
Then the output should contain "Response: Hello"
|
|
51
|
+
And the file "cassettes/localhost.yml" should contain "Hello"
|
|
52
|
+
|
|
53
|
+
When I run `ruby record_replay_cassette.rb`
|
|
54
|
+
Then the output should contain "Response: Hello"
|
|
55
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Feature: cassette_library_dir
|
|
2
|
+
|
|
3
|
+
The `cassette_library_dir` configuration option sets a directory
|
|
4
|
+
where VCR saves each cassette.
|
|
5
|
+
|
|
6
|
+
Note: When using Rails, avoid using the `test/fixtures` directory
|
|
7
|
+
to store the cassettes. Rails treats any YAML file in the fixtures
|
|
8
|
+
directory as an ActiveRecord fixture.
|
|
9
|
+
This will cause an `ActiveRecord::Fixture::FormatError` to be raised.
|
|
10
|
+
|
|
11
|
+
Scenario: cassette_library_dir
|
|
12
|
+
Given a file named "cassette_library_dir.rb" with:
|
|
13
|
+
"""ruby
|
|
14
|
+
$server = start_sinatra_app do
|
|
15
|
+
get('/') { "Hello" }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
require 'vcr'
|
|
19
|
+
|
|
20
|
+
VCR.configure do |c|
|
|
21
|
+
c.cassette_library_dir = 'vcr/cassettes'
|
|
22
|
+
c.hook_into :webmock
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
VCR.use_cassette('localhost') do
|
|
26
|
+
Net::HTTP.get_response('localhost', '/', $server.port)
|
|
27
|
+
end
|
|
28
|
+
"""
|
|
29
|
+
And the directory "vcr/cassettes" does not exist
|
|
30
|
+
When I run `ruby cassette_library_dir.rb`
|
|
31
|
+
Then the file "vcr/cassettes/localhost.yml" should exist
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@exclude-18
|
|
2
|
+
Feature: Debug Logging
|
|
3
|
+
|
|
4
|
+
Use the `debug_logger` option to set an IO-like object that VCR will log
|
|
5
|
+
debug output to. This is a useful way to troubleshoot what VCR is doing.
|
|
6
|
+
|
|
7
|
+
The debug logger must respond to `#puts`.
|
|
8
|
+
|
|
9
|
+
Scenario: Use the debug logger for troubleshooting
|
|
10
|
+
Given a file named "debug_logger.rb" with:
|
|
11
|
+
"""ruby
|
|
12
|
+
if ARGV.include?('--with-server')
|
|
13
|
+
$server = start_sinatra_app do
|
|
14
|
+
get('/') { "Hello World" }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
require 'vcr'
|
|
19
|
+
|
|
20
|
+
VCR.configure do |c|
|
|
21
|
+
c.hook_into :webmock
|
|
22
|
+
c.cassette_library_dir = 'cassettes'
|
|
23
|
+
c.debug_logger = File.open(ARGV.first, 'w')
|
|
24
|
+
c.default_cassette_options = {
|
|
25
|
+
:match_requests_on => [:method, :host, :path]
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
VCR.use_cassette('example') do
|
|
30
|
+
port = $server ? $server.port : 7777
|
|
31
|
+
Net::HTTP.get_response(URI("http://localhost:#{port}/"))
|
|
32
|
+
end
|
|
33
|
+
"""
|
|
34
|
+
When I run `ruby debug_logger.rb record.log --with-server`
|
|
35
|
+
Given that port numbers in "record.log" are normalized to "7777"
|
|
36
|
+
Then the file "record.log" should contain exactly:
|
|
37
|
+
"""
|
|
38
|
+
[Cassette: 'example'] Initialized with options: {:record=>:once, :match_requests_on=>[:method, :host, :path], :allow_unused_http_interactions=>true, :serialize_with=>:yaml, :persist_with=>:file_system}
|
|
39
|
+
[webmock] Handling request: [get http://localhost:7777/] (disabled: false)
|
|
40
|
+
[Cassette: 'example'] Initialized HTTPInteractionList with request matchers [:method, :host, :path] and 0 interaction(s): { }
|
|
41
|
+
[webmock] Identified request type (recordable) for [get http://localhost:7777/]
|
|
42
|
+
[Cassette: 'example'] Recorded HTTP interaction [get http://localhost:7777/] => [200 "Hello World"]
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
When I run `ruby debug_logger.rb playback.log`
|
|
46
|
+
Given that port numbers in "playback.log" are normalized to "7777"
|
|
47
|
+
Then the file "playback.log" should contain exactly:
|
|
48
|
+
"""
|
|
49
|
+
[Cassette: 'example'] Initialized with options: {:record=>:once, :match_requests_on=>[:method, :host, :path], :allow_unused_http_interactions=>true, :serialize_with=>:yaml, :persist_with=>:file_system}
|
|
50
|
+
[webmock] Handling request: [get http://localhost:7777/] (disabled: false)
|
|
51
|
+
[Cassette: 'example'] Initialized HTTPInteractionList with request matchers [:method, :host, :path] and 1 interaction(s): { [get http://localhost:7777/] => [200 "Hello World"] }
|
|
52
|
+
[Cassette: 'example'] Checking if [get http://localhost:7777/] matches [get http://localhost:7777/] using [:method, :host, :path]
|
|
53
|
+
[Cassette: 'example'] method (matched): current request [get http://localhost:7777/] vs [get http://localhost:7777/]
|
|
54
|
+
[Cassette: 'example'] host (matched): current request [get http://localhost:7777/] vs [get http://localhost:7777/]
|
|
55
|
+
[Cassette: 'example'] path (matched): current request [get http://localhost:7777/] vs [get http://localhost:7777/]
|
|
56
|
+
[Cassette: 'example'] Found matching interaction for [get http://localhost:7777/] at index 0: [200 "Hello World"]
|
|
57
|
+
[webmock] Identified request type (stubbed_by_vcr) for [get http://localhost:7777/]
|
|
58
|
+
|
|
59
|
+
"""
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
Feature: default_cassette_options
|
|
2
|
+
|
|
3
|
+
The `default_cassette_options` configuration option takes a hash
|
|
4
|
+
that provides defaults for each cassette you use. Any cassette
|
|
5
|
+
can override the defaults as well as set additional options.
|
|
6
|
+
|
|
7
|
+
The `:match_requests_on` option defaults to `[:method, :uri]` when
|
|
8
|
+
it has not been set.
|
|
9
|
+
|
|
10
|
+
The `:record` option defaults to `:once` when it has not been set.
|
|
11
|
+
|
|
12
|
+
Background:
|
|
13
|
+
Given a file named "vcr_setup.rb" with:
|
|
14
|
+
"""ruby
|
|
15
|
+
require 'vcr'
|
|
16
|
+
|
|
17
|
+
VCR.configure do |c|
|
|
18
|
+
c.default_cassette_options = { :record => :new_episodes, :erb => true }
|
|
19
|
+
|
|
20
|
+
# not important for this example, but must be set to something
|
|
21
|
+
c.hook_into :webmock
|
|
22
|
+
c.cassette_library_dir = 'cassettes'
|
|
23
|
+
end
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
Scenario: cassettes get default values from configured `default_cassette_options`
|
|
27
|
+
Given a file named "default_cassette_options.rb" with:
|
|
28
|
+
"""ruby
|
|
29
|
+
require 'vcr_setup.rb'
|
|
30
|
+
|
|
31
|
+
VCR.use_cassette('example') do
|
|
32
|
+
puts "Record Mode: #{VCR.current_cassette.record_mode}"
|
|
33
|
+
puts "ERB: #{VCR.current_cassette.erb}"
|
|
34
|
+
end
|
|
35
|
+
"""
|
|
36
|
+
When I run `ruby default_cassette_options.rb`
|
|
37
|
+
Then the output should contain:
|
|
38
|
+
"""
|
|
39
|
+
Record Mode: new_episodes
|
|
40
|
+
ERB: true
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
Scenario: `:match_requests_on` defaults to `[:method, :uri]` when it has not been set
|
|
44
|
+
Given a file named "default_cassette_options.rb" with:
|
|
45
|
+
"""ruby
|
|
46
|
+
require 'vcr_setup.rb'
|
|
47
|
+
|
|
48
|
+
VCR.use_cassette('example') do
|
|
49
|
+
puts "Match Requests On: #{VCR.current_cassette.match_requests_on.inspect}"
|
|
50
|
+
end
|
|
51
|
+
"""
|
|
52
|
+
When I run `ruby default_cassette_options.rb`
|
|
53
|
+
Then the output should contain "Match Requests On: [:method, :uri]"
|
|
54
|
+
|
|
55
|
+
Scenario: `:record` defaults to `:once` when it has not been set
|
|
56
|
+
Given a file named "default_record_mode.rb" with:
|
|
57
|
+
"""ruby
|
|
58
|
+
require 'vcr'
|
|
59
|
+
|
|
60
|
+
VCR.configure do |c|
|
|
61
|
+
# not important for this example, but must be set to something
|
|
62
|
+
c.hook_into :webmock
|
|
63
|
+
c.cassette_library_dir = 'cassettes'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
VCR.use_cassette('example') do
|
|
67
|
+
puts "Record mode: #{VCR.current_cassette.record_mode.inspect}"
|
|
68
|
+
end
|
|
69
|
+
"""
|
|
70
|
+
When I run `ruby default_record_mode.rb`
|
|
71
|
+
Then the output should contain "Record mode: :once"
|
|
72
|
+
|
|
73
|
+
Scenario: cassettes can set their own options
|
|
74
|
+
Given a file named "default_cassette_options.rb" with:
|
|
75
|
+
"""ruby
|
|
76
|
+
require 'vcr_setup.rb'
|
|
77
|
+
|
|
78
|
+
VCR.use_cassette('example', :re_record_interval => 10000) do
|
|
79
|
+
puts "Re-record Interval: #{VCR.current_cassette.re_record_interval}"
|
|
80
|
+
end
|
|
81
|
+
"""
|
|
82
|
+
When I run `ruby default_cassette_options.rb`
|
|
83
|
+
Then the output should contain "Re-record Interval: 10000"
|
|
84
|
+
|
|
85
|
+
Scenario: cassettes can override default options
|
|
86
|
+
Given a file named "default_cassette_options.rb" with:
|
|
87
|
+
"""ruby
|
|
88
|
+
require 'vcr_setup.rb'
|
|
89
|
+
|
|
90
|
+
VCR.use_cassette('example', :record => :none, :erb => false) do
|
|
91
|
+
puts "Record Mode: #{VCR.current_cassette.record_mode}"
|
|
92
|
+
puts "ERB: #{VCR.current_cassette.erb}"
|
|
93
|
+
end
|
|
94
|
+
"""
|
|
95
|
+
When I run `ruby default_cassette_options.rb`
|
|
96
|
+
Then the output should contain:
|
|
97
|
+
"""
|
|
98
|
+
Record Mode: none
|
|
99
|
+
ERB: false
|
|
100
|
+
"""
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Feature: Filter sensitive data
|
|
2
|
+
|
|
3
|
+
Note: this config option is also available as `define_cassette_placeholder`
|
|
4
|
+
to reflect the fact that it is useful for more than just sensitive data.
|
|
5
|
+
|
|
6
|
+
The `filter_sensitive_data` configuration option can be used to prevent
|
|
7
|
+
sensitive data from being written to your cassette files. This may be
|
|
8
|
+
important if you commit your cassettes files to source control and do
|
|
9
|
+
not want your sensitive data exposed. Pass the following arguments to
|
|
10
|
+
`filter_sensitive_data`:
|
|
11
|
+
|
|
12
|
+
- A substitution string. This is the string that will be written to
|
|
13
|
+
the cassettte file as a placeholder. It should be unique and you
|
|
14
|
+
may want to wrap it in special characters like `{ }` or `< >`.
|
|
15
|
+
- A symbol specifying a tag (optional). If a tag is given, the
|
|
16
|
+
filtering will only be applied to cassettes with the given tag.
|
|
17
|
+
- A block. The block should return the sensitive text that you want
|
|
18
|
+
replaced with the substitution string. If your block accepts an
|
|
19
|
+
argument, the HTTP interaction will be yielded so that you can
|
|
20
|
+
dynamically specify the sensitive text based on the interaction
|
|
21
|
+
(see the last scenario for an example of this).
|
|
22
|
+
|
|
23
|
+
When the interactions are replayed, the sensitive text will replace the
|
|
24
|
+
substitution string so that the interaction will be identical to what was
|
|
25
|
+
originally recorded.
|
|
26
|
+
|
|
27
|
+
You can specify as many filterings as you want.
|
|
28
|
+
|
|
29
|
+
Scenario: Multiple filterings
|
|
30
|
+
Given a file named "filtering.rb" with:
|
|
31
|
+
"""ruby
|
|
32
|
+
if ARGV.include?('--with-server')
|
|
33
|
+
$server = start_sinatra_app do
|
|
34
|
+
get('/') { "Hello World" }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
require 'vcr'
|
|
39
|
+
|
|
40
|
+
VCR.configure do |c|
|
|
41
|
+
c.hook_into :webmock
|
|
42
|
+
c.cassette_library_dir = 'cassettes'
|
|
43
|
+
c.filter_sensitive_data('<GREETING>') { 'Hello' }
|
|
44
|
+
c.filter_sensitive_data('<LOCATION>') { 'World' }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
VCR.use_cassette('filtering') do
|
|
48
|
+
response = Net::HTTP.get_response('localhost', '/', $server ? $server.port : 0)
|
|
49
|
+
puts "Response: #{response.body}"
|
|
50
|
+
end
|
|
51
|
+
"""
|
|
52
|
+
When I run `ruby filtering.rb --with-server`
|
|
53
|
+
Then the output should contain "Response: Hello World"
|
|
54
|
+
And the file "cassettes/filtering.yml" should contain "<GREETING> <LOCATION>"
|
|
55
|
+
And the file "cassettes/filtering.yml" should not contain "Hello"
|
|
56
|
+
And the file "cassettes/filtering.yml" should not contain "World"
|
|
57
|
+
|
|
58
|
+
When I run `ruby filtering.rb`
|
|
59
|
+
Then the output should contain "Hello World"
|
|
60
|
+
|
|
61
|
+
Scenario: Filter tagged cassettes
|
|
62
|
+
Given a file named "tagged_filtering.rb" with:
|
|
63
|
+
"""ruby
|
|
64
|
+
if ARGV.include?('--with-server')
|
|
65
|
+
response_count = 0
|
|
66
|
+
$server = start_sinatra_app do
|
|
67
|
+
get('/') { "Hello World #{response_count += 1 }" }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
require 'vcr'
|
|
72
|
+
|
|
73
|
+
VCR.configure do |c|
|
|
74
|
+
c.hook_into :webmock
|
|
75
|
+
c.cassette_library_dir = 'cassettes'
|
|
76
|
+
c.filter_sensitive_data('<LOCATION>', :my_tag) { 'World' }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
VCR.use_cassette('tagged', :tag => :my_tag) do
|
|
80
|
+
response = Net::HTTP.get_response('localhost', '/', $server ? $server.port : 0)
|
|
81
|
+
puts "Tagged Response: #{response.body}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
VCR.use_cassette('untagged', :record => :new_episodes) do
|
|
85
|
+
response = Net::HTTP.get_response('localhost', '/', $server ? $server.port : 0)
|
|
86
|
+
puts "Untagged Response: #{response.body}"
|
|
87
|
+
end
|
|
88
|
+
"""
|
|
89
|
+
When I run `ruby tagged_filtering.rb --with-server`
|
|
90
|
+
Then the output should contain each of the following:
|
|
91
|
+
| Tagged Response: Hello World 1 |
|
|
92
|
+
| Untagged Response: Hello World 2 |
|
|
93
|
+
And the file "cassettes/tagged.yml" should contain "Hello <LOCATION> 1"
|
|
94
|
+
And the file "cassettes/untagged.yml" should contain "Hello World 2"
|
|
95
|
+
|
|
96
|
+
When I run `ruby tagged_filtering.rb`
|
|
97
|
+
Then the output should contain each of the following:
|
|
98
|
+
| Tagged Response: Hello World 1 |
|
|
99
|
+
| Untagged Response: Hello World 2 |
|
|
100
|
+
|
|
101
|
+
Scenario: Filter dynamic data based on yielded HTTP interaction
|
|
102
|
+
Given a file named "dynamic_filtering.rb" with:
|
|
103
|
+
"""ruby
|
|
104
|
+
include_http_adapter_for('net/http')
|
|
105
|
+
|
|
106
|
+
if ARGV.include?('--with-server')
|
|
107
|
+
$server = start_sinatra_app do
|
|
108
|
+
helpers do
|
|
109
|
+
def request_header_for(header_key_fragment)
|
|
110
|
+
key = env.keys.find { |k| k =~ /#{header_key_fragment}/i }
|
|
111
|
+
env[key]
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
get('/') { "#{request_header_for('username')}/#{request_header_for('password')}" }
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
require 'vcr'
|
|
120
|
+
|
|
121
|
+
USER_PASSWORDS = {
|
|
122
|
+
'john.doe' => 'monkey',
|
|
123
|
+
'jane.doe' => 'cheetah'
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
VCR.configure do |c|
|
|
127
|
+
c.hook_into :webmock
|
|
128
|
+
c.cassette_library_dir = 'cassettes'
|
|
129
|
+
c.filter_sensitive_data('<PASSWORD>') do |interaction|
|
|
130
|
+
USER_PASSWORDS[interaction.request.headers['X-Http-Username'].first]
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
VCR.use_cassette('example', :match_requests_on => [:method, :uri, :headers]) do
|
|
135
|
+
port = $server ? $server.port : 0
|
|
136
|
+
puts "Response: " + response_body_for(
|
|
137
|
+
:get, "http://localhost:#{port}/", nil,
|
|
138
|
+
'X-Http-Username' => 'john.doe',
|
|
139
|
+
'X-Http-Password' => USER_PASSWORDS['john.doe']
|
|
140
|
+
)
|
|
141
|
+
end
|
|
142
|
+
"""
|
|
143
|
+
When I run `ruby dynamic_filtering.rb --with-server`
|
|
144
|
+
Then the output should contain "john.doe/monkey"
|
|
145
|
+
And the file "cassettes/example.yml" should contain "john.doe/<PASSWORD>"
|
|
146
|
+
And the file "cassettes/example.yml" should contain a YAML fragment like:
|
|
147
|
+
"""
|
|
148
|
+
X-Http-Password:
|
|
149
|
+
- <PASSWORD>
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
When I run `ruby dynamic_filtering.rb`
|
|
153
|
+
Then the output should contain "john.doe/monkey"
|