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,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:datastore) { 'http://local.ch/v2' }
7
+
8
+ before do
9
+ LHC.config.placeholder(:datastore, datastore)
10
+ class Record < LHS::Record
11
+ endpoint '{+datastore}/content-ads/{campaign_id}/feedbacks'
12
+ endpoint '{+datastore}/feedbacks'
13
+ end
14
+ end
15
+
16
+ context 'first' do
17
+ it 'finds a single record' do
18
+ stub_request(:get, "#{datastore}/feedbacks?limit=1")
19
+ .to_return(status: 200, body: load_json(:feedback))
20
+ record = Record.first
21
+ expect(record).to be_kind_of Record
22
+ expect(record.source_id).to be_present
23
+ end
24
+
25
+ it 'returns nil if no record was found' do
26
+ stub_request(:get, "#{datastore}/feedbacks?limit=1")
27
+ .to_return(status: 404)
28
+ expect(Record.first).to be_nil
29
+ end
30
+ end
31
+
32
+ context 'first!' do
33
+ it 'raises if nothing was found with parameters' do
34
+ stub_request(:get, "#{datastore}/feedbacks?limit=1")
35
+ .to_return(status: 404)
36
+ expect { Record.first! }.to raise_error LHC::NotFound
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'merge' do
7
+
8
+ before do
9
+ class Change < LHS::Record
10
+ endpoint 'https://onboarding/places/{id}/change'
11
+ end
12
+ end
13
+
14
+ it 'merges a given hash' do
15
+ stub_request(:get, "https://onboarding/places/1/change")
16
+ .to_return(body: { entry: { name: 'Steve', address: 'Zurich' }, products: ['LBP'] }.to_json)
17
+ record = Change.find(1)
18
+ record.merge!(entry: { name: 'Paul' })
19
+ expect(record.entry.name).to eq 'Paul'
20
+ expect(record.entry.address).to eq nil
21
+ expect(record.products.to_a).to eq ['LBP']
22
+ end
23
+
24
+ it 'merges! a given hash' do
25
+ stub_request(:get, "https://onboarding/places/1/change")
26
+ .to_return(body: { entry: { name: 'Steve', address: 'Zurich' }, products: ['LBP'] }.to_json)
27
+ record = Change.find(1)
28
+ new_record = record.merge(entry: { name: 'Paul' })
29
+ expect(new_record.entry.name).to eq 'Paul'
30
+ expect(new_record.entry.address).to eq nil
31
+ expect(new_record.products.to_a).to eq ['LBP']
32
+ expect(record.entry.name).to eq 'Steve'
33
+ expect(record.entry.address).to eq 'Zurich'
34
+ expect(record.products.to_a).to eq ['LBP']
35
+ end
36
+
37
+ it 'deep_merge! a given hash' do
38
+ stub_request(:get, "https://onboarding/places/1/change")
39
+ .to_return(body: { entry: { name: 'Steve', address: 'Zurich' } }.to_json)
40
+ record = Change.find(1)
41
+ record.deep_merge!(entry: { name: 'Paul' })
42
+ expect(record.entry.name).to eq 'Paul'
43
+ expect(record.entry.address).to eq 'Zurich'
44
+ end
45
+
46
+ it 'deep_merge a given hash' do
47
+ stub_request(:get, "https://onboarding/places/1/change")
48
+ .to_return(body: { entry: { name: 'Steve', address: 'Zurich' } }.to_json)
49
+ record = Change.find(1)
50
+ new_record = record.deep_merge(entry: { name: 'Paul' })
51
+ expect(new_record.entry.name).to eq 'Paul'
52
+ expect(new_record.entry.address).to eq 'Zurich'
53
+ expect(record.entry.name).to eq 'Steve'
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:handler) { spy('handler') }
7
+
8
+ before do
9
+ class Record < LHS::Record
10
+ endpoint 'http://local.ch/v2/records/{id}'
11
+ end
12
+ class NestedRecord < LHS::Record
13
+ endpoint 'http://local.ch/v2/other_records/{id}'
14
+ end
15
+ stub_request(:get, "http://local.ch/v2/records/1")
16
+ .to_return(body: {
17
+ href: 'http://local.ch/v2/records/1',
18
+ other: {
19
+ href: 'http://local.ch/v2/other_records/2'
20
+ }
21
+ }.to_json)
22
+ stub_request(:get, "http://local.ch/v2/other_records/2")
23
+ .to_return(status: 404)
24
+ end
25
+
26
+ it 'allows to pass error_handling for includes to LHC' do
27
+ handler = ->(_) { return { deleted: true } }
28
+ record = Record.includes_first_page(:other).references(other: { rescue: { LHC::NotFound => handler } }).find(id: 1)
29
+
30
+ expect(record.other.deleted).to be(true)
31
+ end
32
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+
7
+ let(:listing) { location.listings.first }
8
+
9
+ before do
10
+ stub_request(:get, 'http://uberall/locations/1')
11
+ .to_return(body: {
12
+ listings: [{
13
+ directory: { name: 'Instagram' }
14
+ }]
15
+ }.to_json)
16
+ end
17
+
18
+ context 'has_many' do
19
+
20
+ before do
21
+ class Location < LHS::Record
22
+ endpoint 'http://uberall/locations'
23
+ endpoint 'http://uberall/locations/{id}'
24
+ has_many :listings
25
+ end
26
+
27
+ class Listing < LHS::Record
28
+
29
+ def supported?
30
+ true
31
+ end
32
+ end
33
+ end
34
+
35
+ let(:location) { Location.find(1) }
36
+
37
+ it 'casts the relation into the correct type' do
38
+ expect(listing).to be_kind_of(Listing)
39
+ expect(listing.supported?).to eq true
40
+ end
41
+
42
+ it 'keeps hirachy when casting it to another class on access' do
43
+ expect(listing._root._raw).to eq location._raw
44
+ expect(listing.parent.parent._raw).to eq location._raw
45
+ end
46
+ end
47
+
48
+ context 'custom class_name' do
49
+ before do
50
+ module Uberall
51
+ class Location < LHS::Record
52
+ endpoint 'http://uberall/locations'
53
+ endpoint 'http://uberall/locations/{id}'
54
+ has_many :listings, class_name: 'Uberall::Listing'
55
+ end
56
+ end
57
+
58
+ module Uberall
59
+ class Listing < LHS::Record
60
+
61
+ def supported?
62
+ true
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ let(:location) { Uberall::Location.find(1) }
69
+
70
+ it 'casts the relation into the correct type' do
71
+ expect(listing).to be_kind_of(Uberall::Listing)
72
+ expect(listing.supported?).to eq true
73
+ end
74
+
75
+ it 'keeps hirachy when casting it to another class on access' do
76
+ expect(listing._root._raw).to eq location._raw
77
+ expect(listing.parent.parent._raw).to eq location._raw
78
+ end
79
+ end
80
+
81
+ context 'explicit association class configuration overrules href class casting' do
82
+ before do
83
+ class Place < LHS::Record
84
+ endpoint 'http://places/places/{id}'
85
+ has_many :categories, class_name: 'NewCategory'
86
+ end
87
+
88
+ class NewCategory < LHS::Record
89
+ endpoint 'http://newcategories/newcategories/{id}'
90
+
91
+ def name
92
+ self['category_name']
93
+ end
94
+ end
95
+
96
+ class Category < LHS::Record
97
+ endpoint 'http://categories/categories/{id}'
98
+ end
99
+
100
+ stub_request(:get, "http://places/places/1")
101
+ .to_return(body: {
102
+ categories: [{
103
+ href: 'https://categories/categories/1'
104
+ }]
105
+ }.to_json)
106
+
107
+ stub_request(:get, "https://categories/categories/1")
108
+ .to_return(body: {
109
+ href: 'https://categories/categories/1',
110
+ category_name: 'Pizza'
111
+ }.to_json)
112
+ end
113
+
114
+ it 'explicit association configuration overrules href class casting' do
115
+ place = Place.includes_first_page(:categories).find(1)
116
+ expect(place.categories.first).to be_kind_of NewCategory
117
+ expect(place.categories.first.name).to eq('Pizza')
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+
7
+ let(:transaction) { Transaction.find(1) }
8
+ let(:user) { transaction.user }
9
+
10
+ before do
11
+ [1, 2].each do |id|
12
+ stub_request(:get, "http://myservice/transactions/#{id}")
13
+ .to_return(body: {
14
+ user: {
15
+ email_address: 'steve@local.ch',
16
+ comments: []
17
+ }
18
+ }.to_json)
19
+ end
20
+ end
21
+
22
+ context 'has_one' do
23
+ before do
24
+ class Transaction < LHS::Record
25
+ endpoint 'http://myservice/transactions'
26
+ endpoint 'http://myservice/transactions/{id}'
27
+ has_one :user
28
+ end
29
+
30
+ class User < LHS::Record
31
+ has_many :comments
32
+
33
+ def email
34
+ self[:email_address]
35
+ end
36
+ end
37
+
38
+ class Comment < LHS::Record
39
+ end
40
+ end
41
+
42
+ it 'casts the relation into the correct type' do
43
+ expect(user).to be_kind_of(User)
44
+ expect(user.email).to eq 'steve@local.ch'
45
+ end
46
+
47
+ it 'keeps hirachy when casting it to another class on access' do
48
+ expect(user._root._raw).to eq transaction._raw
49
+ expect(user.parent._raw).to eq transaction._raw
50
+ end
51
+ end
52
+
53
+ context 'custom class_name' do
54
+
55
+ before do
56
+ class Transaction < LHS::Record
57
+ endpoint 'http://myservice/transactions'
58
+ endpoint 'http://myservice/transactions/{id}'
59
+ has_one :user, class_name: 'Custom::User'
60
+ end
61
+
62
+ module Custom
63
+ class User < LHS::Record
64
+ def email
65
+ self[:email_address]
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ it 'casts the relation into the correct type' do
72
+ expect(user).to be_kind_of(Custom::User)
73
+ expect(user.email).to eq 'steve@local.ch'
74
+ end
75
+ end
76
+
77
+ context 'explicit association class configuration overrules href class casting' do
78
+ before do
79
+ class Place < LHS::Record
80
+ endpoint 'http://places/places/{id}'
81
+ has_one :category, class_name: 'NewCategory'
82
+ end
83
+
84
+ class NewCategory < LHS::Record
85
+ endpoint 'http://newcategories/newcategories/{id}'
86
+
87
+ def name
88
+ self['category_name']
89
+ end
90
+ end
91
+
92
+ class Category < LHS::Record
93
+ endpoint 'http://categories/categories/{id}'
94
+ end
95
+
96
+ stub_request(:get, "http://places/places/1")
97
+ .to_return(body: {
98
+ category: {
99
+ href: 'https://categories/categories/1'
100
+ }
101
+ }.to_json)
102
+
103
+ stub_request(:get, "https://categories/categories/1")
104
+ .to_return(body: {
105
+ href: 'https://categories/categories/1',
106
+ category_name: 'Pizza'
107
+ }.to_json)
108
+ end
109
+
110
+ it 'explicit association configuration overrules href class casting' do
111
+ place = Place.includes_first_page(:category).find(1)
112
+ expect(place.category).to be_kind_of NewCategory
113
+ expect(place.category.name).to eq('Pizza')
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint 'http://datastore/records/'
9
+ endpoint 'http://datastore/records/{id}'
10
+ end
11
+ end
12
+
13
+ context 'href_for' do
14
+
15
+ it 'injects variables and returns href' do
16
+ expect(Record.href_for(1)).to eq 'http://datastore/records/1'
17
+ expect(Record.href_for('vmasd241')).to eq 'http://datastore/records/vmasd241'
18
+ end
19
+
20
+ it 'also works with url_for (alias)' do
21
+ expect(Record.url_for(1)).to eq 'http://datastore/records/1'
22
+ expect(Record.url_for('vmasd241')).to eq 'http://datastore/records/vmasd241'
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:handler) { spy('handler') }
7
+ let(:record_json) { { color: 'blue' }.to_json }
8
+
9
+ before do
10
+ class Record < LHS::Record
11
+ endpoint 'http://local.ch/v2/records'
12
+ endpoint 'http://local.ch/v2/records/{id}'
13
+ end
14
+ end
15
+
16
+ context 'ignore errors' do
17
+ it 'allows to ignore errors' do
18
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 404)
19
+ record = Record
20
+ .where(color: 'blue')
21
+ .ignore(LHC::NotFound)
22
+ .fetch
23
+ expect(record).to eq nil
24
+ end
25
+ end
26
+
27
+ context 'ignore errors during create' do
28
+
29
+ it 'allows to ignore errors during create' do
30
+ stub_request(:post, 'http://local.ch/v2/records')
31
+ .to_return(status: 409)
32
+ record = Record.ignore(LHC::Conflict).create(name: 'Steve')
33
+ expect(record._raw).to eq(name: 'Steve')
34
+ end
35
+ end
36
+
37
+ context 'multiple ignored errors' do
38
+ it 'ignores error if first of them is specified' do
39
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 401)
40
+ record = Record
41
+ .ignore(LHC::Unauthorized)
42
+ .where(color: 'blue')
43
+ .ignore(LHC::NotFound)
44
+ .fetch
45
+ expect(record).to eq nil
46
+ end
47
+
48
+ it 'ignores error if last of them is specified' do
49
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 404)
50
+ record = Record
51
+ .ignore(LHC::Unauthorized)
52
+ .where(color: 'blue')
53
+ .ignore(LHC::NotFound)
54
+ .fetch
55
+ expect(record).to eq nil
56
+ end
57
+ end
58
+
59
+ it 'also can ignore all LHC errors' do
60
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 401)
61
+ record = Record
62
+ .ignore(LHC::Error)
63
+ .where(color: 'blue')
64
+ .fetch
65
+ expect(record).to eq nil
66
+ end
67
+
68
+ it 'can ignore multiple error with one ignore call, on chain start' do
69
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 401)
70
+ record = Record
71
+ .ignore(LHC::Unauthorized, LHC::NotFound)
72
+ .where(color: 'blue')
73
+ .fetch
74
+ expect(record).to eq nil
75
+ end
76
+
77
+ it 'can ignore multiple error with one ignore call, also within the chain' do
78
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 401)
79
+ record = Record
80
+ .where(color: 'blue')
81
+ .ignore(LHC::Unauthorized, LHC::NotFound)
82
+ .fetch
83
+ expect(record).to eq nil
84
+ end
85
+
86
+ it 'returns record when ignoring errors on where' do
87
+ stub_request(:get, 'http://local.ch/v2/records?color=blue').to_return(status: 200, body: record_json)
88
+ record = Record
89
+ .ignore(LHC::Error)
90
+ .where(color: 'blue')
91
+ expect(record).not_to eq nil
92
+ end
93
+
94
+ context 'response body' do
95
+
96
+ let(:body) { { error_message: 'you are not worthy' }.to_json }
97
+
98
+ it 'returns nil also when ignoring errors on find' do
99
+ stub_request(:get, "http://local.ch/v2/records/1").to_return(status: 500, body: body)
100
+ record = Record
101
+ .ignore(LHC::Error)
102
+ .find(1)
103
+ expect(record).to eq nil
104
+ end
105
+
106
+ it 'returns nil also when ignoring errors on find with parameters' do
107
+ stub_request(:get, "http://local.ch/v2/records/1").to_return(status: 500, body: body)
108
+ record = Record
109
+ .ignore(LHC::Error)
110
+ .find(id: 1)
111
+ expect(record).to eq nil
112
+ end
113
+
114
+ it 'returns nil also when ignoring errors on fetch' do
115
+ stub_request(:get, "http://local.ch/v2/records?color=blue").to_return(status: 500, body: body)
116
+ record = Record
117
+ .ignore(LHC::Error)
118
+ .where(color: 'blue')
119
+ .fetch
120
+ expect(record).to eq nil
121
+ end
122
+
123
+ it 'returns nil also when ignoring errors on find_by' do
124
+ stub_request(:get, "http://local.ch/v2/records?color=blue&limit=1").to_return(status: 500, body: body)
125
+ record = Record
126
+ .ignore(LHC::Error)
127
+ .find_by(color: 'blue')
128
+ expect(record).to eq nil
129
+ end
130
+
131
+ it 'returns record when ignoring errors on find' do
132
+ stub_request(:get, "http://local.ch/v2/records/1").to_return(status: 200, body: record_json)
133
+ record = Record
134
+ .ignore(LHC::Error)
135
+ .find(1)
136
+ expect(record).not_to eq nil
137
+ end
138
+ end
139
+ end