Skip to content

Commit

Permalink
Add basic limiting & ordering to payments API
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Hansen committed Jan 30, 2014
1 parent 9c3bfac commit 7e86e3a
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 11 deletions.
40 changes: 38 additions & 2 deletions app/controllers/api/v0/payments_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
class Api::V0::PaymentsController < Api::V0::BaseController
ALLOWED_ORDER_BY_ATTRIBUTES = ['created_at', 'updated_at', 'ct_payment_id', 'status']

def index
campaign = Campaign.find_by_id!(params[:campaign_id])
render json: campaign.payments
resource = ApiResource.new(campaign.payments, params)
resource.apply_filters!

render json: resource.relation
end
end

private

class ApiResource < Struct.new(:relation, :params)
def apply_filters!
self.relation = apply_limit!(relation) if apply_limit?
self.relation = apply_order!(relation) if apply_order?
end

def apply_limit!(relation)
relation.limit(params[:limit])
end

def apply_order!(relation)
relation.order("#{params[:order_by]} #{order_direction}")
end

def apply_order?
String(params[:order_by]).in?(ALLOWED_ORDER_BY_ATTRIBUTES)
end

def apply_limit?
params[:limit].present?
end

private

def order_direction
params[:order_direction] == 'asc' ? 'asc' : 'desc'
end
end
end
92 changes: 83 additions & 9 deletions spec/controllers/api/v0/payments_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,93 @@

let(:campaign) { create(:campaign) }
let!(:first_payment) { create(:payment, campaign: campaign) }
let!(:second_payment) { create(:payment, campaign: campaign) }

subject { get :index, campaign_id: campaign.id, api_key: api_key }
def api_params(params={})
{campaign_id: campaign.id, api_key: api_key}.merge(params)
end

subject { get :index, api_params }

before do
PaymentSerializer.should_receive(:new).with(first_payment, anything)
.and_return(double("serializer", serializable_hash: {payment: 1}))
end

context 'for multiple records' do
let!(:second_payment) { create(:payment, campaign: campaign) }
before do

PaymentSerializer.should_receive(:new).with(second_payment, anything)
.and_return(double("serializer", serializable_hash: {payment: 2}))

end
it 'lists ALL of the payments for the campaign' do

subject

json = JSON.parse(response.body)
json.should == [{'payment' => 1}, {'payment' => 2}]
end
context 'ordering' do
let(:order) { '' }
let(:order_by) { 'created_at' }

subject { get :index, api_params(order_direction: order, order_by: order_by) }

it 'defaults to descending' do
subject

json = JSON.parse(response.body)
json.should == [{'payment' => 2}, {'payment' => 1}]
end

context 'ascending' do
let(:order) { 'asc' }

it 'respects the sort order' do
subject

json = JSON.parse(response.body)
json.should == [{'payment' => 1}, {'payment' => 2}]
end
end

context 'descending' do
let(:order) { 'desc' }

it 'respects the sort order' do
subject

json = JSON.parse(response.body)
json.should == [{'payment' => 2}, {'payment' => 1}]
end
end

context 'when ordering by a fake column' do
let(:order_by) { 'foobar' }

it 'returns the default order' do
subject


json = JSON.parse(response.body)
json.should == [{'payment' => 1}, {'payment' => 2}]
end
end
end
end

context 'limiting' do
let(:limit) { 1 }

it 'lists ALL of the payments for the campaign' do
serializer_double = double("serializer", serializable_hash: {payment: true})
PaymentSerializer.should_receive(:new).with(first_payment, anything).and_return(serializer_double)
PaymentSerializer.should_receive(:new).with(second_payment, anything).and_return(serializer_double)
subject { get :index, api_params(limit: limit) }

subject
it 'limits the objects returned' do
subject

json = JSON.parse(response.body)
json.should == [{'payment' => true}, {'payment' => true}]
JSON.parse(response.body).size.should == 1
end
end
end
end

0 comments on commit 7e86e3a

Please sign in to comment.