lhs 21.3.0.pre.autoauth.1 → 22.1.1.pre
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 +4 -4
- data/README.md +205 -117
- data/lhs.gemspec +1 -1
- data/lib/lhs/concerns/record/chainable.rb +4 -4
- data/lib/lhs/concerns/record/configuration.rb +23 -14
- data/lib/lhs/concerns/record/request.rb +29 -32
- data/lib/lhs/concerns/record/update.rb +17 -0
- data/lib/lhs/interceptors/auto_oauth/interceptor.rb +16 -1
- data/lib/lhs/record.rb +6 -3
- data/lib/lhs/version.rb +1 -1
- data/spec/auto_oauth_spec.rb +141 -23
- data/spec/dummy/app/controllers/application_controller.rb +9 -1
- data/spec/dummy/app/controllers/automatic_authentication_controller.rb +18 -0
- data/spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb +6 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb +7 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb +7 -0
- data/spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb +6 -0
- data/spec/dummy/app/models/providers/internal_services.rb +7 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/item/destroy_spec.rb +1 -1
- data/spec/proxy/record_identification_spec.rb +1 -1
- data/spec/record/all_spec.rb +1 -1
- data/spec/record/endpoints_spec.rb +1 -1
- data/spec/record/handle_includes_errors_spec.rb +1 -1
- data/spec/record/has_many_spec.rb +1 -1
- data/spec/record/has_one_spec.rb +1 -1
- data/spec/record/includes_first_page_spec.rb +727 -0
- data/spec/record/includes_spec.rb +545 -579
- data/spec/record/includes_warning_spec.rb +1 -1
- data/spec/record/mapping_spec.rb +2 -2
- data/spec/record/references_spec.rb +1 -1
- data/spec/record/relation_caching_spec.rb +3 -3
- data/spec/record/update_spec.rb +62 -0
- metadata +21 -10
- data/spec/dummy/config/initializers/lhs.rb +0 -3
- data/spec/record/includes_all_spec.rb +0 -693
@@ -37,7 +37,7 @@ describe LHS::Record do
|
|
37
37
|
|
38
38
|
it 'warns if linked data was simply included but is paginated' do
|
39
39
|
expect(lambda {
|
40
|
-
Customer.
|
40
|
+
Customer.includes_first_page(:contracts).find(1)
|
41
41
|
}).to output(
|
42
42
|
%r{\[WARNING\] You included `http://datastore/customers/1/contracts`, 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\)\.}
|
43
43
|
).to_stderr
|
data/spec/record/mapping_spec.rb
CHANGED
@@ -75,7 +75,7 @@ describe LHS::Record do
|
|
75
75
|
status: 200, body: { 'href' => preceding_agb_url }.to_json, headers: {}
|
76
76
|
)
|
77
77
|
|
78
|
-
agb = Agb.
|
78
|
+
agb = Agb.includes_first_page(:preceding_agb).first!
|
79
79
|
expect(agb.pdf_url).to be == 'de'
|
80
80
|
end
|
81
81
|
|
@@ -94,7 +94,7 @@ describe LHS::Record do
|
|
94
94
|
stub_request(:get, "#{datastore}/favorites/1")
|
95
95
|
.to_return(body: { local_entry: { href: "#{datastore}/local-entries/1" } }.to_json)
|
96
96
|
|
97
|
-
favorite = Favorite.
|
97
|
+
favorite = Favorite.includes_first_page(:local_entry).find(1)
|
98
98
|
expect(favorite.local_entry).to be_kind_of LocalEntry
|
99
99
|
expect(favorite.local_entry.name).to eq 'local.ch'
|
100
100
|
end
|
@@ -40,7 +40,7 @@ describe LHS::Record do
|
|
40
40
|
|
41
41
|
it 'uses the "references" hash for all symbols of the "including" array' do
|
42
42
|
Customer
|
43
|
-
.
|
43
|
+
.includes_first_page(:electronic_addresses, :contact_addresses)
|
44
44
|
.references(
|
45
45
|
electronic_addresses: referencing_options,
|
46
46
|
contact_addresses: referencing_options
|
@@ -92,7 +92,7 @@ describe LHS::Record do
|
|
92
92
|
.to_return(body: place_hash.to_json)
|
93
93
|
place = Place
|
94
94
|
.options(auth: { bearer: 'XYZ' })
|
95
|
-
.
|
95
|
+
.includes(:available_assets)
|
96
96
|
.find(place_id)
|
97
97
|
expect(place.available_assets.first).to be_a(AvailableAsset)
|
98
98
|
end
|
@@ -102,7 +102,7 @@ describe LHS::Record do
|
|
102
102
|
.to_return(body: place_hash.to_json)
|
103
103
|
place = Place
|
104
104
|
.options(auth: { bearer: 'XYZ' })
|
105
|
-
.
|
105
|
+
.includes(:available_assets)
|
106
106
|
.where(id: place_id)
|
107
107
|
expect(place.available_assets.first).to be_a(AvailableAsset)
|
108
108
|
end
|
@@ -112,7 +112,7 @@ describe LHS::Record do
|
|
112
112
|
.to_return(body: place_hash.to_json)
|
113
113
|
place = Place
|
114
114
|
.options(auth: { bearer: 'XYZ' })
|
115
|
-
.
|
115
|
+
.includes(:available_assets)
|
116
116
|
.find_by(id: place_id)
|
117
117
|
expect(place.available_assets.first).to be_a(AvailableAsset)
|
118
118
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
describe LHS::Record do
|
6
|
+
context 'update' do
|
7
|
+
|
8
|
+
before do
|
9
|
+
class Record < LHS::Record
|
10
|
+
endpoint 'http://datastore/records/{id}'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows to directly update a record without fetching it first' do
|
15
|
+
stub_request(:post, "http://datastore/records/123")
|
16
|
+
.with(body: { name: 'Steve' }.to_json)
|
17
|
+
.to_return(status: 200, body: {}.to_json)
|
18
|
+
|
19
|
+
Record.update(
|
20
|
+
id: '123',
|
21
|
+
name: 'Steve'
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'does not fail during an error with update' do
|
26
|
+
stub_request(:post, "http://datastore/records/123")
|
27
|
+
.with(body: { name: 'Steve' }.to_json)
|
28
|
+
.to_return(status: 404, body: {}.to_json)
|
29
|
+
|
30
|
+
record = Record.update(
|
31
|
+
id: '123',
|
32
|
+
name: 'Steve'
|
33
|
+
)
|
34
|
+
|
35
|
+
expect(record.errors.status_code).to eq 404
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'allows to directly update! a record without fetching it first' do
|
39
|
+
stub_request(:post, "http://datastore/records/123")
|
40
|
+
.with(body: { name: 'Steve' }.to_json)
|
41
|
+
.to_return(status: 200)
|
42
|
+
|
43
|
+
Record.update!(
|
44
|
+
id: '123',
|
45
|
+
name: 'Steve'
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises an error when trying to update! but retrieving an error status' do
|
50
|
+
stub_request(:post, "http://datastore/records/123")
|
51
|
+
.with(body: { name: 'Steve' }.to_json)
|
52
|
+
.to_return(status: 404)
|
53
|
+
|
54
|
+
expect(-> {
|
55
|
+
Record.update!(
|
56
|
+
id: '123',
|
57
|
+
name: 'Steve'
|
58
|
+
)
|
59
|
+
}).to raise_error(LHC::NotFound)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
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:
|
4
|
+
version: 22.1.1.pre
|
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-
|
11
|
+
date: 2020-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -146,16 +146,16 @@ dependencies:
|
|
146
146
|
name: rollbar
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
|
-
- - "
|
149
|
+
- - "<="
|
150
150
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
151
|
+
version: 2.24.0
|
152
152
|
type: :development
|
153
153
|
prerelease: false
|
154
154
|
version_requirements: !ruby/object:Gem::Requirement
|
155
155
|
requirements:
|
156
|
-
- - "
|
156
|
+
- - "<="
|
157
157
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
158
|
+
version: 2.24.0
|
159
159
|
- !ruby/object:Gem::Dependency
|
160
160
|
name: rspec-rails
|
161
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -312,6 +312,7 @@ files:
|
|
312
312
|
- lib/lhs/concerns/record/request.rb
|
313
313
|
- lib/lhs/concerns/record/scope.rb
|
314
314
|
- lib/lhs/concerns/record/tracing.rb
|
315
|
+
- lib/lhs/concerns/record/update.rb
|
315
316
|
- lib/lhs/config.rb
|
316
317
|
- lib/lhs/data.rb
|
317
318
|
- lib/lhs/endpoint.rb
|
@@ -388,9 +389,14 @@ files:
|
|
388
389
|
- spec/dummy/app/models/concerns/.keep
|
389
390
|
- spec/dummy/app/models/dummy_customer.rb
|
390
391
|
- spec/dummy/app/models/dummy_record.rb
|
392
|
+
- spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb
|
393
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb
|
394
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb
|
395
|
+
- spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb
|
391
396
|
- spec/dummy/app/models/dummy_record_with_oauth.rb
|
392
397
|
- spec/dummy/app/models/dummy_user.rb
|
393
398
|
- spec/dummy/app/models/providers/customer_system.rb
|
399
|
+
- spec/dummy/app/models/providers/internal_services.rb
|
394
400
|
- spec/dummy/app/views/error_handling_with_chains/error.html.erb
|
395
401
|
- spec/dummy/app/views/error_handling_with_chains/show.html.erb
|
396
402
|
- spec/dummy/app/views/form_for.html.erb
|
@@ -410,7 +416,6 @@ files:
|
|
410
416
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
411
417
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
412
418
|
- spec/dummy/config/initializers/inflections.rb
|
413
|
-
- spec/dummy/config/initializers/lhs.rb
|
414
419
|
- spec/dummy/config/initializers/mime_types.rb
|
415
420
|
- spec/dummy/config/initializers/rollbar.rb
|
416
421
|
- spec/dummy/config/initializers/session_store.rb
|
@@ -496,7 +501,7 @@ files:
|
|
496
501
|
- spec/record/href_for_spec.rb
|
497
502
|
- spec/record/ignore_errors_spec.rb
|
498
503
|
- spec/record/immutable_chains_spec.rb
|
499
|
-
- spec/record/
|
504
|
+
- spec/record/includes_first_page_spec.rb
|
500
505
|
- spec/record/includes_spec.rb
|
501
506
|
- spec/record/includes_warning_spec.rb
|
502
507
|
- spec/record/item_key_spec.rb
|
@@ -526,6 +531,7 @@ files:
|
|
526
531
|
- spec/record/to_hash_spec.rb
|
527
532
|
- spec/record/to_json_spec.rb
|
528
533
|
- spec/record/tracing_spec.rb
|
534
|
+
- spec/record/update_spec.rb
|
529
535
|
- spec/record/where_chains_spec.rb
|
530
536
|
- spec/record/where_spec.rb
|
531
537
|
- spec/record/where_values_hash_spec.rb
|
@@ -611,9 +617,14 @@ test_files:
|
|
611
617
|
- spec/dummy/app/models/concerns/.keep
|
612
618
|
- spec/dummy/app/models/dummy_customer.rb
|
613
619
|
- spec/dummy/app/models/dummy_record.rb
|
620
|
+
- spec/dummy/app/models/dummy_record_with_auto_oauth_provider.rb
|
621
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers1.rb
|
622
|
+
- spec/dummy/app/models/dummy_record_with_multiple_oauth_providers2.rb
|
623
|
+
- spec/dummy/app/models/dummy_record_with_multiple_providers_per_endpoint.rb
|
614
624
|
- spec/dummy/app/models/dummy_record_with_oauth.rb
|
615
625
|
- spec/dummy/app/models/dummy_user.rb
|
616
626
|
- spec/dummy/app/models/providers/customer_system.rb
|
627
|
+
- spec/dummy/app/models/providers/internal_services.rb
|
617
628
|
- spec/dummy/app/views/error_handling_with_chains/error.html.erb
|
618
629
|
- spec/dummy/app/views/error_handling_with_chains/show.html.erb
|
619
630
|
- spec/dummy/app/views/form_for.html.erb
|
@@ -633,7 +644,6 @@ test_files:
|
|
633
644
|
- spec/dummy/config/initializers/cookies_serializer.rb
|
634
645
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
635
646
|
- spec/dummy/config/initializers/inflections.rb
|
636
|
-
- spec/dummy/config/initializers/lhs.rb
|
637
647
|
- spec/dummy/config/initializers/mime_types.rb
|
638
648
|
- spec/dummy/config/initializers/rollbar.rb
|
639
649
|
- spec/dummy/config/initializers/session_store.rb
|
@@ -719,7 +729,7 @@ test_files:
|
|
719
729
|
- spec/record/href_for_spec.rb
|
720
730
|
- spec/record/ignore_errors_spec.rb
|
721
731
|
- spec/record/immutable_chains_spec.rb
|
722
|
-
- spec/record/
|
732
|
+
- spec/record/includes_first_page_spec.rb
|
723
733
|
- spec/record/includes_spec.rb
|
724
734
|
- spec/record/includes_warning_spec.rb
|
725
735
|
- spec/record/item_key_spec.rb
|
@@ -749,6 +759,7 @@ test_files:
|
|
749
759
|
- spec/record/to_hash_spec.rb
|
750
760
|
- spec/record/to_json_spec.rb
|
751
761
|
- spec/record/tracing_spec.rb
|
762
|
+
- spec/record/update_spec.rb
|
752
763
|
- spec/record/where_chains_spec.rb
|
753
764
|
- spec/record/where_spec.rb
|
754
765
|
- spec/record/where_values_hash_spec.rb
|
@@ -1,693 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rails_helper'
|
4
|
-
|
5
|
-
describe LHS::Record do
|
6
|
-
context 'includes all' do
|
7
|
-
before do
|
8
|
-
class Customer < LHS::Record
|
9
|
-
endpoint 'http://datastore/customers/{id}'
|
10
|
-
end
|
11
|
-
|
12
|
-
class User < LHS::Record
|
13
|
-
configuration pagination_strategy: 'link'
|
14
|
-
endpoint 'http://datastore/users'
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:amount_of_contracts) { 33 }
|
19
|
-
let(:amount_of_products) { 22 }
|
20
|
-
let(:amount_of_users_1st_page) { 10 }
|
21
|
-
let(:amount_of_users_2nd_page) { 3 }
|
22
|
-
let(:amount_of_users) { amount_of_users_1st_page + amount_of_users_2nd_page }
|
23
|
-
|
24
|
-
let!(:customer_request) do
|
25
|
-
stub_request(:get, 'http://datastore/customers/1')
|
26
|
-
.to_return(
|
27
|
-
body: {
|
28
|
-
contracts: { href: 'http://datastore/customers/1/contracts' },
|
29
|
-
users: { href: 'http://datastore/users?limit=10' }
|
30
|
-
}.to_json
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
#
|
35
|
-
# Contracts
|
36
|
-
#
|
37
|
-
|
38
|
-
let!(:contracts_request) do
|
39
|
-
stub_request(:get, "http://datastore/customers/1/contracts?limit=100")
|
40
|
-
.to_return(
|
41
|
-
body: {
|
42
|
-
items: 10.times.map do
|
43
|
-
{
|
44
|
-
products: { href: 'http://datastore/products' }
|
45
|
-
}
|
46
|
-
end,
|
47
|
-
limit: 10,
|
48
|
-
offset: 0,
|
49
|
-
total: amount_of_contracts
|
50
|
-
}.to_json
|
51
|
-
)
|
52
|
-
end
|
53
|
-
|
54
|
-
def additional_contracts_request(offset, amount)
|
55
|
-
stub_request(:get, "http://datastore/customers/1/contracts?limit=10&offset=#{offset}")
|
56
|
-
.to_return(
|
57
|
-
body: {
|
58
|
-
items: amount.times.map do
|
59
|
-
{
|
60
|
-
products: { href: 'http://datastore/products' }
|
61
|
-
}
|
62
|
-
end,
|
63
|
-
limit: 10,
|
64
|
-
offset: offset,
|
65
|
-
total: amount_of_contracts
|
66
|
-
}.to_json
|
67
|
-
)
|
68
|
-
end
|
69
|
-
|
70
|
-
let!(:contracts_request_page_2) do
|
71
|
-
additional_contracts_request(10, 10)
|
72
|
-
end
|
73
|
-
|
74
|
-
let!(:contracts_request_page_3) do
|
75
|
-
additional_contracts_request(20, 10)
|
76
|
-
end
|
77
|
-
|
78
|
-
let!(:contracts_request_page_4) do
|
79
|
-
additional_contracts_request(30, 3)
|
80
|
-
end
|
81
|
-
|
82
|
-
#
|
83
|
-
# Products
|
84
|
-
#
|
85
|
-
|
86
|
-
let!(:products_request) do
|
87
|
-
stub_request(:get, "http://datastore/products?limit=100")
|
88
|
-
.to_return(
|
89
|
-
body: {
|
90
|
-
items: 10.times.map do
|
91
|
-
{ name: 'LBC' }
|
92
|
-
end,
|
93
|
-
limit: 10,
|
94
|
-
offset: 0,
|
95
|
-
total: amount_of_products
|
96
|
-
}.to_json
|
97
|
-
)
|
98
|
-
end
|
99
|
-
|
100
|
-
def additional_products_request(offset, amount)
|
101
|
-
stub_request(:get, "http://datastore/products?limit=10&offset=#{offset}")
|
102
|
-
.to_return(
|
103
|
-
body: {
|
104
|
-
items: amount.times.map do
|
105
|
-
{ name: 'LBC' }
|
106
|
-
end,
|
107
|
-
limit: 10,
|
108
|
-
offset: offset,
|
109
|
-
total: amount_of_products
|
110
|
-
}.to_json
|
111
|
-
)
|
112
|
-
end
|
113
|
-
|
114
|
-
let!(:products_request_page_2) do
|
115
|
-
additional_products_request(10, 10)
|
116
|
-
end
|
117
|
-
|
118
|
-
let!(:products_request_page_3) do
|
119
|
-
additional_products_request(20, 2)
|
120
|
-
end
|
121
|
-
|
122
|
-
#
|
123
|
-
# Users
|
124
|
-
#
|
125
|
-
|
126
|
-
let!(:users_request) do
|
127
|
-
stub_request(:get, 'http://datastore/users?limit=10')
|
128
|
-
.to_return(
|
129
|
-
body: {
|
130
|
-
items: amount_of_users_1st_page.times.map do
|
131
|
-
{ name: 'Hans Muster' }
|
132
|
-
end,
|
133
|
-
limit: 10,
|
134
|
-
next: { href: 'http://datastore/users?for_user_id=10&limit=10' }
|
135
|
-
}.to_json
|
136
|
-
)
|
137
|
-
end
|
138
|
-
|
139
|
-
let!(:users_request_page_2) do
|
140
|
-
stub_request(:get, 'http://datastore/users?for_user_id=10&limit=10')
|
141
|
-
.to_return(
|
142
|
-
body: {
|
143
|
-
items: amount_of_users_2nd_page.times.map do
|
144
|
-
{ name: 'Lisa Müller' }
|
145
|
-
end,
|
146
|
-
limit: 10,
|
147
|
-
next: { href: 'http://datastore/users?for_user_id=13&limit=10' }
|
148
|
-
}.to_json
|
149
|
-
)
|
150
|
-
end
|
151
|
-
|
152
|
-
let!(:users_request_page_3) do
|
153
|
-
stub_request(:get, 'http://datastore/users?for_user_id=13&limit=10')
|
154
|
-
.to_return(
|
155
|
-
body: {
|
156
|
-
items: [],
|
157
|
-
limit: 10
|
158
|
-
}.to_json
|
159
|
-
)
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'includes all linked business objects no matter pagination' do
|
163
|
-
customer = nil
|
164
|
-
|
165
|
-
expect(lambda do
|
166
|
-
customer = Customer
|
167
|
-
.includes_all(:users, contracts: :products)
|
168
|
-
.find(1)
|
169
|
-
end).to output(
|
170
|
-
%r{\[WARNING\] You are loading all pages from a resource paginated with links only. As this is performed sequentially, it can result in very poor performance! \(https://github.com/local-ch/lhs#pagination-strategy-link\).}
|
171
|
-
).to_stderr
|
172
|
-
|
173
|
-
expect(customer.users.length).to eq amount_of_users
|
174
|
-
expect(customer.contracts.length).to eq amount_of_contracts
|
175
|
-
expect(customer.contracts.first.products.length).to eq amount_of_products
|
176
|
-
expect(customer_request).to have_been_requested.at_least_once
|
177
|
-
expect(contracts_request).to have_been_requested.at_least_once
|
178
|
-
expect(contracts_request_page_2).to have_been_requested.at_least_once
|
179
|
-
expect(contracts_request_page_3).to have_been_requested.at_least_once
|
180
|
-
expect(contracts_request_page_4).to have_been_requested.at_least_once
|
181
|
-
expect(products_request).to have_been_requested.at_least_once
|
182
|
-
expect(products_request_page_2).to have_been_requested.at_least_once
|
183
|
-
expect(products_request_page_3).to have_been_requested.at_least_once
|
184
|
-
expect(users_request).to have_been_requested.at_least_once
|
185
|
-
expect(users_request_page_2).to have_been_requested.at_least_once
|
186
|
-
expect(users_request_page_3).to have_been_requested.at_least_once
|
187
|
-
end
|
188
|
-
|
189
|
-
context 'links already contain pagination parameters' do
|
190
|
-
let!(:customer_request) do
|
191
|
-
stub_request(:get, 'http://datastore/customers/1')
|
192
|
-
.to_return(
|
193
|
-
body: {
|
194
|
-
contracts: { href: 'http://datastore/customers/1/contracts?limit=5&offset=0' }
|
195
|
-
}.to_json
|
196
|
-
)
|
197
|
-
end
|
198
|
-
|
199
|
-
let!(:contracts_request) do
|
200
|
-
stub_request(:get, "http://datastore/customers/1/contracts?limit=100")
|
201
|
-
.to_return(
|
202
|
-
body: {
|
203
|
-
items: 10.times.map do
|
204
|
-
{
|
205
|
-
products: { href: 'http://datastore/products' }
|
206
|
-
}
|
207
|
-
end,
|
208
|
-
limit: 10,
|
209
|
-
offset: 0,
|
210
|
-
total: amount_of_contracts
|
211
|
-
}.to_json
|
212
|
-
)
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'overwrites existing pagination paramters if they are already contained in a string' do
|
216
|
-
expect(LHC).to receive(:request)
|
217
|
-
.with(url: "http://datastore/customers/1").and_call_original
|
218
|
-
|
219
|
-
expect(LHC).to receive(:request)
|
220
|
-
.with(url: "http://datastore/customers/1/contracts",
|
221
|
-
all: true,
|
222
|
-
params: { limit: 100 }).and_call_original
|
223
|
-
|
224
|
-
expect(LHC).to receive(:request)
|
225
|
-
.with([{ url: "http://datastore/customers/1/contracts",
|
226
|
-
all: true,
|
227
|
-
params: { limit: 10, offset: 10 } },
|
228
|
-
{ url: "http://datastore/customers/1/contracts",
|
229
|
-
all: true,
|
230
|
-
params: { limit: 10, offset: 20 } },
|
231
|
-
{ url: "http://datastore/customers/1/contracts",
|
232
|
-
all: true,
|
233
|
-
params: { limit: 10, offset: 30 } }]).and_call_original
|
234
|
-
|
235
|
-
customer = Customer
|
236
|
-
.includes_all(:contracts)
|
237
|
-
.find(1)
|
238
|
-
expect(customer.contracts.length).to eq amount_of_contracts
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
context 'includes for an empty array' do
|
243
|
-
before do
|
244
|
-
class Contract < LHS::Record
|
245
|
-
endpoint 'http://datastore/contracts/{id}'
|
246
|
-
end
|
247
|
-
stub_request(:get, %r{http://datastore/contracts/\d})
|
248
|
-
.to_return(body: {
|
249
|
-
options: nested_resources
|
250
|
-
}.to_json)
|
251
|
-
end
|
252
|
-
|
253
|
-
context 'empty array' do
|
254
|
-
let(:nested_resources) { [] }
|
255
|
-
|
256
|
-
it 'includes_all in case of an empty array' do
|
257
|
-
expect(
|
258
|
-
-> { Contract.includes(:product).includes_all(:options).find(1) }
|
259
|
-
).not_to raise_error
|
260
|
-
expect(
|
261
|
-
-> { Contract.includes(:product).includes_all(:options).find(1, 2) }
|
262
|
-
).not_to raise_error
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
context 'weird array without hrefs' do
|
267
|
-
before do
|
268
|
-
stub_request(:get, "http://datastore/options/1?limit=100")
|
269
|
-
.to_return(body: { type: 'REACH_EXT' }.to_json)
|
270
|
-
end
|
271
|
-
|
272
|
-
let(:nested_resources) { [{ href: 'http://datastore/options/1' }, { type: 'E_COMMERCE' }] }
|
273
|
-
|
274
|
-
it 'includes_all in case of an unexpect objects within array' do
|
275
|
-
expect(
|
276
|
-
-> { Contract.includes(:product).includes_all(:options).find(1) }
|
277
|
-
).not_to raise_error
|
278
|
-
expect(
|
279
|
-
-> { Contract.includes(:product).includes_all(:options).find(1, 2) }
|
280
|
-
).not_to raise_error
|
281
|
-
end
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
context 'include a known/identifiable record' do
|
286
|
-
before do
|
287
|
-
class Contract < LHS::Record
|
288
|
-
endpoint 'http://datastore/contracts/{id}'
|
289
|
-
end
|
290
|
-
|
291
|
-
class Entry < LHS::Record
|
292
|
-
endpoint '{+datastore}/entry/v1/{id}.json'
|
293
|
-
end
|
294
|
-
|
295
|
-
LHC.config.placeholder(:datastore, 'http://datastore')
|
296
|
-
end
|
297
|
-
|
298
|
-
let!(:customer_request) do
|
299
|
-
stub_request(:get, %r{http://datastore/customers/\d+})
|
300
|
-
.to_return(
|
301
|
-
body: {
|
302
|
-
contracts: [{ href: 'http://datastore/contracts/1' }, { href: 'http://datastore/contracts/2' }]
|
303
|
-
}.to_json
|
304
|
-
)
|
305
|
-
end
|
306
|
-
|
307
|
-
let!(:contracts_request) do
|
308
|
-
stub_request(:get, %r{http://datastore/contracts/\d+})
|
309
|
-
.to_return(
|
310
|
-
body: {
|
311
|
-
type: 'contract',
|
312
|
-
entry: { href: 'http://datastore/entry/v1/1.json' }
|
313
|
-
}.to_json
|
314
|
-
)
|
315
|
-
end
|
316
|
-
|
317
|
-
let!(:entry_request) do
|
318
|
-
stub_request(:get, %r{http://datastore/entry/v1/\d+.json})
|
319
|
-
.to_return(
|
320
|
-
body: {
|
321
|
-
name: 'Casa Ferlin'
|
322
|
-
}.to_json
|
323
|
-
)
|
324
|
-
end
|
325
|
-
|
326
|
-
it 'loads included identifiable records without raising exceptions' do
|
327
|
-
customer = Customer.includes_all(contracts: :entry).find(1, 2).first
|
328
|
-
expect(customer.contracts.first.href).to eq 'http://datastore/contracts/1'
|
329
|
-
expect(customer.contracts.first.type).to eq 'contract'
|
330
|
-
expect(customer.contracts.first.entry.name).to eq 'Casa Ferlin'
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
context 'includes all for parallel loaded ids' do
|
335
|
-
before do
|
336
|
-
class Place < LHS::Record
|
337
|
-
endpoint 'http://datastore/places/{id}'
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
let!(:place_request_1) do
|
342
|
-
stub_request(:get, %r{http://datastore/places/1})
|
343
|
-
.to_return(
|
344
|
-
body: {
|
345
|
-
category_relations: [
|
346
|
-
{ href: 'http://datastore/category_relations/1' },
|
347
|
-
{ href: 'http://datastore/category_relations/2' }
|
348
|
-
]
|
349
|
-
}.to_json
|
350
|
-
)
|
351
|
-
end
|
352
|
-
|
353
|
-
let!(:place_request_2) do
|
354
|
-
stub_request(:get, %r{http://datastore/places/2})
|
355
|
-
.to_return(
|
356
|
-
body: {
|
357
|
-
category_relations: []
|
358
|
-
}.to_json
|
359
|
-
)
|
360
|
-
end
|
361
|
-
|
362
|
-
let!(:place_request_3) do
|
363
|
-
stub_request(:get, %r{http://datastore/places/3})
|
364
|
-
.to_return(
|
365
|
-
body: {
|
366
|
-
category_relations: [
|
367
|
-
{ href: 'http://datastore/category_relations/1' },
|
368
|
-
{ href: 'http://datastore/category_relations/3' }
|
369
|
-
]
|
370
|
-
}.to_json
|
371
|
-
)
|
372
|
-
end
|
373
|
-
|
374
|
-
let!(:category_relation_request_1) do
|
375
|
-
stub_request(:get, %r{http://datastore/category_relations/1})
|
376
|
-
.to_return(
|
377
|
-
body: {
|
378
|
-
name: "Category 1"
|
379
|
-
}.to_json
|
380
|
-
)
|
381
|
-
end
|
382
|
-
|
383
|
-
let!(:category_relation_request_2) do
|
384
|
-
stub_request(:get, %r{http://datastore/category_relations/2})
|
385
|
-
.to_return(
|
386
|
-
body: {
|
387
|
-
name: "Category 2"
|
388
|
-
}.to_json
|
389
|
-
)
|
390
|
-
end
|
391
|
-
|
392
|
-
let!(:category_relation_request_3) do
|
393
|
-
stub_request(:get, %r{http://datastore/category_relations/3})
|
394
|
-
.to_return(
|
395
|
-
body: {
|
396
|
-
name: "Category 3"
|
397
|
-
}.to_json
|
398
|
-
)
|
399
|
-
end
|
400
|
-
|
401
|
-
let(:category_name) { 'Category Relation' }
|
402
|
-
|
403
|
-
it 'requests places in parallel and includes category relation' do
|
404
|
-
places = Place.includes_all(:category_relations).find(1, 2, 3)
|
405
|
-
expect(places[0].category_relations[0].name).to eq 'Category 1'
|
406
|
-
expect(places[0].category_relations[1].name).to eq 'Category 2'
|
407
|
-
expect(places[2].category_relations[0].name).to eq 'Category 1'
|
408
|
-
expect(places[2].category_relations[1].name).to eq 'Category 3'
|
409
|
-
end
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
context 'Linked resources' do
|
414
|
-
before do
|
415
|
-
stub_request(:get, 'http://datastore/places/1/contracts?offset=0&limit=10')
|
416
|
-
.to_return(
|
417
|
-
body: {
|
418
|
-
href: "http://datastore/v2/places/1/contracts?offset=0&limit=10",
|
419
|
-
items: [{ href: "http://datastore/v2/contracts/1" }],
|
420
|
-
offset: 0,
|
421
|
-
limit: 10,
|
422
|
-
total: 10
|
423
|
-
}.to_json
|
424
|
-
)
|
425
|
-
|
426
|
-
stub_request(:get, "http://datastore/v2/contracts/1")
|
427
|
-
.to_return(
|
428
|
-
body: {
|
429
|
-
customer: { name: 'Swisscom Directories AG' }
|
430
|
-
}.to_json
|
431
|
-
)
|
432
|
-
|
433
|
-
stub_request(:get, 'http://datastore/places/1?limit=1')
|
434
|
-
.to_return(
|
435
|
-
body: { href: 'http://datastore/places/1', contracts: { href: 'http://datastore/places/1/contracts?offset=0&limit=10' } }.to_json
|
436
|
-
)
|
437
|
-
|
438
|
-
class Place < LHS::Record
|
439
|
-
endpoint 'http://datastore/places/{id}'
|
440
|
-
end
|
441
|
-
|
442
|
-
class Contract < LHS::Record
|
443
|
-
endpoint 'http://datastore/places/{place_id}/contracts'
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
it 'does not use the root record endpoints when including nested records' do
|
448
|
-
place = Place
|
449
|
-
.includes_all(:contracts)
|
450
|
-
.find_by(id: 1)
|
451
|
-
expect(place.contracts.first.customer.name).to eq 'Swisscom Directories AG'
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
context 'nested includes_all' do
|
456
|
-
context 'with optional children' do
|
457
|
-
|
458
|
-
let(:favorites_request_stub) do
|
459
|
-
stub_request(:get, %r{http://datastore/favorites})
|
460
|
-
.to_return(
|
461
|
-
body: {
|
462
|
-
items: [{
|
463
|
-
href: "http://datastore/favorites/1",
|
464
|
-
place: {
|
465
|
-
href: "http://datastore/places/1"
|
466
|
-
}
|
467
|
-
}, {
|
468
|
-
href: "http://datastore/favorite/2",
|
469
|
-
place: {
|
470
|
-
href: "http://datastore/places/2"
|
471
|
-
}
|
472
|
-
}, {
|
473
|
-
href: "http://datastore/favorite/3",
|
474
|
-
place: {
|
475
|
-
href: "http://datastore/places/3"
|
476
|
-
}
|
477
|
-
}],
|
478
|
-
total: 3,
|
479
|
-
offset: 0,
|
480
|
-
limit: 100
|
481
|
-
}.to_json
|
482
|
-
)
|
483
|
-
end
|
484
|
-
|
485
|
-
let(:place1_request_stub) do
|
486
|
-
stub_request(:get, %r{http://datastore/places/1})
|
487
|
-
.to_return(
|
488
|
-
body: {
|
489
|
-
href: "http://datastore/places/1",
|
490
|
-
name: 'Place 1',
|
491
|
-
contracts: {
|
492
|
-
href: "http://datastore/places/1/contracts"
|
493
|
-
}
|
494
|
-
}.to_json
|
495
|
-
)
|
496
|
-
end
|
497
|
-
|
498
|
-
let(:place2_request_stub) do
|
499
|
-
stub_request(:get, %r{http://datastore/places/2})
|
500
|
-
.to_return(
|
501
|
-
body: {
|
502
|
-
href: "http://datastore/places/2",
|
503
|
-
name: 'Place 2'
|
504
|
-
}.to_json
|
505
|
-
)
|
506
|
-
end
|
507
|
-
|
508
|
-
let(:place3_request_stub) do
|
509
|
-
stub_request(:get, %r{http://datastore/places/3})
|
510
|
-
.to_return(
|
511
|
-
body: {
|
512
|
-
href: "http://datastore/places/3",
|
513
|
-
name: 'Place 3',
|
514
|
-
contracts: {
|
515
|
-
href: "http://datastore/places/3/contracts"
|
516
|
-
}
|
517
|
-
}.to_json
|
518
|
-
)
|
519
|
-
end
|
520
|
-
|
521
|
-
let(:contracts_request_for_place1_stub) do
|
522
|
-
stub_request(:get, %r{http://datastore/places/1/contracts})
|
523
|
-
.to_return(
|
524
|
-
body: {
|
525
|
-
items: [{
|
526
|
-
href: "http://datastore/places/1/contracts/1",
|
527
|
-
name: 'Contract 1'
|
528
|
-
}],
|
529
|
-
total: 1,
|
530
|
-
offset: 0,
|
531
|
-
limit: 10
|
532
|
-
}.to_json
|
533
|
-
)
|
534
|
-
end
|
535
|
-
|
536
|
-
let(:contracts_request_for_place3_stub) do
|
537
|
-
stub_request(:get, %r{http://datastore/places/3/contracts})
|
538
|
-
.to_return(
|
539
|
-
body: {
|
540
|
-
items: [{
|
541
|
-
href: "http://datastore/places/3/contracts/1",
|
542
|
-
name: 'Contract 3'
|
543
|
-
}],
|
544
|
-
total: 1,
|
545
|
-
offset: 0,
|
546
|
-
limit: 10
|
547
|
-
}.to_json
|
548
|
-
)
|
549
|
-
end
|
550
|
-
|
551
|
-
before do
|
552
|
-
class Favorite < LHS::Record
|
553
|
-
endpoint 'http://datastore/favorites'
|
554
|
-
end
|
555
|
-
|
556
|
-
class Place < LHS::Record
|
557
|
-
endpoint 'http://datastore/places/{id}'
|
558
|
-
end
|
559
|
-
|
560
|
-
class Contract < LHS::Record
|
561
|
-
endpoint 'http://datastore/places/{place_id}/contracts'
|
562
|
-
end
|
563
|
-
|
564
|
-
favorites_request_stub
|
565
|
-
place1_request_stub
|
566
|
-
place2_request_stub
|
567
|
-
place3_request_stub
|
568
|
-
contracts_request_for_place1_stub
|
569
|
-
contracts_request_for_place3_stub
|
570
|
-
end
|
571
|
-
|
572
|
-
it 'includes nested objects when they exist' do
|
573
|
-
favorites = Favorite.includes(:place).includes_all(place: :contracts).all
|
574
|
-
|
575
|
-
expect(favorites.first.place.name).to eq('Place 1')
|
576
|
-
expect(favorites.first.place.contracts.first.name).to eq('Contract 1')
|
577
|
-
end
|
578
|
-
|
579
|
-
it 'does not include nested objects when they are not there' do
|
580
|
-
favorites = Favorite.includes(:place).includes_all(place: :contracts).all
|
581
|
-
|
582
|
-
expect(favorites[1].place.name).to eq('Place 2')
|
583
|
-
expect(favorites[1].place.contracts).to be(nil)
|
584
|
-
end
|
585
|
-
|
586
|
-
it 'does include and merges objects after nil objects in collections' do
|
587
|
-
favorites = Favorite.includes(:place).includes_all(place: :contracts).all
|
588
|
-
|
589
|
-
expect(favorites.last.place.name).to eq('Place 3')
|
590
|
-
expect(favorites.last.place.contracts.first.name).to eq('Contract 3')
|
591
|
-
end
|
592
|
-
end
|
593
|
-
end
|
594
|
-
|
595
|
-
context 'includes collection trough single item' do
|
596
|
-
|
597
|
-
before do
|
598
|
-
class Place < LHS::Record
|
599
|
-
endpoint 'https://places/{id}'
|
600
|
-
end
|
601
|
-
|
602
|
-
stub_request(:get, 'https://places/1')
|
603
|
-
.to_return(
|
604
|
-
body: {
|
605
|
-
customer: { href: 'https://customers/1' }
|
606
|
-
}.to_json
|
607
|
-
)
|
608
|
-
|
609
|
-
stub_request(:get, 'https://customers/1?limit=100')
|
610
|
-
.to_return(
|
611
|
-
body: {
|
612
|
-
addresses: { 'href': 'https://customer/1/addresses' }
|
613
|
-
}.to_json
|
614
|
-
)
|
615
|
-
|
616
|
-
stub_request(:get, 'https://customer/1/addresses?limit=100')
|
617
|
-
.to_return(
|
618
|
-
body: {
|
619
|
-
items: [
|
620
|
-
{ city: 'Zurich', no: 1 },
|
621
|
-
{ city: 'Zurich', no: 2 }
|
622
|
-
],
|
623
|
-
total: 2
|
624
|
-
}.to_json
|
625
|
-
)
|
626
|
-
end
|
627
|
-
|
628
|
-
it 'includes a collection trough a single item without exceptions' do
|
629
|
-
place = Place
|
630
|
-
.includes_all(customer: :addresses)
|
631
|
-
.find(1)
|
632
|
-
expect(place.customer.addresses.map(&:no)).to eq [1, 2]
|
633
|
-
end
|
634
|
-
end
|
635
|
-
|
636
|
-
context 'does not fail including all linked resources' do
|
637
|
-
|
638
|
-
before do
|
639
|
-
class CustomerOnboardingToken < LHS::Record
|
640
|
-
endpoint 'https://token/{id}'
|
641
|
-
end
|
642
|
-
|
643
|
-
class Place < LHS::Record
|
644
|
-
endpoint 'https://places/{id}'
|
645
|
-
end
|
646
|
-
|
647
|
-
class AvailableAsset < LHS::Record
|
648
|
-
endpoint 'https://assets'
|
649
|
-
end
|
650
|
-
|
651
|
-
stub_request(:get, 'https://token/1')
|
652
|
-
.to_return(
|
653
|
-
body: {
|
654
|
-
places: [{ href: 'https://places/1' }]
|
655
|
-
}.to_json
|
656
|
-
)
|
657
|
-
|
658
|
-
stub_request(:get, 'https://places/1?limit=100')
|
659
|
-
.to_return(
|
660
|
-
body: {
|
661
|
-
available_assets: { 'href': 'https://assets?limit=10&offset=0' }
|
662
|
-
}.to_json
|
663
|
-
)
|
664
|
-
|
665
|
-
stub_request(:get, 'https://assets?limit=10&offset=0')
|
666
|
-
.to_return(
|
667
|
-
body: {
|
668
|
-
items: 10.times.map { { asset_code: 'CATEGORIES' } },
|
669
|
-
total: 17,
|
670
|
-
offset: 0,
|
671
|
-
limit: 10
|
672
|
-
}.to_json
|
673
|
-
)
|
674
|
-
|
675
|
-
stub_request(:get, 'https://assets?limit=10&offset=10')
|
676
|
-
.to_return(
|
677
|
-
body: {
|
678
|
-
items: 7.times.map { { asset_code: 'CATEGORIES' } },
|
679
|
-
total: 17,
|
680
|
-
offset: 0,
|
681
|
-
limit: 10
|
682
|
-
}.to_json
|
683
|
-
)
|
684
|
-
end
|
685
|
-
|
686
|
-
it 'includes a collection trough a single item without exceptions' do
|
687
|
-
token = CustomerOnboardingToken
|
688
|
-
.includes_all(places: :available_assets)
|
689
|
-
.find(1)
|
690
|
-
expect(token.places.first.available_assets.length).to eq 17
|
691
|
-
end
|
692
|
-
end
|
693
|
-
end
|