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,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ before do
7
+ class LocalEntry < LHS::Record
8
+ endpoint '{+datastore}/local-entries'
9
+ end
10
+ end
11
+
12
+ context '#assign_attributes' do
13
+ it 'sets the attributes' do
14
+ entry = LocalEntry.new
15
+ entry.assign_attributes(company_name: 'localsearch')
16
+ expect(entry.company_name).to eq 'localsearch'
17
+ end
18
+ end
19
+
20
+ context 'when not a hash was passed' do
21
+ it 'raises an error' do
22
+ entry = LocalEntry.new
23
+ expect do
24
+ entry.assign_attributes([:company_name, 'localsearch'])
25
+ end.to raise_error(ArgumentError)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'build' 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}/content-ads/{campaign_id}/feedbacks'
13
+ endpoint '{+datastore}/feedbacks'
14
+ end
15
+ end
16
+
17
+ it 'builds a new item from scratch' do
18
+ feedback = Feedback.build recommended: true
19
+ expect(feedback).to be_kind_of Feedback
20
+ expect(feedback.recommended).to eq true
21
+ stub_request(:post, 'http://local.ch/v2/feedbacks')
22
+ .with(body: "{\"recommended\":true}")
23
+ feedback.save
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'cast nested data' do
7
+ let(:stub_customer_request) do
8
+ stub_request(:get, "https://datastore/customers?limit=1")
9
+ .to_return(
10
+ body: {
11
+ items: [
12
+ {
13
+ href: "https://datastore/customers/12",
14
+ address: {
15
+ href: "https://datastore/addresses/3"
16
+ },
17
+ contracts: [
18
+ {
19
+ href: "https://datastore/contracts/2"
20
+ }
21
+ ]
22
+ }
23
+ ]
24
+ }.to_json
25
+ )
26
+ end
27
+
28
+ before do
29
+ class Customer < LHS::Record
30
+ endpoint 'https://datastore/customers'
31
+ endpoint 'https://datastore/customers/{id}'
32
+ end
33
+ class Contract < LHS::Record
34
+ endpoint 'https://datastore/contracts'
35
+ endpoint 'https://datastore/contracts/{id}'
36
+ end
37
+ class Address < LHS::Record
38
+ endpoint 'https://datastore/addresses'
39
+ endpoint 'https://datastore/addresses/{id}', headers: { 'Authorization' => 'Bearer 123' }
40
+ end
41
+ stub_customer_request
42
+ end
43
+
44
+ it 'casts nested data properly' do
45
+ customer = Customer.first
46
+ expect(customer).to be_kind_of Customer
47
+ expect(customer.address).to be_kind_of Address
48
+ expect(customer.contracts.first).to be_kind_of Contract
49
+ end
50
+
51
+ context 'interact with nested resouce remotely' do
52
+ let(:address_request_stub) do
53
+ stub_request(:post, "https://datastore/addresses/3")
54
+ .with(
55
+ body: {
56
+ href: 'https://datastore/addresses/3',
57
+ zip: 8050
58
+ }.to_json,
59
+ headers: {
60
+ 'Authorization': 'Bearer 123'
61
+ }
62
+ )
63
+ .to_return(status: 201)
64
+ end
65
+
66
+ before do
67
+ address_request_stub
68
+ end
69
+
70
+ it 'applies casted records endpoint options to requests made to the nested resource' do
71
+ customer = Customer.first
72
+ address = customer.address
73
+ address.zip = 8050
74
+ address.save
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'create' 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}/content-ads/{campaign_id}/feedbacks'
13
+ endpoint '{+datastore}/feedbacks'
14
+ end
15
+ end
16
+
17
+ let(:object) do
18
+ {
19
+ recommended: true,
20
+ source_id: 'aaa'
21
+ }
22
+ end
23
+
24
+ it 'creates new record on the backend' do
25
+ stub_request(:post, "#{datastore}/feedbacks")
26
+ .with(body: object.to_json)
27
+ .to_return(status: 200, body: object.to_json)
28
+ record = Feedback.create(object)
29
+ expect(record).to be_kind_of Feedback
30
+ expect(record.recommended).to eq true
31
+ expect(record.errors.messages).to eq({})
32
+ expect(record.errors.message).to eq nil
33
+ end
34
+
35
+ it 'uses proper endpoint when creating data' do
36
+ stub_request(:post, "#{datastore}/content-ads/12345/feedbacks")
37
+ .with(body: object.to_json)
38
+ .to_return(status: 200, body: object.to_json)
39
+ Feedback.create(object.merge(campaign_id: '12345'))
40
+ end
41
+
42
+ it 'merges backend response object with object' do
43
+ body = object.merge(additional_key: 1)
44
+ stub_request(:post, "#{datastore}/content-ads/12345/feedbacks")
45
+ .with(body: object.to_json)
46
+ .to_return(status: 200, body: body.to_json)
47
+ data = Feedback.create(object.merge(campaign_id: '12345'))
48
+ expect(data.additional_key).to eq 1
49
+ end
50
+
51
+ context 'creation errors' do
52
+ let(:creation_error) do
53
+ {
54
+ "status" => 400,
55
+ "fields" => [
56
+ {
57
+ "name" => "ratings",
58
+ "details" => [{ "code" => "REQUIRED_PROPERTY_VALUE" }]
59
+ }, {
60
+ "name" => "recommended",
61
+ "details" => [{ "code" => "REQUIRED_PROPERTY_VALUE" }]
62
+ }
63
+ ]
64
+ }
65
+ end
66
+
67
+ it 'provides errors accessor on the record when creation failed using create' do
68
+ stub_request(:post, "#{datastore}/content-ads/12345/feedbacks")
69
+ .to_return(status: 400, body: creation_error.to_json)
70
+ feedback = Feedback.create(object.merge(campaign_id: '12345'))
71
+ expect(feedback.errors).to be_kind_of LHS::Problems::Errors
72
+ end
73
+
74
+ it 'raises an exception when creation failed using create!' do
75
+ stub_request(:post, "#{datastore}/content-ads/12345/feedbacks")
76
+ .to_return(status: 400, body: creation_error.to_json)
77
+ expect(lambda {
78
+ Feedback.create!(object.merge(campaign_id: '12345'))
79
+ }).to raise_error(LHC::Error)
80
+ end
81
+ end
82
+
83
+ context 'custom setters' do
84
+ before do
85
+ class Feedback
86
+ def ratings=(ratings)
87
+ _raw[:ratings] = ratings.map { |k, v| { name: k.to_s, value: v } }
88
+ end
89
+ end
90
+
91
+ stub_request(:post, "#{datastore}/feedbacks")
92
+ .with(body: { ratings: converted_ratings }.to_json)
93
+ .to_return(status: 200, body: { ratings: converted_ratings }.to_json)
94
+ end
95
+
96
+ let(:ratings) do
97
+ {
98
+ a: 1,
99
+ b: 2
100
+ }
101
+ end
102
+
103
+ let(:converted_ratings) do
104
+ [
105
+ { name: 'a', value: 1 },
106
+ { name: 'b', value: 2 }
107
+ ]
108
+ end
109
+
110
+ it 'are used by create' do
111
+ feedback = Feedback.create(ratings: ratings)
112
+ expect(feedback.ratings._raw).to eq(converted_ratings)
113
+ end
114
+
115
+ it 'can be used directly to change raw data' do
116
+ feedback = Feedback.create(ratings: ratings)
117
+ feedback.ratings = { z: 3 }
118
+ expect(feedback.ratings.first.name).to eq 'z'
119
+ end
120
+
121
+ context 'and custom getters' do
122
+ before do
123
+ class Feedback
124
+ def ratings
125
+ Hash[_raw[:ratings].map { |r| [r[:name].to_sym, r[:value]] }]
126
+ end
127
+ end
128
+ end
129
+
130
+ it 'uses custom getters to show data for exploration' do
131
+ feedback = Feedback.create(ratings: ratings)
132
+ expect(feedback.ratings).to eq(ratings)
133
+ end
134
+ end
135
+ end
136
+
137
+ context 'location header' do
138
+ before do
139
+ class ContactPerson < LHS::Record
140
+ endpoint 'http://datastore/contact_persons'
141
+ end
142
+ end
143
+
144
+ let(:location) { 'http://datastore/contact_persons/1' }
145
+ let(:created_at) { '2017-12-21' }
146
+ let(:name) { 'Sebastian' }
147
+
148
+ it 'Loads the data from the "Location" header after creation' do
149
+ stub_request(:post, "http://datastore/contact_persons")
150
+ .to_return(status: 204, headers: { Location: location })
151
+ stub_request(:get, "http://datastore/contact_persons/1")
152
+ .to_return(body: { href: location, name: name, created_at: created_at }.to_json)
153
+ contact_person = ContactPerson.create!(name: name)
154
+ expect(contact_person.href).to eq location
155
+ expect(contact_person.created_at).to eq Date.parse(created_at)
156
+ expect(contact_person.name).to eq name
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'creation failed' do
7
+ let(:datastore) { 'http://local.ch/v2' }
8
+
9
+ before do
10
+ LHC.config.placeholder(:datastore, datastore)
11
+ class Record < LHS::Record
12
+ endpoint '{+datastore}/{campaign_id}/feedbacks'
13
+ endpoint '{+datastore}/feedbacks'
14
+ end
15
+ end
16
+
17
+ let(:error_message) { "ratings must be set when review or name or review_title is set | The property value is required; it cannot be null, empty, or blank." }
18
+
19
+ let(:creation_error) do
20
+ {
21
+ "status" => 400,
22
+ "message" => error_message,
23
+ "fields" => [
24
+ {
25
+ "name" => "ratings",
26
+ "details" => [{ "code" => "REQUIRED_PROPERTY_VALUE" }]
27
+ }, {
28
+ "name" => "recommended",
29
+ "details" => [{ "code" => "REQUIRED_PROPERTY_VALUE" }]
30
+ }
31
+ ]
32
+ }
33
+ end
34
+
35
+ it 'provides errors when creation failed' do
36
+ stub_request(:post, "#{datastore}/feedbacks")
37
+ .to_return(status: 400, body: creation_error.to_json)
38
+ record = Record.create(name: 'Steve')
39
+ expect(record).to be_kind_of Record
40
+ expect(record.errors).to be_present
41
+ expect(record.name).to eq 'Steve'
42
+ expect(record.errors.include?(:ratings)).to eq true
43
+ expect(record.errors.include?(:recommended)).to eq true
44
+ expect(record.errors[:ratings]).to eq ['REQUIRED_PROPERTY_VALUE']
45
+ expect(record.errors.messages).to eq('ratings' => ["REQUIRED_PROPERTY_VALUE"], 'recommended' => ["REQUIRED_PROPERTY_VALUE"])
46
+ expect(record.errors.message).to eq error_message
47
+ end
48
+
49
+ it 'doesnt fail when no fields are provided by the backend' do
50
+ stub_request(:post, "#{datastore}/feedbacks")
51
+ .to_return(status: 400, body: {}.to_json)
52
+ Record.create(name: 'Steve')
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'custom setters' do
7
+
8
+ context 'assigning values directly to other attributes' do
9
+
10
+ before do
11
+ Object.send(:remove_const, :Booking) # make sure there is no other booking from previous tests around
12
+ class Booking < LHS::Record
13
+ endpoint 'https://bookings'
14
+
15
+ def appointment_attributes=(params)
16
+ self.appointments = params.map { |item| item[:id] }
17
+ end
18
+ end
19
+ end
20
+
21
+ it 'allows to change raw in custom setters' do
22
+ booking = Booking.new(appointment_attributes: [{ id: 1 }])
23
+ expect(booking.appointments.to_a).to eq [1]
24
+ end
25
+ end
26
+
27
+ context 'assign values directly by using square brackets' do
28
+
29
+ before do
30
+ class Booking < LHS::Record
31
+ endpoint 'https://bookings'
32
+
33
+ def appointment_attributes=(params)
34
+ self[:appointments] = params.map { |item| item[:id] }
35
+ end
36
+ end
37
+ end
38
+
39
+ it 'allows to change raw in custom setters' do
40
+ booking = Booking.new(appointment_attributes: [{ id: 1 }])
41
+ expect(booking.appointments.to_a).to eq [1]
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'definitions' do
7
+ let(:datastore) { 'http://local.ch/v2' }
8
+
9
+ before do
10
+ LHC.config.placeholder('datastore', datastore)
11
+ class LocalEntry < LHS::Record
12
+ endpoint '{+datastore}/local-entries'
13
+ endpoint '{+datastore}/local-entries/{id}'
14
+ end
15
+ end
16
+
17
+ it 'allows mappings in all functions/defitions' do
18
+ class LocalEntry < LHS::Record
19
+ def name
20
+ addresses.first.business.identities.first.name
21
+ end
22
+ end
23
+ stub_request(:get, "#{datastore}/local-entries/1")
24
+ .to_return(status: 200, body: { addresses: [{ business: { identities: [{ name: 'Löwenzorn' }] } }] }.to_json)
25
+ entry = LocalEntry.find(1)
26
+ expect(entry.name).to eq 'Löwenzorn'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'destroy' do
7
+ before do
8
+ class Record < LHS::Record
9
+ endpoint 'http://datastore/history'
10
+ endpoint 'http://datastore/history/{id}'
11
+ end
12
+ end
13
+
14
+ let(:entry) { { what: 'Cafe', where: 'Zurich' } }
15
+
16
+ it 'allows to destroy by parameters directly' do
17
+ stub_request(:delete, "http://datastore/history?what=Cafe&where=Zurich")
18
+ .to_return(body: [entry].to_json)
19
+ deleted_entries = Record.destroy(what: 'Cafe', where: 'Zurich')
20
+ expect(deleted_entries.first.to_h).to eq entry
21
+ end
22
+
23
+ it 'allows to destroy by id' do
24
+ stub_request(:delete, "http://datastore/history/1")
25
+ .to_return(body: entry.to_json)
26
+ deleted_entry = Record.destroy(1)
27
+ expect(deleted_entry.to_h).to eq entry
28
+ end
29
+
30
+ it 'chains' do
31
+ stub_request(:delete, "http://datastore/history/1")
32
+ .with(headers: { 'Authorization' => 'Bearer 123' })
33
+ .to_return(body: entry.to_json)
34
+ deleted_entry = Record.options(headers: { 'Authorization' => 'Bearer 123' }).destroy(1)
35
+ expect(deleted_entry.to_h).to eq entry
36
+ end
37
+ end
38
+ end