dhs 1.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 (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
+ }