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