spree_payflow 0.60.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.
@@ -0,0 +1,9 @@
1
+ \#*
2
+ *~
3
+ .#*
4
+ .DS_Store
5
+ .idea
6
+ .project
7
+ tmp
8
+ nbproject
9
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,33 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'rspec-rails', '= 2.5.0'
5
+ gem 'factory_girl', '= 1.3.3'
6
+ gem 'factory_girl_rails', '= 1.0.1'
7
+ gem 'rcov'
8
+ gem 'shoulda'
9
+ gem 'faker'
10
+ if RUBY_VERSION < "1.9"
11
+ gem "ruby-debug"
12
+ else
13
+ gem "ruby-debug19"
14
+ end
15
+ end
16
+
17
+ group :cucumber do
18
+ gem 'cucumber-rails'
19
+ gem 'database_cleaner', '= 0.6.7'
20
+ gem 'nokogiri'
21
+ gem 'capybara', '= 0.4.1.2'
22
+ gem 'factory_girl', '= 1.3.3'
23
+ gem 'factory_girl_rails', '= 1.0.1'
24
+ gem 'faker'
25
+ gem 'launchy'
26
+
27
+ if RUBY_VERSION < "1.9"
28
+ gem "ruby-debug"
29
+ else
30
+ gem "ruby-debug19"
31
+ end
32
+ end
33
+ gem 'sqlite3-ruby'
@@ -0,0 +1,139 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionpack (3.0.9)
6
+ activemodel (= 3.0.9)
7
+ activesupport (= 3.0.9)
8
+ builder (~> 2.1.2)
9
+ erubis (~> 2.6.6)
10
+ i18n (~> 0.5.0)
11
+ rack (~> 1.2.1)
12
+ rack-mount (~> 0.6.14)
13
+ rack-test (~> 0.5.7)
14
+ tzinfo (~> 0.3.23)
15
+ activemodel (3.0.9)
16
+ activesupport (= 3.0.9)
17
+ builder (~> 2.1.2)
18
+ i18n (~> 0.5.0)
19
+ activesupport (3.0.9)
20
+ archive-tar-minitar (0.5.2)
21
+ builder (2.1.2)
22
+ capybara (0.4.1.2)
23
+ celerity (>= 0.7.9)
24
+ culerity (>= 0.2.4)
25
+ mime-types (>= 1.16)
26
+ nokogiri (>= 1.3.3)
27
+ rack (>= 1.0.0)
28
+ rack-test (>= 0.5.4)
29
+ selenium-webdriver (>= 0.0.27)
30
+ xpath (~> 0.1.3)
31
+ celerity (0.8.9)
32
+ childprocess (0.1.9)
33
+ ffi (~> 1.0.6)
34
+ columnize (0.3.4)
35
+ configuration (1.3.1)
36
+ cucumber (1.0.0)
37
+ builder (>= 2.1.2)
38
+ diff-lcs (>= 1.1.2)
39
+ gherkin (~> 2.4.1)
40
+ json (>= 1.4.6)
41
+ term-ansicolor (>= 1.0.5)
42
+ cucumber-rails (0.4.1)
43
+ cucumber (>= 0.10.1)
44
+ nokogiri (>= 1.4.4)
45
+ rack-test (>= 0.5.7)
46
+ culerity (0.2.15)
47
+ database_cleaner (0.6.7)
48
+ diff-lcs (1.1.2)
49
+ erubis (2.6.6)
50
+ abstract (>= 1.0.0)
51
+ factory_girl (1.3.3)
52
+ factory_girl_rails (1.0.1)
53
+ factory_girl (~> 1.3)
54
+ railties (>= 3.0.0)
55
+ faker (0.9.5)
56
+ i18n (~> 0.4)
57
+ ffi (1.0.9)
58
+ gherkin (2.4.1)
59
+ json (>= 1.4.6)
60
+ i18n (0.5.0)
61
+ json (1.5.3)
62
+ json_pure (1.5.3)
63
+ launchy (0.4.0)
64
+ configuration (>= 0.0.5)
65
+ rake (>= 0.8.1)
66
+ linecache19 (0.5.12)
67
+ ruby_core_source (>= 0.1.4)
68
+ mime-types (1.16)
69
+ nokogiri (1.5.0)
70
+ rack (1.2.3)
71
+ rack-mount (0.6.14)
72
+ rack (>= 1.0.0)
73
+ rack-test (0.5.7)
74
+ rack (>= 1.0)
75
+ railties (3.0.9)
76
+ actionpack (= 3.0.9)
77
+ activesupport (= 3.0.9)
78
+ rake (>= 0.8.7)
79
+ rdoc (~> 3.4)
80
+ thor (~> 0.14.4)
81
+ rake (0.9.2)
82
+ rcov (0.9.9)
83
+ rdoc (3.8)
84
+ rspec (2.5.0)
85
+ rspec-core (~> 2.5.0)
86
+ rspec-expectations (~> 2.5.0)
87
+ rspec-mocks (~> 2.5.0)
88
+ rspec-core (2.5.2)
89
+ rspec-expectations (2.5.0)
90
+ diff-lcs (~> 1.1.2)
91
+ rspec-mocks (2.5.0)
92
+ rspec-rails (2.5.0)
93
+ actionpack (~> 3.0)
94
+ activesupport (~> 3.0)
95
+ railties (~> 3.0)
96
+ rspec (~> 2.5.0)
97
+ ruby-debug-base19 (0.11.25)
98
+ columnize (>= 0.3.1)
99
+ linecache19 (>= 0.5.11)
100
+ ruby_core_source (>= 0.1.4)
101
+ ruby-debug19 (0.11.6)
102
+ columnize (>= 0.3.1)
103
+ linecache19 (>= 0.5.11)
104
+ ruby-debug-base19 (>= 0.11.19)
105
+ ruby_core_source (0.1.5)
106
+ archive-tar-minitar (>= 0.5.2)
107
+ rubyzip (0.9.4)
108
+ selenium-webdriver (2.0.0)
109
+ childprocess (>= 0.1.9)
110
+ ffi (>= 1.0.7)
111
+ json_pure
112
+ rubyzip
113
+ shoulda (2.11.3)
114
+ sqlite3 (1.3.3)
115
+ sqlite3-ruby (1.3.3)
116
+ sqlite3 (>= 1.3.3)
117
+ term-ansicolor (1.0.5)
118
+ thor (0.14.6)
119
+ tzinfo (0.3.29)
120
+ xpath (0.1.4)
121
+ nokogiri (~> 1.3)
122
+
123
+ PLATFORMS
124
+ ruby
125
+
126
+ DEPENDENCIES
127
+ capybara (= 0.4.1.2)
128
+ cucumber-rails
129
+ database_cleaner (= 0.6.7)
130
+ factory_girl (= 1.3.3)
131
+ factory_girl_rails (= 1.0.1)
132
+ faker
133
+ launchy
134
+ nokogiri
135
+ rcov
136
+ rspec-rails (= 2.5.0)
137
+ ruby-debug19
138
+ shoulda
139
+ sqlite3-ruby
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Redistribution and use in source and binary forms, with or without modification,
2
+ are permitted provided that the following conditions are met:
3
+
4
+ * Redistributions of source code must retain the above copyright notice,
5
+ this list of conditions and the following disclaimer.
6
+ * Redistributions in binary form must reproduce the above copyright notice,
7
+ this list of conditions and the following disclaimer in the documentation
8
+ and/or other materials provided with the distribution.
9
+ * Neither the name of the Rails Dog LLC nor the names of its
10
+ contributors may be used to endorse or promote products derived from this
11
+ software without specific prior written permission.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,13 @@
1
+ SpreePayflow
2
+ ============
3
+
4
+ Introduction goes here.
5
+
6
+
7
+ Example
8
+ =======
9
+
10
+ Example goes here.
11
+
12
+
13
+ Copyright (c) 2011 Chad Nantais, released under the New BSD License
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'rake/testtask'
5
+
6
+ desc "Default Task"
7
+ task :default => [ :spec ]
8
+
9
+ gemfile = File.expand_path('../spec/test_app/Gemfile', __FILE__)
10
+ if File.exists?(gemfile) && %w(rcov spec cucumber).include?(ARGV.first.to_s)
11
+ require 'bundler'
12
+ ENV['BUNDLE_GEMFILE'] = gemfile
13
+ Bundler.setup
14
+
15
+ require 'rspec/core/rake_task'
16
+ RSpec::Core::RakeTask.new
17
+
18
+ require 'cucumber/rake/task'
19
+ Cucumber::Rake::Task.new do |t|
20
+ t.cucumber_opts = %w{--format pretty}
21
+ end
22
+
23
+ desc "Run specs with RCov"
24
+ RSpec::Core::RakeTask.new(:rcov) do |t|
25
+ t.rcov = true
26
+ t.rcov_opts = %w{ --exclude gems\/,spec\/,features\/}
27
+ t.verbose = true
28
+ end
29
+
30
+ end
31
+
32
+ desc "Regenerates a rails 3 app for testing"
33
+ task :test_app do
34
+ SPREE_PATH = ENV['SPREE_PATH']
35
+ raise "SPREE_PATH should be specified" unless SPREE_PATH
36
+ require File.join(SPREE_PATH, 'lib/generators/spree/test_app_generator')
37
+ class AuthTestAppGenerator < Spree::Generators::TestAppGenerator
38
+ def tweak_gemfile
39
+ append_file 'Gemfile' do
40
+ <<-gems
41
+ gem 'spree_core', :path => '#{File.join(SPREE_PATH, 'core')}'
42
+ gem 'spree_auth', :path => '#{File.join(SPREE_PATH, 'auth')}'
43
+ gem 'spree_payflow', :path => '#{File.dirname(__FILE__)}'
44
+ gems
45
+ end
46
+ end
47
+
48
+ def install_gems
49
+ inside "test_app" do
50
+ run 'rake spree_core:install'
51
+ run 'rake spree_auth:install'
52
+ run 'rake spree_payflow:install'
53
+ end
54
+ end
55
+
56
+ def migrate_db
57
+ run_migrations
58
+ end
59
+ end
60
+ AuthTestAppGenerator.start
61
+ end
62
+
63
+ namespace :test_app do
64
+ desc 'Rebuild test and cucumber databases'
65
+ task :rebuild_dbs do
66
+ system("cd spec/test_app && rake db:drop db:migrate RAILS_ENV=test && rake db:drop db:migrate RAILS_ENV=cucumber")
67
+ end
68
+ end
@@ -0,0 +1,3 @@
1
+ "0.60.x" => { :branch => "master" }
2
+
3
+
@@ -0,0 +1,9 @@
1
+ class Gateway::Payflow < Gateway
2
+ preference :login, :string
3
+ preference :password, :password
4
+ preference :partner, :string
5
+
6
+ def provider_class
7
+ ActiveMerchant::Billing::PayflowGateway
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ # Add your extension routes here
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'spree_core'
2
+ require 'spree_payflow_hooks'
3
+
4
+ module SpreePayflow
5
+ class Engine < Rails::Engine
6
+
7
+ config.autoload_paths += %W(#{config.root}/lib)
8
+
9
+ def self.activate
10
+
11
+ require 'active_merchant'
12
+ ActiveMerchant::Billing::PayflowGateway
13
+
14
+ Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
15
+ Rails.env.production? ? require(c) : load(c)
16
+ end
17
+
18
+ Gateway::Payflow.register
19
+ end
20
+
21
+ config.to_prepare &method(:activate).to_proc
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ class SpreePayflowHooks < Spree::ThemeSupport::HookListener
2
+ # custom hooks go here
3
+ end
@@ -0,0 +1,25 @@
1
+ namespace :spree_payflow do
2
+ desc "Copies all migrations and assets (NOTE: This will be obsolete with Rails 3.1)"
3
+ task :install do
4
+ Rake::Task['spree_payflow:install:migrations'].invoke
5
+ Rake::Task['spree_payflow:install:assets'].invoke
6
+ end
7
+
8
+ namespace :install do
9
+ desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)"
10
+ task :migrations do
11
+ source = File.join(File.dirname(__FILE__), '..', '..', 'db')
12
+ destination = File.join(Rails.root, 'db')
13
+ Spree::FileUtilz.mirror_files(source, destination)
14
+ end
15
+
16
+ desc "Copies all assets (NOTE: This will be obsolete with Rails 3.1)"
17
+ task :assets do
18
+ source = File.join(File.dirname(__FILE__), '..', '..', 'public')
19
+ destination = File.join(Rails.root, 'public')
20
+ puts "INFO: Mirroring assets from #{source} to #{destination}"
21
+ Spree::FileUtilz.mirror_files(source, destination)
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1 @@
1
+ # add custom rake tasks here
@@ -0,0 +1,277 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe CheckoutController do
4
+ let(:token) { "EC-2OPN7UJGFWK9OYFV" }
5
+ let(:order) { Factory(:ppx_order_with_totals, :state => "payment") }
6
+ let(:order_total) { (order.total * 100).to_i }
7
+ let(:gateway_provider) { mock(ActiveMerchant::Billing::PaypalExpressGateway) }
8
+ let(:paypal_gateway) { mock(BillingIntegration::PaypalExpress, :id => 123, :preferred_review => false, :preferred_no_shipping => true, :provider => gateway_provider) }
9
+
10
+ let(:details_for_response) { mock(ActiveMerchant::Billing::PaypalExpressResponse, :success? => true,
11
+ :params => {"payer" => order.user.email, "payer_id" => "FWRVKNRRZ3WUC"}, :address => {}) }
12
+
13
+ let(:purchase_response) { mock(ActiveMerchant::Billing::PaypalExpressResponse, :success? => true,
14
+ :params => {"payer" => order.user.email, "payer_id" => "FWRVKNRRZ3WUC", "gross_amount" => order_total, "payment_status" => "Completed"},
15
+ :avs_result => "F",
16
+ :to_yaml => "fake") }
17
+
18
+
19
+ before do
20
+ Spree::Auth::Config.set(:registration_step => false)
21
+ controller.stub(:current_order => order, :check_authorization => true, :current_user => order.user)
22
+ order.stub(:checkout_allowed? => true, :completed? => false)
23
+ order.update!
24
+ end
25
+
26
+ it "should understand paypal routes" do
27
+ assert_routing("/orders/#{order.number}/checkout/paypal_payment", {:controller => "checkout", :action => "paypal_payment", :order_id => order.number })
28
+ assert_routing("/orders/#{order.number}/checkout/paypal_confirm", {:controller => "checkout", :action => "paypal_confirm", :order_id => order.number })
29
+ end
30
+
31
+ context "paypal_checkout" do
32
+ #feature not implemented
33
+ end
34
+
35
+ context "paypal_payment without auto_capture" do
36
+ let(:redirect_url) { "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=#{token}&useraction=commit" }
37
+
38
+ before { Spree::Config.set(:auto_capture => false) }
39
+
40
+ it "should setup an authorize transaction and redirect to sandbox" do
41
+ PaymentMethod.should_receive(:find).at_least(1).with('123').and_return(paypal_gateway)
42
+
43
+ gateway_provider.should_receive(:redirect_url_for).with(token, {:review => false}).and_return redirect_url
44
+ paypal_gateway.provider.should_receive(:setup_authorization).with(order_total, anything()).and_return(mock(:success? => true, :token => token))
45
+
46
+ get :paypal_payment, {:order_id => order.number, :payment_method_id => "123" }
47
+
48
+ response.should redirect_to "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=#{assigns[:ppx_response].token}&useraction=commit"
49
+ end
50
+
51
+ end
52
+
53
+ context "paypal_payment with auto_capture" do
54
+ let(:redirect_url) { "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=#{token}&useraction=commit" }
55
+
56
+ before { Spree::Config.set(:auto_capture => true) }
57
+
58
+ it "should setup a purchase transaction and redirect to sandbox" do
59
+ PaymentMethod.should_receive(:find).at_least(1).with("123").and_return(paypal_gateway)
60
+
61
+ gateway_provider.should_receive(:redirect_url_for).with(token, {:review => false}).and_return redirect_url
62
+ paypal_gateway.provider.should_receive(:setup_purchase).with(order_total, anything()).and_return(mock(:success? => true, :token => token))
63
+
64
+ get :paypal_payment, {:order_id => order.number, :payment_method_id => "123" }
65
+
66
+ response.should redirect_to "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=#{assigns[:ppx_response].token}&useraction=commit"
67
+ end
68
+
69
+ end
70
+
71
+ context "paypal_confirm" do
72
+ before { PaymentMethod.should_receive(:find).at_least(1).with("123").and_return(paypal_gateway) }
73
+
74
+ context "with auto_capture and no review" do
75
+ before do
76
+ Spree::Config.set(:auto_capture => true)
77
+ paypal_gateway.stub(:preferred_review => false)
78
+ end
79
+
80
+ it "should capture payment" do
81
+ paypal_gateway.provider.should_receive(:details_for).with(token).and_return(details_for_response)
82
+
83
+ paypal_gateway.provider.should_receive(:purchase).with(order_total, anything()).and_return(purchase_response)
84
+
85
+ get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
86
+
87
+ response.should redirect_to order_url(order)
88
+
89
+ order.reload
90
+ order.state.should == "complete"
91
+ order.payments.size.should == 1
92
+ order.payment_state.should == "paid"
93
+ end
94
+ end
95
+
96
+ context "with review" do
97
+ before { paypal_gateway.stub(:preferred_review => true) }
98
+
99
+ it "should render review" do
100
+ paypal_gateway.provider.should_receive(:details_for).with(token).and_return(details_for_response)
101
+
102
+ get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
103
+
104
+ response.should render_template("shared/paypal_express_confirm")
105
+
106
+ end
107
+ end
108
+
109
+ context "with review and shipping update" do
110
+ before do
111
+ paypal_gateway.stub(:preferred_review => true)
112
+ paypal_gateway.stub(:preferred_no_shipping => false)
113
+
114
+ details_for_response.stub(:params => details_for_response.params.merge({'first_name' => 'Dr.', 'last_name' => 'Evil'}),
115
+ :address => {'address1' => 'Apt. 187', 'address2'=> 'Some Str.', 'city' => 'Chevy Chase', 'country' => 'US', 'zip' => '20815', 'state' => 'MD' })
116
+
117
+ end
118
+
119
+ it "should update ship_address and render review" do
120
+ paypal_gateway.provider.should_receive(:details_for).with(token).and_return(details_for_response)
121
+
122
+ get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
123
+
124
+ order.ship_address.address1.should == "Apt. 187"
125
+ response.should render_template("shared/paypal_express_confirm")
126
+ end
127
+ end
128
+
129
+ context "with un-successful repsonse" do
130
+ before { details_for_response.stub(:success? => false) }
131
+
132
+ it "should log error and redirect to payment step" do
133
+ paypal_gateway.provider.should_receive(:details_for).with(token).and_return(details_for_response)
134
+
135
+ controller.should_receive(:gateway_error).with(details_for_response)
136
+
137
+ get :paypal_confirm, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
138
+
139
+ response.should redirect_to edit_order_checkout_url(order, :state => 'payment')
140
+ end
141
+ end
142
+
143
+ end
144
+
145
+ context "paypal_finish" do
146
+ let(:paypal_account) { stub_model(PaypalAccount, :payer_id => "FWRVKNRRZ3WUC", :email => order.email ) }
147
+ let(:authorize_response) { mock(ActiveMerchant::Billing::PaypalExpressResponse, :success? => true,
148
+ :params => {"payer" => order.user.email, "payer_id" => "FWRVKNRRZ3WUC", "gross_amount" => order_total, "payment_status" => "Pending"},
149
+ :avs_result => "F",
150
+ :to_yaml => "fake") }
151
+
152
+ before do
153
+ PaymentMethod.should_receive(:find).at_least(1).with("123").and_return(paypal_gateway)
154
+ PaypalAccount.should_receive(:find_by_payer_id).with("FWRVKNRRZ3WUC").and_return(paypal_account)
155
+ end
156
+
157
+ context "with auto_capture" do
158
+ before { Spree::Config.set(:auto_capture => true) }
159
+
160
+ it "should capture payment" do
161
+
162
+ paypal_gateway.provider.should_receive(:purchase).with(order_total, anything()).and_return(purchase_response)
163
+
164
+ get :paypal_finish, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
165
+
166
+ response.should redirect_to order_url(order)
167
+
168
+ order.reload
169
+ order.update!
170
+ order.payments.size.should == 1
171
+ order.payment_state.should == "paid"
172
+ end
173
+ end
174
+
175
+ context "with auto_capture and pending(echeck) response" do
176
+ before do
177
+ Spree::Config.set(:auto_capture => true)
178
+ purchase_response.params["payment_status"] = "pending"
179
+ end
180
+
181
+ it "should authorize payment" do
182
+
183
+ paypal_gateway.provider.should_receive(:purchase).with(order_total, anything()).and_return(purchase_response)
184
+
185
+ get :paypal_finish, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
186
+
187
+ response.should redirect_to order_url(order)
188
+
189
+ order.reload
190
+ order.update!
191
+ order.payments.size.should == 1
192
+ order.payment_state.should == "balance_due"
193
+ order.payment.state.should == "pending"
194
+ end
195
+ end
196
+
197
+ context "without auto_capture" do
198
+ before { Spree::Config.set(:auto_capture => false) }
199
+
200
+ it "should authorize payment" do
201
+
202
+ paypal_gateway.provider.should_receive(:authorize).with(order_total, anything()).and_return(authorize_response)
203
+
204
+ get :paypal_finish, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
205
+
206
+ response.should redirect_to order_url(order)
207
+
208
+ order.reload
209
+ order.update!
210
+ order.payments.size.should == 1
211
+ order.payment_state.should == "balance_due"
212
+ order.payment.state.should == "pending"
213
+ end
214
+ end
215
+
216
+ context "with un-successful repsonse" do
217
+ before do
218
+ Spree::Config.set(:auto_capture => true)
219
+ purchase_response.stub(:success? => false)
220
+ end
221
+
222
+ it "should log error and redirect to payment step" do
223
+ paypal_gateway.provider.should_receive(:purchase).with(order_total, anything()).and_return(purchase_response)
224
+
225
+ controller.should_receive(:gateway_error).with(purchase_response)
226
+
227
+ get :paypal_finish, {:order_id => order.number, :payment_method_id => "123", :token => token, :PayerID => "FWRVKNRRZ3WUC" }
228
+
229
+ response.should redirect_to edit_order_checkout_url(order, :state => 'payment')
230
+
231
+ order.reload
232
+ order.update!
233
+ order.payments.size.should == 1
234
+ order.payment_state.should == "failed"
235
+ order.payment.state.should == "failed"
236
+ end
237
+ end
238
+
239
+ end
240
+
241
+ context "order_opts" do
242
+
243
+ it "should return hash containing basic order details" do
244
+ opts = controller.send(:order_opts, order, paypal_gateway.id, 'payment')
245
+
246
+ opts.class.should == Hash
247
+ opts[:money].should == order_total
248
+ opts[:subtotal].should == (order.item_total * 100).to_i
249
+ opts[:order_id].should == order.number
250
+ opts[:custom].should == order.number
251
+ opts[:handling].should == 0
252
+ opts[:shipping].should == (order.ship_total * 100).to_i
253
+
254
+ opts[:return_url].should == paypal_confirm_order_checkout_url(order, :payment_method_id => paypal_gateway.id)
255
+ opts[:cancel_return_url].should == edit_order_url(order)
256
+
257
+ opts[:items].size.should > 0
258
+ opts[:items].size.should == order.line_items.count
259
+ end
260
+
261
+ it "should include credits in returned hash" do
262
+ order_total #need here so variable is set before credit is created.
263
+ order.adjustments.create(:label => "Credit", :amount => -1)
264
+ order.update!
265
+
266
+ opts = controller.send(:order_opts, order, paypal_gateway.id, 'payment')
267
+
268
+ opts.class.should == Hash
269
+ opts[:money].should == order_total - 100
270
+ opts[:subtotal].should == ((order.item_total * 100) + (order.adjustments.select{|c| c.amount < 0}.sum(&:amount) * 100)).to_i
271
+
272
+ opts[:items].size.should == order.line_items.count + 1
273
+ end
274
+
275
+
276
+ end
277
+ end
@@ -0,0 +1,13 @@
1
+ Factory.define :ppx_address do |f|
2
+ f.firstname 'John'
3
+ f.lastname 'Doe'
4
+ f.address1 '10 Lovely Street'
5
+ f.address2 'Northwest'
6
+ f.city "Herndon"
7
+ f.state { |state| state.association(:ppx_state) }
8
+ f.zipcode '20170'
9
+ f.country { |country| country.association(:country) }
10
+ f.phone '123-456-7890'
11
+ f.state_name "maryland"
12
+ f.alternative_phone "123-456-7899"
13
+ end
@@ -0,0 +1,11 @@
1
+ Factory.define(:ppx_order) do |record|
2
+ # associations:
3
+ record.association(:user, :factory => :user)
4
+ record.association(:bill_address, :factory => :address)
5
+ record.association(:shipping_method, :factory => :shipping_method)
6
+ record.ship_address { |ship_address| Factory(:ppx_address, :city => "Chevy Chase", :zipcode => "20815") }
7
+ end
8
+
9
+ Factory.define :ppx_order_with_totals, :parent => :order do |f|
10
+ f.after_create { |order| Factory(:line_item, :order => order) }
11
+ end
@@ -0,0 +1,42 @@
1
+ # This file is copied to ~/spec when you run 'ruby script/generate rspec'
2
+ # from the project root directory.
3
+ ENV["RAILS_ENV"] ||= 'test'
4
+ require File.expand_path("../test_app/config/environment", __FILE__)
5
+ require 'rspec/rails'
6
+
7
+ #include spree's factories
8
+ require 'spree_core/testing_support/factories'
9
+
10
+ # include local factories
11
+ Dir["#{File.dirname(__FILE__)}/factories/**/*.rb"].each do |f|
12
+ fp = File.expand_path(f)
13
+ require fp
14
+ end
15
+
16
+
17
+ RSpec.configure do |config|
18
+ # == Mock Framework
19
+ #
20
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
21
+ #
22
+ # config.mock_with :mocha
23
+ # config.mock_with :flexmock
24
+ # config.mock_with :rr
25
+ config.mock_with :rspec
26
+
27
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
28
+
29
+ #config.include Devise::TestHelpers, :type => :controller
30
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
31
+ # examples within a transaction, comment the following line or assign false
32
+ # instead of true.
33
+ config.use_transactional_fixtures = true
34
+ end
35
+
36
+ Zone.class_eval do
37
+ def self.global
38
+ find_by_name("GlobalZone") || Factory(:global_zone)
39
+ end
40
+ end
41
+
42
+ @configuration ||= AppConfiguration.find_or_create_by_name("Default configuration")
@@ -0,0 +1,36 @@
1
+ source 'http://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'rspec-rails', '= 2.5.0'
5
+ gem 'factory_girl', '= 1.3.3'
6
+ gem 'factory_girl_rails', '= 1.0.1'
7
+ gem 'rcov'
8
+ gem 'shoulda'
9
+ gem 'faker'
10
+ if RUBY_VERSION < "1.9"
11
+ gem "ruby-debug"
12
+ else
13
+ gem "ruby-debug19"
14
+ end
15
+ end
16
+
17
+ group :cucumber do
18
+ gem 'cucumber-rails'
19
+ gem 'database_cleaner', '= 0.6.7'
20
+ gem 'nokogiri'
21
+ gem 'capybara', '= 0.4.1.2'
22
+ gem 'factory_girl', '= 1.3.3'
23
+ gem 'factory_girl_rails', '= 1.0.1'
24
+ gem 'faker'
25
+ gem 'launchy'
26
+
27
+ if RUBY_VERSION < "1.9"
28
+ gem "ruby-debug"
29
+ else
30
+ gem "ruby-debug19"
31
+ end
32
+ end
33
+ gem 'spree_core', :path => '/Users/bestbuy/.rvm/gems/ruby-1.9.2-p0/gems/spree-0.60.0/core'
34
+ gem 'spree_auth', :path => '/Users/bestbuy/.rvm/gems/ruby-1.9.2-p0/gems/spree-0.60.0/auth'
35
+ gem 'spree_payflow', :path => '/Users/bestbuy/Desktop/chad/airblaster/spree_payflow'
36
+ gem "sqlite3-ruby"
@@ -0,0 +1,17 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: db/cucumber.sqlite3
4
+ pool: 5
5
+ timeout: 5000
6
+
7
+ test:
8
+ adapter: sqlite3
9
+ database: db/test.sqlite3
10
+ pool: 5
11
+ timeout: 5000
12
+
13
+ cucumber:
14
+ adapter: sqlite3
15
+ database: db/cucumber.sqlite3
16
+ pool: 5
17
+ timeout: 5000
@@ -0,0 +1,38 @@
1
+ TestApp::Application.configure do
2
+ # Settings specified here will take precedence over those in config/environment.rb
3
+
4
+ # The test environment is used exclusively to run your application's
5
+ # test suite. You never need to work with it otherwise. Remember that
6
+ # your test database is "scratch space" for the test suite and is wiped
7
+ # and recreated between test runs. Don't rely on the data there!
8
+ config.cache_classes = true
9
+
10
+ # Log error messages when you accidentally call methods on nil.
11
+ config.whiny_nils = true
12
+
13
+ # Show full error reports and disable caching
14
+ config.consider_all_requests_local = true
15
+ config.action_controller.perform_caching = false
16
+
17
+ # Raise exceptions instead of rendering exception templates
18
+ config.action_dispatch.show_exceptions = false
19
+
20
+ # Disable request forgery protection in test environment
21
+ config.action_controller.allow_forgery_protection = false
22
+
23
+ # Tell Action Mailer not to deliver emails to the real world.
24
+ # The :test delivery method accumulates sent emails in the
25
+ # ActionMailer::Base.deliveries array.
26
+ config.action_mailer.delivery_method = :test
27
+
28
+ # Use SQL instead of Active Record's schema dumper when creating the test database.
29
+ # This is necessary if your schema can't be completely dumped by the schema dumper,
30
+ # like if you have constraints or database-specific column types
31
+ # config.active_record.schema_format = :sql
32
+
33
+ # Print deprecation notices to the stderr
34
+ config.active_support.deprecation = :stderr
35
+
36
+ config.action_mailer.default_url_options = { :host => 'testapp.com' }
37
+
38
+ end
@@ -0,0 +1,20 @@
1
+ Gem::Specification.new do |s|
2
+ s.platform = Gem::Platform::RUBY
3
+ s.name = 'spree_payflow'
4
+ s.version = '0.60.0'
5
+ s.summary = 'Spree Commerce extension for PayPal Payflow gateway'
6
+ s.description = 'Spree Commerce extension for PayPal Payflow gateway'
7
+ s.required_ruby_version = '>= 1.8.7'
8
+
9
+ s.author = 'Chad Nantais'
10
+ s.email = 'cnantais@gmail.com'
11
+ s.homepage = 'http://www.zkron.com'
12
+ s.rubyforge_project = 'spree_payflow'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.require_path = 'lib'
17
+ s.requirements << 'none'
18
+
19
+ s.add_dependency('spree_core', '>= 0.60.0')
20
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_payflow
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 60
8
+ - 0
9
+ version: 0.60.0
10
+ platform: ruby
11
+ authors:
12
+ - Chad Nantais
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-07-07 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: spree_core
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 60
31
+ - 0
32
+ version: 0.60.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Spree Commerce extension for PayPal Payflow gateway
36
+ email: cnantais@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - .gitignore
45
+ - Gemfile
46
+ - Gemfile.lock
47
+ - LICENSE
48
+ - README.md
49
+ - Rakefile
50
+ - Versionfile
51
+ - app/models/gateway/payflow.rb
52
+ - config/routes.rb
53
+ - lib/spree_payflow.rb
54
+ - lib/spree_payflow_hooks.rb
55
+ - lib/tasks/install.rake
56
+ - lib/tasks/spree_payflow.rake
57
+ - spec/controllers/checkout_controller_spec.rb
58
+ - spec/factories/address_factory.rb
59
+ - spec/factories/order_factory.rb
60
+ - spec/spec_helper.rb
61
+ - spec/test_app/Gemfile
62
+ - spec/test_app/config/database.yml
63
+ - spec/test_app/config/environments/cucumber.rb
64
+ - spree_payflow.gemspec
65
+ has_rdoc: true
66
+ homepage: http://www.zkron.com
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 1
81
+ - 8
82
+ - 7
83
+ version: 1.8.7
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements:
93
+ - none
94
+ rubyforge_project: spree_payflow
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: Spree Commerce extension for PayPal Payflow gateway
99
+ test_files:
100
+ - spec/controllers/checkout_controller_spec.rb
101
+ - spec/factories/address_factory.rb
102
+ - spec/factories/order_factory.rb
103
+ - spec/spec_helper.rb
104
+ - spec/test_app/Gemfile
105
+ - spec/test_app/config/database.yml
106
+ - spec/test_app/config/environments/cucumber.rb