lhs 24.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 (306) hide show
  1. checksums.yaml +7 -0
  2. data/.bundler-version +1 -0
  3. data/.gitignore +39 -0
  4. data/.rubocop.localch.yml +325 -0
  5. data/.rubocop.yml +52 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +4 -0
  8. data/Gemfile.activesupport4 +5 -0
  9. data/Gemfile.activesupport5 +4 -0
  10. data/LICENSE +674 -0
  11. data/README.md +2836 -0
  12. data/Rakefile +25 -0
  13. data/cider-ci.yml +6 -0
  14. data/cider-ci/bin/bundle +51 -0
  15. data/cider-ci/bin/ruby_install +8 -0
  16. data/cider-ci/bin/ruby_version +25 -0
  17. data/cider-ci/jobs/rspec-activesupport-4.yml +27 -0
  18. data/cider-ci/jobs/rspec-activesupport-5.yml +26 -0
  19. data/cider-ci/jobs/rspec-activesupport-latest.yml +24 -0
  20. data/cider-ci/jobs/rubocop.yml +18 -0
  21. data/cider-ci/task_components/bundle.yml +22 -0
  22. data/cider-ci/task_components/rspec.yml +37 -0
  23. data/cider-ci/task_components/rubocop.yml +29 -0
  24. data/cider-ci/task_components/ruby.yml +15 -0
  25. data/friday.yml +2 -0
  26. data/lhs.gemspec +43 -0
  27. data/lib/lhs.rb +100 -0
  28. data/lib/lhs/collection.rb +84 -0
  29. data/lib/lhs/complex.rb +158 -0
  30. data/lib/lhs/concerns/autoload_records.rb +55 -0
  31. data/lib/lhs/concerns/collection/handle_nested.rb +43 -0
  32. data/lib/lhs/concerns/collection/internal_collection.rb +49 -0
  33. data/lib/lhs/concerns/configuration.rb +20 -0
  34. data/lib/lhs/concerns/data/becomes.rb +18 -0
  35. data/lib/lhs/concerns/data/equality.rb +14 -0
  36. data/lib/lhs/concerns/data/json.rb +14 -0
  37. data/lib/lhs/concerns/data/to_hash.rb +14 -0
  38. data/lib/lhs/concerns/inspect.rb +70 -0
  39. data/lib/lhs/concerns/is_href.rb +15 -0
  40. data/lib/lhs/concerns/item/destroy.rb +38 -0
  41. data/lib/lhs/concerns/item/endpoint_lookup.rb +27 -0
  42. data/lib/lhs/concerns/item/save.rb +55 -0
  43. data/lib/lhs/concerns/item/update.rb +50 -0
  44. data/lib/lhs/concerns/item/validation.rb +61 -0
  45. data/lib/lhs/concerns/o_auth.rb +25 -0
  46. data/lib/lhs/concerns/option_blocks.rb +26 -0
  47. data/lib/lhs/concerns/proxy/accessors.rb +132 -0
  48. data/lib/lhs/concerns/proxy/create.rb +45 -0
  49. data/lib/lhs/concerns/proxy/link.rb +25 -0
  50. data/lib/lhs/concerns/proxy/problems.rb +27 -0
  51. data/lib/lhs/concerns/record/attribute_assignment.rb +25 -0
  52. data/lib/lhs/concerns/record/batch.rb +40 -0
  53. data/lib/lhs/concerns/record/chainable.rb +465 -0
  54. data/lib/lhs/concerns/record/configuration.rb +103 -0
  55. data/lib/lhs/concerns/record/create.rb +24 -0
  56. data/lib/lhs/concerns/record/custom_setters.rb +22 -0
  57. data/lib/lhs/concerns/record/destroy.rb +18 -0
  58. data/lib/lhs/concerns/record/endpoints.rb +108 -0
  59. data/lib/lhs/concerns/record/equality.rb +14 -0
  60. data/lib/lhs/concerns/record/find.rb +86 -0
  61. data/lib/lhs/concerns/record/find_by.rb +38 -0
  62. data/lib/lhs/concerns/record/first.rb +20 -0
  63. data/lib/lhs/concerns/record/href_for.rb +19 -0
  64. data/lib/lhs/concerns/record/last.rb +27 -0
  65. data/lib/lhs/concerns/record/mapping.rb +25 -0
  66. data/lib/lhs/concerns/record/merge.rb +26 -0
  67. data/lib/lhs/concerns/record/model.rb +23 -0
  68. data/lib/lhs/concerns/record/pagination.rb +47 -0
  69. data/lib/lhs/concerns/record/provider.rb +23 -0
  70. data/lib/lhs/concerns/record/relations.rb +26 -0
  71. data/lib/lhs/concerns/record/request.rb +620 -0
  72. data/lib/lhs/concerns/record/scope.rb +25 -0
  73. data/lib/lhs/concerns/record/tracing.rb +24 -0
  74. data/lib/lhs/concerns/record/update.rb +17 -0
  75. data/lib/lhs/config.rb +24 -0
  76. data/lib/lhs/data.rb +165 -0
  77. data/lib/lhs/endpoint.rb +12 -0
  78. data/lib/lhs/interceptors/auto_oauth/interceptor.rb +33 -0
  79. data/lib/lhs/interceptors/auto_oauth/thread_registry.rb +18 -0
  80. data/lib/lhs/interceptors/extended_rollbar/handler.rb +40 -0
  81. data/lib/lhs/interceptors/extended_rollbar/interceptor.rb +20 -0
  82. data/lib/lhs/interceptors/extended_rollbar/thread_registry.rb +19 -0
  83. data/lib/lhs/interceptors/request_cycle_cache/interceptor.rb +41 -0
  84. data/lib/lhs/interceptors/request_cycle_cache/thread_registry.rb +18 -0
  85. data/lib/lhs/item.rb +59 -0
  86. data/lib/lhs/pagination/base.rb +90 -0
  87. data/lib/lhs/pagination/link.rb +21 -0
  88. data/lib/lhs/pagination/offset.rb +22 -0
  89. data/lib/lhs/pagination/page.rb +18 -0
  90. data/lib/lhs/pagination/start.rb +22 -0
  91. data/lib/lhs/problems/base.rb +113 -0
  92. data/lib/lhs/problems/errors.rb +69 -0
  93. data/lib/lhs/problems/nested/base.rb +54 -0
  94. data/lib/lhs/problems/nested/errors.rb +16 -0
  95. data/lib/lhs/problems/nested/warnings.rb +15 -0
  96. data/lib/lhs/problems/warnings.rb +24 -0
  97. data/lib/lhs/proxy.rb +68 -0
  98. data/lib/lhs/railtie.rb +34 -0
  99. data/lib/lhs/record.rb +112 -0
  100. data/lib/lhs/rspec.rb +10 -0
  101. data/lib/lhs/test/stubbable_records.rb +34 -0
  102. data/lib/lhs/unprocessable.rb +6 -0
  103. data/lib/lhs/version.rb +5 -0
  104. data/script/ci/build.sh +18 -0
  105. data/spec/auto_oauth_spec.rb +169 -0
  106. data/spec/autoloading_spec.rb +48 -0
  107. data/spec/collection/accessors_spec.rb +31 -0
  108. data/spec/collection/collection_items_spec.rb +44 -0
  109. data/spec/collection/configurable_spec.rb +43 -0
  110. data/spec/collection/delegate_spec.rb +21 -0
  111. data/spec/collection/enumerable_spec.rb +27 -0
  112. data/spec/collection/href_spec.rb +17 -0
  113. data/spec/collection/meta_data_spec.rb +57 -0
  114. data/spec/collection/respond_to_spec.rb +20 -0
  115. data/spec/collection/to_a_spec.rb +34 -0
  116. data/spec/collection/to_ary_spec.rb +40 -0
  117. data/spec/collection/without_object_items_spec.rb +27 -0
  118. data/spec/complex/reduce_spec.rb +202 -0
  119. data/spec/concerns/record/request_spec.rb +78 -0
  120. data/spec/data/collection_spec.rb +56 -0
  121. data/spec/data/equality_spec.rb +23 -0
  122. data/spec/data/inspect_spec.rb +88 -0
  123. data/spec/data/is_item_or_collection_spec.rb +40 -0
  124. data/spec/data/item_spec.rb +106 -0
  125. data/spec/data/merge_spec.rb +27 -0
  126. data/spec/data/parent_spec.rb +39 -0
  127. data/spec/data/raw_spec.rb +48 -0
  128. data/spec/data/respond_to_spec.rb +26 -0
  129. data/spec/data/root_spec.rb +25 -0
  130. data/spec/data/select_spec.rb +27 -0
  131. data/spec/data/to_ary_spec.rb +28 -0
  132. data/spec/data/to_json_spec.rb +68 -0
  133. data/spec/dummy/Rakefile +8 -0
  134. data/spec/dummy/app/assets/images/.keep +0 -0
  135. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  136. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  137. data/spec/dummy/app/controllers/application_controller.rb +26 -0
  138. data/spec/dummy/app/controllers/automatic_authentication_controller.rb +29 -0
  139. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  140. data/spec/dummy/app/controllers/error_handling_with_chains_controller.rb +36 -0
  141. data/spec/dummy/app/controllers/extended_rollbar_controller.rb +10 -0
  142. data/spec/dummy/app/controllers/option_blocks_controller.rb +15 -0
  143. data/spec/dummy/app/controllers/request_cycle_cache_controller.rb +27 -0
  144. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  145. data/spec/dummy/app/mailers/.keep +0 -0
  146. data/spec/dummy/app/models/.keep +0 -0
  147. data/spec/dummy/app/models/concerns/.keep +0 -0
  148. data/spec/dummy/app/models/dummy_customer.rb +6 -0
  149. data/spec/dummy/app/models/dummy_record.rb +6 -0
  150. data/spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb +6 -0
  151. data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb +7 -0
  152. data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb +7 -0
  153. data/spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb +6 -0
  154. data/spec/dummy/app/models/dummy_record_with_oauth.rb +7 -0
  155. data/spec/dummy/app/models/dummy_user.rb +6 -0
  156. data/spec/dummy/app/models/providers/customer_system.rb +7 -0
  157. data/spec/dummy/app/models/providers/internal_services.rb +7 -0
  158. data/spec/dummy/app/views/error_handling_with_chains/error.html.erb +1 -0
  159. data/spec/dummy/app/views/error_handling_with_chains/show.html.erb +3 -0
  160. data/spec/dummy/app/views/form_for.html.erb +5 -0
  161. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  162. data/spec/dummy/bin/bundle +5 -0
  163. data/spec/dummy/bin/rails +6 -0
  164. data/spec/dummy/bin/rake +6 -0
  165. data/spec/dummy/config.ru +6 -0
  166. data/spec/dummy/config/application.rb +16 -0
  167. data/spec/dummy/config/boot.rb +7 -0
  168. data/spec/dummy/config/environment.rb +7 -0
  169. data/spec/dummy/config/environments/development.rb +36 -0
  170. data/spec/dummy/config/environments/production.rb +77 -0
  171. data/spec/dummy/config/environments/test.rb +40 -0
  172. data/spec/dummy/config/initializers/assets.rb +10 -0
  173. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  174. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  175. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  176. data/spec/dummy/config/initializers/inflections.rb +18 -0
  177. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  178. data/spec/dummy/config/initializers/rollbar.rb +9 -0
  179. data/spec/dummy/config/initializers/session_store.rb +5 -0
  180. data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
  181. data/spec/dummy/config/locales/en.yml +23 -0
  182. data/spec/dummy/config/routes.rb +27 -0
  183. data/spec/dummy/config/secrets.yml +22 -0
  184. data/spec/dummy/lib/assets/.keep +0 -0
  185. data/spec/dummy/public/404.html +67 -0
  186. data/spec/dummy/public/422.html +67 -0
  187. data/spec/dummy/public/500.html +66 -0
  188. data/spec/dummy/public/favicon.ico +0 -0
  189. data/spec/endpoint/for_url_spec.rb +27 -0
  190. data/spec/extended_rollbar_spec.rb +67 -0
  191. data/spec/item/access_errors_spec.rb +33 -0
  192. data/spec/item/accessors_spec.rb +21 -0
  193. data/spec/item/add_error_spec.rb +21 -0
  194. data/spec/item/becomes_spec.rb +38 -0
  195. data/spec/item/blacklisted_keywords_spec.rb +30 -0
  196. data/spec/item/delegate_spec.rb +32 -0
  197. data/spec/item/destroy_spec.rb +113 -0
  198. data/spec/item/dig_spec.rb +29 -0
  199. data/spec/item/error_codes_spec.rb +55 -0
  200. data/spec/item/errors_spec.rb +324 -0
  201. data/spec/item/fetch_spec.rb +39 -0
  202. data/spec/item/getter_spec.rb +24 -0
  203. data/spec/item/internal_data_structure_spec.rb +37 -0
  204. data/spec/item/map_spec.rb +46 -0
  205. data/spec/item/nested_errors_spec.rb +28 -0
  206. data/spec/item/partial_update_spec.rb +170 -0
  207. data/spec/item/respond_to_spec.rb +31 -0
  208. data/spec/item/save_spec.rb +115 -0
  209. data/spec/item/setter_spec.rb +44 -0
  210. data/spec/item/translate_errors_spec.rb +257 -0
  211. data/spec/item/update_spec.rb +161 -0
  212. data/spec/item/validation_spec.rb +131 -0
  213. data/spec/item/warning_codes_spec.rb +55 -0
  214. data/spec/item/warnings_spec.rb +52 -0
  215. data/spec/option_blocks/ensure_reset_between_requests_spec.rb +23 -0
  216. data/spec/option_blocks/main_spec.rb +55 -0
  217. data/spec/pagination/link/current_page_spec.rb +19 -0
  218. data/spec/pagination/link/pages_left_spec.rb +36 -0
  219. data/spec/pagination/link/parallel_spec.rb +19 -0
  220. data/spec/pagination/link/total_spec.rb +46 -0
  221. data/spec/pagination/offset/pages_left_spec.rb +26 -0
  222. data/spec/pagination/parameters_spec.rb +61 -0
  223. data/spec/proxy/create_sub_resource_spec.rb +182 -0
  224. data/spec/proxy/load_spec.rb +75 -0
  225. data/spec/proxy/record_identification_spec.rb +35 -0
  226. data/spec/rails_helper.rb +13 -0
  227. data/spec/record/all_spec.rb +133 -0
  228. data/spec/record/attribute_assignment_spec.rb +28 -0
  229. data/spec/record/build_spec.rb +26 -0
  230. data/spec/record/cast_nested_data_spec.rb +78 -0
  231. data/spec/record/create_spec.rb +160 -0
  232. data/spec/record/creation_failed_spec.rb +55 -0
  233. data/spec/record/custom_setters_spec.rb +45 -0
  234. data/spec/record/definitions_spec.rb +29 -0
  235. data/spec/record/destroy_spec.rb +38 -0
  236. data/spec/record/dig_configuration_spec.rb +75 -0
  237. data/spec/record/dup_spec.rb +20 -0
  238. data/spec/record/endpoint_inheritance_spec.rb +65 -0
  239. data/spec/record/endpoint_options_spec.rb +52 -0
  240. data/spec/record/endpoint_priorities_spec.rb +26 -0
  241. data/spec/record/endpoints_spec.rb +96 -0
  242. data/spec/record/equality_spec.rb +27 -0
  243. data/spec/record/error_handling_integration_spec.rb +25 -0
  244. data/spec/record/error_handling_spec.rb +40 -0
  245. data/spec/record/expanded_spec.rb +69 -0
  246. data/spec/record/fetch_spec.rb +41 -0
  247. data/spec/record/find_by_chains_spec.rb +21 -0
  248. data/spec/record/find_by_spec.rb +76 -0
  249. data/spec/record/find_each_spec.rb +57 -0
  250. data/spec/record/find_in_batches_spec.rb +122 -0
  251. data/spec/record/find_in_parallel_spec.rb +67 -0
  252. data/spec/record/find_spec.rb +104 -0
  253. data/spec/record/first_spec.rb +39 -0
  254. data/spec/record/force_merge_spec.rb +56 -0
  255. data/spec/record/handle_includes_errors_spec.rb +32 -0
  256. data/spec/record/has_many_spec.rb +120 -0
  257. data/spec/record/has_one_spec.rb +116 -0
  258. data/spec/record/href_for_spec.rb +25 -0
  259. data/spec/record/ignore_errors_spec.rb +139 -0
  260. data/spec/record/immutable_chains_spec.rb +22 -0
  261. data/spec/record/includes_first_page_spec.rb +737 -0
  262. data/spec/record/includes_spec.rb +693 -0
  263. data/spec/record/includes_warning_spec.rb +46 -0
  264. data/spec/record/item_key_spec.rb +81 -0
  265. data/spec/record/items_created_key_configuration_spec.rb +37 -0
  266. data/spec/record/last_spec.rb +68 -0
  267. data/spec/record/loading_twice_spec.rb +19 -0
  268. data/spec/record/mapping_spec.rb +102 -0
  269. data/spec/record/model_name_spec.rb +17 -0
  270. data/spec/record/new_spec.rb +106 -0
  271. data/spec/record/options_getter_spec.rb +26 -0
  272. data/spec/record/options_spec.rb +164 -0
  273. data/spec/record/paginatable_collection_spec.rb +360 -0
  274. data/spec/record/pagination_chain_spec.rb +101 -0
  275. data/spec/record/pagination_links_spec.rb +72 -0
  276. data/spec/record/pagination_spec.rb +71 -0
  277. data/spec/record/persisted_spec.rb +52 -0
  278. data/spec/record/provider_spec.rb +41 -0
  279. data/spec/record/references_spec.rb +53 -0
  280. data/spec/record/relation_caching_spec.rb +121 -0
  281. data/spec/record/reload_by_id_spec.rb +43 -0
  282. data/spec/record/reload_spec.rb +65 -0
  283. data/spec/record/request_spec.rb +90 -0
  284. data/spec/record/save_spec.rb +40 -0
  285. data/spec/record/scope_chains_spec.rb +39 -0
  286. data/spec/record/select_spec.rb +17 -0
  287. data/spec/record/to_ary_spec.rb +65 -0
  288. data/spec/record/to_hash_spec.rb +22 -0
  289. data/spec/record/to_json_spec.rb +22 -0
  290. data/spec/record/tracing_spec.rb +154 -0
  291. data/spec/record/update_spec.rb +62 -0
  292. data/spec/record/where_chains_spec.rb +57 -0
  293. data/spec/record/where_spec.rb +62 -0
  294. data/spec/record/where_values_hash_spec.rb +32 -0
  295. data/spec/request_cycle_cache_spec.rb +106 -0
  296. data/spec/require_lhs_spec.rb +9 -0
  297. data/spec/spec_helper.rb +6 -0
  298. data/spec/stubs/all_spec.rb +72 -0
  299. data/spec/support/fixtures/json/feedback.json +11 -0
  300. data/spec/support/fixtures/json/feedbacks.json +174 -0
  301. data/spec/support/fixtures/json/localina_content_ad.json +23 -0
  302. data/spec/support/load_json.rb +5 -0
  303. data/spec/support/request_cycle_cache.rb +10 -0
  304. data/spec/support/reset.rb +67 -0
  305. data/spec/views/form_for_spec.rb +20 -0
  306. metadata +776 -0
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'update' do
7
+
8
+ before do
9
+ class Record < LHS::Record
10
+ endpoint 'http://datastore/records/{id}'
11
+ end
12
+ end
13
+
14
+ it 'allows to directly update a record without fetching it first' do
15
+ stub_request(:post, "http://datastore/records/123")
16
+ .with(body: { name: 'Steve' }.to_json)
17
+ .to_return(status: 200, body: {}.to_json)
18
+
19
+ Record.update(
20
+ id: '123',
21
+ name: 'Steve'
22
+ )
23
+ end
24
+
25
+ it 'does not fail during an error with update' do
26
+ stub_request(:post, "http://datastore/records/123")
27
+ .with(body: { name: 'Steve' }.to_json)
28
+ .to_return(status: 404, body: {}.to_json)
29
+
30
+ record = Record.update(
31
+ id: '123',
32
+ name: 'Steve'
33
+ )
34
+
35
+ expect(record.errors.status_code).to eq 404
36
+ end
37
+
38
+ it 'allows to directly update! a record without fetching it first' do
39
+ stub_request(:post, "http://datastore/records/123")
40
+ .with(body: { name: 'Steve' }.to_json)
41
+ .to_return(status: 200)
42
+
43
+ Record.update!(
44
+ id: '123',
45
+ name: 'Steve'
46
+ )
47
+ end
48
+
49
+ it 'raises an error when trying to update! but retrieving an error status' do
50
+ stub_request(:post, "http://datastore/records/123")
51
+ .with(body: { name: 'Steve' }.to_json)
52
+ .to_return(status: 404)
53
+
54
+ expect(-> {
55
+ Record.update!(
56
+ id: '123',
57
+ name: 'Steve'
58
+ )
59
+ }).to raise_error(LHC::NotFound)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:datastore) do
7
+ 'http://datastore/v2'
8
+ end
9
+
10
+ let(:response) do
11
+ { body: [{ name: 'Steve' }] }
12
+ end
13
+
14
+ before do
15
+ LHC.config.placeholder('datastore', datastore)
16
+ class Record < LHS::Record
17
+ endpoint '{+datastore}/records/'
18
+
19
+ def uppercase_name
20
+ name.upcase
21
+ end
22
+ end
23
+ end
24
+
25
+ context 'where chains' do
26
+ before do
27
+ stub_request(:get, "http://datastore/v2/records/?available=true&color=blue&range=%3E26")
28
+ .to_return(response)
29
+ end
30
+
31
+ let(:records) { Record.where(color: 'blue').where(range: '>26').where(available: true) }
32
+
33
+ it 'allows chaining where statements' do
34
+ expect(records.class).to eq Record
35
+ expect(records._raw).to eq [{ name: 'Steve' }]
36
+ expect(records.first.uppercase_name).to eq 'STEVE'
37
+ end
38
+
39
+ it 'resolves triggered by method missing' do
40
+ expect(records._raw).to eq [{ name: 'Steve' }]
41
+ expect(
42
+ Record.where(color: 'blue').where(range: '>26', available: true).first.name
43
+ ).to eq 'Steve'
44
+ end
45
+ end
46
+
47
+ context 'multiple parameters' do
48
+ before do
49
+ stub_request(:get, "http://datastore/v2/records/?parameter=last").to_return(response)
50
+ end
51
+
52
+ it 'takes the last value for chains with same name parameters' do
53
+ records = Record.where(parameter: 'first').where(parameter: 'last')
54
+ records.first
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:datastore) do
7
+ 'http://datastore/v2'
8
+ end
9
+
10
+ before do
11
+ LHC.config.placeholder('datastore', datastore)
12
+ class Record < LHS::Record
13
+ endpoint '{+datastore}/content-ads/{campaign_id}/feedbacks'
14
+ endpoint '{+datastore}/feedbacks'
15
+ end
16
+ end
17
+
18
+ context 'where' do
19
+ it 'is querying relevant endpoint when using where' do
20
+ stub_request(:get, "#{datastore}/feedbacks?has_review=true").to_return(status: 200, body: { items: [] }.to_json)
21
+ Record.where(has_review: true)
22
+ stub_request(:get, "#{datastore}/content-ads/123/feedbacks?has_review=true").to_return(status: 200, body: [].to_json)
23
+ Record.where(campaign_id: '123', has_review: true)
24
+ stub_request(:get, "#{datastore}/feedbacks").to_return(status: 200, body: [].to_json)
25
+ records = Record.where
26
+ expect(records).to be_kind_of Record
27
+ end
28
+
29
+ it 'is using params as query params explicitly when provided in params namespace' do
30
+ stub_request(:get, "#{datastore}/content-ads/123/feedbacks?campaign_id=456").to_return(status: 200, body: [].to_json)
31
+ Record.where(campaign_id: '123', params: { campaign_id: '456' })
32
+ end
33
+
34
+ context 'where with href' do
35
+ let(:return_body) { [email: 'steve@local.ch'].to_json }
36
+
37
+ context 'chain initialization' do
38
+ before do
39
+ stub_request(:get, "https://localch-accounts/?from_user_id=123")
40
+ .to_return(body: return_body)
41
+ end
42
+
43
+ it 'queries api with provided href' do
44
+ records = Record.where('https://localch-accounts?from_user_id=123').fetch
45
+ expect(records.first.email).to eq 'steve@local.ch'
46
+ end
47
+ end
48
+
49
+ context 'after chain initialization' do
50
+ before do
51
+ stub_request(:get, "https://localch-accounts/?color=blue&from_user_id=123")
52
+ .to_return(body: return_body)
53
+ end
54
+
55
+ it 'queries api with provided href also when passed after chain is initialized' do
56
+ records = Record.where(color: 'blue').where('https://localch-accounts?from_user_id=123').fetch
57
+ expect(records.first.email).to eq 'steve@local.ch'
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:datastore) do
7
+ 'http://datastore/v2'
8
+ end
9
+
10
+ let(:response) do
11
+ { body: [{ name: 'Steve' }] }
12
+ end
13
+
14
+ before do
15
+ LHC.config.placeholder('datastore', datastore)
16
+ class Record < LHS::Record
17
+ endpoint '{+datastore}/records/'
18
+ end
19
+ end
20
+
21
+ context 'where values hash' do
22
+ it 'provides the hash or where parameters that have been requested' do
23
+ stub_request(:get, "http://datastore/v2/records/?available=true&color=blue").to_return(response)
24
+ expect(
25
+ Record.where(available: true).where(color: 'blue').where_values_hash
26
+ ).to eq(available: true, color: 'blue')
27
+ expect(
28
+ Record.where(available: true, color: 'red').where(color: 'blue').where_values_hash
29
+ ).to eq(available: true, color: 'blue')
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'lhc/rspec'
5
+
6
+ describe 'Request Cycle Cache', type: :request do
7
+ let!(:request) do
8
+ stub_request(:get, "http://datastore/v2/users/1").to_return(body: { name: 'Steve' }.to_json)
9
+ end
10
+
11
+ let!(:second_request) do
12
+ stub_request(:get, "http://datastore/v2/users/2").to_return(body: { name: 'Peter' }.to_json)
13
+ end
14
+
15
+ before do
16
+ class User < LHS::Record
17
+ endpoint 'http://datastore/v2/users'
18
+ endpoint 'http://datastore/v2/users/{id}'
19
+ end
20
+ LHC.configure do |config|
21
+ config.interceptors = [LHC::Caching]
22
+ end
23
+ end
24
+
25
+ it 'serves requests that are exactly the same during one request cycle from the cache',
26
+ dummy_models: true, request_cycle_cache: true do
27
+ get '/request_cycle_cache/simple'
28
+ expect(request).to have_been_made.once
29
+
30
+ # Second Request, Second Cycle, requests again
31
+ get '/request_cycle_cache/simple'
32
+ expect(request).to have_been_made.times(2)
33
+ end
34
+
35
+ it 'does not serve from request cycle cache when cache interceptor is not hooked in, but logs a warning',
36
+ dummy_models: true, request_cycle_cache: true do
37
+ expect(lambda do
38
+ get '/request_cycle_cache/no_caching_interceptor'
39
+ end).to output(
40
+ %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor\)!}
41
+ ).to_stderr
42
+ expect(request).to have_been_made.times(2)
43
+ end
44
+
45
+ it 'serves requests also from cache when LHS/LHC makes requests in parallel',
46
+ dummy_models: true, request_cycle_cache: true do
47
+ get '/request_cycle_cache/parallel'
48
+ expect(request).to have_been_made.once
49
+ expect(second_request).to have_been_made.once
50
+ end
51
+
52
+ it 'sets different uniq request ids as base for request cycle caching for different requests',
53
+ dummy_models: true, request_cycle_cache: true do
54
+ get '/request_cycle_cache/simple'
55
+ first_request_id = LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id
56
+ second_request_id = nil
57
+ thread = Thread.new do
58
+ get '/request_cycle_cache/simple'
59
+ second_request_id = LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id
60
+ end
61
+ thread.join
62
+ expect(first_request_id).not_to be_nil
63
+ expect(second_request_id).not_to be_nil
64
+ expect(first_request_id).not_to eq second_request_id
65
+ end
66
+
67
+ context 'disabled request cycle cache' do
68
+ it 'does not serve from request cycle cache when cache interceptor is not hooked in, and does not warn if request cycle cache is explicitly disabled',
69
+ dummy_models: true do
70
+ expect(lambda do
71
+ get '/request_cycle_cache/no_caching_interceptor'
72
+ end).not_to output(
73
+ %r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor\)!}
74
+ ).to_stderr
75
+ expect(request).to have_been_made.times(2)
76
+ end
77
+
78
+ it 'DOES NOT serve requests that are exactly the same during one request cycle from the cache, when request cycle cache is disabled',
79
+ dummy_models: true do
80
+ get '/request_cycle_cache/simple'
81
+ expect(request).to have_been_made.times(2)
82
+ end
83
+ end
84
+
85
+ context 'headers' do
86
+ it 'considers the request headers when setting the cache key',
87
+ dummy_models: true, request_cycle_cache: true do
88
+ get '/request_cycle_cache/headers'
89
+ expect(request).to have_been_made.times(2)
90
+ end
91
+ end
92
+
93
+ context 'use: cache' do
94
+ let!(:old_cache) { LHS.config.request_cycle_cache }
95
+
96
+ before { LHS.config.request_cycle_cache = double('cache', fetch: nil, write: nil) }
97
+ after { LHS.config.request_cycle_cache = old_cache }
98
+
99
+ it 'uses the cache passed in',
100
+ dummy_models: true, request_cycle_cache: true do
101
+ expect(LHS.config.request_cycle_cache).to receive(:fetch).at_least(:once)
102
+ expect(LHS.config.request_cycle_cache).to receive(:write).at_least(:once)
103
+ get '/request_cycle_cache/simple'
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe LHS do
4
+ context 'when requiring lhs' do
5
+ it 'does not raise an exception' do
6
+ expect { require 'lhs' }.not_to raise_error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pry'
4
+ require 'webmock/rspec'
5
+
6
+ Dir[File.join(__dir__, "support/**/*.rb")].each { |f| require f }
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'lhs/rspec'
5
+
6
+ describe LHS do
7
+
8
+ before do
9
+ class Record < LHS::Record
10
+ endpoint 'https://records'
11
+ end
12
+
13
+ Record.stub_all(
14
+ 'https://records',
15
+ 200.times.map { |index| { name: "Item #{index}" } },
16
+ headers: {
17
+ 'Authorization' => 'Bearer 123'
18
+ }
19
+ )
20
+ end
21
+
22
+ it 'stubs all requests' do
23
+ records = Record.options(headers: { 'Authorization' => 'Bearer 123' }).all.fetch
24
+ expect(records.count).to eq 200
25
+ expect(records.length).to eq 200
26
+ expect(records.first.name).to eq 'Item 0'
27
+ end
28
+
29
+ context 'without conditions' do
30
+
31
+ before do
32
+ class Record < LHS::Record
33
+ endpoint 'https://records'
34
+ end
35
+
36
+ Record.stub_all(
37
+ 'https://records',
38
+ 200.times.map { |index| { name: "Item #{index}" } }
39
+ )
40
+ end
41
+
42
+ it 'stubs all requests without a webmock "with"' do
43
+ records = Record.all.fetch
44
+ expect(records.count).to eq 200
45
+ expect(records.length).to eq 200
46
+ expect(records.first.name).to eq 'Item 0'
47
+ end
48
+ end
49
+
50
+ context 'with configured record' do
51
+
52
+ before do
53
+ class Record < LHS::Record
54
+ configuration limit_key: :per_page, pagination_strategy: :page, pagination_key: :page
55
+
56
+ endpoint 'https://records'
57
+ end
58
+
59
+ Record.stub_all(
60
+ 'https://records',
61
+ 200.times.map { |index| { name: "Item #{index}" } }
62
+ )
63
+ end
64
+
65
+ it 'stubs all requests with record configurations for pagination' do
66
+ records = Record.all.fetch
67
+ expect(records.count).to eq 200
68
+ expect(records.length).to eq 200
69
+ expect(records.first.name).to eq 'Item 0'
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,11 @@
1
+ {
2
+ "href": "http://local.ch/v2/feedbacks/-Sc4_pYNpqfsudzhtivfkA",
3
+ "campaign": {
4
+ "href": "http://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,174 @@
1
+ {
2
+ "href" : "http://local.ch/v2/feedbacks/?exclude_hidden=false&offset=0&limit=10",
3
+ "items" : [ {
4
+ "href" : "http://local.ch/v2/feedbacks/0sdaetZ-OWVg4oBiBJ-7IQ",
5
+ "campaign" : {
6
+ "href" : "http://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
+ "valid_from" : "2014-10-01",
16
+ "modified" : "2014-09-18T16:13:32.987+02:00",
17
+ "created_date" : "2014-09-18T16:13:31.496+02:00",
18
+ "average_rating" : 3.0,
19
+ "comments" : [ ]
20
+ }, {
21
+ "href" : "http://local.ch/v2/feedbacks/QsUOQWNJoB-GFUNsX7z0jg",
22
+ "campaign" : {
23
+ "href" : "http://local.ch/v2/content-ads/51dfc5690cf271c375c5a11f"
24
+ },
25
+ "source_id" : "abcdefghs12345",
26
+ "name" : "Steve",
27
+ "recommended" : true,
28
+ "ratings" : {
29
+ "ambiente" : 3,
30
+ "service" : 5,
31
+ "food" : 2
32
+ },
33
+ "valid_from" : "2014-10-01",
34
+ "modified" : "2014-09-18T15:43:12.134+02:00",
35
+ "created_date" : "2014-09-18T15:42:57.892+02:00",
36
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
37
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
38
+ "average_rating" : 3.3333333333333335,
39
+ "comments" : [ ]
40
+ }, {
41
+ "href" : "http://local.ch/v2/feedbacks/QynNtmpXlsEGvUJ0ekDKVw",
42
+ "campaign" : {
43
+ "href" : "http://local.ch/v2/content-ads/51dfc56b0cf271c375c5a14d"
44
+ },
45
+ "source_id" : "abcdefghs12345",
46
+ "name" : "Steve",
47
+ "recommended" : true,
48
+ "ratings" : {
49
+ "ambiente" : 3,
50
+ "service" : 5,
51
+ "food" : 2
52
+ },
53
+ "valid_from" : "2014-10-01",
54
+ "modified" : "2014-09-17T11:17:39.660+02:00",
55
+ "created_date" : "2014-09-17T11:17:34.234+02:00",
56
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
57
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
58
+ "average_rating" : 3.3333333333333335,
59
+ "comments" : [ ]
60
+ }, {
61
+ "href" : "http://local.ch/v2/feedbacks/INmminYWNZwW_qNFx5peJQ",
62
+ "campaign" : {
63
+ "href" : "http://local.ch/v2/content-ads/51dfc56b0cf271c375c5a153"
64
+ },
65
+ "source_id" : "abcdefghs12345",
66
+ "name" : "Steve",
67
+ "recommended" : true,
68
+ "ratings" : {
69
+ "ambiente" : 3,
70
+ "service" : 5,
71
+ "food" : 2
72
+ },
73
+ "valid_from" : "2014-10-01",
74
+ "modified" : "2014-09-16T11:20:32.600+02:00",
75
+ "created_date" : "2014-09-16T11:20:30.194+02:00",
76
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
77
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
78
+ "average_rating" : 3.3333333333333335,
79
+ "comments" : [ ]
80
+ }, {
81
+ "href" : "http://local.ch/v2/feedbacks/ltgfr0VRYDN2nxyC119wTg",
82
+ "campaign" : {
83
+ "href" : "http://local.ch/v2/content-ads/51dfc56b0cf271c375c5a14c"
84
+ },
85
+ "source_id" : "aaa",
86
+ "recommended" : false,
87
+ "ratings" : {
88
+ "ambiente" : 2,
89
+ "service" : 1,
90
+ "food" : 1
91
+ },
92
+ "valid_from" : "2014-10-01",
93
+ "modified" : "2014-09-15T16:23:54.898+02:00",
94
+ "created_date" : "2014-09-15T16:23:40.355+02:00",
95
+ "average_rating" : 1.3333333333333333,
96
+ "comments" : [ ]
97
+ }, {
98
+ "href" : "http://local.ch/v2/feedbacks/5dUdQP-kZ6sulN8NtpGXTw",
99
+ "campaign" : {
100
+ "href" : "http://local.ch/v2/content-ads/51dfc56b0cf271c375c5a14c"
101
+ },
102
+ "source_id" : "abcdefghs12345",
103
+ "name" : "Steve",
104
+ "recommended" : true,
105
+ "ratings" : {
106
+ "ambiente" : 3,
107
+ "service" : 5,
108
+ "food" : 2
109
+ },
110
+ "valid_from" : "2014-10-01",
111
+ "modified" : "2014-09-12T13:10:51.220+02:00",
112
+ "created_date" : "2014-09-12T13:10:48.813+02:00",
113
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
114
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
115
+ "average_rating" : 3.3333333333333335,
116
+ "comments" : [ ]
117
+ }, {
118
+ "href" : "http://local.ch/v2/feedbacks/Z3KfWzIEQ3ZVCUj2IdrSNQ",
119
+ "campaign" : {
120
+ "href" : "http://local.ch/v2/content-ads/51dfc5690cf271c375c5a12e"
121
+ },
122
+ "source_id" : "abcdefghs",
123
+ "recommended" : true,
124
+ "valid_from" : "2014-10-01",
125
+ "modified" : "2014-09-10T16:57:36.255+02:00",
126
+ "created_date" : "2014-09-10T16:57:36.254+02:00",
127
+ "comments" : [ ]
128
+ }, {
129
+ "href" : "http://local.ch/v2/feedbacks/ZUUUeiw-Stw5Zb1baHDUzQ",
130
+ "campaign" : {
131
+ "href" : "http://local.ch/v2/content-ads/51dfc5690cf271c375c5a12d"
132
+ },
133
+ "source_id" : "abcdefghs",
134
+ "recommended" : true,
135
+ "valid_from" : "2014-10-01",
136
+ "modified" : "2014-09-10T16:57:32.792+02:00",
137
+ "created_date" : "2014-09-10T16:57:32.791+02:00",
138
+ "comments" : [ ]
139
+ }, {
140
+ "href" : "http://local.ch/v2/feedbacks/GyeWvhEtU4cYN_5T2FX2UA",
141
+ "campaign" : {
142
+ "href" : "http://local.ch/v2/content-ads/539266ec0cf2cd754583cfa0"
143
+ },
144
+ "source_id" : "abcdefghs",
145
+ "name" : "aa",
146
+ "recommended" : true,
147
+ "ratings" : {
148
+ "ambiente" : 2,
149
+ "service" : 4,
150
+ "food" : 3
151
+ },
152
+ "valid_from" : "2014-10-01",
153
+ "modified" : "2014-09-11T09:48:19.096+02:00",
154
+ "created_date" : "2014-09-10T16:35:39.201+02:00",
155
+ "review_title" : "bbb",
156
+ "review" : "fff",
157
+ "average_rating" : 3.0,
158
+ "comments" : [ ]
159
+ }, {
160
+ "href" : "http://local.ch/v2/feedbacks/o-qTRqQGFS3Z_RPJm1f8SA",
161
+ "campaign" : {
162
+ "href" : "http://local.ch/v2/content-ads/51dfc56c0cf271c375c5a160"
163
+ },
164
+ "source_id" : "abcdefghs12345",
165
+ "recommended" : true,
166
+ "valid_from" : "2014-10-01",
167
+ "modified" : "2014-09-10T16:31:52.493+02:00",
168
+ "created_date" : "2014-09-10T16:31:52.492+02:00",
169
+ "comments" : [ ]
170
+ } ],
171
+ "total" : 98,
172
+ "offset" : 0,
173
+ "limit" : 10
174
+ }