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::Item do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint '{+datastore}/records'
9
+ end
10
+ end
11
+
12
+ let(:json) do
13
+ {
14
+ local_entry_id: 'ABC123'
15
+ }
16
+ end
17
+
18
+ let(:item) do
19
+ LHS::Data.new(json, nil, Record)
20
+ end
21
+
22
+ it 'is possible to fetch data' do
23
+ expect(
24
+ item.fetch(:local_entry_id)
25
+ ).to eq 'ABC123'
26
+ end
27
+
28
+ context 'empty data' do
29
+ let(:json) do
30
+ {}
31
+ end
32
+
33
+ it 'is possible to get a default when fetched data is nil' do
34
+ expect(
35
+ item.fetch(:local_entry_id, 'DEFAULT')
36
+ ).to eq 'DEFAULT'
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint '{+datastore}/v2/{campaign_id}/feedbacks'
9
+ endpoint '{+datastore}/v2/feedbacks'
10
+ end
11
+ end
12
+
13
+ let(:data) do
14
+ LHS::Data.new({ addresses: [{ business: { identities: [{ name: 'Löwenzorn' }] } }] }, nil, Record)
15
+ end
16
+
17
+ context 'item getter' do
18
+ it 'returns a collection if you access an array' do
19
+ expect(data.addresses).to be_kind_of(LHS::Data)
20
+ expect(data.addresses._proxy).to be_kind_of(LHS::Collection)
21
+ expect(data.addresses.first.business.identities.first.name).to eq 'Löwenzorn'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+ before do
7
+ class Feedback < LHS::Record
8
+ endpoint '{+datastore}/v2/feedbacks'
9
+ endpoint '{+datastore}/v2/feedbacks/{id}'
10
+ end
11
+ end
12
+
13
+ let(:hash) do
14
+ { 'addresses' => [{ 'businesses' => { 'identities' => [{ 'name' => 'Löwenzorn' }] } }] }
15
+ end
16
+
17
+ let(:data) do
18
+ LHS::Data.new(hash, nil, Feedback)
19
+ end
20
+
21
+ it 'deep symbolizes keys internaly when new data is initalized' do
22
+ expect(data._raw[:addresses].first[:businesses][:identities].first[:name]).to eq 'Löwenzorn'
23
+ data.id = 'YZ12'
24
+ expect(data._raw.keys).to include(:id)
25
+ end
26
+
27
+ it 'deep symbolizes internal data' do
28
+ feedback = Feedback.build(hash)
29
+ expect(feedback._raw.keys).to include(:addresses)
30
+ expect(feedback._raw[:addresses].first[:businesses][:identities].first[:name]).to eq 'Löwenzorn'
31
+ end
32
+
33
+ it 'deep symbolizes internal data when building new objects' do
34
+ feedback = Feedback.build('name' => 'BB8')
35
+ expect(feedback._data._raw.keys).to include(:name)
36
+ end
37
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint '{+datastore}/records'
9
+ end
10
+ end
11
+
12
+ let(:json) do
13
+ {
14
+ key: 'value'
15
+ }
16
+ end
17
+
18
+ let(:item) do
19
+ LHS::Data.new(json, nil, Record)
20
+ end
21
+
22
+ it 'is possible to map' do
23
+ mapped_data = item.map do |key, value|
24
+ { value => key }
25
+ end
26
+ expect(mapped_data).to eq([{ 'value' => :key }])
27
+ end
28
+
29
+ context 'nested' do
30
+ let(:json) do
31
+ {
32
+ languages: {
33
+ de: { key: 'german value' },
34
+ en: { key: 'english value' }
35
+ }
36
+ }
37
+ end
38
+
39
+ it 'also maps nested data' do
40
+ mapped_data = item.languages.map do |_language, value|
41
+ value[:key]
42
+ end
43
+ expect(mapped_data).to eq(['german value', 'english value'])
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+
7
+ context 'nested data' do
8
+ before do
9
+ class Presence < LHS::Record
10
+ endpoint 'http://opm/presences'
11
+ end
12
+ stub_request(:post, "http://opm/presences")
13
+ .to_return(
14
+ body: {
15
+ listings: [{ status: 'CONNECTED' }],
16
+ field_errors: []
17
+ }.to_json
18
+ )
19
+ end
20
+
21
+ it 'does not raise when accessing nested data' do
22
+ presence = Presence.create
23
+ expect(lambda {
24
+ presence.listings.first
25
+ }).not_to raise_error NoMethodError
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint '{+datastore}/v2/{campaign_id}/feedbacks'
9
+ endpoint '{+datastore}/v2/feedbacks'
10
+ end
11
+ end
12
+
13
+ let(:json) do
14
+ load_json(:feedbacks)
15
+ end
16
+
17
+ let(:data) do
18
+ LHS::Data.new(json, nil, Record)
19
+ end
20
+
21
+ let(:item) do
22
+ data[0]
23
+ end
24
+
25
+ context 'update' do
26
+ it 'persists changes on the backend' do
27
+ stub_request(:post, item.href)
28
+ .with(body: { name: 'Steve' }.to_json)
29
+ result = item.partial_update(name: 'Steve')
30
+ expect(result).to eq true
31
+ end
32
+
33
+ it 'returns false if persisting went wrong' do
34
+ stub_request(:post, item.href).to_return(status: 500)
35
+ result = item.partial_update(name: 'Steve')
36
+ expect(result).to eq false
37
+ end
38
+
39
+ it 'merges reponse data with object' do
40
+ stub_request(:post, item.href)
41
+ .to_return(status: 200, body: item._raw.merge(likes: 'Banana').to_json)
42
+ item.partial_update(name: 'Steve')
43
+ expect(item.name).to eq 'Steve'
44
+ expect(item.likes).to eq 'Banana'
45
+ end
46
+
47
+ it 'updates local version of an object even if BE request fails' do
48
+ stub_request(:post, item.href)
49
+ .to_return(status: 400, body: item._raw.merge(likes: 'Banana').to_json)
50
+ item.update(name: 'Andrea')
51
+ expect(item.name).to eq 'Andrea'
52
+ expect(item.likes).not_to eq 'Banana'
53
+ end
54
+ end
55
+
56
+ context 'with many placeholders' do
57
+ before do
58
+ class GrandChild < LHS::Record
59
+ endpoint 'http://host/v2/parents/{parent_id}/children/{child_id}/grand_children'
60
+ endpoint 'http://host/v2/parents/{parent_id}/children/{child_id}/grand_children/{id}'
61
+ end
62
+ end
63
+
64
+ let(:data) do
65
+ {
66
+ id: "aaa",
67
+ parent_id: "bbb",
68
+ child_id: 'ccc',
69
+ name: "Lorem"
70
+ }
71
+ end
72
+
73
+ let(:item) do
74
+ GrandChild.new(data)
75
+ end
76
+
77
+ it 'persists changes on the backend' do
78
+ stub_request(:get, 'http://host/v2/parents/bbb/children/ccc/grand_children/aaa')
79
+ .to_return(status: 200, body: data.to_json)
80
+ stub_request(:post, 'http://host/v2/parents/bbb/children/ccc/grand_children/aaa')
81
+ .with(body: { name: 'Steve' }.to_json)
82
+
83
+ grand_child = GrandChild.find(parent_id: 'bbb', child_id: 'ccc', id: 'aaa')
84
+ expect(grand_child.name).to eq('Lorem')
85
+ result = grand_child.partial_update(name: 'Steve')
86
+ expect(result).to eq true
87
+ end
88
+
89
+ it 'persists changes on the backend removing placeholder from body' do
90
+ stub_request(:post, 'http://host/v2/parents/bbb/children/ccc/grand_children/kkkk')
91
+ .with(body: { name: 'Steve' }.to_json)
92
+
93
+ result = item.partial_update(name: 'Steve', id: 'kkkk')
94
+ expect(result).to eq true
95
+ end
96
+ end
97
+
98
+ context 'update!' do
99
+ it 'raises if something goes wrong' do
100
+ stub_request(:post, item.href)
101
+ .with(body: { name: 'Steve' }.to_json)
102
+ .to_return(status: 500)
103
+ expect(-> { item.partial_update!(name: 'Steve') }).to raise_error LHC::ServerError
104
+ end
105
+ end
106
+
107
+ context 'records without hrefs and nested items' do
108
+
109
+ before do
110
+ class Location < LHS::Record
111
+ endpoint 'http://uberall/locations'
112
+ endpoint 'http://uberall/locations/{id}'
113
+ end
114
+ end
115
+
116
+ it 'finds and compiles existing endpoints to determine update url' do
117
+ stub_request(:get, "http://uberall/locations/1").to_return(body: { id: 1 }.to_json)
118
+ stub_request(:post, "http://uberall/locations/1").to_return(body: { id: 1, listings: [{ directory: 'facebook' }] }.to_json)
119
+ location = Location.find(1)
120
+ location.partial_update(autoSync: true)
121
+ expect(location.autoSync).to eq true
122
+ expect(location.listings.first.directory).to eq 'facebook'
123
+ end
124
+
125
+ context 'records with nested items' do
126
+
127
+ before do
128
+ class Location < LHS::Record
129
+ endpoint 'http://uberall/locations'
130
+ endpoint 'http://uberall/locations/{id}'
131
+ configuration item_created_key: [:response, :location], item_key: [:response, :location]
132
+ end
133
+ end
134
+
135
+ it 'finds and compiles existing endpoints to determine update url' do
136
+ stub_request(:get, "http://uberall/locations/1").to_return(body: { response: { location: { id: 1 } } }.to_json)
137
+ stub_request(:post, "http://uberall/locations/1").to_return(body: { response: { location: { id: 1, listings: [{ directory: 'facebook' }] } } }.to_json)
138
+ location = Location.find(1)
139
+ location.partial_update(autoSync: true)
140
+ expect(location.autoSync).to eq true
141
+ expect(location.listings.first.directory).to eq 'facebook'
142
+ end
143
+
144
+ it 'use given update http method' do
145
+ stub_request(:get, "http://uberall/locations/1").to_return(body: { response: { location: { id: 1 } } }.to_json)
146
+ stub_request(:patch, "http://uberall/locations/1").to_return(body: { response: { location: { id: 1, listings: [{ directory: 'facebook' }] } } }.to_json)
147
+ location = Location.find(1)
148
+ location.partial_update({ autoSync: true }, { method: :patch })
149
+ expect(location.autoSync).to eq true
150
+ expect(location.listings.first.directory).to eq 'facebook'
151
+ end
152
+ end
153
+ end
154
+
155
+ context 'chainable' do
156
+ it 'allows to chain partial_update with options' do
157
+ stub_request(:put, item.href)
158
+ .with(body: { name: 'Steve' }.to_json)
159
+ result = item.options(method: :put).partial_update(name: 'Steve')
160
+ expect(result).to eq true
161
+ end
162
+
163
+ it 'allows to chain partial_update! with options' do
164
+ stub_request(:put, item.href)
165
+ .with(body: { name: 'Steve' }.to_json)
166
+ result = item.options(method: :put).partial_update!(name: 'Steve')
167
+ expect(result).to eq true
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+ let(:item) do
7
+ LHS::Item.new(id: 1234)
8
+ end
9
+
10
+ context '#respond_to?' do
11
+ it 'is true for setters' do
12
+ expect(item.respond_to?(:id=)).to be(true)
13
+ end
14
+
15
+ it 'is true for getters' do
16
+ expect(item.respond_to?(:id)).to be(true)
17
+ end
18
+
19
+ it 'is true for brackets' do
20
+ expect(item.respond_to?(:[])).to be(true)
21
+ end
22
+
23
+ it 'is false for new' do
24
+ expect(item.respond_to?(:new)).to be(false)
25
+ end
26
+
27
+ it 'is false for proxy_association' do
28
+ expect(item.respond_to?(:proxy_association)).to be(false)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Item do
6
+ before do
7
+ class Record < LHS::Record
8
+ endpoint '{+datastore}/v2/{campaign_id}/feedbacks'
9
+ endpoint '{+datastore}/v2/feedbacks'
10
+ end
11
+ end
12
+
13
+ let(:json) do
14
+ load_json(:feedbacks)
15
+ end
16
+
17
+ let(:data) do
18
+ LHS::Data.new(json, nil, Record)
19
+ end
20
+
21
+ let(:item) do
22
+ data[0]
23
+ end
24
+
25
+ context 'endpoint options' do
26
+ let(:headers) { { 'X-Header' => 'VALUE' } }
27
+
28
+ before do
29
+ class RecordWithOptions < LHS::Record
30
+ endpoint 'http://datastore/records', headers: { 'X-Header' => 'VALUE' }
31
+ end
32
+ end
33
+
34
+ it 'considers end point options when saving' do
35
+ data = { name: 'Steve' }
36
+ stub_request(:post, "http://datastore/records")
37
+ .with(body: data.to_json, headers: headers)
38
+ .to_return(body: data.to_json)
39
+ RecordWithOptions.create!(data)
40
+ end
41
+ end
42
+
43
+ context 'save' do
44
+ it 'persists changes on the backend' do
45
+ stub_request(:post, item.href).with(body: item._raw.merge(name: 'Steve').to_json)
46
+ item.name = 'Steve'
47
+ expect(item.save).to eq true
48
+ end
49
+
50
+ it 'returns false if persting goes wrong' do
51
+ stub_request(:post, item.href)
52
+ .with(body: item._raw.to_json)
53
+ .to_return(status: 500)
54
+ expect(item.save).to eq false
55
+ end
56
+
57
+ it 'merges reponse data with object' do
58
+ stub_request(:post, item.href)
59
+ .with(body: item._raw.to_json)
60
+ .to_return(status: 200, body: item._raw.merge(name: 'Steve').to_json)
61
+ item.save
62
+ expect(item.name).to eq 'Steve'
63
+ end
64
+ end
65
+
66
+ context 'with many placeholders' do
67
+ before do
68
+ class GrandChild < LHS::Record
69
+ endpoint 'http://host/v2/parents/{parent_id}/children/{child_id}/grand_children'
70
+ endpoint 'http://host/v2/parents/{parent_id}/children/{child_id}/grand_children/{id}'
71
+ end
72
+ end
73
+
74
+ let(:data) do
75
+ {
76
+ parent_id: "bbb",
77
+ child_id: 'ccc',
78
+ name: "Lorem"
79
+ }
80
+ end
81
+
82
+ let(:item) do
83
+ GrandChild.new(data)
84
+ end
85
+
86
+ it 'persists changes on the backend' do
87
+ stub_request(:post, 'http://host/v2/parents/bbb/children/ccc/grand_children')
88
+ .with(body: { name: "Lorem" }.to_json)
89
+
90
+ expect(item.save).to eq true
91
+ end
92
+ end
93
+
94
+ context 'save!' do
95
+ it 'raises if something goes wrong' do
96
+ stub_request(:post, item.href)
97
+ .with(body: item._raw.to_json)
98
+ .to_return(status: 500)
99
+ expect(-> { item.save! }).to raise_error LHC::ServerError
100
+ end
101
+
102
+ it 'keeps header psassed in the options' do
103
+ headers = { 'Stats' => 'first-access' }
104
+ request = stub_request(:post, item.href)
105
+ .with(
106
+ body: item._raw.to_json,
107
+ headers: headers
108
+ )
109
+ .to_return(status: 200, body: item._raw.to_json)
110
+
111
+ item.save!(headers: headers)
112
+ expect(request).to have_been_requested
113
+ end
114
+ end
115
+ end