lhs 21.2.4 → 22.1.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 +4 -4
- data/README.md +264 -116
- data/lhs.gemspec +1 -1
- data/lib/lhs.rb +8 -0
- data/lib/lhs/concerns/o_auth.rb +25 -0
- data/lib/lhs/concerns/record/chainable.rb +4 -4
- data/lib/lhs/concerns/record/configuration.rb +28 -11
- data/lib/lhs/concerns/record/request.rb +26 -7
- data/lib/lhs/concerns/record/update.rb +17 -0
- data/lib/lhs/config.rb +1 -1
- data/lib/lhs/interceptors/auto_oauth/interceptor.rb +33 -0
- data/lib/lhs/interceptors/auto_oauth/thread_registry.rb +18 -0
- data/lib/lhs/record.rb +6 -3
- data/lib/lhs/version.rb +1 -1
- data/spec/auto_oauth_spec.rb +169 -0
- data/spec/dummy/app/controllers/application_controller.rb +15 -0
- data/spec/dummy/app/controllers/automatic_authentication_controller.rb +29 -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/dummy_record_with_oauth.rb +7 -0
- data/spec/dummy/app/models/providers/internal_services.rb +7 -0
- data/spec/dummy/config/routes.rb +5 -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/error_handling_integration_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
- data/spec/request_cycle_cache_spec.rb +3 -3
- metadata +30 -8
- 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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails_helper'
|
4
|
-
require 'lhc/
|
4
|
+
require 'lhc/rspec'
|
5
5
|
|
6
6
|
describe 'Request Cycle Cache', type: :request do
|
7
7
|
let!(:request) do
|
@@ -37,7 +37,7 @@ describe 'Request Cycle Cache', type: :request do
|
|
37
37
|
expect(lambda do
|
38
38
|
get '/request_cycle_cache/no_caching_interceptor'
|
39
39
|
end).to output(
|
40
|
-
%r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/
|
40
|
+
%r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor\)!}
|
41
41
|
).to_stderr
|
42
42
|
expect(request).to have_been_made.times(2)
|
43
43
|
end
|
@@ -70,7 +70,7 @@ describe 'Request Cycle Cache', type: :request do
|
|
70
70
|
expect(lambda do
|
71
71
|
get '/request_cycle_cache/no_caching_interceptor'
|
72
72
|
end).not_to output(
|
73
|
-
%r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/
|
73
|
+
%r{\[WARNING\] Can't enable request cycle cache as LHC::Caching interceptor is not enabled/configured \(see https://github.com/local-ch/lhc/blob/master/README.md#caching-interceptor\)!}
|
74
74
|
).to_stderr
|
75
75
|
expect(request).to have_been_made.times(2)
|
76
76
|
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.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-
|
11
|
+
date: 2020-07-03 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
|
@@ -283,6 +283,7 @@ files:
|
|
283
283
|
- lib/lhs/concerns/item/save.rb
|
284
284
|
- lib/lhs/concerns/item/update.rb
|
285
285
|
- lib/lhs/concerns/item/validation.rb
|
286
|
+
- lib/lhs/concerns/o_auth.rb
|
286
287
|
- lib/lhs/concerns/option_blocks.rb
|
287
288
|
- lib/lhs/concerns/proxy/accessors.rb
|
288
289
|
- lib/lhs/concerns/proxy/create.rb
|
@@ -311,9 +312,12 @@ files:
|
|
311
312
|
- lib/lhs/concerns/record/request.rb
|
312
313
|
- lib/lhs/concerns/record/scope.rb
|
313
314
|
- lib/lhs/concerns/record/tracing.rb
|
315
|
+
- lib/lhs/concerns/record/update.rb
|
314
316
|
- lib/lhs/config.rb
|
315
317
|
- lib/lhs/data.rb
|
316
318
|
- lib/lhs/endpoint.rb
|
319
|
+
- lib/lhs/interceptors/auto_oauth/interceptor.rb
|
320
|
+
- lib/lhs/interceptors/auto_oauth/thread_registry.rb
|
317
321
|
- lib/lhs/interceptors/extended_rollbar/handler.rb
|
318
322
|
- lib/lhs/interceptors/extended_rollbar/interceptor.rb
|
319
323
|
- lib/lhs/interceptors/extended_rollbar/thread_registry.rb
|
@@ -340,6 +344,7 @@ files:
|
|
340
344
|
- lib/lhs/version.rb
|
341
345
|
- script/ci/build.sh
|
342
346
|
- spec/.DS_Store
|
347
|
+
- spec/auto_oauth_spec.rb
|
343
348
|
- spec/autoloading_spec.rb
|
344
349
|
- spec/collection/accessors_spec.rb
|
345
350
|
- spec/collection/collection_items_spec.rb
|
@@ -372,6 +377,7 @@ files:
|
|
372
377
|
- spec/dummy/app/assets/javascripts/application.js
|
373
378
|
- spec/dummy/app/assets/stylesheets/application.css
|
374
379
|
- spec/dummy/app/controllers/application_controller.rb
|
380
|
+
- spec/dummy/app/controllers/automatic_authentication_controller.rb
|
375
381
|
- spec/dummy/app/controllers/concerns/.keep
|
376
382
|
- spec/dummy/app/controllers/error_handling_with_chains_controller.rb
|
377
383
|
- spec/dummy/app/controllers/extended_rollbar_controller.rb
|
@@ -383,8 +389,14 @@ files:
|
|
383
389
|
- spec/dummy/app/models/concerns/.keep
|
384
390
|
- spec/dummy/app/models/dummy_customer.rb
|
385
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
|
396
|
+
- spec/dummy/app/models/dummy_record_with_oauth.rb
|
386
397
|
- spec/dummy/app/models/dummy_user.rb
|
387
398
|
- spec/dummy/app/models/providers/customer_system.rb
|
399
|
+
- spec/dummy/app/models/providers/internal_services.rb
|
388
400
|
- spec/dummy/app/views/error_handling_with_chains/error.html.erb
|
389
401
|
- spec/dummy/app/views/error_handling_with_chains/show.html.erb
|
390
402
|
- spec/dummy/app/views/form_for.html.erb
|
@@ -489,7 +501,7 @@ files:
|
|
489
501
|
- spec/record/href_for_spec.rb
|
490
502
|
- spec/record/ignore_errors_spec.rb
|
491
503
|
- spec/record/immutable_chains_spec.rb
|
492
|
-
- spec/record/
|
504
|
+
- spec/record/includes_first_page_spec.rb
|
493
505
|
- spec/record/includes_spec.rb
|
494
506
|
- spec/record/includes_warning_spec.rb
|
495
507
|
- spec/record/item_key_spec.rb
|
@@ -519,6 +531,7 @@ files:
|
|
519
531
|
- spec/record/to_hash_spec.rb
|
520
532
|
- spec/record/to_json_spec.rb
|
521
533
|
- spec/record/tracing_spec.rb
|
534
|
+
- spec/record/update_spec.rb
|
522
535
|
- spec/record/where_chains_spec.rb
|
523
536
|
- spec/record/where_spec.rb
|
524
537
|
- spec/record/where_values_hash_spec.rb
|
@@ -559,6 +572,7 @@ specification_version: 4
|
|
559
572
|
summary: 'REST services accelerator: Rails gem providing an easy, active-record-like
|
560
573
|
interface for http (hypermedia) json services'
|
561
574
|
test_files:
|
575
|
+
- spec/auto_oauth_spec.rb
|
562
576
|
- spec/autoloading_spec.rb
|
563
577
|
- spec/collection/accessors_spec.rb
|
564
578
|
- spec/collection/collection_items_spec.rb
|
@@ -591,6 +605,7 @@ test_files:
|
|
591
605
|
- spec/dummy/app/assets/javascripts/application.js
|
592
606
|
- spec/dummy/app/assets/stylesheets/application.css
|
593
607
|
- spec/dummy/app/controllers/application_controller.rb
|
608
|
+
- spec/dummy/app/controllers/automatic_authentication_controller.rb
|
594
609
|
- spec/dummy/app/controllers/concerns/.keep
|
595
610
|
- spec/dummy/app/controllers/error_handling_with_chains_controller.rb
|
596
611
|
- spec/dummy/app/controllers/extended_rollbar_controller.rb
|
@@ -602,8 +617,14 @@ test_files:
|
|
602
617
|
- spec/dummy/app/models/concerns/.keep
|
603
618
|
- spec/dummy/app/models/dummy_customer.rb
|
604
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
|
624
|
+
- spec/dummy/app/models/dummy_record_with_oauth.rb
|
605
625
|
- spec/dummy/app/models/dummy_user.rb
|
606
626
|
- spec/dummy/app/models/providers/customer_system.rb
|
627
|
+
- spec/dummy/app/models/providers/internal_services.rb
|
607
628
|
- spec/dummy/app/views/error_handling_with_chains/error.html.erb
|
608
629
|
- spec/dummy/app/views/error_handling_with_chains/show.html.erb
|
609
630
|
- spec/dummy/app/views/form_for.html.erb
|
@@ -708,7 +729,7 @@ test_files:
|
|
708
729
|
- spec/record/href_for_spec.rb
|
709
730
|
- spec/record/ignore_errors_spec.rb
|
710
731
|
- spec/record/immutable_chains_spec.rb
|
711
|
-
- spec/record/
|
732
|
+
- spec/record/includes_first_page_spec.rb
|
712
733
|
- spec/record/includes_spec.rb
|
713
734
|
- spec/record/includes_warning_spec.rb
|
714
735
|
- spec/record/item_key_spec.rb
|
@@ -738,6 +759,7 @@ test_files:
|
|
738
759
|
- spec/record/to_hash_spec.rb
|
739
760
|
- spec/record/to_json_spec.rb
|
740
761
|
- spec/record/tracing_spec.rb
|
762
|
+
- spec/record/update_spec.rb
|
741
763
|
- spec/record/where_chains_spec.rb
|
742
764
|
- spec/record/where_spec.rb
|
743
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
|