spree_affirm 0.2.3
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/Gemfile +19 -0
- data/LICENSE +29 -0
- data/README.md +51 -0
- data/Rakefile +15 -0
- data/Versionfile +5 -0
- data/app/assets/javascripts/spree/backend/spree_affirm.js +3 -0
- data/app/assets/javascripts/spree/frontend/spree_affirm.js +2 -0
- data/app/assets/stylesheets/spree/backend/spree_affirm.css +4 -0
- data/app/assets/stylesheets/spree/frontend/spree_affirm.css +4 -0
- data/app/controllers/spree/affirm_controller.rb +68 -0
- data/app/models/spree/affirm_checkout.rb +38 -0
- data/app/models/spree/gateway/affirm.rb +51 -0
- data/app/views/spree/admin/log_entries/_affirm.html.erb +4 -0
- data/app/views/spree/admin/log_entries/index.html.erb +28 -0
- data/app/views/spree/admin/payments/source_forms/_affirm.html.erb +19 -0
- data/app/views/spree/admin/payments/source_views/_affirm.html.erb +12 -0
- data/app/views/spree/checkout/payment/_affirm.html.erb +195 -0
- data/bin/rails +7 -0
- data/config/locales/en.yml +29 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20140514194315_create_affirm_checkout.rb +10 -0
- data/lib/active_merchant/billing/affirm.rb +161 -0
- data/lib/generators/spree_affirm/install/install_generator.rb +21 -0
- data/lib/spree_affirm/engine.rb +27 -0
- data/lib/spree_affirm/factories/affirm_checkout_factory.rb +211 -0
- data/lib/spree_affirm/factories/affirm_payment_method_factory.rb +8 -0
- data/lib/spree_affirm/factories/payment_factory.rb +10 -0
- data/lib/spree_affirm/factories.rb +5 -0
- data/lib/spree_affirm/version.rb +3 -0
- data/lib/spree_affirm.rb +2 -0
- data/spec/controllers/affirm_controller_spec.rb +138 -0
- data/spec/lib/active_merchant/billing/affirm_spec.rb +294 -0
- data/spec/models/affirm_address_validator_spec.rb +13 -0
- data/spec/models/spree_affirm_checkout_spec.rb +328 -0
- data/spec/models/spree_gateway_affirm_spec.rb +134 -0
- data/spec/spec_helper.rb +98 -0
- data/spree_affirm.gemspec +30 -0
- metadata +190 -0
@@ -0,0 +1,161 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class Affirm < Gateway
|
4
|
+
self.supported_countries = %w(US)
|
5
|
+
self.default_currency = 'USD'
|
6
|
+
self.money_format = :cents
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
requires!(options, :api_key, :secret_key, :server)
|
10
|
+
@api_key = options[:api_key]
|
11
|
+
@secret_key = options[:secret_key]
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_charge(charge_id)
|
16
|
+
@charge_id = charge_id
|
17
|
+
end
|
18
|
+
|
19
|
+
def authorize(money, affirm_source, options = {})
|
20
|
+
result = commit(:post, "", {"checkout_token"=>affirm_source.token}, options, true)
|
21
|
+
return result unless result.success?
|
22
|
+
|
23
|
+
if amount(money).to_i != result.params["amount"].to_i
|
24
|
+
return Response.new(false,
|
25
|
+
"Auth amount does not match charge amount",
|
26
|
+
result.params
|
27
|
+
)
|
28
|
+
elsif result.params["pending"].to_s != "true"
|
29
|
+
return Response.new(false,
|
30
|
+
"There was an error authorizing this Charge",
|
31
|
+
result.params
|
32
|
+
)
|
33
|
+
end
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
# To create a charge on a card or a token, call
|
38
|
+
#
|
39
|
+
# purchase(money, card_hash_or_token, { ... })
|
40
|
+
#
|
41
|
+
# To create a charge on a customer, call
|
42
|
+
#
|
43
|
+
# purchase(money, nil, { :customer => id, ... })
|
44
|
+
def purchase(money, affirm_source, options = {})
|
45
|
+
result = authorize(money, affirm_source, options)
|
46
|
+
return result unless result.success?
|
47
|
+
capture(money, @charge_id, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def capture(money, charge_source, options = {})
|
51
|
+
post = {:amount => amount(money)}
|
52
|
+
set_charge(charge_source)
|
53
|
+
result = commit(:post, "#{@charge_id}/capture", post, options)
|
54
|
+
return result unless result.success?
|
55
|
+
|
56
|
+
if amount(money).to_i != result.params["amount"].to_i
|
57
|
+
return Response.new(false,
|
58
|
+
"Capture amount does not match charge amount",
|
59
|
+
result.params
|
60
|
+
)
|
61
|
+
end
|
62
|
+
result
|
63
|
+
end
|
64
|
+
|
65
|
+
def void(charge_source, options = {})
|
66
|
+
set_charge(charge_source)
|
67
|
+
commit(:post, "#{@charge_id}/void", {}, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def refund(money, charge_source, options = {})
|
71
|
+
post = {:amount => amount(money)}
|
72
|
+
set_charge(charge_source)
|
73
|
+
commit(:post, "#{@charge_id}/refund", post, options)
|
74
|
+
end
|
75
|
+
|
76
|
+
def credit(money, charge_source, options = {})
|
77
|
+
set_charge(charge_source)
|
78
|
+
return Response.new(true ,
|
79
|
+
"Credited Zero amount",
|
80
|
+
{},
|
81
|
+
:authorization => @charge_id,
|
82
|
+
) unless money > 0
|
83
|
+
refund(money, charge_source, options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def root_url
|
87
|
+
"#{root_api_url}charges/"
|
88
|
+
end
|
89
|
+
|
90
|
+
def root_api_url
|
91
|
+
"https://#{@options[:server]}/api/v2/"
|
92
|
+
end
|
93
|
+
|
94
|
+
def headers
|
95
|
+
{
|
96
|
+
"Content-Type" => "application/json",
|
97
|
+
"Authorization" => "Basic " + Base64.encode64(@api_key.to_s + ":" + @secret_key.to_s).gsub(/\n/, '').strip,
|
98
|
+
"User-Agent" => "Affirm/v1 ActiveMerchantBindings",
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse(body)
|
103
|
+
JSON.parse(body)
|
104
|
+
end
|
105
|
+
|
106
|
+
def post_data(params)
|
107
|
+
return nil unless params
|
108
|
+
params.to_json
|
109
|
+
end
|
110
|
+
|
111
|
+
def response_error(raw_response)
|
112
|
+
begin
|
113
|
+
parse(raw_response)
|
114
|
+
rescue JSON::ParserError
|
115
|
+
json_error(raw_response)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def json_error(raw_response)
|
120
|
+
msg = 'Invalid response. Please contact affirm if you continue to receive this message.'
|
121
|
+
msg += " (The raw response returned by the API was #{raw_response.inspect})"
|
122
|
+
{
|
123
|
+
"error" => {
|
124
|
+
"message" => msg
|
125
|
+
}
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_checkout(checkout_token)
|
130
|
+
_url = root_api_url + "checkout/#{checkout_token}"
|
131
|
+
_raw_response = ssl_request :get, _url, nil, headers
|
132
|
+
|
133
|
+
parse(_raw_response)
|
134
|
+
end
|
135
|
+
|
136
|
+
def commit(method, url, parameters=nil, options = {}, ret_charge=false)
|
137
|
+
raw_response = response = nil
|
138
|
+
success = false
|
139
|
+
begin
|
140
|
+
raw_response = ssl_request(method, root_url + url, post_data(parameters), headers)
|
141
|
+
response = parse(raw_response)
|
142
|
+
success = !response.key?("status_code") && (!ret_charge || response.key?("id"))
|
143
|
+
rescue ResponseError => e
|
144
|
+
raw_response = e.response.body
|
145
|
+
response = response_error(raw_response)
|
146
|
+
rescue JSON::ParserError
|
147
|
+
response = json_error(raw_response)
|
148
|
+
end
|
149
|
+
|
150
|
+
if success && ret_charge
|
151
|
+
@charge_id = response["id"]
|
152
|
+
end
|
153
|
+
Response.new(success,
|
154
|
+
success ? "Transaction approved" : response["message"],
|
155
|
+
response,
|
156
|
+
:authorization => @charge_id,
|
157
|
+
)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SpreeAffirm
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
class_option :auto_run_migrations, :type => :boolean, :default => false
|
6
|
+
|
7
|
+
def add_migrations
|
8
|
+
run 'bundle exec rake railties:install:migrations FROM=spree_affirm'
|
9
|
+
end
|
10
|
+
|
11
|
+
def run_migrations
|
12
|
+
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
|
13
|
+
if run_migrations
|
14
|
+
run 'bundle exec rake db:migrate'
|
15
|
+
else
|
16
|
+
puts 'Skipping rake db:migrate, don\'t forget to run it!'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module SpreeAffirm
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
require 'spree/core'
|
4
|
+
isolate_namespace Spree
|
5
|
+
engine_name 'spree_affirm'
|
6
|
+
|
7
|
+
|
8
|
+
# use rspec for tests
|
9
|
+
config.generators do |g|
|
10
|
+
g.test_framework :rspec
|
11
|
+
end
|
12
|
+
|
13
|
+
config.autoload_paths += %W(#{config.root}/lib)
|
14
|
+
|
15
|
+
def self.activate
|
16
|
+
Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
|
17
|
+
Rails.configuration.cache_classes ? require(c) : load(c)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
config.to_prepare &method(:activate).to_proc
|
22
|
+
|
23
|
+
initializer "spree.spree_affirm.payment_methods", :after => "spree.register.payment_methods" do |app|
|
24
|
+
app.config.spree.payment_methods << Spree::Gateway::Affirm
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
def BASE_CHECKOUT_DETAILS
|
2
|
+
{
|
3
|
+
"merchant"=> {
|
4
|
+
"public_api_key"=> "PPPPPPPPPPPPPPP",
|
5
|
+
"user_cancel_url"=> "http=>//google.com/cancel",
|
6
|
+
"user_confirmation_url"=> "http=>//google.com/confirm",
|
7
|
+
"name"=> "Test Merchant"
|
8
|
+
},
|
9
|
+
"tax_amount"=> 0,
|
10
|
+
"billing"=> {
|
11
|
+
"address"=> {
|
12
|
+
"city"=> "San Francisco",
|
13
|
+
"street1"=> "12345 Main",
|
14
|
+
"street2"=> "300",
|
15
|
+
"region1_code"=> "AL",
|
16
|
+
"postal_code"=> "55555",
|
17
|
+
"country_code"=> "USA",
|
18
|
+
"for_billing"=> true,
|
19
|
+
"validation_source"=> 3
|
20
|
+
},
|
21
|
+
"email"=> "test@affirm.com",
|
22
|
+
"name"=> {
|
23
|
+
"for_billing"=> true,
|
24
|
+
"last"=> "Doe",
|
25
|
+
"first"=> "John"
|
26
|
+
}
|
27
|
+
},
|
28
|
+
"items"=> {
|
29
|
+
"xxx-xx-xxx-x"=> {
|
30
|
+
"sku"=> "xxx-xx-xxx-x",
|
31
|
+
"item_url"=> "http=>//google.com/products/the-blue-hat",
|
32
|
+
"display_name"=> "The Blue Hat",
|
33
|
+
"unit_price"=> 85000,
|
34
|
+
"qty"=> 1,
|
35
|
+
"item_type"=> "physical",
|
36
|
+
"item_image_url"=> "http=>//google.com/products/6/large/the-blue-hat"
|
37
|
+
}
|
38
|
+
},
|
39
|
+
"shipping"=> {
|
40
|
+
"name"=> {
|
41
|
+
"last"=> "Doe",
|
42
|
+
"first"=> "John"
|
43
|
+
},
|
44
|
+
"address"=> {
|
45
|
+
"city"=> "San Francisco",
|
46
|
+
"street1"=> "12345 Main Street",
|
47
|
+
"street2"=> "300",
|
48
|
+
"region1_code"=> "AL",
|
49
|
+
"postal_code"=> "94110",
|
50
|
+
"country_code"=> "USA",
|
51
|
+
"validation_source"=> 3
|
52
|
+
}
|
53
|
+
},
|
54
|
+
"checkout_id"=> "S123123-456",
|
55
|
+
"currency"=> "USD",
|
56
|
+
"meta"=> {
|
57
|
+
"release"=> "true",
|
58
|
+
"user_timezone"=> "America/Los_Angeles",
|
59
|
+
"__affirm_tracking_uuid"=> "97570a41-cd07-4f52-8869-46c6d2588407"
|
60
|
+
},
|
61
|
+
"discount_code"=> "",
|
62
|
+
"misc_fee_amount"=> 0,
|
63
|
+
"shipping_type"=> "Free National UPS",
|
64
|
+
"config"=> {
|
65
|
+
"required_billing_fields"=> [
|
66
|
+
"name",
|
67
|
+
"address",
|
68
|
+
"email"
|
69
|
+
]
|
70
|
+
},
|
71
|
+
"api_version"=> "v2",
|
72
|
+
"shipping_amount"=> 0
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
FactoryGirl.define do
|
77
|
+
factory :affirm_checkout, class: Spree::AffirmCheckout do
|
78
|
+
token "12345678910"
|
79
|
+
association(:payment_method, factory: :affirm_payment_method)
|
80
|
+
association(:order, factory: :order_with_line_items)
|
81
|
+
|
82
|
+
|
83
|
+
transient do
|
84
|
+
stub_details true
|
85
|
+
shipping_address_mismatch false
|
86
|
+
billing_address_mismatch false
|
87
|
+
alternate_billing_address_format false
|
88
|
+
billing_address_full_name false
|
89
|
+
billing_email_mismatch false
|
90
|
+
extra_line_item false
|
91
|
+
missing_line_item false
|
92
|
+
quantity_mismatch false
|
93
|
+
price_mismatch false
|
94
|
+
full_name_case_mismatch false
|
95
|
+
end
|
96
|
+
|
97
|
+
after(:build) do |checkout, evaluator|
|
98
|
+
|
99
|
+
_details = BASE_CHECKOUT_DETAILS()
|
100
|
+
|
101
|
+
# case mismatch
|
102
|
+
unless evaluator.full_name_case_mismatch
|
103
|
+
_details['billing']['name'] = {
|
104
|
+
"full" => checkout.order.bill_address.firstname.upcase + " " +
|
105
|
+
checkout.order.bill_address.lastname.upcase
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
# shipping address
|
110
|
+
unless evaluator.shipping_address_mismatch
|
111
|
+
_details['shipping'] = {
|
112
|
+
"name" => {
|
113
|
+
"first" => checkout.order.ship_address.firstname,
|
114
|
+
"last" => checkout.order.ship_address.lastname
|
115
|
+
},
|
116
|
+
"address"=> {
|
117
|
+
"city"=> checkout.order.ship_address.city,
|
118
|
+
"street1"=> checkout.order.ship_address.address1,
|
119
|
+
"street2"=> checkout.order.ship_address.address2,
|
120
|
+
"region1_code"=> checkout.order.ship_address.state.abbr,
|
121
|
+
"postal_code"=> checkout.order.ship_address.zipcode,
|
122
|
+
"country_code"=> checkout.order.ship_address.country.iso3
|
123
|
+
}
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
# billing address
|
128
|
+
unless evaluator.billing_address_mismatch
|
129
|
+
_details["billing"] = {
|
130
|
+
"email" => "joe@schmoe.com",
|
131
|
+
"name" => {
|
132
|
+
"first" => checkout.order.bill_address.firstname,
|
133
|
+
"last" => checkout.order.bill_address.lastname
|
134
|
+
},
|
135
|
+
"address"=> {
|
136
|
+
"city"=> checkout.order.bill_address.city,
|
137
|
+
"street1"=> checkout.order.bill_address.address1,
|
138
|
+
"street2"=> checkout.order.bill_address.address2,
|
139
|
+
"region1_code"=> checkout.order.bill_address.state.abbr,
|
140
|
+
"postal_code"=> checkout.order.bill_address.zipcode,
|
141
|
+
"country_code"=> checkout.order.bill_address.country.iso3
|
142
|
+
}
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
# use alternate format for billing address
|
147
|
+
if evaluator.alternate_billing_address_format
|
148
|
+
_details['billing']["address"] = {
|
149
|
+
"city" => _details['billing']["address"]["city"],
|
150
|
+
"line1"=> _details['billing']["address"]["street1"],
|
151
|
+
"line2"=> _details['billing']["address"]["street2"],
|
152
|
+
"state"=> _details['billing']["address"]["postal_code"],
|
153
|
+
"zipcode"=> _details['billing']["address"]["region1_code"],
|
154
|
+
"country"=> _details['billing']["address"]["country_code"]
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
# use name.full instead of first/last
|
159
|
+
if evaluator.billing_address_full_name
|
160
|
+
_details['billing']['name'] = {
|
161
|
+
'full' => "#{_details['billing']['name']['first']} #{_details['billing']['name']['last']}"
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
# billing email
|
167
|
+
unless evaluator.billing_email_mismatch
|
168
|
+
_details["billing"]["email"] = checkout.order.email
|
169
|
+
end
|
170
|
+
|
171
|
+
# setup items in cart
|
172
|
+
_details['items'] = {}
|
173
|
+
checkout.order.line_items.each do |item|
|
174
|
+
_details['items'][item.variant.sku] = {
|
175
|
+
"qty" => item.quantity.to_s,
|
176
|
+
"unit_price" => (item.price*100).to_s,
|
177
|
+
"display_name" => item.product.name
|
178
|
+
}
|
179
|
+
end
|
180
|
+
|
181
|
+
if evaluator.extra_line_item
|
182
|
+
_details['items']['extra-1-2-3'] = {
|
183
|
+
"qty" => "1",
|
184
|
+
"unit_price" => "12300",
|
185
|
+
"display_name" => "Really cool hat"
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
if evaluator.missing_line_item
|
190
|
+
_details['items'].delete _details['items'].keys.last
|
191
|
+
end
|
192
|
+
|
193
|
+
if evaluator.quantity_mismatch
|
194
|
+
_last_item = _details['items'][_details['items'].keys.last]
|
195
|
+
_details['items'][_details['items'].keys.last]['qty'] = (_last_item['qty'].to_i + 1).to_s
|
196
|
+
end
|
197
|
+
|
198
|
+
if evaluator.price_mismatch
|
199
|
+
_last_item = _details['items'][_details['items'].keys.last]
|
200
|
+
_details['items'][_details['items'].keys.last]['unit_price'] = 456456
|
201
|
+
end
|
202
|
+
|
203
|
+
if evaluator.stub_details
|
204
|
+
checkout.stub(details: _details)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :affirm_payment, class: Spree::Payment do
|
3
|
+
amount 45.75
|
4
|
+
association(:payment_method, factory: :affirm_payment_method)
|
5
|
+
association(:source, factory: :affirm_checkout)
|
6
|
+
order
|
7
|
+
state 'checkout'
|
8
|
+
response_code '12345'
|
9
|
+
end
|
10
|
+
end
|
data/lib/spree_affirm.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Spree::AffirmController do
|
4
|
+
let(:user) { FactoryGirl.create(:user) }
|
5
|
+
let(:checkout) { FactoryGirl.build(:affirm_checkout) }
|
6
|
+
let(:bad_billing_checkout) { FactoryGirl.build(:affirm_checkout, billing_address_mismatch: true) }
|
7
|
+
let(:bad_shipping_checkout) { FactoryGirl.build(:affirm_checkout, shipping_address_mismatch: true) }
|
8
|
+
let(:bad_email_checkout) { FactoryGirl.build(:affirm_checkout, billing_email_mismatch: true) }
|
9
|
+
|
10
|
+
|
11
|
+
describe "POST confirm" do
|
12
|
+
|
13
|
+
def post_request(token, payment_id)
|
14
|
+
post :confirm, checkout_token: token, payment_method_id: payment_id, use_route: 'spree'
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
controller.stub authenticate_spree_user!: true
|
19
|
+
controller.stub spree_current_user: user
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when the checkout matches the order" do
|
23
|
+
before do
|
24
|
+
Spree::AffirmCheckout.stub new: checkout
|
25
|
+
controller.stub current_order: checkout.order
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when no checkout_token is provided" do
|
29
|
+
it "redirects to the current order state" do
|
30
|
+
post_request(nil, nil)
|
31
|
+
expect(response).to redirect_to(controller.checkout_state_path(checkout.order.state))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when the order is complete" do
|
36
|
+
before do
|
37
|
+
checkout.order.state = 'complete'
|
38
|
+
end
|
39
|
+
it "redirects to the current order state" do
|
40
|
+
post_request '123456789', checkout.payment_method.id
|
41
|
+
expect(response).to redirect_to(controller.order_path(checkout.order))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when the order state is payment" do
|
46
|
+
before do
|
47
|
+
checkout.order.state = 'payment'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "creates a new payment" do
|
51
|
+
post_request "123423423", checkout.payment_method.id
|
52
|
+
|
53
|
+
expect(checkout.order.payments.first.source).to eq(checkout)
|
54
|
+
end
|
55
|
+
|
56
|
+
# it "transitions to complete if confirmation is not required" do
|
57
|
+
# checkout.order.stub confirmation_required?: false
|
58
|
+
# post_request "123423423", checkout.payment_method.id
|
59
|
+
|
60
|
+
# expect(checkout.order.state).to eq("complete")
|
61
|
+
# end
|
62
|
+
|
63
|
+
it "transitions to confirm if confirmation is required" do
|
64
|
+
checkout.order.stub confirmation_required?: true
|
65
|
+
post_request "123423423", checkout.payment_method.id
|
66
|
+
|
67
|
+
expect(checkout.order.reload.state).to eq("confirm")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when the billing_address does not match the order" do
|
74
|
+
before do
|
75
|
+
Spree::AffirmCheckout.stub new: bad_billing_checkout
|
76
|
+
state = FactoryGirl.create(:state, abbr: bad_billing_checkout.details['billing']['address']['region1_code'])
|
77
|
+
Spree::State.stub find_by_abbr: state, find_by_name: state
|
78
|
+
controller.stub current_order: bad_billing_checkout.order
|
79
|
+
end
|
80
|
+
|
81
|
+
it "creates a new address record for the order" do
|
82
|
+
_old_billing_address = bad_billing_checkout.order.bill_address
|
83
|
+
post_request '12345789', bad_billing_checkout.payment_method.id
|
84
|
+
|
85
|
+
expect(bad_billing_checkout.order.bill_address).not_to be(_old_billing_address)
|
86
|
+
expect(bad_billing_checkout.valid?).to be(true)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
context "when the shipping_address does not match the order" do
|
92
|
+
before do
|
93
|
+
Spree::AffirmCheckout.stub new: bad_shipping_checkout
|
94
|
+
state = FactoryGirl.create(:state, abbr: bad_shipping_checkout.details['shipping']['address']['region1_code'])
|
95
|
+
Spree::State.stub find_by_abbr: state, find_by_name: state
|
96
|
+
controller.stub current_order: bad_shipping_checkout.order
|
97
|
+
end
|
98
|
+
|
99
|
+
it "creates a new address record for the order" do
|
100
|
+
_old_shipping_address = bad_shipping_checkout.order.ship_address
|
101
|
+
post_request '12345789', bad_shipping_checkout.payment_method.id
|
102
|
+
|
103
|
+
expect(bad_shipping_checkout.order.ship_address).not_to be(_old_shipping_address)
|
104
|
+
expect(bad_shipping_checkout.valid?).to be(true)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
context "when the billing_email does not match the order" do
|
111
|
+
before do
|
112
|
+
Spree::AffirmCheckout.stub new: bad_email_checkout
|
113
|
+
controller.stub current_order: bad_email_checkout.order
|
114
|
+
end
|
115
|
+
|
116
|
+
it "updates the billing_email on the order" do
|
117
|
+
_old_email = bad_email_checkout.order.email
|
118
|
+
post_request '12345789', bad_email_checkout.payment_method.id
|
119
|
+
|
120
|
+
expect(bad_email_checkout.order.email).not_to be(_old_email)
|
121
|
+
expect(bad_email_checkout.valid?).to be(true)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
context "there is no current order" do
|
127
|
+
before(:each) do
|
128
|
+
controller.stub current_order: nil
|
129
|
+
end
|
130
|
+
|
131
|
+
it "raises an ActiveRecord::RecordNotFound error" do
|
132
|
+
expect do
|
133
|
+
post_request nil, nil
|
134
|
+
end.to raise_error(ActiveRecord::RecordNotFound)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|