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,43 @@
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
+
12
+ class AnotherRecord < LHS::Record
13
+ endpoint 'http://datastore/otherrecords'
14
+ endpoint 'http://datastore/otherrecords/{id}'
15
+
16
+ def id
17
+ another_id
18
+ end
19
+ end
20
+ end
21
+
22
+ context 'reload!' do
23
+ it 'reloads the record by id' do
24
+ stub_request(:post, "http://datastore/records")
25
+ .to_return(body: { id: 1, name: 'Steve' }.to_json)
26
+ record = Record.create!(name: 'Steve')
27
+ stub_request(:get, "http://datastore/records/1")
28
+ .to_return(body: { id: 1, name: 'Steve', async: 'data' }.to_json)
29
+ record.reload!
30
+ expect(record.async).to eq 'data'
31
+ end
32
+
33
+ it 'reloads the record by id if a record method defines the actual id' do
34
+ stub_request(:post, "http://datastore/otherrecords")
35
+ .to_return(body: { another_id: 2, name: 'Can' }.to_json)
36
+ record = AnotherRecord.create!(name: 'Can')
37
+ stub_request(:get, "http://datastore/otherrecords/2")
38
+ .to_return(body: { id: 2, name: 'Can', async: 'data' }.to_json)
39
+ record.reload!
40
+ expect(record.async).to eq 'data'
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,65 @@
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
+ let(:json) do
14
+ { id: 1, name: 'Steve' }.to_json
15
+ end
16
+
17
+ context 'reload!' do
18
+ it 'returns an instance of the record, not an LHS::Item' do
19
+ stub_request(:post, "http://datastore/records").to_return(body: json)
20
+ stub_request(:get, "http://datastore/records/1").to_return(body: json)
21
+ record = Record.create!(name: 'Steve')
22
+ expect(record).to be_kind_of Record
23
+ expect(record.reload!).to be_kind_of Record
24
+ end
25
+ end
26
+
27
+ context 'nested items' do
28
+
29
+ before do
30
+ class Location < LHS::Record
31
+ endpoint 'http://uberall/locations'
32
+ endpoint 'http://uberall/locations/{id}'
33
+
34
+ configuration item_key: [:response, :location], items_key: [:response, :locations]
35
+ end
36
+ end
37
+
38
+ it 'merges reloads properly' do
39
+ stub_request(:get, "http://uberall/locations?identifier=http://places/1&limit=1")
40
+ .to_return(
41
+ body: {
42
+ response: {
43
+ locations: [{
44
+ id: 1,
45
+ name: 'Fridolin'
46
+ }]
47
+ }
48
+ }.to_json
49
+ )
50
+ location = Location.find_by(identifier: 'http://places/1')
51
+ stub_request(:get, "http://uberall/locations/1")
52
+ .to_return(
53
+ body: {
54
+ response: {
55
+ location: {
56
+ normalizationStatus: 'NORMALIZED'
57
+ }
58
+ }
59
+ }.to_json
60
+ )
61
+ location.reload!
62
+ expect(location.normalizationStatus).to eq 'NORMALIZED'
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,90 @@
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/feedbacks/{id}'
9
+ end
10
+ end
11
+
12
+ context 'url pattern' do
13
+ let(:datastore) { 'http://local.ch/v2' }
14
+
15
+ before do
16
+ LHC.config.placeholder(:datastore, datastore)
17
+ class Record < LHS::Record
18
+ endpoint '{+datastore}/content-ads/{campaign_id}/feedbacks'
19
+ endpoint '{+datastore}/feedbacks'
20
+ end
21
+ end
22
+
23
+ it 'is using params as query params explicitly when provided in params namespace' do
24
+ request = stub_request(:get, "#{datastore}/content-ads/123/feedbacks?campaign_id=456").to_return(status: 200)
25
+ Record.where(campaign_id: 123, params: { campaign_id: '456' }).to_a
26
+ assert_requested(request)
27
+ end
28
+ end
29
+
30
+ context '#convert_options_to_endpoint' do
31
+ before do
32
+ class Record < LHS::Record
33
+ endpoint 'http://datastore/feedbacks/{id}', params: { tracking: 123 }
34
+ end
35
+ end
36
+
37
+ it 'identifies endpoint by given url and merges back endpoint template parameters' do
38
+ options = LHS::Record.send(:convert_options_to_endpoints, url: 'http://datastore/feedbacks/1')
39
+ expect(options[:params][:id]).to eq '1'
40
+ expect(options[:url]).to eq 'http://datastore/feedbacks/{id}'
41
+ end
42
+
43
+ it 'identifies endpoint by given url and merges back endpoint template parameters into an array, if array was given' do
44
+ options = LHS::Record.send(:convert_options_to_endpoints, [{ url: 'http://datastore/feedbacks/1' }])
45
+ expect(options[0][:params][:id]).to eq '1'
46
+ expect(options[0][:url]).to eq 'http://datastore/feedbacks/{id}'
47
+ end
48
+
49
+ it 'returnes nil if endpoint was not found for the given url' do
50
+ options = LHS::Record.send(:convert_options_to_endpoints, url: 'http://datastore/reviews/1')
51
+ expect(options).to eq nil
52
+ end
53
+ end
54
+
55
+ context '#extend_with_reference' do
56
+ it 'extends given options with the one for the refernce' do
57
+ options = LHS::Record.send(:extend_with_reference, { url: 'http://datastore/feedbacks/1' }, { auth: { bearer: '123' } })
58
+ expect(options[:auth][:bearer]).to eq '123'
59
+ end
60
+
61
+ it 'extends given list of options with the one for the refernce' do
62
+ options = LHS::Record.send(:extend_with_reference, [{ url: 'http://datastore/feedbacks/1' }], auth: { bearer: '123' })
63
+ expect(options[0][:auth][:bearer]).to eq '123'
64
+ end
65
+ end
66
+
67
+ context '#options_for_data' do
68
+ it 'extract request options from raw data' do
69
+ options = LHS::Record.send(:url_option_for, LHS::Data.new({ href: 'http://datastore/feedbacks/1' }, nil, Record))
70
+ expect(options[:url]).to eq 'http://datastore/feedbacks/1'
71
+ end
72
+
73
+ it 'extract a list of request options from raw data if data is a collection' do
74
+ options = LHS::Record.send(:url_option_for, LHS::Data.new({ items: [{ href: 'http://datastore/feedbacks/1' }] }, nil, Record))
75
+ expect(options[0][:url]).to eq 'http://datastore/feedbacks/1'
76
+ end
77
+
78
+ it 'extract request options from raw nested data' do
79
+ options = LHS::Record.send(:url_option_for, LHS::Data.new({ reviews: { href: 'http://datastore/reviews/1' } }, nil, Record), :reviews)
80
+ expect(options[:url]).to eq 'http://datastore/reviews/1'
81
+ end
82
+ end
83
+
84
+ context '#record_for_options' do
85
+ it 'identifies lhs record from given options, as all request have to be done through LHS Records' do
86
+ record = LHS::Record.send(:record_for_options, url: 'http://datastore/feedbacks/1')
87
+ expect(record).to eq Record
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'save!' do
7
+ context 'without href' do
8
+ before do
9
+ LHC.config.placeholder('datastore', datastore)
10
+ class Feedback < LHS::Record
11
+ endpoint '{+datastore}/content-ads/{campaign_id}/feedbacks'
12
+ end
13
+ end
14
+
15
+ let(:datastore) { 'http://local.ch/v2' }
16
+ let(:campaign_id) { 12345 }
17
+ let(:object) { { recommended: true } }
18
+ let(:item) { Feedback.new(object.merge(campaign_id: campaign_id)) }
19
+ let!(:request) do
20
+ stub_request(:post, "#{datastore}/content-ads/#{campaign_id}/feedbacks")
21
+ .with(body: object.to_json)
22
+ .to_return(status: 200, body: object.to_json)
23
+ end
24
+
25
+ it 'removes params used to compute url from send data' do
26
+ item.save!
27
+ expect(request).to have_been_made.once
28
+ end
29
+
30
+ context 'item without data' do
31
+ let(:item) { Feedback.new(object) }
32
+
33
+ it 'takes params to find endpoint also from the options' do
34
+ item.save!(params: { campaign_id: campaign_id })
35
+ expect(request).to have_been_made.once
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,39 @@
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
+ scope :blue, -> { where(color: 'blue') }
19
+ scope :available, -> { where(availalbe: 'true') }
20
+ scope :limited_to, ->(limit) { where(limit: limit) }
21
+ end
22
+ end
23
+
24
+ context 'scope chains' do
25
+ it 'allows chaining multiple scopes' do
26
+ stub_request(:get, "http://datastore/v2/records/?availalbe=true&color=blue&limit=20").to_return(response)
27
+ expect(
28
+ Record.blue.available.limited_to(20).first.name
29
+ ).to eq 'Steve'
30
+ end
31
+
32
+ it 'allows to chain multiple scopes when first one has arguments' do
33
+ stub_request(:get, "http://datastore/v2/records/?availalbe=true&color=blue&limit=20").to_return(response)
34
+ expect(
35
+ Record.limited_to(20).blue.available.first.name
36
+ ).to eq 'Steve'
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:record) do
7
+ LHS::Record.new(LHS::Data.new(['cat', 'dog']))
8
+ end
9
+
10
+ context 'select' do
11
+ it 'works with select' do
12
+ expect(
13
+ record.select { |x| x }.join
14
+ ).to eq 'catdog'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ let(:user_item) do
7
+ {
8
+ email: 'someone@somewhe.re'
9
+ }
10
+ end
11
+
12
+ let(:item) do
13
+ {
14
+ href: 'http://datastore/records/1',
15
+ user: user_item
16
+ }
17
+ end
18
+
19
+ let(:record) { Record.find(1) }
20
+
21
+ before do
22
+ class User < LHS::Record
23
+ end
24
+
25
+ class Record < LHS::Record
26
+ endpoint 'http://datastore/records/{id}'
27
+
28
+ has_one :user, class_name: 'User'
29
+ end
30
+
31
+ stub_request(:get, 'http://datastore/records/1')
32
+ .to_return(body: item.to_json)
33
+ end
34
+
35
+ describe 'respond_to?(:to_ary)' do
36
+ context 'when creating item' do
37
+ let(:record) do
38
+ Record.new(user: User.new)
39
+ end
40
+
41
+ it 'does not respond to to_ary' do
42
+ expect(record.user.respond_to?(:to_ary)).to eq false
43
+ end
44
+ end
45
+
46
+ context 'when returning a single item' do
47
+ it 'does not respond to to_ary' do
48
+ expect(record.user.respond_to?(:to_ary)).to eq false
49
+ end
50
+ end
51
+
52
+ context 'when returning array of items' do
53
+ let(:user_item) do
54
+ [
55
+ { email: 'someone@somewhe.re' },
56
+ { email: 'someone.else@somewhe.re' }
57
+ ]
58
+ end
59
+
60
+ it 'responds to to_ary' do
61
+ expect(record.user.respond_to?(:to_ary)).to eq true
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,22 @@
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
+ end
10
+ end
11
+
12
+ let(:item) { { name: 'Thomas' } }
13
+ let(:body) { [item] }
14
+
15
+ it 'converts itself to hash' do
16
+ stub_request(:get, "http://datastore/records")
17
+ .to_return(body: body.to_json)
18
+ record = Record.where.first
19
+ expect(record.to_h).to eq item
20
+ expect(record.to_hash).to eq item
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'to_json' do
7
+ let(:datastore) { 'http://local.ch/v2' }
8
+
9
+ before do
10
+ LHC.config.placeholder('datastore', datastore)
11
+ class Feedback < LHS::Record
12
+ endpoint '{+datastore}/feedbacks'
13
+ end
14
+ end
15
+
16
+ it 'converts to json' do
17
+ feedback = Feedback.new recommended: true
18
+ expect(feedback.as_json).to eq('recommended' => true)
19
+ expect(feedback.to_json).to eq("{\"recommended\":true}")
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+
7
+ context 'tracing' do
8
+ context 'with tracing enabled' do
9
+
10
+ before do
11
+ allow(LHS.config).to receive(:trace).and_return(true)
12
+ end
13
+
14
+ context 'with non-paginated methods' do
15
+
16
+ let(:request) do
17
+ stub_request(:get, "https://records/3jg781")
18
+ .to_return(status: 204)
19
+ end
20
+
21
+ before do
22
+ class Record < LHS::Record
23
+ endpoint 'https://records'
24
+ end
25
+
26
+ expect(LHC).to receive(:request).with(anything) do |arguments|
27
+ expect(arguments[:source]).to include(__FILE__)
28
+ spy(:response)
29
+ end
30
+ end
31
+
32
+ %w[find find_by find_by! first first! last!].each do |method|
33
+ context method do
34
+ it 'forwards tracing options to lhc' do
35
+ Record.public_send(method, color: :blue)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ context 'with paginated method last' do
42
+
43
+ before do
44
+ class Place < LHS::Record
45
+ endpoint 'http://datastore/places'
46
+ end
47
+
48
+ stub_request(:get, "http://datastore/places?limit=1")
49
+ .to_return(
50
+ body: {
51
+ items: [
52
+ { id: 'first-1', company_name: 'Localsearch AG' }
53
+ ],
54
+ total: 500,
55
+ limit: 1,
56
+ offset: 0
57
+ }.to_json
58
+ )
59
+
60
+ stub_request(:get, "http://datastore/places?limit=1&offset=499")
61
+ .to_return(
62
+ body: {
63
+ items: [
64
+ { id: 'last-500', company_name: 'Curious GmbH' }
65
+ ],
66
+ total: 500,
67
+ limit: 1,
68
+ offset: 0
69
+ }.to_json
70
+ )
71
+
72
+ expect(LHC).to receive(:request).and_call_original
73
+ expect(LHC).to receive(:request).with(hash_including(params: { offset: 499, limit: 1 })) do |arguments|
74
+ expect(arguments[:source]).to include(__FILE__)
75
+ spy(:response)
76
+ end
77
+ end
78
+
79
+ it 'forwards tracing options to lhc' do
80
+ Place.last
81
+ end
82
+ end
83
+ end
84
+
85
+ context 'tracing disabled (default)' do
86
+ context 'non-paginated methods' do
87
+
88
+ before do
89
+ class Record < LHS::Record
90
+ endpoint 'https://records'
91
+ end
92
+
93
+ expect(LHC).to receive(:request).with(anything) do |arguments|
94
+ expect(arguments).not_to include(:source)
95
+ spy(:response)
96
+ end
97
+ end
98
+
99
+ %w[find find_by find_by! first first! last!].each do |method|
100
+ context method do
101
+ it 'does not forward tracing options to lhc' do
102
+ Record.public_send(method, color: :blue)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ context 'with paginated method last' do
109
+ before do
110
+ class Place < LHS::Record
111
+ endpoint 'http://datastore/places'
112
+ end
113
+
114
+ stub_request(:get, "http://datastore/places?limit=1")
115
+ .to_return(
116
+ body: {
117
+ items: [
118
+ { id: 'first-1', company_name: 'Localsearch AG' }
119
+ ],
120
+ total: 500,
121
+ limit: 1,
122
+ offset: 0
123
+ }.to_json
124
+ )
125
+
126
+ stub_request(:get, "http://datastore/places?limit=1&offset=499")
127
+ .to_return(
128
+ body: {
129
+ items: [
130
+ { id: 'last-500', company_name: 'Curious GmbH' }
131
+ ],
132
+ total: 500,
133
+ limit: 1,
134
+ offset: 0
135
+ }.to_json
136
+ )
137
+ end
138
+
139
+ it 'does not forward tracing options to lhc' do
140
+ # for first pagination requets (first-1)
141
+ expect(LHC).to receive(:request).and_call_original
142
+
143
+ # for second reques (last-500)
144
+ expect(LHC).to receive(:request).with(hash_including(params: { offset: 499, limit: 1 })) do |arguments|
145
+ expect(arguments).not_to include(:source)
146
+ spy(:response)
147
+ end
148
+
149
+ Place.last
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end