Skip to content
This repository was archived by the owner on Oct 6, 2024. It is now read-only.

Commit 9173aab

Browse files
authored
fix find_in_batches for other pagination types (#2)
1 parent 978670a commit 9173aab

File tree

4 files changed

+63
-24
lines changed

4 files changed

+63
-24
lines changed

lib/dhs/concerns/record/batch.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,18 @@ def find_each(options = {})
2222
def find_in_batches(options = {})
2323
raise 'No block given' unless block_given?
2424
options = options.dup
25-
start = options.delete(:start) || 1
26-
batch_size = options.delete(:batch_size) || DHS::Pagination::Base::DEFAULT_LIMIT
25+
start = options[:start] || self.pagination_class::DEFAULT_OFFSET
26+
batch_size = options.delete(:batch_size) || self.pagination_class::DEFAULT_LIMIT
2727
loop do # as suggested by Matz
2828
options = options.dup
2929
options[:params] = (options[:params] || {}).merge(limit_key(:parameter) => batch_size, pagination_key(:parameter) => start)
3030
data = request(options)
31-
batch_size = data._raw.dig(*limit_key(:body))
32-
left = data._raw.dig(*total_key).to_i - data._raw.dig(*pagination_key(:body)).to_i - data._raw.dig(*limit_key(:body)).to_i
31+
pagination = self.pagination(data)
32+
batch_size = pagination.limit
33+
left = pagination.pages_left
3334
yield new(data)
3435
break if left <= 0
35-
start += batch_size
36+
start = pagination.next_offset
3637
end
3738
end
3839
end

lib/dhs/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module DHS
4-
VERSION = '1.0.1'
4+
VERSION = '1.0.2'
55
end

spec/record/find_each_spec.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ class Record < DHS::Record
2929

3030
context 'find_each' do
3131
it 'processes each record by fetching records in batches' do
32-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=1").to_return(status: 200, body: api_response((1..100).to_a, 1))
33-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=101").to_return(status: 200, body: api_response((101..200).to_a, 101))
34-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=201").to_return(status: 200, body: api_response((201..300).to_a, 201))
35-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=301").to_return(status: 200, body: api_response((301..400).to_a, 301))
36-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=401").to_return(status: 200, body: api_response((401..total).to_a, 401))
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))
3737
count = 0
3838
Record.find_each do |record|
3939
count += 1
@@ -45,7 +45,7 @@ class Record < DHS::Record
4545
end
4646

4747
it 'passes options to the requests made' do
48-
request = stub_request(:get, 'http://depay.fi/v2/feedbacks?limit=100&offset=1')
48+
request = stub_request(:get, 'http://depay.fi/v2/feedbacks?limit=100&offset=0')
4949
.with(headers: { 'Authorization' => 'Bearer 123' })
5050
.to_return(body: {
5151
items: []

spec/record/find_in_batches_spec.rb

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ class Record < DHS::Record
2929

3030
context 'find_batches' do
3131
it 'processes records in batches' do
32-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=1").to_return(status: 200, body: api_response((1..100).to_a, 1))
33-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=101").to_return(status: 200, body: api_response((101..200).to_a, 101))
34-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=201").to_return(status: 200, body: api_response((201..300).to_a, 201))
35-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=301").to_return(status: 200, body: api_response((301..400).to_a, 301))
36-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=401").to_return(status: 200, body: api_response((401..total).to_a, 401))
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))
3737
length = 0
3838
Record.find_in_batches do |records|
3939
length += records.length
@@ -44,11 +44,11 @@ class Record < DHS::Record
4444
end
4545

4646
it 'adapts to backend max limit' do
47-
stub_request(:get, "#{datastore}/feedbacks?limit=230&offset=1").to_return(status: 200, body: api_response((1..100).to_a, 1))
48-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=101").to_return(status: 200, body: api_response((101..200).to_a, 101))
49-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=201").to_return(status: 200, body: api_response((201..300).to_a, 201))
50-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=301").to_return(status: 200, body: api_response((301..400).to_a, 301))
51-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=401").to_return(status: 200, body: api_response((401..total).to_a, 401))
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))
5252
length = 0
5353
Record.find_in_batches(batch_size: 230) do |records|
5454
length += records.length
@@ -59,8 +59,8 @@ class Record < DHS::Record
5959
end
6060

6161
it 'forwards offset' do
62-
stub_request(:get, "#{datastore}/feedbacks?limit=100&offset=401").to_return(status: 200, body: api_response((401..total).to_a, 401))
63-
Record.find_in_batches(start: 401) do |records|
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|
6464
expect(records.length).to eq(total - 400)
6565
end
6666
end
@@ -119,4 +119,42 @@ class Record < DHS::Record
119119
expect(length).to eq total
120120
end
121121
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
122160
end

0 commit comments

Comments
 (0)