oso-cloud 1.8.0 → 1.9.1.pre.vendored.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.
Files changed (113) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +31 -12
  5. data/README.md +1 -1
  6. data/lib/oso/api.rb +18 -2
  7. data/lib/oso/oso.rb +10 -7
  8. data/lib/oso/version.rb +1 -1
  9. data/vendor/gems/faraday-2.5.2/CHANGELOG.md +574 -0
  10. data/vendor/gems/faraday-2.5.2/LICENSE.md +20 -0
  11. data/vendor/gems/faraday-2.5.2/README.md +55 -0
  12. data/vendor/gems/faraday-2.5.2/Rakefile +7 -0
  13. data/vendor/gems/faraday-2.5.2/examples/client_spec.rb +119 -0
  14. data/vendor/gems/faraday-2.5.2/examples/client_test.rb +144 -0
  15. data/vendor/gems/faraday-2.5.2/lib/faraday/adapter/test.rb +298 -0
  16. data/vendor/gems/faraday-2.5.2/lib/faraday/adapter.rb +102 -0
  17. data/vendor/gems/faraday-2.5.2/lib/faraday/adapter_registry.rb +30 -0
  18. data/vendor/gems/faraday-2.5.2/lib/faraday/connection.rb +561 -0
  19. data/vendor/gems/faraday-2.5.2/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  20. data/vendor/gems/faraday-2.5.2/lib/faraday/encoders/nested_params_encoder.rb +183 -0
  21. data/vendor/gems/faraday-2.5.2/lib/faraday/error.rb +147 -0
  22. data/vendor/gems/faraday-2.5.2/lib/faraday/logging/formatter.rb +106 -0
  23. data/vendor/gems/faraday-2.5.2/lib/faraday/methods.rb +6 -0
  24. data/vendor/gems/faraday-2.5.2/lib/faraday/middleware.rb +30 -0
  25. data/vendor/gems/faraday-2.5.2/lib/faraday/middleware_registry.rb +83 -0
  26. data/vendor/gems/faraday-2.5.2/lib/faraday/options/connection_options.rb +22 -0
  27. data/vendor/gems/faraday-2.5.2/lib/faraday/options/env.rb +199 -0
  28. data/vendor/gems/faraday-2.5.2/lib/faraday/options/proxy_options.rb +32 -0
  29. data/vendor/gems/faraday-2.5.2/lib/faraday/options/request_options.rb +22 -0
  30. data/vendor/gems/faraday-2.5.2/lib/faraday/options/ssl_options.rb +69 -0
  31. data/vendor/gems/faraday-2.5.2/lib/faraday/options.rb +218 -0
  32. data/vendor/gems/faraday-2.5.2/lib/faraday/parameters.rb +5 -0
  33. data/vendor/gems/faraday-2.5.2/lib/faraday/rack_builder.rb +252 -0
  34. data/vendor/gems/faraday-2.5.2/lib/faraday/request/authorization.rb +49 -0
  35. data/vendor/gems/faraday-2.5.2/lib/faraday/request/instrumentation.rb +56 -0
  36. data/vendor/gems/faraday-2.5.2/lib/faraday/request/json.rb +55 -0
  37. data/vendor/gems/faraday-2.5.2/lib/faraday/request/url_encoded.rb +60 -0
  38. data/vendor/gems/faraday-2.5.2/lib/faraday/request.rb +136 -0
  39. data/vendor/gems/faraday-2.5.2/lib/faraday/response/json.rb +54 -0
  40. data/vendor/gems/faraday-2.5.2/lib/faraday/response/logger.rb +33 -0
  41. data/vendor/gems/faraday-2.5.2/lib/faraday/response/raise_error.rb +64 -0
  42. data/vendor/gems/faraday-2.5.2/lib/faraday/response.rb +90 -0
  43. data/vendor/gems/faraday-2.5.2/lib/faraday/utils/headers.rb +139 -0
  44. data/vendor/gems/faraday-2.5.2/lib/faraday/utils/params_hash.rb +61 -0
  45. data/vendor/gems/faraday-2.5.2/lib/faraday/utils.rb +122 -0
  46. data/vendor/gems/faraday-2.5.2/lib/faraday/version.rb +5 -0
  47. data/vendor/gems/faraday-2.5.2/lib/faraday.rb +157 -0
  48. data/vendor/gems/faraday-2.5.2/spec/external_adapters/faraday_specs_setup.rb +14 -0
  49. data/vendor/gems/faraday-2.5.2/spec/faraday/adapter/test_spec.rb +413 -0
  50. data/vendor/gems/faraday-2.5.2/spec/faraday/adapter_registry_spec.rb +28 -0
  51. data/vendor/gems/faraday-2.5.2/spec/faraday/adapter_spec.rb +55 -0
  52. data/vendor/gems/faraday-2.5.2/spec/faraday/connection_spec.rb +793 -0
  53. data/vendor/gems/faraday-2.5.2/spec/faraday/error_spec.rb +60 -0
  54. data/vendor/gems/faraday-2.5.2/spec/faraday/middleware_registry_spec.rb +31 -0
  55. data/vendor/gems/faraday-2.5.2/spec/faraday/middleware_spec.rb +52 -0
  56. data/vendor/gems/faraday-2.5.2/spec/faraday/options/env_spec.rb +76 -0
  57. data/vendor/gems/faraday-2.5.2/spec/faraday/options/options_spec.rb +297 -0
  58. data/vendor/gems/faraday-2.5.2/spec/faraday/options/proxy_options_spec.rb +44 -0
  59. data/vendor/gems/faraday-2.5.2/spec/faraday/options/request_options_spec.rb +19 -0
  60. data/vendor/gems/faraday-2.5.2/spec/faraday/params_encoders/flat_spec.rb +42 -0
  61. data/vendor/gems/faraday-2.5.2/spec/faraday/params_encoders/nested_spec.rb +150 -0
  62. data/vendor/gems/faraday-2.5.2/spec/faraday/rack_builder_spec.rb +317 -0
  63. data/vendor/gems/faraday-2.5.2/spec/faraday/request/authorization_spec.rb +83 -0
  64. data/vendor/gems/faraday-2.5.2/spec/faraday/request/instrumentation_spec.rb +74 -0
  65. data/vendor/gems/faraday-2.5.2/spec/faraday/request/json_spec.rb +111 -0
  66. data/vendor/gems/faraday-2.5.2/spec/faraday/request/url_encoded_spec.rb +93 -0
  67. data/vendor/gems/faraday-2.5.2/spec/faraday/request_spec.rb +110 -0
  68. data/vendor/gems/faraday-2.5.2/spec/faraday/response/json_spec.rb +117 -0
  69. data/vendor/gems/faraday-2.5.2/spec/faraday/response/logger_spec.rb +220 -0
  70. data/vendor/gems/faraday-2.5.2/spec/faraday/response/raise_error_spec.rb +172 -0
  71. data/vendor/gems/faraday-2.5.2/spec/faraday/response_spec.rb +75 -0
  72. data/vendor/gems/faraday-2.5.2/spec/faraday/utils/headers_spec.rb +82 -0
  73. data/vendor/gems/faraday-2.5.2/spec/faraday/utils_spec.rb +118 -0
  74. data/vendor/gems/faraday-2.5.2/spec/faraday_spec.rb +37 -0
  75. data/vendor/gems/faraday-2.5.2/spec/spec_helper.rb +132 -0
  76. data/vendor/gems/faraday-2.5.2/spec/support/disabling_stub.rb +14 -0
  77. data/vendor/gems/faraday-2.5.2/spec/support/fake_safe_buffer.rb +15 -0
  78. data/vendor/gems/faraday-2.5.2/spec/support/helper_methods.rb +96 -0
  79. data/vendor/gems/faraday-2.5.2/spec/support/shared_examples/adapter.rb +105 -0
  80. data/vendor/gems/faraday-2.5.2/spec/support/shared_examples/params_encoder.rb +18 -0
  81. data/vendor/gems/faraday-2.5.2/spec/support/shared_examples/request_method.rb +263 -0
  82. data/vendor/gems/faraday-2.5.2/spec/support/streaming_response_checker.rb +35 -0
  83. data/vendor/gems/faraday-net_http-3.0.2/LICENSE.md +21 -0
  84. data/vendor/gems/faraday-net_http-3.0.2/README.md +57 -0
  85. data/vendor/gems/faraday-net_http-3.0.2/lib/faraday/adapter/net_http.rb +208 -0
  86. data/vendor/gems/faraday-net_http-3.0.2/lib/faraday/net_http/version.rb +7 -0
  87. data/vendor/gems/faraday-net_http-3.0.2/lib/faraday/net_http.rb +10 -0
  88. data/vendor/gems/faraday-net_http_persistent-2.3.0/LICENSE.md +21 -0
  89. data/vendor/gems/faraday-net_http_persistent-2.3.0/README.md +66 -0
  90. data/vendor/gems/faraday-net_http_persistent-2.3.0/lib/faraday/adapter/net_http_persistent.rb +234 -0
  91. data/vendor/gems/faraday-net_http_persistent-2.3.0/lib/faraday/net_http_persistent/version.rb +7 -0
  92. data/vendor/gems/faraday-net_http_persistent-2.3.0/lib/faraday/net_http_persistent.rb +18 -0
  93. data/vendor/gems/faraday-retry-2.0.0/CHANGELOG.md +24 -0
  94. data/vendor/gems/faraday-retry-2.0.0/LICENSE.md +21 -0
  95. data/vendor/gems/faraday-retry-2.0.0/README.md +169 -0
  96. data/vendor/gems/faraday-retry-2.0.0/lib/faraday/retriable_response.rb +8 -0
  97. data/vendor/gems/faraday-retry-2.0.0/lib/faraday/retry/middleware.rb +254 -0
  98. data/vendor/gems/faraday-retry-2.0.0/lib/faraday/retry/version.rb +7 -0
  99. data/vendor/gems/faraday-retry-2.0.0/lib/faraday/retry.rb +13 -0
  100. data/vendor/gems/net-http-persistent-4.0.5/.autotest +9 -0
  101. data/vendor/gems/net-http-persistent-4.0.5/.gemtest +0 -0
  102. data/vendor/gems/net-http-persistent-4.0.5/Gemfile +14 -0
  103. data/vendor/gems/net-http-persistent-4.0.5/History.txt +460 -0
  104. data/vendor/gems/net-http-persistent-4.0.5/Manifest.txt +13 -0
  105. data/vendor/gems/net-http-persistent-4.0.5/README.rdoc +82 -0
  106. data/vendor/gems/net-http-persistent-4.0.5/Rakefile +25 -0
  107. data/vendor/gems/net-http-persistent-4.0.5/lib/net/http/persistent/connection.rb +41 -0
  108. data/vendor/gems/net-http-persistent-4.0.5/lib/net/http/persistent/pool.rb +65 -0
  109. data/vendor/gems/net-http-persistent-4.0.5/lib/net/http/persistent/timed_stack_multi.rb +79 -0
  110. data/vendor/gems/net-http-persistent-4.0.5/lib/net/http/persistent.rb +1158 -0
  111. data/vendor/gems/net-http-persistent-4.0.5/test/test_net_http_persistent.rb +1512 -0
  112. data/vendor/gems/net-http-persistent-4.0.5/test/test_net_http_persistent_timed_stack_multi.rb +151 -0
  113. metadata +112 -8
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Requires Ruby with rspec and faraday gems.
4
+ # rspec client_spec.rb
5
+
6
+ require 'faraday'
7
+ require 'json'
8
+
9
+ # Example API client
10
+ class Client
11
+ def initialize(conn)
12
+ @conn = conn
13
+ end
14
+
15
+ def httpbingo(jname, params: {})
16
+ res = @conn.get("/#{jname}", params)
17
+ data = JSON.parse(res.body)
18
+ data['origin']
19
+ end
20
+
21
+ def foo(params)
22
+ res = @conn.post('/foo', JSON.dump(params))
23
+ res.status
24
+ end
25
+ end
26
+
27
+ RSpec.describe Client do
28
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
29
+ let(:conn) { Faraday.new { |b| b.adapter(:test, stubs) } }
30
+ let(:client) { Client.new(conn) }
31
+
32
+ it 'parses origin' do
33
+ stubs.get('/ip') do |env|
34
+ # optional: you can inspect the Faraday::Env
35
+ expect(env.url.path).to eq('/ip')
36
+ [
37
+ 200,
38
+ { 'Content-Type': 'application/javascript' },
39
+ '{"origin": "127.0.0.1"}'
40
+ ]
41
+ end
42
+
43
+ # uncomment to trigger stubs.verify_stubbed_calls failure
44
+ # stubs.get('/unused') { [404, {}, ''] }
45
+
46
+ expect(client.httpbingo('ip')).to eq('127.0.0.1')
47
+ stubs.verify_stubbed_calls
48
+ end
49
+
50
+ it 'handles 404' do
51
+ stubs.get('/api') do
52
+ [
53
+ 404,
54
+ { 'Content-Type': 'application/javascript' },
55
+ '{}'
56
+ ]
57
+ end
58
+ expect(client.httpbingo('api')).to be_nil
59
+ stubs.verify_stubbed_calls
60
+ end
61
+
62
+ it 'handles exception' do
63
+ stubs.get('/api') do
64
+ raise Faraday::ConnectionFailed
65
+ end
66
+
67
+ expect { client.httpbingo('api') }.to raise_error(Faraday::ConnectionFailed)
68
+ stubs.verify_stubbed_calls
69
+ end
70
+
71
+ context 'When the test stub is run in strict_mode' do
72
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new(strict_mode: true) }
73
+
74
+ it 'verifies the all parameter values are identical' do
75
+ stubs.get('/api?abc=123') do
76
+ [
77
+ 200,
78
+ { 'Content-Type': 'application/javascript' },
79
+ '{"origin": "127.0.0.1"}'
80
+ ]
81
+ end
82
+
83
+ # uncomment to raise Stubs::NotFound
84
+ # expect(client.httpbingo('api', params: { abc: 123, foo: 'Kappa' })).to eq('127.0.0.1')
85
+ expect(client.httpbingo('api', params: { abc: 123 })).to eq('127.0.0.1')
86
+ stubs.verify_stubbed_calls
87
+ end
88
+ end
89
+
90
+ context 'When the Faraday connection is configured with FlatParamsEncoder' do
91
+ let(:conn) { Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) { |b| b.adapter(:test, stubs) } }
92
+
93
+ it 'handles the same multiple URL parameters' do
94
+ stubs.get('/api?a=x&a=y&a=z') { [200, { 'Content-Type' => 'application/json' }, '{"origin": "127.0.0.1"}'] }
95
+
96
+ # uncomment to raise Stubs::NotFound
97
+ # expect(client.httpbingo('api', params: { a: %w[x y] })).to eq('127.0.0.1')
98
+ expect(client.httpbingo('api', params: { a: %w[x y z] })).to eq('127.0.0.1')
99
+ stubs.verify_stubbed_calls
100
+ end
101
+ end
102
+
103
+ context 'When you want to test the body, you can use a proc as well as string' do
104
+ it 'tests with a string' do
105
+ stubs.post('/foo', '{"name":"YK"}') { [200, {}, ''] }
106
+
107
+ expect(client.foo(name: 'YK')).to eq 200
108
+ stubs.verify_stubbed_calls
109
+ end
110
+
111
+ it 'tests with a proc' do
112
+ check = ->(request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }
113
+ stubs.post('/foo', check) { [200, {}, ''] }
114
+
115
+ expect(client.foo(name: 'YK', created_at: Time.now)).to eq 200
116
+ stubs.verify_stubbed_calls
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Requires Ruby with test-unit and faraday gems.
4
+ # ruby client_test.rb
5
+
6
+ require 'faraday'
7
+ require 'json'
8
+ require 'test/unit'
9
+
10
+ # Example API client
11
+ class Client
12
+ def initialize(conn)
13
+ @conn = conn
14
+ end
15
+
16
+ def httpbingo(jname, params: {})
17
+ res = @conn.get("/#{jname}", params)
18
+ data = JSON.parse(res.body)
19
+ data['origin']
20
+ end
21
+
22
+ def foo(params)
23
+ res = @conn.post('/foo', JSON.dump(params))
24
+ res.status
25
+ end
26
+ end
27
+
28
+ # Example API client test
29
+ class ClientTest < Test::Unit::TestCase
30
+ def test_httpbingo_name
31
+ stubs = Faraday::Adapter::Test::Stubs.new
32
+ stubs.get('/api') do |env|
33
+ # optional: you can inspect the Faraday::Env
34
+ assert_equal '/api', env.url.path
35
+ [
36
+ 200,
37
+ { 'Content-Type': 'application/javascript' },
38
+ '{"origin": "127.0.0.1"}'
39
+ ]
40
+ end
41
+
42
+ # uncomment to trigger stubs.verify_stubbed_calls failure
43
+ # stubs.get('/unused') { [404, {}, ''] }
44
+
45
+ cli = client(stubs)
46
+ assert_equal '127.0.0.1', cli.httpbingo('api')
47
+ stubs.verify_stubbed_calls
48
+ end
49
+
50
+ def test_httpbingo_not_found
51
+ stubs = Faraday::Adapter::Test::Stubs.new
52
+ stubs.get('/api') do
53
+ [
54
+ 404,
55
+ { 'Content-Type': 'application/javascript' },
56
+ '{}'
57
+ ]
58
+ end
59
+
60
+ cli = client(stubs)
61
+ assert_nil cli.httpbingo('api')
62
+ stubs.verify_stubbed_calls
63
+ end
64
+
65
+ def test_httpbingo_exception
66
+ stubs = Faraday::Adapter::Test::Stubs.new
67
+ stubs.get('/api') do
68
+ raise Faraday::ConnectionFailed
69
+ end
70
+
71
+ cli = client(stubs)
72
+ assert_raise Faraday::ConnectionFailed do
73
+ cli.httpbingo('api')
74
+ end
75
+ stubs.verify_stubbed_calls
76
+ end
77
+
78
+ def test_strict_mode
79
+ stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
80
+ stubs.get('/api?abc=123') do
81
+ [
82
+ 200,
83
+ { 'Content-Type': 'application/javascript' },
84
+ '{"origin": "127.0.0.1"}'
85
+ ]
86
+ end
87
+
88
+ cli = client(stubs)
89
+ assert_equal '127.0.0.1', cli.httpbingo('api', params: { abc: 123 })
90
+
91
+ # uncomment to raise Stubs::NotFound
92
+ # assert_equal '127.0.0.1', cli.httpbingo('api', params: { abc: 123, foo: 'Kappa' })
93
+ stubs.verify_stubbed_calls
94
+ end
95
+
96
+ def test_non_default_params_encoder
97
+ stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true)
98
+ stubs.get('/api?a=x&a=y&a=z') do
99
+ [
100
+ 200,
101
+ { 'Content-Type': 'application/javascript' },
102
+ '{"origin": "127.0.0.1"}'
103
+ ]
104
+ end
105
+ conn = Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder|
106
+ builder.adapter :test, stubs
107
+ end
108
+
109
+ cli = Client.new(conn)
110
+ assert_equal '127.0.0.1', cli.httpbingo('api', params: { a: %w[x y z] })
111
+
112
+ # uncomment to raise Stubs::NotFound
113
+ # assert_equal '127.0.0.1', cli.httpbingo('api', params: { a: %w[x y] })
114
+ stubs.verify_stubbed_calls
115
+ end
116
+
117
+ def test_with_string_body
118
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
119
+ stub.post('/foo', '{"name":"YK"}') { [200, {}, ''] }
120
+ end
121
+ cli = client(stubs)
122
+ assert_equal 200, cli.foo(name: 'YK')
123
+
124
+ stubs.verify_stubbed_calls
125
+ end
126
+
127
+ def test_with_proc_body
128
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
129
+ check = ->(request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }
130
+ stub.post('/foo', check) { [200, {}, ''] }
131
+ end
132
+ cli = client(stubs)
133
+ assert_equal 200, cli.foo(name: 'YK', created_at: Time.now)
134
+
135
+ stubs.verify_stubbed_calls
136
+ end
137
+
138
+ def client(stubs)
139
+ conn = Faraday.new do |builder|
140
+ builder.adapter :test, stubs
141
+ end
142
+ Client.new(conn)
143
+ end
144
+ end
@@ -0,0 +1,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ class Adapter
5
+ # @example
6
+ # test = Faraday::Connection.new do
7
+ # use Faraday::Adapter::Test do |stub|
8
+ # # Define matcher to match the request
9
+ # stub.get '/resource.json' do
10
+ # # return static content
11
+ # [200, {'Content-Type' => 'application/json'}, 'hi world']
12
+ # end
13
+ #
14
+ # # response with content generated based on request
15
+ # stub.get '/showget' do |env|
16
+ # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
17
+ # end
18
+ #
19
+ # # A regular expression can be used as matching filter
20
+ # stub.get /\A\/items\/(\d+)\z/ do |env, meta|
21
+ # # in case regular expression is used, an instance of MatchData
22
+ # # can be received
23
+ # [200,
24
+ # {'Content-Type' => 'text/plain'},
25
+ # "showing item: #{meta[:match_data][1]}"
26
+ # ]
27
+ # end
28
+ #
29
+ # # Test the request body is the same as the stubbed body
30
+ # stub.post('/bar', 'name=YK&word=call') { [200, {}, ''] }
31
+ #
32
+ # # You can pass a proc as a stubbed body and check the request body in your way.
33
+ # # In this case, the proc should return true or false.
34
+ # stub.post('/foo', ->(request_body) do
35
+ # JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }) { [200, {}, '']
36
+ # end
37
+ #
38
+ # # You can set strict_mode to exactly match the stubbed requests.
39
+ # stub.strict_mode = true
40
+ # end
41
+ # end
42
+ #
43
+ # resp = test.get '/resource.json'
44
+ # resp.body # => 'hi world'
45
+ #
46
+ # resp = test.get '/showget'
47
+ # resp.body # => 'get'
48
+ #
49
+ # resp = test.get '/items/1'
50
+ # resp.body # => 'showing item: 1'
51
+ #
52
+ # resp = test.get '/items/2'
53
+ # resp.body # => 'showing item: 2'
54
+ #
55
+ # resp = test.post '/bar', 'name=YK&word=call'
56
+ # resp.status # => 200
57
+ #
58
+ # resp = test.post '/foo', JSON.dump(name: 'YK', created_at: Time.now)
59
+ # resp.status # => 200
60
+ class Test < Faraday::Adapter
61
+ attr_accessor :stubs
62
+
63
+ # A stack of Stubs
64
+ class Stubs
65
+ class NotFound < StandardError
66
+ end
67
+
68
+ def initialize(strict_mode: false)
69
+ # { get: [Stub, Stub] }
70
+ @stack = {}
71
+ @consumed = {}
72
+ @strict_mode = strict_mode
73
+ @stubs_mutex = Monitor.new
74
+ yield(self) if block_given?
75
+ end
76
+
77
+ def empty?
78
+ @stack.empty?
79
+ end
80
+
81
+ # @param env [Faraday::Env]
82
+ def match(env)
83
+ request_method = env[:method]
84
+ return false unless @stack.key?(request_method)
85
+
86
+ stack = @stack[request_method]
87
+ consumed = (@consumed[request_method] ||= [])
88
+
89
+ @stubs_mutex.synchronize do
90
+ stub, meta = matches?(stack, env)
91
+ if stub
92
+ removed = stack.delete(stub)
93
+ consumed << removed unless removed.nil?
94
+ return stub, meta
95
+ end
96
+ end
97
+ matches?(consumed, env)
98
+ end
99
+
100
+ def get(path, headers = {}, &block)
101
+ new_stub(:get, path, headers, &block)
102
+ end
103
+
104
+ def head(path, headers = {}, &block)
105
+ new_stub(:head, path, headers, &block)
106
+ end
107
+
108
+ def post(path, body = nil, headers = {}, &block)
109
+ new_stub(:post, path, headers, body, &block)
110
+ end
111
+
112
+ def put(path, body = nil, headers = {}, &block)
113
+ new_stub(:put, path, headers, body, &block)
114
+ end
115
+
116
+ def patch(path, body = nil, headers = {}, &block)
117
+ new_stub(:patch, path, headers, body, &block)
118
+ end
119
+
120
+ def delete(path, headers = {}, &block)
121
+ new_stub(:delete, path, headers, &block)
122
+ end
123
+
124
+ def options(path, headers = {}, &block)
125
+ new_stub(:options, path, headers, &block)
126
+ end
127
+
128
+ # Raises an error if any of the stubbed calls have not been made.
129
+ def verify_stubbed_calls
130
+ failed_stubs = []
131
+ @stack.each do |method, stubs|
132
+ next if stubs.empty?
133
+
134
+ failed_stubs.concat(
135
+ stubs.map do |stub|
136
+ "Expected #{method} #{stub}."
137
+ end
138
+ )
139
+ end
140
+ raise failed_stubs.join(' ') unless failed_stubs.empty?
141
+ end
142
+
143
+ # Set strict_mode. If the value is true, this adapter tries to find matched requests strictly,
144
+ # which means that all of a path, parameters, and headers must be the same as an actual request.
145
+ def strict_mode=(value)
146
+ @strict_mode = value
147
+ @stack.each do |_method, stubs|
148
+ stubs.each do |stub|
149
+ stub.strict_mode = value
150
+ end
151
+ end
152
+ end
153
+
154
+ protected
155
+
156
+ def new_stub(request_method, path, headers = {}, body = nil, &block)
157
+ normalized_path, host =
158
+ if path.is_a?(Regexp)
159
+ path
160
+ else
161
+ [
162
+ Faraday::Utils.normalize_path(path),
163
+ Faraday::Utils.URI(path).host
164
+ ]
165
+ end
166
+ path, query = normalized_path.respond_to?(:split) ? normalized_path.split('?') : normalized_path
167
+ headers = Utils::Headers.new(headers)
168
+
169
+ stub = Stub.new(host, path, query, headers, body, @strict_mode, block)
170
+ (@stack[request_method] ||= []) << stub
171
+ end
172
+
173
+ # @param stack [Hash]
174
+ # @param env [Faraday::Env]
175
+ def matches?(stack, env)
176
+ stack.each do |stub|
177
+ match_result, meta = stub.matches?(env)
178
+ return stub, meta if match_result
179
+ end
180
+ nil
181
+ end
182
+ end
183
+
184
+ # Stub request
185
+ class Stub < Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) # rubocop:disable Style/StructInheritance
186
+ # @param env [Faraday::Env]
187
+ def matches?(env)
188
+ request_host = env[:url].host
189
+ request_path = Faraday::Utils.normalize_path(env[:url].path)
190
+ request_headers = env.request_headers
191
+ request_body = env[:body]
192
+
193
+ # meta is a hash used as carrier
194
+ # that will be yielded to consumer block
195
+ meta = {}
196
+ [(host.nil? || host == request_host) &&
197
+ path_match?(request_path, meta) &&
198
+ params_match?(env) &&
199
+ body_match?(request_body) &&
200
+ headers_match?(request_headers), meta]
201
+ end
202
+
203
+ def path_match?(request_path, meta)
204
+ if path.is_a?(Regexp)
205
+ !!(meta[:match_data] = path.match(request_path))
206
+ else
207
+ path == request_path
208
+ end
209
+ end
210
+
211
+ # @param env [Faraday::Env]
212
+ def params_match?(env)
213
+ request_params = env[:params]
214
+ params = env.params_encoder.decode(query) || {}
215
+
216
+ if strict_mode
217
+ return Set.new(params) == Set.new(request_params)
218
+ end
219
+
220
+ params.keys.all? do |key|
221
+ request_params[key] == params[key]
222
+ end
223
+ end
224
+
225
+ def headers_match?(request_headers)
226
+ if strict_mode
227
+ headers_with_user_agent = headers.dup.tap do |hs|
228
+ # NOTE: Set User-Agent in case it's not set when creating Stubs.
229
+ # Users would not want to set Faraday's User-Agent explicitly.
230
+ hs[:user_agent] ||= Connection::USER_AGENT
231
+ end
232
+ return Set.new(headers_with_user_agent) == Set.new(request_headers)
233
+ end
234
+
235
+ headers.keys.all? do |key|
236
+ request_headers[key] == headers[key]
237
+ end
238
+ end
239
+
240
+ def body_match?(request_body)
241
+ return true if body.to_s.size.zero?
242
+
243
+ case body
244
+ when Proc
245
+ body.call(request_body)
246
+ else
247
+ request_body == body
248
+ end
249
+ end
250
+
251
+ def to_s
252
+ "#{path} #{body}"
253
+ end
254
+ end
255
+
256
+ def initialize(app, stubs = nil, &block)
257
+ super(app)
258
+ @stubs = stubs || Stubs.new
259
+ configure(&block) if block
260
+ end
261
+
262
+ def configure
263
+ yield(stubs)
264
+ end
265
+
266
+ # @param env [Faraday::Env]
267
+ def call(env)
268
+ super
269
+
270
+ env.request.params_encoder ||= Faraday::Utils.default_params_encoder
271
+ env[:params] = env.params_encoder.decode(env[:url].query) || {}
272
+ stub, meta = stubs.match(env)
273
+
274
+ unless stub
275
+ raise Stubs::NotFound, "no stubbed request for #{env[:method]} " \
276
+ "#{env[:url]} #{env[:body]}"
277
+ end
278
+
279
+ block_arity = stub.block.arity
280
+ status, headers, body =
281
+ if block_arity >= 0
282
+ stub.block.call(*[env, meta].take(block_arity))
283
+ else
284
+ stub.block.call(env, meta)
285
+ end
286
+
287
+ # We need to explicitly pass `reason_phrase = nil` here to avoid keyword args conflicts.
288
+ # See https://github.com/lostisland/faraday/issues/1444
289
+ # TODO: remove `nil` explicit reason_phrase once Ruby 3.0 becomes minimum req. version
290
+ save_response(env, status, body, headers, nil)
291
+
292
+ @app.call(env)
293
+ end
294
+ end
295
+ end
296
+ end
297
+
298
+ Faraday::Adapter.register_middleware(test: Faraday::Adapter::Test)
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ # Base class for all Faraday adapters. Adapters are
5
+ # responsible for fulfilling a Faraday request.
6
+ class Adapter
7
+ extend MiddlewareRegistry
8
+
9
+ CONTENT_LENGTH = 'Content-Length'
10
+
11
+ # This module marks an Adapter as supporting parallel requests.
12
+ module Parallelism
13
+ attr_writer :supports_parallel
14
+
15
+ def supports_parallel?
16
+ @supports_parallel
17
+ end
18
+
19
+ def inherited(subclass)
20
+ super
21
+ subclass.supports_parallel = supports_parallel?
22
+ end
23
+ end
24
+
25
+ extend Parallelism
26
+ self.supports_parallel = false
27
+
28
+ def initialize(_app = nil, opts = {}, &block)
29
+ @app = ->(env) { env.response }
30
+ @connection_options = opts
31
+ @config_block = block
32
+ end
33
+
34
+ # Yields or returns an adapter's configured connection. Depends on
35
+ # #build_connection being defined on this adapter.
36
+ #
37
+ # @param env [Faraday::Env, Hash] The env object for a faraday request.
38
+ #
39
+ # @return The return value of the given block, or the HTTP connection object
40
+ # if no block is given.
41
+ def connection(env)
42
+ conn = build_connection(env)
43
+ return conn unless block_given?
44
+
45
+ yield conn
46
+ end
47
+
48
+ # Close any persistent connections. The adapter should still be usable
49
+ # after calling close.
50
+ def close
51
+ # Possible implementation:
52
+ # @app.close if @app.respond_to?(:close)
53
+ end
54
+
55
+ def call(env)
56
+ env.clear_body if env.needs_body?
57
+ env.response = Response.new
58
+ end
59
+
60
+ private
61
+
62
+ def save_response(env, status, body, headers = nil, reason_phrase = nil, finished: true)
63
+ env.status = status
64
+ env.body = body
65
+ env.reason_phrase = reason_phrase&.to_s&.strip
66
+ env.response_headers = Utils::Headers.new.tap do |response_headers|
67
+ response_headers.update headers unless headers.nil?
68
+ yield(response_headers) if block_given?
69
+ end
70
+
71
+ env.response.finish(env) unless env.parallel? || !finished
72
+ env.response
73
+ end
74
+
75
+ # Fetches either a read, write, or open timeout setting. Defaults to the
76
+ # :timeout value if a more specific one is not given.
77
+ #
78
+ # @param type [Symbol] Describes which timeout setting to get: :read,
79
+ # :write, or :open.
80
+ # @param options [Hash] Hash containing Symbol keys like :timeout,
81
+ # :read_timeout, :write_timeout, :open_timeout, or
82
+ # :timeout
83
+ #
84
+ # @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
85
+ # has been set.
86
+ def request_timeout(type, options)
87
+ key = TIMEOUT_KEYS.fetch(type) do
88
+ msg = "Expected :read, :write, :open. Got #{type.inspect} :("
89
+ raise ArgumentError, msg
90
+ end
91
+ options[key] || options[:timeout]
92
+ end
93
+
94
+ TIMEOUT_KEYS = {
95
+ read: :read_timeout,
96
+ open: :open_timeout,
97
+ write: :write_timeout
98
+ }.freeze
99
+ end
100
+ end
101
+
102
+ require 'faraday/adapter/test'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'monitor'
4
+
5
+ module Faraday
6
+ # AdapterRegistry registers adapter class names so they can be looked up by a
7
+ # String or Symbol name.
8
+ class AdapterRegistry
9
+ def initialize
10
+ @lock = Monitor.new
11
+ @constants = {}
12
+ end
13
+
14
+ def get(name)
15
+ klass = @lock.synchronize do
16
+ @constants[name]
17
+ end
18
+ return klass if klass
19
+
20
+ Object.const_get(name).tap { |c| set(c, name) }
21
+ end
22
+
23
+ def set(klass, name = nil)
24
+ name ||= klass.to_s
25
+ @lock.synchronize do
26
+ @constants[name] = klass
27
+ end
28
+ end
29
+ end
30
+ end