Skip to content

Commit

Permalink
feature: paginating params preprocessing
Browse files Browse the repository at this point in the history
  • Loading branch information
deniskorobicyn committed May 6, 2016
1 parent ad0bc33 commit c8935c8
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 3 deletions.
39 changes: 39 additions & 0 deletions lib/apress/api/api_controller/pagination.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,45 @@ module Apress
module Api
module ApiController
module Pagination
class InvalidPaginationError < StandardError; end

extend ActiveSupport::Concern

included do
attr_reader :per_page, :page
alias_method :current_page, :page
rescue_from InvalidPaginationError, with: :bad_request
end

DEFAULT_PER_PAGE = 30
MAX_PER_PAGE = 100

# Public: sets page and per_page variables
#
# options - Hash, configuration
# :per_page - Hash, per_page value configuration
# :max - Integer, max per_page value
# :defuault - Integer, default value for per_page
# Examples
# prepare_pagination(per_page: {max: 110, default: 40})
#
# or with defaults max - 100 and default - 30
#
# prepare_pagination
#
# Returns nothing
def prepare_pagination(options = {})
per_page = options.fetch(:per_page, {})
max_per_page = per_page.fetch(:max, MAX_PER_PAGE)
default_per_page = per_page.fetch(:default, DEFAULT_PER_PAGE)

@page = params.fetch(:page, 1).to_i
raise InvalidPaginationError if @page <= 0

@per_page = params.fetch(:per_page, default_per_page).to_i
raise InvalidPaginationError unless (1..max_per_page).include?(@per_page)
end

def pagination_headers(collection)
headers["X-Total-Count"] = collection.total_entries.to_s
headers["X-Total-Pages"] = collection.total_pages.to_s
Expand Down
51 changes: 48 additions & 3 deletions spec/controllers/api_controller/pagination_spec.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,60 @@
require "spec_helper"

describe Apress::Api::ApiController::Base, type: :controller do
controller do
def index
render json: {status: "ok"}
describe '#prepare_pagination' do
controller do
skip_before_filter :authenticate

def index
prepare_pagination(per_page: {max: 100, default: 40})
head 204
end
end

context 'when params present' do
context 'when params are valid' do
it 'sets variables' do
get :index, page: 2, per_page: 5

expect(assigns(:page)).to eq 2
expect(assigns(:per_page)).to eq 5
end
end

context 'when params are invalid' do
it 'returns 400 for negative page' do
get :index, page: -1

expect(response.status).to eq 400
end

it 'returns 400 for > max per_page value' do
get :index, per_page: 101

expect(response.status).to eq 400
end
end
end

context 'when no params are set' do
it 'sets defaults' do
get :index

expect(assigns(:page)).to eq 1
expect(assigns(:per_page)).to eq 40
end
end
end

describe "#pagination_headers" do
let(:collection) { double(total_entries: 30, total_pages: 10) }

controller do
def index
render json: {status: "ok"}
end
end

context "when auth successfull" do
before do
get :index
Expand Down

0 comments on commit c8935c8

Please sign in to comment.