Skip to content

Instantly share code, notes, and snippets.

@jordelver
Created April 2, 2013 09:32
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jordelver/5291053 to your computer and use it in GitHub Desktop.
class BookingPaymentController < ApplicationController
def card
@credit_card_details = CreditCardDetails.new(params[:credit_card_details])
@credit_card_details.ip_address = request.ip
return unless request.post?
payment = MakesBookingPayment.new(
booking: @booking,
payment_details: @credit_card_details
)
if payment.pay!
redirect_to balance_trip_path, notice: 'Yay! Thanks for paying'
else
flash.now[:notice] = 'There was a problem taking your payment, please try again'
render 'card'
end
end
end
class MakesBookingPayment
attr_reader :booking, :payment_details, :payment_processor
def initialize(args)
@payment_details = args.fetch(:payment_details)
@booking = args.fetch(:booking)
@payment_processor = args.fetch(:payment_processor, PaymentProcessor)
end
def pay!
return false unless payment_details.valid?
response = booking_payment.pay!
record_transaction(response)
if response && response.success?
create_payment
return true
end
false
end
private
def booking_payment
payment_processor.new(
:amount => booking.balance,
:credit_card => payment_details.credit_card,
:payment_options => { ip: payment_details.ip_address }
)
end
def record_transaction(response)
booking.transactions.create!(
:action => 'purchase',
:amount => booking.balance,
:response => response
)
end
def create_payment
booking.payments.create!(
:amount => booking.balance,
:description => 'Payment for full balance',
:payment_method => 'Credit Card'
)
end
end
require "minitest/autorun"
require "minitest/pride"
require "mocha"
require_relative "../../app/models/makes_booking_payment"
require_relative "../../app/models/payment_processor"
describe MakesBookingPayment do
it "must return false if the payment details are invalid" do
makes_booking_payment = MakesBookingPayment.new(
payment_details: stub(:valid? => false),
booking: stub()
)
makes_booking_payment.pay!.must_equal false
end
it "must call the payment processor with the correct arguments" do
payment_details = stub_everything(
:valid? => true,
:errors => stub_everything(),
:ip_address => '1.2.3.4'
)
payment_processor_instance = mock()
payment_processor_instance.expects(:pay!).returns(stub_everything())
payment_processor = mock('Payment Processor')
payment_processor.expects(:new).with(
has_entries(
:amount => 1.23,
:payment_options => { ip: '1.2.3.4' }
)
).returns(payment_processor_instance)
makes_booking_payment = MakesBookingPayment.new(
payment_details: payment_details,
booking: stub_everything(:balance => 1.23, :transactions => stub_everything()),
payment_processor: payment_processor
)
makes_booking_payment.pay!
end
it "must keep a record of each transaction" do
response = mock('Payment response')
response.stub_everything()
payment_processor_instance = mock()
payment_processor_instance.stubs(:pay!).returns(response)
payment_processor = mock('Payment Processor')
payment_processor.stubs(:new).returns(payment_processor_instance)
transactions = mock()
transactions.expects(:create!).with(
has_entries(
:action => 'purchase',
:amount => 2.34,
:response => response
)
)
booking = mock()
booking.stubs(:balance => 2.34)
booking.stubs(:transactions).returns(transactions)
makes_booking_payment = MakesBookingPayment.new(
payment_details: stub_everything(:valid? => true),
booking: booking,
payment_processor: payment_processor
)
makes_booking_payment.pay!
end
it "must create a payment for successful transactions" do
response = mock('Payment response')
response.stubs(:success? => true)
payment_processor_instance = mock()
payment_processor_instance.stubs(:pay!).returns(response)
payment_processor = mock('Payment Processor')
payment_processor.stubs(:new).returns(payment_processor_instance)
transactions = mock('Booking transactions')
transactions.stubs(:create!)
payments = mock()
payments.expects(:create!).with(
has_entries(
:amount => 2.34,
:description => 'Payment for full balance',
:payment_method => 'Credit Card'
)
)
booking = mock()
booking.stubs(:balance => 2.34)
booking.stubs(:transactions).returns(transactions)
booking.stubs(:payments).returns(payments)
makes_booking_payment = MakesBookingPayment.new(
payment_details: stub_everything(:valid? => true),
booking: booking,
payment_processor: payment_processor
)
makes_booking_payment.pay!
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment