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,40 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor response competition' do
6
+
7
+ before(:each) do
8
+
9
+ class LocalCacheInterceptor < LHC::Interceptor
10
+ @@cached = false
11
+ cattr_accessor :cached
12
+
13
+ def before_request(request)
14
+ if @@cached
15
+ return LHC::Response.new(Typhoeus::Response.new(response_body: 'Im served from local cache'), nil)
16
+ end
17
+ end
18
+ end
19
+
20
+ class RemoteCacheInterceptor < LHC::Interceptor
21
+
22
+ def before_request(request)
23
+ if request.response.nil?
24
+ return LHC::Response.new(Typhoeus::Response.new(response_body: 'Im served from remote cache'), nil)
25
+ end
26
+ end
27
+ end
28
+
29
+ LHC.configure { |c| c.interceptors = [LocalCacheInterceptor, RemoteCacheInterceptor] }
30
+ end
31
+
32
+ it 'can handle multiple interceptors that compete for returning the response' do
33
+ response = LHC.get('http://local.ch')
34
+ expect(response.body).to eq 'Im served from remote cache'
35
+ LocalCacheInterceptor.cached = true
36
+ response = LHC.get('http://local.ch')
37
+ expect(response.body).to eq 'Im served from local cache'
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC do
4
+
5
+ context 'interceptor' do
6
+
7
+ before(:each) do
8
+ class CacheInterceptor < LHC::Interceptor
9
+
10
+ def before_request(request)
11
+ return LHC::Response.new(Typhoeus::Response.new(response_body: 'Im served from cache'), nil)
12
+ end
13
+ end
14
+ LHC.configure { |c| c.interceptors = [CacheInterceptor] }
15
+ end
16
+
17
+ it 'can return a response rather then doing a real request' do
18
+ response = LHC.get('http://local.ch')
19
+ expect(response.body).to eq 'Im served from cache'
20
+ end
21
+
22
+ context 'misusage' do
23
+
24
+ before(:each) do
25
+ class AnotherInterceptor < LHC::Interceptor
26
+ def before_request(request)
27
+ return LHC::Response.new(Typhoeus::Response.new({}), nil)
28
+ end
29
+ end
30
+ end
31
+
32
+ it 'raises an exception when two interceptors try to return a response' do
33
+ expect(->{
34
+ LHC.get('http://local.ch', interceptors: [CacheInterceptor, AnotherInterceptor])
35
+ }).to raise_error 'Response already set from another interceptor'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+ require File.expand_path("../dummy/config/environment", __FILE__)
3
+
4
+ ENV["RAILS_ENV"] ||= 'test'
@@ -0,0 +1,52 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Request do
4
+
5
+ context 'error handling' do
6
+
7
+ def to_fail_with(error)
8
+ raise_error(error)
9
+ end
10
+
11
+ def expect_status_code(status_code)
12
+ stub_request(:get, "http://something/#{status_code}").to_return(status: status_code)
13
+ expect(
14
+ -> { LHC::Request.new(url: "http://something/#{status_code}") }
15
+ ).to yield
16
+ end
17
+
18
+ it 'raises errors for anything but 2XX response codes' do
19
+ expect_status_code(400) { to_fail_with(LHC::BadRequest) }
20
+ expect_status_code(401) { to_fail_with(LHC::Unauthorized) }
21
+ expect_status_code(402) { to_fail_with(LHC::PaymentRequired) }
22
+ expect_status_code(403) { to_fail_with(LHC::Forbidden) }
23
+ expect_status_code(403) { to_fail_with(LHC::Forbidden) }
24
+ expect_status_code(404) { to_fail_with(LHC::NotFound) }
25
+ expect_status_code(405) { to_fail_with(LHC::MethodNotAllowed) }
26
+ expect_status_code(406) { to_fail_with(LHC::NotAcceptable) }
27
+ expect_status_code(407) { to_fail_with(LHC::ProxyAuthenticationRequired) }
28
+ expect_status_code(408) { to_fail_with(LHC::RequestTimeout) }
29
+ expect_status_code(409) { to_fail_with(LHC::Conflict) }
30
+ expect_status_code(410) { to_fail_with(LHC::Gone) }
31
+ expect_status_code(411) { to_fail_with(LHC::LengthRequired) }
32
+ expect_status_code(412) { to_fail_with(LHC::PreconditionFailed) }
33
+ expect_status_code(413) { to_fail_with(LHC::RequestEntityTooLarge) }
34
+ expect_status_code(414) { to_fail_with(LHC::RequestUriToLong) }
35
+ expect_status_code(415) { to_fail_with(LHC::UnsupportedMediaType) }
36
+ expect_status_code(416) { to_fail_with(LHC::RequestedRangeNotSatisfiable) }
37
+ expect_status_code(417) { to_fail_with(LHC::ExpectationFailed) }
38
+ expect_status_code(422) { to_fail_with(LHC::UnprocessableEntity) }
39
+ expect_status_code(423) { to_fail_with(LHC::Locked) }
40
+ expect_status_code(424) { to_fail_with(LHC::FailedDependency) }
41
+ expect_status_code(426) { to_fail_with(LHC::UpgradeRequired) }
42
+ expect_status_code(500) { to_fail_with(LHC::InternalServerError) }
43
+ expect_status_code(501) { to_fail_with(LHC::NotImplemented) }
44
+ expect_status_code(502) { to_fail_with(LHC::BadGateway) }
45
+ expect_status_code(503) { to_fail_with(LHC::ServiceUnavailable) }
46
+ expect_status_code(504) { to_fail_with(LHC::GatewayTimeout) }
47
+ expect_status_code(505) { to_fail_with(LHC::HttpVersionNotSupported) }
48
+ expect_status_code(507) { to_fail_with(LHC::InsufficientStorage) }
49
+ expect_status_code(510) { to_fail_with(LHC::NotExtended) }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,11 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Request do
4
+
5
+ it 'provides request headers' do
6
+ stub_request(:get, 'http://local.ch')
7
+ response = LHC.get('http://local.ch')
8
+ request = response.request
9
+ expect(request.headers).to eq({"User-Agent"=>"Typhoeus - https://github.com/typhoeus/typhoeus"})
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Request do
4
+
5
+ it 'does not alter the options that where passed' do
6
+ LHC.configure { |c| c.endpoint(:kpi_tracker, 'http://analytics.lb-service/track/:entity_id/w', { params: { env: 'PROD' } }) }
7
+ options = { params: { entity_id: '123' } }
8
+ stub_request(:get, "http://analytics.lb-service/track/123/w?env=PROD")
9
+ LHC.get(:kpi_tracker, options)
10
+ expect(options).to eq({ params: { entity_id: '123' } })
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Request do
4
+
5
+ it 'does parallel requests if you provide an array of requests' do
6
+ requests = []
7
+ requests << { url: 'http://www.local.ch/restaurants' }
8
+ requests << { url: 'http://www.local.ch' }
9
+ stub_request(:get, "http://www.local.ch/restaurants").to_return(status: 200, body: '1')
10
+ stub_request(:get, "http://www.local.ch").to_return(status: 200, body: '2')
11
+ responses = LHC.request(requests)
12
+ expect(responses[0].body).to eq '1'
13
+ expect(responses[1].body).to eq '2'
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Request do
4
+
5
+ it 'compiles url in case of configured endpoints' do
6
+ options = { params: {
7
+ has_reviews: true
8
+ }}
9
+ url = 'http://datastore-stg.lb-service/v2/campaign/:campaign_id/feedbacks'
10
+ LHC.configure { |c| c.endpoint(:feedbacks, url, options) }
11
+ stub_request(:get, 'http://datastore-stg.lb-service/v2/campaign/123/feedbacks?has_reviews=true')
12
+ LHC.get(:feedbacks, params:{campaign_id: 123})
13
+ end
14
+
15
+ it 'compiles url when doing a request' do
16
+ stub_request(:get, 'http://datastore-stg.lb-service:8080/v2/feedbacks/123')
17
+ LHC.get('http://datastore-stg.lb-service:8080/v2/feedbacks/:id', params:{id: 123})
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Response do
4
+
5
+ context 'body' do
6
+
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 = LHC::Response.new(raw_response, nil)
13
+ expect(response.body).to eq body
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Response do
4
+
5
+ context 'code' do
6
+
7
+ let(:code) { 200 }
8
+
9
+ let(:raw_response) { OpenStruct.new({ code: code }) }
10
+
11
+ it 'provides response code' do
12
+ response = LHC::Response.new(raw_response, nil)
13
+ expect(response.code).to eq code
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Response do
4
+
5
+ context 'data' do
6
+
7
+ let(:value) { 'some_value' }
8
+
9
+ let(:body) {{ some_key: {nested: value} }}
10
+
11
+ let(:raw_response) { OpenStruct.new({ body: body.to_json }) }
12
+
13
+ it 'makes data from response body available' do
14
+ response = LHC::Response.new(raw_response, nil)
15
+ expect(response.data.some_key.nested).to eq value
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Response do
4
+
5
+ context 'headers' do
6
+
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 = LHC::Response.new(raw_response, nil)
15
+ expect(response.headers).to eq headers
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Response do
4
+
5
+ context 'success?' do
6
+ let(:response_success) { LHC::Response.new(Typhoeus::Response.new(response_code: 200, mock: true), nil) }
7
+ let(:response_error) { LHC::Response.new(Typhoeus::Response.new(response_code: 404, mock: true), nil) }
8
+
9
+ it { expect(response_success.success?).to be_truthy }
10
+ it { expect(response_error.success?).to be_falsy }
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails_helper'
2
+
3
+ describe LHC::Response do
4
+
5
+ context 'time' do
6
+
7
+ let(:time) { 1.3 }
8
+
9
+ let(:raw_response) { OpenStruct.new({time: time}) }
10
+
11
+ it 'provides response time in milliseconds' do
12
+ response = LHC::Response.new(raw_response, nil)
13
+ expect(response.time).to eq time*1000
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ require 'pry'
2
+ require 'webmock/rspec'
3
+
4
+ Dir[File.join(__dir__, "support/**/*.rb")].each {|f| require f}
@@ -0,0 +1,11 @@
1
+ {
2
+ "href": "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/-Sc4_pYNpqfsudzhtivfkA",
3
+ "campaign": {
4
+ "href": "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc5690cf271c375c5a12d"
5
+ },
6
+ "source_id": "aaa",
7
+ "recommended": true,
8
+ "modified": "2014-09-19T14:03:35.599+02:00",
9
+ "created_date": "2014-09-19T14:03:35.597+02:00",
10
+ "comments": []
11
+ }
@@ -0,0 +1,164 @@
1
+ {
2
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/?exclude_hidden=false&offset=0&limit=10",
3
+ "items" : [ {
4
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/0sdaetZ-OWVg4oBiBJ-7IQ",
5
+ "campaign" : {
6
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc5690cf271c375c5a12d"
7
+ },
8
+ "source_id" : "aaa",
9
+ "recommended" : true,
10
+ "ratings" : {
11
+ "ambiente" : 4,
12
+ "service" : 2,
13
+ "food" : 3
14
+ },
15
+ "modified" : "2014-09-18T16:13:32.987+02:00",
16
+ "created_date" : "2014-09-18T16:13:31.496+02:00",
17
+ "average_rating" : 3.0,
18
+ "comments" : [ ]
19
+ }, {
20
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/QsUOQWNJoB-GFUNsX7z0jg",
21
+ "campaign" : {
22
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc5690cf271c375c5a11f"
23
+ },
24
+ "source_id" : "abcdefghs12345",
25
+ "name" : "Steve",
26
+ "recommended" : true,
27
+ "ratings" : {
28
+ "ambiente" : 3,
29
+ "service" : 5,
30
+ "food" : 2
31
+ },
32
+ "modified" : "2014-09-18T15:43:12.134+02:00",
33
+ "created_date" : "2014-09-18T15:42:57.892+02:00",
34
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
35
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
36
+ "average_rating" : 3.3333333333333335,
37
+ "comments" : [ ]
38
+ }, {
39
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/QynNtmpXlsEGvUJ0ekDKVw",
40
+ "campaign" : {
41
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc56b0cf271c375c5a14d"
42
+ },
43
+ "source_id" : "abcdefghs12345",
44
+ "name" : "Steve",
45
+ "recommended" : true,
46
+ "ratings" : {
47
+ "ambiente" : 3,
48
+ "service" : 5,
49
+ "food" : 2
50
+ },
51
+ "modified" : "2014-09-17T11:17:39.660+02:00",
52
+ "created_date" : "2014-09-17T11:17:34.234+02:00",
53
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
54
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
55
+ "average_rating" : 3.3333333333333335,
56
+ "comments" : [ ]
57
+ }, {
58
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/INmminYWNZwW_qNFx5peJQ",
59
+ "campaign" : {
60
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc56b0cf271c375c5a153"
61
+ },
62
+ "source_id" : "abcdefghs12345",
63
+ "name" : "Steve",
64
+ "recommended" : true,
65
+ "ratings" : {
66
+ "ambiente" : 3,
67
+ "service" : 5,
68
+ "food" : 2
69
+ },
70
+ "modified" : "2014-09-16T11:20:32.600+02:00",
71
+ "created_date" : "2014-09-16T11:20:30.194+02:00",
72
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
73
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
74
+ "average_rating" : 3.3333333333333335,
75
+ "comments" : [ ]
76
+ }, {
77
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/ltgfr0VRYDN2nxyC119wTg",
78
+ "campaign" : {
79
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc56b0cf271c375c5a14c"
80
+ },
81
+ "source_id" : "aaa",
82
+ "recommended" : false,
83
+ "ratings" : {
84
+ "ambiente" : 2,
85
+ "service" : 1,
86
+ "food" : 1
87
+ },
88
+ "modified" : "2014-09-15T16:23:54.898+02:00",
89
+ "created_date" : "2014-09-15T16:23:40.355+02:00",
90
+ "average_rating" : 1.3333333333333333,
91
+ "comments" : [ ]
92
+ }, {
93
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/5dUdQP-kZ6sulN8NtpGXTw",
94
+ "campaign" : {
95
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc56b0cf271c375c5a14c"
96
+ },
97
+ "source_id" : "abcdefghs12345",
98
+ "name" : "Steve",
99
+ "recommended" : true,
100
+ "ratings" : {
101
+ "ambiente" : 3,
102
+ "service" : 5,
103
+ "food" : 2
104
+ },
105
+ "modified" : "2014-09-12T13:10:51.220+02:00",
106
+ "created_date" : "2014-09-12T13:10:48.813+02:00",
107
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
108
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
109
+ "average_rating" : 3.3333333333333335,
110
+ "comments" : [ ]
111
+ }, {
112
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/Z3KfWzIEQ3ZVCUj2IdrSNQ",
113
+ "campaign" : {
114
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc5690cf271c375c5a12e"
115
+ },
116
+ "source_id" : "abcdefghs",
117
+ "recommended" : true,
118
+ "modified" : "2014-09-10T16:57:36.255+02:00",
119
+ "created_date" : "2014-09-10T16:57:36.254+02:00",
120
+ "comments" : [ ]
121
+ }, {
122
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/ZUUUeiw-Stw5Zb1baHDUzQ",
123
+ "campaign" : {
124
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc5690cf271c375c5a12d"
125
+ },
126
+ "source_id" : "abcdefghs",
127
+ "recommended" : true,
128
+ "modified" : "2014-09-10T16:57:32.792+02:00",
129
+ "created_date" : "2014-09-10T16:57:32.791+02:00",
130
+ "comments" : [ ]
131
+ }, {
132
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/GyeWvhEtU4cYN_5T2FX2UA",
133
+ "campaign" : {
134
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/539266ec0cf2cd754583cfa0"
135
+ },
136
+ "source_id" : "abcdefghs",
137
+ "name" : "aa",
138
+ "recommended" : true,
139
+ "ratings" : {
140
+ "ambiente" : 2,
141
+ "service" : 4,
142
+ "food" : 3
143
+ },
144
+ "modified" : "2014-09-11T09:48:19.096+02:00",
145
+ "created_date" : "2014-09-10T16:35:39.201+02:00",
146
+ "review_title" : "bbb",
147
+ "review" : "fff",
148
+ "average_rating" : 3.0,
149
+ "comments" : [ ]
150
+ }, {
151
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/feedbacks/o-qTRqQGFS3Z_RPJm1f8SA",
152
+ "campaign" : {
153
+ "href" : "http://datastore-stg.lb-service.sunrise.intra.local.ch/v2/content-ads/51dfc56c0cf271c375c5a160"
154
+ },
155
+ "source_id" : "abcdefghs12345",
156
+ "recommended" : true,
157
+ "modified" : "2014-09-10T16:31:52.493+02:00",
158
+ "created_date" : "2014-09-10T16:31:52.492+02:00",
159
+ "comments" : [ ]
160
+ } ],
161
+ "total" : 98,
162
+ "offset" : 0,
163
+ "limit" : 10
164
+ }