lhs 24.1.0.pre.1 → 25.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0098eb4147ef54ee7e80bb67e1a466c39165ef4b65ad2ac18f6a2c024ee2e9f7'
4
- data.tar.gz: 853bd4e9697debd6c559d24d295019473793c3c5bcf4c1a3f5cdba3d966a743c
3
+ metadata.gz: 75364b152de7b958acefbb09ab084ca96dd15f1daad2465ab80db56584f5f600
4
+ data.tar.gz: 1456ffc9b3a696bc871248981364f7012deeb921647d88493041db4d40effea5
5
5
  SHA512:
6
- metadata.gz: d3db0060e2155188d1697ec6e9c9000d05b13592d6a8ec7c5f952a28b25d1162f72c009f5f70375e06e67637a8d4e488e1946a161bda24513cbb1ea17fe626a3
7
- data.tar.gz: aa448eeb65c3b13ba529040d79b4a3cb6ac31f3961cf407e6d72d6f69bdc3dfc5f543c8d02cd1a3d4932b6a57e0c26fabbd91f365f7629676445cbc328e93e42
6
+ metadata.gz: c271c49bce686c2686ef1d80b535433aba05f1cd58dc98b2265cc8cc63149faa9b3094e0cf82acf8f0afd80721fbbfa5369aea1ffb091e0b14ce35120bc400fc
7
+ data.tar.gz: a24a6debcbe0866a73167eee9b44a3adc7cda111bcd4971e77982d14d44e2bda3cce3eaa63666e257f60f5653a3e013321eb622ca2d6e152cae9b03fce79839d
data/README.md CHANGED
@@ -126,6 +126,7 @@ record.review # "Lunch was great
126
126
  * [Include various levels of linked data](#include-various-levels-of-linked-data)
127
127
  * [Identify and cast known records when including records](#identify-and-cast-known-records-when-including-records)
128
128
  * [Apply options for requests performed to fetch included records](#apply-options-for-requests-performed-to-fetch-included-records)
129
+ * [compact: Remove included resources that didn't return any records](#compact-remove-included-resources-that-didnt-return-any-records)
129
130
  * [Record batch processing](#record-batch-processing)
130
131
  * [all](#all-1)
131
132
  * [Using all, when endpoint does not implement response pagination meta data](#using-all-when-endpoint-does-not-implement-response-pagination-meta-data)
@@ -149,12 +150,15 @@ record.review # "Lunch was great
149
150
  * [Test query chains](#test-query-chains)
150
151
  * [By explicitly resolving the chain: fetch](#by-explicitly-resolving-the-chain-fetch)
151
152
  * [Without resolving the chain: where_values_hash](#without-resolving-the-chain-where_values_hash)
153
+ * [Extended developer documentation](#extended-developer-documentation)
154
+ * [Accessing data in LHS](#accessing-data-in-lhs)
152
155
  * [License](#license)
153
156
 
154
157
 
155
158
 
156
159
 
157
160
 
161
+
158
162
  ## Installation/Startup checklist
159
163
 
160
164
  - [ ] Install LHS gem, preferably via `Gemfile`
@@ -1698,7 +1702,7 @@ record.partial_update(recommended: true)
1698
1702
 
1699
1703
  ```
1700
1704
  ```
1701
- POST https://service.example.com/records/1z-5r1fkaj { body: "{ 'name': 'Starbucks', 'recommended': true }" }
1705
+ POST https://service.example.com/records/1z-5r1fkaj { body: "{ 'recommended': true }" }
1702
1706
  ```
1703
1707
 
1704
1708
  -> See [record validation](#record-validation) for how to handle validation errors when updating records.
@@ -2878,6 +2882,12 @@ expect(
2878
2882
  ).to eq {color: 'red', available: true}
2879
2883
  ```
2880
2884
 
2885
+ ## Extended developer documentation
2886
+
2887
+ ### Accessing data in LHS
2888
+
2889
+ ![diagram](docs/accessing-data-in-lhs.png)
2890
+
2881
2891
  ## License
2882
2892
 
2883
2893
  [GNU General Public License Version 3.](https://www.gnu.org/licenses/gpl-3.0.en.html)
@@ -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', '>= 12.1.1', '< 13'
27
+ s.add_dependency 'lhc', '>= 12.1.1', '< 14'
28
28
  s.add_dependency 'local_uri'
29
29
 
30
30
  s.add_development_dependency 'capybara'
@@ -47,7 +47,7 @@ class LHS::Collection < LHS::Proxy
47
47
  if item.is_a?(LHS::Data) && item._request && !item._request.response.success?
48
48
  nil
49
49
  else
50
- item
50
+ cast_item(item)
51
51
  end
52
52
  end.compact
53
53
  end
@@ -55,10 +55,18 @@ class LHS::Collection < LHS::Proxy
55
55
  private
56
56
 
57
57
  def cast_item(item)
58
- record_by_href = LHS::Record.for_url(item[:href]) if item[:href]
59
58
  data = LHS::Data.new(item, @parent, @record)
60
- return (record_by_href || @record).new(data) if record_by_href || @record
61
- data
59
+ (record_by_href(item) || @record)&.new(data) || data
60
+ end
61
+
62
+ def record_by_href(item)
63
+ return if plain_value?(item) || item[:href].blank?
64
+
65
+ LHS::Record.for_url(item[:href])
66
+ end
67
+
68
+ def plain_value?(item)
69
+ item.is_a?(String) || item.is_a?(Numeric) || item.is_a?(TrueClass) || item.is_a?(FalseClass)
62
70
  end
63
71
  end
64
72
  end
@@ -10,6 +10,7 @@ class LHS::Data
10
10
  # Extends already fetched data (self) with additionally
11
11
  # fetched data (addition) using the given key
12
12
  def extend!(addition, key)
13
+ addition = cast_relation_class_for_extension(addition, key)
13
14
  if collection?
14
15
  extend_collection!(addition, key)
15
16
  elsif self[key]._raw.is_a? Array
@@ -21,6 +22,11 @@ class LHS::Data
21
22
 
22
23
  private
23
24
 
25
+ def cast_relation_class_for_extension(addition, key)
26
+ return addition if _record.nil? || _record._relations.nil? || _record._relations[key].nil?
27
+ addition.becomes(_record._relations[key][:record_class_name].constantize, errors: addition.errors, warnings: addition.warnings)
28
+ end
29
+
24
30
  def extend_collection!(addition, key)
25
31
  map do |item|
26
32
  item_raw = item._raw[key]
@@ -120,7 +120,7 @@ class LHS::Record
120
120
  options = extend_with_reference(options, reference)
121
121
  addition = load_include(options, data, sub_includes, reference)
122
122
  data.extend!(addition, included)
123
- expand_addition!(data, included, options) unless expanded_data?(addition)
123
+ expand_addition!(data, included, reference) unless expanded_data?(addition)
124
124
  end
125
125
  end
126
126
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHS
4
- VERSION = '24.1.0.pre.1'
4
+ VERSION = '25.0.0'
5
5
  end
@@ -6,6 +6,11 @@ describe LHS::Record do
6
6
  before do
7
7
  class Place < LHS::Record
8
8
  endpoint 'http://datastore/places/{id}'
9
+ endpoint 'http://datastore/users/{user_id}/places/{id}'
10
+
11
+ def display_name
12
+ "*#{name}*"
13
+ end
9
14
  end
10
15
 
11
16
  class User < LHS::Record
@@ -24,14 +29,24 @@ describe LHS::Record do
24
29
  items: [
25
30
  {
26
31
  href: 'http://datastore/users/123/places/789'
32
+ }, {
33
+ href: 'http://datastore/users/123/places/790'
27
34
  }
28
35
  ],
29
- total: 4,
36
+ total: 2,
30
37
  offset: 0,
31
38
  limit: 10
32
39
  }.to_json)
33
40
 
34
- stub_request(:get, 'http://datastore/users/123/places/789?limit=100')
41
+ stub_request(:get, 'http://datastore/users/123/places/789')
42
+ .to_return(
43
+ body: {
44
+ href: 'http://datastore/users/123/places/789?limit=100',
45
+ name: 'Mc Donalds'
46
+ }.to_json
47
+ )
48
+
49
+ stub_request(:get, 'http://datastore/users/123/places/790')
35
50
  .to_return(
36
51
  status: 404,
37
52
  body: {
@@ -51,17 +66,25 @@ describe LHS::Record do
51
66
  end
52
67
 
53
68
  context '.compact' do
54
-
55
69
  it 'removes linked resouces which could not get fetched' do
56
- expect(places.compact.length).to eq 0
57
- expect(places.length).not_to eq 0 # leaves the original intact
70
+ expect(places.compact.length).to eq 1
71
+ expect(places.length).not_to eq 1 # leaves the original intact
72
+ end
73
+ end
74
+
75
+ context 'record casting' do
76
+ let(:expected_display_name) { '*Mc Donalds*' }
77
+
78
+ it 'finds the right record class' do
79
+ expect(places.first.display_name).to eq expected_display_name
80
+ expect(places.compact.map(&:display_name)).to eq [expected_display_name]
58
81
  end
59
82
  end
60
83
 
61
84
  context '.compact!' do
62
85
  it 'removes linked resouces which could not get fetched' do
63
- expect(places.compact!.length).to eq 0
64
- expect(places.length).to eq 0 # and changes the original intact
86
+ expect(places.compact!.length).to eq 1
87
+ expect(places.length).to eq 1 # and changes the original intact
65
88
  end
66
89
  end
67
90
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHS::Record do
6
+ context 'includes all (expanded)' do
7
+ before do
8
+ class Record < LHS::Record
9
+ endpoint 'http://records/{id}'
10
+ end
11
+
12
+ stub_request(:get, "http://records/1")
13
+ .to_return(
14
+ body: {
15
+ car: { href: 'http://records/1/car' }
16
+ }.to_json
17
+ )
18
+
19
+ stub_request(:get, "http://records/1/car?color=blue&limit=100")
20
+ .to_return(
21
+ body: { href: 'http://records/cars/1' }.to_json
22
+ )
23
+
24
+ stub_request(:get, "http://records/cars/1?color=blue&limit=100")
25
+ .to_return(
26
+ body: { name: 'wrum wrum' }.to_json
27
+ )
28
+ end
29
+
30
+ it 'expands linked resources and forwards proper reference' do
31
+ record = Record.includes(:car).references(car: { params: { color: :blue } }).find(1)
32
+ expect(
33
+ record.car.name
34
+ ).to eq 'wrum wrum'
35
+ end
36
+ end
37
+ end
@@ -8,6 +8,14 @@ describe LHS::Record do
8
8
  class Customer < LHS::Record
9
9
  endpoint 'http://datastore/customers/{id}'
10
10
  end
11
+
12
+ class User < LHS::Record
13
+ endpoint 'http://datastore/users/{id}'
14
+ endpoint 'http://datastore/customers/{customer_id}/users/{id}'
15
+ def reversed_name
16
+ name.split.reverse.join(' ')
17
+ end
18
+ end
11
19
  end
12
20
 
13
21
  let!(:customer_request) do
@@ -18,6 +26,9 @@ describe LHS::Record do
18
26
  },
19
27
  'contact_addresses' => {
20
28
  'href' => "http://datastore/contact_addresses"
29
+ },
30
+ 'users' => {
31
+ 'href' => 'http://datastore/customers/1/users'
21
32
  }
22
33
  }.to_json)
23
34
  end
@@ -49,5 +60,37 @@ describe LHS::Record do
49
60
  assert_requested(electronic_addresses_request)
50
61
  assert_requested(contact_addresses_request)
51
62
  end
63
+
64
+ describe 'mapping related classes correctly' do
65
+ before do
66
+ stub_request(:get, 'http://datastore/customers/1/users?limit=100').to_return(
67
+ status: 200,
68
+ body: {
69
+ href: 'http://datastore/customers/1/users?offset=0&limit=100',
70
+ items: [
71
+ { href: 'http://datastore/customers/1/users/1' }
72
+ ],
73
+ total: 1,
74
+ offset: 0,
75
+ limit: 10
76
+ }.to_json
77
+ )
78
+
79
+ stub_request(:get, 'http://datastore/customers/1/users/1')
80
+ .with(headers: { 'Authentication' => 'Bearer 123' })
81
+ .to_return(body: { href: 'http://datastore/users/1', name: 'Elizabeth Baker' }.to_json)
82
+ end
83
+
84
+ it 'maps correctly' do
85
+ users = Customer
86
+ .includes(:users)
87
+ .references(users: referencing_options)
88
+ .find(1)
89
+ .users
90
+
91
+ expect(users.first.reversed_name).to be_present
92
+ end
93
+ end
94
+
52
95
  end
53
96
  end
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: 24.1.0.pre.1
4
+ version: 25.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-08-12 00:00:00.000000000 Z
11
+ date: 2020-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -47,7 +47,7 @@ dependencies:
47
47
  version: 12.1.1
48
48
  - - "<"
49
49
  - !ruby/object:Gem::Version
50
- version: '13'
50
+ version: '14'
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
@@ -57,7 +57,7 @@ dependencies:
57
57
  version: 12.1.1
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
- version: '13'
60
+ version: '14'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: local_uri
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -263,6 +263,7 @@ files:
263
263
  - cider-ci/task_components/rspec.yml
264
264
  - cider-ci/task_components/rubocop.yml
265
265
  - cider-ci/task_components/ruby.yml
266
+ - docs/accessing-data-in-lhs.png
266
267
  - friday.yml
267
268
  - lhs.gemspec
268
269
  - lib/lhs.rb
@@ -503,6 +504,7 @@ files:
503
504
  - spec/record/href_for_spec.rb
504
505
  - spec/record/ignore_errors_spec.rb
505
506
  - spec/record/immutable_chains_spec.rb
507
+ - spec/record/includes_expanded_spec.rb
506
508
  - spec/record/includes_first_page_spec.rb
507
509
  - spec/record/includes_spec.rb
508
510
  - spec/record/includes_warning_spec.rb
@@ -563,9 +565,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
563
565
  version: 2.3.0
564
566
  required_rubygems_version: !ruby/object:Gem::Requirement
565
567
  requirements:
566
- - - ">"
568
+ - - ">="
567
569
  - !ruby/object:Gem::Version
568
- version: 1.3.1
570
+ version: '0'
569
571
  requirements:
570
572
  - Ruby >= 2.3.0
571
573
  rubygems_version: 3.0.6
@@ -732,6 +734,7 @@ test_files:
732
734
  - spec/record/href_for_spec.rb
733
735
  - spec/record/ignore_errors_spec.rb
734
736
  - spec/record/immutable_chains_spec.rb
737
+ - spec/record/includes_expanded_spec.rb
735
738
  - spec/record/includes_first_page_spec.rb
736
739
  - spec/record/includes_spec.rb
737
740
  - spec/record/includes_warning_spec.rb