dhs 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (301) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/rubocop.yml +27 -0
  3. data/.github/workflows/test.yml +27 -0
  4. data/.gitignore +39 -0
  5. data/.rubocop.yml +186 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE +674 -0
  9. data/README.md +2807 -0
  10. data/Rakefile +26 -0
  11. data/dhs.gemspec +44 -0
  12. data/docs/accessing-data.png +0 -0
  13. data/lib/dhs.rb +67 -0
  14. data/lib/dhs/collection.rb +84 -0
  15. data/lib/dhs/complex.rb +158 -0
  16. data/lib/dhs/concerns/autoload_records.rb +57 -0
  17. data/lib/dhs/concerns/collection/handle_nested.rb +43 -0
  18. data/lib/dhs/concerns/collection/internal_collection.rb +74 -0
  19. data/lib/dhs/concerns/configuration.rb +20 -0
  20. data/lib/dhs/concerns/data/becomes.rb +18 -0
  21. data/lib/dhs/concerns/data/equality.rb +14 -0
  22. data/lib/dhs/concerns/data/extend.rb +87 -0
  23. data/lib/dhs/concerns/data/json.rb +14 -0
  24. data/lib/dhs/concerns/data/to_hash.rb +14 -0
  25. data/lib/dhs/concerns/inspect.rb +70 -0
  26. data/lib/dhs/concerns/is_href.rb +15 -0
  27. data/lib/dhs/concerns/item/destroy.rb +38 -0
  28. data/lib/dhs/concerns/item/endpoint_lookup.rb +27 -0
  29. data/lib/dhs/concerns/item/save.rb +55 -0
  30. data/lib/dhs/concerns/item/update.rb +50 -0
  31. data/lib/dhs/concerns/item/validation.rb +61 -0
  32. data/lib/dhs/concerns/o_auth.rb +25 -0
  33. data/lib/dhs/concerns/option_blocks.rb +26 -0
  34. data/lib/dhs/concerns/proxy/accessors.rb +132 -0
  35. data/lib/dhs/concerns/proxy/create.rb +45 -0
  36. data/lib/dhs/concerns/proxy/link.rb +25 -0
  37. data/lib/dhs/concerns/proxy/problems.rb +27 -0
  38. data/lib/dhs/concerns/record/attribute_assignment.rb +25 -0
  39. data/lib/dhs/concerns/record/batch.rb +40 -0
  40. data/lib/dhs/concerns/record/chainable.rb +465 -0
  41. data/lib/dhs/concerns/record/configuration.rb +103 -0
  42. data/lib/dhs/concerns/record/create.rb +24 -0
  43. data/lib/dhs/concerns/record/custom_setters.rb +22 -0
  44. data/lib/dhs/concerns/record/destroy.rb +18 -0
  45. data/lib/dhs/concerns/record/endpoints.rb +108 -0
  46. data/lib/dhs/concerns/record/equality.rb +14 -0
  47. data/lib/dhs/concerns/record/find.rb +86 -0
  48. data/lib/dhs/concerns/record/find_by.rb +38 -0
  49. data/lib/dhs/concerns/record/first.rb +20 -0
  50. data/lib/dhs/concerns/record/href_for.rb +19 -0
  51. data/lib/dhs/concerns/record/last.rb +27 -0
  52. data/lib/dhs/concerns/record/mapping.rb +25 -0
  53. data/lib/dhs/concerns/record/merge.rb +26 -0
  54. data/lib/dhs/concerns/record/model.rb +23 -0
  55. data/lib/dhs/concerns/record/pagination.rb +49 -0
  56. data/lib/dhs/concerns/record/provider.rb +23 -0
  57. data/lib/dhs/concerns/record/relations.rb +26 -0
  58. data/lib/dhs/concerns/record/request.rb +581 -0
  59. data/lib/dhs/concerns/record/scope.rb +25 -0
  60. data/lib/dhs/concerns/record/tracing.rb +24 -0
  61. data/lib/dhs/concerns/record/update.rb +17 -0
  62. data/lib/dhs/config.rb +24 -0
  63. data/lib/dhs/data.rb +180 -0
  64. data/lib/dhs/endpoint.rb +12 -0
  65. data/lib/dhs/interceptors/auto_oauth/interceptor.rb +33 -0
  66. data/lib/dhs/interceptors/auto_oauth/thread_registry.rb +18 -0
  67. data/lib/dhs/interceptors/extended_rollbar/handler.rb +40 -0
  68. data/lib/dhs/interceptors/extended_rollbar/interceptor.rb +20 -0
  69. data/lib/dhs/interceptors/extended_rollbar/thread_registry.rb +19 -0
  70. data/lib/dhs/interceptors/request_cycle_cache/interceptor.rb +41 -0
  71. data/lib/dhs/interceptors/request_cycle_cache/thread_registry.rb +18 -0
  72. data/lib/dhs/item.rb +59 -0
  73. data/lib/dhs/pagination/base.rb +90 -0
  74. data/lib/dhs/pagination/link.rb +21 -0
  75. data/lib/dhs/pagination/offset.rb +22 -0
  76. data/lib/dhs/pagination/page.rb +18 -0
  77. data/lib/dhs/pagination/start.rb +22 -0
  78. data/lib/dhs/pagination/total_pages.rb +9 -0
  79. data/lib/dhs/problems/base.rb +113 -0
  80. data/lib/dhs/problems/errors.rb +69 -0
  81. data/lib/dhs/problems/nested/base.rb +54 -0
  82. data/lib/dhs/problems/nested/errors.rb +16 -0
  83. data/lib/dhs/problems/nested/warnings.rb +15 -0
  84. data/lib/dhs/problems/warnings.rb +24 -0
  85. data/lib/dhs/proxy.rb +69 -0
  86. data/lib/dhs/railtie.rb +34 -0
  87. data/lib/dhs/record.rb +112 -0
  88. data/lib/dhs/rspec.rb +10 -0
  89. data/lib/dhs/test/stubbable_records.rb +34 -0
  90. data/lib/dhs/unprocessable.rb +6 -0
  91. data/lib/dhs/version.rb +5 -0
  92. data/script/ci/build.sh +18 -0
  93. data/spec/auto_oauth_spec.rb +163 -0
  94. data/spec/autoloading_spec.rb +45 -0
  95. data/spec/collection/accessors_spec.rb +31 -0
  96. data/spec/collection/collection_items_spec.rb +44 -0
  97. data/spec/collection/configurable_spec.rb +43 -0
  98. data/spec/collection/delegate_spec.rb +21 -0
  99. data/spec/collection/enumerable_spec.rb +27 -0
  100. data/spec/collection/href_spec.rb +17 -0
  101. data/spec/collection/meta_data_spec.rb +58 -0
  102. data/spec/collection/respond_to_spec.rb +20 -0
  103. data/spec/collection/to_a_spec.rb +34 -0
  104. data/spec/collection/to_ary_spec.rb +40 -0
  105. data/spec/collection/without_object_items_spec.rb +27 -0
  106. data/spec/complex/reduce_spec.rb +202 -0
  107. data/spec/concerns/record/request_spec.rb +78 -0
  108. data/spec/data/collection_spec.rb +56 -0
  109. data/spec/data/equality_spec.rb +23 -0
  110. data/spec/data/inspect_spec.rb +88 -0
  111. data/spec/data/is_item_or_collection_spec.rb +40 -0
  112. data/spec/data/item_spec.rb +106 -0
  113. data/spec/data/merge_spec.rb +27 -0
  114. data/spec/data/parent_spec.rb +39 -0
  115. data/spec/data/raw_spec.rb +48 -0
  116. data/spec/data/respond_to_spec.rb +26 -0
  117. data/spec/data/root_spec.rb +25 -0
  118. data/spec/data/select_spec.rb +27 -0
  119. data/spec/data/to_ary_spec.rb +28 -0
  120. data/spec/data/to_json_spec.rb +68 -0
  121. data/spec/dummy/Rakefile +8 -0
  122. data/spec/dummy/app/assets/images/.keep +0 -0
  123. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  124. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  125. data/spec/dummy/app/controllers/application_controller.rb +26 -0
  126. data/spec/dummy/app/controllers/automatic_authentication_controller.rb +29 -0
  127. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  128. data/spec/dummy/app/controllers/error_handling_with_chains_controller.rb +36 -0
  129. data/spec/dummy/app/controllers/extended_rollbar_controller.rb +10 -0
  130. data/spec/dummy/app/controllers/option_blocks_controller.rb +15 -0
  131. data/spec/dummy/app/controllers/request_cycle_cache_controller.rb +27 -0
  132. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  133. data/spec/dummy/app/mailers/.keep +0 -0
  134. data/spec/dummy/app/models/.keep +0 -0
  135. data/spec/dummy/app/models/concerns/.keep +0 -0
  136. data/spec/dummy/app/models/concerns/dummy_customer/some_concern.rb +9 -0
  137. data/spec/dummy/app/models/dummy_customer.rb +7 -0
  138. data/spec/dummy/app/models/dummy_record.rb +6 -0
  139. data/spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb +6 -0
  140. data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb +7 -0
  141. data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb +7 -0
  142. data/spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb +6 -0
  143. data/spec/dummy/app/models/dummy_record_with_oauth.rb +7 -0
  144. data/spec/dummy/app/models/dummy_user.rb +6 -0
  145. data/spec/dummy/app/models/providers/customer_system.rb +7 -0
  146. data/spec/dummy/app/models/providers/internal_services.rb +7 -0
  147. data/spec/dummy/app/views/error_handling_with_chains/error.html.erb +1 -0
  148. data/spec/dummy/app/views/error_handling_with_chains/show.html.erb +3 -0
  149. data/spec/dummy/app/views/form_for.html.erb +5 -0
  150. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  151. data/spec/dummy/bin/bundle +5 -0
  152. data/spec/dummy/bin/rails +6 -0
  153. data/spec/dummy/bin/rake +6 -0
  154. data/spec/dummy/config.ru +6 -0
  155. data/spec/dummy/config/application.rb +16 -0
  156. data/spec/dummy/config/boot.rb +7 -0
  157. data/spec/dummy/config/environment.rb +7 -0
  158. data/spec/dummy/config/environments/development.rb +36 -0
  159. data/spec/dummy/config/environments/production.rb +77 -0
  160. data/spec/dummy/config/environments/test.rb +40 -0
  161. data/spec/dummy/config/initializers/assets.rb +10 -0
  162. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  163. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  164. data/spec/dummy/config/initializers/dhs.rb +5 -0
  165. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  166. data/spec/dummy/config/initializers/inflections.rb +18 -0
  167. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  168. data/spec/dummy/config/initializers/rollbar.rb +9 -0
  169. data/spec/dummy/config/initializers/session_store.rb +5 -0
  170. data/spec/dummy/config/initializers/wrap_parameters.rb +11 -0
  171. data/spec/dummy/config/locales/en.yml +23 -0
  172. data/spec/dummy/config/routes.rb +27 -0
  173. data/spec/dummy/config/secrets.yml +22 -0
  174. data/spec/dummy/lib/assets/.keep +0 -0
  175. data/spec/dummy/public/404.html +67 -0
  176. data/spec/dummy/public/422.html +67 -0
  177. data/spec/dummy/public/500.html +66 -0
  178. data/spec/dummy/public/favicon.ico +0 -0
  179. data/spec/endpoint/for_url_spec.rb +27 -0
  180. data/spec/extended_rollbar_spec.rb +67 -0
  181. data/spec/item/access_errors_spec.rb +31 -0
  182. data/spec/item/accessors_spec.rb +21 -0
  183. data/spec/item/add_error_spec.rb +21 -0
  184. data/spec/item/becomes_spec.rb +38 -0
  185. data/spec/item/blacklisted_keywords_spec.rb +28 -0
  186. data/spec/item/delegate_spec.rb +32 -0
  187. data/spec/item/destroy_spec.rb +113 -0
  188. data/spec/item/dig_spec.rb +29 -0
  189. data/spec/item/error_codes_spec.rb +55 -0
  190. data/spec/item/errors_spec.rb +324 -0
  191. data/spec/item/fetch_spec.rb +39 -0
  192. data/spec/item/getter_spec.rb +24 -0
  193. data/spec/item/internal_data_structure_spec.rb +37 -0
  194. data/spec/item/map_spec.rb +46 -0
  195. data/spec/item/nested_errors_spec.rb +27 -0
  196. data/spec/item/partial_update_spec.rb +168 -0
  197. data/spec/item/respond_to_spec.rb +31 -0
  198. data/spec/item/save_spec.rb +115 -0
  199. data/spec/item/setter_spec.rb +44 -0
  200. data/spec/item/translate_errors_spec.rb +257 -0
  201. data/spec/item/update_spec.rb +161 -0
  202. data/spec/item/validation_spec.rb +131 -0
  203. data/spec/item/warning_codes_spec.rb +55 -0
  204. data/spec/item/warnings_spec.rb +51 -0
  205. data/spec/option_blocks/ensure_reset_between_requests_spec.rb +23 -0
  206. data/spec/option_blocks/main_spec.rb +54 -0
  207. data/spec/pagination/link/current_page_spec.rb +19 -0
  208. data/spec/pagination/link/pages_left_spec.rb +36 -0
  209. data/spec/pagination/link/parallel_spec.rb +19 -0
  210. data/spec/pagination/link/total_spec.rb +45 -0
  211. data/spec/pagination/offset/pages_left_spec.rb +26 -0
  212. data/spec/pagination/parameters_spec.rb +59 -0
  213. data/spec/pagination/total_pages_spec.rb +51 -0
  214. data/spec/proxy/create_sub_resource_spec.rb +182 -0
  215. data/spec/proxy/load_spec.rb +75 -0
  216. data/spec/proxy/record_identification_spec.rb +35 -0
  217. data/spec/rails_helper.rb +13 -0
  218. data/spec/record/all_spec.rb +133 -0
  219. data/spec/record/attribute_assignment_spec.rb +28 -0
  220. data/spec/record/build_spec.rb +26 -0
  221. data/spec/record/cast_nested_data_spec.rb +80 -0
  222. data/spec/record/compact_spec.rb +93 -0
  223. data/spec/record/create_spec.rb +160 -0
  224. data/spec/record/creation_failed_spec.rb +55 -0
  225. data/spec/record/custom_setters_spec.rb +42 -0
  226. data/spec/record/definitions_spec.rb +29 -0
  227. data/spec/record/destroy_spec.rb +38 -0
  228. data/spec/record/dig_configuration_spec.rb +75 -0
  229. data/spec/record/dup_spec.rb +20 -0
  230. data/spec/record/endpoint_inheritance_spec.rb +65 -0
  231. data/spec/record/endpoint_options_spec.rb +51 -0
  232. data/spec/record/endpoint_priorities_spec.rb +24 -0
  233. data/spec/record/endpoints_spec.rb +96 -0
  234. data/spec/record/equality_spec.rb +27 -0
  235. data/spec/record/error_handling_integration_spec.rb +25 -0
  236. data/spec/record/error_handling_spec.rb +40 -0
  237. data/spec/record/expanded_spec.rb +69 -0
  238. data/spec/record/fetch_spec.rb +40 -0
  239. data/spec/record/find_by_chains_spec.rb +21 -0
  240. data/spec/record/find_by_spec.rb +76 -0
  241. data/spec/record/find_each_spec.rb +57 -0
  242. data/spec/record/find_in_batches_spec.rb +122 -0
  243. data/spec/record/find_in_parallel_spec.rb +67 -0
  244. data/spec/record/find_spec.rb +103 -0
  245. data/spec/record/first_spec.rb +39 -0
  246. data/spec/record/force_merge_spec.rb +55 -0
  247. data/spec/record/handle_includes_errors_spec.rb +33 -0
  248. data/spec/record/has_many_spec.rb +118 -0
  249. data/spec/record/has_one_spec.rb +114 -0
  250. data/spec/record/href_for_spec.rb +24 -0
  251. data/spec/record/ignore_errors_spec.rb +137 -0
  252. data/spec/record/immutable_chains_spec.rb +22 -0
  253. data/spec/record/includes_after_expansion_spec.rb +70 -0
  254. data/spec/record/includes_expanded_spec.rb +37 -0
  255. data/spec/record/includes_first_page_spec.rb +738 -0
  256. data/spec/record/includes_missing_spec.rb +57 -0
  257. data/spec/record/includes_spec.rb +690 -0
  258. data/spec/record/includes_warning_spec.rb +46 -0
  259. data/spec/record/item_key_spec.rb +81 -0
  260. data/spec/record/items_created_key_configuration_spec.rb +37 -0
  261. data/spec/record/last_spec.rb +64 -0
  262. data/spec/record/loading_twice_spec.rb +19 -0
  263. data/spec/record/mapping_spec.rb +103 -0
  264. data/spec/record/model_name_spec.rb +17 -0
  265. data/spec/record/new_spec.rb +106 -0
  266. data/spec/record/options_getter_spec.rb +25 -0
  267. data/spec/record/options_spec.rb +164 -0
  268. data/spec/record/paginatable_collection_spec.rb +360 -0
  269. data/spec/record/pagination_chain_spec.rb +101 -0
  270. data/spec/record/pagination_links_spec.rb +72 -0
  271. data/spec/record/pagination_spec.rb +71 -0
  272. data/spec/record/persisted_spec.rb +52 -0
  273. data/spec/record/provider_spec.rb +40 -0
  274. data/spec/record/references_spec.rb +95 -0
  275. data/spec/record/relation_caching_spec.rb +120 -0
  276. data/spec/record/reload_by_id_spec.rb +43 -0
  277. data/spec/record/reload_spec.rb +64 -0
  278. data/spec/record/request_spec.rb +90 -0
  279. data/spec/record/save_spec.rb +40 -0
  280. data/spec/record/scope_chains_spec.rb +39 -0
  281. data/spec/record/select_spec.rb +17 -0
  282. data/spec/record/to_ary_spec.rb +65 -0
  283. data/spec/record/to_hash_spec.rb +22 -0
  284. data/spec/record/to_json_spec.rb +22 -0
  285. data/spec/record/tracing_spec.rb +149 -0
  286. data/spec/record/update_spec.rb +61 -0
  287. data/spec/record/where_chains_spec.rb +57 -0
  288. data/spec/record/where_spec.rb +62 -0
  289. data/spec/record/where_values_hash_spec.rb +32 -0
  290. data/spec/request_cycle_cache_spec.rb +106 -0
  291. data/spec/require_dhs_spec.rb +9 -0
  292. data/spec/spec_helper.rb +6 -0
  293. data/spec/stubs/all_spec.rb +69 -0
  294. data/spec/support/fixtures/json/feedback.json +11 -0
  295. data/spec/support/fixtures/json/feedbacks.json +174 -0
  296. data/spec/support/fixtures/json/localina_content_ad.json +23 -0
  297. data/spec/support/load_json.rb +5 -0
  298. data/spec/support/request_cycle_cache.rb +10 -0
  299. data/spec/support/reset.rb +67 -0
  300. data/spec/views/form_for_spec.rb +20 -0
  301. metadata +783 -0
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Record do
6
+ context 'update' do
7
+ before do
8
+ class Record < DHS::Record
9
+ endpoint 'http://datastore/records/{id}'
10
+ end
11
+ end
12
+
13
+ it 'allows to directly update a record without fetching it first' do
14
+ stub_request(:post, 'http://datastore/records/123')
15
+ .with(body: { name: 'Steve' }.to_json)
16
+ .to_return(status: 200, body: {}.to_json)
17
+
18
+ Record.update(
19
+ id: '123',
20
+ name: 'Steve'
21
+ )
22
+ end
23
+
24
+ it 'does not fail during an error with update' do
25
+ stub_request(:post, 'http://datastore/records/123')
26
+ .with(body: { name: 'Steve' }.to_json)
27
+ .to_return(status: 404, body: {}.to_json)
28
+
29
+ record = Record.update(
30
+ id: '123',
31
+ name: 'Steve'
32
+ )
33
+
34
+ expect(record.errors.status_code).to eq 404
35
+ end
36
+
37
+ it 'allows to directly update! a record without fetching it first' do
38
+ stub_request(:post, 'http://datastore/records/123')
39
+ .with(body: { name: 'Steve' }.to_json)
40
+ .to_return(status: 200)
41
+
42
+ Record.update!(
43
+ id: '123',
44
+ name: 'Steve'
45
+ )
46
+ end
47
+
48
+ it 'raises an error when trying to update! but retrieving an error status' do
49
+ stub_request(:post, 'http://datastore/records/123')
50
+ .with(body: { name: 'Steve' }.to_json)
51
+ .to_return(status: 404)
52
+
53
+ expect(-> {
54
+ Record.update!(
55
+ id: '123',
56
+ name: 'Steve'
57
+ )
58
+ }).to raise_error(DHC::NotFound)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::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
+ DHC.config.placeholder('datastore', datastore)
16
+ class Record < DHS::Record
17
+ endpoint '{+datastore}/records/'
18
+
19
+ def uppercase_name
20
+ name.upcase
21
+ end
22
+ end
23
+ end
24
+
25
+ context 'where chains' do
26
+ before do
27
+ stub_request(:get, 'http://datastore/v2/records/?available=true&color=blue&range=%3E26')
28
+ .to_return(response)
29
+ end
30
+
31
+ let(:records) { Record.where(color: 'blue').where(range: '>26').where(available: true) }
32
+
33
+ it 'allows chaining where statements' do
34
+ expect(records.class).to eq Record
35
+ expect(records._raw).to eq [{ name: 'Steve' }]
36
+ expect(records.first.uppercase_name).to eq 'STEVE'
37
+ end
38
+
39
+ it 'resolves triggered by method missing' do
40
+ expect(records._raw).to eq [{ name: 'Steve' }]
41
+ expect(
42
+ Record.where(color: 'blue').where(range: '>26', available: true).first.name
43
+ ).to eq 'Steve'
44
+ end
45
+ end
46
+
47
+ context 'multiple parameters' do
48
+ before do
49
+ stub_request(:get, 'http://datastore/v2/records/?parameter=last').to_return(response)
50
+ end
51
+
52
+ it 'takes the last value for chains with same name parameters' do
53
+ records = Record.where(parameter: 'first').where(parameter: 'last')
54
+ records.first
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Record do
6
+ let(:datastore) do
7
+ 'http://datastore/v2'
8
+ end
9
+
10
+ before do
11
+ DHC.config.placeholder('datastore', datastore)
12
+ class Record < DHS::Record
13
+ endpoint '{+datastore}/content-ads/{campaign_id}/feedbacks'
14
+ endpoint '{+datastore}/feedbacks'
15
+ end
16
+ end
17
+
18
+ context 'where' do
19
+ it 'is querying relevant endpoint when using where' do
20
+ stub_request(:get, "#{datastore}/feedbacks?has_review=true").to_return(status: 200, body: { items: [] }.to_json)
21
+ Record.where(has_review: true)
22
+ stub_request(:get, "#{datastore}/content-ads/123/feedbacks?has_review=true").to_return(status: 200, body: [].to_json)
23
+ Record.where(campaign_id: '123', has_review: true)
24
+ stub_request(:get, "#{datastore}/feedbacks").to_return(status: 200, body: [].to_json)
25
+ records = Record.where
26
+ expect(records).to be_kind_of Record
27
+ end
28
+
29
+ it 'is using params as query params explicitly when provided in params namespace' do
30
+ stub_request(:get, "#{datastore}/content-ads/123/feedbacks?campaign_id=456").to_return(status: 200, body: [].to_json)
31
+ Record.where(campaign_id: '123', params: { campaign_id: '456' })
32
+ end
33
+
34
+ context 'where with href' do
35
+ let(:return_body) { [email: 'steve@depay.fi'].to_json }
36
+
37
+ context 'chain initialization' do
38
+ before do
39
+ stub_request(:get, 'https://localch-accounts/?from_user_id=123')
40
+ .to_return(body: return_body)
41
+ end
42
+
43
+ it 'queries api with provided href' do
44
+ records = Record.where('https://localch-accounts?from_user_id=123').fetch
45
+ expect(records.first.email).to eq 'steve@depay.fi'
46
+ end
47
+ end
48
+
49
+ context 'after chain initialization' do
50
+ before do
51
+ stub_request(:get, 'https://localch-accounts/?color=blue&from_user_id=123')
52
+ .to_return(body: return_body)
53
+ end
54
+
55
+ it 'queries api with provided href also when passed after chain is initialized' do
56
+ records = Record.where(color: 'blue').where('https://localch-accounts?from_user_id=123').fetch
57
+ expect(records.first.email).to eq 'steve@depay.fi'
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::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
+ DHC.config.placeholder('datastore', datastore)
16
+ class Record < DHS::Record
17
+ endpoint '{+datastore}/records/'
18
+ end
19
+ end
20
+
21
+ context 'where values hash' do
22
+ it 'provides the hash or where parameters that have been requested' do
23
+ stub_request(:get, 'http://datastore/v2/records/?available=true&color=blue').to_return(response)
24
+ expect(
25
+ Record.where(available: true).where(color: 'blue').where_values_hash
26
+ ).to eq(available: true, color: 'blue')
27
+ expect(
28
+ Record.where(available: true, color: 'red').where(color: 'blue').where_values_hash
29
+ ).to eq(available: true, color: 'blue')
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'dhc/rspec'
5
+
6
+ describe 'Request Cycle Cache', type: :request do
7
+ let!(:request) do
8
+ stub_request(:get, 'http://datastore/v2/users/1').to_return(body: { name: 'Steve' }.to_json)
9
+ end
10
+
11
+ let!(:second_request) do
12
+ stub_request(:get, 'http://datastore/v2/users/2').to_return(body: { name: 'Peter' }.to_json)
13
+ end
14
+
15
+ before do
16
+ class User < DHS::Record
17
+ endpoint 'http://datastore/v2/users'
18
+ endpoint 'http://datastore/v2/users/{id}'
19
+ end
20
+ DHC.configure do |config|
21
+ config.interceptors = [DHC::Caching]
22
+ end
23
+ end
24
+
25
+ it 'serves requests that are exactly the same during one request cycle from the cache',
26
+ dummy_models: true, request_cycle_cache: true do
27
+ get '/request_cycle_cache/simple'
28
+ expect(request).to have_been_made.once
29
+
30
+ # Second Request, Second Cycle, requests again
31
+ get '/request_cycle_cache/simple'
32
+ expect(request).to have_been_made.times(2)
33
+ end
34
+
35
+ it 'does not serve from request cycle cache when cache interceptor is not hooked in, but logs a warning',
36
+ dummy_models: true, request_cycle_cache: true do
37
+ expect(lambda do
38
+ get '/request_cycle_cache/no_caching_interceptor'
39
+ end).to output(
40
+ %r{\[WARNING\] Can't enable request cycle cache as DHC::Caching interceptor is not enabled/configured \(see https://github.com/DePayFi/dhc/blob/master/README.md#caching-interceptor\)!}
41
+ ).to_stderr
42
+ expect(request).to have_been_made.times(2)
43
+ end
44
+
45
+ it 'serves requests also from cache when DHS/DHC makes requests in parallel',
46
+ dummy_models: true, request_cycle_cache: true do
47
+ get '/request_cycle_cache/parallel'
48
+ expect(request).to have_been_made.once
49
+ expect(second_request).to have_been_made.once
50
+ end
51
+
52
+ it 'sets different uniq request ids as base for request cycle caching for different requests',
53
+ dummy_models: true, request_cycle_cache: true do
54
+ get '/request_cycle_cache/simple'
55
+ first_request_id = DHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id
56
+ second_request_id = nil
57
+ thread = Thread.new do
58
+ get '/request_cycle_cache/simple'
59
+ second_request_id = DHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id
60
+ end
61
+ thread.join
62
+ expect(first_request_id).not_to be_nil
63
+ expect(second_request_id).not_to be_nil
64
+ expect(first_request_id).not_to eq second_request_id
65
+ end
66
+
67
+ context 'disabled request cycle cache' do
68
+ it 'does not serve from request cycle cache when cache interceptor is not hooked in, and does not warn if request cycle cache is explicitly disabled',
69
+ dummy_models: true do
70
+ expect(lambda do
71
+ get '/request_cycle_cache/no_caching_interceptor'
72
+ end).not_to output(
73
+ %r{\[WARNING\] Can't enable request cycle cache as DHC::Caching interceptor is not enabled/configured \(see https://github.com/DePayFi/dhc/blob/master/README.md#caching-interceptor\)!}
74
+ ).to_stderr
75
+ expect(request).to have_been_made.times(2)
76
+ end
77
+
78
+ it 'DOES NOT serve requests that are exactly the same during one request cycle from the cache, when request cycle cache is disabled',
79
+ dummy_models: true do
80
+ get '/request_cycle_cache/simple'
81
+ expect(request).to have_been_made.times(2)
82
+ end
83
+ end
84
+
85
+ context 'headers' do
86
+ it 'considers the request headers when setting the cache key',
87
+ dummy_models: true, request_cycle_cache: true do
88
+ get '/request_cycle_cache/headers_are_different'
89
+ expect(request).to have_been_made.times(2)
90
+ end
91
+ end
92
+
93
+ context 'use: cache' do
94
+ let!(:old_cache) { DHS.config.request_cycle_cache }
95
+
96
+ before { DHS.config.request_cycle_cache = double('cache', fetch: nil, write: nil) }
97
+ after { DHS.config.request_cycle_cache = old_cache }
98
+
99
+ it 'uses the cache passed in',
100
+ dummy_models: true, request_cycle_cache: true do
101
+ expect(DHS.config.request_cycle_cache).to receive(:fetch).at_least(:once)
102
+ expect(DHS.config.request_cycle_cache).to receive(:write).at_least(:once)
103
+ get '/request_cycle_cache/simple'
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe DHS do
4
+ context 'when requiring dhs' do
5
+ it 'does not raise an exception' do
6
+ expect { require 'dhs' }.not_to raise_error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pry'
4
+ require 'webmock/rspec'
5
+
6
+ Dir[File.join(__dir__, 'support/**/*.rb')].each { |f| require f }
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'dhs/rspec'
5
+
6
+ describe DHS do
7
+ before do
8
+ class Record < DHS::Record
9
+ endpoint 'https://records'
10
+ end
11
+
12
+ Record.stub_all(
13
+ 'https://records',
14
+ 200.times.map { |index| { name: "Item #{index}" } },
15
+ headers: {
16
+ 'Authorization' => 'Bearer 123'
17
+ }
18
+ )
19
+ end
20
+
21
+ it 'stubs all requests' do
22
+ records = Record.options(headers: { 'Authorization' => 'Bearer 123' }).all.fetch
23
+ expect(records.count).to eq 200
24
+ expect(records.length).to eq 200
25
+ expect(records.first.name).to eq 'Item 0'
26
+ end
27
+
28
+ context 'without conditions' do
29
+ before do
30
+ class Record < DHS::Record
31
+ endpoint 'https://records'
32
+ end
33
+
34
+ Record.stub_all(
35
+ 'https://records',
36
+ 200.times.map { |index| { name: "Item #{index}" } }
37
+ )
38
+ end
39
+
40
+ it 'stubs all requests without a webmock "with"' do
41
+ records = Record.all.fetch
42
+ expect(records.count).to eq 200
43
+ expect(records.length).to eq 200
44
+ expect(records.first.name).to eq 'Item 0'
45
+ end
46
+ end
47
+
48
+ context 'with configured record' do
49
+ before do
50
+ class Record < DHS::Record
51
+ configuration limit_key: :per_page, pagination_strategy: :page, pagination_key: :page
52
+
53
+ endpoint 'https://records'
54
+ end
55
+
56
+ Record.stub_all(
57
+ 'https://records',
58
+ 200.times.map { |index| { name: "Item #{index}" } }
59
+ )
60
+ end
61
+
62
+ it 'stubs all requests with record configurations for pagination' do
63
+ records = Record.all.fetch
64
+ expect(records.count).to eq 200
65
+ expect(records.length).to eq 200
66
+ expect(records.first.name).to eq 'Item 0'
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ {
2
+ "href": "http://depay.fi/v2/feedbacks/-Sc4_pYNpqfsudzhtivfkA",
3
+ "campaign": {
4
+ "href": "http://depay.fi/v2/content-ads/51dfc5690cf271c375c5a12d"
5
+ },
6
+ "source_id": "aaa",
7
+ "recommended": true,
8
+ "modified": "2014-09-19T14:03:35.599+02:00",
9
+ "created_date": "2014-09-19T14:03:35.597+02:00",
10
+ "comments": []
11
+ }
@@ -0,0 +1,174 @@
1
+ {
2
+ "href" : "http://depay.fi/v2/feedbacks/?exclude_hidden=false&offset=0&limit=10",
3
+ "items" : [ {
4
+ "href" : "http://depay.fi/v2/feedbacks/0sdaetZ-OWVg4oBiBJ-7IQ",
5
+ "campaign" : {
6
+ "href" : "http://depay.fi/v2/content-ads/51dfc5690cf271c375c5a12d"
7
+ },
8
+ "source_id" : "aaa",
9
+ "recommended" : true,
10
+ "ratings" : {
11
+ "ambiente" : 4,
12
+ "service" : 2,
13
+ "food" : 3
14
+ },
15
+ "valid_from" : "2014-10-01",
16
+ "modified" : "2014-09-18T16:13:32.987+02:00",
17
+ "created_date" : "2014-09-18T16:13:31.496+02:00",
18
+ "average_rating" : 3.0,
19
+ "comments" : [ ]
20
+ }, {
21
+ "href" : "http://depay.fi/v2/feedbacks/QsUOQWNJoB-GFUNsX7z0jg",
22
+ "campaign" : {
23
+ "href" : "http://depay.fi/v2/content-ads/51dfc5690cf271c375c5a11f"
24
+ },
25
+ "source_id" : "abcdefghs12345",
26
+ "name" : "Steve",
27
+ "recommended" : true,
28
+ "ratings" : {
29
+ "ambiente" : 3,
30
+ "service" : 5,
31
+ "food" : 2
32
+ },
33
+ "valid_from" : "2014-10-01",
34
+ "modified" : "2014-09-18T15:43:12.134+02:00",
35
+ "created_date" : "2014-09-18T15:42:57.892+02:00",
36
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
37
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
38
+ "average_rating" : 3.3333333333333335,
39
+ "comments" : [ ]
40
+ }, {
41
+ "href" : "http://depay.fi/v2/feedbacks/QynNtmpXlsEGvUJ0ekDKVw",
42
+ "campaign" : {
43
+ "href" : "http://depay.fi/v2/content-ads/51dfc56b0cf271c375c5a14d"
44
+ },
45
+ "source_id" : "abcdefghs12345",
46
+ "name" : "Steve",
47
+ "recommended" : true,
48
+ "ratings" : {
49
+ "ambiente" : 3,
50
+ "service" : 5,
51
+ "food" : 2
52
+ },
53
+ "valid_from" : "2014-10-01",
54
+ "modified" : "2014-09-17T11:17:39.660+02:00",
55
+ "created_date" : "2014-09-17T11:17:34.234+02:00",
56
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
57
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
58
+ "average_rating" : 3.3333333333333335,
59
+ "comments" : [ ]
60
+ }, {
61
+ "href" : "http://depay.fi/v2/feedbacks/INmminYWNZwW_qNFx5peJQ",
62
+ "campaign" : {
63
+ "href" : "http://depay.fi/v2/content-ads/51dfc56b0cf271c375c5a153"
64
+ },
65
+ "source_id" : "abcdefghs12345",
66
+ "name" : "Steve",
67
+ "recommended" : true,
68
+ "ratings" : {
69
+ "ambiente" : 3,
70
+ "service" : 5,
71
+ "food" : 2
72
+ },
73
+ "valid_from" : "2014-10-01",
74
+ "modified" : "2014-09-16T11:20:32.600+02:00",
75
+ "created_date" : "2014-09-16T11:20:30.194+02:00",
76
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
77
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
78
+ "average_rating" : 3.3333333333333335,
79
+ "comments" : [ ]
80
+ }, {
81
+ "href" : "http://depay.fi/v2/feedbacks/ltgfr0VRYDN2nxyC119wTg",
82
+ "campaign" : {
83
+ "href" : "http://depay.fi/v2/content-ads/51dfc56b0cf271c375c5a14c"
84
+ },
85
+ "source_id" : "aaa",
86
+ "recommended" : false,
87
+ "ratings" : {
88
+ "ambiente" : 2,
89
+ "service" : 1,
90
+ "food" : 1
91
+ },
92
+ "valid_from" : "2014-10-01",
93
+ "modified" : "2014-09-15T16:23:54.898+02:00",
94
+ "created_date" : "2014-09-15T16:23:40.355+02:00",
95
+ "average_rating" : 1.3333333333333333,
96
+ "comments" : [ ]
97
+ }, {
98
+ "href" : "http://depay.fi/v2/feedbacks/5dUdQP-kZ6sulN8NtpGXTw",
99
+ "campaign" : {
100
+ "href" : "http://depay.fi/v2/content-ads/51dfc56b0cf271c375c5a14c"
101
+ },
102
+ "source_id" : "abcdefghs12345",
103
+ "name" : "Steve",
104
+ "recommended" : true,
105
+ "ratings" : {
106
+ "ambiente" : 3,
107
+ "service" : 5,
108
+ "food" : 2
109
+ },
110
+ "valid_from" : "2014-10-01",
111
+ "modified" : "2014-09-12T13:10:51.220+02:00",
112
+ "created_date" : "2014-09-12T13:10:48.813+02:00",
113
+ "review_title" : "GUMMYBEARS GUMMYBEARS GUMMYBEARS",
114
+ "review" : "GUMMYBEARS! ... WOAH, STEVE! No, we both know how you get when you eat gummybears!",
115
+ "average_rating" : 3.3333333333333335,
116
+ "comments" : [ ]
117
+ }, {
118
+ "href" : "http://depay.fi/v2/feedbacks/Z3KfWzIEQ3ZVCUj2IdrSNQ",
119
+ "campaign" : {
120
+ "href" : "http://depay.fi/v2/content-ads/51dfc5690cf271c375c5a12e"
121
+ },
122
+ "source_id" : "abcdefghs",
123
+ "recommended" : true,
124
+ "valid_from" : "2014-10-01",
125
+ "modified" : "2014-09-10T16:57:36.255+02:00",
126
+ "created_date" : "2014-09-10T16:57:36.254+02:00",
127
+ "comments" : [ ]
128
+ }, {
129
+ "href" : "http://depay.fi/v2/feedbacks/ZUUUeiw-Stw5Zb1baHDUzQ",
130
+ "campaign" : {
131
+ "href" : "http://depay.fi/v2/content-ads/51dfc5690cf271c375c5a12d"
132
+ },
133
+ "source_id" : "abcdefghs",
134
+ "recommended" : true,
135
+ "valid_from" : "2014-10-01",
136
+ "modified" : "2014-09-10T16:57:32.792+02:00",
137
+ "created_date" : "2014-09-10T16:57:32.791+02:00",
138
+ "comments" : [ ]
139
+ }, {
140
+ "href" : "http://depay.fi/v2/feedbacks/GyeWvhEtU4cYN_5T2FX2UA",
141
+ "campaign" : {
142
+ "href" : "http://depay.fi/v2/content-ads/539266ec0cf2cd754583cfa0"
143
+ },
144
+ "source_id" : "abcdefghs",
145
+ "name" : "aa",
146
+ "recommended" : true,
147
+ "ratings" : {
148
+ "ambiente" : 2,
149
+ "service" : 4,
150
+ "food" : 3
151
+ },
152
+ "valid_from" : "2014-10-01",
153
+ "modified" : "2014-09-11T09:48:19.096+02:00",
154
+ "created_date" : "2014-09-10T16:35:39.201+02:00",
155
+ "review_title" : "bbb",
156
+ "review" : "fff",
157
+ "average_rating" : 3.0,
158
+ "comments" : [ ]
159
+ }, {
160
+ "href" : "http://depay.fi/v2/feedbacks/o-qTRqQGFS3Z_RPJm1f8SA",
161
+ "campaign" : {
162
+ "href" : "http://depay.fi/v2/content-ads/51dfc56c0cf271c375c5a160"
163
+ },
164
+ "source_id" : "abcdefghs12345",
165
+ "recommended" : true,
166
+ "valid_from" : "2014-10-01",
167
+ "modified" : "2014-09-10T16:31:52.493+02:00",
168
+ "created_date" : "2014-09-10T16:31:52.492+02:00",
169
+ "comments" : [ ]
170
+ } ],
171
+ "total" : 98,
172
+ "offset" : 0,
173
+ "limit" : 10
174
+ }