dhc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/rubocop.yml +27 -0
  3. data/.github/workflows/test.yml +27 -0
  4. data/.gitignore +37 -0
  5. data/.rubocop.yml +105 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +5 -0
  8. data/LICENSE +674 -0
  9. data/README.md +999 -0
  10. data/Rakefile +25 -0
  11. data/dhc.gemspec +40 -0
  12. data/lib/core_ext/hash/deep_transform_values.rb +48 -0
  13. data/lib/dhc.rb +77 -0
  14. data/lib/dhc/concerns/dhc/basic_methods_concern.rb +42 -0
  15. data/lib/dhc/concerns/dhc/configuration_concern.rb +20 -0
  16. data/lib/dhc/concerns/dhc/fix_invalid_encoding_concern.rb +42 -0
  17. data/lib/dhc/concerns/dhc/formats_concern.rb +25 -0
  18. data/lib/dhc/concerns/dhc/request/user_agent_concern.rb +25 -0
  19. data/lib/dhc/config.rb +47 -0
  20. data/lib/dhc/endpoint.rb +119 -0
  21. data/lib/dhc/error.rb +82 -0
  22. data/lib/dhc/errors/client_error.rb +73 -0
  23. data/lib/dhc/errors/parser_error.rb +4 -0
  24. data/lib/dhc/errors/server_error.rb +28 -0
  25. data/lib/dhc/errors/timeout.rb +4 -0
  26. data/lib/dhc/errors/unknown_error.rb +4 -0
  27. data/lib/dhc/format.rb +18 -0
  28. data/lib/dhc/formats.rb +8 -0
  29. data/lib/dhc/formats/form.rb +45 -0
  30. data/lib/dhc/formats/json.rb +55 -0
  31. data/lib/dhc/formats/multipart.rb +45 -0
  32. data/lib/dhc/formats/plain.rb +42 -0
  33. data/lib/dhc/interceptor.rb +36 -0
  34. data/lib/dhc/interceptors.rb +26 -0
  35. data/lib/dhc/interceptors/auth.rb +94 -0
  36. data/lib/dhc/interceptors/caching.rb +148 -0
  37. data/lib/dhc/interceptors/default_timeout.rb +16 -0
  38. data/lib/dhc/interceptors/logging.rb +37 -0
  39. data/lib/dhc/interceptors/monitoring.rb +92 -0
  40. data/lib/dhc/interceptors/prometheus.rb +51 -0
  41. data/lib/dhc/interceptors/retry.rb +41 -0
  42. data/lib/dhc/interceptors/rollbar.rb +36 -0
  43. data/lib/dhc/interceptors/throttle.rb +86 -0
  44. data/lib/dhc/interceptors/zipkin.rb +110 -0
  45. data/lib/dhc/railtie.rb +9 -0
  46. data/lib/dhc/request.rb +161 -0
  47. data/lib/dhc/response.rb +60 -0
  48. data/lib/dhc/response/data.rb +28 -0
  49. data/lib/dhc/response/data/base.rb +18 -0
  50. data/lib/dhc/response/data/collection.rb +16 -0
  51. data/lib/dhc/response/data/item.rb +29 -0
  52. data/lib/dhc/rspec.rb +11 -0
  53. data/lib/dhc/test/cache_helper.rb +3 -0
  54. data/lib/dhc/version.rb +5 -0
  55. data/script/ci/build.sh +19 -0
  56. data/spec/basic_methods/delete_spec.rb +34 -0
  57. data/spec/basic_methods/get_spec.rb +49 -0
  58. data/spec/basic_methods/post_spec.rb +42 -0
  59. data/spec/basic_methods/put_spec.rb +48 -0
  60. data/spec/basic_methods/request_spec.rb +19 -0
  61. data/spec/basic_methods/request_without_rails_spec.rb +29 -0
  62. data/spec/config/endpoints_spec.rb +63 -0
  63. data/spec/config/placeholders_spec.rb +32 -0
  64. data/spec/core_ext/hash/deep_transform_values_spec.rb +24 -0
  65. data/spec/dummy/README.rdoc +28 -0
  66. data/spec/dummy/Rakefile +8 -0
  67. data/spec/dummy/app/assets/config/manifest.js +3 -0
  68. data/spec/dummy/app/assets/images/.keep +0 -0
  69. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  70. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  71. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  72. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  73. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  74. data/spec/dummy/app/mailers/.keep +0 -0
  75. data/spec/dummy/app/models/.keep +0 -0
  76. data/spec/dummy/app/models/concerns/.keep +0 -0
  77. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  78. data/spec/dummy/bin/bundle +5 -0
  79. data/spec/dummy/bin/rails +6 -0
  80. data/spec/dummy/bin/rake +6 -0
  81. data/spec/dummy/config.ru +6 -0
  82. data/spec/dummy/config/application.rb +16 -0
  83. data/spec/dummy/config/boot.rb +7 -0
  84. data/spec/dummy/config/environment.rb +7 -0
  85. data/spec/dummy/config/environments/development.rb +36 -0
  86. data/spec/dummy/config/environments/production.rb +77 -0
  87. data/spec/dummy/config/environments/test.rb +41 -0
  88. data/spec/dummy/config/initializers/assets.rb +10 -0
  89. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  90. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  91. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  92. data/spec/dummy/config/initializers/inflections.rb +18 -0
  93. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  94. data/spec/dummy/config/initializers/session_store.rb +5 -0
  95. data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
  96. data/spec/dummy/config/locales/en.yml +23 -0
  97. data/spec/dummy/config/routes.rb +58 -0
  98. data/spec/dummy/config/secrets.yml +22 -0
  99. data/spec/dummy/lib/assets/.keep +0 -0
  100. data/spec/dummy/log/.keep +0 -0
  101. data/spec/dummy/public/404.html +67 -0
  102. data/spec/dummy/public/422.html +67 -0
  103. data/spec/dummy/public/500.html +66 -0
  104. data/spec/dummy/public/favicon.ico +0 -0
  105. data/spec/endpoint/compile_spec.rb +35 -0
  106. data/spec/endpoint/match_spec.rb +41 -0
  107. data/spec/endpoint/placeholders_spec.rb +30 -0
  108. data/spec/endpoint/remove_interpolated_params_spec.rb +17 -0
  109. data/spec/endpoint/values_as_params_spec.rb +31 -0
  110. data/spec/error/dup_spec.rb +12 -0
  111. data/spec/error/find_spec.rb +57 -0
  112. data/spec/error/response_spec.rb +17 -0
  113. data/spec/error/timeout_spec.rb +14 -0
  114. data/spec/error/to_s_spec.rb +85 -0
  115. data/spec/formats/form_spec.rb +27 -0
  116. data/spec/formats/json_spec.rb +66 -0
  117. data/spec/formats/multipart_spec.rb +26 -0
  118. data/spec/formats/plain_spec.rb +29 -0
  119. data/spec/interceptors/after_request_spec.rb +20 -0
  120. data/spec/interceptors/after_response_spec.rb +39 -0
  121. data/spec/interceptors/auth/basic_auth_spec.rb +17 -0
  122. data/spec/interceptors/auth/bearer_spec.rb +19 -0
  123. data/spec/interceptors/auth/body_spec.rb +36 -0
  124. data/spec/interceptors/auth/long_basic_auth_credentials_spec.rb +17 -0
  125. data/spec/interceptors/auth/no_instance_var_for_options_spec.rb +27 -0
  126. data/spec/interceptors/auth/reauthentication_configuration_spec.rb +61 -0
  127. data/spec/interceptors/auth/reauthentication_spec.rb +44 -0
  128. data/spec/interceptors/before_request_spec.rb +21 -0
  129. data/spec/interceptors/before_response_spec.rb +20 -0
  130. data/spec/interceptors/caching/hydra_spec.rb +26 -0
  131. data/spec/interceptors/caching/main_spec.rb +73 -0
  132. data/spec/interceptors/caching/methods_spec.rb +42 -0
  133. data/spec/interceptors/caching/multilevel_cache_spec.rb +139 -0
  134. data/spec/interceptors/caching/options_spec.rb +78 -0
  135. data/spec/interceptors/caching/parameters_spec.rb +24 -0
  136. data/spec/interceptors/caching/response_status_spec.rb +29 -0
  137. data/spec/interceptors/caching/to_cache_spec.rb +16 -0
  138. data/spec/interceptors/default_interceptors_spec.rb +15 -0
  139. data/spec/interceptors/default_timeout/main_spec.rb +34 -0
  140. data/spec/interceptors/define_spec.rb +30 -0
  141. data/spec/interceptors/dup_spec.rb +19 -0
  142. data/spec/interceptors/logging/main_spec.rb +37 -0
  143. data/spec/interceptors/monitoring/caching_spec.rb +66 -0
  144. data/spec/interceptors/monitoring/main_spec.rb +97 -0
  145. data/spec/interceptors/prometheus_spec.rb +54 -0
  146. data/spec/interceptors/response_competition_spec.rb +39 -0
  147. data/spec/interceptors/retry/main_spec.rb +73 -0
  148. data/spec/interceptors/return_response_spec.rb +38 -0
  149. data/spec/interceptors/rollbar/invalid_encoding_spec.rb +43 -0
  150. data/spec/interceptors/rollbar/main_spec.rb +57 -0
  151. data/spec/interceptors/throttle/main_spec.rb +236 -0
  152. data/spec/interceptors/throttle/reset_track_spec.rb +53 -0
  153. data/spec/interceptors/zipkin/distributed_tracing_spec.rb +135 -0
  154. data/spec/rails_helper.rb +6 -0
  155. data/spec/request/body_spec.rb +39 -0
  156. data/spec/request/encoding_spec.rb +38 -0
  157. data/spec/request/error_handling_spec.rb +88 -0
  158. data/spec/request/headers_spec.rb +12 -0
  159. data/spec/request/ignore_errors_spec.rb +73 -0
  160. data/spec/request/option_dup_spec.rb +13 -0
  161. data/spec/request/parallel_requests_spec.rb +59 -0
  162. data/spec/request/params_encoding_spec.rb +26 -0
  163. data/spec/request/request_without_rails_spec.rb +15 -0
  164. data/spec/request/url_patterns_spec.rb +54 -0
  165. data/spec/request/user_agent_spec.rb +26 -0
  166. data/spec/request/user_agent_without_rails_spec.rb +27 -0
  167. data/spec/response/body_spec.rb +16 -0
  168. data/spec/response/code_spec.rb +16 -0
  169. data/spec/response/data_accessor_spec.rb +29 -0
  170. data/spec/response/data_spec.rb +85 -0
  171. data/spec/response/effective_url_spec.rb +16 -0
  172. data/spec/response/headers_spec.rb +18 -0
  173. data/spec/response/options_spec.rb +18 -0
  174. data/spec/response/success_spec.rb +13 -0
  175. data/spec/response/time_spec.rb +21 -0
  176. data/spec/spec_helper.rb +9 -0
  177. data/spec/support/fixtures/json/feedback.json +11 -0
  178. data/spec/support/fixtures/json/feedbacks.json +164 -0
  179. data/spec/support/fixtures/json/localina_content_ad.json +23 -0
  180. data/spec/support/load_json.rb +5 -0
  181. data/spec/support/reset_config.rb +8 -0
  182. data/spec/support/zipkin_mock.rb +114 -0
  183. data/spec/timeouts/no_signal_spec.rb +13 -0
  184. data/spec/timeouts/timings_spec.rb +55 -0
  185. metadata +527 -0
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Request do
6
+ it 'does not alter the options that where passed' do
7
+ DHC.configure { |c| c.endpoint(:kpi_tracker, 'http://analytics/track/{entity_id}/w', params: { env: 'PROD' }) }
8
+ options = { params: { entity_id: '123' } }
9
+ stub_request(:get, 'http://analytics/track/123/w?env=PROD')
10
+ DHC.get(:kpi_tracker, options)
11
+ expect(options).to eq(params: { entity_id: '123' })
12
+ end
13
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Request do
6
+ let(:request_options) do
7
+ [
8
+ { url: 'http://www.depay.fi/restaurants' },
9
+ { url: 'http://www.depay.fi' }
10
+ ]
11
+ end
12
+
13
+ let(:stub_parallel_requests) do
14
+ stub_request(:get, 'http://www.depay.fi/restaurants').to_return(status: 200, body: '1')
15
+ stub_request(:get, 'http://www.depay.fi').to_return(status: 200, body: '2')
16
+ end
17
+
18
+ it 'does parallel requests if you provide an array of requests' do
19
+ stub_parallel_requests
20
+ responses = DHC.request(request_options)
21
+ expect(responses[0].body).to eq '1'
22
+ expect(responses[1].body).to eq '2'
23
+ end
24
+
25
+ context 'interceptors' do
26
+ before(:each) do
27
+ class TestInterceptor < DHC::Interceptor; end
28
+ DHC.configure { |c| c.interceptors = [TestInterceptor] }
29
+ end
30
+
31
+ it 'calls interceptors also for parallel requests' do
32
+ stub_parallel_requests
33
+ @called = 0
34
+ allow_any_instance_of(TestInterceptor)
35
+ .to receive(:before_request) { @called += 1 }
36
+ DHC.request(request_options)
37
+ expect(@called).to eq 2
38
+ end
39
+ end
40
+
41
+ context 'webmock disabled' do
42
+ before do
43
+ WebMock.disable!
44
+ end
45
+
46
+ after do
47
+ WebMock.enable!
48
+ end
49
+
50
+ it 'does not memorize parallelization handlers in typhoeus (hydra) in case one request of the parallization fails' do
51
+ begin
52
+ DHC.request([{ url: 'https://www.google.com/' }, { url: 'https://nonexisting123' }, { url: 'https://www.google.com/' }, { url: 'https://nonexisting123' }])
53
+ rescue DHC::UnknownError
54
+ end
55
+
56
+ DHC.request([{ url: 'https://www.google.com' }])
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Request do
6
+ context 'without an encoding setting' do
7
+ it 'encodes array params in default rack format' do
8
+ stub_request(:get, 'http://datastore/q?a%5B%5D=1&a%5B%5D=2&a%5B%5D=3')
9
+ DHC.get('http://datastore/q', params: { a: [1, 2, 3] })
10
+ end
11
+ end
12
+
13
+ context 'with encoding set to :rack' do
14
+ it 'encodes array params in rack format' do
15
+ stub_request(:get, 'http://datastore/q?a%5B%5D=1&a%5B%5D=2&a%5B%5D=3')
16
+ DHC.get('http://datastore/q', params: { a: [1, 2, 3] }, params_encoding: :rack)
17
+ end
18
+ end
19
+
20
+ context 'with encoding set to :multi' do
21
+ it 'encodes array params in multi format' do
22
+ stub_request(:get, 'http://datastore/q?a=1&a=2&a=3')
23
+ DHC.get('http://datastore/q', params: { a: [1, 2, 3] }, params_encoding: :multi)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DHC::Request do
6
+ before do
7
+ allow_any_instance_of(DHC::Request).to receive(:use_configured_endpoint!)
8
+ allow_any_instance_of(DHC::Request).to receive(:generate_url_from_template!)
9
+ end
10
+ context 'request without rails' do
11
+ it 'does have deep_merge dependency met' do
12
+ expect { DHC::Request.new({}, false) }.not_to raise_error
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Request do
6
+ it 'compiles url in case of configured endpoints' do
7
+ options = { params: {
8
+ has_reviews: true
9
+ } }
10
+ url = 'http://datastore/v2/campaign/{campaign_id}/feedbacks'
11
+ DHC.configure { |c| c.endpoint(:feedbacks, url, options) }
12
+ stub_request(:get, 'http://datastore/v2/campaign/123/feedbacks?has_reviews=true')
13
+ DHC.get(:feedbacks, params: { campaign_id: 123 })
14
+ end
15
+
16
+ it 'compiles url when doing a request' do
17
+ stub_request(:get, 'http://datastore:8080/v2/feedbacks/123')
18
+ DHC.get('http://datastore:8080/v2/feedbacks/{id}', params: { id: 123 })
19
+ end
20
+
21
+ it 'considers body when compiling urls' do
22
+ stub_request(:post, 'http://datastore:8080/v2/places/123')
23
+ DHC.json.post('http://datastore:8080/v2/places/{id}', body: { id: 123 })
24
+ end
25
+
26
+ context 'custom data structures that respond to as_json (like LHS data or record)' do
27
+ before do
28
+ class CustomStructure
29
+
30
+ def initialize(data)
31
+ @data = data
32
+ end
33
+
34
+ def as_json
35
+ @data.as_json
36
+ end
37
+
38
+ def to_json
39
+ as_json.to_json
40
+ end
41
+ end
42
+ end
43
+
44
+ let(:data) do
45
+ CustomStructure.new(id: '12345')
46
+ end
47
+
48
+ it 'compiles url from body params when body object respond_to(:as_json)' do
49
+ stub_request(:post, 'http://datastore/places/12345')
50
+ .to_return(status: 200)
51
+ DHC.post('http://datastore/places/{id}', body: data)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Request do
6
+ before do
7
+ DHC.send(:remove_const, :Request)
8
+ load('dhc/concerns/dhc/request/user_agent_concern.rb')
9
+ load('dhc/request.rb')
10
+ end
11
+
12
+ context 'default headers' do
13
+ context 'agent' do
14
+ it 'sets header agent information to be DHC' do
15
+ stub_request(:get, 'http://depay.fi/')
16
+ .with(
17
+ headers: {
18
+ 'User-Agent' => "DHC (#{DHC::VERSION}; Dummy) [https://github.com/DePayFi/dhc]"
19
+ }
20
+ )
21
+ .to_return(status: 200)
22
+ DHC.get('http://depay.fi')
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DHC::Request do
6
+ before do
7
+ Object.send(:remove_const, :Rails)
8
+ DHC.send(:remove_const, :Request)
9
+ load('dhc/concerns/dhc/request/user_agent_concern.rb')
10
+ load('dhc/request.rb')
11
+ end
12
+
13
+ context 'default headers' do
14
+ context 'agent' do
15
+ it 'sets header agent information to be DHC' do
16
+ stub_request(:get, 'http://depay.fi/')
17
+ .with(
18
+ headers: {
19
+ 'User-Agent' => "DHC (#{DHC::VERSION}) [https://github.com/DePayFi/dhc]"
20
+ }
21
+ )
22
+ .to_return(status: 200)
23
+ DHC.get('http://depay.fi')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'body' do
7
+ let(:body) { 'this is a body' }
8
+
9
+ let(:raw_response) { OpenStruct.new(body: body) }
10
+
11
+ it 'provides response body' do
12
+ response = DHC::Response.new(raw_response, nil)
13
+ expect(response.body).to eq body
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'code' do
7
+ let(:code) { 200 }
8
+
9
+ let(:raw_response) { OpenStruct.new(code: code) }
10
+
11
+ it 'provides response code' do
12
+ response = DHC::Response.new(raw_response, nil)
13
+ expect(response.code).to eq code
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'data accessor (hash with indifferent access)' do
7
+ before(:each) do
8
+ stub_request(:get, 'http://depay.fi/')
9
+ .with(headers: {
10
+ 'Accept' => 'application/json,application/vnd.api+json',
11
+ 'Content-Type' => 'application/json; charset=utf-8',
12
+ 'Accept-Charset' => 'utf-8'
13
+ })
14
+ .to_return(body: { 'MyProp' => 'MyValue' }.to_json)
15
+ end
16
+
17
+ it 'makes data accessible with square bracket accessor (string)' do
18
+ expect(
19
+ DHC.json.get('http://depay.fi')['MyProp']
20
+ ).to eq 'MyValue'
21
+ end
22
+
23
+ it 'makes data accessible with square bracket accessor (symbol)' do
24
+ expect(
25
+ DHC.json.get('http://depay.fi')[:MyProp]
26
+ ).to eq 'MyValue'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'data' do
7
+ let(:value) { 'some_value' }
8
+
9
+ let(:raw_response) { OpenStruct.new(body: body.to_json) }
10
+
11
+ let(:response) { DHC::Response.new(raw_response, nil) }
12
+
13
+ context 'for item' do
14
+ let(:body) { { some_key: { nested: value } } }
15
+
16
+ it 'makes data from response body available' do
17
+ expect(response.data.some_key.nested).to eq value
18
+ end
19
+
20
+ it 'makes data from response body available with hash bracket notation' do
21
+ expect(response.data[:some_key][:nested]).to eq value
22
+ end
23
+
24
+ it 'can be converted to json with the as_json method' do
25
+ expect(response.data.as_json).to eq body.as_json
26
+ end
27
+
28
+ it 'can be converted to an open struct with the as_open_struct method' do
29
+ expect(response.data.as_open_struct).to eq JSON.parse(response.body, object_class: OpenStruct)
30
+ end
31
+
32
+ it 'returns nil when data is not available' do
33
+ expect(response.data.something).to be_nil
34
+ end
35
+ end
36
+
37
+ context 'for collection' do
38
+ let(:body) { [{ some_key: { nested: value } }] }
39
+
40
+ it 'can be converted to json with the as_json method' do
41
+ expect(response.data.as_json).to eq body.as_json
42
+ end
43
+
44
+ it 'can be converted to an open struct with the as_open_struct method' do
45
+ expect(response.data.as_open_struct).to eq JSON.parse(response.body, object_class: OpenStruct)
46
+ end
47
+
48
+ it 'is a collection of items' do
49
+ expect(response.data.size).to eq(1)
50
+ end
51
+
52
+ it 'makes item data from response body available' do
53
+ expect(response.data.first.some_key.nested).to eq value
54
+ end
55
+
56
+ it 'makes item data from response body available with hash bracket notation' do
57
+ expect(response.data.first[:some_key][:nested]).to eq value
58
+ end
59
+ end
60
+ end
61
+
62
+ context 'response data if responding error data contains a response' do
63
+ before do
64
+ stub_request(:get, 'http://listings/')
65
+ .to_return(status: 404, body: {
66
+ meta: {
67
+ errors: [
68
+ { code: 2000, msg: 'I like to hide error messages (this is meta).' }
69
+ ]
70
+ },
71
+ response: 'why not?'
72
+ }.to_json)
73
+ end
74
+
75
+ it 'does not throw a stack level to deep issue when accessing data in a rescue context' do
76
+ begin
77
+ DHC.get('http://listings')
78
+ rescue DHC::Error => error
79
+ expect(
80
+ error.response.request.response.data.meta.errors.detect { |item| item.code == 2000 }.msg
81
+ ).to eq 'I like to hide error messages (this is meta).'
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'effective_url' do
7
+ let(:effective_url) { 'https://www.depay.fi' }
8
+
9
+ let(:raw_response) { OpenStruct.new(effective_url: effective_url) }
10
+
11
+ it 'provides effective_url' do
12
+ response = DHC::Response.new(raw_response, nil)
13
+ expect(response.effective_url).to eq effective_url
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'headers' do
7
+ let(:headers) do
8
+ { 'Content-Encoding' => 'UTF-8' }
9
+ end
10
+
11
+ let(:raw_response) { OpenStruct.new(headers: headers) }
12
+
13
+ it 'provides headers' do
14
+ response = DHC::Response.new(raw_response, nil)
15
+ expect(response.headers).to eq headers
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'headers' do
7
+ let(:options) do
8
+ { 'return_code' => :ok }
9
+ end
10
+
11
+ let(:raw_response) { OpenStruct.new(options: options) }
12
+
13
+ it 'provides headers' do
14
+ response = DHC::Response.new(raw_response, nil)
15
+ expect(response.options).to eq options
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC::Response do
6
+ context 'success?' do
7
+ let(:response_success) { DHC::Response.new(Typhoeus::Response.new(response_code: 200, mock: true), nil) }
8
+ let(:response_error) { DHC::Response.new(Typhoeus::Response.new(response_code: 404, mock: true), nil) }
9
+
10
+ it { expect(response_success).to be_success }
11
+ it { expect(response_error).not_to be_success }
12
+ end
13
+ end