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,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS::Problems
4
+ module Nested
5
+ class Errors < LHS::Problems::Errors
6
+ include LHS::Problems::Nested::Base
7
+
8
+ def initialize(errors, scope)
9
+ @raw = errors
10
+ @messages = nest(errors.messages, scope)
11
+ @message = errors.message
12
+ @scope = scope
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS::Problems
4
+ module Nested
5
+ class Warnings < LHS::Problems::Warnings
6
+ include LHS::Problems::Nested::Base
7
+
8
+ def initialize(warnings, scope)
9
+ @raw = warnings.raw
10
+ @messages = nest(warnings.messages, scope)
11
+ @scope = scope
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS::Problems
4
+ class Warnings < Base
5
+
6
+ def initialize(raw, record = nil)
7
+ @raw = raw
8
+ @record = record
9
+ @codes = {}.with_indifferent_access
10
+ @messages = warnings_from_raw
11
+ end
12
+
13
+ private
14
+
15
+ def warnings_from_raw
16
+ messages = {}
17
+ return messages if !raw.is_a?(Hash) || raw[:field_warnings].blank?
18
+ raw[:field_warnings].each do |field_warning|
19
+ add_error(messages, field_warning[:path].join('.').to_sym, field_warning[:code])
20
+ end
21
+ messages.with_indifferent_access
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Proxy makes different kind of data accessible
4
+ # If href is present it also alows loading/reloading
5
+ class LHS::Proxy
6
+ autoload :Accessors,
7
+ 'lhs/concerns/proxy/accessors'
8
+ autoload :Create,
9
+ 'lhs/concerns/proxy/create'
10
+ autoload :Problems,
11
+ 'lhs/concerns/proxy/problems'
12
+ autoload :Link,
13
+ 'lhs/concerns/proxy/link'
14
+
15
+ include Accessors
16
+ include Create
17
+ include Link
18
+ include Problems
19
+
20
+ # prevent clashing with attributes of underlying data
21
+ attr_accessor :_data, :_loaded
22
+ delegate :_record, :becomes, to: :_data, allow_nil: true
23
+
24
+ def initialize(data)
25
+ self._data = data
26
+ self._loaded = false
27
+ end
28
+
29
+ def record
30
+ _data.class
31
+ end
32
+
33
+ def load!(options = nil)
34
+ return self if _loaded
35
+ reload!(options)
36
+ end
37
+
38
+ def reload!(options = nil)
39
+ options = {} if options.blank?
40
+ data = _data.class.request(
41
+ options.merge(method: :get).merge(reload_options)
42
+ )
43
+ _data.merge_raw!(data.unwrap(:item_key))
44
+ self._loaded = true
45
+ return becomes(_record) if _record
46
+ self
47
+ end
48
+
49
+ private
50
+
51
+ def as_record
52
+ @as_record ||= becomes(_record)
53
+ end
54
+
55
+ def reload_options
56
+ return { url: _data.href } if _data.href
57
+ return { params: { id: as_record.id } } if as_record.id
58
+ {}
59
+ end
60
+
61
+ def merge_data_with_options(data, options)
62
+ if options && options[:params]
63
+ data.merge(options[:params])
64
+ else
65
+ data
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS
4
+ class Railtie < Rails::Railtie
5
+ initializer "lhs.hook_into_controller_initialization" do
6
+ class ActionController::Base
7
+
8
+ def initialize
9
+ prepare_lhs_request_cycle_cache
10
+ reset_option_blocks
11
+ reset_extended_rollbar_request_logs
12
+ super
13
+ end
14
+
15
+ private
16
+
17
+ def prepare_lhs_request_cycle_cache
18
+ return unless LHS.config.request_cycle_cache_enabled
19
+ LHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id = [Time.now.to_f, request.object_id].join('#')
20
+ end
21
+
22
+ def reset_option_blocks
23
+ LHS::OptionBlocks::CurrentOptionBlock.options = nil
24
+ end
25
+
26
+ def reset_extended_rollbar_request_logs
27
+ return unless defined?(::Rollbar)
28
+ return unless LHC.config.interceptors.include?(LHS::Interceptors::ExtendedRollbar::Interceptor)
29
+ LHS::Interceptors::ExtendedRollbar::ThreadRegistry.log = []
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHS::Record
4
+ autoload :AttributeAssignment,
5
+ 'lhs/concerns/record/attribute_assignment'
6
+ autoload :Batch,
7
+ 'lhs/concerns/record/batch'
8
+ autoload :Chainable,
9
+ 'lhs/concerns/record/chainable'
10
+ autoload :Configuration,
11
+ 'lhs/concerns/record/configuration'
12
+ autoload :Create,
13
+ 'lhs/concerns/record/create'
14
+ autoload :CustomSetters,
15
+ 'lhs/concerns/record/custom_setters'
16
+ autoload :Destroy,
17
+ 'lhs/concerns/record/destroy'
18
+ autoload :Endpoints,
19
+ 'lhs/concerns/record/endpoints'
20
+ autoload :Equality,
21
+ 'lhs/concerns/record/equality'
22
+ autoload :Find,
23
+ 'lhs/concerns/record/find'
24
+ autoload :FindBy,
25
+ 'lhs/concerns/record/find_by'
26
+ autoload :First,
27
+ 'lhs/concerns/record/first'
28
+ autoload :HrefFor,
29
+ 'lhs/concerns/record/href_for'
30
+ autoload :Last,
31
+ 'lhs/concerns/record/last'
32
+ autoload :Mapping,
33
+ 'lhs/concerns/record/mapping'
34
+ autoload :Merge,
35
+ 'lhs/concerns/record/merge'
36
+ autoload :Model,
37
+ 'lhs/concerns/record/model'
38
+ autoload :Pagination,
39
+ 'lhs/concerns/record/pagination'
40
+ autoload :Provider,
41
+ 'lhs/concerns/record/provider'
42
+ autoload :Request,
43
+ 'lhs/concerns/record/request'
44
+ autoload :Relations,
45
+ 'lhs/concerns/record/relations'
46
+ autoload :Scope,
47
+ 'lhs/concerns/record/scope'
48
+ autoload :Tracing,
49
+ 'lhs/concerns/record/tracing'
50
+ autoload :Update,
51
+ 'lhs/concerns/record/update'
52
+
53
+ include AttributeAssignment
54
+ include Batch
55
+ include Chainable
56
+ include Configuration
57
+ include Create
58
+ include CustomSetters
59
+ include Destroy
60
+ include Endpoints
61
+ include Equality
62
+ include Find
63
+ include FindBy
64
+ include First
65
+ include HrefFor
66
+ include LHS::IsHref
67
+ include Last
68
+ include LHS::Inspect
69
+ include Mapping
70
+ include Merge
71
+ include Model
72
+ include Pagination
73
+ include Provider
74
+ include Request
75
+ include Relations
76
+ include Scope
77
+ include Tracing
78
+ include Update
79
+
80
+ delegate :_proxy, :_endpoint, :merge_raw!, :select, :becomes, :respond_to?, to: :_data
81
+
82
+ def initialize(data = nil, apply_customer_setters = true)
83
+ data ||= LHS::Data.new({}, nil, self.class)
84
+ data = LHS::Data.new(data, nil, self.class) unless data.is_a?(LHS::Data)
85
+ define_singleton_method(:_data) { data }
86
+ apply_custom_setters! if apply_customer_setters
87
+ end
88
+
89
+ def as_json(options = nil)
90
+ _data.as_json(options)
91
+ end
92
+
93
+ def self.build(data = nil)
94
+ new(data)
95
+ end
96
+
97
+ # Override Object#dup because it doesn't support copying any singleton
98
+ # methods, which leads to missing `_data` method when you execute `dup`.
99
+ def dup
100
+ clone
101
+ end
102
+
103
+ protected
104
+
105
+ def method_missing(name, *args, &block)
106
+ _data.send(name, *args, &block)
107
+ end
108
+
109
+ def respond_to_missing?(name, include_all = false)
110
+ _data.respond_to_missing?(name, include_all)
111
+ end
112
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'lhs'
4
+ require 'lhs/test/stubbable_records'
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do
8
+ LHS.config.request_cycle_cache.clear
9
+ end
10
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'local_uri'
4
+ require 'webmock'
5
+
6
+ class LHS::Record
7
+ DEFAULT_LIMIT = LHS::Pagination::Base::DEFAULT_LIMIT
8
+
9
+ def self.stub_all(url, items, options = {})
10
+ extend WebMock::API
11
+
12
+ items.each_slice(DEFAULT_LIMIT).with_index do |(*batch), index|
13
+ uri = LocalUri::URI.new(url)
14
+ uri.query.merge!(
15
+ limit_key(:parameter) => DEFAULT_LIMIT
16
+ )
17
+ offset = pagination_class.page_to_offset(index + 1, DEFAULT_LIMIT)
18
+ unless index.zero?
19
+ uri.query.merge!(
20
+ pagination_key(:parameter) => offset
21
+ )
22
+ end
23
+ request_stub = stub_request(:get, uri.to_s)
24
+ request_stub.with(options) if options.present?
25
+ request_stub.to_return(
26
+ body: {
27
+ items: batch,
28
+ offset: index.zero? ? 0 : offset,
29
+ total: items.length
30
+ }.to_json
31
+ )
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS
4
+ class Unprocessable < StandardError
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LHS
4
+ VERSION = '24.0.0'
5
+ end
@@ -0,0 +1,18 @@
1
+ #!/bin/bash -e
2
+
3
+ # custom vars
4
+ # RUBY = ruby-1.9.3-p125
5
+ # GEMSET = location-app-${GitHub pull request id|branch name}
6
+ # standard vars
7
+
8
+ if [ -z "$SKIP_RVM" ]; then
9
+ [[ -s "/usr/local/rvm/scripts/rvm" ]] && . "/usr/local/rvm/scripts/rvm"
10
+ RUBY=${RUBY:-ruby-2.1.2}
11
+ GEMSET=${GEMSET:-LHS}
12
+ rvm use ${RUBY}@${GEMSET} --create
13
+ gem install bundler --no-rdoc --no-ri
14
+ fi
15
+
16
+ bundle install --local || bundle install
17
+ RAILS_ENV=test bundle exec rspec
18
+ rvm --force gemset delete ${RUBY}@${GEMSET}
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe 'Auto OAuth Authentication', type: :request, dummy_models: true do
6
+
7
+ context 'without LHC::Auth interceptor enabled' do
8
+
9
+ before do
10
+ LHS.configure do |config|
11
+ config.auto_oauth = -> { access_token }
12
+ end
13
+ end
14
+
15
+ it 'shows a warning that it can not perform auto authentication' do
16
+ expect(lambda do
17
+ get '/automatic_authentication/oauth'
18
+ end).to output(
19
+ %r{\[WARNING\] Can't enable auto oauth as LHC::Auth interceptor is not enabled\/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#authentication-interceptor\)!}
20
+ ).to_stderr
21
+ end
22
+ end
23
+
24
+ context 'with LHC::Auth interceptor enabled' do
25
+
26
+ context 'with only one auth provider' do
27
+
28
+ let(:token) { ApplicationController::ACCESS_TOKEN }
29
+
30
+ let(:record_request) do
31
+ stub_request(:get, "http://datastore/v2/records_with_oauth/1")
32
+ .with(
33
+ headers: { 'Authorization' => "Bearer #{token}" }
34
+ ).to_return(status: 200, body: { name: 'Record' }.to_json)
35
+ end
36
+
37
+ let(:records_request) do
38
+ stub_request(:get, "http://datastore/v2/records_with_oauth?color=blue")
39
+ .with(
40
+ headers: { 'Authorization' => "Bearer #{token}" }
41
+ ).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
42
+ end
43
+
44
+ before do
45
+ LHS.configure do |config|
46
+ config.auto_oauth = -> { access_token }
47
+ end
48
+ LHC.configure do |config|
49
+ config.interceptors = [LHC::Auth]
50
+ end
51
+ record_request
52
+ records_request
53
+ end
54
+
55
+ after do
56
+ LHC.config.reset
57
+ end
58
+
59
+ it 'applies OAuth credentials for the individual request automatically' do
60
+ get '/automatic_authentication/oauth'
61
+ expect(record_request).to have_been_requested
62
+ expect(records_request).to have_been_requested
63
+ end
64
+ end
65
+
66
+ context 'with multiple auth providers' do
67
+
68
+ before do
69
+ LHS.configure do |config|
70
+ config.auto_oauth = proc do
71
+ {
72
+ provider1: access_token_provider_1,
73
+ provider2: access_token_provider_2
74
+ }
75
+ end
76
+ end
77
+ LHC.configure do |config|
78
+ config.interceptors = [LHC::Auth]
79
+ end
80
+ record_request_provider_1
81
+ records_request_provider_2
82
+ records_request_per_endpoint_provider_1
83
+ record_request_per_endpoint_provider_2
84
+ end
85
+
86
+ let(:token) { ApplicationController::ACCESS_TOKEN }
87
+
88
+ let(:record_request_provider_1) do
89
+ stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_1/1")
90
+ .with(
91
+ headers: { 'Authorization' => "Bearer #{token}_provider_1" }
92
+ ).to_return(status: 200, body: { name: 'Record' }.to_json)
93
+ end
94
+
95
+ let(:records_request_provider_2) do
96
+ stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_2?color=blue")
97
+ .with(
98
+ headers: { 'Authorization' => "Bearer #{token}_provider_2" }
99
+ ).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
100
+ end
101
+
102
+ let(:records_request_per_endpoint_provider_1) do
103
+ stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_per_endpoint?color=blue")
104
+ .with(
105
+ headers: { 'Authorization' => "Bearer #{token}_provider_1" }
106
+ ).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
107
+ end
108
+
109
+ let(:record_request_per_endpoint_provider_2) do
110
+ stub_request(:get, "http://datastore/v2/records_with_multiple_oauth_providers_per_endpoint/1")
111
+ .with(
112
+ headers: { 'Authorization' => "Bearer #{token}_provider_2" }
113
+ ).to_return(status: 200, body: { name: 'Record' }.to_json)
114
+ end
115
+
116
+ after do
117
+ LHC.config.reset
118
+ end
119
+
120
+ it 'applies OAuth credentials for the individual request automatically no matter how many auth providers are configured ' do
121
+ get '/automatic_authentication/oauth_with_multiple_providers'
122
+ expect(record_request_provider_1).to have_been_requested
123
+ expect(records_request_provider_2).to have_been_requested
124
+ expect(records_request_per_endpoint_provider_1).to have_been_requested
125
+ expect(record_request_per_endpoint_provider_2).to have_been_requested
126
+ end
127
+ end
128
+
129
+ context 'with provider enabled for auto oauth' do
130
+
131
+ let(:token) { ApplicationController::ACCESS_TOKEN }
132
+
133
+ let(:record_request) do
134
+ stub_request(:get, "http://internalservice/v2/records/1")
135
+ .with(
136
+ headers: { 'Authorization' => "Bearer #{token}" }
137
+ ).to_return(status: 200, body: { name: 'Record' }.to_json)
138
+ end
139
+
140
+ let(:records_request) do
141
+ stub_request(:get, "http://internalservice/v2/records?color=blue")
142
+ .with(
143
+ headers: { 'Authorization' => "Bearer #{token}" }
144
+ ).to_return(status: 200, body: { items: [{ name: 'Record' }] }.to_json)
145
+ end
146
+
147
+ before do
148
+ LHS.configure do |config|
149
+ config.auto_oauth = -> { access_token }
150
+ end
151
+ LHC.configure do |config|
152
+ config.interceptors = [LHC::Auth]
153
+ end
154
+ record_request
155
+ records_request
156
+ end
157
+
158
+ after do
159
+ LHC.config.reset
160
+ end
161
+
162
+ it 'applies OAuth credentials for the individual request automatically' do
163
+ get '/automatic_authentication/oauth_with_provider'
164
+ expect(record_request).to have_been_requested
165
+ expect(records_request).to have_been_requested
166
+ end
167
+ end
168
+ end
169
+ end