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,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/module'
4
+
5
+ # The response contains the raw response (typhoeus)
6
+ # and provides functionality to access response data.
7
+ class DHC::Response
8
+ autoload :Data, 'dhc/response/data'
9
+
10
+ attr_accessor :request, :body_replacement
11
+ attr_reader :from_cache
12
+
13
+ delegate :effective_url, :code, :headers, :options, :mock, :success?, to: :raw
14
+ delegate :error_ignored?, to: :request
15
+ alias from_cache? from_cache
16
+
17
+ # A response is initalized with the underlying raw response (typhoeus in our case)
18
+ # and the associated request.
19
+ def initialize(raw, request, from_cache: false)
20
+ self.request = request
21
+ self.raw = raw
22
+ @from_cache = from_cache
23
+ end
24
+
25
+ def data
26
+ @data ||= body.present? ? DHC::Response::Data.new(self) : nil
27
+ end
28
+
29
+ def [](key)
30
+ data[key]
31
+ end
32
+
33
+ def body
34
+ body_replacement || raw.body.presence
35
+ end
36
+
37
+ # Provides response time in seconds
38
+ def time
39
+ raw.time || 0
40
+ end
41
+
42
+ # Provides response time in milliseconds
43
+ def time_ms
44
+ time * 1000
45
+ end
46
+
47
+ def timeout?
48
+ raw.timed_out?
49
+ end
50
+
51
+ def format
52
+ return DHC::Formats::JSON.new if request.nil?
53
+ request.format
54
+ end
55
+
56
+ private
57
+
58
+ attr_accessor :raw
59
+
60
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DHC::Response::Data
4
+ autoload :Base, 'dhc/response/data/base'
5
+ autoload :Item, 'dhc/response/data/item'
6
+ autoload :Collection, 'dhc/response/data/collection'
7
+
8
+ include DHC::Response::Data::Base
9
+
10
+ def initialize(response, data: nil)
11
+ @response = response
12
+ @data = data
13
+
14
+ if as_json.is_a?(Hash)
15
+ @base = DHC::Response::Data::Item.new(@response, data: data)
16
+ elsif as_json.is_a?(Array)
17
+ @base = DHC::Response::Data::Collection.new(@response, data: data)
18
+ end
19
+ end
20
+
21
+ def method_missing(method, *args, &block)
22
+ @base.send(method, *args, &block)
23
+ end
24
+
25
+ def respond_to_missing?(method_name, include_private = false)
26
+ @base.respond_to?(method_name, include_private) || super
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Response data is data provided through the response body
4
+ # but made accssible in the ruby world
5
+ module DHC::Response::Data::Base
6
+ def as_json
7
+ @json ||= (@data || @response.format.as_json(@response.body))
8
+ end
9
+
10
+ def as_open_struct
11
+ @open_struct ||=
12
+ if @data
13
+ JSON.parse(@data.to_json, object_class: OpenStruct)
14
+ else
15
+ @response.format.as_open_struct(@response.body)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DHC::Response::Data::Collection < Array
4
+ include DHC::Response::Data::Base
5
+
6
+ def initialize(response, data: nil)
7
+ @response = response
8
+ @data = data
9
+
10
+ super(
11
+ as_json.map do |i|
12
+ DHC::Response::Data.new(response, data: i)
13
+ end
14
+ )
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DHC::Response::Data::Item < OpenStruct
4
+ include DHC::Response::Data::Base
5
+
6
+ def initialize(response, data: nil)
7
+ @response = response
8
+ @data = data
9
+
10
+ set_dynamic_accessor_methods
11
+
12
+ super(as_json)
13
+ end
14
+
15
+ def [](key)
16
+ @hash ||= as_json.with_indifferent_access
17
+ @hash[key]
18
+ end
19
+
20
+ private
21
+
22
+ def set_dynamic_accessor_methods
23
+ as_json.keys.each do |key|
24
+ define_singleton_method key do |*args|
25
+ as_open_struct.send key, *args
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/dhc/rspec.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dhc'
4
+
5
+ RSpec.configure do |config|
6
+ config.before(:each) do
7
+ DHC::Caching.cache = ActiveSupport::Cache::MemoryStore.new
8
+ DHC::Caching.cache.clear
9
+ DHC::Throttle.track = nil
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ warn("[WARNING] require 'dhc/test/cache_helper.rb' is not needed any more! Just require 'dhc/rspec' in your spec helper instead.")
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DHC
4
+ VERSION ||= '1.0.0'
5
+ end
@@ -0,0 +1,19 @@
1
+ #!/bin/bash -e
2
+
3
+ # custom vars
4
+ # RUBY = ruby-1.9.3-p125
5
+ # GEMSET = location-app-${GitHub pull request id|branch name}
6
+ # standard vars
7
+
8
+ if [ -z "$SKIP_RVM" ]; then
9
+ [[ -s "/usr/local/rvm/scripts/rvm" ]] && . "/usr/local/rvm/scripts/rvm"
10
+ RUBY=${RUBY:-ruby-2.1.2}
11
+ GEMSET=${GEMSET:-DHC}
12
+ rvm use ${RUBY}@${GEMSET} --create
13
+ gem install bundler --no-rdoc --no-ri
14
+ fi
15
+
16
+ bundle install --local --quiet || bundle install --quiet
17
+ RAILS_ENV=test bundle exec rspec
18
+ bundle exec rspec non_rails_spec
19
+ rvm --force gemset delete ${RUBY}@${GEMSET}
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'delete' do
7
+ let(:feedback) do
8
+ {
9
+ recommended: true,
10
+ source_id: 'aaa',
11
+ content_ad_id: '1z-5r1fkaj'
12
+ }
13
+ end
14
+
15
+ before(:each) do
16
+ stub_request(:delete, 'http://datastore/v2/feedbacks/12121')
17
+ .to_return(status: 200, body: feedback.to_json, headers: { 'Content-Encoding' => 'UTF-8' })
18
+ end
19
+
20
+ it 'does a delete request when providing a complete url' do
21
+ DHC.delete('http://datastore/v2/feedbacks/12121')
22
+ end
23
+
24
+ it 'makes response data available in a rails way' do
25
+ response = DHC.delete('http://datastore/v2/feedbacks/12121')
26
+ expect(response.data.recommended).to eq true
27
+ end
28
+
29
+ it 'provides response headers' do
30
+ response = DHC.delete('http://datastore/v2/feedbacks/12121')
31
+ expect(response.headers).to be_present
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'get' do
7
+ before(:each) do
8
+ stub_request(:get, 'http://datastore/v2/feedbacks?has_reviews=true')
9
+ .to_return(status: 200, body: { total: 99 }.to_json, headers: { 'Content-Encoding' => 'UTF-8' })
10
+ end
11
+
12
+ let(:parameters) do
13
+ { has_reviews: true }
14
+ end
15
+
16
+ it 'does a get request when providing a complete url' do
17
+ DHC.get('http://datastore/v2/feedbacks', params: parameters)
18
+ end
19
+
20
+ it 'does a get request when providing the name of a configured endpoint' do
21
+ url = 'http://{+datastore}/v2/feedbacks'
22
+ options = { params: { datastore: 'datastore' } }
23
+ DHC.configure { |c| c.endpoint(:feedbacks, url, options) }
24
+ DHC.get(:feedbacks, params: parameters)
25
+ end
26
+
27
+ it 'makes response data available in a rails way' do
28
+ response = DHC.get('http://datastore/v2/feedbacks', params: parameters)
29
+ expect(response.data.total).to eq 99
30
+ end
31
+
32
+ it 'provides response headers' do
33
+ response = DHC.get('http://datastore/v2/feedbacks', params: parameters)
34
+ expect(response.headers).to be_present
35
+ end
36
+ end
37
+
38
+ context 'get json' do
39
+ before(:each) do
40
+ stub_request(:get, 'http://datastore/v2/feedbacks').with(headers: { 'Content-Type' => 'application/json; charset=utf-8' })
41
+ .to_return(body: { some: 'json' }.to_json)
42
+ end
43
+
44
+ it 'requests json and parses response body' do
45
+ data = DHC.json.get('http://datastore/v2/feedbacks').data
46
+ expect(data.some).to eq 'json'
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'post' do
7
+ let(:feedback) do
8
+ {
9
+ recommended: true,
10
+ source_id: 'aaa',
11
+ content_ad_id: '1z-5r1fkaj'
12
+ }
13
+ end
14
+
15
+ before(:each) do
16
+ stub_request(:post, 'http://datastore/v2/feedbacks')
17
+ .with(body: feedback.to_json)
18
+ .to_return(status: 200, body: feedback.to_json, headers: { 'Content-Encoding' => 'UTF-8' })
19
+ end
20
+
21
+ it 'does a post request when providing a complete url' do
22
+ DHC.post('http://datastore/v2/feedbacks', body: feedback)
23
+ end
24
+
25
+ it 'does a post request when providing the name of a configured endpoint' do
26
+ url = 'http://{+datastore}/v2/feedbacks'
27
+ options = { params: { datastore: 'datastore' } }
28
+ DHC.configure { |c| c.endpoint(:feedbacks, url, options) }
29
+ DHC.post(:feedbacks, body: feedback)
30
+ end
31
+
32
+ it 'makes response data available in a rails way' do
33
+ response = DHC.post('http://datastore/v2/feedbacks', body: feedback)
34
+ expect(response.data.source_id).to eq 'aaa'
35
+ end
36
+
37
+ it 'provides response headers' do
38
+ response = DHC.post('http://datastore/v2/feedbacks', body: feedback)
39
+ expect(response.headers).to be_present
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'post' do
7
+ let(:feedback) do
8
+ {
9
+ recommended: false,
10
+ source_id: 'aaa',
11
+ content_ad_id: '1z-5r1fkaj'
12
+ }
13
+ end
14
+
15
+ let(:change) do
16
+ {
17
+ recommended: false
18
+ }
19
+ end
20
+
21
+ before(:each) do
22
+ stub_request(:put, 'http://datastore/v2/feedbacks')
23
+ .with(body: change.to_json)
24
+ .to_return(status: 200, body: feedback.merge(change).to_json, headers: { 'Content-Encoding' => 'UTF-8' })
25
+ end
26
+
27
+ it 'does a post request when providing a complete url' do
28
+ DHC.put('http://datastore/v2/feedbacks', body: change)
29
+ end
30
+
31
+ it 'does a post request when providing the name of a configured endpoint' do
32
+ url = 'http://{+datastore}/v2/feedbacks'
33
+ options = { params: { datastore: 'datastore' } }
34
+ DHC.configure { |c| c.endpoint(:feedbacks, url, options) }
35
+ DHC.put(:feedbacks, body: change)
36
+ end
37
+
38
+ it 'makes response data available in a rails way' do
39
+ response = DHC.put('http://datastore/v2/feedbacks', body: change)
40
+ expect(response.data.recommended).to eq false
41
+ end
42
+
43
+ it 'provides response headers' do
44
+ response = DHC.put('http://datastore/v2/feedbacks', body: change)
45
+ expect(response.headers).to be_present
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'request' do
7
+ let(:total) { 99 }
8
+
9
+ before(:each) do
10
+ stub_request(:get, 'http://datastore/v2/feedbacks?has_reviews=true')
11
+ .to_return(status: 200, body: { total: total }.to_json, headers: { 'Content-Encoding' => 'UTF-8' })
12
+ end
13
+
14
+ it 'does a request returning a response' do
15
+ response = DHC.request(url: 'http://datastore/v2/feedbacks', params: { has_reviews: true }, method: :get)
16
+ expect(response.data.total).to eq total
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DHC do
6
+ context 'GET' do
7
+ before do
8
+ stub_request(:get, 'http://datastore/v2/feedbacks').to_return(status: 200, body: '{}')
9
+ end
10
+ it "is able to call .request without DHC raising NoMethodError: undefined method `blank?' for nil:NilClass when calling it outside of the rails context" do
11
+ expect { DHC.request(url: 'http://datastore/v2/feedbacks', method: :get) }.not_to raise_error
12
+ end
13
+ end
14
+
15
+ context 'POST' do
16
+ before do
17
+ stub_request(:post, 'http://datastore/v2/feedbacks').to_return(status: 200, body: '{}')
18
+ end
19
+
20
+ it "is able to call .request without DHC raising NoMethodError: undefined method `deep_symbolize_keys' for {}:Hash" do
21
+ options = {
22
+ url: 'http://datastore/v2/feedbacks',
23
+ method: :post,
24
+ body: {}
25
+ }
26
+ expect { DHC.request(options) }.not_to raise_error
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHC do
6
+ context 'configured endpoints' do
7
+ let(:url) { 'http://analytics/track/{entity_id}/w/{type}' }
8
+
9
+ let(:options) do
10
+ {
11
+ params: { env: 'PROD' },
12
+ followlocation: false
13
+ }
14
+ end
15
+
16
+ before(:each) do
17
+ DHC.configure do |c|
18
+ c.endpoint(:kpi_tracker, url, options)
19
+ end
20
+ end
21
+
22
+ it 'configures urls to be able to access them by name later' do
23
+ expect(DHC.config.endpoints[:kpi_tracker].url).to eq url
24
+ expect(DHC.config.endpoints[:kpi_tracker].options).to eq options
25
+ end
26
+
27
+ it 'compile url' do
28
+ stub_request(:get, 'http://analytics/track/123/w/request?env=PROD')
29
+ response = DHC.get(:kpi_tracker, params: { entity_id: 123, type: 'request' })
30
+ expect(response.request.options[:followlocation]).to eq false
31
+ end
32
+
33
+ it 'gets overwritten by explicit request options' do
34
+ stub_request(:get, 'http://analytics/track/123/w/request?env=STG')
35
+ DHC.get(:kpi_tracker, params: { entity_id: 123, type: 'request', env: 'STG' })
36
+ end
37
+
38
+ it 'raises in case of claching endpoint names' do
39
+ expect(lambda {
40
+ DHC.config.endpoint(:kpi_tracker, 'http://kpi-tracker')
41
+ }).to raise_error 'Endpoint already exists for that name'
42
+ end
43
+
44
+ it 'enforces endpoint name to be a symbol' do
45
+ DHC.configure { |c| c.endpoint('datastore', 'http://datastore') }
46
+ expect(DHC.config.endpoints[:datastore].url).to eq 'http://datastore'
47
+ end
48
+ end
49
+
50
+ context 'configured enpoints with default params' do
51
+ before(:each) do
52
+ DHC.config.endpoint(:telemarketers, 'http://datastore/v2/spamnumbers?order_by=-user_frequency&swiss_number=true&offset=0&limit=:limit', params: { limit: 200 })
53
+ stub_request(:get, 'http://datastore/v2/spamnumbers?limit=200&offset=0&order_by=-user_frequency&swiss_number=true')
54
+ .to_return(status: 200)
55
+ end
56
+
57
+ it 'is possible to call them multiple times with default params' do
58
+ DHC.get(:telemarketers)
59
+ DHC.get(:telemarketers)
60
+ DHC.get(:telemarketers)
61
+ end
62
+ end
63
+ end