diff --git a/Rakefile b/Rakefile
index 4e970e4..29b6b92 100644
--- a/Rakefile
+++ b/Rakefile
@@ -3,11 +3,9 @@ require 'rake/testtask'
require 'rake/packagetask'
require 'rubygems/package_task'
require 'rspec/core/rake_task'
-require 'cucumber/rake/task'
require 'spree/core/testing_support/common_rake'
RSpec::Core::RakeTask.new
-Cucumber::Rake::Task.new
task :default => [:spec, :cucumber ]
diff --git a/app/assets/javascripts/admin/spree_paypal_express.js b/app/assets/javascripts/admin/spree_paypal_express.js
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/javascripts/store/spree_paypal_express.js b/app/assets/javascripts/store/spree_paypal_express.js
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/stylesheets/admin/spree_paypal_express.css b/app/assets/stylesheets/admin/spree_paypal_express.css
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/stylesheets/store/spree_paypal_express.css b/app/assets/stylesheets/store/spree_paypal_express.css
new file mode 100644
index 0000000..e69de29
diff --git a/app/controllers/spree/checkout_controller_decorator.rb b/app/controllers/spree/checkout_controller_decorator.rb
index 026fbbc..81801f9 100644
--- a/app/controllers/spree/checkout_controller_decorator.rb
+++ b/app/controllers/spree/checkout_controller_decorator.rb
@@ -90,9 +90,11 @@ module Spree
@order.ship_address = order_ship_address
@order.bill_address ||= order_ship_address
end
+ @order.state = "payment"
@order.save
if payment_method.preferred_review
+ @order.next
render 'spree/shared/paypal_express_confirm'
else
paypal_finish
@@ -145,8 +147,15 @@ module Spree
Rails.logger.error ppx_auth_response.to_yaml
end
- @order.update_attribute(:state, "complete")
+ @order.update_attributes({:state => "complete", :completed_at => Time.now}, :without_protection => true)
+
state_callback(:after) # So that after_complete is called, setting session[:order_id] to nil
+
+ # Since we dont rely on state machine callback, we just explicitly call this method for spree_store_credits
+ if @order.respond_to?(:consume_users_credit, true)
+ @order.send(:consume_users_credit)
+ end
+
@order.finalize!
flash[:notice] = I18n.t(:order_processed_successfully)
redirect_to completion_route
@@ -178,9 +187,8 @@ module Spree
return unless (params[:state] == "payment")
return unless params[:order][:payments_attributes]
- if params[:order][:coupon_code]
- @order.update_attributes(object_params)
- if @order.coupon_code.present?
+ if @order.update_attributes(object_params)
+ if params[:order][:coupon_code] and !params[:order][:coupon_code].blank? and @order.coupon_code.present?
fire_event('spree.checkout.coupon_code_added', :coupon_code => @order.coupon_code)
end
end
@@ -189,7 +197,7 @@ module Spree
payment_method = Spree::PaymentMethod.find(params[:order][:payments_attributes].first[:payment_method_id])
if payment_method.kind_of?(Spree::BillingIntegration::PaypalExpress) || payment_method.kind_of?(Spree::BillingIntegration::PaypalExpressUk)
- redirect_to paypal_payment_order_checkout_url(@order, :payment_method_id => payment_method)
+ redirect_to(paypal_payment_order_checkout_url(@order, :payment_method_id => payment_method.id)) and return
end
end
@@ -199,7 +207,7 @@ module Spree
else
user_action = Spree::PaypalExpress::Config[:paypal_express_local_confirm] == "t" ? "continue" : "commit"
end
-
+
#asset_url doesn't like Spree::Config[:logo] being an absolute url
#if statement didn't work within hash
if URI.parse(Spree::Config[:logo]).absolute?
@@ -214,7 +222,7 @@ module Spree
:background_color => "ffffff", # must be hex only, six chars
:header_background_color => "ffffff",
:header_border_color => "ffffff",
- :header_image => chosen_image,
+ :header_image => chosen_image,
:allow_note => true,
:locale => user_locale,
:req_confirm_shipping => false, # for security, might make an option later
diff --git a/app/models/spree/billing_integration/paypal_express.rb b/app/models/spree/billing_integration/paypal_express.rb
index 9509b67..572f19e 100644
--- a/app/models/spree/billing_integration/paypal_express.rb
+++ b/app/models/spree/billing_integration/paypal_express.rb
@@ -1,15 +1,3 @@
-class Spree::BillingIntegration::PaypalExpress < Spree::BillingIntegration
- preference :login, :string
- preference :password, :password
- preference :signature, :string
- preference :review, :boolean, :default => false
- preference :no_shipping, :boolean, :default => false
+class Spree::BillingIntegration::PaypalExpress < Spree::BillingIntegration::PaypalExpressBase
preference :currency, :string, :default => 'USD'
- preference :allow_guest_checkout, :boolean, :default => false
-
- attr_accessible :preferred_login, :preferred_password, :preferred_signature, :preferred_review, :preferred_no_shipping, :preferred_currency, :preferred_allow_guest_checkout, :preferred_server, :preferred_test_mode
-
- def provider_class
- ActiveMerchant::Billing::PaypalExpressGateway
- end
end
diff --git a/app/models/spree/billing_integration/paypal_express_base.rb b/app/models/spree/billing_integration/paypal_express_base.rb
new file mode 100644
index 0000000..d2e9820
--- /dev/null
+++ b/app/models/spree/billing_integration/paypal_express_base.rb
@@ -0,0 +1,62 @@
+class Spree::BillingIntegration::PaypalExpressBase < Spree::BillingIntegration
+ preference :login, :string
+ preference :password, :password
+ preference :signature, :string
+ preference :review, :boolean, :default => false
+ preference :no_shipping, :boolean, :default => false
+ preference :currency, :string, :default => 'USD'
+ preference :allow_guest_checkout, :boolean, :default => false
+
+ attr_accessible :preferred_login, :preferred_password, :preferred_signature, :preferred_review, :preferred_no_shipping, :preferred_currency, :preferred_allow_guest_checkout, :preferred_server, :preferred_test_mode
+
+ def provider_class
+ ActiveMerchant::Billing::PaypalExpressGateway
+ end
+
+ def payment_profiles_supported?
+ !!preferred_review
+ end
+
+ def capture(payment_or_amount, account_or_response_code, gateway_options)
+ if payment_or_amount.is_a?(Spree::Payment)
+ authorization = find_authorization(payment_or_amount)
+ provider.capture(amount_in_cents(payment_or_amount.amount), authorization.params["transaction_id"], :currency => preferred_currency)
+ else
+ provider.capture(payment_or_amount, account_or_response_code, :currency => preferred_currency)
+ end
+ end
+
+ def credit(*args)
+ amount = args.shift
+ response_code = args.first.is_a?(String) ? args.first : args[1]
+ provider.credit(amount, response_code, :currency => preferred_currency)
+ end
+
+ def find_authorization(payment)
+ logs = payment.log_entries.all(:order => 'created_at DESC')
+ logs.each do |log|
+ details = YAML.load(log.details) # return the transaction details
+ if (details.params['payment_status'] == 'Pending' && details.params['pending_reason'] == 'authorization')
+ return details
+ end
+ end
+ return nil
+ end
+
+ def find_capture(payment)
+ #find the transaction associated with the original authorization/capture
+ logs = payment.log_entries.all(:order => 'created_at DESC')
+ logs.each do |log|
+ details = YAML.load(log.details) # return the transaction details
+ if details.params['payment_status'] == 'Completed'
+ return details
+ end
+ end
+ return nil
+ end
+
+ def amount_in_cents(amount)
+ (100 * amount).to_i
+ end
+
+end
\ No newline at end of file
diff --git a/app/models/spree/billing_integration/paypal_express_uk.rb b/app/models/spree/billing_integration/paypal_express_uk.rb
index 7021b37..3dc9a79 100644
--- a/app/models/spree/billing_integration/paypal_express_uk.rb
+++ b/app/models/spree/billing_integration/paypal_express_uk.rb
@@ -1,16 +1,3 @@
-class Spree::BillingIntegration::PaypalExpressUk < Spree::BillingIntegration
- preference :login, :string
- preference :password, :password
- preference :signature, :string
- preference :review, :boolean, :default => false
- preference :no_shipping, :boolean, :default => false
+class Spree::BillingIntegration::PaypalExpressUk < Spree::BillingIntegration::PaypalExpressBase
preference :currency, :string, :default => 'GBP'
- preference :allow_guest_checkout, :boolean, :default => false
-
- attr_accessible :preferred_login, :preferred_password, :preferred_signature, :preferred_review, :preferred_currency, :preferred_no_shipping, :preferred_server, :preferred_test_mode
-
- def provider_class
- ActiveMerchant::Billing::PaypalExpressGateway
- end
-
end
diff --git a/app/models/spree/paypal_account.rb b/app/models/spree/paypal_account.rb
index cc09d6a..8980ab1 100644
--- a/app/models/spree/paypal_account.rb
+++ b/app/models/spree/paypal_account.rb
@@ -6,46 +6,15 @@ class Spree::PaypalAccount < ActiveRecord::Base
%w{capture credit}
end
- def capture(payment)
- authorization = find_authorization(payment)
-
- ppx_response = payment.payment_method.provider.capture(amount_in_cents(payment.amount), authorization.params["transaction_id"], :currency => payment.payment_method.preferred_currency)
- if ppx_response.success?
- record_log payment, ppx_response
- payment.complete
- else
- gateway_error(ppx_response.message)
- end
-
- end
-
def can_capture?(payment)
!echeck?(payment) && payment.state == "pending"
end
- def credit(payment, amount=nil)
- authorization = find_capture(payment)
-
- amount = payment.credit_allowed >= payment.order.outstanding_balance.abs ? payment.order.outstanding_balance : payment.credit_allowed
- amount=amount.abs if amount
-
- ppx_response = payment.payment_method.provider.credit(amount.nil? ? amount_in_cents(amount) : amount_in_cents(amount), authorization.params['transaction_id'], :currency => payment.payment_method.preferred_currency)
-
- if ppx_response.success?
- record_log payment, ppx_response
- payment.update_attribute(:amount, payment.amount - amount)
- payment.complete
- payment.order.update!
- else
- gateway_error(ppx_response.message)
- end
- end
-
def can_credit?(payment)
return false unless payment.state == "completed"
return false unless payment.order.payment_state == "credit_owed"
payment.credit_allowed > 0
- !find_capture(payment).nil?
+ !payment.payment_method.find_capture(payment).nil?
end
# fix for Payment#payment_profiles_supported?
@@ -64,43 +33,4 @@ class Spree::PaypalAccount < ActiveRecord::Base
return false
end
- def record_log(payment, response)
- payment.log_entries.create(:details => response.to_yaml)
- end
-
- private
- def find_authorization(payment)
- logs = payment.log_entries.all(:order => 'created_at DESC')
- logs.each do |log|
- details = YAML.load(log.details) # return the transaction details
- if (details.params['payment_status'] == 'Pending' && details.params['pending_reason'] == 'authorization')
- return details
- end
- end
- return nil
- end
-
- def find_capture(payment)
- #find the transaction associated with the original authorization/capture
- logs = payment.log_entries.all(:order => 'created_at DESC')
- logs.each do |log|
- details = YAML.load(log.details) # return the transaction details
- if details.params['payment_status'] == 'Completed'
- return details
- end
- end
- return nil
- end
-
- def gateway_error(text)
- msg = "#{I18n.t('gateway_error')} ... #{text}"
- logger.error(msg)
- raise Spree::Core::GatewayError.new(msg)
- end
-
- private
-
- def amount_in_cents(amount)
- (100 * amount).to_i
- end
end
diff --git a/app/views/spree/shared/paypal_express_confirm.html.erb b/app/views/spree/shared/paypal_express_confirm.html.erb
index 879fb42..2956f44 100644
--- a/app/views/spree/shared/paypal_express_confirm.html.erb
+++ b/app/views/spree/shared/paypal_express_confirm.html.erb
@@ -1,10 +1,23 @@
-
<%= t("confirm") %>
-
- <%= raw t("order_not_yet_placed") %>
-
+
+ <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @order } %>
-<%= render :partial => 'spree/shared/order_details', :locals => {:order => @order} -%>
-
- <%= button_to t('place_order'), paypal_finish_order_checkout_url(@order, {:token => params[:token] , :PayerID => params[:PayerID], :payment_method_id =>
- params[:payment_method_id] } ), :class => "button primary" %>
-
+
+
<%= t(:checkout) %>
+
<%= checkout_progress %>
+
+
+
+ <%= raw t(:order_not_yet_placed) %>
+
+
+
+
+ <%= render :partial => 'spree/shared/order_details', :locals => {:order => @order} -%>
+
+
+ <%= button_to t(:place_order), paypal_finish_order_checkout_url(@order, {:token => params[:token] , :PayerID => params[:PayerID], :payment_method_id => params[:payment_method_id] } ), :class => "button primary" %>
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/spree_paypal_express.rb b/lib/spree_paypal_express.rb
index e3dafc3..60822df 100644
--- a/lib/spree_paypal_express.rb
+++ b/lib/spree_paypal_express.rb
@@ -1,2 +1,3 @@
require 'spree_core'
+require 'spree_auth'
require 'spree_paypal_express/engine'
diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb
index e559811..1c4fa22 100644
--- a/spec/controllers/checkout_controller_spec.rb
+++ b/spec/controllers/checkout_controller_spec.rb
@@ -2,8 +2,10 @@ require File.dirname(__FILE__) + '/../spec_helper'
module Spree
describe CheckoutController do
+ render_views
let(:token) { "EC-2OPN7UJGFWK9OYFV" }
- let(:order) { Factory(:ppx_order_with_totals, :state => "payment") }
+ let(:order) { Factory(:ppx_order_with_totals, :state => "payment", :shipping_method => shipping_method) }
+ let(:shipping_method) { FactoryGirl.create(:shipping_method, :zone => Spree::Zone.find_by_name('North America')) }
let(:order_total) { (order.total * 100).to_i }
let(:gateway_provider) { mock(ActiveMerchant::Billing::PaypalExpressGateway) }
let(:paypal_gateway) { mock(BillingIntegration::PaypalExpress, :id => 123, :preferred_review => false, :preferred_no_shipping => true, :provider => gateway_provider, :preferred_currency => "US", :preferred_allow_guest_checkout => true
@@ -73,7 +75,10 @@ module Spree
end
context "paypal_confirm" do
- before { PaymentMethod.should_receive(:find).at_least(1).with("123").and_return(paypal_gateway) }
+ before do
+ PaymentMethod.should_receive(:find).at_least(1).with("123").and_return(paypal_gateway)
+ order.stub!(:payment_method).and_return paypal_gateway
+ end
context "with auto_capture and no review" do
before do
@@ -92,13 +97,17 @@ module Spree
order.reload
order.state.should == "complete"
+ order.completed_at.should_not be_nil
order.payments.size.should == 1
order.payment_state.should == "paid"
end
end
context "with review" do
- before { paypal_gateway.stub(:preferred_review => true) }
+ before do
+ paypal_gateway.stub(:preferred_review => true, :payment_profiles_supported? => true)
+ order.stub_chain(:payment, :payment_method, :payment_profiles_supported? => true)
+ end
it "should render review" do
paypal_gateway.provider.should_receive(:details_for).with(token).and_return(details_for_response)
@@ -106,7 +115,15 @@ module Spree
get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
response.should render_template("shared/paypal_express_confirm")
+ order.state.should == "confirm"
+ end
+ it "order state should not change on multiple call" do
+ paypal_gateway.provider.should_receive(:details_for).twice.with(token).and_return(details_for_response)
+
+ get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
+ get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
+ order.state.should == "confirm"
end
end
@@ -114,7 +131,8 @@ module Spree
before do
paypal_gateway.stub(:preferred_review => true)
paypal_gateway.stub(:preferred_no_shipping => false)
-
+ paypal_gateway.stub(:payment_profiles_supported? => true)
+ order.stub_chain(:payment, :payment_method, :payment_profiles_supported? => true)
details_for_response.stub(:params => details_for_response.params.merge({'first_name' => 'Dr.', 'last_name' => 'Evil'}),
:address => {'address1' => 'Apt. 187', 'address2'=> 'Some Str.', 'city' => 'Chevy Chase', 'country' => 'US', 'zip' => '20815', 'state' => 'MD' })
@@ -126,6 +144,7 @@ module Spree
get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
order.ship_address.address1.should == "Apt. 187"
+ order.state.should == "confirm"
response.should render_template("shared/paypal_express_confirm")
end
end
diff --git a/spec/factories/ppx_factory.rb b/spec/factories/ppx_factory.rb
new file mode 100644
index 0000000..86a47d1
--- /dev/null
+++ b/spec/factories/ppx_factory.rb
@@ -0,0 +1,5 @@
+FactoryGirl.define do
+ factory :ppx, :class => Spree::BillingIntegration::PaypalExpress, :parent => :payment_method do
+ name 'Paypal'
+ end
+end
\ No newline at end of file
diff --git a/spec/models/billing_integration/paypal_express_base_spec.rb b/spec/models/billing_integration/paypal_express_base_spec.rb
new file mode 100644
index 0000000..a346839
--- /dev/null
+++ b/spec/models/billing_integration/paypal_express_base_spec.rb
@@ -0,0 +1,135 @@
+require 'spec_helper'
+
+describe Spree::BillingIntegration::PaypalExpressBase do
+ let(:order) do
+ order = Spree::Order.new(:bill_address => Spree::Address.new,
+ :ship_address => Spree::Address.new)
+ end
+
+ let(:gateway) do
+ gateway = Spree::BillingIntegration::PaypalExpressBase.new({:environment => 'test', :active => true, :preferred_currency => "EUR"}, :without_protection => true)
+ gateway.stub :source_required => true
+ gateway.stub :provider => mock('paypal provider')
+ gateway.stub :find_authorization => mock('authorization', :params => authorization_params)
+ gateway
+ end
+
+ let(:authorization_params) { {'transaction_id' => '123'} }
+ let(:provider) { gateway.provider }
+
+ let(:account) do
+ mock_model(Spree::PaypalAccount)
+ end
+
+ let(:payment) do
+ payment = Spree::Payment.new
+ payment.source = account
+ payment.order = order
+ payment.payment_method = gateway
+ payment.amount = 10.0
+ payment
+ end
+
+ let(:amount_in_cents) { payment.amount.to_f * 100 }
+
+ let!(:success_response) do
+ mock('success_response', :success? => true,
+ :authorization => '123',
+ :avs_result => { 'code' => 'avs-code' })
+ end
+
+ let(:failed_response) { mock('gateway_response', :success? => false) }
+
+ before(:each) do
+ # So it doesn't create log entries every time a processing method is called
+ payment.log_entries.stub(:create)
+ end
+
+ describe "#capture" do
+ before { payment.state = 'pending' }
+
+ context "when payment_profiles_supported = true" do
+ before { gateway.stub :payment_profiles_supported? => true }
+
+ context "if sucessful" do
+ before do
+ provider.should_receive(:capture).with(amount_in_cents, '123', :currency => 'EUR').and_return(success_response)
+ end
+
+ it "should store the response_code" do
+ payment.capture!
+ payment.response_code.should == '123'
+ end
+ end
+
+ context "if unsucessful" do
+ before do
+ gateway.should_receive(:capture).with(payment, account, anything).and_return(failed_response)
+ end
+
+ it "should not make payment complete" do
+ lambda { payment.capture! }.should raise_error(Spree::Core::GatewayError)
+ payment.state.should == "failed"
+ end
+ end
+ end
+
+ context "when payment_profiles_supported = false" do
+ before do
+ payment.stub :response_code => '123'
+ gateway.stub :payment_profiles_supported? => false
+ end
+
+ context "if sucessful" do
+ before do
+ provider.should_receive(:capture).with(amount_in_cents, '123', anything).and_return(success_response)
+ end
+
+ it "should store the response_code" do
+ payment.capture!
+ payment.response_code.should == '123'
+ end
+ end
+
+ context "if unsucessful" do
+ before do
+ provider.should_receive(:capture).with(amount_in_cents, '123', anything).and_return(failed_response)
+ end
+
+ it "should not make payment complete" do
+ lambda { payment.capture! }.should raise_error(Spree::Core::GatewayError)
+ payment.state.should == "failed"
+ end
+ end
+
+ end
+ end
+
+ describe "#credit" do
+ before { payment.stub :response_code => '123' }
+ context "when payment_profiles_supported = true" do
+ before { gateway.stub :payment_profiles_supported? => true }
+
+
+ it "should receive correct params" do
+ provider.should_receive(:credit).with(1000, '123', :currency => 'EUR').and_return(success_response)
+ payment.credit!(10.0)
+ payment.response_code.should == '123'
+ end
+ end
+
+ context "when payment_profiles_supported = false" do
+ before do
+ payment.stub :response_code => '123'
+ gateway.stub :payment_profiles_supported? => false
+ end
+
+ it "should receive correct params" do
+ provider.should_receive(:credit).with(amount_in_cents, '123', :currency => 'EUR').and_return(success_response)
+ payment.credit!(10.0)
+ payment.response_code.should == '123'
+ end
+
+ end
+ end
+end
diff --git a/spec/requests/paypal_express_spec.rb b/spec/requests/paypal_express_spec.rb
new file mode 100644
index 0000000..0d8c33c
--- /dev/null
+++ b/spec/requests/paypal_express_spec.rb
@@ -0,0 +1,38 @@
+require 'spec_helper'
+
+feature "paypal express" do
+ background do
+ PAYMENT_STATES = Spree::Payment.state_machine.states.keys unless defined? PAYMENT_STATES
+ SHIPMENT_STATES = Spree::Shipment.state_machine.states.keys unless defined? SHIPMENT_STATES
+ ORDER_STATES = Spree::Order.state_machine.states.keys unless defined? ORDER_STATES
+ FactoryGirl.create(:shipping_method, :zone => Spree::Zone.find_by_name('North America'))
+ FactoryGirl.create(:payment_method, :environment => 'test')
+ @product = FactoryGirl.create(:product, :name => "RoR Mug")
+ sign_in_as! FactoryGirl.create(:user)
+
+ Factory(:ppx)
+ end
+
+ let!(:address) { FactoryGirl.create(:address, :state => Spree::State.first) }
+
+ scenario "can use paypal confirm", :js => true do
+ visit spree.product_path(@product)
+
+ click_button "Add To Cart"
+ click_link "Checkout"
+
+ str_addr = "bill_address"
+ select "United States", :from => "order_#{str_addr}_attributes_country_id"
+ ['firstname', 'lastname', 'address1', 'city', 'zipcode', 'phone'].each do |field|
+ fill_in "order_#{str_addr}_attributes_#{field}", :with => "#{address.send(field)}"
+ end
+
+ select "#{address.state.name}", :from => "order_#{str_addr}_attributes_state_id"
+ check "order_use_billing"
+ click_button "Save and Continue"
+
+ pending
+ choose "Paypal"
+ click_button "Save and Continue"
+ end
+end
\ No newline at end of file
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index b865e87..70631c3 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -18,6 +18,8 @@ Dir["#{File.dirname(__FILE__)}/factories/**/*.rb"].each do |f|
require fp
end
+require 'ffaker'
+
RSpec.configure do |config|
# == Mock Framework
#
diff --git a/spec/support/authentication_helpers.rb b/spec/support/authentication_helpers.rb
new file mode 100644
index 0000000..2de8eb3
--- /dev/null
+++ b/spec/support/authentication_helpers.rb
@@ -0,0 +1,13 @@
+module AuthenticationHelpers
+ def sign_in_as!(user)
+ visit '/login'
+ fill_in 'Email', :with => user.email
+ fill_in 'Password', :with => 'secret'
+ click_button 'Login'
+ end
+
+end
+
+RSpec.configure do |c|
+ c.include AuthenticationHelpers, :type => :request
+end
diff --git a/spec/support/shared_connection.rb b/spec/support/shared_connection.rb
new file mode 100644
index 0000000..7d8b40c
--- /dev/null
+++ b/spec/support/shared_connection.rb
@@ -0,0 +1,12 @@
+class ActiveRecord::Base
+ mattr_accessor :shared_connection
+ @@shared_connection = nil
+
+ def self.connection
+ @@shared_connection || retrieve_connection
+ end
+end
+
+# Forces all threads to share the same connection. This works on
+# Capybara because it starts the web server in a thread.
+ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
\ No newline at end of file
diff --git a/spree_paypal_express.gemspec b/spree_paypal_express.gemspec
index d073314..56f145c 100644
--- a/spree_paypal_express.gemspec
+++ b/spree_paypal_express.gemspec
@@ -14,5 +14,16 @@ Gem::Specification.new do |s|
s.has_rdoc = false
s.add_dependency('spree_core', '>=1.0.0')
- s.add_development_dependency('rspec-rails')
+ s.add_dependency('spree_auth', '>=1.0.0')
+ s.add_development_dependency 'capybara', '1.0.1'
+ s.add_development_dependency 'ffaker'
+ s.add_development_dependency 'rspec-rails', '~> 2.9'
+ s.add_development_dependency 'sqlite3'
+ s.add_development_dependency 'factory_girl_rails', '~> 1.5.0'
+ s.add_development_dependency 'launchy'
+ s.add_development_dependency 'debugger'
+ s.add_development_dependency 'sass-rails'
+ s.add_development_dependency 'coffee-rails'
+ s.add_development_dependency 'spree_sample', "~> 1.1.0"
+ s.add_development_dependency 'debugger'
end