solidus_core 1.0.2 → 1.0.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.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile +3 -0
  4. data/Rakefile +16 -0
  5. data/script/rails +9 -0
  6. data/solidus_core.gemspec +48 -0
  7. data/spec/fixtures/thinking-cat.jpg +0 -0
  8. data/spec/helpers/base_helper_spec.rb +173 -0
  9. data/spec/helpers/order_helper_spec.rb +12 -0
  10. data/spec/helpers/products_helper_spec.rb +220 -0
  11. data/spec/helpers/taxons_helper_spec.rb +17 -0
  12. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  13. data/spec/lib/i18n_spec.rb +123 -0
  14. data/spec/lib/search/base_spec.rb +86 -0
  15. data/spec/lib/search/variant_spec.rb +92 -0
  16. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +66 -0
  17. data/spec/lib/spree/core/controller_helpers/order_spec.rb +92 -0
  18. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  19. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  20. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  21. data/spec/lib/spree/core/current_store_spec.rb +36 -0
  22. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
  23. data/spec/lib/spree/core/importer/order_spec.rb +431 -0
  24. data/spec/lib/spree/core/role_configuration_spec.rb +138 -0
  25. data/spec/lib/spree/core/validators/email_spec.rb +48 -0
  26. data/spec/lib/spree/localized_number_spec.rb +38 -0
  27. data/spec/lib/spree/migrations_spec.rb +36 -0
  28. data/spec/lib/spree/money_spec.rb +127 -0
  29. data/spec/lib/tasks/exchanges_spec.rb +231 -0
  30. data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +115 -0
  31. data/spec/lib/tasks/order_capturing_spec.rb +56 -0
  32. data/spec/mailers/carton_mailer_spec.rb +43 -0
  33. data/spec/mailers/order_mailer_spec.rb +122 -0
  34. data/spec/mailers/reimbursement_mailer_spec.rb +40 -0
  35. data/spec/mailers/test_mailer_spec.rb +15 -0
  36. data/spec/models/spree/ability_spec.rb +276 -0
  37. data/spec/models/spree/address_spec.rb +250 -0
  38. data/spec/models/spree/adjustment_reason_spec.rb +13 -0
  39. data/spec/models/spree/adjustment_spec.rb +177 -0
  40. data/spec/models/spree/app_configuration_spec.rb +20 -0
  41. data/spec/models/spree/asset_spec.rb +24 -0
  42. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  43. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  44. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  45. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  46. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  47. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  48. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
  49. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  50. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  51. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  52. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  53. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +30 -0
  54. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +36 -0
  55. data/spec/models/spree/calculator/tiered_percent_spec.rb +47 -0
  56. data/spec/models/spree/calculator_spec.rb +36 -0
  57. data/spec/models/spree/carton_spec.rb +133 -0
  58. data/spec/models/spree/classification_spec.rb +15 -0
  59. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  60. data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
  61. data/spec/models/spree/credit_card_spec.rb +334 -0
  62. data/spec/models/spree/customer_return_spec.rb +276 -0
  63. data/spec/models/spree/exchange_spec.rb +79 -0
  64. data/spec/models/spree/gateway/bogus_simple.rb +20 -0
  65. data/spec/models/spree/gateway/bogus_spec.rb +13 -0
  66. data/spec/models/spree/gateway_spec.rb +82 -0
  67. data/spec/models/spree/inventory_unit_spec.rb +307 -0
  68. data/spec/models/spree/item_adjustments_spec.rb +256 -0
  69. data/spec/models/spree/line_item_spec.rb +191 -0
  70. data/spec/models/spree/option_type_spec.rb +14 -0
  71. data/spec/models/spree/option_value_spec.rb +22 -0
  72. data/spec/models/spree/order/address_spec.rb +50 -0
  73. data/spec/models/spree/order/adjustments_spec.rb +39 -0
  74. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  75. data/spec/models/spree/order/checkout_spec.rb +902 -0
  76. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  77. data/spec/models/spree/order/finalizing_spec.rb +111 -0
  78. data/spec/models/spree/order/payment_spec.rb +210 -0
  79. data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
  80. data/spec/models/spree/order/state_machine_spec.rb +221 -0
  81. data/spec/models/spree/order/tax_spec.rb +84 -0
  82. data/spec/models/spree/order/totals_spec.rb +24 -0
  83. data/spec/models/spree/order/updating_spec.rb +18 -0
  84. data/spec/models/spree/order/validations_spec.rb +15 -0
  85. data/spec/models/spree/order_cancellations_spec.rb +120 -0
  86. data/spec/models/spree/order_capturing_spec.rb +116 -0
  87. data/spec/models/spree/order_contents_spec.rb +265 -0
  88. data/spec/models/spree/order_inventory_spec.rb +228 -0
  89. data/spec/models/spree/order_mutex_spec.rb +85 -0
  90. data/spec/models/spree/order_promotion_spec.rb +31 -0
  91. data/spec/models/spree/order_shipping_spec.rb +247 -0
  92. data/spec/models/spree/order_spec.rb +1412 -0
  93. data/spec/models/spree/order_stock_location_spec.rb +18 -0
  94. data/spec/models/spree/order_updater_spec.rb +299 -0
  95. data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
  96. data/spec/models/spree/payment_method_spec.rb +96 -0
  97. data/spec/models/spree/payment_spec.rb +1044 -0
  98. data/spec/models/spree/permission_sets/base_spec.rb +12 -0
  99. data/spec/models/spree/permission_sets/configuration_display.rb +82 -0
  100. data/spec/models/spree/permission_sets/configuration_management_spec.rb +50 -0
  101. data/spec/models/spree/permission_sets/dashboard_display_spec.rb +22 -0
  102. data/spec/models/spree/permission_sets/order_display_spec.rb +49 -0
  103. data/spec/models/spree/permission_sets/order_management_spec.rb +36 -0
  104. data/spec/models/spree/permission_sets/product_display_spec.rb +60 -0
  105. data/spec/models/spree/permission_sets/product_management_spec.rb +40 -0
  106. data/spec/models/spree/permission_sets/promotion_display_spec.rb +34 -0
  107. data/spec/models/spree/permission_sets/promotion_management_spec.rb +26 -0
  108. data/spec/models/spree/permission_sets/report_display_spec.rb +24 -0
  109. data/spec/models/spree/permission_sets/restricted_transfer_management_spec.rb +132 -0
  110. data/spec/models/spree/permission_sets/stock_display_spec.rb +26 -0
  111. data/spec/models/spree/permission_sets/stock_management_spec.rb +24 -0
  112. data/spec/models/spree/permission_sets/user_display_spec.rb +36 -0
  113. data/spec/models/spree/permission_sets/user_management_spec.rb +28 -0
  114. data/spec/models/spree/preference_spec.rb +80 -0
  115. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  116. data/spec/models/spree/preferences/preferable_spec.rb +294 -0
  117. data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
  118. data/spec/models/spree/preferences/static_model_preferences_spec.rb +78 -0
  119. data/spec/models/spree/preferences/statically_configurable_spec.rb +60 -0
  120. data/spec/models/spree/preferences/store_spec.rb +39 -0
  121. data/spec/models/spree/price_spec.rb +42 -0
  122. data/spec/models/spree/product/scopes_spec.rb +148 -0
  123. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  124. data/spec/models/spree/product_filter_spec.rb +26 -0
  125. data/spec/models/spree/product_property_spec.rb +20 -0
  126. data/spec/models/spree/product_spec.rb +437 -0
  127. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +96 -0
  128. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +165 -0
  129. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +115 -0
  130. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +40 -0
  131. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  132. data/spec/models/spree/promotion/rules/item_total_spec.rb +67 -0
  133. data/spec/models/spree/promotion/rules/nth_order_spec.rb +70 -0
  134. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  135. data/spec/models/spree/promotion/rules/option_value_spec.rb +94 -0
  136. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  137. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  138. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  139. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  140. data/spec/models/spree/promotion_builder_spec.rb +118 -0
  141. data/spec/models/spree/promotion_category_spec.rb +17 -0
  142. data/spec/models/spree/promotion_code/code_builder_spec.rb +79 -0
  143. data/spec/models/spree/promotion_code_spec.rb +187 -0
  144. data/spec/models/spree/promotion_handler/cart_spec.rb +114 -0
  145. data/spec/models/spree/promotion_handler/coupon_spec.rb +335 -0
  146. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +47 -0
  147. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  148. data/spec/models/spree/promotion_rule_spec.rb +28 -0
  149. data/spec/models/spree/promotion_spec.rb +767 -0
  150. data/spec/models/spree/refund_spec.rb +204 -0
  151. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  152. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  153. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  154. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  155. data/spec/models/spree/reimbursement_spec.rb +231 -0
  156. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  157. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  158. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  159. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +107 -0
  160. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +97 -0
  161. data/spec/models/spree/return_authorization_spec.rb +290 -0
  162. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  163. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  164. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +85 -0
  165. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  166. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  167. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  168. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  169. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  170. data/spec/models/spree/return_item_spec.rb +775 -0
  171. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  172. data/spec/models/spree/shipment_spec.rb +709 -0
  173. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  174. data/spec/models/spree/shipping_method_spec.rb +88 -0
  175. data/spec/models/spree/shipping_rate_spec.rb +142 -0
  176. data/spec/models/spree/state_spec.rb +14 -0
  177. data/spec/models/spree/stock/availability_validator_spec.rb +83 -0
  178. data/spec/models/spree/stock/coordinator_spec.rb +116 -0
  179. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  180. data/spec/models/spree/stock/estimator_spec.rb +146 -0
  181. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  182. data/spec/models/spree/stock/package_spec.rb +163 -0
  183. data/spec/models/spree/stock/packer_spec.rb +91 -0
  184. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  185. data/spec/models/spree/stock/quantifier_spec.rb +115 -0
  186. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  187. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  188. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +50 -0
  189. data/spec/models/spree/stock/splitter/weight_spec.rb +29 -0
  190. data/spec/models/spree/stock_item_spec.rb +426 -0
  191. data/spec/models/spree/stock_location_spec.rb +279 -0
  192. data/spec/models/spree/stock_movement_spec.rb +56 -0
  193. data/spec/models/spree/stock_transfer_spec.rb +290 -0
  194. data/spec/models/spree/store_credit_category_spec.rb +17 -0
  195. data/spec/models/spree/store_credit_event_spec.rb +314 -0
  196. data/spec/models/spree/store_credit_spec.rb +876 -0
  197. data/spec/models/spree/store_spec.rb +55 -0
  198. data/spec/models/spree/tax_category_spec.rb +27 -0
  199. data/spec/models/spree/tax_rate_spec.rb +378 -0
  200. data/spec/models/spree/taxon_spec.rb +74 -0
  201. data/spec/models/spree/taxonomy_spec.rb +18 -0
  202. data/spec/models/spree/tracker_spec.rb +21 -0
  203. data/spec/models/spree/transfer_item_spec.rb +264 -0
  204. data/spec/models/spree/unit_cancel_spec.rb +148 -0
  205. data/spec/models/spree/user_spec.rb +223 -0
  206. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +23 -0
  207. data/spec/models/spree/variant/scopes_spec.rb +55 -0
  208. data/spec/models/spree/variant_spec.rb +546 -0
  209. data/spec/models/spree/zone_spec.rb +305 -0
  210. data/spec/spec_helper.rb +78 -0
  211. data/spec/support/big_decimal.rb +5 -0
  212. data/spec/support/concerns/default_price.rb +34 -0
  213. data/spec/support/dummy_ability.rb +4 -0
  214. data/spec/support/test_gateway.rb +2 -0
  215. metadata +229 -3
  216. data/lib/spree/testing_support/rspec-activemodel-mocks_patch.rb +0 -8
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::PaymentMethod, :type => :model do
4
+ describe "#available" do
5
+ before do
6
+ [nil, 'both', 'front_end', 'back_end'].each do |display_on|
7
+ Spree::Gateway::Test.create(
8
+ :name => 'Display Both',
9
+ :display_on => display_on,
10
+ :active => true,
11
+ :environment => 'test',
12
+ :description => 'foofah'
13
+ )
14
+ end
15
+ end
16
+
17
+ it "should have 4 total methods" do
18
+ expect(Spree::PaymentMethod.all.size).to eq(4)
19
+ end
20
+
21
+ it "should return all methods available to front-end/back-end when no parameter is passed" do
22
+ expect(Spree::PaymentMethod.available.size).to eq(2)
23
+ end
24
+
25
+ it "should return all methods available to front-end/back-end when display_on = :both" do
26
+ expect(Spree::PaymentMethod.available(:both).size).to eq(2)
27
+ end
28
+
29
+ it "should return all methods available to front-end when display_on = :front_end" do
30
+ expect(Spree::PaymentMethod.available(:front_end).size).to eq(2)
31
+ end
32
+
33
+ it "should return all methods available to back-end when display_on = :back_end" do
34
+ expect(Spree::PaymentMethod.available(:back_end).size).to eq(2)
35
+ end
36
+ end
37
+
38
+ describe '#auto_capture?' do
39
+ class TestGateway < Spree::Gateway
40
+ def provider_class
41
+ Provider
42
+ end
43
+ end
44
+
45
+ let(:gateway) { TestGateway.new }
46
+
47
+ subject { gateway.auto_capture? }
48
+
49
+ context 'when auto_capture is nil' do
50
+ before(:each) do
51
+ expect(Spree::Config).to receive('[]').with(:auto_capture).and_return(auto_capture)
52
+ end
53
+
54
+ context 'and when Spree::Config[:auto_capture] is false' do
55
+ let(:auto_capture) { false }
56
+
57
+ it 'should be false' do
58
+ expect(gateway.auto_capture).to be_nil
59
+ expect(subject).to be false
60
+ end
61
+ end
62
+
63
+ context 'and when Spree::Config[:auto_capture] is true' do
64
+ let(:auto_capture) { true }
65
+
66
+ it 'should be true' do
67
+ expect(gateway.auto_capture).to be_nil
68
+ expect(subject).to be true
69
+ end
70
+ end
71
+ end
72
+
73
+ context 'when auto_capture is not nil' do
74
+ before(:each) do
75
+ gateway.auto_capture = auto_capture
76
+ end
77
+
78
+ context 'and is true' do
79
+ let(:auto_capture) { true }
80
+
81
+ it 'should be true' do
82
+ expect(subject).to be true
83
+ end
84
+ end
85
+
86
+ context 'and is false' do
87
+ let(:auto_capture) { false }
88
+
89
+ it 'should be true' do
90
+ expect(subject).to be false
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,1044 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Payment, :type => :model do
4
+ let(:order) { Spree::Order.create }
5
+ let(:refund_reason) { create(:refund_reason) }
6
+
7
+ let(:gateway) do
8
+ gateway = Spree::Gateway::Bogus.new(:environment => 'test', :active => true, :name => 'Bogus gateway')
9
+ allow(gateway).to receive_messages :source_required => true
10
+ gateway
11
+ end
12
+
13
+ let(:avs_code) { 'D' }
14
+ let(:cvv_code) { 'M' }
15
+
16
+ let(:card) { create :credit_card }
17
+
18
+ let(:payment) do
19
+ payment = Spree::Payment.new
20
+ payment.source = card
21
+ payment.order = order
22
+ payment.payment_method = gateway
23
+ payment.amount = 5
24
+ payment
25
+ end
26
+
27
+ let(:amount_in_cents) { (payment.amount * 100).round }
28
+
29
+ let!(:success_response) do
30
+ ActiveMerchant::Billing::Response.new(true, '', {}, {
31
+ authorization: '123',
32
+ cvv_result: cvv_code,
33
+ avs_result: { code: avs_code }
34
+ })
35
+ end
36
+
37
+ let(:failed_response) do
38
+ ActiveMerchant::Billing::Response.new(false, '', {}, {})
39
+ end
40
+
41
+ before(:each) do
42
+ # So it doesn't create log entries every time a processing method is called
43
+ allow(payment.log_entries).to receive(:create!)
44
+ end
45
+
46
+ context '.risky' do
47
+
48
+ let!(:payment_1) { create(:payment, avs_response: 'Y', cvv_response_code: 'M', cvv_response_message: 'Match') }
49
+ let!(:payment_2) { create(:payment, avs_response: 'Y', cvv_response_code: 'M', cvv_response_message: '') }
50
+ let!(:payment_3) { create(:payment, avs_response: 'A', cvv_response_code: 'M', cvv_response_message: 'Match') }
51
+ let!(:payment_4) { create(:payment, avs_response: 'Y', cvv_response_code: 'N', cvv_response_message: 'No Match') }
52
+
53
+ it 'should not return successful responses' do
54
+ expect(subject.class.risky.to_a).to match_array([payment_3, payment_4])
55
+ end
56
+
57
+ end
58
+
59
+ context "#captured_amount" do
60
+ context "calculates based on capture events" do
61
+ it "with 0 capture events" do
62
+ expect(payment.captured_amount).to eq(0)
63
+ end
64
+
65
+ it "with some capture events" do
66
+ payment.save
67
+ payment.capture_events.create!(amount: 2.0)
68
+ payment.capture_events.create!(amount: 3.0)
69
+ expect(payment.captured_amount).to eq(5)
70
+ end
71
+ end
72
+ end
73
+
74
+ context '#uncaptured_amount' do
75
+ context "calculates based on capture events" do
76
+ it "with 0 capture events" do
77
+ expect(payment.uncaptured_amount).to eq(5.0)
78
+ end
79
+
80
+ it "with some capture events" do
81
+ payment.save
82
+ payment.capture_events.create!(amount: 2.0)
83
+ payment.capture_events.create!(amount: 3.0)
84
+ expect(payment.uncaptured_amount).to eq(0)
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'validations' do
90
+ it "returns useful error messages when source is invalid" do
91
+ payment.source = Spree::CreditCard.new
92
+ expect(payment).not_to be_valid
93
+ cc_errors = payment.errors['Credit Card']
94
+ expect(cc_errors).to include("Number can't be blank")
95
+ expect(cc_errors).to include("Month is not a number")
96
+ expect(cc_errors).to include("Year is not a number")
97
+ expect(cc_errors).to include("Verification Value can't be blank")
98
+ end
99
+ end
100
+
101
+ # Regression test for https://github.com/spree/spree/pull/2224
102
+ context 'failure' do
103
+ it 'should transition to failed from pending state' do
104
+ payment.state = 'pending'
105
+ payment.failure
106
+ expect(payment.state).to eql('failed')
107
+ end
108
+
109
+ it 'should transition to failed from processing state' do
110
+ payment.state = 'processing'
111
+ payment.failure
112
+ expect(payment.state).to eql('failed')
113
+ end
114
+
115
+ end
116
+
117
+ context 'invalidate' do
118
+ it 'should transition from checkout to invalid' do
119
+ payment.state = 'checkout'
120
+ payment.invalidate
121
+ expect(payment.state).to eq('invalid')
122
+ end
123
+
124
+ context "the payment's source is invalid" do
125
+
126
+ before(:each) do
127
+ card.year = 2014
128
+ payment.source = card
129
+ end
130
+
131
+ it "transitions to invalid" do
132
+ payment.state = 'checkout'
133
+ payment.invalidate
134
+ expect(payment.state).to eq ('invalid')
135
+ end
136
+ end
137
+ end
138
+
139
+ context "processing" do
140
+ describe "#process!" do
141
+ context 'with autocapture' do
142
+ before do
143
+ payment.payment_method.update_attributes!(auto_capture: true)
144
+ end
145
+
146
+ it "should purchase" do
147
+ payment.process!
148
+ expect(payment).to be_completed
149
+ end
150
+ end
151
+
152
+ context 'without autocapture' do
153
+ before do
154
+ payment.payment_method.update_attributes!(auto_capture: false)
155
+ end
156
+
157
+ context 'when in the checkout state' do
158
+ before { payment.update_attributes!(state: 'checkout') }
159
+
160
+ it "authorizes" do
161
+ payment.process!
162
+ expect(payment).to be_pending
163
+ end
164
+ end
165
+
166
+ context 'when in the processing state' do
167
+ before { payment.update_attributes!(state: 'processing') }
168
+
169
+ it "does not authorize" do
170
+ payment.process!
171
+ expect(payment).to be_processing
172
+ end
173
+ end
174
+
175
+ context 'when in the pending state' do
176
+ before { payment.update_attributes!(state: 'pending') }
177
+
178
+ it "does not re-authorize" do
179
+ expect(payment).to_not receive(:authorize!)
180
+ payment.process!
181
+ expect(payment).to be_pending
182
+ end
183
+ end
184
+
185
+ context 'when in a failed state' do
186
+ before { payment.update_attributes!(state: 'failed') }
187
+
188
+ it "raises an exception" do
189
+ expect {
190
+ payment.process!
191
+ }.to raise_error(StateMachines::InvalidTransition, /Cannot transition/)
192
+ end
193
+ end
194
+
195
+ context 'when in the completed state' do
196
+ before { payment.update_attributes!(state: 'completed') }
197
+
198
+ it "authorizes" do
199
+ payment.process!
200
+ # TODO: Is this really what we want to happen in this case?
201
+ expect(payment).to be_pending
202
+ end
203
+ end
204
+ end
205
+
206
+ it "should make the state 'processing'" do
207
+ expect(payment).to receive(:started_processing!)
208
+ payment.process!
209
+ end
210
+
211
+ it "should invalidate if payment method doesnt support source" do
212
+ expect(payment.payment_method).to receive(:supports?).with(payment.source).and_return(false)
213
+ expect { payment.process!}.to raise_error(Spree::Core::GatewayError)
214
+ expect(payment.state).to eq('invalid')
215
+ end
216
+
217
+ # Regression test for #4598
218
+ it "should allow payments with a gateway_customer_profile_id" do
219
+ allow(payment.source).to receive_messages :gateway_customer_profile_id => "customer_1"
220
+ expect(payment.payment_method).to receive(:supports?).with(payment.source).and_return(false)
221
+ expect(payment).to receive(:started_processing!)
222
+ payment.process!
223
+ end
224
+
225
+ # Another regression test for #4598
226
+ it "should allow payments with a gateway_payment_profile_id" do
227
+ allow(payment.source).to receive_messages :gateway_payment_profile_id => "customer_1"
228
+ expect(payment.payment_method).to receive(:supports?).with(payment.source).and_return(false)
229
+ expect(payment).to receive(:started_processing!)
230
+ payment.process!
231
+ end
232
+ end
233
+
234
+ describe "#authorize!" do
235
+ it "should call authorize on the gateway with the payment amount" do
236
+ expect(payment.payment_method).to receive(:authorize).with(amount_in_cents,
237
+ card,
238
+ anything).and_return(success_response)
239
+ payment.authorize!
240
+ end
241
+
242
+ it "should call authorize on the gateway with the currency code" do
243
+ allow(payment).to receive_messages :currency => 'GBP'
244
+ expect(payment.payment_method).to receive(:authorize).with(amount_in_cents,
245
+ card,
246
+ hash_including({:currency => "GBP"})).and_return(success_response)
247
+ payment.authorize!
248
+ end
249
+
250
+ it "should log the response" do
251
+ payment.save!
252
+ expect(payment.log_entries).to receive(:create!).with(details: anything)
253
+ payment.authorize!
254
+ end
255
+
256
+ context "when gateway does not match the environment" do
257
+ it "should raise an exception" do
258
+ allow(gateway).to receive_messages :environment => "foo"
259
+ expect { payment.authorize! }.to raise_error(Spree::Core::GatewayError)
260
+ end
261
+ end
262
+
263
+ context "if successful" do
264
+ before do
265
+ expect(payment.payment_method).to receive(:authorize).with(amount_in_cents,
266
+ card,
267
+ anything).and_return(success_response)
268
+ end
269
+
270
+ it "should store the response_code, avs_response and cvv_response fields" do
271
+ payment.authorize!
272
+ expect(payment.response_code).to eq('123')
273
+ expect(payment.avs_response).to eq(avs_code)
274
+ expect(payment.cvv_response_code).to eq(cvv_code)
275
+ expect(payment.cvv_response_message).to eq(ActiveMerchant::Billing::CVVResult::MESSAGES[cvv_code])
276
+ end
277
+
278
+ it "should make payment pending" do
279
+ expect(payment).to receive(:pend!)
280
+ payment.authorize!
281
+ end
282
+ end
283
+
284
+ context "if unsuccessful" do
285
+ it "should mark payment as failed" do
286
+ allow(gateway).to receive(:authorize).and_return(failed_response)
287
+ expect(payment).to receive(:failure)
288
+ expect(payment).not_to receive(:pend)
289
+ expect {
290
+ payment.authorize!
291
+ }.to raise_error(Spree::Core::GatewayError)
292
+ end
293
+ end
294
+ end
295
+
296
+ describe "#purchase!" do
297
+ it "should call purchase on the gateway with the payment amount" do
298
+ expect(gateway).to receive(:purchase).with(amount_in_cents, card, anything).and_return(success_response)
299
+ payment.purchase!
300
+ end
301
+
302
+ it "should log the response" do
303
+ payment.save!
304
+ expect(payment.log_entries).to receive(:create!).with(details: anything)
305
+ payment.purchase!
306
+ end
307
+
308
+ context "when gateway does not match the environment" do
309
+ it "should raise an exception" do
310
+ allow(gateway).to receive_messages :environment => "foo"
311
+ expect { payment.purchase! }.to raise_error(Spree::Core::GatewayError)
312
+ end
313
+ end
314
+
315
+ context "if successful" do
316
+ before do
317
+ expect(payment.payment_method).to receive(:purchase).with(amount_in_cents,
318
+ card,
319
+ anything).and_return(success_response)
320
+ end
321
+
322
+ it "should store the response_code and avs_response" do
323
+ payment.purchase!
324
+ expect(payment.response_code).to eq('123')
325
+ expect(payment.avs_response).to eq(avs_code)
326
+ end
327
+
328
+ it "should make payment complete" do
329
+ expect(payment).to receive(:complete!)
330
+ payment.purchase!
331
+ end
332
+
333
+ it "should log a capture event" do
334
+ payment.purchase!
335
+ expect(payment.capture_events.count).to eq(1)
336
+ expect(payment.capture_events.first.amount).to eq(payment.amount)
337
+ end
338
+
339
+ it "should set the uncaptured amount to 0" do
340
+ payment.purchase!
341
+ expect(payment.uncaptured_amount).to eq(0)
342
+ end
343
+ end
344
+
345
+ context "if unsuccessful" do
346
+ before do
347
+ allow(gateway).to receive(:purchase).and_return(failed_response)
348
+ expect(payment).to receive(:failure)
349
+ expect(payment).not_to receive(:pend)
350
+ end
351
+
352
+ it "should make payment failed" do
353
+ expect { payment.purchase! }.to raise_error(Spree::Core::GatewayError)
354
+ end
355
+
356
+ it "should not log a capture event" do
357
+ expect { payment.purchase! }.to raise_error(Spree::Core::GatewayError)
358
+ expect(payment.capture_events.count).to eq(0)
359
+ end
360
+ end
361
+ end
362
+
363
+ describe "#capture!" do
364
+ context "when payment is pending" do
365
+ before do
366
+ payment.amount = 100
367
+ payment.state = 'pending'
368
+ payment.response_code = '12345'
369
+ end
370
+
371
+ context "if successful" do
372
+ context 'for entire amount' do
373
+ before do
374
+ expect(payment.payment_method).to receive(:capture).with(payment.display_amount.money.cents, payment.response_code, anything).and_return(success_response)
375
+ end
376
+
377
+ it "should make payment complete" do
378
+ expect(payment).to receive(:complete!)
379
+ payment.capture!
380
+ end
381
+
382
+ it "logs capture events" do
383
+ payment.capture!
384
+ expect(payment.capture_events.count).to eq(1)
385
+ expect(payment.capture_events.first.amount).to eq(payment.amount)
386
+ end
387
+ end
388
+
389
+ it "logs capture events" do
390
+ payment.capture!
391
+ expect(payment.capture_events.count).to eq(1)
392
+ expect(payment.capture_events.first.amount).to eq(payment.amount)
393
+ end
394
+ end
395
+
396
+ context "capturing a partial amount" do
397
+ it "logs capture events" do
398
+ payment.capture!(5000)
399
+ expect(payment.capture_events.count).to eq(1)
400
+ expect(payment.capture_events.first.amount).to eq(50)
401
+ end
402
+
403
+ it "stores the captured amount on the payment" do
404
+ payment.capture!(6000)
405
+ expect(payment.captured_amount).to eq(60)
406
+ end
407
+
408
+ it "updates the amount of the payment" do
409
+ payment.capture!(6000)
410
+ expect(payment.reload.amount).to eq(60)
411
+ end
412
+ end
413
+
414
+ context "if unsuccessful" do
415
+ it "should not make payment complete" do
416
+ allow(gateway).to receive_messages :capture => failed_response
417
+ expect(payment).to receive(:failure)
418
+ expect(payment).not_to receive(:complete)
419
+ expect { payment.capture! }.to raise_error(Spree::Core::GatewayError)
420
+ end
421
+ end
422
+ end
423
+
424
+ # Regression test for #2119
425
+ context "when payment is completed" do
426
+ before do
427
+ payment.state = 'completed'
428
+ end
429
+
430
+ it "should do nothing" do
431
+ expect(payment).not_to receive(:complete)
432
+ expect(payment.payment_method).not_to receive(:capture)
433
+ expect(payment.log_entries).not_to receive(:create!)
434
+ payment.capture!
435
+ end
436
+ end
437
+ end
438
+
439
+ describe "#cancel!" do
440
+ before do
441
+ payment.response_code = 'abc'
442
+ payment.state = 'pending'
443
+ end
444
+
445
+ context "if successful" do
446
+ it "should update the response_code with the authorization from the gateway" do
447
+ # Change it to something different
448
+ allow(gateway).to receive_messages :cancel => success_response
449
+ payment.cancel!
450
+ expect(payment.state).to eq('void')
451
+ expect(payment.response_code).to eq('123')
452
+ end
453
+ end
454
+
455
+ context "if unsuccessful" do
456
+ it "should not void the payment" do
457
+ allow(gateway).to receive_messages :cancel => failed_response
458
+ expect { payment.cancel! }.to raise_error(Spree::Core::GatewayError)
459
+ expect(payment.state).to eq('pending')
460
+ expect(payment.response_code).to eq('abc')
461
+ end
462
+ end
463
+
464
+ end
465
+
466
+
467
+ describe "#void_transaction!" do
468
+ before do
469
+ payment.response_code = '123'
470
+ payment.state = 'pending'
471
+ end
472
+
473
+ context "when profiles are supported" do
474
+ it "should call payment_gateway.void with the payment's response_code" do
475
+ allow(gateway).to receive_messages :payment_profiles_supported? => true
476
+ expect(gateway).to receive(:void).with('123', card, anything).and_return(success_response)
477
+ payment.void_transaction!
478
+ end
479
+ end
480
+
481
+ context "when profiles are not supported" do
482
+ it "should call payment_gateway.void with the payment's response_code" do
483
+ allow(gateway).to receive_messages :payment_profiles_supported? => false
484
+ expect(gateway).to receive(:void).with('123', anything).and_return(success_response)
485
+ payment.void_transaction!
486
+ end
487
+ end
488
+
489
+ it "should log the response" do
490
+ expect(payment.log_entries).to receive(:create!).with(:details => anything)
491
+ payment.void_transaction!
492
+ end
493
+
494
+ context "when gateway does not match the environment" do
495
+ it "should raise an exception" do
496
+ allow(gateway).to receive_messages :environment => "foo"
497
+ expect { payment.void_transaction! }.to raise_error(Spree::Core::GatewayError)
498
+ end
499
+ end
500
+
501
+ context "if successful" do
502
+ it "should update the response_code with the authorization from the gateway" do
503
+ # Change it to something different
504
+ payment.response_code = 'abc'
505
+ payment.void_transaction!
506
+ expect(payment.response_code).to eq('12345')
507
+ end
508
+ end
509
+
510
+ context "if unsuccessful" do
511
+ it "should not void the payment" do
512
+ allow(gateway).to receive_messages :void => failed_response
513
+ expect(payment).not_to receive(:void)
514
+ expect { payment.void_transaction! }.to raise_error(Spree::Core::GatewayError)
515
+ end
516
+ end
517
+
518
+ # Regression test for #2119
519
+ context "if payment is already voided" do
520
+ before do
521
+ payment.state = 'void'
522
+ end
523
+
524
+ it "should not void the payment" do
525
+ expect(payment.payment_method).not_to receive(:void)
526
+ payment.void_transaction!
527
+ end
528
+ end
529
+ end
530
+
531
+ end
532
+
533
+ context "when already processing" do
534
+ it "should return nil without trying to process the source" do
535
+ payment.state = 'processing'
536
+
537
+ expect(payment.process!).to be_nil
538
+ end
539
+ end
540
+
541
+ context "with source required" do
542
+ context "raises an error if no source is specified" do
543
+ before do
544
+ payment.source = nil
545
+ end
546
+
547
+ specify do
548
+ expect { payment.process! }.to raise_error(Spree::Core::GatewayError, Spree.t(:payment_processing_failed))
549
+ end
550
+ end
551
+ end
552
+
553
+ context "with source optional" do
554
+ context "raises no error if source is not specified" do
555
+ before do
556
+ payment.source = nil
557
+ allow(payment.payment_method).to receive_messages(:source_required? => false)
558
+ end
559
+
560
+ specify do
561
+ expect { payment.process! }.not_to raise_error
562
+ end
563
+ end
564
+ end
565
+
566
+ describe "#credit_allowed" do
567
+ # Regression test for #4403 & #4407
568
+ it "is the difference between offsets total and payment amount" do
569
+ payment.amount = 100
570
+ allow(payment).to receive(:offsets_total).and_return(0)
571
+ expect(payment.credit_allowed).to eq(100)
572
+ allow(payment).to receive(:offsets_total).and_return(-80)
573
+ expect(payment.credit_allowed).to eq(20)
574
+ end
575
+ end
576
+
577
+ describe "#can_credit?" do
578
+ it "is true if credit_allowed > 0" do
579
+ allow(payment).to receive(:credit_allowed).and_return(100)
580
+ expect(payment.can_credit?).to be true
581
+ end
582
+
583
+ it "is false if credit_allowed is 0" do
584
+ allow(payment).to receive(:credit_allowed).and_return(0)
585
+ expect(payment.can_credit?).to be false
586
+ end
587
+ end
588
+
589
+ describe "#save" do
590
+ context "captured payments" do
591
+ it "update order payment total" do
592
+ payment = create(:payment, order: order, state: 'completed')
593
+ expect(order.payment_total).to eq payment.amount
594
+ end
595
+ end
596
+
597
+ context "not completed payments" do
598
+ it "doesn't update order payment total" do
599
+ expect {
600
+ Spree::Payment.create(:amount => 100, :order => order)
601
+ }.not_to change { order.payment_total }
602
+ end
603
+ end
604
+
605
+ context 'when the payment was completed but now void' do
606
+ let(:payment) do
607
+ Spree::Payment.create(
608
+ amount: 100,
609
+ order: order,
610
+ state: 'completed'
611
+ )
612
+ end
613
+
614
+ it 'updates order payment total' do
615
+ payment.void
616
+ expect(order.payment_total).to eq 0
617
+ end
618
+ end
619
+
620
+ context "completed orders" do
621
+ before { allow(order).to receive_messages completed?: true }
622
+
623
+ it "updates payment_state and shipments" do
624
+ expect(order.updater).to receive(:update_payment_state)
625
+ expect(order.updater).to receive(:update_shipment_state)
626
+ Spree::Payment.create(:amount => 100, :order => order)
627
+ end
628
+ end
629
+
630
+ context "when profiles are supported" do
631
+ before do
632
+ allow(gateway).to receive_messages :payment_profiles_supported? => true
633
+ allow(payment.source).to receive_messages :has_payment_profile? => false
634
+ end
635
+
636
+ context "when there is an error connecting to the gateway" do
637
+ it "should call gateway_error " do
638
+ expect(gateway).to receive(:create_profile).and_raise(ActiveMerchant::ConnectionError.new("foo", nil))
639
+ expect do
640
+ Spree::Payment.create(
641
+ :amount => 100,
642
+ :order => order,
643
+ :source => card,
644
+ :payment_method => gateway
645
+ )
646
+ end.to raise_error(Spree::Core::GatewayError)
647
+ end
648
+ end
649
+
650
+ context "with multiple payment attempts" do
651
+ let(:attributes) { attributes_for(:credit_card) }
652
+ it "should not try to create profiles on old failed payment attempts" do
653
+ allow_any_instance_of(Spree::Payment).to receive(:payment_method) { gateway }
654
+
655
+ order.payments.create!(
656
+ source_attributes: attributes,
657
+ payment_method: gateway,
658
+ amount: 100
659
+ )
660
+ expect(gateway).to receive(:create_profile).exactly :once
661
+ expect(order.payments.count).to eq(1)
662
+ order.payments.create!(
663
+ source_attributes: attributes,
664
+ payment_method: gateway,
665
+ amount: 100
666
+ )
667
+ end
668
+
669
+ end
670
+
671
+ context "when successfully connecting to the gateway" do
672
+ it "should create a payment profile" do
673
+ expect(payment.payment_method).to receive :create_profile
674
+ payment = Spree::Payment.create(
675
+ :amount => 100,
676
+ :order => order,
677
+ :source => card,
678
+ :payment_method => gateway
679
+ )
680
+ end
681
+ end
682
+ end
683
+
684
+ context "when profiles are not supported" do
685
+ before { allow(gateway).to receive_messages :payment_profiles_supported? => false }
686
+
687
+ it "should not create a payment profile" do
688
+ expect(gateway).not_to receive :create_profile
689
+ payment = Spree::Payment.create(
690
+ :amount => 100,
691
+ :order => order,
692
+ :source => card,
693
+ :payment_method => gateway
694
+ )
695
+ end
696
+ end
697
+ end
698
+
699
+ describe '#invalidate_old_payments' do
700
+ it 'should not invalidate other payments if not valid' do
701
+ payment.save
702
+ invalid_payment = Spree::Payment.new(:amount => 100, :order => order, :state => 'invalid', :payment_method => gateway)
703
+ invalid_payment.save
704
+ expect(payment.reload.state).to eq('checkout')
705
+ end
706
+ end
707
+
708
+ describe "#build_source" do
709
+ let(:params) do
710
+ {
711
+ :amount => 100,
712
+ :payment_method => gateway,
713
+ :source_attributes => {
714
+ :expiry =>"01 / 99",
715
+ :number => '1234567890123',
716
+ :verification_value => '123',
717
+ :name => 'Spree Commerce'
718
+ }
719
+ }
720
+ end
721
+
722
+ it "should build the payment's source" do
723
+ payment = Spree::Payment.new(params)
724
+ expect(payment).to be_valid
725
+ expect(payment.source).not_to be_nil
726
+ end
727
+
728
+ it "assigns user and gateway to payment source" do
729
+ order = create(:order)
730
+ source = order.payments.new(params).source
731
+
732
+ expect(source.user_id).to eq order.user_id
733
+ expect(source.payment_method_id).to eq gateway.id
734
+ end
735
+
736
+ it "errors when payment source not valid" do
737
+ params = { :amount => 100, :payment_method => gateway,
738
+ :source_attributes => {:expiry => "1 / 12" }}
739
+
740
+ payment = Spree::Payment.new(params)
741
+ expect(payment).not_to be_valid
742
+ expect(payment.source).not_to be_nil
743
+ expect(payment.source.error_on(:number).size).to eq(1)
744
+ expect(payment.source.error_on(:verification_value).size).to eq(1)
745
+ end
746
+
747
+ it "does not build a new source when duplicating the model with source_attributes set" do
748
+ payment = create(:payment)
749
+ payment.source_attributes = params[:source_attributes]
750
+ expect { payment.dup }.to_not change { payment.source }
751
+ end
752
+ end
753
+
754
+ describe "#currency" do
755
+ before { allow(order).to receive(:currency) { "ABC" } }
756
+ it "returns the order currency" do
757
+ expect(payment.currency).to eq("ABC")
758
+ end
759
+ end
760
+
761
+ describe "#display_amount" do
762
+ it "returns a Spree::Money for this amount" do
763
+ expect(payment.display_amount).to eq(Spree::Money.new(payment.amount))
764
+ end
765
+ end
766
+
767
+ # Regression test for #2216
768
+ describe "#gateway_options" do
769
+ before { allow(order).to receive_messages(:last_ip_address => "192.168.1.1") }
770
+
771
+ it "contains an IP" do
772
+ expect(payment.gateway_options[:ip]).to eq(order.last_ip_address)
773
+ end
774
+
775
+ it "contains the email address from a persisted order" do
776
+ # Sets the payment's order to a different Ruby object entirely
777
+ payment.order = Spree::Order.find(payment.order_id)
778
+ email = 'foo@example.com'
779
+ order.update_attributes(:email => email)
780
+ expect(payment.gateway_options[:email]).to eq(email)
781
+ end
782
+ end
783
+
784
+ describe "#set_unique_identifier" do
785
+ # Regression test for #1998
786
+ it "sets a unique identifier on create" do
787
+ payment.run_callbacks(:create)
788
+ expect(payment.identifier).not_to be_blank
789
+ expect(payment.identifier.size).to eq(8)
790
+ expect(payment.identifier).to be_a(String)
791
+ end
792
+
793
+ # Regression test for #3733
794
+ it "does not regenerate the identifier on re-save" do
795
+ payment.save
796
+ old_identifier = payment.identifier
797
+ payment.save
798
+ expect(payment.identifier).to eq(old_identifier)
799
+ end
800
+
801
+ context "other payment exists" do
802
+ let(:other_payment) {
803
+ payment = Spree::Payment.new
804
+ payment.source = card
805
+ payment.order = order
806
+ payment.payment_method = gateway
807
+ payment
808
+ }
809
+
810
+ before { other_payment.save! }
811
+
812
+ it "doesn't set duplicate identifier" do
813
+ expect(payment).to receive(:generate_identifier).and_return(other_payment.identifier)
814
+ expect(payment).to receive(:generate_identifier).and_call_original
815
+
816
+ payment.run_callbacks(:create)
817
+
818
+ expect(payment.identifier).not_to be_blank
819
+ expect(payment.identifier).not_to eq(other_payment.identifier)
820
+ end
821
+ end
822
+ end
823
+
824
+ describe "#amount=" do
825
+ before do
826
+ subject.amount = amount
827
+ end
828
+
829
+ context "when the amount is a string" do
830
+ context "amount is a decimal" do
831
+ let(:amount) { '2.99' }
832
+
833
+ it '#amount' do
834
+ expect(subject.amount).to eql(BigDecimal('2.99'))
835
+ end
836
+ end
837
+
838
+ context "amount is an integer" do
839
+ let(:amount) { '2' }
840
+
841
+ it '#amount' do
842
+ expect(subject.amount).to eql(BigDecimal('2.0'))
843
+ end
844
+ end
845
+
846
+ context "amount contains a dollar sign" do
847
+ let(:amount) { '$2.99' }
848
+
849
+ it '#amount' do
850
+ expect(subject.amount).to eql(BigDecimal('2.99'))
851
+ end
852
+ end
853
+
854
+ context "amount contains a comma" do
855
+ let(:amount) { '$2,999.99' }
856
+
857
+ it '#amount' do
858
+ expect(subject.amount).to eql(BigDecimal('2999.99'))
859
+ end
860
+ end
861
+
862
+ context "amount contains a negative sign" do
863
+ let(:amount) { '-2.99' }
864
+
865
+ it '#amount' do
866
+ expect(subject.amount).to eql(BigDecimal('-2.99'))
867
+ end
868
+ end
869
+
870
+ context "amount is invalid" do
871
+ let(:amount) { 'invalid' }
872
+
873
+ # this is a strange default for ActiveRecord
874
+
875
+ it '#amount' do
876
+ expect(subject.amount).to eql(BigDecimal('0'))
877
+ end
878
+ end
879
+
880
+ context "amount is an empty string" do
881
+ let(:amount) { '' }
882
+
883
+ it '#amount' do
884
+ expect(subject.amount).to be_nil
885
+ end
886
+ end
887
+ end
888
+
889
+ context "when the amount is a number" do
890
+ let(:amount) { 1.55 }
891
+
892
+ it '#amount' do
893
+ expect(subject.amount).to eql(BigDecimal('1.55'))
894
+ end
895
+ end
896
+
897
+ context "when the locale uses a coma as a decimal separator" do
898
+ before(:each) do
899
+ I18n.backend.store_translations(:fr, { :number => { :currency => { :format => { :delimiter => ' ', :separator => ',' } } } })
900
+ I18n.locale = :fr
901
+ subject.amount = amount
902
+ end
903
+
904
+ after do
905
+ I18n.locale = I18n.default_locale
906
+ end
907
+
908
+ context "amount is a decimal" do
909
+ let(:amount) { '2,99' }
910
+
911
+ it '#amount' do
912
+ expect(subject.amount).to eql(BigDecimal('2.99'))
913
+ end
914
+ end
915
+
916
+ context "amount contains a $ sign" do
917
+ let(:amount) { '2,99 $' }
918
+
919
+ it '#amount' do
920
+ expect(subject.amount).to eql(BigDecimal('2.99'))
921
+ end
922
+ end
923
+
924
+ context "amount is a number" do
925
+ let(:amount) { 2.99 }
926
+
927
+ it '#amount' do
928
+ expect(subject.amount).to eql(BigDecimal('2.99'))
929
+ end
930
+ end
931
+
932
+ context "amount contains a negative sign" do
933
+ let(:amount) { '-2,99 $' }
934
+
935
+ it '#amount' do
936
+ expect(subject.amount).to eql(BigDecimal('-2.99'))
937
+ end
938
+ end
939
+
940
+ context "amount uses a dot as a decimal separator" do
941
+ let(:amount) { '2.99' }
942
+
943
+ it '#amount' do
944
+ expect(subject.amount).to eql(BigDecimal('2.99'))
945
+ end
946
+ end
947
+ end
948
+ end
949
+
950
+ describe "is_avs_risky?" do
951
+ it "returns false if avs_response included in NON_RISKY_AVS_CODES" do
952
+ ('A'..'Z').reject{ |x| subject.class::RISKY_AVS_CODES.include?(x) }.to_a.each do |char|
953
+ payment.update_attribute(:avs_response, char)
954
+ expect(payment.is_avs_risky?).to eq false
955
+ end
956
+ end
957
+
958
+ it "returns false if avs_response.blank?" do
959
+ payment.update_attribute(:avs_response, nil)
960
+ expect(payment.is_avs_risky?).to eq false
961
+ payment.update_attribute(:avs_response, '')
962
+ expect(payment.is_avs_risky?).to eq false
963
+ end
964
+
965
+ it "returns true if avs_response in RISKY_AVS_CODES" do
966
+ # should use avs_response_code helper
967
+ ('A'..'Z').reject{ |x| subject.class::NON_RISKY_AVS_CODES.include?(x) }.to_a.each do |char|
968
+ payment.update_attribute(:avs_response, char)
969
+ expect(payment.is_avs_risky?).to eq true
970
+ end
971
+ end
972
+ end
973
+
974
+ describe "is_cvv_risky?" do
975
+ it "returns false if cvv_response_code == 'M'" do
976
+ payment.update_attribute(:cvv_response_code, "M")
977
+ expect(payment.is_cvv_risky?).to eq(false)
978
+ end
979
+
980
+ it "returns false if cvv_response_code == nil" do
981
+ payment.update_attribute(:cvv_response_code, nil)
982
+ expect(payment.is_cvv_risky?).to eq(false)
983
+ end
984
+
985
+ it "returns false if cvv_response_message == ''" do
986
+ payment.update_attribute(:cvv_response_message, '')
987
+ expect(payment.is_cvv_risky?).to eq(false)
988
+ end
989
+
990
+ it "returns true if cvv_response_code == [A-Z], omitting D" do
991
+ # should use cvv_response_code helper
992
+ (%w{N P S U} << "").each do |char|
993
+ payment.update_attribute(:cvv_response_code, char)
994
+ expect(payment.is_cvv_risky?).to eq(true)
995
+ end
996
+ end
997
+ end
998
+
999
+ # Regression test for #4072 (kinda)
1000
+ # The need for this was discovered in the research for #4072
1001
+ context "state changes" do
1002
+ it "are logged to the database" do
1003
+ expect(payment.state_changes).to be_empty
1004
+ expect(payment.process!).to be true
1005
+ expect(payment.state_changes.count).to eq(2)
1006
+ changes = payment.state_changes.map { |change| { change.previous_state => change.next_state} }
1007
+ expect(changes).to match_array([
1008
+ {"checkout" => "processing"},
1009
+ { "processing" => "pending"}
1010
+ ])
1011
+ end
1012
+ end
1013
+
1014
+ describe "#actions" do
1015
+ let(:source) { Spree::CreditCard.new }
1016
+ before { allow(subject).to receive(:payment_source) { source } }
1017
+
1018
+ it "includes the actions that the source can take" do
1019
+ allow(source).to receive(:can_capture?) { true }
1020
+ expect(subject.actions).to include "capture"
1021
+ end
1022
+
1023
+ it "excludes actions that the source cannot take" do
1024
+ allow(source).to receive(:can_capture?) { false }
1025
+ expect(subject.actions).not_to include "capture"
1026
+ end
1027
+
1028
+ it "does not include 'failure' by default" do
1029
+ expect(subject.actions).not_to include "failure"
1030
+ end
1031
+
1032
+ context "payment state is processing" do
1033
+ it "includes the 'failure' action" do
1034
+ # because the processing state does not provide
1035
+ # clarity about what has happened with an external
1036
+ # payment processor, so we want to allow the ability
1037
+ # to have someone look at the what happened and determine
1038
+ # to mark the payment as having failed
1039
+ subject.state = 'processing'
1040
+ expect(subject.actions).to include "failure"
1041
+ end
1042
+ end
1043
+ end
1044
+ end