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::Promotion::Actions::CreateAdjustment, :type => :model do
4
+ let(:order) { create(:order_with_line_items, :line_items_count => 1) }
5
+ let(:promotion) { create(:promotion) }
6
+ let(:action) { Spree::Promotion::Actions::CreateAdjustment.new }
7
+ let(:payload) { { order: order } }
8
+
9
+ # From promotion spec:
10
+ context "#perform" do
11
+ before do
12
+ action.calculator = Spree::Calculator::FlatRate.new(:preferred_amount => 10)
13
+ promotion.promotion_actions = [action]
14
+ allow(action).to receive_messages(:promotion => promotion)
15
+ end
16
+
17
+ # Regression test for #3966
18
+ it "does not apply an adjustment if the amount is 0" do
19
+ action.calculator.preferred_amount = 0
20
+ action.perform(payload)
21
+ expect(promotion.usage_count).to eq(0)
22
+ expect(order.adjustments.count).to eq(0)
23
+ end
24
+
25
+ it "should create a discount with correct negative amount" do
26
+ order.shipments.create!(:cost => 10)
27
+
28
+ action.perform(payload)
29
+ expect(promotion.usage_count).to eq(0)
30
+ expect(order.adjustments.count).to eq(1)
31
+ expect(order.adjustments.first.amount.to_i).to eq(-10)
32
+ end
33
+
34
+ it "should create a discount accessible through both order_id and adjustable_id" do
35
+ action.perform(payload)
36
+ expect(order.adjustments.count).to eq(1)
37
+ expect(order.all_adjustments.count).to eq(1)
38
+ end
39
+
40
+ it "should not create a discount when order already has one from this promotion" do
41
+ order.shipments.create!(:cost => 10)
42
+
43
+ action.perform(payload)
44
+ action.perform(payload)
45
+ expect(promotion.usage_count).to eq(0)
46
+ expect(order.adjustments.count).to eq(1)
47
+ end
48
+
49
+ context "when a promotion code is used" do
50
+ let(:promotion_code) { create(:promotion_code) }
51
+ let(:promotion) { promotion_code.promotion }
52
+ let(:payload) { { order: order, promotion_code: promotion_code } }
53
+
54
+ it "should connect the adjustment to the promotion_code" do
55
+ expect {
56
+ action.perform(payload)
57
+ }.to change { order.adjustments.count }.by(1)
58
+ expect(order.adjustments.last.promotion_code).to eq promotion_code
59
+ end
60
+ end
61
+ end
62
+
63
+ context "#destroy" do
64
+ before(:each) do
65
+ action.calculator = Spree::Calculator::FlatRate.new(:preferred_amount => 10)
66
+ promotion.promotion_actions = [action]
67
+ end
68
+
69
+ context "when order is not complete" do
70
+ it "should not keep the adjustment" do
71
+ action.perform(payload)
72
+ action.destroy
73
+ expect(order.adjustments.count).to eq(0)
74
+ end
75
+ end
76
+
77
+ context "when order is complete" do
78
+ let(:order) do
79
+ create(:completed_order_with_totals, :line_items_count => 1)
80
+ end
81
+
82
+ before(:each) do
83
+ action.perform(payload)
84
+ action.destroy
85
+ end
86
+
87
+ it "should keep the adjustment" do
88
+ expect(order.adjustments.count).to eq(1)
89
+ end
90
+
91
+ it "should nullify the adjustment source" do
92
+ expect(order.adjustments.reload.first.source).to be_nil
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ class Promotion
5
+ module Actions
6
+ describe CreateItemAdjustments, :type => :model do
7
+ let(:order) { create(:order) }
8
+ let(:promotion) { create(:promotion) }
9
+ let(:action) { CreateItemAdjustments.new }
10
+ let!(:line_item) { create(:line_item, :order => order) }
11
+ let(:payload) { { order: order, promotion: promotion } }
12
+
13
+ before do
14
+ allow(action).to receive(:promotion).and_return(promotion)
15
+ promotion.promotion_actions = [action]
16
+ end
17
+
18
+ context "#perform" do
19
+ # Regression test for #3966
20
+ context "when calculator computes 0" do
21
+ before do
22
+ allow(action).to receive_messages :compute_amount => 0
23
+ end
24
+
25
+ it "does not create an adjustment when calculator returns 0" do
26
+ action.perform(payload)
27
+ expect(action.adjustments).to be_empty
28
+ end
29
+ end
30
+
31
+ context "when calculator returns a non-zero value" do
32
+ before do
33
+ promotion.promotion_actions = [action]
34
+ allow(action).to receive_messages :compute_amount => 10
35
+ end
36
+
37
+ it "creates adjustment with item as adjustable" do
38
+ action.perform(payload)
39
+ expect(action.adjustments.count).to eq(1)
40
+ expect(line_item.reload.adjustments).to eq(action.adjustments)
41
+ end
42
+
43
+ it "creates adjustment with self as source" do
44
+ action.perform(payload)
45
+ expect(line_item.reload.adjustments.first.source).to eq action
46
+ end
47
+
48
+ it "does not perform twice on the same item" do
49
+ 2.times { action.perform(payload) }
50
+ expect(action.adjustments.count).to eq(1)
51
+ end
52
+
53
+ context "with products rules" do
54
+ let(:rule) { double Spree::Promotion::Rules::Product }
55
+
56
+ before { allow(promotion).to receive(:eligible_rules) { [rule] } }
57
+
58
+ context "when the rule is actionable" do
59
+ before { allow(rule).to receive(:actionable?).and_return(true) }
60
+
61
+ it "creates an adjustment" do
62
+ expect {
63
+ expect {
64
+ action.perform(payload)
65
+ }.to change { action.adjustments.count }.by(1)
66
+ }.to change { line_item.adjustments.count }.by(1)
67
+
68
+ expect(action.adjustments.last).to eq line_item.adjustments.last
69
+ end
70
+ end
71
+
72
+ context "when the rule is not actionable" do
73
+ before { allow(rule).to receive(:actionable?).and_return(false) }
74
+
75
+ it "does not create an adjustment" do
76
+ expect {
77
+ expect {
78
+ action.perform(payload)
79
+ }.to_not change { action.adjustments.count }
80
+ }.to_not change { line_item.adjustments.count }
81
+ end
82
+ end
83
+ end
84
+
85
+ context "when a promotion code is used" do
86
+ let(:promotion_code) { create(:promotion_code) }
87
+ let(:promotion) { promotion_code.promotion }
88
+ let(:payload) { { order: order, promotion: promotion, promotion_code: promotion_code } }
89
+
90
+ it "should connect the adjustment to the promotion_code" do
91
+ expect {
92
+ action.perform(payload)
93
+ }.to change { line_item.adjustments.count }.by(1)
94
+ expect(line_item.adjustments.last.promotion_code).to eq promotion_code
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ context "#compute_amount" do
101
+ before { promotion.promotion_actions = [action] }
102
+
103
+ context "when the adjustable is actionable" do
104
+ it "calls compute on the calculator" do
105
+ expect(action.calculator).to receive(:compute).with(line_item)
106
+ action.compute_amount(line_item)
107
+ end
108
+
109
+ context "calculator returns amount greater than item total" do
110
+ before do
111
+ expect(action.calculator).to receive(:compute).with(line_item).and_return(300)
112
+ allow(line_item).to receive_messages(amount: 100)
113
+ end
114
+
115
+ it "does not exceed it" do
116
+ expect(action.compute_amount(line_item)).to eql(-100)
117
+ end
118
+ end
119
+ end
120
+
121
+ context "when the adjustable is not actionable" do
122
+ before { allow(promotion).to receive(:line_item_actionable?) { false } }
123
+
124
+ it 'returns 0' do
125
+ expect(action.compute_amount(line_item)).to eql(0)
126
+ end
127
+ end
128
+ end
129
+
130
+ context "#destroy" do
131
+ let!(:action) { promotion.actions.first }
132
+ let(:other_action) { other_promotion.actions.first }
133
+ let(:promotion) { create(:promotion, :with_line_item_adjustment) }
134
+ let(:other_promotion) { create(:promotion, :with_line_item_adjustment) }
135
+
136
+ it "destroys adjustments for incompleted orders" do
137
+ order = Order.create
138
+ action.adjustments.create!(label: "Check", amount: 0, order: order, adjustable: order)
139
+
140
+ expect {
141
+ action.destroy
142
+ }.to change { Adjustment.count }.by(-1)
143
+ end
144
+
145
+ it "nullifies adjustments for completed orders" do
146
+ order = Order.create(completed_at: Time.now)
147
+ adjustment = action.adjustments.create!(label: "Check", amount: 0, order: order, adjustable: order)
148
+
149
+ expect {
150
+ action.destroy
151
+ }.to change { adjustment.reload.source_id }.from(action.id).to nil
152
+ end
153
+
154
+ it "doesnt mess with unrelated adjustments" do
155
+ other_action.adjustments.create!(label: "Check", amount: 0, order: order, adjustable: order)
156
+
157
+ expect {
158
+ action.destroy
159
+ }.not_to change { other_action.adjustments.count }
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,115 @@
1
+ require "spec_helper"
2
+
3
+ module Spree::Promotion::Actions
4
+ RSpec.describe CreateQuantityAdjustments do
5
+ let(:action) { CreateQuantityAdjustments.create!(calculator: calculator, promotion: promotion) }
6
+
7
+ let(:order) { FactoryGirl.create :order }
8
+ let(:promotion) { FactoryGirl.create :promotion }
9
+
10
+ describe "#compute_amount" do
11
+ subject { action.compute_amount(line_item) }
12
+
13
+ let!(:item_a) { FactoryGirl.create :line_item, order: order, quantity: quantity, price: 10 }
14
+
15
+ context "with a flat rate adjustment" do
16
+ let(:calculator) { FactoryGirl.create :flat_rate_calculator, preferred_amount: 5 }
17
+
18
+ context "with a quantity group of 2" do
19
+ let(:line_item) { item_a }
20
+ before { action.preferred_group_size = 2 }
21
+ context "and an item with a quantity of 0" do
22
+ let(:quantity) { 0 }
23
+ it { is_expected.to eq 0 }
24
+ end
25
+ context "and an item with a quantity of 1" do
26
+ let(:quantity) { 1 }
27
+ it { is_expected.to eq 0 }
28
+ end
29
+ context "and an item with a quantity of 2" do
30
+ let(:quantity) { 2 }
31
+ it { is_expected.to eq -10 }
32
+ end
33
+ context "and an item with a quantity of 3" do
34
+ let(:quantity) { 3 }
35
+ it { is_expected.to eq -10 }
36
+ end
37
+ context "and an item with a quantity of 4" do
38
+ let(:quantity) { 4 }
39
+ it { is_expected.to eq -20 }
40
+ end
41
+ end
42
+
43
+ context "with a quantity group of 3" do
44
+ let(:quantity) { 2 }
45
+ let!(:item_b) { FactoryGirl.create :line_item, order: order, quantity: 1 }
46
+ let!(:item_c) { FactoryGirl.create :line_item, order: order, quantity: 1 }
47
+ before { action.preferred_group_size = 3 }
48
+ context "and 2x item A, 1x item B and 1x item C" do
49
+ before { action.perform({ order: order, promotion: promotion }) }
50
+ describe "the adjustment for the first item" do
51
+ let(:line_item) { item_a }
52
+ it { is_expected.to eq -10 }
53
+ end
54
+ describe "the adjustment for the second item" do
55
+ let(:line_item) { item_b }
56
+ it { is_expected.to eq -5 }
57
+ end
58
+ describe "the adjustment for the third item" do
59
+ let(:line_item) { item_c }
60
+ it { is_expected.to eq 0 }
61
+ end
62
+ end
63
+ end
64
+
65
+ context "with multiple orders using the same action" do
66
+ let(:quantity) { 2 }
67
+ let(:line_item) { item_a }
68
+ before do
69
+ action.preferred_group_size = 2
70
+ other_order = FactoryGirl.create :order
71
+ FactoryGirl.create :line_item, order: other_order, quantity: 3
72
+ action.perform({ order: other_order, promotion: promotion })
73
+ end
74
+ it { is_expected.to eq -10 }
75
+ end
76
+ end
77
+
78
+ context "with a percentage based adjustment" do
79
+ let(:calculator) { FactoryGirl.create :percent_on_item_calculator, preferred_percent: 10 }
80
+
81
+ context "with a quantity group of 3" do
82
+ before do
83
+ action.preferred_group_size = 3
84
+ action.perform({ order: order, promotion: promotion })
85
+ end
86
+ context "and 2x item A and 1x item B" do
87
+ let(:quantity) { 2 }
88
+ let!(:item_b) { FactoryGirl.create :line_item, order: order, quantity: 1, price: 10 }
89
+ describe "the adjustment for the first item" do
90
+ let(:line_item) { item_a }
91
+ it { is_expected.to eq -2 }
92
+ end
93
+ describe "the adjustment for the second item" do
94
+ let(:line_item) { item_b }
95
+ it { is_expected.to eq -1 }
96
+ end
97
+ end
98
+
99
+ context "and the items cost different amounts" do
100
+ let(:quantity) { 3 }
101
+ let!(:item_b) { FactoryGirl.create :line_item, order: order, quantity: 1, price: 20 }
102
+ describe "the adjustment for the first item" do
103
+ let(:line_item) { item_a }
104
+ it { is_expected.to eq -3 }
105
+ end
106
+ describe "the adjustment for the second item" do
107
+ let(:line_item) { item_b }
108
+ it { is_expected.to eq 0 }
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Actions::FreeShipping, :type => :model do
4
+ let(:order) { create(:completed_order_with_totals) }
5
+ let(:promotion_code) { create(:promotion_code, value: 'somecode') }
6
+ let(:promotion) { promotion_code.promotion }
7
+ let(:action) { Spree::Promotion::Actions::FreeShipping.create }
8
+ let(:payload) { { order: order, promotion_code: promotion_code } }
9
+
10
+ # From promotion spec:
11
+ context "#perform" do
12
+ before do
13
+ order.shipments << create(:shipment)
14
+ promotion.promotion_actions << action
15
+ end
16
+
17
+ context "when valid" do
18
+ it "should create a discount with correct negative amount" do
19
+ expect(order.shipments.count).to eq(2)
20
+ expect(order.shipments.first.cost).to eq(100)
21
+ expect(order.shipments.last.cost).to eq(100)
22
+ expect(action.perform(payload)).to be true
23
+ expect(promotion.usage_count).to eq(1)
24
+ expect(order.shipment_adjustments.count).to eq(2)
25
+ expect(order.shipment_adjustments.first.amount.to_i).to eq(-100)
26
+ expect(order.shipment_adjustments.last.amount.to_i).to eq(-100)
27
+ expect(order.shipment_adjustments.map(&:promotion_code)).to eq [promotion_code, promotion_code]
28
+ end
29
+ end
30
+
31
+ context "when order already has one from this promotion" do
32
+ it "should not create a discount" do
33
+ expect(action.perform(payload)).to be true
34
+ expect(action.perform(payload)).to be false
35
+ expect(promotion.usage_count).to eq(1)
36
+ expect(order.shipment_adjustments.count).to eq(2)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::FirstOrder, :type => :model do
4
+ let(:rule) { Spree::Promotion::Rules::FirstOrder.new }
5
+ let(:order) { mock_model(Spree::Order, :user => nil, :email => nil) }
6
+ let(:user) { mock_model(Spree::LegacyUser) }
7
+
8
+ context "without a user or email" do
9
+ it { expect(rule).not_to be_eligible(order) }
10
+ it "sets an error message" do
11
+ rule.eligible?(order)
12
+ expect(rule.eligibility_errors.full_messages.first).
13
+ to eq "You need to login or provide your email before applying this coupon code."
14
+ end
15
+ end
16
+
17
+ context "first order" do
18
+ context "for a signed user" do
19
+ context "with no completed orders" do
20
+ before(:each) do
21
+ allow(user).to receive_message_chain(:orders, :complete => [])
22
+ end
23
+
24
+ specify do
25
+ allow(order).to receive_messages(:user => user)
26
+ expect(rule).to be_eligible(order)
27
+ end
28
+
29
+ it "should be eligible when user passed in payload data" do
30
+ expect(rule).to be_eligible(order, :user => user)
31
+ end
32
+ end
33
+
34
+ context "with completed orders" do
35
+ before(:each) do
36
+ allow(order).to receive_messages(:user => user)
37
+ end
38
+
39
+ it "should be eligible when checked against first completed order" do
40
+ allow(user).to receive_message_chain(:orders, :complete => [order])
41
+ expect(rule).to be_eligible(order)
42
+ end
43
+
44
+ context "with another order" do
45
+ before { allow(user).to receive_message_chain(:orders, :complete => [mock_model(Spree::Order)]) }
46
+ it { expect(rule).not_to be_eligible(order) }
47
+ it "sets an error message" do
48
+ rule.eligible?(order)
49
+ expect(rule.eligibility_errors.full_messages.first).
50
+ to eq "This coupon code can only be applied to your first order."
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ context "for a guest user" do
57
+ let(:email) { 'user@spreecommerce.com' }
58
+ before { allow(order).to receive_messages :email => 'user@spreecommerce.com' }
59
+
60
+ context "with no other orders" do
61
+ it { expect(rule).to be_eligible(order) }
62
+ end
63
+
64
+ context "with another order" do
65
+ before { allow(rule).to receive_messages(:orders_by_email => [mock_model(Spree::Order)]) }
66
+ it { expect(rule).not_to be_eligible(order) }
67
+ it "sets an error message" do
68
+ rule.eligible?(order)
69
+ expect(rule.eligibility_errors.full_messages.first).
70
+ to eq "This coupon code can only be applied to your first order."
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end