lhc 0.2.1

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 (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/Gemfile +11 -0
  4. data/README.md +116 -0
  5. data/Rakefile +25 -0
  6. data/docs/configuration.md +57 -0
  7. data/docs/exceptions.md +68 -0
  8. data/docs/interceptors.md +90 -0
  9. data/docs/request.md +24 -0
  10. data/docs/response.md +19 -0
  11. data/lhc.gemspec +30 -0
  12. data/lib/lhc.rb +16 -0
  13. data/lib/lhc/concerns/lhc/basic_methods.rb +42 -0
  14. data/lib/lhc/config.rb +45 -0
  15. data/lib/lhc/endpoint.rb +53 -0
  16. data/lib/lhc/error.rb +63 -0
  17. data/lib/lhc/errors/client_error.rb +73 -0
  18. data/lib/lhc/errors/server_error.rb +28 -0
  19. data/lib/lhc/errors/timeout.rb +4 -0
  20. data/lib/lhc/errors/unknown_error.rb +4 -0
  21. data/lib/lhc/interceptor.rb +9 -0
  22. data/lib/lhc/interceptor_processor.rb +24 -0
  23. data/lib/lhc/request.rb +91 -0
  24. data/lib/lhc/response.rb +52 -0
  25. data/lib/lhc/version.rb +3 -0
  26. data/script/ci/build.sh +19 -0
  27. data/spec/basic_methods/delete_spec.rb +34 -0
  28. data/spec/basic_methods/get_spec.rb +37 -0
  29. data/spec/basic_methods/post_spec.rb +42 -0
  30. data/spec/basic_methods/put_spec.rb +48 -0
  31. data/spec/basic_methods/request_spec.rb +19 -0
  32. data/spec/config/endpoints_spec.rb +49 -0
  33. data/spec/config/placeholders_spec.rb +32 -0
  34. data/spec/dummy/README.rdoc +28 -0
  35. data/spec/dummy/Rakefile +6 -0
  36. data/spec/dummy/app/assets/images/.keep +0 -0
  37. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  38. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  39. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  40. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  41. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  42. data/spec/dummy/app/mailers/.keep +0 -0
  43. data/spec/dummy/app/models/.keep +0 -0
  44. data/spec/dummy/app/models/concerns/.keep +0 -0
  45. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  46. data/spec/dummy/bin/bundle +3 -0
  47. data/spec/dummy/bin/rails +4 -0
  48. data/spec/dummy/bin/rake +4 -0
  49. data/spec/dummy/config.ru +4 -0
  50. data/spec/dummy/config/application.rb +14 -0
  51. data/spec/dummy/config/boot.rb +5 -0
  52. data/spec/dummy/config/environment.rb +5 -0
  53. data/spec/dummy/config/environments/development.rb +34 -0
  54. data/spec/dummy/config/environments/production.rb +75 -0
  55. data/spec/dummy/config/environments/test.rb +39 -0
  56. data/spec/dummy/config/initializers/assets.rb +8 -0
  57. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  58. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  59. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  60. data/spec/dummy/config/initializers/inflections.rb +16 -0
  61. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  62. data/spec/dummy/config/initializers/session_store.rb +3 -0
  63. data/spec/dummy/config/initializers/wrap_parameters.rb +9 -0
  64. data/spec/dummy/config/locales/en.yml +23 -0
  65. data/spec/dummy/config/routes.rb +56 -0
  66. data/spec/dummy/config/secrets.yml +22 -0
  67. data/spec/dummy/lib/assets/.keep +0 -0
  68. data/spec/dummy/log/.keep +0 -0
  69. data/spec/dummy/public/404.html +67 -0
  70. data/spec/dummy/public/422.html +67 -0
  71. data/spec/dummy/public/500.html +66 -0
  72. data/spec/dummy/public/favicon.ico +0 -0
  73. data/spec/endpoint/compile_spec.rb +25 -0
  74. data/spec/endpoint/placeholders_spec.rb +14 -0
  75. data/spec/endpoint/remove_interpolated_params_spec.rb +16 -0
  76. data/spec/error/find_spec.rb +56 -0
  77. data/spec/error/response_spec.rb +17 -0
  78. data/spec/error/timeout_spec.rb +14 -0
  79. data/spec/interceptors/after_request_spec.rb +21 -0
  80. data/spec/interceptors/after_response_spec.rb +42 -0
  81. data/spec/interceptors/before_request_spec.rb +21 -0
  82. data/spec/interceptors/before_response_spec.rb +21 -0
  83. data/spec/interceptors/default_interceptors_spec.rb +15 -0
  84. data/spec/interceptors/define_spec.rb +29 -0
  85. data/spec/interceptors/response_competition_spec.rb +40 -0
  86. data/spec/interceptors/return_response_spec.rb +39 -0
  87. data/spec/rails_helper.rb +4 -0
  88. data/spec/request/error_handling_spec.rb +52 -0
  89. data/spec/request/headers_spec.rb +11 -0
  90. data/spec/request/option_dup_spec.rb +12 -0
  91. data/spec/request/parallel_requests_spec.rb +15 -0
  92. data/spec/request/url_patterns_spec.rb +19 -0
  93. data/spec/response/body_spec.rb +16 -0
  94. data/spec/response/code_spec.rb +16 -0
  95. data/spec/response/data_spec.rb +18 -0
  96. data/spec/response/headers_spec.rb +18 -0
  97. data/spec/response/success_spec.rb +12 -0
  98. data/spec/response/time_spec.rb +16 -0
  99. data/spec/spec_helper.rb +4 -0
  100. data/spec/support/fixtures/json/feedback.json +11 -0
  101. data/spec/support/fixtures/json/feedbacks.json +164 -0
  102. data/spec/support/fixtures/json/localina_content_ad.json +23 -0
  103. data/spec/support/load_json.rb +3 -0
  104. data/spec/support/reset_config.rb +7 -0
  105. data/spec/timeouts/no_signal_spec.rb +13 -0
  106. data/spec/timeouts/timings_spec.rb +59 -0
  107. metadata +313 -0
@@ -0,0 +1,67 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>The change you wanted was rejected (422)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/422.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>The change you wanted was rejected.</h1>
62
+ <p>Maybe you tried to change something you didn't have access to.</p>
63
+ </div>
64
+ <p>If you are the application owner check the logs for more information.</p>
65
+ </div>
66
+ </body>
67
+ </html>
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ body {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body>
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
@@ -0,0 +1,25 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Endpoint do
4
+
5
+ context 'compile' do
6
+
7
+ it 'uses parameters for interpolation' do
8
+ endpoint = LHC::Endpoint.new(':datastore/v2/:campaign_id/feedbacks')
9
+ expect(
10
+ endpoint.compile(datastore: 'http://datastore.lb-service', campaign_id: 'abc')
11
+ ).to eq "http://datastore.lb-service/v2/abc/feedbacks"
12
+ end
13
+
14
+ it 'uses provided proc to find values' do
15
+ endpoint = LHC::Endpoint.new(':datastore/v2')
16
+ config = { datastore: 'http://datastore.lb-service' }
17
+ find_value = ->(match){
18
+ config[match.gsub(':', '').to_sym]
19
+ }
20
+ expect(
21
+ endpoint.compile(find_value)
22
+ ).to eq "http://datastore.lb-service/v2"
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Endpoint do
4
+
5
+ context 'placeholders' do
6
+
7
+ it 'returns all placeholders alphabetically sorted' do
8
+ endpoint = LHC::Endpoint.new(':datastore/v2/:campaign_id/feedbacks')
9
+ expect(
10
+ endpoint.placeholders
11
+ ).to eq [':campaign_id', ':datastore']
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Endpoint do
4
+
5
+ it 'removes params used for interpolation' do
6
+ params = {
7
+ datastore: 'http://datastore.lb-service',
8
+ campaign_id: 'abc',
9
+ has_reviews: true
10
+ }
11
+ endpoint = LHC::Endpoint.new(':datastore/v2/:campaign_id/feedbacks')
12
+ removed = endpoint.remove_interpolated_params!(params)
13
+ expect(params).to eq ({ has_reviews: true })
14
+ expect(removed).to eq(datastore: 'http://datastore.lb-service', campaign_id: 'abc')
15
+ end
16
+ end
@@ -0,0 +1,56 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Error do
4
+
5
+ def response(code)
6
+ LHC::Response.new(OpenStruct.new({code: code}), nil)
7
+ end
8
+
9
+ context 'find' do
10
+
11
+ it 'finds error class by status code' do
12
+ expect(LHC::Error.find(response('400'))).to eq LHC::BadRequest
13
+ expect(LHC::Error.find(response('401'))).to eq LHC::Unauthorized
14
+ expect(LHC::Error.find(response('402'))).to eq LHC::PaymentRequired
15
+ expect(LHC::Error.find(response('403'))).to eq LHC::Forbidden
16
+ expect(LHC::Error.find(response('403'))).to eq LHC::Forbidden
17
+ expect(LHC::Error.find(response('404'))).to eq LHC::NotFound
18
+ expect(LHC::Error.find(response('405'))).to eq LHC::MethodNotAllowed
19
+ expect(LHC::Error.find(response('406'))).to eq LHC::NotAcceptable
20
+ expect(LHC::Error.find(response('407'))).to eq LHC::ProxyAuthenticationRequired
21
+ expect(LHC::Error.find(response('408'))).to eq LHC::RequestTimeout
22
+ expect(LHC::Error.find(response('409'))).to eq LHC::Conflict
23
+ expect(LHC::Error.find(response('410'))).to eq LHC::Gone
24
+ expect(LHC::Error.find(response('411'))).to eq LHC::LengthRequired
25
+ expect(LHC::Error.find(response('412'))).to eq LHC::PreconditionFailed
26
+ expect(LHC::Error.find(response('413'))).to eq LHC::RequestEntityTooLarge
27
+ expect(LHC::Error.find(response('414'))).to eq LHC::RequestUriToLong
28
+ expect(LHC::Error.find(response('415'))).to eq LHC::UnsupportedMediaType
29
+ expect(LHC::Error.find(response('416'))).to eq LHC::RequestedRangeNotSatisfiable
30
+ expect(LHC::Error.find(response('417'))).to eq LHC::ExpectationFailed
31
+ expect(LHC::Error.find(response('422'))).to eq LHC::UnprocessableEntity
32
+ expect(LHC::Error.find(response('423'))).to eq LHC::Locked
33
+ expect(LHC::Error.find(response('424'))).to eq LHC::FailedDependency
34
+ expect(LHC::Error.find(response('426'))).to eq LHC::UpgradeRequired
35
+ expect(LHC::Error.find(response('500'))).to eq LHC::InternalServerError
36
+ expect(LHC::Error.find(response('501'))).to eq LHC::NotImplemented
37
+ expect(LHC::Error.find(response('502'))).to eq LHC::BadGateway
38
+ expect(LHC::Error.find(response('503'))).to eq LHC::ServiceUnavailable
39
+ expect(LHC::Error.find(response('504'))).to eq LHC::GatewayTimeout
40
+ expect(LHC::Error.find(response('505'))).to eq LHC::HttpVersionNotSupported
41
+ expect(LHC::Error.find(response('507'))).to eq LHC::InsufficientStorage
42
+ expect(LHC::Error.find(response('510'))).to eq LHC::NotExtended
43
+ end
44
+
45
+ it 'finds error class also by extended status codes' do
46
+ expect(LHC::Error.find(response('40001'))).to eq LHC::BadRequest
47
+ expect(LHC::Error.find(response('50002'))).to eq LHC::InternalServerError
48
+ end
49
+
50
+ it 'returns UnknownError if no specific error was found' do
51
+ expect(LHC::Error.find(response('0'))).to eq LHC::UnknownError
52
+ expect(LHC::Error.find(response(''))).to eq LHC::UnknownError
53
+ expect(LHC::Error.find(response('600'))).to eq LHC::UnknownError
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Error do
4
+
5
+ context 'response' do
6
+
7
+ it 'throws timeout exception in case of a timeout' do
8
+ stub_request(:any, 'local.ch').to_return(status: 403)
9
+ begin
10
+ LHC.get('local.ch')
11
+ rescue => e
12
+ expect(e.response).to be_kind_of(LHC::Response)
13
+ expect(e.response.code).to eq 403
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Error do
4
+
5
+ context 'timeout' do
6
+
7
+ it 'throws timeout exception in case of a timeout' do
8
+ stub_request(:any, 'local.ch').to_timeout
9
+ expect(->{
10
+ LHC.get('local.ch')
11
+ }).to raise_error LHC::Timeout
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor' do
6
+
7
+ before(:each) do
8
+ class SomeInterceptor < LHC::Interceptor
9
+ def after_request(request)
10
+ end
11
+ end
12
+ LHC.configure { |c| c.interceptors = [SomeInterceptor] }
13
+ end
14
+
15
+ it 'can perform some actions after a request was fired' do
16
+ expect_any_instance_of(SomeInterceptor).to receive(:after_request)
17
+ stub_request(:get, 'http://local.ch')
18
+ LHC.get('http://local.ch')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor' do
6
+
7
+ before(:each) do
8
+ class Services
9
+ def self.timing(path, time)
10
+ end
11
+ end
12
+ end
13
+
14
+ before(:each) do
15
+ class StatsTimingInterceptor < LHC::Interceptor
16
+ def after_response(response)
17
+ uri = URI.parse(response.request.url)
18
+ path = [
19
+ 'web',
20
+ Rails.application.class.parent_name,
21
+ Rails.env,
22
+ response.request.method,
23
+ uri.scheme,
24
+ uri.host,
25
+ response.code
26
+ ].join('.')
27
+ Services.timing(path.downcase, response.time)
28
+ end
29
+ end
30
+ LHC.configure { |c| c.interceptors = [StatsTimingInterceptor] }
31
+ end
32
+
33
+ let(:url) { "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/-Sc4_pYNpqfsudzhtivfkA" }
34
+
35
+ it 'can take action after a response was received' do
36
+ allow(Services).to receive(:timing).with('web.dummy.test.get.http.datastore-stg.lb-service.sunrise.intra.local.ch.200', 0)
37
+ stub_request(:get, url)
38
+ LHC.get(url)
39
+ expect(Services).to have_received(:timing)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,21 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor' do
6
+
7
+ before(:each) do
8
+ class TrackingIdInterceptor < LHC::Interceptor
9
+ def before_request(request)
10
+ request.params[:tid] = 123
11
+ end
12
+ end
13
+ LHC.configure { |c| c.interceptors = [TrackingIdInterceptor] }
14
+ end
15
+
16
+ it 'can modify requests before they are send' do
17
+ stub_request(:get, "http://local.ch/?tid=123")
18
+ LHC.get('http://local.ch')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor' do
6
+
7
+ before(:each) do
8
+ class SomeInterceptor < LHC::Interceptor
9
+ def before_response(request)
10
+ end
11
+ end
12
+ LHC.configure { |c| c.interceptors = [SomeInterceptor] }
13
+ end
14
+
15
+ it 'can perform some actions before a reponse is received' do
16
+ expect_any_instance_of(SomeInterceptor).to receive(:before_response)
17
+ stub_request(:get, 'http://local.ch')
18
+ LHC.get('http://local.ch')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'default interceptors' do
6
+
7
+ before(:each) do
8
+ LHC.configure {}
9
+ end
10
+
11
+ it 'should always return a list for default interceptors' do
12
+ expect(LHC.config.interceptors).to eq []
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor' do
6
+
7
+ before(:each) do
8
+ class SomeInterceptor < LHC::Interceptor
9
+ end
10
+ class AnotherInterceptor < LHC::Interceptor
11
+ end
12
+ end
13
+
14
+ it 'performs interceptor when they are set globally' do
15
+ LHC.configure { |c| c.interceptors = [SomeInterceptor] }
16
+ expect_any_instance_of(SomeInterceptor).to receive(:before_request)
17
+ stub_request(:get, 'http://local.ch')
18
+ LHC.get('http://local.ch')
19
+ end
20
+
21
+ it 'overrides interceptors on request level' do
22
+ LHC.configure { |c| c.interceptors = [SomeInterceptor] }
23
+ expect_any_instance_of(AnotherInterceptor).to receive(:before_request)
24
+ expect_any_instance_of(SomeInterceptor).not_to receive(:before_request)
25
+ stub_request(:get, 'http://local.ch')
26
+ LHC.get('http://local.ch', interceptors: [AnotherInterceptor])
27
+ end
28
+ end
29
+ end