dhs 1.0.0 → 1.2.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/.github/workflows/rubocop.yml +2 -13
- data/.github/workflows/test.yml +2 -13
- data/README.md +48 -1
- data/dhs.gemspec +2 -2
- data/lib/dhs.rb +5 -2
- data/lib/dhs/concerns/autoload_records.rb +17 -14
- data/lib/dhs/concerns/record/batch.rb +6 -5
- data/lib/dhs/concerns/record/chainable.rb +14 -0
- data/lib/dhs/concerns/record/pagination.rb +2 -0
- data/lib/dhs/pagination/offset_page.rb +7 -0
- data/lib/dhs/railtie.rb +2 -25
- data/lib/dhs/railtie/action_controller_extension.rb +34 -0
- data/lib/dhs/version.rb +1 -1
- data/spec/pagination/offset_page_spec.rb +61 -0
- data/spec/record/find_each_spec.rb +6 -6
- data/spec/record/find_in_batches_spec.rb +50 -12
- data/spec/record/order_spec.rb +37 -0
- metadata +10 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca31fdaf95b8fbff1a8de50591e9861554d00fed99645e79f01cd2363de9e8b7
|
|
4
|
+
data.tar.gz: 06d8d350c5da6878fd6c54a76826bb56c4fb506f6bc8c9be732743014b875f50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 00035a95ea3b634fc97f6af5c7592b32e09a7135a371d29e234c54ee240da99b1b71ce8305b6342aa61b7fb9103c26576a6e729cfead930d7754745d106b5bda
|
|
7
|
+
data.tar.gz: 8f844da13a8f5d011b6179310b5ac1629853f3be24496eeba52b425412a5d7159fd2cb89744953afa2a0d615ef696c04993e3b3f921891bac060bd8d1702d63d
|
|
@@ -8,20 +8,9 @@ jobs:
|
|
|
8
8
|
|
|
9
9
|
steps:
|
|
10
10
|
- uses: actions/checkout@v2
|
|
11
|
-
- uses:
|
|
11
|
+
- uses: ruby/setup-ruby@master
|
|
12
12
|
with:
|
|
13
|
-
|
|
14
|
-
- name: Cache Ruby Gems
|
|
15
|
-
uses: actions/cache@v2
|
|
16
|
-
with:
|
|
17
|
-
path: /.tmp/vendor/bundle
|
|
18
|
-
key: ${{ runner.os }}-gems-latest-${{ hashFiles('**/Gemfile.lock') }}
|
|
19
|
-
restore-keys: |
|
|
20
|
-
${{ runner.os }}-gems-latest-
|
|
21
|
-
- name: Bundle Install
|
|
22
|
-
run: |
|
|
23
|
-
bundle config path /.tmp/vendor/bundle
|
|
24
|
-
bundle install --jobs 4 --retry 3
|
|
13
|
+
bundler-cache: true
|
|
25
14
|
- name: Run Rubocop
|
|
26
15
|
run: |
|
|
27
16
|
bundle exec rubocop
|
data/.github/workflows/test.yml
CHANGED
|
@@ -8,20 +8,9 @@ jobs:
|
|
|
8
8
|
|
|
9
9
|
steps:
|
|
10
10
|
- uses: actions/checkout@v2
|
|
11
|
-
- uses:
|
|
11
|
+
- uses: ruby/setup-ruby@master
|
|
12
12
|
with:
|
|
13
|
-
|
|
14
|
-
- name: Cache Ruby Gems
|
|
15
|
-
uses: actions/cache@v2
|
|
16
|
-
with:
|
|
17
|
-
path: /.tmp/vendor/bundle
|
|
18
|
-
key: ${{ runner.os }}-gems-latest-${{ hashFiles('**/Gemfile.lock') }}
|
|
19
|
-
restore-keys: |
|
|
20
|
-
${{ runner.os }}-gems-latest-
|
|
21
|
-
- name: Bundle Install
|
|
22
|
-
run: |
|
|
23
|
-
bundle config path /.tmp/vendor/bundle
|
|
24
|
-
bundle install --jobs 4 --retry 3
|
|
13
|
+
bundler-cache: true
|
|
25
14
|
- name: Run Tests
|
|
26
15
|
run: |
|
|
27
16
|
bundle exec rspec
|
data/README.md
CHANGED
|
@@ -305,6 +305,20 @@ records = Record.blue.available(true)
|
|
|
305
305
|
GET https://service.example.com/records?color=blue&available=true
|
|
306
306
|
```
|
|
307
307
|
|
|
308
|
+
#### order
|
|
309
|
+
|
|
310
|
+
Set the expected order of things using `.order`
|
|
311
|
+
|
|
312
|
+
```ruby
|
|
313
|
+
# app/controllers/some_controller.rb
|
|
314
|
+
|
|
315
|
+
Record.where(color: 'blue').order(:name, { created_at: :desc })
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
```
|
|
319
|
+
GET https://service.example.com/records?color=blue&order[name]=asc&order[created_at]=desc
|
|
320
|
+
```
|
|
321
|
+
|
|
308
322
|
#### all
|
|
309
323
|
|
|
310
324
|
You can fetch all remote records by using `all`. Pagination will be performed automatically (See: [Record pagination](#record-pagination))
|
|
@@ -1131,6 +1145,40 @@ In parallel:
|
|
|
1131
1145
|
GET https://service.example.com/records?limit=100&page=3
|
|
1132
1146
|
```
|
|
1133
1147
|
|
|
1148
|
+
##### Pagination strategy: offset_page
|
|
1149
|
+
|
|
1150
|
+
The `offest_page` strategy is based on the `page` strategy with the only difference
|
|
1151
|
+
that the pages are counted from 0 onwards (not from 1).
|
|
1152
|
+
|
|
1153
|
+
```ruby
|
|
1154
|
+
# app/models/transaction.rb
|
|
1155
|
+
|
|
1156
|
+
class Transaction < DHS::Record
|
|
1157
|
+
configuration pagination_strategy: 'offset_page', pagination_key: 'page'
|
|
1158
|
+
|
|
1159
|
+
endpoint '{+service}/transactions'
|
|
1160
|
+
end
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
```ruby
|
|
1164
|
+
# app/controllers/some_controller.rb
|
|
1165
|
+
|
|
1166
|
+
Record.all
|
|
1167
|
+
|
|
1168
|
+
```
|
|
1169
|
+
```
|
|
1170
|
+
GET https://service.example.com/records?limit=100
|
|
1171
|
+
{
|
|
1172
|
+
items: [{...}, ...],
|
|
1173
|
+
total: 300,
|
|
1174
|
+
limit: 100,
|
|
1175
|
+
page: 0
|
|
1176
|
+
}
|
|
1177
|
+
In parallel:
|
|
1178
|
+
GET https://service.example.com/records?limit=100&page=1
|
|
1179
|
+
GET https://service.example.com/records?limit=100&page=2
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1134
1182
|
##### Pagination strategy: total_pages
|
|
1135
1183
|
|
|
1136
1184
|
The `total_pages` strategy is based on the `page` strategy with the only difference
|
|
@@ -1165,7 +1213,6 @@ In parallel:
|
|
|
1165
1213
|
GET https://service.example.com/records?limit=100&page=3
|
|
1166
1214
|
```
|
|
1167
1215
|
|
|
1168
|
-
|
|
1169
1216
|
##### Pagination strategy: start
|
|
1170
1217
|
|
|
1171
1218
|
In comparison to the `offset` strategy, the `start` strategy indicates with which item the current page starts.
|
data/dhs.gemspec
CHANGED
|
@@ -19,8 +19,8 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
|
20
20
|
s.require_paths = ['lib']
|
|
21
21
|
|
|
22
|
-
s.requirements << 'Ruby >=
|
|
23
|
-
s.required_ruby_version = '>=
|
|
22
|
+
s.requirements << 'Ruby >= 2.7.2'
|
|
23
|
+
s.required_ruby_version = '>= 2.7.2'
|
|
24
24
|
|
|
25
25
|
s.add_dependency 'activemodel'
|
|
26
26
|
s.add_dependency 'activesupport', '>= 6'
|
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
|
|
@@ -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
|
|
|
@@ -22,17 +22,18 @@ class DHS::Record
|
|
|
22
22
|
def find_in_batches(options = {})
|
|
23
23
|
raise 'No block given' unless block_given?
|
|
24
24
|
options = options.dup
|
|
25
|
-
start = options
|
|
26
|
-
batch_size = options.delete(:batch_size) ||
|
|
25
|
+
start = options[:start] || self.pagination_class::DEFAULT_OFFSET
|
|
26
|
+
batch_size = options.delete(:batch_size) || self.pagination_class::DEFAULT_LIMIT
|
|
27
27
|
loop do # as suggested by Matz
|
|
28
28
|
options = options.dup
|
|
29
29
|
options[:params] = (options[:params] || {}).merge(limit_key(:parameter) => batch_size, pagination_key(:parameter) => start)
|
|
30
30
|
data = request(options)
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
pagination = self.pagination(data)
|
|
32
|
+
batch_size = pagination.limit
|
|
33
|
+
left = pagination.pages_left
|
|
33
34
|
yield new(data)
|
|
34
35
|
break if left <= 0
|
|
35
|
-
start
|
|
36
|
+
start = pagination.next_offset
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
end
|
|
@@ -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
|
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
|
|
@@ -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/version.rb
CHANGED
|
@@ -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
|
|
@@ -29,11 +29,11 @@ describe DHS::Collection do
|
|
|
29
29
|
|
|
30
30
|
context 'find_each' do
|
|
31
31
|
it 'processes each record by fetching records in batches' do
|
|
32
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
33
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
34
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
35
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
36
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
32
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=0").to_return(status: 200, body: api_response((1..100).to_a, 0))
|
|
33
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=100").to_return(status: 200, body: api_response((101..200).to_a, 100))
|
|
34
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=200").to_return(status: 200, body: api_response((201..300).to_a, 200))
|
|
35
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=300").to_return(status: 200, body: api_response((301..400).to_a, 300))
|
|
36
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=400").to_return(status: 200, body: api_response((401..total).to_a, 400))
|
|
37
37
|
count = 0
|
|
38
38
|
Record.find_each do |record|
|
|
39
39
|
count += 1
|
|
@@ -45,7 +45,7 @@ describe DHS::Collection do
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it 'passes options to the requests made' do
|
|
48
|
-
request = stub_request(:get, 'http://depay.fi/v2/feedbacks?limit=100&offset=
|
|
48
|
+
request = stub_request(:get, 'http://depay.fi/v2/feedbacks?limit=100&offset=0')
|
|
49
49
|
.with(headers: { 'Authorization' => 'Bearer 123' })
|
|
50
50
|
.to_return(body: {
|
|
51
51
|
items: []
|
|
@@ -29,11 +29,11 @@ describe DHS::Collection do
|
|
|
29
29
|
|
|
30
30
|
context 'find_batches' do
|
|
31
31
|
it 'processes records in batches' do
|
|
32
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
33
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
34
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
35
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
36
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
32
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=0").to_return(status: 200, body: api_response((1..100).to_a, 0))
|
|
33
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=100").to_return(status: 200, body: api_response((101..200).to_a, 100))
|
|
34
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=200").to_return(status: 200, body: api_response((201..300).to_a, 200))
|
|
35
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=300").to_return(status: 200, body: api_response((301..400).to_a, 300))
|
|
36
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=400").to_return(status: 200, body: api_response((401..total).to_a, 400))
|
|
37
37
|
length = 0
|
|
38
38
|
Record.find_in_batches do |records|
|
|
39
39
|
length += records.length
|
|
@@ -44,11 +44,11 @@ describe DHS::Collection do
|
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it 'adapts to backend max limit' do
|
|
47
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=230&offset=
|
|
48
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
49
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
50
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
51
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
47
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=230&offset=0").to_return(status: 200, body: api_response((1..100).to_a, 0))
|
|
48
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=100").to_return(status: 200, body: api_response((101..200).to_a, 100))
|
|
49
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=200").to_return(status: 200, body: api_response((201..300).to_a, 200))
|
|
50
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=300").to_return(status: 200, body: api_response((301..400).to_a, 300))
|
|
51
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=400").to_return(status: 200, body: api_response((401..total).to_a, 400))
|
|
52
52
|
length = 0
|
|
53
53
|
Record.find_in_batches(batch_size: 230) do |records|
|
|
54
54
|
length += records.length
|
|
@@ -59,8 +59,8 @@ describe DHS::Collection do
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
it 'forwards offset' do
|
|
62
|
-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=
|
|
63
|
-
Record.find_in_batches(start:
|
|
62
|
+
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=400").to_return(status: 200, body: api_response((401..total).to_a, 400))
|
|
63
|
+
Record.find_in_batches(start: 400) do |records|
|
|
64
64
|
expect(records.length).to eq(total - 400)
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -119,4 +119,42 @@ describe DHS::Collection do
|
|
|
119
119
|
expect(length).to eq total
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
|
+
|
|
123
|
+
context 'different pagination strategy' do
|
|
124
|
+
before do
|
|
125
|
+
class Transaction < DHS::Record
|
|
126
|
+
endpoint 'https://api/transactions'
|
|
127
|
+
configuration limit_key: :items_on_page, pagination_strategy: :total_pages, pagination_key: :page, items_key: :transactions, total_key: :total_pages
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
stub_request(:get, 'https://api/transactions?items_on_page=50&page=1')
|
|
131
|
+
.to_return(body: {
|
|
132
|
+
page: 1,
|
|
133
|
+
total_pages: 2,
|
|
134
|
+
items_on_page: 50,
|
|
135
|
+
transactions: 50.times.map { |index| { id: index } }
|
|
136
|
+
}.to_json)
|
|
137
|
+
|
|
138
|
+
stub_request(:get, 'https://api/transactions?items_on_page=50&page=2')
|
|
139
|
+
.to_return(body: {
|
|
140
|
+
page: 2,
|
|
141
|
+
total_pages: 2,
|
|
142
|
+
items_on_page: 50,
|
|
143
|
+
transactions: 22.times.map { |index| { id: 50 + index } }
|
|
144
|
+
}.to_json)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
it 'find in batches and paginates automatically even for different pagination strategies' do
|
|
148
|
+
total = 0
|
|
149
|
+
transactions = []
|
|
150
|
+
|
|
151
|
+
Transaction.find_in_batches(batch_size: 50) do |batch|
|
|
152
|
+
total += batch.length
|
|
153
|
+
transactions << batch
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
expect(total).to eq(72)
|
|
157
|
+
expect(transactions.flatten.as_json).to eq(72.times.map { |index| { id: index }.as_json })
|
|
158
|
+
end
|
|
159
|
+
end
|
|
122
160
|
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.
|
|
4
|
+
version: 1.2.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-05-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -322,6 +322,7 @@ files:
|
|
|
322
322
|
- lib/dhs/pagination/base.rb
|
|
323
323
|
- lib/dhs/pagination/link.rb
|
|
324
324
|
- lib/dhs/pagination/offset.rb
|
|
325
|
+
- lib/dhs/pagination/offset_page.rb
|
|
325
326
|
- lib/dhs/pagination/page.rb
|
|
326
327
|
- lib/dhs/pagination/start.rb
|
|
327
328
|
- lib/dhs/pagination/total_pages.rb
|
|
@@ -333,6 +334,7 @@ files:
|
|
|
333
334
|
- lib/dhs/problems/warnings.rb
|
|
334
335
|
- lib/dhs/proxy.rb
|
|
335
336
|
- lib/dhs/railtie.rb
|
|
337
|
+
- lib/dhs/railtie/action_controller_extension.rb
|
|
336
338
|
- lib/dhs/record.rb
|
|
337
339
|
- lib/dhs/rspec.rb
|
|
338
340
|
- lib/dhs/test/stubbable_records.rb
|
|
@@ -458,6 +460,7 @@ files:
|
|
|
458
460
|
- spec/pagination/link/parallel_spec.rb
|
|
459
461
|
- spec/pagination/link/total_spec.rb
|
|
460
462
|
- spec/pagination/offset/pages_left_spec.rb
|
|
463
|
+
- spec/pagination/offset_page_spec.rb
|
|
461
464
|
- spec/pagination/parameters_spec.rb
|
|
462
465
|
- spec/pagination/total_pages_spec.rb
|
|
463
466
|
- spec/proxy/create_sub_resource_spec.rb
|
|
@@ -514,6 +517,7 @@ files:
|
|
|
514
517
|
- spec/record/new_spec.rb
|
|
515
518
|
- spec/record/options_getter_spec.rb
|
|
516
519
|
- spec/record/options_spec.rb
|
|
520
|
+
- spec/record/order_spec.rb
|
|
517
521
|
- spec/record/paginatable_collection_spec.rb
|
|
518
522
|
- spec/record/pagination_chain_spec.rb
|
|
519
523
|
- spec/record/pagination_links_spec.rb
|
|
@@ -559,14 +563,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
559
563
|
requirements:
|
|
560
564
|
- - ">="
|
|
561
565
|
- !ruby/object:Gem::Version
|
|
562
|
-
version:
|
|
566
|
+
version: 2.7.2
|
|
563
567
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
564
568
|
requirements:
|
|
565
569
|
- - ">="
|
|
566
570
|
- !ruby/object:Gem::Version
|
|
567
571
|
version: '0'
|
|
568
572
|
requirements:
|
|
569
|
-
- Ruby >=
|
|
573
|
+
- Ruby >= 2.7.2
|
|
570
574
|
rubygems_version: 3.2.3
|
|
571
575
|
signing_key:
|
|
572
576
|
specification_version: 4
|
|
@@ -692,6 +696,7 @@ test_files:
|
|
|
692
696
|
- spec/pagination/link/parallel_spec.rb
|
|
693
697
|
- spec/pagination/link/total_spec.rb
|
|
694
698
|
- spec/pagination/offset/pages_left_spec.rb
|
|
699
|
+
- spec/pagination/offset_page_spec.rb
|
|
695
700
|
- spec/pagination/parameters_spec.rb
|
|
696
701
|
- spec/pagination/total_pages_spec.rb
|
|
697
702
|
- spec/proxy/create_sub_resource_spec.rb
|
|
@@ -748,6 +753,7 @@ test_files:
|
|
|
748
753
|
- spec/record/new_spec.rb
|
|
749
754
|
- spec/record/options_getter_spec.rb
|
|
750
755
|
- spec/record/options_spec.rb
|
|
756
|
+
- spec/record/order_spec.rb
|
|
751
757
|
- spec/record/paginatable_collection_spec.rb
|
|
752
758
|
- spec/record/pagination_chain_spec.rb
|
|
753
759
|
- spec/record/pagination_links_spec.rb
|