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,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Item do
6
+ let(:user) do
7
+ User.build(email: 'steve@depay.fi')
8
+ end
9
+
10
+ let(:record) do
11
+ Record.build(number: '123456')
12
+ end
13
+
14
+ context 'deprecation warning for old syntax' do
15
+ it 'throws errors when using validates with the old syntax' do
16
+ expect(lambda do
17
+ class User < DHS::Record
18
+ endpoint 'http://datastore/v2/users', validates: true
19
+ end
20
+ end).to raise_error 'Validates with either true or a simple string is deprecated! See here: https://github.com/DePayFi/dhs#validation'
21
+ expect(lambda do
22
+ class Record < DHS::Record
23
+ endpoint 'http://datastore/v2/records', validates: 'publish'
24
+ end
25
+ end).to raise_error 'Validates with either true or a simple string is deprecated! See here: https://github.com/DePayFi/dhs#validation'
26
+ end
27
+ end
28
+
29
+ context 'passing validation parameters' do
30
+ let(:user) do
31
+ User.build(email: 'steve@depay.fi')
32
+ end
33
+
34
+ it 'validates {publish: false}' do
35
+ class User < DHS::Record
36
+ endpoint 'http://datastore/v2/users', validates: { params: { publish: false } }
37
+ end
38
+ stub_request(:post, 'http://datastore/v2/users?publish=false').to_return(body: {}.to_json)
39
+ expect(user.valid?).to eq true
40
+ end
41
+
42
+ it 'validates {persist: false}' do
43
+ class User < DHS::Record
44
+ endpoint 'http://datastore/v2/users', validates: { params: { persist: false } }
45
+ end
46
+ stub_request(:post, 'http://datastore/v2/users?persist=false').to_return(body: {}.to_json)
47
+ expect(user.valid?).to eq true
48
+ end
49
+
50
+ it 'validates {validates: true}' do
51
+ class User < DHS::Record
52
+ endpoint 'http://datastore/v2/users', validates: { params: { validates: true } }
53
+ end
54
+ stub_request(:post, 'http://datastore/v2/users?validates=true').to_return(body: {}.to_json)
55
+ expect(user.valid?).to eq true
56
+ end
57
+
58
+ it 'validates /validate' do
59
+ class User < DHS::Record
60
+ endpoint 'http://datastore/v2/users', validates: { path: 'validate' }
61
+ end
62
+ stub_request(:post, 'http://datastore/v2/users/validate').to_return(body: {}.to_json)
63
+ expect(user.valid?).to eq true
64
+ end
65
+ end
66
+
67
+ context 'errors object' do
68
+ let(:validation_errors) { { field_errors: [{ code: 'UNSUPPORTED_PROPERTY_VALUE', 'path' => ['email'] }] } }
69
+ let(:successful_validation) do
70
+ stub_request(:post, 'http://datastore/v2/users?persist=false').to_return(body: {}.to_json)
71
+ end
72
+ let(:failing_validation) do
73
+ stub_request(:post, 'http://datastore/v2/users?persist=false')
74
+ .to_return(status: 400, body: validation_errors.to_json)
75
+ end
76
+
77
+ before do
78
+ class User < DHS::Record
79
+ endpoint 'http://datastore/v2/users', validates: { params: { persist: false } }
80
+ end
81
+ end
82
+
83
+ it 'provides validation errors through the error object' do
84
+ successful_validation
85
+ expect(user.valid?).to eq true
86
+ user.email = 'not a valid email'
87
+ failing_validation
88
+ expect(user.valid?).to eq false
89
+ expect(user.errors[:email]).to be_present
90
+ end
91
+
92
+ it 'gets reset when revalidation' do
93
+ failing_validation
94
+ expect(user.valid?).to eq false
95
+ user.email = 'steve@depay.fi'
96
+ successful_validation
97
+ expect(user.valid?).to eq true
98
+ expect(user.errors.messages).to be_empty
99
+ end
100
+ end
101
+
102
+ context 'endpoint does not support validations' do
103
+ before do
104
+ class Favorite < DHS::Record
105
+ endpoint '{+datastore}/v2/favorites'
106
+ end
107
+ end
108
+
109
+ it 'fails when trying to use an endpoint for validations that does not support it' do
110
+ expect(lambda do
111
+ Favorite.build.valid?
112
+ end).to raise_error('Endpoint does not support validations!')
113
+ end
114
+ end
115
+
116
+ context 'generate validation url from locally passed params' do
117
+ before do
118
+ class User < DHS::Record
119
+ endpoint 'http://datastore/v2/users/{user_id}', validates: { params: { persist: false } }
120
+ end
121
+ end
122
+
123
+ it 'takes local params when generating validation url' do
124
+ stub_request(:post, 'http://datastore/v2/users/2?persist=false')
125
+ .to_return(status: 201)
126
+ expect(
127
+ user.valid?(params: { user_id: 2 })
128
+ ).to eq true
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Item do
6
+ context 'error codes' do
7
+ before do
8
+ I18n.reload!
9
+ I18n.backend.store_translations(:en, YAML.safe_load(translation)) if translation.present?
10
+ class Record < DHS::Record
11
+ endpoint 'http://datastore/records'
12
+ end
13
+ end
14
+
15
+ let(:translation) do
16
+ %q{
17
+ dhs:
18
+ warnings:
19
+ fallback_message: 'This value is problematic'
20
+ }
21
+ end
22
+
23
+ it 'provides error codes along side with translated messages' do
24
+ stub_request(:post, 'http://datastore/records')
25
+ .to_return(body: {
26
+ field_warnings: [{
27
+ code: 'UNSUPPORTED_PROPERTY_VALUE',
28
+ path: ['gender'],
29
+ message: 'The property value is unsupported.'
30
+ }, {
31
+ code: 'INCOMPLETE_PROPERTY_VALUE',
32
+ path: ['gender'],
33
+ message: 'The property value is incomplete. It misses some data'
34
+ }, {
35
+ code: 'INCOMPLETE_PROPERTY_VALUE',
36
+ path: %w[contract entry_id],
37
+ message: 'The property value is incomplete. It misses some data'
38
+ }]
39
+ }.to_json)
40
+ record = Record.create
41
+ expect(record.warnings.messages['gender']).to eq(
42
+ ['This value is problematic', 'This value is problematic']
43
+ )
44
+ expect(record.warnings.codes['gender']).to eq(
45
+ %w[UNSUPPORTED_PROPERTY_VALUE INCOMPLETE_PROPERTY_VALUE]
46
+ )
47
+ expect(record.warnings.messages['contract.entry_id']).to eq(
48
+ ['This value is problematic']
49
+ )
50
+ expect(record.warnings.codes['contract.entry_id']).to eq(
51
+ ['INCOMPLETE_PROPERTY_VALUE']
52
+ )
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Item do
6
+ before do
7
+ class Presence < DHS::Record
8
+ endpoint 'http://opm/presence'
9
+ end
10
+
11
+ I18n.reload!
12
+ I18n.backend.store_translations(:en, YAML.safe_load(%q{
13
+ dhs:
14
+ warnings:
15
+ records:
16
+ presence:
17
+ will_be_resized: 'The photos will be resized'
18
+ }))
19
+ end
20
+
21
+ it 'provides warnings together with validation errors' do
22
+ stub_request(:post, 'http://opm/presence?synchronize=false')
23
+ .to_return(
24
+ body: {
25
+ field_warnings: [{
26
+ code: 'WILL_BE_RESIZED',
27
+ path: ['place', 'photos', 0],
28
+ message: 'The image will be resized.'
29
+ }],
30
+ place: {
31
+ href: 'http://storage/places/1',
32
+ photos: [{
33
+ href: 'http://bin.staticdepay.fi/123',
34
+ width: 10,
35
+ height: 10
36
+ }]
37
+ }
38
+ }.to_json
39
+ )
40
+ presence = Presence.options(params: { synchronize: false }).create(
41
+ place: { href: 'http://storage/places/1' }
42
+ )
43
+ expect(presence.warnings.any?).to eq true
44
+ expect(presence.place.warnings.any?).to eq true
45
+ expect(presence.place.photos.warnings.any?).to eq true
46
+ expect(presence.place.photos[0].warnings.any?).to eq true
47
+ expect(presence.place.photos[0].warnings.messages.first).to eq(
48
+ 'The photos will be resized'
49
+ )
50
+ end
51
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe 'Option Blocks', type: :request do
6
+ let!(:first_request) do
7
+ stub_request(:get, 'http://datastore/v2/records?request=first')
8
+ .to_return(status: 200)
9
+ end
10
+
11
+ let!(:second_request) do
12
+ stub_request(:get, 'http://datastore/v2/records?request=second')
13
+ .to_return(status: 200)
14
+ end
15
+
16
+ it 'always ensures option blocks are always reset for new requests',
17
+ dummy_models: true, reset_before: true do
18
+ get '/option_blocks/first'
19
+ expect(first_request).to have_been_made.once
20
+ get '/option_blocks/second'
21
+ expect(second_request).to have_been_made.once
22
+ end
23
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::OptionBlocks do
6
+ let(:status) { 200 }
7
+
8
+ before do
9
+ class Record < DHS::Record
10
+ endpoint 'http://records'
11
+ end
12
+
13
+ stub_request(:get, 'http://records/?id=1234')
14
+ .with(headers: { 'Tracking-Id' => 1 })
15
+ .to_return(status: status)
16
+ end
17
+
18
+ it 'allows to apply options to all requests made within a certain block' do
19
+ DHS.options(headers: { 'Tracking-Id': 1 }) do
20
+ Record.find(1234)
21
+ end
22
+ end
23
+
24
+ it 'ensures that option blocks are reset after the block has been executed' do
25
+ expect(DHS::OptionBlocks::CurrentOptionBlock.options).to eq nil
26
+ DHS.options(headers: { 'Tracking-Id': 1 }) do
27
+ Record.find(1234)
28
+ end
29
+ expect(DHS::OptionBlocks::CurrentOptionBlock.options).to eq nil
30
+ end
31
+
32
+ context 'failing request' do
33
+ let(:status) { 400 }
34
+
35
+ it 'ensures that option blocks are reset when an exception occures in the block' do
36
+ expect(DHS::OptionBlocks::CurrentOptionBlock.options).to eq nil
37
+ DHS.options(headers: { 'Tracking-Id': 1 }) do
38
+ begin
39
+ Record.find(1234)
40
+ rescue DHC::Error
41
+ end
42
+ end
43
+ expect(DHS::OptionBlocks::CurrentOptionBlock.options).to eq nil
44
+ end
45
+ end
46
+
47
+ context 'parallel requests' do
48
+ it 'does not fail merging option blocks for parallel requests' do
49
+ DHS.options(headers: { 'Tracking-Id': 1 }) do
50
+ Record.find(1234, 1234)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Record do
6
+ let(:data_hash) do
7
+ { items: 98.times.map { { foo: 'bar' } }, limit: 10, next: { href: 'http://example.com/users?from_user_id=100&limit=100' } }
8
+ end
9
+
10
+ let(:data) do
11
+ DHS::Data.new(data_hash, nil, DHS::Record)
12
+ end
13
+
14
+ let(:pagination) { DHS::Pagination::Link.new(data) }
15
+
16
+ it 'responds to parallel?' do
17
+ expect(pagination.current_page).to be nil
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Record do
6
+ let(:next_parameter) do
7
+ { next: { href: 'http://example.com/users?from_user_id=100&limit=100' } }
8
+ end
9
+ let(:data_hash) { { items: 98.times.map { { foo: 'bar' } }, limit: 10 }.merge(next_parameter) }
10
+
11
+ let(:data) do
12
+ DHS::Data.new(data_hash, nil, DHS::Record)
13
+ end
14
+
15
+ let(:pagination) { DHS::Pagination::Link.new(data) }
16
+
17
+ it 'responds to pages_left' do
18
+ expect(pagination.pages_left).to eq(1)
19
+ end
20
+
21
+ it 'responds to pages_left?' do
22
+ expect(pagination.pages_left?).to be true
23
+ end
24
+
25
+ context 'when there is no next' do
26
+ let(:next_parameter) { {} }
27
+
28
+ it 'responds to pages_left' do
29
+ expect(pagination.pages_left).to eq(0)
30
+ end
31
+
32
+ it 'responds to pages_left?' do
33
+ expect(pagination.pages_left?).to be false
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe DHS::Record do
6
+ let(:data_hash) do
7
+ { items: 98.times.map { { foo: 'bar' } }, limit: 10, next: { href: 'http://example.com/users?from_user_id=100&limit=100' } }
8
+ end
9
+
10
+ let(:data) do
11
+ DHS::Data.new(data_hash, nil, DHS::Record)
12
+ end
13
+
14
+ let(:pagination) { DHS::Pagination::Link.new(data) }
15
+
16
+ it 'responds to parallel?' do
17
+ expect(pagination.parallel?).to be false
18
+ end
19
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+ require 'webrick'
5
+
6
+ describe DHS::Record do
7
+ before do
8
+ class User < DHS::Record
9
+ endpoint 'http://example.com/users'
10
+ configuration(
11
+ limit_key: 'limit',
12
+ items_key: 'items',
13
+ pagination_strategy: 'link'
14
+ )
15
+ end
16
+ end
17
+
18
+ context 'explicit pagination parameters for retrieving pages' do
19
+ it 'uses explicit parameters when retrieving pages' do
20
+ stub_request(:get, 'http://example.com/users?limit=100')
21
+ .to_return(body: {
22
+ items: 100.times.map { |_| { name: WEBrick::Utils.random_string(10) } },
23
+ limit: 100,
24
+ next: { href: 'http://example.com/users?from_user_id=100&limit=100' }
25
+ }.to_json)
26
+
27
+ stub_request(:get, 'http://example.com/users?from_user_id=100&limit=100')
28
+ .to_return(body: {
29
+ items: 3.times.map { |_| { name: WEBrick::Utils.random_string(10) } },
30
+ limit: 100,
31
+ next: { href: 'http://example.com/users?from_user_id=200&limit=100' }
32
+ }.to_json)
33
+
34
+ stub_request(:get, 'http://example.com/users?from_user_id=200&limit=100')
35
+ .to_return(body: {
36
+ items: [],
37
+ limit: 100
38
+ }.to_json)
39
+
40
+ users = User.all.fetch
41
+ expect(users.total).to eq 103
42
+ expect(users.count).to eq 103
43
+ end
44
+ end
45
+ end