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.
- checksums.yaml +7 -0
- data/.github/workflows/rubocop.yml +27 -0
- data/.github/workflows/test.yml +27 -0
- data/.gitignore +37 -0
- data/.rubocop.yml +105 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -0
- data/LICENSE +674 -0
- data/README.md +999 -0
- data/Rakefile +25 -0
- data/dhc.gemspec +40 -0
- data/lib/core_ext/hash/deep_transform_values.rb +48 -0
- data/lib/dhc.rb +77 -0
- data/lib/dhc/concerns/dhc/basic_methods_concern.rb +42 -0
- data/lib/dhc/concerns/dhc/configuration_concern.rb +20 -0
- data/lib/dhc/concerns/dhc/fix_invalid_encoding_concern.rb +42 -0
- data/lib/dhc/concerns/dhc/formats_concern.rb +25 -0
- data/lib/dhc/concerns/dhc/request/user_agent_concern.rb +25 -0
- data/lib/dhc/config.rb +47 -0
- data/lib/dhc/endpoint.rb +119 -0
- data/lib/dhc/error.rb +82 -0
- data/lib/dhc/errors/client_error.rb +73 -0
- data/lib/dhc/errors/parser_error.rb +4 -0
- data/lib/dhc/errors/server_error.rb +28 -0
- data/lib/dhc/errors/timeout.rb +4 -0
- data/lib/dhc/errors/unknown_error.rb +4 -0
- data/lib/dhc/format.rb +18 -0
- data/lib/dhc/formats.rb +8 -0
- data/lib/dhc/formats/form.rb +45 -0
- data/lib/dhc/formats/json.rb +55 -0
- data/lib/dhc/formats/multipart.rb +45 -0
- data/lib/dhc/formats/plain.rb +42 -0
- data/lib/dhc/interceptor.rb +36 -0
- data/lib/dhc/interceptors.rb +26 -0
- data/lib/dhc/interceptors/auth.rb +94 -0
- data/lib/dhc/interceptors/caching.rb +148 -0
- data/lib/dhc/interceptors/default_timeout.rb +16 -0
- data/lib/dhc/interceptors/logging.rb +37 -0
- data/lib/dhc/interceptors/monitoring.rb +92 -0
- data/lib/dhc/interceptors/prometheus.rb +51 -0
- data/lib/dhc/interceptors/retry.rb +41 -0
- data/lib/dhc/interceptors/rollbar.rb +36 -0
- data/lib/dhc/interceptors/throttle.rb +86 -0
- data/lib/dhc/interceptors/zipkin.rb +110 -0
- data/lib/dhc/railtie.rb +9 -0
- data/lib/dhc/request.rb +161 -0
- data/lib/dhc/response.rb +60 -0
- data/lib/dhc/response/data.rb +28 -0
- data/lib/dhc/response/data/base.rb +18 -0
- data/lib/dhc/response/data/collection.rb +16 -0
- data/lib/dhc/response/data/item.rb +29 -0
- data/lib/dhc/rspec.rb +11 -0
- data/lib/dhc/test/cache_helper.rb +3 -0
- data/lib/dhc/version.rb +5 -0
- data/script/ci/build.sh +19 -0
- data/spec/basic_methods/delete_spec.rb +34 -0
- data/spec/basic_methods/get_spec.rb +49 -0
- data/spec/basic_methods/post_spec.rb +42 -0
- data/spec/basic_methods/put_spec.rb +48 -0
- data/spec/basic_methods/request_spec.rb +19 -0
- data/spec/basic_methods/request_without_rails_spec.rb +29 -0
- data/spec/config/endpoints_spec.rb +63 -0
- data/spec/config/placeholders_spec.rb +32 -0
- data/spec/core_ext/hash/deep_transform_values_spec.rb +24 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +7 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +5 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/config.ru +6 -0
- data/spec/dummy/config/application.rb +16 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +36 -0
- data/spec/dummy/config/environments/production.rb +77 -0
- data/spec/dummy/config/environments/test.rb +41 -0
- data/spec/dummy/config/initializers/assets.rb +10 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/session_store.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/endpoint/compile_spec.rb +35 -0
- data/spec/endpoint/match_spec.rb +41 -0
- data/spec/endpoint/placeholders_spec.rb +30 -0
- data/spec/endpoint/remove_interpolated_params_spec.rb +17 -0
- data/spec/endpoint/values_as_params_spec.rb +31 -0
- data/spec/error/dup_spec.rb +12 -0
- data/spec/error/find_spec.rb +57 -0
- data/spec/error/response_spec.rb +17 -0
- data/spec/error/timeout_spec.rb +14 -0
- data/spec/error/to_s_spec.rb +85 -0
- data/spec/formats/form_spec.rb +27 -0
- data/spec/formats/json_spec.rb +66 -0
- data/spec/formats/multipart_spec.rb +26 -0
- data/spec/formats/plain_spec.rb +29 -0
- data/spec/interceptors/after_request_spec.rb +20 -0
- data/spec/interceptors/after_response_spec.rb +39 -0
- data/spec/interceptors/auth/basic_auth_spec.rb +17 -0
- data/spec/interceptors/auth/bearer_spec.rb +19 -0
- data/spec/interceptors/auth/body_spec.rb +36 -0
- data/spec/interceptors/auth/long_basic_auth_credentials_spec.rb +17 -0
- data/spec/interceptors/auth/no_instance_var_for_options_spec.rb +27 -0
- data/spec/interceptors/auth/reauthentication_configuration_spec.rb +61 -0
- data/spec/interceptors/auth/reauthentication_spec.rb +44 -0
- data/spec/interceptors/before_request_spec.rb +21 -0
- data/spec/interceptors/before_response_spec.rb +20 -0
- data/spec/interceptors/caching/hydra_spec.rb +26 -0
- data/spec/interceptors/caching/main_spec.rb +73 -0
- data/spec/interceptors/caching/methods_spec.rb +42 -0
- data/spec/interceptors/caching/multilevel_cache_spec.rb +139 -0
- data/spec/interceptors/caching/options_spec.rb +78 -0
- data/spec/interceptors/caching/parameters_spec.rb +24 -0
- data/spec/interceptors/caching/response_status_spec.rb +29 -0
- data/spec/interceptors/caching/to_cache_spec.rb +16 -0
- data/spec/interceptors/default_interceptors_spec.rb +15 -0
- data/spec/interceptors/default_timeout/main_spec.rb +34 -0
- data/spec/interceptors/define_spec.rb +30 -0
- data/spec/interceptors/dup_spec.rb +19 -0
- data/spec/interceptors/logging/main_spec.rb +37 -0
- data/spec/interceptors/monitoring/caching_spec.rb +66 -0
- data/spec/interceptors/monitoring/main_spec.rb +97 -0
- data/spec/interceptors/prometheus_spec.rb +54 -0
- data/spec/interceptors/response_competition_spec.rb +39 -0
- data/spec/interceptors/retry/main_spec.rb +73 -0
- data/spec/interceptors/return_response_spec.rb +38 -0
- data/spec/interceptors/rollbar/invalid_encoding_spec.rb +43 -0
- data/spec/interceptors/rollbar/main_spec.rb +57 -0
- data/spec/interceptors/throttle/main_spec.rb +236 -0
- data/spec/interceptors/throttle/reset_track_spec.rb +53 -0
- data/spec/interceptors/zipkin/distributed_tracing_spec.rb +135 -0
- data/spec/rails_helper.rb +6 -0
- data/spec/request/body_spec.rb +39 -0
- data/spec/request/encoding_spec.rb +38 -0
- data/spec/request/error_handling_spec.rb +88 -0
- data/spec/request/headers_spec.rb +12 -0
- data/spec/request/ignore_errors_spec.rb +73 -0
- data/spec/request/option_dup_spec.rb +13 -0
- data/spec/request/parallel_requests_spec.rb +59 -0
- data/spec/request/params_encoding_spec.rb +26 -0
- data/spec/request/request_without_rails_spec.rb +15 -0
- data/spec/request/url_patterns_spec.rb +54 -0
- data/spec/request/user_agent_spec.rb +26 -0
- data/spec/request/user_agent_without_rails_spec.rb +27 -0
- data/spec/response/body_spec.rb +16 -0
- data/spec/response/code_spec.rb +16 -0
- data/spec/response/data_accessor_spec.rb +29 -0
- data/spec/response/data_spec.rb +85 -0
- data/spec/response/effective_url_spec.rb +16 -0
- data/spec/response/headers_spec.rb +18 -0
- data/spec/response/options_spec.rb +18 -0
- data/spec/response/success_spec.rb +13 -0
- data/spec/response/time_spec.rb +21 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/fixtures/json/feedback.json +11 -0
- data/spec/support/fixtures/json/feedbacks.json +164 -0
- data/spec/support/fixtures/json/localina_content_ad.json +23 -0
- data/spec/support/load_json.rb +5 -0
- data/spec/support/reset_config.rb +8 -0
- data/spec/support/zipkin_mock.rb +114 -0
- data/spec/timeouts/no_signal_spec.rb +13 -0
- data/spec/timeouts/timings_spec.rb +55 -0
- metadata +527 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Endpoint do
|
|
6
|
+
context 'placeholders' do
|
|
7
|
+
it 'returns all placeholders alphabetically sorted' do
|
|
8
|
+
endpoint = DHC::Endpoint.new('{+datastore}/v2/{campaign_id}/feedbacks')
|
|
9
|
+
expect(
|
|
10
|
+
endpoint.placeholders
|
|
11
|
+
).to eq %i[campaign_id datastore]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'allows basic auth token in url, like used on github' do
|
|
15
|
+
stub_request(:get, 'https://d123token:@api.github.com/search')
|
|
16
|
+
.to_return(body: {}.to_json)
|
|
17
|
+
expect(-> {
|
|
18
|
+
DHC.get('https://d123token:@api.github.com/search')
|
|
19
|
+
}).not_to raise_error
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'allows complete basic auth (username password) in url, like used for the gemserer' do
|
|
23
|
+
stub_request(:get, 'https://name:password@gemserver.com')
|
|
24
|
+
.to_return(body: {}.to_json)
|
|
25
|
+
expect(-> {
|
|
26
|
+
DHC.get('https://name:password@gemserver.com')
|
|
27
|
+
}).not_to raise_error
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Endpoint do
|
|
6
|
+
it 'removes params used for interpolation' do
|
|
7
|
+
params = {
|
|
8
|
+
datastore: 'http://datastore',
|
|
9
|
+
campaign_id: 'abc',
|
|
10
|
+
has_reviews: true
|
|
11
|
+
}
|
|
12
|
+
endpoint = DHC::Endpoint.new('{+datastore}/v2/{campaign_id}/feedbacks')
|
|
13
|
+
removed = endpoint.remove_interpolated_params!(params)
|
|
14
|
+
expect(params).to eq(has_reviews: true)
|
|
15
|
+
expect(removed).to eq(datastore: 'http://datastore', campaign_id: 'abc')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Endpoint do
|
|
6
|
+
context 'values_as_params' do
|
|
7
|
+
[
|
|
8
|
+
['{+datastore}/v2/places', 'http://depay.fi:8082/v2/places', {
|
|
9
|
+
datastore: 'http://depay.fi:8082'
|
|
10
|
+
}],
|
|
11
|
+
['{+datastore}/v2/places/{id}', 'http://depay.fi:8082/v2/places/ZW9OJyrbt4OZE9ueu80w-A', {
|
|
12
|
+
datastore: 'http://depay.fi:8082',
|
|
13
|
+
id: 'ZW9OJyrbt4OZE9ueu80w-A'
|
|
14
|
+
}],
|
|
15
|
+
['{+datastore}/v2/places/{namespace}/{id}', 'http://depay.fi:8082/v2/places/switzerland/ZW9OJyrbt', {
|
|
16
|
+
datastore: 'http://depay.fi:8082',
|
|
17
|
+
namespace: 'switzerland',
|
|
18
|
+
id: 'ZW9OJyrbt'
|
|
19
|
+
}]
|
|
20
|
+
].each do |example|
|
|
21
|
+
template = example[0]
|
|
22
|
+
url = example[1]
|
|
23
|
+
params = example[2]
|
|
24
|
+
|
|
25
|
+
it "for the template #{template} it extracts #{params.keys.join(', ')} from the url" do
|
|
26
|
+
extracted = DHC::Endpoint.values_as_params(template, url)
|
|
27
|
+
expect(extracted).to eq(params)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Error do
|
|
6
|
+
def response(code, timedout = false)
|
|
7
|
+
DHC::Response.new(OpenStruct.new(code: code, 'timed_out?' => timedout), nil)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'find' do
|
|
11
|
+
it 'finds error class by status code' do
|
|
12
|
+
expect(DHC::Error.find(response('0', true))).to eq DHC::Timeout
|
|
13
|
+
expect(DHC::Error.find(response('400'))).to eq DHC::BadRequest
|
|
14
|
+
expect(DHC::Error.find(response('401'))).to eq DHC::Unauthorized
|
|
15
|
+
expect(DHC::Error.find(response('402'))).to eq DHC::PaymentRequired
|
|
16
|
+
expect(DHC::Error.find(response('403'))).to eq DHC::Forbidden
|
|
17
|
+
expect(DHC::Error.find(response('403'))).to eq DHC::Forbidden
|
|
18
|
+
expect(DHC::Error.find(response('404'))).to eq DHC::NotFound
|
|
19
|
+
expect(DHC::Error.find(response('405'))).to eq DHC::MethodNotAllowed
|
|
20
|
+
expect(DHC::Error.find(response('406'))).to eq DHC::NotAcceptable
|
|
21
|
+
expect(DHC::Error.find(response('407'))).to eq DHC::ProxyAuthenticationRequired
|
|
22
|
+
expect(DHC::Error.find(response('408'))).to eq DHC::RequestTimeout
|
|
23
|
+
expect(DHC::Error.find(response('409'))).to eq DHC::Conflict
|
|
24
|
+
expect(DHC::Error.find(response('410'))).to eq DHC::Gone
|
|
25
|
+
expect(DHC::Error.find(response('411'))).to eq DHC::LengthRequired
|
|
26
|
+
expect(DHC::Error.find(response('412'))).to eq DHC::PreconditionFailed
|
|
27
|
+
expect(DHC::Error.find(response('413'))).to eq DHC::RequestEntityTooLarge
|
|
28
|
+
expect(DHC::Error.find(response('414'))).to eq DHC::RequestUriToLong
|
|
29
|
+
expect(DHC::Error.find(response('415'))).to eq DHC::UnsupportedMediaType
|
|
30
|
+
expect(DHC::Error.find(response('416'))).to eq DHC::RequestedRangeNotSatisfiable
|
|
31
|
+
expect(DHC::Error.find(response('417'))).to eq DHC::ExpectationFailed
|
|
32
|
+
expect(DHC::Error.find(response('422'))).to eq DHC::UnprocessableEntity
|
|
33
|
+
expect(DHC::Error.find(response('423'))).to eq DHC::Locked
|
|
34
|
+
expect(DHC::Error.find(response('424'))).to eq DHC::FailedDependency
|
|
35
|
+
expect(DHC::Error.find(response('426'))).to eq DHC::UpgradeRequired
|
|
36
|
+
expect(DHC::Error.find(response('500'))).to eq DHC::InternalServerError
|
|
37
|
+
expect(DHC::Error.find(response('501'))).to eq DHC::NotImplemented
|
|
38
|
+
expect(DHC::Error.find(response('502'))).to eq DHC::BadGateway
|
|
39
|
+
expect(DHC::Error.find(response('503'))).to eq DHC::ServiceUnavailable
|
|
40
|
+
expect(DHC::Error.find(response('504'))).to eq DHC::GatewayTimeout
|
|
41
|
+
expect(DHC::Error.find(response('505'))).to eq DHC::HttpVersionNotSupported
|
|
42
|
+
expect(DHC::Error.find(response('507'))).to eq DHC::InsufficientStorage
|
|
43
|
+
expect(DHC::Error.find(response('510'))).to eq DHC::NotExtended
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'finds error class also by extended status codes' do
|
|
47
|
+
expect(DHC::Error.find(response('40001'))).to eq DHC::BadRequest
|
|
48
|
+
expect(DHC::Error.find(response('50002'))).to eq DHC::InternalServerError
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'returns UnknownError if no specific error was found' do
|
|
52
|
+
expect(DHC::Error.find(response('0'))).to eq DHC::UnknownError
|
|
53
|
+
expect(DHC::Error.find(response(''))).to eq DHC::UnknownError
|
|
54
|
+
expect(DHC::Error.find(response('600'))).to eq DHC::UnknownError
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Error do
|
|
6
|
+
context 'response' do
|
|
7
|
+
it 'throws timeout exception in case of a timeout' do
|
|
8
|
+
stub_request(:any, 'depay.fi').to_return(status: 403)
|
|
9
|
+
begin
|
|
10
|
+
DHC.get('depay.fi')
|
|
11
|
+
rescue => e
|
|
12
|
+
expect(e.response).to be_kind_of(DHC::Response)
|
|
13
|
+
expect(e.response.code).to eq 403
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Error do
|
|
6
|
+
context 'timeout' do
|
|
7
|
+
it 'throws timeout exception in case of a timeout' do
|
|
8
|
+
stub_request(:any, 'depay.fi').to_timeout
|
|
9
|
+
expect(lambda {
|
|
10
|
+
DHC.get('depay.fi')
|
|
11
|
+
}).to raise_error DHC::Timeout
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC::Error do
|
|
6
|
+
context 'to_s' do
|
|
7
|
+
let(:invalid) { (+"in\xc3lid").force_encoding('ASCII-8BIT') }
|
|
8
|
+
let(:valid) { 'vælid' }
|
|
9
|
+
|
|
10
|
+
context 'check assumptions' do
|
|
11
|
+
it 'joining raises an error' do
|
|
12
|
+
expect { [valid, invalid].join }.to raise_error Encoding::CompatibilityError
|
|
13
|
+
end
|
|
14
|
+
it 'interpolation raises an error' do
|
|
15
|
+
expect { "#{valid} #{invalid}" }.to raise_error Encoding::CompatibilityError
|
|
16
|
+
end
|
|
17
|
+
it 'to_json on an array raises an error' do
|
|
18
|
+
expect { [valid, invalid].to_json }.to raise_error Encoding::UndefinedConversionError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'to_s on a hash does not raise an error' do
|
|
22
|
+
expect { { valid: valid, invalid: invalid }.to_s }.not_to raise_error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'to_json on a hash does raise an error' do
|
|
26
|
+
expect { { valid: valid, invalid: invalid }.to_json }.to raise_error Encoding::UndefinedConversionError
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'invalid body, valid message' do
|
|
31
|
+
stub_request(:get, 'http://depay.fi')
|
|
32
|
+
.to_return(status: 200, body: "{ text : '#{invalid}' }")
|
|
33
|
+
response = DHC.get('http://depay.fi')
|
|
34
|
+
expect { DHC::Error.new(valid, response).to_s }.not_to raise_error # Encoding::CompatibilityError
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'valid body, invalid message' do
|
|
38
|
+
stub_request(:get, 'http://depay.fi')
|
|
39
|
+
.to_return(status: 200, body: "{ text : '#{valid}' }")
|
|
40
|
+
response = DHC.get('http://depay.fi')
|
|
41
|
+
expect { DHC::Error.new(invalid, response).to_s }.not_to raise_error # Encoding::CompatibilityError
|
|
42
|
+
end
|
|
43
|
+
# the other cases cannot be tested (for example what happens if the headers contain invalid data)
|
|
44
|
+
# because the mocking framework triggers the encoding error already
|
|
45
|
+
|
|
46
|
+
context 'some mocked response' do
|
|
47
|
+
let(:request) do
|
|
48
|
+
double('DHC::Request',
|
|
49
|
+
method: 'GET',
|
|
50
|
+
url: 'http://example.com/sessions',
|
|
51
|
+
headers: { 'Bearer Token' => 'aaaaaaaa-bbbb-cccc-dddd-eeee' },
|
|
52
|
+
options: { followlocation: true,
|
|
53
|
+
auth: { bearer: 'aaaaaaaa-bbbb-cccc-dddd-eeee' },
|
|
54
|
+
params: { limit: 20 }, url: 'http://example.com/sessions' })
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
let(:response) do
|
|
58
|
+
double('DHC::Response',
|
|
59
|
+
request: request,
|
|
60
|
+
code: 500,
|
|
61
|
+
options: { return_code: :internal_error, response_headers: '' },
|
|
62
|
+
body: '{"status":500,"message":"undefined"}')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
subject { DHC::Error.new('The error message', response) }
|
|
66
|
+
|
|
67
|
+
before do
|
|
68
|
+
allow(request).to receive(:is_a?).with(DHC::Request).and_return(true)
|
|
69
|
+
allow(response).to receive(:is_a?).with(DHC::Response).and_return(true)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'produces correct debug output' do
|
|
73
|
+
expect(subject.to_s.split("\n")).to eq(<<-MSG.strip_heredoc.split("\n"))
|
|
74
|
+
GET http://example.com/sessions
|
|
75
|
+
Options: {:followlocation=>true, :auth=>{:bearer=>"aaaaaaaa-bbbb-cccc-dddd-eeee"}, :params=>{:limit=>20}, :url=>"http://example.com/sessions"}
|
|
76
|
+
Headers: {"Bearer Token"=>"aaaaaaaa-bbbb-cccc-dddd-eeee"}
|
|
77
|
+
Response Code: 500 (internal_error)
|
|
78
|
+
Response Options: {:return_code=>:internal_error, :response_headers=>""}
|
|
79
|
+
{"status":500,"message":"undefined"}
|
|
80
|
+
The error message
|
|
81
|
+
MSG
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC do
|
|
6
|
+
include ActionDispatch::TestProcess
|
|
7
|
+
|
|
8
|
+
context 'form' do
|
|
9
|
+
it 'formats requests to be application/x-www-form-urlencoded' do
|
|
10
|
+
stub = stub_request(:post, 'http://depay.fi/')
|
|
11
|
+
.with(body: 'client_id=1234&client_secret=4567&grant_type=client_credentials')
|
|
12
|
+
.with(headers: { 'Content-Type': 'application/x-www-form-urlencoded' })
|
|
13
|
+
.to_return(status: 200)
|
|
14
|
+
|
|
15
|
+
DHC.form.post(
|
|
16
|
+
'http://depay.fi',
|
|
17
|
+
body: {
|
|
18
|
+
client_id: '1234',
|
|
19
|
+
client_secret: '4567',
|
|
20
|
+
grant_type: 'client_credentials'
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
expect(stub).to have_been_requested
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC do
|
|
6
|
+
context 'formats' do
|
|
7
|
+
it 'adds Content-Type, Accept and Accept-Charset Headers to the request' 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: {}.to_json)
|
|
15
|
+
DHC.json.get('http://depay.fi')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context 'header key as symbol' do
|
|
19
|
+
it 'raises an error when trying to set content-type header even though the format is used' do
|
|
20
|
+
expect(lambda {
|
|
21
|
+
DHC.post(
|
|
22
|
+
'http://depay.fi',
|
|
23
|
+
headers: {
|
|
24
|
+
'Content-Type': 'multipart/form-data'
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}).to raise_error 'Content-Type header is not allowed for formatted requests!\nSee https://github.com/DePayFi/dhc#formats for more information.'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'raises an error when trying to set accept header even though the format is used' do
|
|
31
|
+
expect(lambda {
|
|
32
|
+
DHC.post(
|
|
33
|
+
'http://depay.fi',
|
|
34
|
+
headers: {
|
|
35
|
+
'Accept': 'multipart/form-data'
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
}).to raise_error 'Accept header is not allowed for formatted requests!\nSee https://github.com/DePayFi/dhc#formats for more information.'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'header key as string' do
|
|
43
|
+
it 'raises an error when trying to set content-type header even though the format is used' do
|
|
44
|
+
expect(lambda {
|
|
45
|
+
DHC.post(
|
|
46
|
+
'http://depay.fi',
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type' => 'multipart/form-data'
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
}).to raise_error 'Content-Type header is not allowed for formatted requests!\nSee https://github.com/DePayFi/dhc#formats for more information.'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'raises an error when trying to set accept header even though the format is used' do
|
|
55
|
+
expect(lambda {
|
|
56
|
+
DHC.post(
|
|
57
|
+
'http://depay.fi',
|
|
58
|
+
headers: {
|
|
59
|
+
'Accept' => 'multipart/form-data'
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
}).to raise_error 'Accept header is not allowed for formatted requests!\nSee https://github.com/DePayFi/dhc#formats for more information.'
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC do
|
|
6
|
+
include ActionDispatch::TestProcess
|
|
7
|
+
|
|
8
|
+
context 'multipart' do
|
|
9
|
+
let(:file) { Rack::Test::UploadedFile.new(Tempfile.new) }
|
|
10
|
+
let(:body) { { size: 2231 }.to_json }
|
|
11
|
+
let(:location) { 'http://depay.fi/uploads/image.jpg' }
|
|
12
|
+
|
|
13
|
+
it 'formats requests to be multipart/form-data' do
|
|
14
|
+
stub_request(:post, 'http://depay.fi/') do |request|
|
|
15
|
+
raise 'Content-Type header wrong' unless request.headers['Content-Type'] == 'multipart/form-data'
|
|
16
|
+
raise 'Body wrongly formatted' unless request.body.match(/file=%23%3CActionDispatch%3A%3AHttp%3A%3AUploadedFile%3A.*%3E&type=Image/)
|
|
17
|
+
end.to_return(status: 200, body: body, headers: { 'Location' => location })
|
|
18
|
+
response = DHC.multipart.post(
|
|
19
|
+
'http://depay.fi',
|
|
20
|
+
body: { file: file, type: 'Image' }
|
|
21
|
+
)
|
|
22
|
+
expect(response.body).to eq body
|
|
23
|
+
expect(response.headers['Location']).to eq location
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC do
|
|
6
|
+
include ActionDispatch::TestProcess
|
|
7
|
+
|
|
8
|
+
context 'plain' do
|
|
9
|
+
let(:file) { Rack::Test::UploadedFile.new(Tempfile.new) }
|
|
10
|
+
|
|
11
|
+
it 'leaves plains requests unformatted' do
|
|
12
|
+
stub_request(:post, 'http://depay.fi/')
|
|
13
|
+
.with(body: /file=%23%3CRack%3A%3ATest%3A%3AUploadedFile%3.*%3E&type=Image/)
|
|
14
|
+
.to_return do |request|
|
|
15
|
+
expect(request.headers['Content-Type']).to be_blank
|
|
16
|
+
|
|
17
|
+
{ status: 204 }
|
|
18
|
+
end
|
|
19
|
+
response = DHC.plain.post(
|
|
20
|
+
'http://depay.fi',
|
|
21
|
+
body: { file: file, type: 'Image' }
|
|
22
|
+
)
|
|
23
|
+
expect(lambda {
|
|
24
|
+
response.body
|
|
25
|
+
response.data
|
|
26
|
+
}).not_to raise_error
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHC do
|
|
6
|
+
context 'interceptor' do
|
|
7
|
+
before(:each) do
|
|
8
|
+
class SomeInterceptor < DHC::Interceptor
|
|
9
|
+
def after_request; end
|
|
10
|
+
end
|
|
11
|
+
DHC.configure { |c| c.interceptors = [SomeInterceptor] }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'can perform some actions after a request was fired' do
|
|
15
|
+
expect_any_instance_of(SomeInterceptor).to receive(:after_request)
|
|
16
|
+
stub_request(:get, 'http://depay.fi')
|
|
17
|
+
DHC.get('http://depay.fi')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|