lhs 22.1.0 → 24.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b42b1f0f10d4d0dcf31de3e65ed4ca0c3f7bcfded40e9897231b5ff09a9c472
4
- data.tar.gz: 1c041ff80320d79d73ef02e9af30278d58e779c239044c3485eac9b5e047f8ee
3
+ metadata.gz: e31a9b37f1bc0f12b3a6c87933b145781ed3054e08ea4ea347d5b27d00a069ea
4
+ data.tar.gz: d67f414e70fdcae5567dcf5c81c2e2dec93237026e829c9dc9522df5eb778480
5
5
  SHA512:
6
- metadata.gz: 1a33c68f7d0c82a6c54482fa3ba3986bac1dccc83d9284951fa0f95bf92c0cd17fe3283c62c1c9dee067769d0fe81daf5ca3c86b8c6f84c07ccc0c3977b108cc
7
- data.tar.gz: fe26fa077139d670284ef136e6f702549bd1fd8e8d2c3bfd5f5d43dcd1dba3bf3ac72f7dca8ae70628184c85ff83908558353e0d835fa00052d21ab0539b88d8
6
+ metadata.gz: f39832a96aa989660bfbaf051c53bd53c647d4e75f7b9fa3ca81ab1243ec94bd17828da931207f80fd57a9f98f38188cca659143912a01a4ffc5e197090f6b3a
7
+ data.tar.gz: 19ea228303da96f4f4e831825c19c98ea9a81c15b76ad645b3ecbe23532f0a7336eb87d815f432f2d25ee5d6f0c07d98963ed0ba5388022cd79521cd0ae04424
data/README.md CHANGED
@@ -99,6 +99,8 @@ record.review # "Lunch was great
99
99
  * [Change/Update existing records](#changeupdate-existing-records)
100
100
  * [save](#save)
101
101
  * [update](#update)
102
+ * [Directly via Record](#directly-via-record)
103
+ * [per Instance](#per-instance)
102
104
  * [partial_update](#partial_update)
103
105
  * [Endpoint url parameter injection during record creation/change](#endpoint-url-parameter-injection-during-record-creationchange)
104
106
  * [Record validation](#record-validation)
@@ -119,8 +121,8 @@ record.review # "Lunch was great
119
121
  * [Record getters](#record-getters)
120
122
  * [Include linked resources (hyperlinks and hypermedia)](#include-linked-resources-hyperlinks-and-hypermedia)
121
123
  * [Generate links from parameters](#generate-links-from-parameters)
122
- * [Ensure the whole linked collection is included: includes_all](#ensure-the-whole-linked-collection-is-included-includes_all)
123
- * [Include the first linked page or single item is included: include](#include-the-first-linked-page-or-single-item-is-included-include)
124
+ * [Ensure the whole linked collection is included with includes](#ensure-the-whole-linked-collection-is-included-with-includes)
125
+ * [Include only the first linked page of a linked collection: includes_first_page](#include-only-the-first-linked-page-of-a-linked-collection-includes_first_page)
124
126
  * [Include various levels of linked data](#include-various-levels-of-linked-data)
125
127
  * [Identify and cast known records when including records](#identify-and-cast-known-records-when-including-records)
126
128
  * [Apply options for requests performed to fetch included records](#apply-options-for-requests-performed-to-fetch-included-records)
@@ -152,6 +154,7 @@ record.review # "Lunch was great
152
154
 
153
155
 
154
156
 
157
+
155
158
  ## Installation/Startup checklist
156
159
 
157
160
  - [ ] Install LHS gem, preferably via `Gemfile`
@@ -976,7 +979,7 @@ If you need to render some different view in Rails based on an LHS error raised
976
979
 
977
980
  def show
978
981
  @records = Record
979
- .handle(LHC::Error, ->(error){ handle_error(error) })
982
+ .rescue(LHC::Error, ->(error){ rescue_from(error) })
980
983
  .where(color: 'blue')
981
984
  render 'show'
982
985
  render_error if @error
@@ -984,7 +987,7 @@ end
984
987
 
985
988
  private
986
989
 
987
- def handle_error(error)
990
+ def rescue_from(error)
988
991
  @error = error
989
992
  nil
990
993
  end
@@ -1009,7 +1012,7 @@ If you want to inject values for the failing records, that might not have been f
1009
1012
  # app/controllers/some_controller.rb
1010
1013
 
1011
1014
  data = Record
1012
- .handle(LHC::Unauthorized, ->(response) { Record.new(name: 'unknown') })
1015
+ .rescue(LHC::Unauthorized, ->(response) { Record.new(name: 'unknown') })
1013
1016
  .find(1, 2, 3)
1014
1017
 
1015
1018
  data[1].name # 'unknown'
@@ -2276,6 +2279,17 @@ In parallel:
2276
2279
  GET https://service.example.com/places/4 { headers: { 'Authentication': 'Bearer 123' } }
2277
2280
  ```
2278
2281
 
2282
+ Here is another example, if you want to ignore errors, that occure while you fetch included resources:
2283
+
2284
+ ```ruby
2285
+ # app/controllers/some_controller.rb
2286
+
2287
+ feedback = Feedback
2288
+ .includes(campaign: :entry)
2289
+ .references(campaign: { ignore: LHC::NotFound })
2290
+ .find(12345)
2291
+ ```
2292
+
2279
2293
  ### Record batch processing
2280
2294
 
2281
2295
  **Be careful using methods for batch processing. They could result in a lot of HTTP requests!**
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_dependency 'activemodel'
26
26
  s.add_dependency 'activesupport', '>= 4.2.11'
27
- s.add_dependency 'lhc', '>= 10', '< 12'
27
+ s.add_dependency 'lhc', '>= 12.1.1', '< 13'
28
28
  s.add_dependency 'local_uri'
29
29
 
30
30
  s.add_development_dependency 'capybara'
@@ -39,5 +39,5 @@ Gem::Specification.new do |s|
39
39
  s.add_development_dependency 'sprockets', '< 4'
40
40
  s.add_development_dependency 'webmock'
41
41
 
42
- s.license = 'GPL-3'
42
+ s.license = 'GPL-3.0'
43
43
  end
@@ -52,7 +52,7 @@ class LHS::Record
52
52
  Chain.new(self, Pagination.new(per: argument))
53
53
  end
54
54
 
55
- def handle(error_class, handler)
55
+ def rescue(error_class, handler)
56
56
  Chain.new(self, ErrorHandling.new(error_class => handler))
57
57
  end
58
58
 
@@ -255,7 +255,7 @@ class LHS::Record
255
255
  push(Pagination.new(per: argument))
256
256
  end
257
257
 
258
- def handle(error_class, handler)
258
+ def rescue(error_class, handler)
259
259
  push(ErrorHandling.new(error_class => handler))
260
260
  end
261
261
 
@@ -348,8 +348,8 @@ class LHS::Record
348
348
  def resolved_options
349
349
  options = chain_options
350
350
  options = options.deep_merge(params: chain_parameters.merge(chain_pagination))
351
- options = options.merge(error_handler: chain_error_handler) if chain_error_handler.present?
352
- options = options.merge(ignored_errors: chain_ignored_errors) if chain_ignored_errors.present?
351
+ options = options.merge(rescue: chain_error_handler) if chain_error_handler.present?
352
+ options = options.merge(ignore: chain_ignored_errors) if chain_ignored_errors.present?
353
353
  options = options.merge(including: chain_includes) if chain_includes.present?
354
354
  options = options.merge(referencing: chain_references) if chain_references.present?
355
355
  options
@@ -138,6 +138,7 @@ class LHS::Record
138
138
  end
139
139
 
140
140
  def extend_base_item!(data, addition, key)
141
+ return if addition.nil?
141
142
  if addition.collection?
142
143
  extend_base_item_with_collection!(data, addition, key)
143
144
  else # simple case merges hash into hash
@@ -187,7 +188,7 @@ class LHS::Record
187
188
  options = extend_with_reference(options, reference)
188
189
  addition = load_include(options, data, sub_includes, reference)
189
190
  extend_raw_data!(data, addition, included)
190
- expand_addition!(data, included, options) if no_expanded_data?(addition)
191
+ expand_addition!(data, included, options) unless expanded_data?(addition)
191
192
  end
192
193
  end
193
194
 
@@ -205,28 +206,24 @@ class LHS::Record
205
206
  def expand_addition!(data, included, reference)
206
207
  addition = data[included]
207
208
  options = options_for_data(addition)
208
- options = extend_with_reference(options, reference.except(:url))
209
+ options = extend_with_reference(options, reference)
209
210
  record = record_for_options(options) || self
210
211
  options = convert_options_to_endpoints(options) if record_for_options(options)
211
- expanded_data = begin
212
- record.request(options)
213
- rescue LHC::NotFound
214
- LHS::Data.new({}, data, record)
215
- end
212
+ expanded_data = record.request(options)
216
213
  extend_raw_data!(data, expanded_data, included)
217
214
  end
218
215
 
219
- def no_expanded_data?(addition)
216
+ def expanded_data?(addition)
220
217
  return false if addition.blank?
221
218
  if addition.item?
222
- (addition._raw.keys - [:href]).empty?
219
+ (addition._raw.keys - [:href]).any?
223
220
  elsif addition.collection?
224
- addition.all? do |item|
221
+ addition.any? do |item|
225
222
  next if item.blank?
226
223
  if item._raw.is_a?(Hash)
227
- (item._raw.keys - [:href]).empty?
224
+ (item._raw.keys - [:href]).any?
228
225
  elsif item._raw.is_a?(Array)
229
- item.any? { |item| (item._raw.keys - [:href]).empty? }
226
+ item.any? { |item| (item._raw.keys - [:href]).any? }
230
227
  end
231
228
  end
232
229
  end
@@ -234,7 +231,8 @@ class LHS::Record
234
231
 
235
232
  # Extends request options with options provided for this reference
236
233
  def extend_with_reference(options, reference)
237
- return options unless reference
234
+ return options if reference.blank?
235
+ reference = reference.except(:url)
238
236
  options ||= {}
239
237
  if options.is_a?(Array)
240
238
  options.map { |request_options| request_options.merge(reference) if request_options.present? }
@@ -348,18 +346,14 @@ class LHS::Record
348
346
  end
349
347
 
350
348
  # Load additional resources that are requested with include
351
- def load_include(options, data, sub_includes, references)
349
+ def load_include(options, _data, sub_includes, references)
352
350
  record = record_for_options(options) || self
353
351
  options = convert_options_to_endpoints(options) if record_for_options(options)
354
- begin
355
- prepare_options_for_include_request!(options, sub_includes, references)
356
- if references && references[:all] # include all linked resources
357
- load_include_all!(options, record, sub_includes, references)
358
- else # simply request first page/batch
359
- load_include_simple!(options, record)
360
- end
361
- rescue LHC::NotFound
362
- LHS::Data.new({}, data, record)
352
+ prepare_options_for_include_request!(options, sub_includes, references)
353
+ if references && references[:all] # include all linked resources
354
+ load_include_all!(options, record, sub_includes, references)
355
+ else # simply request first page/batch
356
+ load_include_simple!(options, record)
363
357
  end
364
358
  end
365
359
 
@@ -372,7 +366,7 @@ class LHS::Record
372
366
 
373
367
  def load_include_simple!(options, record)
374
368
  data = record.request(options)
375
- warn "[WARNING] You included `#{options[:url]}`, but this endpoint is paginated. You might want to use `includes_all` instead of `includes` (https://github.com/local-ch/lhs#includes_all-for-paginated-endpoints)." if paginated?(data._raw)
369
+ warn "[WARNING] You included `#{options[:url]}`, but this endpoint is paginated. You might want to use `includes_all` instead of `includes` (https://github.com/local-ch/lhs#includes_all-for-paginated-endpoints)." if data && paginated?(data._raw)
376
370
  data
377
371
  end
378
372
 
@@ -510,7 +504,7 @@ class LHS::Record
510
504
  options = options.deep_dup
511
505
  options[:ignored_errors] = ignored_errors if ignored_errors.present?
512
506
  options[:params]&.deep_symbolize_keys!
513
- options[:error_handler] = merge_error_handlers(options[:error_handler]) if options[:error_handler]
507
+ options[:rescue] = merge_error_handlers(options[:rescue]) if options[:rescue]
514
508
  options = (provider_options || {})
515
509
  .deep_merge(endpoint.options || {})
516
510
  .deep_merge(options)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHS
4
- VERSION = '22.1.0'
4
+ VERSION = '24.0.0'
5
5
  end
@@ -6,7 +6,7 @@ class ErrorHandlingWithChainsController < ApplicationController
6
6
  # in the view (during render 'show')
7
7
  def fetch_in_view
8
8
  @records = DummyRecord
9
- .handle(LHC::Error, ->(error) { handle_error(error) })
9
+ .rescue(LHC::Error, ->(error) { handle_error(error) })
10
10
  .where(color: 'blue')
11
11
  render 'show'
12
12
  render_error if @error
@@ -16,7 +16,7 @@ class ErrorHandlingWithChainsController < ApplicationController
16
16
  # before the view is rendered
17
17
  def fetch_in_controller
18
18
  @records = DummyRecord
19
- .handle(LHC::Error, ->(error) { handle_error(error) })
19
+ .rescue(LHC::Error, ->(error) { handle_error(error) })
20
20
  .where(color: 'blue').fetch
21
21
  render 'show'
22
22
  render_error if @error
@@ -15,14 +15,14 @@ describe LHS::Record do
15
15
 
16
16
  it 'allows to chain error handling' do
17
17
  expect {
18
- Record.where(color: 'blue').handle(LHC::Error, ->(_error) { handler.handle }).first
18
+ Record.where(color: 'blue').rescue(LHC::Error, ->(_error) { handler.handle }).first
19
19
  }.not_to raise_error
20
20
  expect(handler).to have_received(:handle)
21
21
  end
22
22
 
23
23
  it 'reraises in case chained error is not matched' do
24
24
  expect {
25
- Record.where(color: 'blue').handle(LHC::Conflict, ->(_error) { handler.handle }).first
25
+ Record.where(color: 'blue').rescue(LHC::Conflict, ->(_error) { handler.handle }).first
26
26
  }.to raise_error(LHC::Error)
27
27
  expect(handler).not_to have_received(:handle)
28
28
  end
@@ -30,8 +30,8 @@ describe LHS::Record do
30
30
  it 'calls all the handlers' do
31
31
  expect {
32
32
  Record.where(color: 'blue')
33
- .handle(LHC::Error, ->(_error) { handler.handle_1 })
34
- .handle(LHC::Error, ->(_error) { handler.handle_2 })
33
+ .rescue(LHC::Error, ->(_error) { handler.handle_1 })
34
+ .rescue(LHC::Error, ->(_error) { handler.handle_2 })
35
35
  .first
36
36
  }.not_to raise_error
37
37
  expect(handler).to have_received(:handle_1)
@@ -33,7 +33,7 @@ describe LHS::Record do
33
33
  it 'applies error handlers from the chain and returns whatever the error handler returns' do
34
34
  stub_request(:get, "http://datastore/records/2").to_return(status: 401)
35
35
  data = Record
36
- .handle(LHC::Unauthorized, ->(_response) { Record.new(name: 'unknown') })
36
+ .rescue(LHC::Unauthorized, ->(_response) { Record.new(name: 'unknown') })
37
37
  .find(1, 2, 3)
38
38
  expect(data[1].name).to eq 'unknown'
39
39
  end
@@ -25,7 +25,7 @@ describe LHS::Record do
25
25
 
26
26
  it 'allows to pass error_handling for includes to LHC' do
27
27
  handler = ->(_) { return { deleted: true } }
28
- record = Record.includes_first_page(:other).references(other: { error_handler: { LHC::NotFound => handler } }).find(id: 1)
28
+ record = Record.includes_first_page(:other).references(other: { rescue: { LHC::NotFound => handler } }).find(id: 1)
29
29
 
30
30
  expect(record.other.deleted).to be(true)
31
31
  end
@@ -224,7 +224,7 @@ describe LHS::Record do
224
224
  end
225
225
 
226
226
  context 'links pointing to nowhere' do
227
- it 'sets nil for links that cannot be included' do
227
+ before do
228
228
  class Feedback < LHS::Record
229
229
  endpoint '{+datastore}/feedbacks'
230
230
  endpoint '{+datastore}/feedbacks/{id}'
@@ -238,10 +238,20 @@ describe LHS::Record do
238
238
 
239
239
  stub_request(:get, "#{datastore}/content-ads/51dfc5690cf271c375c5a12d")
240
240
  .to_return(status: 404)
241
+ end
242
+
243
+ it 'raises LHC::NotFound for links that cannot be included' do
244
+ expect(-> {
245
+ Feedback.includes_first_page(campaign: :entry).find(123)
246
+ }).to raise_error LHC::NotFound
247
+ end
241
248
 
242
- feedback = Feedback.includes_first_page(campaign: :entry).find(123)
243
- expect(feedback.campaign._raw.keys.count).to eq 1
244
- expect(feedback.campaign.href).to be_present
249
+ it 'ignores LHC::NotFound for links that cannot be included if configured so with reference options' do
250
+ feedback = Feedback
251
+ .includes_first_page(campaign: :entry)
252
+ .references(campaign: { ignore: [LHC::NotFound] })
253
+ .find(123)
254
+ expect(feedback.campaign._raw.keys.length).to eq 1
245
255
  end
246
256
  end
247
257
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhs
3
3
  version: !ruby/object:Gem::Version
4
- version: 22.1.0
4
+ version: 24.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhs/graphs/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-03 00:00:00.000000000 Z
11
+ date: 2020-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -44,20 +44,20 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '10'
47
+ version: 12.1.1
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
- version: '12'
50
+ version: '13'
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: '10'
57
+ version: 12.1.1
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
- version: '12'
60
+ version: '13'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: local_uri
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -548,7 +548,7 @@ files:
548
548
  - spec/views/form_for_spec.rb
549
549
  homepage: https://github.com/local-ch/lhs
550
550
  licenses:
551
- - GPL-3
551
+ - GPL-3.0
552
552
  metadata: {}
553
553
  post_install_message:
554
554
  rdoc_options: []