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,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, :type => :model do
4
+ context 'CurrencyUpdater' do
5
+ context "when changing order currency" do
6
+ let!(:line_item) { create(:line_item) }
7
+ let!(:euro_price) { create(:price, variant: line_item.variant, amount: 8, currency: 'EUR') }
8
+
9
+ context "#homogenize_line_item_currencies" do
10
+ it "succeeds without error" do
11
+ expect { line_item.order.update_attributes!(currency: 'EUR') }.to_not raise_error
12
+ end
13
+
14
+ it "changes the line_item currencies" do
15
+ expect { line_item.order.update_attributes!(currency: 'EUR') }.to change{ line_item.reload.currency }.from('USD').to('EUR')
16
+ end
17
+
18
+ it "changes the line_item amounts" do
19
+ expect { line_item.order.update_attributes!(currency: 'EUR') }.to change{ line_item.reload.amount }.to(8)
20
+ end
21
+
22
+ it "fails to change the order currency when no prices are available in that currency" do
23
+ expect { line_item.order.update_attributes!(currency: 'GBP') }.to raise_error RuntimeError
24
+ end
25
+
26
+ it "calculates the item total in the order.currency" do
27
+ expect { line_item.order.update_attributes!(currency: 'EUR') }.to change{ line_item.order.item_total }.to(8)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, :type => :model do
4
+ let(:order) { stub_model("Spree::Order") }
5
+
6
+ context "#finalize!" do
7
+ let(:order) { Spree::Order.create(email: 'test@example.com', store: store) }
8
+ let(:store) { FactoryGirl.build(:store) }
9
+
10
+ before do
11
+ order.update_column :state, 'complete'
12
+ end
13
+
14
+ it "should set completed_at" do
15
+ expect(order).to receive(:touch).with(:completed_at)
16
+ order.finalize!
17
+ end
18
+
19
+ it "should sell inventory units" do
20
+ order.shipments.each do |shipment|
21
+ expect(shipment).to receive(:update!)
22
+ expect(shipment).to receive(:finalize!)
23
+ end
24
+ order.finalize!
25
+ end
26
+
27
+ it "should decrease the stock for each variant in the shipment" do
28
+ order.shipments.each do |shipment|
29
+ expect(shipment.stock_location).to receive(:decrease_stock_for_variant)
30
+ end
31
+ order.finalize!
32
+ end
33
+
34
+ it "should change the shipment state to ready if order is paid" do
35
+ Spree::Shipment.create(order: order)
36
+ order.shipments.reload
37
+
38
+ allow(order).to receive_messages(:paid? => true, :complete? => true)
39
+ order.finalize!
40
+ order.reload # reload so we're sure the changes are persisted
41
+ expect(order.shipment_state).to eq('ready')
42
+ end
43
+
44
+ after { Spree::Config.set :track_inventory_levels => true }
45
+ it "should not sell inventory units if track_inventory_levels is false" do
46
+ Spree::Config.set :track_inventory_levels => false
47
+ expect(Spree::InventoryUnit).not_to receive(:sell_units)
48
+ order.finalize!
49
+ end
50
+
51
+ it "should send an order confirmation email" do
52
+ mail_message = double "Mail::Message"
53
+ expect(Spree::OrderMailer).to receive(:confirm_email).with(order.id).and_return mail_message
54
+ expect(mail_message).to receive :deliver_now
55
+ order.finalize!
56
+ end
57
+
58
+ it "sets confirmation delivered when finalizing" do
59
+ expect(order.confirmation_delivered?).to be false
60
+ order.finalize!
61
+ expect(order.confirmation_delivered?).to be true
62
+ end
63
+
64
+ it "should not send duplicate confirmation emails" do
65
+ allow(order).to receive_messages(:confirmation_delivered? => true)
66
+ expect(Spree::OrderMailer).not_to receive(:confirm_email)
67
+ order.finalize!
68
+ end
69
+
70
+ it "should freeze all adjustments" do
71
+ # Stub this method as it's called due to a callback
72
+ # and it's irrelevant to this test
73
+ allow(order).to receive :has_available_shipment
74
+ allow(Spree::OrderMailer).to receive_message_chain :confirm_email, :deliver_now
75
+ adjustments = [double]
76
+ expect(order).to receive(:all_adjustments).and_return(adjustments)
77
+ adjustments.each do |adj|
78
+ expect(adj).to receive(:close)
79
+ end
80
+ order.finalize!
81
+ end
82
+
83
+ context "order is considered risky" do
84
+ before do
85
+ allow(order).to receive_messages :is_risky? => true
86
+ end
87
+
88
+ context "and order is approved" do
89
+ before do
90
+ allow(order).to receive_messages :approved? => true
91
+ end
92
+
93
+ it "should leave order in complete state" do
94
+ order.finalize!
95
+ expect(order.state).to eq 'complete'
96
+ end
97
+ end
98
+ end
99
+
100
+ context "order is not considered risky" do
101
+ before do
102
+ allow(order).to receive_messages :is_risky? => false
103
+ end
104
+
105
+ it "should set completed_at" do
106
+ order.finalize!
107
+ expect(order.completed_at).to be_present
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,210 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Spree::Order, :type => :model do
5
+ let(:order) { stub_model(Spree::Order) }
6
+ let(:updater) { Spree::OrderUpdater.new(order) }
7
+
8
+ context "processing payments" do
9
+ before do
10
+ # So that Payment#purchase! is called during processing
11
+ Spree::Config[:auto_capture] = true
12
+
13
+ allow(order).to receive_message_chain(:line_items, :empty?).and_return(false)
14
+ allow(order).to receive_messages :total => 100
15
+ end
16
+
17
+ it 'processes all checkout payments' do
18
+ payment_1 = create(:payment, :amount => 50)
19
+ payment_2 = create(:payment, :amount => 50)
20
+ allow(order).to receive(:unprocessed_payments).and_return([payment_1, payment_2])
21
+
22
+ order.process_payments!
23
+ updater.update_payment_state
24
+ expect(order.payment_state).to eq('paid')
25
+
26
+ expect(payment_1).to be_completed
27
+ expect(payment_2).to be_completed
28
+ end
29
+
30
+ it 'does not go over total for order' do
31
+ payment_1 = create(:payment, :amount => 50)
32
+ payment_2 = create(:payment, :amount => 50)
33
+ payment_3 = create(:payment, :amount => 50)
34
+ allow(order).to receive(:unprocessed_payments).and_return([payment_1, payment_2, payment_3])
35
+
36
+ order.process_payments!
37
+ updater.update_payment_state
38
+ expect(order.payment_state).to eq('paid')
39
+
40
+ expect(payment_1).to be_completed
41
+ expect(payment_2).to be_completed
42
+ expect(payment_3).to be_checkout
43
+ end
44
+
45
+ it "does not use failed payments" do
46
+ payment_1 = create(:payment, :amount => 50)
47
+ payment_2 = create(:payment, :amount => 50, :state => 'failed')
48
+ allow(order).to receive(:pending_payments).and_return([payment_1])
49
+
50
+ expect(payment_2).not_to receive(:process!)
51
+
52
+ order.process_payments!
53
+ end
54
+ end
55
+
56
+ context "with no payments" do
57
+ it "should return falsy" do
58
+ expect(order).to receive_messages total: 100
59
+ expect(order.process_payments!).to be_falsy
60
+ end
61
+ end
62
+
63
+ context "with payments completed" do
64
+ it "should not fail transitioning to complete when paid" do
65
+ expect(order).to receive_messages total: 100, payment_total: 100
66
+ expect(order.process_payments!).to be_truthy
67
+ end
68
+ end
69
+
70
+ context "ensure source attributes stick around" do
71
+ # For the reason of this test, please see spree/spree_gateway#132
72
+ it "does not have inverse_of defined" do
73
+ expect(Spree::Order.reflections['payments'].options[:inverse_of]).to be_nil
74
+ end
75
+
76
+ it "keeps source attributes after updating" do
77
+ persisted_order = Spree::Order.create
78
+ credit_card_payment_method = create(:credit_card_payment_method)
79
+ attributes = {
80
+ :payments_attributes => [
81
+ {
82
+ :payment_method_id => credit_card_payment_method.id,
83
+ :source_attributes => {
84
+ :name => "Ryan Bigg",
85
+ :number => "41111111111111111111",
86
+ :expiry => "01 / 15",
87
+ :verification_value => "123"
88
+ }
89
+ }
90
+ ]
91
+ }
92
+
93
+ persisted_order.update_attributes(attributes)
94
+ expect(persisted_order.unprocessed_payments.last.source.number).to be_present
95
+ end
96
+ end
97
+
98
+ context "checking if order is paid" do
99
+ context "payment_state is paid" do
100
+ before { allow(order).to receive_messages payment_state: 'paid' }
101
+ it { expect(order).to be_paid }
102
+ end
103
+
104
+ context "payment_state is credit_owned" do
105
+ before { allow(order).to receive_messages payment_state: 'credit_owed' }
106
+ it { expect(order).to be_paid }
107
+ end
108
+ end
109
+
110
+ context "#process_payments!" do
111
+ let(:payment) { stub_model(Spree::Payment) }
112
+ before { allow(order).to receive_messages unprocessed_payments: [payment], total: 10 }
113
+
114
+ it "should process the payments" do
115
+ expect(payment).to receive(:process!)
116
+ expect(order.process_payments!).to be_truthy
117
+ end
118
+
119
+ # Regression spec for https://github.com/spree/spree/issues/5436
120
+ it 'should raise an error if there are no payments to process' do
121
+ allow(order).to receive_messages unprocessed_payments: []
122
+ expect(payment).to_not receive(:process!)
123
+ expect(order.process_payments!).to be_falsey
124
+ end
125
+
126
+ context "when a payment raises a GatewayError" do
127
+ before { expect(payment).to receive(:process!).and_raise(Spree::Core::GatewayError) }
128
+
129
+ it "should return true when configured to allow checkout on gateway failures" do
130
+ Spree::Config.set :allow_checkout_on_gateway_error => true
131
+ expect(order.process_payments!).to be true
132
+ end
133
+
134
+ it "should return false when not configured to allow checkout on gateway failures" do
135
+ Spree::Config.set :allow_checkout_on_gateway_error => false
136
+ expect(order.process_payments!).to be false
137
+ end
138
+ end
139
+ end
140
+
141
+ context "#authorize_payments!" do
142
+ let(:payment) { stub_model(Spree::Payment) }
143
+ before { allow(order).to receive_messages :unprocessed_payments => [payment], :total => 10 }
144
+ subject { order.authorize_payments! }
145
+
146
+ it "processes payments with attempt_authorization!" do
147
+ expect(payment).to receive(:authorize!)
148
+ subject
149
+ end
150
+
151
+ it { is_expected.to be_truthy }
152
+ end
153
+
154
+ context "#capture_payments!" do
155
+ let(:payment) { stub_model(Spree::Payment) }
156
+ before { allow(order).to receive_messages :unprocessed_payments => [payment], :total => 10 }
157
+ subject { order.capture_payments! }
158
+
159
+ it "processes payments with attempt_authorization!" do
160
+ expect(payment).to receive(:purchase!)
161
+ subject
162
+ end
163
+
164
+ it { is_expected.to be_truthy }
165
+ end
166
+
167
+ context "#outstanding_balance" do
168
+ it "should return positive amount when payment_total is less than total" do
169
+ order.payment_total = 20.20
170
+ order.total = 30.30
171
+ expect(order.outstanding_balance).to eq(10.10)
172
+ end
173
+ it "should return negative amount when payment_total is greater than total" do
174
+ order.total = 8.20
175
+ order.payment_total = 10.20
176
+ expect(order.outstanding_balance).to be_within(0.001).of(-2.00)
177
+ end
178
+ end
179
+
180
+ context "#outstanding_balance?" do
181
+ it "should be true when total greater than payment_total" do
182
+ order.total = 10.10
183
+ order.payment_total = 9.50
184
+ expect(order.outstanding_balance?).to be true
185
+ end
186
+ it "should be true when total less than payment_total" do
187
+ order.total = 8.25
188
+ order.payment_total = 10.44
189
+ expect(order.outstanding_balance?).to be true
190
+ end
191
+ it "should be false when total equals payment_total" do
192
+ order.total = 10.10
193
+ order.payment_total = 10.10
194
+ expect(order.outstanding_balance?).to be false
195
+ end
196
+ end
197
+
198
+ context "payment required?" do
199
+ context "total is zero" do
200
+ before { allow(order).to receive_messages(total: 0) }
201
+ it { expect(order.payment_required?).to be false }
202
+ end
203
+
204
+ context "total > zero" do
205
+ before { allow(order).to receive_messages(total: 1) }
206
+ it { expect(order.payment_required?).to be true }
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, :type => :model do
4
+ let(:order) { stub_model('Spree::Order') }
5
+
6
+ describe ".is_risky?" do
7
+ context "Not risky order" do
8
+ let(:order) { FactoryGirl.create(:order, payments: [payment]) }
9
+ context "with avs_response == D" do
10
+ let(:payment) { FactoryGirl.create(:payment, avs_response: "D") }
11
+ it "is not considered risky" do
12
+ expect(order.is_risky?).to eq(false)
13
+ end
14
+ end
15
+
16
+ context "with avs_response == M" do
17
+ let(:payment) { FactoryGirl.create(:payment, avs_response: "M") }
18
+ it "is not considered risky" do
19
+ expect(order.is_risky?).to eq(false)
20
+ end
21
+ end
22
+
23
+ context "with avs_response == ''" do
24
+ let(:payment) { FactoryGirl.create(:payment, avs_response: "") }
25
+ it "is not considered risky" do
26
+ expect(order.is_risky?).to eq(false)
27
+ end
28
+ end
29
+
30
+ context "with cvv_response_code == M" do
31
+ let(:payment) { FactoryGirl.create(:payment, cvv_response_code: "M") }
32
+ it "is not considered risky" do
33
+ expect(order.is_risky?).to eq(false)
34
+ end
35
+ end
36
+
37
+ context "with cvv_response_message == ''" do
38
+ let(:payment) { FactoryGirl.create(:payment, cvv_response_message: "") }
39
+ it "is not considered risky" do
40
+ expect(order.is_risky?).to eq(false)
41
+ end
42
+ end
43
+ end
44
+
45
+ context "Risky order" do
46
+ context "AVS response message" do
47
+ let(:order) { FactoryGirl.create(:order, payments: [FactoryGirl.create(:payment, avs_response: "A")]) }
48
+ it "returns true if the order has an avs_response" do
49
+ expect(order.is_risky?).to eq(true)
50
+ end
51
+ end
52
+
53
+ context "CVV response code" do
54
+ let(:order) { FactoryGirl.create(:order, payments: [FactoryGirl.create(:payment, cvv_response_code: "N")]) }
55
+ it "returns true if the order has an cvv_response_code" do
56
+ expect(order.is_risky?).to eq(true)
57
+ end
58
+ end
59
+
60
+ context "state == 'failed'" do
61
+ let(:order) { FactoryGirl.create(:order, payments: [FactoryGirl.create(:payment, state: 'failed')]) }
62
+ it "returns true if the order has state == 'failed'" do
63
+ expect(order.is_risky?).to eq(true)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,221 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, :type => :model do
4
+ let(:order) { Spree::Order.new }
5
+ before do
6
+ # Ensure state machine has been re-defined correctly
7
+ Spree::Order.define_state_machine!
8
+ # We don't care about this validation here
9
+ allow(order).to receive(:require_email)
10
+ end
11
+
12
+ context "#next!" do
13
+ context "when current state is confirm" do
14
+ before do
15
+ order.state = "confirm"
16
+ order.run_callbacks(:create)
17
+ allow(order).to receive_messages :payment_required? => true
18
+ allow(order).to receive_messages :process_payments! => true
19
+ allow(order).to receive_messages :ensure_available_shipping_rates => true
20
+ allow(order).to receive :has_available_shipment
21
+ end
22
+
23
+ context "when payment processing succeeds" do
24
+ before do
25
+ order.payments << FactoryGirl.create(:payment, state: 'checkout', order: order)
26
+ allow(order).to receive_messages process_payments: true
27
+ end
28
+
29
+ it "should finalize order when transitioning to complete state" do
30
+ expect(order).to receive(:finalize!)
31
+ order.complete!
32
+ end
33
+
34
+ context "when credit card processing fails" do
35
+ before { allow(order).to receive_messages :process_payments! => false }
36
+
37
+ it "should not complete the order" do
38
+ order.next
39
+ expect(order.state).to eq("confirm")
40
+ end
41
+ end
42
+ end
43
+
44
+ context "when payment processing fails" do
45
+ before { allow(order).to receive_messages :process_payments! => false }
46
+
47
+ it "cannot transition to complete" do
48
+ order.next
49
+ expect(order.state).to eq("confirm")
50
+ end
51
+ end
52
+ end
53
+
54
+ context "when current state is delivery" do
55
+ before do
56
+ allow(order).to receive_messages :payment_required? => true
57
+ allow(order).to receive :apply_free_shipping_promotions
58
+ order.state = "delivery"
59
+ end
60
+
61
+ it "adjusts tax rates when transitioning to delivery" do
62
+ # Once for the line items
63
+ expect(Spree::TaxRate).to receive(:adjust).once
64
+ allow(order).to receive :set_shipments_cost
65
+ order.next!
66
+ end
67
+
68
+ it "adjusts tax rates twice if there are any shipments" do
69
+ # Once for the line items, once for the shipments
70
+ order.shipments.build
71
+ expect(Spree::TaxRate).to receive(:adjust).twice
72
+ allow(order).to receive :set_shipments_cost
73
+ order.next!
74
+ end
75
+ end
76
+ end
77
+
78
+ context "#can_cancel?" do
79
+ states = [:pending, :backorder, :ready]
80
+
81
+ states.each do |shipment_state|
82
+ it "should be true if shipment_state is #{shipment_state}" do
83
+ allow(order).to receive_messages :completed? => true
84
+ order.shipment_state = shipment_state
85
+ expect(order.can_cancel?).to be true
86
+ end
87
+ end
88
+
89
+ (Spree::Shipment.state_machine.states.keys - states).each do |shipment_state|
90
+ it "should be false if shipment_state is #{shipment_state}" do
91
+ allow(order).to receive_messages :completed? => true
92
+ order.shipment_state = shipment_state
93
+ expect(order.can_cancel?).to be false
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ context "#cancel" do
100
+ let!(:variant) { stub_model(Spree::Variant) }
101
+ let!(:inventory_units) { [stub_model(Spree::InventoryUnit, :variant => variant),
102
+ stub_model(Spree::InventoryUnit, :variant => variant) ]}
103
+ let!(:shipment) do
104
+ shipment = stub_model(Spree::Shipment)
105
+ allow(shipment).to receive_messages :inventory_units => inventory_units, :order => order
106
+ allow(order).to receive_messages :shipments => [shipment]
107
+ shipment
108
+ end
109
+
110
+ before do
111
+
112
+ 2.times do
113
+ create(:line_item, :order => order, price: 10)
114
+ end
115
+
116
+ allow(order.line_items).to receive_messages :find_by_variant_id => order.line_items.first
117
+
118
+ allow(order).to receive_messages :completed? => true
119
+ allow(order).to receive_messages :allow_cancel? => true
120
+
121
+ shipments = [shipment]
122
+ allow(order).to receive_messages :shipments => shipments
123
+ allow(shipments).to receive_messages :states => []
124
+ allow(shipments).to receive_messages :ready => []
125
+ allow(shipments).to receive_messages :pending => []
126
+ allow(shipments).to receive_messages :shipped => []
127
+
128
+ allow_any_instance_of(Spree::OrderUpdater).to receive(:update_adjustment_total) { 10 }
129
+ end
130
+
131
+ it "should send a cancel email" do
132
+
133
+ # Stub methods that cause side-effects in this test
134
+ allow(shipment).to receive(:cancel!)
135
+ allow(order).to receive :has_available_shipment
136
+ allow(order).to receive :restock_items!
137
+ mail_message = double "Mail::Message"
138
+ order_id = nil
139
+ expect(Spree::OrderMailer).to receive(:cancel_email) { |*args|
140
+ order_id = args[0]
141
+ mail_message
142
+ }
143
+ expect(mail_message).to receive :deliver_now
144
+ order.cancel!
145
+ expect(order_id).to eq(order.id)
146
+ end
147
+
148
+ context "restocking inventory" do
149
+ before do
150
+ allow(shipment).to receive(:ensure_correct_adjustment)
151
+ allow(shipment).to receive(:update_order)
152
+ allow(Spree::OrderMailer).to receive(:cancel_email).and_return(mail_message = double)
153
+ allow(mail_message).to receive :deliver_now
154
+
155
+ allow(order).to receive :has_available_shipment
156
+ end
157
+ end
158
+
159
+ context "resets payment state" do
160
+
161
+ let(:payment) { create(:payment, amount: order.total) }
162
+
163
+ before do
164
+ # TODO: This is ugly :(
165
+ # Stubs methods that cause unwanted side effects in this test
166
+ allow(Spree::OrderMailer).to receive(:cancel_email).and_return(mail_message = double)
167
+ allow(mail_message).to receive :deliver_now
168
+ allow(order).to receive :has_available_shipment
169
+ allow(order).to receive :restock_items!
170
+ allow(shipment).to receive(:cancel!)
171
+ allow(payment).to receive(:cancel!)
172
+ allow(order).to receive_message_chain(:payments, :valid, :size).and_return(1)
173
+ allow(order).to receive_message_chain(:payments, :completed).and_return([payment])
174
+ allow(order).to receive_message_chain(:payments, :completed, :includes).and_return([payment])
175
+ allow(order).to receive_message_chain(:payments, :last).and_return(payment)
176
+ allow(order).to receive_message_chain(:payments, :store_credits, :pending).and_return([payment])
177
+ end
178
+
179
+ context "without shipped items" do
180
+ it "should set payment state to 'void'" do
181
+ expect { order.cancel! }.to change{ order.reload.payment_state }.to("void")
182
+ end
183
+ end
184
+
185
+ context "with shipped items" do
186
+ before do
187
+ allow(order).to receive_messages shipment_state: 'partial'
188
+ allow(order).to receive_messages outstanding_balance?: false
189
+ allow(order).to receive_messages payment_state: "paid"
190
+ end
191
+
192
+ it "should not alter the payment state" do
193
+ order.cancel!
194
+ expect(order.payment_state).to eql "paid"
195
+ end
196
+ end
197
+
198
+ context "with payments" do
199
+ let(:payment) { create(:payment) }
200
+
201
+ it "should automatically refund all payments" do
202
+ expect(payment).to receive(:cancel!)
203
+ order.cancel!
204
+ end
205
+ end
206
+ end
207
+ end
208
+
209
+
210
+ # Another regression test for #729
211
+ context "#resume" do
212
+ before do
213
+ allow(order).to receive_messages email: "user@spreecommerce.com"
214
+ allow(order).to receive_messages state: "canceled"
215
+ allow(order).to receive_messages allow_resume?: true
216
+
217
+ # Stubs method that cause unwanted side effects in this test
218
+ allow(order).to receive :has_available_shipment
219
+ end
220
+ end
221
+ end