api-pagination 6.0.0 → 7.0.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.
@@ -1,76 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ApiPagination do
4
- let(:collection) {(1..100).to_a}
5
- let(:active_record_relation) {double("ActiveRecord_Relation").as_null_object}
6
- let(:paginate_array_options) {{ total_count: 1000 }}
7
-
8
- describe "#paginate" do
9
- if ENV['PAGINATOR'].to_sym == :kaminari
10
- context 'Using kaminari' do
11
- describe '.paginate' do
12
- it 'should accept paginate_array_options option' do
13
- expect(Kaminari).to receive(:paginate_array)
14
- .with(collection, **paginate_array_options)
15
- .and_call_original
16
-
17
- ApiPagination.paginate(
18
- collection,
19
- {
20
- per_page: 30,
21
- paginate_array_options: paginate_array_options
22
- }
23
- )
24
- end
25
-
26
- context 'configured not to include the total' do
27
- before { ApiPagination.config.include_total = false }
28
-
29
- context 'and paginating an array' do
30
- it 'should not call without_count on the collection' do
31
- expect(collection).to_not receive :without_count
32
- ApiPagination.paginate(collection)
33
- end
34
- end
35
- context 'and paginating an active record relation' do
36
- it 'should call without_count on the relation' do
37
- expect(active_record_relation).to receive :without_count
38
- ApiPagination.paginate(active_record_relation)
39
- end
40
- end
41
-
42
- after { ApiPagination.config.include_total = true }
43
- end
44
- end
45
-
46
- describe '.pages_from' do
47
- subject { described_class.pages_from(collection) }
48
-
49
- context 'on empty collection' do
50
- let(:collection) { ApiPagination.paginate([], page: 1).first }
51
-
52
- it { is_expected.to be_empty }
53
- end
54
- end
55
- end
56
- end
57
-
58
- if ENV['PAGINATOR'].to_sym == :will_paginate
59
- context 'Using will_paginate' do
60
- context 'passing in total_entries in options' do
61
- it 'should set total_entries using the passed in value' do
62
- paginated_collection = ApiPagination.paginate(collection, total_entries: 3000).first
63
- expect(paginated_collection.total_entries).to eq(3000)
64
- end
65
- end
66
-
67
- context 'passing in collection only' do
68
- it 'should set total_entries using the size of the collection ' do
69
- paginated_collection = ApiPagination.paginate(collection).first
70
- expect(paginated_collection.total_entries).to eq(100)
71
- end
72
- end
73
- end
74
- end
75
- end
76
- end
data/spec/grape_spec.rb DELETED
@@ -1,165 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/shared_examples/existing_headers'
3
- require 'support/shared_examples/first_page'
4
- require 'support/shared_examples/middle_page'
5
- require 'support/shared_examples/last_page'
6
-
7
- describe NumbersAPI do
8
- it { is_expected.to be_kind_of(Grape::Pagination) }
9
-
10
- describe 'GET #index' do
11
- let(:link) { last_response.headers['Link'] }
12
- let(:links) { link.split(', ') }
13
- let(:total) { last_response.headers['Total'].to_i }
14
- let(:per_page) { last_response.headers['Per-Page'].to_i }
15
-
16
- context 'without enough items to give more than one page' do
17
- before { get '/numbers', :count => 10 }
18
-
19
- it 'should not paginate' do
20
- expect(last_response.headers.keys).not_to include('Link')
21
- end
22
-
23
- it 'should give a Total header' do
24
- expect(total).to eq(10)
25
- end
26
-
27
- it 'should give a Per-Page header' do
28
- expect(per_page).to eq(10)
29
- end
30
-
31
- it 'should list all numbers in the response body' do
32
- body = '[1,2,3,4,5,6,7,8,9,10]'
33
- expect(last_response.body).to eq(body)
34
- end
35
- end
36
-
37
- context 'with existing Link headers' do
38
- before { get '/numbers', :count => 30, :with_headers => true }
39
-
40
- it_behaves_like 'an endpoint with existing Link headers'
41
- end
42
-
43
- context 'with enough items to paginate' do
44
- context 'when on the first page' do
45
- before { get '/numbers', :count => 100 }
46
-
47
- it_behaves_like 'an endpoint with a first page'
48
- end
49
-
50
- context 'when on the last page' do
51
- before { get '/numbers', :count => 100, :page => 10 }
52
-
53
- it_behaves_like 'an endpoint with a last page'
54
- end
55
-
56
- context 'when somewhere comfortably in the middle' do
57
- before { get '/numbers', :count => 100, :page => 2 }
58
-
59
- it_behaves_like 'an endpoint with a middle page'
60
- end
61
-
62
- context 'without a max_per_page setting' do
63
- before { get '/numbers', :count => 100, :per_page => 30 }
64
-
65
- it 'should list all numbers within per page in the response body' do
66
- body = '[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]'
67
-
68
- expect(last_response.body).to eq(body)
69
- end
70
- end
71
-
72
- context 'with a max_per_page setting not enforced' do
73
- before { get '/numbers_with_max_per_page', :count => 100, :per_page => 30 }
74
-
75
- it 'should not go above the max_per_page_limit' do
76
- body = '[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]'
77
-
78
- expect(last_response.body).to eq(body)
79
- end
80
- end
81
-
82
- context 'with a max_per_page setting enforced' do
83
- before { get '/numbers_with_enforced_max_per_page', :count => 100, :per_page => 30 }
84
-
85
- it 'should not allow value above the max_per_page_limit' do
86
- body = '{"error":"per_page does not have a valid value"}'
87
-
88
- expect(last_response.body).to eq(body)
89
- end
90
- end
91
- end
92
-
93
- context 'with custom response headers' do
94
- before do
95
- ApiPagination.config.total_header = 'X-Total-Count'
96
- ApiPagination.config.per_page_header = 'X-Per-Page'
97
- ApiPagination.config.page_header = 'X-Page'
98
-
99
- get '/numbers', count: 10
100
- end
101
-
102
- after do
103
- ApiPagination.config.total_header = 'Total'
104
- ApiPagination.config.per_page_header = 'Per-Page'
105
- ApiPagination.config.page_header = nil
106
- end
107
-
108
- let(:total) { last_response.header['X-Total-Count'].to_i }
109
- let(:per_page) { last_response.header['X-Per-Page'].to_i }
110
- let(:page) { last_response.header['X-Page'].to_i }
111
-
112
- it 'should give a X-Total-Count header' do
113
- headers_keys = last_response.headers.keys
114
-
115
- expect(headers_keys).not_to include('Total')
116
- expect(headers_keys).to include('X-Total-Count')
117
- expect(total).to eq(10)
118
- end
119
-
120
- it 'should give a X-Per-Page header' do
121
- headers_keys = last_response.headers.keys
122
-
123
- expect(headers_keys).not_to include('Per-Page')
124
- expect(headers_keys).to include('X-Per-Page')
125
- expect(per_page).to eq(10)
126
- end
127
-
128
- it 'should give a X-Page header' do
129
- headers_keys = last_response.headers.keys
130
-
131
- expect(headers_keys).to include('X-Page')
132
- expect(page).to eq(1)
133
- end
134
- end
135
-
136
- context 'configured not to include the total' do
137
- before { ApiPagination.config.include_total = false }
138
-
139
- it 'should not include a Total header' do
140
- get '/numbers', count: 10
141
-
142
- expect(last_response.header['Total']).to be_nil
143
- end
144
-
145
- it 'should not include a link with rel "last"' do
146
- get '/numbers', count: 100
147
-
148
- expect(link).to_not include('rel="last"')
149
- end
150
-
151
- after { ApiPagination.config.include_total = true }
152
- end
153
-
154
- context 'with query string including array parameter' do
155
- before do
156
- get '/numbers', { count: 100, parity: ['odd', 'even']}
157
- end
158
-
159
- it 'returns links with with same received parameters' do
160
- expect(links).to include('<http://example.org/numbers?count=100&page=10&parity%5B%5D=odd&parity%5B%5D=even>; rel="last"')
161
- expect(links).to include('<http://example.org/numbers?count=100&page=2&parity%5B%5D=odd&parity%5B%5D=even>; rel="next"')
162
- end
163
- end
164
- end
165
- end
data/spec/rails_spec.rb DELETED
@@ -1,312 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/shared_examples/existing_headers'
3
- require 'support/shared_examples/first_page'
4
- require 'support/shared_examples/middle_page'
5
- require 'support/shared_examples/last_page'
6
-
7
- describe NumbersController, :type => :controller do
8
- before { request.host = 'example.org' }
9
-
10
- describe 'GET #index' do
11
- let(:link) { response.headers['Link'] }
12
- let(:links) { link.split(', ') }
13
- let(:total) { response.headers['Total'].to_i }
14
- let(:per_page) { response.headers['Per-Page'].to_i }
15
-
16
- context 'without enough items to give more than one page' do
17
- before { get :index, params: {count: 10} }
18
-
19
- it 'should not paginate' do
20
- expect(response.headers.keys).not_to include('Link')
21
- end
22
-
23
- it 'should give a Total header' do
24
- expect(total).to eq(10)
25
- end
26
-
27
- it 'should give a Per-Page header' do
28
- expect(per_page).to eq(10)
29
- end
30
-
31
- it 'should list all numbers in the response body' do
32
- body = '[1,2,3,4,5,6,7,8,9,10]'
33
- expect(response.body).to eq(body)
34
- end
35
- end
36
-
37
- context 'with existing Link headers' do
38
- before { get :index, params: {count: 30, with_headers: true} }
39
-
40
- it_behaves_like 'an endpoint with existing Link headers'
41
- end
42
-
43
- context 'with enough items to paginate' do
44
- context 'when on the first page' do
45
- before { get :index, params: {count: 100} }
46
-
47
- it_behaves_like 'an endpoint with a first page'
48
- end
49
-
50
- context 'when on the last page' do
51
- before { get :index, params: {count: 100, page: 10} }
52
-
53
- it_behaves_like 'an endpoint with a last page'
54
- end
55
-
56
- context 'when somewhere comfortably in the middle' do
57
- before { get :index, params: {count: 100, page: 2} }
58
-
59
- it_behaves_like 'an endpoint with a middle page'
60
- end
61
- end
62
-
63
- context 'providing a block' do
64
- it 'yields to the block instead of implicitly rendering' do
65
- get :index_with_custom_render, params: {count: 100}
66
-
67
- json = { numbers: (1..10).map { |n| { number: n } } }.to_json
68
-
69
- expect(response.body).to eq(json)
70
- end
71
- end
72
-
73
- context 'with custom response headers' do
74
- before do
75
- ApiPagination.config.total_header = 'X-Total-Count'
76
- ApiPagination.config.per_page_header = 'X-Per-Page'
77
- ApiPagination.config.page_header = 'X-Page'
78
- ApiPagination.config.base_url = 'http://guybrush:3000'
79
-
80
- get :index, params: params
81
- end
82
-
83
- after do
84
- ApiPagination.config.total_header = 'Total'
85
- ApiPagination.config.per_page_header = 'Per-Page'
86
- ApiPagination.config.page_header = nil
87
- ApiPagination.config.base_url = nil
88
- end
89
-
90
- let(:params) { { count: 10 } }
91
- let(:total) { response.header['X-Total-Count'].to_i }
92
- let(:per_page) { response.header['X-Per-Page'].to_i }
93
- let(:page) { response.header['X-Page'].to_i }
94
- let(:link) { response.header['Link'] }
95
-
96
- it 'should give a X-Total-Count header' do
97
- headers_keys = response.headers.keys
98
-
99
- expect(headers_keys).not_to include('Total')
100
- expect(headers_keys).to include('X-Total-Count')
101
- expect(total).to eq(10)
102
- end
103
-
104
- it 'should give a X-Per-Page header' do
105
- headers_keys = response.headers.keys
106
-
107
- expect(headers_keys).not_to include('Per-Page')
108
- expect(headers_keys).to include('X-Per-Page')
109
- expect(per_page).to eq(10)
110
- end
111
-
112
- it 'should give a X-Page header' do
113
- headers_keys = response.headers.keys
114
-
115
- expect(headers_keys).to include('X-Page')
116
- expect(page).to eq(1)
117
- end
118
-
119
- context 'with paginated result' do
120
- let(:params) { { count: 20 } }
121
- it 'should use custom base_url in the Link header' do
122
-
123
- expect(response.headers['Link']).to eq(
124
- '<http://guybrush:3000/numbers?count=20&page=2>; rel="last", <http://guybrush:3000/numbers?count=20&page=2>; rel="next"')
125
- end
126
- end
127
- end
128
-
129
- context 'configured not to include the total' do
130
- before { ApiPagination.config.include_total = false }
131
-
132
- it 'should not include a Total header' do
133
- get :index, params: {count: 10}
134
-
135
- expect(response.header['Total']).to be_nil
136
- end
137
-
138
- it 'should not include a link with rel "last"' do
139
- get :index, params: { count: 100 }
140
-
141
- expect(link).to_not include('rel="last"')
142
- end
143
-
144
- after { ApiPagination.config.include_total = true }
145
- end
146
-
147
- context 'custom page param' do
148
- context 'page_param as a symbol' do
149
- before do
150
- ApiPagination.config.page_param = :foo
151
- ApiPagination.config.page_header = 'Page'
152
- end
153
-
154
- after do
155
- ApiPagination.config.page_param = :page
156
- ApiPagination.config.page_header = nil
157
- end
158
-
159
- it 'should work' do
160
- get :index, params: {foo: 2, count: 100}
161
-
162
- expect(response.header['Page']).to eq('2')
163
- end
164
- end
165
-
166
- context 'page_param as a block' do
167
- before do
168
- ApiPagination.config.page_param do |params|
169
- params[:foo][:bar]
170
- end
171
-
172
- ApiPagination.config.page_header = 'Page'
173
- end
174
-
175
- after do
176
- ApiPagination.config.page_param = :page
177
- ApiPagination.config.page_header = nil
178
- end
179
-
180
- it 'should work' do
181
- get :index, params: {foo: {bar: 2}, count: 100}
182
-
183
- expect(response.header['Page']).to eq('2')
184
- end
185
- end
186
- end
187
-
188
- context 'custom per_page param' do
189
- context 'per_page_param as a symbol' do
190
- before do
191
- ApiPagination.config.per_page_param = :foo
192
- end
193
-
194
- after do
195
- ApiPagination.config.per_page_param = :per_page
196
- end
197
-
198
- it 'should work' do
199
- get :index_with_no_per_page, params: {foo: 2, count: 100}
200
-
201
- expect(response.header['Per-Page']).to eq('2')
202
- end
203
- end
204
-
205
- context 'page_param as a block' do
206
- before do
207
- ApiPagination.config.per_page_param do |params|
208
- params[:foo][:bar]
209
- end
210
- end
211
-
212
- after do
213
- ApiPagination.config.per_page_param = :per_page
214
- end
215
-
216
- it 'should work' do
217
- get :index_with_no_per_page, params: {foo: {bar: 2}, count: 100}
218
-
219
- expect(response.header['Per-Page']).to eq('2')
220
- end
221
- end
222
- end
223
-
224
- if ApiPagination.config.paginator.to_sym == :kaminari
225
- context 'paginate array options' do
226
- let(:paginate_array_total_count) { 300 }
227
- let(:total_header) { 300 }
228
- let(:count) { 50 }
229
- let(:params) do
230
- {
231
- paginate_array_total_count: paginate_array_total_count,
232
- count: count,
233
- }
234
- end
235
-
236
- it 'has a properly set Total header' do
237
- get :index_with_paginate_array_options, params: params
238
-
239
- expect(response.header['Total']).to be_kind_of(String)
240
- expect(response.header['Total'].to_i).to eq total_header
241
- end
242
- end
243
- end
244
-
245
- if [:will_paginate, :kaminari].include?(ApiPagination.config.paginator.to_sym)
246
- context 'default per page in model' do
247
- before do
248
- class Fixnum
249
- @default_per_page = 6
250
- @per_page = 6
251
-
252
- class << self
253
- attr_accessor :default_per_page, :per_page
254
- end
255
- end
256
- end
257
-
258
- after do
259
- class Fixnum
260
- @default_per_page = 25
261
- @per_page = 25
262
- end
263
- end
264
-
265
- after :all do
266
- class Fixnum
267
- class << self
268
- undef_method :default_per_page, :per_page
269
- end
270
- end
271
- end
272
-
273
- it 'should use default per page from model' do
274
- get :index_with_no_per_page, params: {count: 100}
275
-
276
- expect(response.header['Per-Page']).to eq('6')
277
- end
278
-
279
- it 'should not fail if the model yields nil for per page' do
280
- class Fixnum
281
- @default_per_page = nil
282
- @per_page = nil
283
- end
284
-
285
- get :index_with_no_per_page, params: {count: 100}
286
-
287
- expect(response.header['Per-Page']).to eq(
288
- case ApiPagination.config.paginator
289
- when :pagy then Pagy::DEFAULT[:limit].to_s
290
- when :kaminari then Kaminari.config.default_per_page.to_s
291
- when :will_paginate then WillPaginate.per_page.to_s
292
- end
293
- )
294
- end
295
- end
296
- end
297
-
298
- context 'default per page in objects without paginator defaults' do
299
- it 'should not fail if model does not respond to per page' do
300
- get :index_with_no_per_page, params: {count: 100}
301
-
302
- expect(response.header['Per-Page']).to eq(
303
- case ApiPagination.config.paginator
304
- when :pagy then Pagy::DEFAULT[:limit].to_s
305
- when :kaminari then Kaminari.config.default_per_page.to_s
306
- when :will_paginate then WillPaginate.per_page.to_s
307
- end
308
- )
309
- end
310
- end
311
- end
312
- end
data/spec/sequel_spec.rb DELETED
@@ -1,30 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if ApiPagination.config.paginator == :will_paginate
4
- require 'sqlite3'
5
- require 'sequel'
6
- require 'will_paginate/sequel'
7
-
8
- DB = Sequel.sqlite
9
- DB.extension :pagination
10
- DB.create_table :people do
11
- primary_key :id
12
- String :name
13
- end
14
-
15
- describe 'Using will_paginate with Sequel' do
16
- let(:people) do
17
- DB[:people]
18
- end
19
-
20
- before(:each) do
21
- people.insert(name: 'John')
22
- people.insert(name: 'Mary')
23
- end
24
-
25
- it 'returns a Sequel::Dataset' do
26
- collection = ApiPagination.paginate(people).first
27
- expect(collection.kind_of?(Sequel::Dataset)).to be_truthy
28
- end
29
- end
30
- end
data/spec/spec_helper.rb DELETED
@@ -1,39 +0,0 @@
1
- require 'support/numbers_controller'
2
- require 'support/numbers_api'
3
- require 'api-pagination'
4
-
5
- if ENV['PAGINATOR'].nil?
6
- warn <<-WARNING
7
- No PAGINATOR set. Defaulting to pagy.
8
-
9
- To test against kaminari, run `PAGINATOR=kaminari bundle exec rspec`
10
- To test against will_paginate, run `PAGINATOR=will_paginate bundle exec rspec`
11
- WARNING
12
-
13
- ENV['PAGINATOR'] = 'pagy'
14
- end
15
-
16
- require ENV['PAGINATOR']
17
- ApiPagination.config.paginator = ENV['PAGINATOR'].to_sym
18
-
19
- require 'will_paginate/array' if ENV['PAGINATOR'].to_sym == :will_paginate
20
-
21
- RSpec.configure do |config|
22
- config.include Rack::Test::Methods
23
- config.include ControllerExampleGroup, :type => :controller
24
-
25
- # Disable the 'should' syntax.
26
- config.expect_with :rspec do |c|
27
- c.syntax = :expect
28
- end
29
-
30
- # Run specs in random order to surface order dependencies. If you find an
31
- # order dependency and want to debug it, you can fix the order by providing
32
- # the seed, which is printed after each run.
33
- # --seed 1234
34
- config.order = 'random'
35
-
36
- def app
37
- NumbersAPI
38
- end
39
- end
@@ -1,3 +0,0 @@
1
- require 'active_record'
2
-
3
- class Foo < ActiveRecord::Base; end
@@ -1,5 +0,0 @@
1
- ActiveRecord::Schema.define(version: 0) do
2
- create_table "foos", :force => true do |t|
3
- t.string "foo"
4
- end
5
- end
@@ -1,41 +0,0 @@
1
- require 'grape'
2
- require 'api-pagination'
3
-
4
- class NumbersAPI < Grape::API
5
- format :json
6
-
7
- desc 'Return some paginated set of numbers'
8
- paginate :per_page => 10
9
- params do
10
- requires :count, :type => Integer
11
- optional :with_headers, :default => false, :type => Boolean
12
- end
13
- get :numbers do
14
- if params[:with_headers]
15
- url = request.url.sub(/\?.*/, '')
16
- query = Rack::Utils.parse_query(request.query_string)
17
- query.delete('with_headers')
18
- header 'Link', %(<#{url}?#{query.to_query}>; rel="without")
19
- end
20
-
21
- paginate (1..params[:count]).to_a
22
- end
23
-
24
- desc 'Return some paginated set of numbers with max_per_page'
25
- paginate :per_page => 10, :max_per_page => 25
26
- params do
27
- requires :count, :type => Integer
28
- end
29
- get :numbers_with_max_per_page do
30
- paginate (1..params[:count]).to_a
31
- end
32
-
33
- desc 'Return some paginated set of numbers with max_per_page enforced'
34
- paginate :per_page => 10, :max_per_page => 25, :enforce_max_per_page => true
35
- params do
36
- requires :count, :type => Integer
37
- end
38
- get :numbers_with_enforced_max_per_page do
39
- paginate (1..params[:count]).to_a
40
- end
41
- end