dhs 1.0.2 → 1.3.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 +149 -2
- data/dhs.gemspec +2 -2
- data/lib/dhs/concerns/autoload_records.rb +17 -14
- data/lib/dhs/concerns/record/chainable.rb +14 -0
- data/lib/dhs/concerns/record/pagination.rb +2 -0
- data/lib/dhs/concerns/record/request.rb +14 -0
- data/lib/dhs/concerns/record/update.rb +1 -1
- data/lib/dhs/pagination/offset_page.rb +7 -0
- data/lib/dhs/railtie/action_controller_extension.rb +34 -0
- data/lib/dhs/railtie.rb +2 -25
- data/lib/dhs/version.rb +1 -1
- data/lib/dhs.rb +5 -2
- data/spec/graphql/main_spec.rb +124 -0
- data/spec/pagination/offset_page_spec.rb +61 -0
- data/spec/record/order_spec.rb +37 -0
- metadata +19 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ed15754a20492dd70e8d58fba832f6db2c747d4f13d04ad23457ab72fd81eda
|
|
4
|
+
data.tar.gz: 2626f410568a801f540f592e32c8f2f6ca5f9c21fa9e1a74229d9f0866139f21
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 86b1ecd19fe674a0464ad2032337bd5801c9a4a6ef5209515e11b4f38b16d14a896f1b577e0cd37d2399159a7bb7c7a1cb2b0c2cd0d4dac1925616940d22bcb1
|
|
7
|
+
data.tar.gz: a663b02f76a6571a9f50ee00af2268be77c16d8c7606d01391e2d36c20d5e81fd0ba66b38f71226c9f643a403d8bd84b5162fa581447c68713c2a1748be6b324
|
data/README.md
CHANGED
|
@@ -155,6 +155,107 @@ GET https://service.example.com/records
|
|
|
155
155
|
|
|
156
156
|
**Be aware that, if you configure ambigious endpoints accross multiple classes, the order of things is not deteministic. Ambigious endpoints accross multiple classes need to be avoided.**
|
|
157
157
|
|
|
158
|
+
#### GraphQL Endpoints
|
|
159
|
+
|
|
160
|
+
You can use DHS also to fetch records from GraphQL Endpoints:
|
|
161
|
+
|
|
162
|
+
```ruby
|
|
163
|
+
# app/models/record.rb
|
|
164
|
+
|
|
165
|
+
class Record < DHS::Record
|
|
166
|
+
|
|
167
|
+
configuration items_keys: [:data, :ethereum, :address, 0, :balances]
|
|
168
|
+
|
|
169
|
+
endpoint 'https://graphql.bitquery.io/',
|
|
170
|
+
graphql: {
|
|
171
|
+
query: %Q{
|
|
172
|
+
query ($network: EthereumNetwork!, $address: String!) {
|
|
173
|
+
ethereum(network: $network) {
|
|
174
|
+
address(address: {is: $address}) {
|
|
175
|
+
balances {
|
|
176
|
+
currency {
|
|
177
|
+
address
|
|
178
|
+
name
|
|
179
|
+
symbol
|
|
180
|
+
decimals
|
|
181
|
+
tokenType
|
|
182
|
+
}
|
|
183
|
+
value
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
variables: [:network, :address]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
end
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
# app/controllers/some_controller.rb
|
|
197
|
+
|
|
198
|
+
records = Record.where(network: 'ethereum', address: '0x317D875cA3B9f8d14f960486C0d1D1913be74e90')
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
POST https://graphql.bitquery.io/
|
|
203
|
+
|
|
204
|
+
BODY
|
|
205
|
+
{
|
|
206
|
+
"query": "
|
|
207
|
+
query ($network: EthereumNetwork!, $address: String!) {
|
|
208
|
+
ethereum(network: $network) {
|
|
209
|
+
address(address: {is: $address}) {
|
|
210
|
+
balances {
|
|
211
|
+
currency {
|
|
212
|
+
address
|
|
213
|
+
name
|
|
214
|
+
symbol
|
|
215
|
+
decimals
|
|
216
|
+
tokenType
|
|
217
|
+
}
|
|
218
|
+
value
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
",
|
|
224
|
+
"variables": {
|
|
225
|
+
"network": "ethereum",
|
|
226
|
+
"address": "0x317D875cA3B9f8d14f960486C0d1D1913be74e90"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
RESPONSE
|
|
231
|
+
"data": {
|
|
232
|
+
"ethereum": {
|
|
233
|
+
"address": [
|
|
234
|
+
{
|
|
235
|
+
balances: [
|
|
236
|
+
{
|
|
237
|
+
"currency": {
|
|
238
|
+
"address": "-",
|
|
239
|
+
"name": "Ether",
|
|
240
|
+
"decimals": 18,
|
|
241
|
+
"symbol": "ETH",
|
|
242
|
+
"tokenType": ""
|
|
243
|
+
},
|
|
244
|
+
"value": 0.11741978
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
# app/controllers/some_controller.rb
|
|
255
|
+
|
|
256
|
+
records.first.currency.name # Ethereum
|
|
257
|
+
```
|
|
258
|
+
|
|
158
259
|
### Provider
|
|
159
260
|
|
|
160
261
|
Providers in DHS allow you to group shared endpoint options under a common provider.
|
|
@@ -305,6 +406,20 @@ records = Record.blue.available(true)
|
|
|
305
406
|
GET https://service.example.com/records?color=blue&available=true
|
|
306
407
|
```
|
|
307
408
|
|
|
409
|
+
#### order
|
|
410
|
+
|
|
411
|
+
Set the expected order of things using `.order`
|
|
412
|
+
|
|
413
|
+
```ruby
|
|
414
|
+
# app/controllers/some_controller.rb
|
|
415
|
+
|
|
416
|
+
Record.where(color: 'blue').order(:name, { created_at: :desc })
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
```
|
|
420
|
+
GET https://service.example.com/records?color=blue&order[name]=asc&order[created_at]=desc
|
|
421
|
+
```
|
|
422
|
+
|
|
308
423
|
#### all
|
|
309
424
|
|
|
310
425
|
You can fetch all remote records by using `all`. Pagination will be performed automatically (See: [Record pagination](#record-pagination))
|
|
@@ -1131,6 +1246,40 @@ In parallel:
|
|
|
1131
1246
|
GET https://service.example.com/records?limit=100&page=3
|
|
1132
1247
|
```
|
|
1133
1248
|
|
|
1249
|
+
##### Pagination strategy: offset_page
|
|
1250
|
+
|
|
1251
|
+
The `offest_page` strategy is based on the `page` strategy with the only difference
|
|
1252
|
+
that the pages are counted from 0 onwards (not from 1).
|
|
1253
|
+
|
|
1254
|
+
```ruby
|
|
1255
|
+
# app/models/transaction.rb
|
|
1256
|
+
|
|
1257
|
+
class Transaction < DHS::Record
|
|
1258
|
+
configuration pagination_strategy: 'offset_page', pagination_key: 'page'
|
|
1259
|
+
|
|
1260
|
+
endpoint '{+service}/transactions'
|
|
1261
|
+
end
|
|
1262
|
+
```
|
|
1263
|
+
|
|
1264
|
+
```ruby
|
|
1265
|
+
# app/controllers/some_controller.rb
|
|
1266
|
+
|
|
1267
|
+
Record.all
|
|
1268
|
+
|
|
1269
|
+
```
|
|
1270
|
+
```
|
|
1271
|
+
GET https://service.example.com/records?limit=100
|
|
1272
|
+
{
|
|
1273
|
+
items: [{...}, ...],
|
|
1274
|
+
total: 300,
|
|
1275
|
+
limit: 100,
|
|
1276
|
+
page: 0
|
|
1277
|
+
}
|
|
1278
|
+
In parallel:
|
|
1279
|
+
GET https://service.example.com/records?limit=100&page=1
|
|
1280
|
+
GET https://service.example.com/records?limit=100&page=2
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1134
1283
|
##### Pagination strategy: total_pages
|
|
1135
1284
|
|
|
1136
1285
|
The `total_pages` strategy is based on the `page` strategy with the only difference
|
|
@@ -1165,7 +1314,6 @@ In parallel:
|
|
|
1165
1314
|
GET https://service.example.com/records?limit=100&page=3
|
|
1166
1315
|
```
|
|
1167
1316
|
|
|
1168
|
-
|
|
1169
1317
|
##### Pagination strategy: start
|
|
1170
1318
|
|
|
1171
1319
|
In comparison to the `offset` strategy, the `start` strategy indicates with which item the current page starts.
|
|
@@ -2804,4 +2952,3 @@ expect(
|
|
|
2804
2952
|
## License
|
|
2805
2953
|
|
|
2806
2954
|
[GNU General Public License Version 3.](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
|
2807
|
-
|
data/dhs.gemspec
CHANGED
|
@@ -24,14 +24,14 @@ Gem::Specification.new do |s|
|
|
|
24
24
|
|
|
25
25
|
s.add_dependency 'activemodel'
|
|
26
26
|
s.add_dependency 'activesupport', '>= 6'
|
|
27
|
-
s.add_dependency 'dhc'
|
|
27
|
+
s.add_dependency 'dhc', '>= 2'
|
|
28
28
|
s.add_dependency 'local_uri'
|
|
29
29
|
|
|
30
30
|
s.add_development_dependency 'capybara'
|
|
31
31
|
s.add_development_dependency 'json', '>= 1.8.2'
|
|
32
32
|
s.add_development_dependency 'pry'
|
|
33
33
|
s.add_development_dependency 'pry-byebug'
|
|
34
|
-
s.add_development_dependency 'rails', '>= 6'
|
|
34
|
+
s.add_development_dependency 'rails', '>= 6', '< 7'
|
|
35
35
|
s.add_development_dependency 'rollbar', '<= 2.24.0'
|
|
36
36
|
s.add_development_dependency 'rspec-rails', '>= 3.7.0'
|
|
37
37
|
s.add_development_dependency 'rubocop'
|
|
@@ -18,6 +18,9 @@ module AutoloadRecords
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
class Middleware
|
|
21
|
+
|
|
22
|
+
MODEL_FILES = 'app/models/**/*.rb'
|
|
23
|
+
|
|
21
24
|
def initialize(app)
|
|
22
25
|
@app = app
|
|
23
26
|
end
|
|
@@ -27,24 +30,24 @@ module AutoloadRecords
|
|
|
27
30
|
@app.call(env)
|
|
28
31
|
end
|
|
29
32
|
|
|
30
|
-
def self.model_files
|
|
31
|
-
Dir.glob(Rails.root.join('app', 'models', '**', '*.rb'))
|
|
32
|
-
end
|
|
33
|
-
|
|
34
33
|
def self.require_direct_inheritance
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
Rails.application.reloader.to_prepare do
|
|
35
|
+
Dir.glob(Rails.root.join(MODEL_FILES)).each do |file|
|
|
36
|
+
next unless File.read(file).match('DHS::Record')
|
|
37
|
+
require_dependency file
|
|
38
|
+
file.split('models/').last.gsub('.rb', '').classify
|
|
39
|
+
end.compact
|
|
40
|
+
end
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def self.require_inheriting_records(parents)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
Rails.application.reloader.to_prepare do
|
|
45
|
+
Dir.glob(Rails.root.join(MODEL_FILES)).each do |file|
|
|
46
|
+
file_content = File.read(file)
|
|
47
|
+
next if parents.none? { |parent| file_content.match(/\b#{parent}\b/) }
|
|
48
|
+
next if file_content.match?('extend ActiveSupport::Concern')
|
|
49
|
+
require_dependency file
|
|
50
|
+
end
|
|
48
51
|
end
|
|
49
52
|
end
|
|
50
53
|
|
|
@@ -222,6 +222,20 @@ class DHS::Record
|
|
|
222
222
|
end
|
|
223
223
|
end
|
|
224
224
|
|
|
225
|
+
def order(*args)
|
|
226
|
+
order_params = {}
|
|
227
|
+
args.each do |arg|
|
|
228
|
+
if arg.is_a?(Hash)
|
|
229
|
+
arg.each do |key, value|
|
|
230
|
+
order_params[key] = value
|
|
231
|
+
end
|
|
232
|
+
else
|
|
233
|
+
order_params[arg.to_s] = 'asc'
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
push(Parameter.new(order: order_params))
|
|
237
|
+
end
|
|
238
|
+
|
|
225
239
|
def all(hash = nil)
|
|
226
240
|
push([Parameter.new(hash), Option.new(all: true)])
|
|
227
241
|
end
|
|
@@ -469,6 +469,7 @@ class DHS::Record
|
|
|
469
469
|
options = (provider_options || {})
|
|
470
470
|
.deep_merge(endpoint.options || {})
|
|
471
471
|
.deep_merge(options)
|
|
472
|
+
set_graphql_options!(options) if options.dig(:graphql).present?
|
|
472
473
|
options[:url] = compute_url!(options[:params]) unless options.key?(:url)
|
|
473
474
|
merge_explicit_params!(options[:params])
|
|
474
475
|
options.delete(:params) if options[:params]&.empty?
|
|
@@ -476,6 +477,19 @@ class DHS::Record
|
|
|
476
477
|
options
|
|
477
478
|
end
|
|
478
479
|
|
|
480
|
+
def set_graphql_options!(options)
|
|
481
|
+
options[:method] = :post
|
|
482
|
+
variables = {}
|
|
483
|
+
options.dig(:graphql, :variables).each do |key|
|
|
484
|
+
variables[key] = options[:params][key]
|
|
485
|
+
options[:params].delete(key)
|
|
486
|
+
end
|
|
487
|
+
options[:body] = {
|
|
488
|
+
query: options.dig(:graphql, :query).squish,
|
|
489
|
+
variables: variables.to_json
|
|
490
|
+
}
|
|
491
|
+
end
|
|
492
|
+
|
|
479
493
|
def inject_interceptors!(options)
|
|
480
494
|
if DHS.config.request_cycle_cache_enabled
|
|
481
495
|
inject_interceptor!(
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module DHS
|
|
4
|
+
class Railtie < Rails::Railtie
|
|
5
|
+
|
|
6
|
+
class ::ActionController::Base
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
prepare_dhs_request_cycle_cache
|
|
10
|
+
reset_option_blocks
|
|
11
|
+
reset_extended_rollbar_request_logs
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def prepare_dhs_request_cycle_cache
|
|
18
|
+
return unless DHS.config.request_cycle_cache_enabled
|
|
19
|
+
DHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id = [Time.now.to_f, request.object_id].join('#')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def reset_option_blocks
|
|
23
|
+
DHS::OptionBlocks::CurrentOptionBlock.options = nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def reset_extended_rollbar_request_logs
|
|
27
|
+
return unless defined?(::Rollbar)
|
|
28
|
+
return unless DHC.config.interceptors.include?(DHS::Interceptors::ExtendedRollbar::Interceptor)
|
|
29
|
+
DHS::Interceptors::ExtendedRollbar::ThreadRegistry.log = []
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/dhs/railtie.rb
CHANGED
|
@@ -3,31 +3,8 @@
|
|
|
3
3
|
module DHS
|
|
4
4
|
class Railtie < Rails::Railtie
|
|
5
5
|
initializer 'dhs.hook_into_controller_initialization' do
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def initialize
|
|
9
|
-
prepare_dhs_request_cycle_cache
|
|
10
|
-
reset_option_blocks
|
|
11
|
-
reset_extended_rollbar_request_logs
|
|
12
|
-
super
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def prepare_dhs_request_cycle_cache
|
|
18
|
-
return unless DHS.config.request_cycle_cache_enabled
|
|
19
|
-
DHS::Interceptors::RequestCycleCache::ThreadRegistry.request_id = [Time.now.to_f, request.object_id].join('#')
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def reset_option_blocks
|
|
23
|
-
DHS::OptionBlocks::CurrentOptionBlock.options = nil
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def reset_extended_rollbar_request_logs
|
|
27
|
-
return unless defined?(::Rollbar)
|
|
28
|
-
return unless DHC.config.interceptors.include?(DHS::Interceptors::ExtendedRollbar::Interceptor)
|
|
29
|
-
DHS::Interceptors::ExtendedRollbar::ThreadRegistry.log = []
|
|
30
|
-
end
|
|
6
|
+
Rails.application.reloader.to_prepare do
|
|
7
|
+
require_relative 'railtie/action_controller_extension'
|
|
31
8
|
end
|
|
32
9
|
end
|
|
33
10
|
end
|
data/lib/dhs/version.rb
CHANGED
data/lib/dhs.rb
CHANGED
|
@@ -38,6 +38,7 @@ module DHS
|
|
|
38
38
|
autoload :Offset, 'dhs/pagination/offset'
|
|
39
39
|
autoload :Page, 'dhs/pagination/page'
|
|
40
40
|
autoload :TotalPages, 'dhs/pagination/total_pages'
|
|
41
|
+
autoload :OffsetPage, 'dhs/pagination/offset_page'
|
|
41
42
|
autoload :Start, 'dhs/pagination/start'
|
|
42
43
|
autoload :Link, 'dhs/pagination/link'
|
|
43
44
|
end
|
|
@@ -58,10 +59,12 @@ module DHS
|
|
|
58
59
|
autoload :Unprocessable, 'dhs/unprocessable'
|
|
59
60
|
|
|
60
61
|
include Configuration
|
|
61
|
-
include AutoloadRecords if defined?(Rails)
|
|
62
62
|
include OptionBlocks
|
|
63
63
|
|
|
64
64
|
require 'dhs/record' # as dhs records in an application are directly inheriting it
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
if defined?(Rails)
|
|
67
|
+
include AutoloadRecords
|
|
68
|
+
require 'dhs/railtie'
|
|
69
|
+
end
|
|
67
70
|
end
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe 'main graphql support' do
|
|
6
|
+
let(:network) { 'ethereum' }
|
|
7
|
+
let(:address) { '0x317D875cA3B9f8d14f960486C0d1D1913be74e90' }
|
|
8
|
+
|
|
9
|
+
let!(:stubbed_request) do
|
|
10
|
+
stub_request(:post, 'https://graphql.bitquery.io/')
|
|
11
|
+
.with(
|
|
12
|
+
body: {
|
|
13
|
+
query: %{
|
|
14
|
+
query ($network: EthereumNetwork!, $address: String!) {
|
|
15
|
+
ethereum(network: $network) {
|
|
16
|
+
address(address: {is: $address}) {
|
|
17
|
+
balances {
|
|
18
|
+
currency {
|
|
19
|
+
address
|
|
20
|
+
name
|
|
21
|
+
symbol
|
|
22
|
+
decimals
|
|
23
|
+
tokenType
|
|
24
|
+
}
|
|
25
|
+
value
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}.squish,
|
|
31
|
+
variables: {
|
|
32
|
+
"network": network,
|
|
33
|
+
"address": address
|
|
34
|
+
}.to_json
|
|
35
|
+
}.to_json
|
|
36
|
+
).to_return(body: {
|
|
37
|
+
"data": {
|
|
38
|
+
"ethereum": {
|
|
39
|
+
"address": [
|
|
40
|
+
{
|
|
41
|
+
balances: [
|
|
42
|
+
{
|
|
43
|
+
"currency": {
|
|
44
|
+
"address": '-',
|
|
45
|
+
"name": 'Ether',
|
|
46
|
+
"decimals": 18,
|
|
47
|
+
"symbol": 'ETH',
|
|
48
|
+
"tokenType": ''
|
|
49
|
+
},
|
|
50
|
+
"value": 0.11741978
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"currency": {
|
|
54
|
+
"address": '0xb63b606ac810a52cca15e44bb630fd42d8d1d83d',
|
|
55
|
+
"name": 'Monaco',
|
|
56
|
+
"decimals": 8,
|
|
57
|
+
"symbol": 'MCO',
|
|
58
|
+
"tokenType": 'ERC20'
|
|
59
|
+
},
|
|
60
|
+
"value": 0
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"currency": {
|
|
64
|
+
"address": '0x06012c8cf97bead5deae237070f9587f8e7a266d',
|
|
65
|
+
"name": 'CryptoKitties',
|
|
66
|
+
"decimals": 0,
|
|
67
|
+
"symbol": 'CK',
|
|
68
|
+
"tokenType": 'ERC721'
|
|
69
|
+
},
|
|
70
|
+
"value": 90
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"currency": {
|
|
74
|
+
"address": '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
75
|
+
"name": 'Tether USD',
|
|
76
|
+
"decimals": 6,
|
|
77
|
+
"symbol": 'USDT',
|
|
78
|
+
"tokenType": 'ERC20'
|
|
79
|
+
},
|
|
80
|
+
"value": 10
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}.to_json)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
before do
|
|
91
|
+
class Record < DHS::Record
|
|
92
|
+
|
|
93
|
+
configuration items_key: [:data, :ethereum, :address, 0, :balances]
|
|
94
|
+
|
|
95
|
+
endpoint 'https://graphql.bitquery.io/',
|
|
96
|
+
graphql: {
|
|
97
|
+
query: %{
|
|
98
|
+
query ($network: EthereumNetwork!, $address: String!) {
|
|
99
|
+
ethereum(network: $network) {
|
|
100
|
+
address(address: {is: $address}) {
|
|
101
|
+
balances {
|
|
102
|
+
currency {
|
|
103
|
+
address
|
|
104
|
+
name
|
|
105
|
+
symbol
|
|
106
|
+
decimals
|
|
107
|
+
tokenType
|
|
108
|
+
}
|
|
109
|
+
value
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
variables: %i[network address]
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'fetches data from graphql and converts it into DHS Record structure' do
|
|
121
|
+
records = Record.where(network: 'ethereum', address: '0x317D875cA3B9f8d14f960486C0d1D1913be74e90').fetch
|
|
122
|
+
expect(records.first.currency.name).to eq 'Ether'
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHS::Record do
|
|
6
|
+
context 'pagination' do
|
|
7
|
+
def stub_api_request(items: [], page: nil)
|
|
8
|
+
stub_request(:get, ['http://depay.fi/v2/transactions?limit=100', page].compact.join('&page='))
|
|
9
|
+
.to_return(body: { items: items }.to_json)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let!(:requests) do
|
|
13
|
+
stub_api_request(items: (0...100).to_a)
|
|
14
|
+
stub_api_request(items: (100...200).to_a, page: 1)
|
|
15
|
+
stub_api_request(items: (200...300).to_a, page: 2)
|
|
16
|
+
stub_api_request(items: [], page: 3)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
before do
|
|
20
|
+
class Transaction < DHS::Record
|
|
21
|
+
configuration pagination_strategy: :offset_page, pagination_key: :page
|
|
22
|
+
|
|
23
|
+
endpoint 'http://depay.fi/v2/transactions'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'fetches all the pages' do
|
|
28
|
+
transactions = Transaction.all.fetch
|
|
29
|
+
expect(transactions.to_a).to eq (0...300).to_a
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
context 'incomplete pages' do
|
|
33
|
+
let!(:requests) do
|
|
34
|
+
stub_api_request(items: (0...100).to_a)
|
|
35
|
+
stub_api_request(items: (100...200).to_a, page: 1)
|
|
36
|
+
stub_api_request(items: (200...300).to_a, page: 2)
|
|
37
|
+
stub_api_request(items: [300], page: 3)
|
|
38
|
+
stub_api_request(items: [], page: 4)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'fetches all the pages' do
|
|
42
|
+
transactions = Transaction.all.fetch
|
|
43
|
+
expect(transactions.to_a).to eq (0..300).to_a
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context 'incomplete pages' do
|
|
48
|
+
let!(:requests) do
|
|
49
|
+
stub_api_request(items: (0...100).to_a)
|
|
50
|
+
stub_api_request(items: (100...200).to_a, page: 1)
|
|
51
|
+
stub_api_request(items: (200...299).to_a, page: 2)
|
|
52
|
+
stub_api_request(items: [], page: 3)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'fetches all the pages' do
|
|
56
|
+
transactions = Transaction.all.fetch
|
|
57
|
+
expect(transactions.to_a).to eq (0...299).to_a
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails_helper'
|
|
4
|
+
|
|
5
|
+
describe DHS::Record do
|
|
6
|
+
context 'order in where chains' do
|
|
7
|
+
before do
|
|
8
|
+
class Record < DHS::Record
|
|
9
|
+
endpoint 'http://records'
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'single parameter for order' do
|
|
14
|
+
before do
|
|
15
|
+
stub_request(:get, 'http://records/?color=blue&order[created_at]=desc')
|
|
16
|
+
.to_return(body: [{ name: 'ordered by created_at desc' }].to_json)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'allows to add order params with .order' do
|
|
20
|
+
records = Record.where(color: 'blue').order(created_at: :desc)
|
|
21
|
+
expect(records.first.name).to eq 'ordered by created_at desc'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'multiple parameters for order' do
|
|
26
|
+
before do
|
|
27
|
+
stub_request(:get, 'http://records/?color=blue&order[name]=asc&order[created_at]=desc')
|
|
28
|
+
.to_return(body: [{ name: 'ordered by name asc (implicitly) and created_at desc (explicitly)' }].to_json)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'allows to add order params with .order' do
|
|
32
|
+
records = Record.where(color: 'blue').order(:name, created_at: :desc)
|
|
33
|
+
expect(records.first.name).to eq 'ordered by name asc (implicitly) and created_at desc (explicitly)'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dhs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- https://github.com/DePayFi/dhs/graphs/contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-12-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '2'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '2'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: local_uri
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -129,6 +129,9 @@ dependencies:
|
|
|
129
129
|
- - ">="
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
131
|
version: '6'
|
|
132
|
+
- - "<"
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '7'
|
|
132
135
|
type: :development
|
|
133
136
|
prerelease: false
|
|
134
137
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -136,6 +139,9 @@ dependencies:
|
|
|
136
139
|
- - ">="
|
|
137
140
|
- !ruby/object:Gem::Version
|
|
138
141
|
version: '6'
|
|
142
|
+
- - "<"
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '7'
|
|
139
145
|
- !ruby/object:Gem::Dependency
|
|
140
146
|
name: rollbar
|
|
141
147
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -322,6 +328,7 @@ files:
|
|
|
322
328
|
- lib/dhs/pagination/base.rb
|
|
323
329
|
- lib/dhs/pagination/link.rb
|
|
324
330
|
- lib/dhs/pagination/offset.rb
|
|
331
|
+
- lib/dhs/pagination/offset_page.rb
|
|
325
332
|
- lib/dhs/pagination/page.rb
|
|
326
333
|
- lib/dhs/pagination/start.rb
|
|
327
334
|
- lib/dhs/pagination/total_pages.rb
|
|
@@ -333,6 +340,7 @@ files:
|
|
|
333
340
|
- lib/dhs/problems/warnings.rb
|
|
334
341
|
- lib/dhs/proxy.rb
|
|
335
342
|
- lib/dhs/railtie.rb
|
|
343
|
+
- lib/dhs/railtie/action_controller_extension.rb
|
|
336
344
|
- lib/dhs/record.rb
|
|
337
345
|
- lib/dhs/rspec.rb
|
|
338
346
|
- lib/dhs/test/stubbable_records.rb
|
|
@@ -427,6 +435,7 @@ files:
|
|
|
427
435
|
- spec/dummy/public/favicon.ico
|
|
428
436
|
- spec/endpoint/for_url_spec.rb
|
|
429
437
|
- spec/extended_rollbar_spec.rb
|
|
438
|
+
- spec/graphql/main_spec.rb
|
|
430
439
|
- spec/item/access_errors_spec.rb
|
|
431
440
|
- spec/item/accessors_spec.rb
|
|
432
441
|
- spec/item/add_error_spec.rb
|
|
@@ -458,6 +467,7 @@ files:
|
|
|
458
467
|
- spec/pagination/link/parallel_spec.rb
|
|
459
468
|
- spec/pagination/link/total_spec.rb
|
|
460
469
|
- spec/pagination/offset/pages_left_spec.rb
|
|
470
|
+
- spec/pagination/offset_page_spec.rb
|
|
461
471
|
- spec/pagination/parameters_spec.rb
|
|
462
472
|
- spec/pagination/total_pages_spec.rb
|
|
463
473
|
- spec/proxy/create_sub_resource_spec.rb
|
|
@@ -514,6 +524,7 @@ files:
|
|
|
514
524
|
- spec/record/new_spec.rb
|
|
515
525
|
- spec/record/options_getter_spec.rb
|
|
516
526
|
- spec/record/options_spec.rb
|
|
527
|
+
- spec/record/order_spec.rb
|
|
517
528
|
- spec/record/paginatable_collection_spec.rb
|
|
518
529
|
- spec/record/pagination_chain_spec.rb
|
|
519
530
|
- spec/record/pagination_links_spec.rb
|
|
@@ -567,7 +578,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
567
578
|
version: '0'
|
|
568
579
|
requirements:
|
|
569
580
|
- Ruby >= 2.7.2
|
|
570
|
-
rubygems_version: 3.2.
|
|
581
|
+
rubygems_version: 3.2.22
|
|
571
582
|
signing_key:
|
|
572
583
|
specification_version: 4
|
|
573
584
|
summary: 'REST services accelerator: Rails gem providing an easy, active-record-like
|
|
@@ -661,6 +672,7 @@ test_files:
|
|
|
661
672
|
- spec/dummy/public/favicon.ico
|
|
662
673
|
- spec/endpoint/for_url_spec.rb
|
|
663
674
|
- spec/extended_rollbar_spec.rb
|
|
675
|
+
- spec/graphql/main_spec.rb
|
|
664
676
|
- spec/item/access_errors_spec.rb
|
|
665
677
|
- spec/item/accessors_spec.rb
|
|
666
678
|
- spec/item/add_error_spec.rb
|
|
@@ -692,6 +704,7 @@ test_files:
|
|
|
692
704
|
- spec/pagination/link/parallel_spec.rb
|
|
693
705
|
- spec/pagination/link/total_spec.rb
|
|
694
706
|
- spec/pagination/offset/pages_left_spec.rb
|
|
707
|
+
- spec/pagination/offset_page_spec.rb
|
|
695
708
|
- spec/pagination/parameters_spec.rb
|
|
696
709
|
- spec/pagination/total_pages_spec.rb
|
|
697
710
|
- spec/proxy/create_sub_resource_spec.rb
|
|
@@ -748,6 +761,7 @@ test_files:
|
|
|
748
761
|
- spec/record/new_spec.rb
|
|
749
762
|
- spec/record/options_getter_spec.rb
|
|
750
763
|
- spec/record/options_spec.rb
|
|
764
|
+
- spec/record/order_spec.rb
|
|
751
765
|
- spec/record/paginatable_collection_spec.rb
|
|
752
766
|
- spec/record/pagination_chain_spec.rb
|
|
753
767
|
- spec/record/pagination_links_spec.rb
|