spree_core 3.3.0.rc1 → 3.3.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +1 -1
  3. data/app/mailers/spree/base_mailer.rb +5 -0
  4. data/app/models/spree/ability.rb +4 -1
  5. data/app/models/spree/image.rb +6 -2
  6. data/app/models/spree/order.rb +10 -9
  7. data/app/models/spree/order/payments.rb +1 -1
  8. data/app/models/spree/payment_method/store_credit.rb +4 -0
  9. data/app/models/spree/shipment.rb +2 -0
  10. data/app/views/spree/shared/_base_mailer_header.html.erb +5 -1
  11. data/app/views/spree/shared/_mailer_line_item.html.erb +5 -1
  12. data/config/routes.rb +0 -3
  13. data/lib/spree/core/components.rb +17 -0
  14. data/lib/spree/core/controller_helpers/auth.rb +3 -1
  15. data/lib/spree/core/engine.rb +1 -0
  16. data/lib/spree/core/validators/email.rb +1 -5
  17. data/lib/spree/core/version.rb +1 -1
  18. data/spree_core.gemspec +1 -1
  19. metadata +4 -204
  20. data/lib/spree/testing_support/shoulda_matcher_configuration.rb +0 -6
  21. data/spec/fixtures/thinking-cat.jpg +0 -0
  22. data/spec/helpers/base_helper_spec.rb +0 -200
  23. data/spec/helpers/products_helper_spec.rb +0 -289
  24. data/spec/lib/calculated_adjustments_spec.rb +0 -7
  25. data/spec/lib/i18n_spec.rb +0 -123
  26. data/spec/lib/search/base_spec.rb +0 -86
  27. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +0 -103
  28. data/spec/lib/spree/core/controller_helpers/order_spec.rb +0 -110
  29. data/spec/lib/spree/core/controller_helpers/search_spec.rb +0 -17
  30. data/spec/lib/spree/core/controller_helpers/store_spec.rb +0 -72
  31. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +0 -39
  32. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -22
  33. data/spec/lib/spree/core/importer/order_spec.rb +0 -607
  34. data/spec/lib/spree/core/number_generator_spec.rb +0 -139
  35. data/spec/lib/spree/core/token_generator_spec.rb +0 -24
  36. data/spec/lib/spree/core/validators/email_spec.rb +0 -54
  37. data/spec/lib/spree/core_spec.rb +0 -23
  38. data/spec/lib/spree/localized_number_spec.rb +0 -54
  39. data/spec/lib/spree/migrations_spec.rb +0 -36
  40. data/spec/lib/spree/money_spec.rb +0 -122
  41. data/spec/lib/tasks/exchanges_spec.rb +0 -136
  42. data/spec/mailers/order_mailer_spec.rb +0 -122
  43. data/spec/mailers/reimbursement_mailer_spec.rb +0 -52
  44. data/spec/mailers/shipment_mailer_spec.rb +0 -81
  45. data/spec/mailers/test_mailer_spec.rb +0 -38
  46. data/spec/models/spree/ability_spec.rb +0 -251
  47. data/spec/models/spree/address_spec.rb +0 -402
  48. data/spec/models/spree/adjustable/adjuster/base_spec.rb +0 -10
  49. data/spec/models/spree/adjustable/adjuster/promotion_spec.rb +0 -211
  50. data/spec/models/spree/adjustable/adjuster/tax_spec.rb +0 -86
  51. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +0 -26
  52. data/spec/models/spree/adjustment_spec.rb +0 -189
  53. data/spec/models/spree/app_configuration_spec.rb +0 -26
  54. data/spec/models/spree/asset_spec.rb +0 -28
  55. data/spec/models/spree/calculator/default_tax_spec.rb +0 -152
  56. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +0 -25
  57. data/spec/models/spree/calculator/flat_rate_spec.rb +0 -47
  58. data/spec/models/spree/calculator/flexi_rate_spec.rb +0 -41
  59. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +0 -15
  60. data/spec/models/spree/calculator/price_sack_spec.rb +0 -30
  61. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +0 -47
  62. data/spec/models/spree/calculator/shipping.rb +0 -8
  63. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +0 -23
  64. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +0 -13
  65. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +0 -52
  66. data/spec/models/spree/calculator/shipping/per_item_spec.rb +0 -20
  67. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +0 -29
  68. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +0 -40
  69. data/spec/models/spree/calculator/tiered_percent_spec.rb +0 -51
  70. data/spec/models/spree/calculator_spec.rb +0 -69
  71. data/spec/models/spree/classification_spec.rb +0 -93
  72. data/spec/models/spree/concerns/display_money_spec.rb +0 -43
  73. data/spec/models/spree/concerns/user_methods_spec.rb +0 -82
  74. data/spec/models/spree/concerns/vat_price_calculation_spec.rb +0 -66
  75. data/spec/models/spree/country_spec.rb +0 -55
  76. data/spec/models/spree/credit_card_spec.rb +0 -328
  77. data/spec/models/spree/customer_return_spec.rb +0 -240
  78. data/spec/models/spree/exchange_spec.rb +0 -75
  79. data/spec/models/spree/gateway/bogus_simple.rb +0 -20
  80. data/spec/models/spree/gateway/bogus_spec.rb +0 -13
  81. data/spec/models/spree/gateway_spec.rb +0 -61
  82. data/spec/models/spree/image_spec.rb +0 -8
  83. data/spec/models/spree/inventory_unit_spec.rb +0 -256
  84. data/spec/models/spree/line_item_spec.rb +0 -348
  85. data/spec/models/spree/option_type_prototype_spec.rb +0 -9
  86. data/spec/models/spree/option_type_spec.rb +0 -14
  87. data/spec/models/spree/option_value_spec.rb +0 -18
  88. data/spec/models/spree/order/address_spec.rb +0 -50
  89. data/spec/models/spree/order/adjustments_spec.rb +0 -29
  90. data/spec/models/spree/order/callbacks_spec.rb +0 -42
  91. data/spec/models/spree/order/checkout_spec.rb +0 -770
  92. data/spec/models/spree/order/currency_updater_spec.rb +0 -32
  93. data/spec/models/spree/order/finalizing_spec.rb +0 -114
  94. data/spec/models/spree/order/helpers_spec.rb +0 -5
  95. data/spec/models/spree/order/payment_spec.rb +0 -214
  96. data/spec/models/spree/order/risk_assessment_spec.rb +0 -84
  97. data/spec/models/spree/order/shipments_spec.rb +0 -43
  98. data/spec/models/spree/order/state_machine_spec.rb +0 -212
  99. data/spec/models/spree/order/store_credit_spec.rb +0 -457
  100. data/spec/models/spree/order/tax_spec.rb +0 -84
  101. data/spec/models/spree/order/totals_spec.rb +0 -24
  102. data/spec/models/spree/order/updating_spec.rb +0 -18
  103. data/spec/models/spree/order/validations_spec.rb +0 -15
  104. data/spec/models/spree/order_contents_spec.rb +0 -332
  105. data/spec/models/spree/order_inventory_spec.rb +0 -247
  106. data/spec/models/spree/order_merger_spec.rb +0 -135
  107. data/spec/models/spree/order_spec.rb +0 -1067
  108. data/spec/models/spree/order_updater_spec.rb +0 -305
  109. data/spec/models/spree/payment/gateway_options_spec.rb +0 -127
  110. data/spec/models/spree/payment/store_credit_spec.rb +0 -60
  111. data/spec/models/spree/payment_method/store_credit_spec.rb +0 -291
  112. data/spec/models/spree/payment_method_spec.rb +0 -108
  113. data/spec/models/spree/payment_spec.rb +0 -922
  114. data/spec/models/spree/preference_spec.rb +0 -80
  115. data/spec/models/spree/preferences/configuration_spec.rb +0 -30
  116. data/spec/models/spree/preferences/preferable_spec.rb +0 -344
  117. data/spec/models/spree/preferences/scoped_store_spec.rb +0 -58
  118. data/spec/models/spree/preferences/store_spec.rb +0 -46
  119. data/spec/models/spree/price_spec.rb +0 -128
  120. data/spec/models/spree/product/scopes_spec.rb +0 -174
  121. data/spec/models/spree/product_duplicator_spec.rb +0 -102
  122. data/spec/models/spree/product_filter_spec.rb +0 -26
  123. data/spec/models/spree/product_option_type_spec.rb +0 -9
  124. data/spec/models/spree/product_promotion_rule_spec.rb +0 -9
  125. data/spec/models/spree/product_property_spec.rb +0 -26
  126. data/spec/models/spree/product_spec.rb +0 -626
  127. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +0 -113
  128. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +0 -148
  129. data/spec/models/spree/promotion/actions/create_line_items_spec.rb +0 -86
  130. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +0 -36
  131. data/spec/models/spree/promotion/rules/country_spec.rb +0 -36
  132. data/spec/models/spree/promotion/rules/first_order_spec.rb +0 -75
  133. data/spec/models/spree/promotion/rules/item_total_spec.rb +0 -282
  134. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +0 -42
  135. data/spec/models/spree/promotion/rules/option_value_spec.rb +0 -90
  136. data/spec/models/spree/promotion/rules/product_spec.rb +0 -143
  137. data/spec/models/spree/promotion/rules/taxon_spec.rb +0 -102
  138. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +0 -27
  139. data/spec/models/spree/promotion/rules/user_spec.rb +0 -45
  140. data/spec/models/spree/promotion_action_spec.rb +0 -10
  141. data/spec/models/spree/promotion_category_spec.rb +0 -17
  142. data/spec/models/spree/promotion_handler/cart_spec.rb +0 -102
  143. data/spec/models/spree/promotion_handler/coupon_spec.rb +0 -323
  144. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +0 -48
  145. data/spec/models/spree/promotion_handler/page_spec.rb +0 -44
  146. data/spec/models/spree/promotion_rule_spec.rb +0 -29
  147. data/spec/models/spree/promotion_rule_taxon_spec.rb +0 -9
  148. data/spec/models/spree/promotion_rule_user_spec.rb +0 -9
  149. data/spec/models/spree/promotion_spec.rb +0 -674
  150. data/spec/models/spree/property_prototype_spec.rb +0 -9
  151. data/spec/models/spree/property_spec.rb +0 -5
  152. data/spec/models/spree/prototype_spec.rb +0 -5
  153. data/spec/models/spree/prototype_taxon_spec.rb +0 -9
  154. data/spec/models/spree/refund_reason_spec.rb +0 -20
  155. data/spec/models/spree/refund_spec.rb +0 -195
  156. data/spec/models/spree/reimbursement/credit_spec.rb +0 -36
  157. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +0 -140
  158. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +0 -83
  159. data/spec/models/spree/reimbursement_performer_spec.rb +0 -30
  160. data/spec/models/spree/reimbursement_spec.rb +0 -188
  161. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +0 -63
  162. data/spec/models/spree/reimbursement_type/credit_spec.rb +0 -53
  163. data/spec/models/spree/reimbursement_type/exchange_spec.rb +0 -46
  164. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +0 -55
  165. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +0 -101
  166. data/spec/models/spree/return_authorization_reason_spec.rb +0 -7
  167. data/spec/models/spree/return_authorization_spec.rb +0 -230
  168. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +0 -77
  169. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +0 -58
  170. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +0 -61
  171. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +0 -32
  172. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +0 -29
  173. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +0 -35
  174. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +0 -65
  175. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +0 -43
  176. data/spec/models/spree/return_item_spec.rb +0 -734
  177. data/spec/models/spree/returns_calculator_spec.rb +0 -14
  178. data/spec/models/spree/role_spec.rb +0 -7
  179. data/spec/models/spree/shipment_spec.rb +0 -744
  180. data/spec/models/spree/shipping_calculator_spec.rb +0 -45
  181. data/spec/models/spree/shipping_category_spec.rb +0 -19
  182. data/spec/models/spree/shipping_method_spec.rb +0 -125
  183. data/spec/models/spree/shipping_rate_spec.rb +0 -140
  184. data/spec/models/spree/state_spec.rb +0 -29
  185. data/spec/models/spree/stock/availability_validator_spec.rb +0 -42
  186. data/spec/models/spree/stock/content_item_spec.rb +0 -31
  187. data/spec/models/spree/stock/coordinator_spec.rb +0 -61
  188. data/spec/models/spree/stock/differentiator_spec.rb +0 -39
  189. data/spec/models/spree/stock/estimator_spec.rb +0 -202
  190. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +0 -37
  191. data/spec/models/spree/stock/package_spec.rb +0 -182
  192. data/spec/models/spree/stock/packer_spec.rb +0 -70
  193. data/spec/models/spree/stock/prioritizer_spec.rb +0 -125
  194. data/spec/models/spree/stock/quantifier_spec.rb +0 -126
  195. data/spec/models/spree/stock/splitter/backordered_spec.rb +0 -29
  196. data/spec/models/spree/stock/splitter/base_spec.rb +0 -21
  197. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +0 -47
  198. data/spec/models/spree/stock/splitter/weight_spec.rb +0 -32
  199. data/spec/models/spree/stock_item_spec.rb +0 -465
  200. data/spec/models/spree/stock_location_spec.rb +0 -243
  201. data/spec/models/spree/stock_movement_spec.rb +0 -120
  202. data/spec/models/spree/stock_transfer_spec.rb +0 -50
  203. data/spec/models/spree/store_credit_event_spec.rb +0 -101
  204. data/spec/models/spree/store_credit_spec.rb +0 -798
  205. data/spec/models/spree/store_spec.rb +0 -78
  206. data/spec/models/spree/tax_category_spec.rb +0 -32
  207. data/spec/models/spree/tax_rate_spec.rb +0 -561
  208. data/spec/models/spree/taxon_spec.rb +0 -93
  209. data/spec/models/spree/taxonomy_spec.rb +0 -18
  210. data/spec/models/spree/tracker_spec.rb +0 -21
  211. data/spec/models/spree/user_spec.rb +0 -203
  212. data/spec/models/spree/variant_spec.rb +0 -818
  213. data/spec/models/spree/zone_member_spec.rb +0 -38
  214. data/spec/models/spree/zone_spec.rb +0 -472
  215. data/spec/spec_helper.rb +0 -82
  216. data/spec/support/big_decimal.rb +0 -5
  217. data/spec/support/concerns/adjustment_source.rb +0 -23
  218. data/spec/support/concerns/default_price.rb +0 -37
  219. data/spec/support/rake.rb +0 -13
  220. data/spec/support/test_gateway.rb +0 -2
@@ -1,48 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Spree
4
- module PromotionHandler
5
- describe FreeShipping, type: :model do
6
- let(:order) { create(:order) }
7
- let(:shipment) { create(:shipment, order: order ) }
8
-
9
- let(:promotion) { Promotion.create(name: "Free Shipping") }
10
- let(:calculator) { Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10) }
11
- let!(:action) { Promotion::Actions::FreeShipping.create(promotion: promotion) }
12
-
13
- subject { Spree::PromotionHandler::FreeShipping.new(order) }
14
-
15
- context "activates in Shipment level" do
16
- it "creates the adjustment" do
17
- expect { subject.activate }.to change { shipment.adjustments.count }.by(1)
18
- end
19
- end
20
-
21
- context "if promo has a code" do
22
- before do
23
- promotion.update_column(:code, "code")
24
- end
25
-
26
- it "does adjust the shipment when applied to order" do
27
- order.promotions << promotion
28
-
29
- expect { subject.activate }.to change { shipment.adjustments.count }
30
- end
31
-
32
- it "does not adjust the shipment when not applied to order" do
33
- expect { subject.activate }.to_not change { shipment.adjustments.count }
34
- end
35
- end
36
-
37
- context "if promo has a path" do
38
- before do
39
- promotion.update_column(:path, "path")
40
- end
41
-
42
- it "does not adjust the shipment" do
43
- expect { subject.activate }.to_not change { shipment.adjustments.count }
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Spree
4
- module PromotionHandler
5
- describe Page, type: :model do
6
- let(:order) { create(:order_with_line_items, line_items_count: 1) }
7
-
8
- let(:promotion) { Promotion.create(name: "10% off", path: '10off') }
9
- before do
10
- calculator = Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)
11
- action = Promotion::Actions::CreateItemAdjustments.create(calculator: calculator)
12
- promotion.actions << action
13
- end
14
-
15
- it "activates at the right path" do
16
- expect(order.line_item_adjustments.count).to eq(0)
17
- Spree::PromotionHandler::Page.new(order, '10off').activate
18
- expect(order.line_item_adjustments.count).to eq(1)
19
- end
20
-
21
- context "when promotion is expired" do
22
- before do
23
- promotion.update_columns(
24
- starts_at: 1.week.ago,
25
- expires_at: 1.day.ago
26
- )
27
- end
28
-
29
- it "is not activated" do
30
- expect(order.line_item_adjustments.count).to eq(0)
31
- Spree::PromotionHandler::Page.new(order, '10off').activate
32
- expect(order.line_item_adjustments.count).to eq(0)
33
- end
34
- end
35
-
36
- it "does not activate at the wrong path" do
37
- expect(order.line_item_adjustments.count).to eq(0)
38
- Spree::PromotionHandler::Page.new(order, 'wrongpath').activate
39
- expect(order.line_item_adjustments.count).to eq(0)
40
- end
41
- end
42
- end
43
- end
44
-
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Spree
4
- describe Spree::PromotionRule, type: :model do
5
-
6
- class BadTestRule < Spree::PromotionRule; end
7
-
8
- class TestRule < Spree::PromotionRule
9
- def eligible?
10
- true
11
- end
12
- end
13
-
14
- it "should force developer to implement eligible? method" do
15
- expect { BadTestRule.new.eligible? }.to raise_error(ArgumentError)
16
- end
17
-
18
- it "validates unique rules for a promotion" do
19
- p1 = TestRule.new
20
- p1.promotion_id = 1
21
- p1.save
22
-
23
- p2 = TestRule.new
24
- p2.promotion_id = 1
25
- expect(p2).not_to be_valid
26
- end
27
-
28
- end
29
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Spree::PromotionRuleTaxon do
4
- describe 'Validations' do
5
- it { is_expected.to validate_presence_of(:promotion_rule) }
6
- it { is_expected.to validate_presence_of(:taxon) }
7
- it { is_expected.to validate_uniqueness_of(:promotion_rule_id).scoped_to(:taxon_id).allow_nil }
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Spree::PromotionRuleUser do
4
- describe 'Validations' do
5
- it { is_expected.to validate_presence_of(:promotion_rule) }
6
- it { is_expected.to validate_presence_of(:user) }
7
- it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:promotion_rule_id).allow_nil }
8
- end
9
- end
@@ -1,674 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Spree::Promotion, type: :model do
4
- let(:promotion) { Spree::Promotion.new }
5
-
6
- describe "validations" do
7
- before :each do
8
- @valid_promotion = Spree::Promotion.new name: "A promotion"
9
- end
10
-
11
- it { is_expected.to validate_presence_of(:name) }
12
- it { is_expected.to validate_uniqueness_of(:path).case_insensitive.allow_blank }
13
- it { is_expected.to validate_uniqueness_of(:code).case_insensitive.allow_blank }
14
- it { is_expected.to validate_numericality_of(:usage_limit).is_greater_than(0).allow_nil }
15
- it { is_expected.to validate_length_of(:description).is_at_most(255) }
16
- it { is_expected.to allow_values('', nil).for(:description) }
17
-
18
- it "valid_promotion is valid" do
19
- expect(@valid_promotion).to be_valid
20
- end
21
-
22
- it "validates usage limit" do
23
- @valid_promotion.usage_limit = -1
24
- expect(@valid_promotion).not_to be_valid
25
-
26
- @valid_promotion.usage_limit = 100
27
- expect(@valid_promotion).to be_valid
28
- end
29
-
30
- it "validates name" do
31
- @valid_promotion.name = nil
32
- expect(@valid_promotion).not_to be_valid
33
- end
34
-
35
- describe "expires_at_must_be_later_than_starts_at" do
36
- before do
37
- @valid_promotion.starts_at = Date.today
38
- end
39
-
40
- context "starts_at is a date earlier than expires_at" do
41
- before { @valid_promotion.expires_at = 5.days.from_now }
42
-
43
- it "is valid" do
44
- expect(@valid_promotion).to be_valid
45
- end
46
- end
47
-
48
- context "starts_at is a date earlier than expires_at" do
49
- before { @valid_promotion.expires_at = 5.days.ago }
50
-
51
- context "is not valid" do
52
- before { @valid_promotion.valid? }
53
- it { expect(@valid_promotion).not_to be_valid }
54
- it { expect(@valid_promotion.errors[:expires_at]).to include(I18n.t(:invalid_date_range, scope: 'activerecord.errors.models.spree/promotion.attributes.expires_at')) }
55
- end
56
- end
57
-
58
- context "starts_at and expires_at are nil" do
59
- before do
60
- @valid_promotion.expires_at = nil
61
- @valid_promotion.starts_at = nil
62
- end
63
-
64
- it "is valid" do
65
- expect(@valid_promotion).to be_valid
66
- end
67
- end
68
- end
69
- end
70
-
71
- describe 'scopes' do
72
- describe '.coupons' do
73
- let!(:promotion_without_code) { Spree::Promotion.create! name: 'test', code: '' }
74
- let!(:promotion_with_code) { Spree::Promotion.create! name: 'test1', code: 'code' }
75
-
76
- subject { Spree::Promotion.coupons }
77
-
78
- it 'is expected to not include promotion without code' do
79
- is_expected.to_not include(promotion_without_code)
80
- end
81
-
82
- it 'is expected to include promotion with code' do
83
- is_expected.to include(promotion_with_code)
84
- end
85
- end
86
-
87
- describe '.applied' do
88
- let!(:promotion_not_applied) { Spree::Promotion.create! name: 'test', code: '' }
89
- let(:order) { create(:order) }
90
- let!(:promotion_applied) do
91
- promotion = Spree::Promotion.create!(name: 'test1', code: '')
92
- promotion.orders << order
93
- promotion
94
- end
95
-
96
- subject { Spree::Promotion.applied }
97
-
98
- it 'is expected to not include promotion not applied' do
99
- is_expected.to_not include(promotion_not_applied)
100
- end
101
-
102
- it 'is expected to include promotion applied' do
103
- is_expected.to include(promotion_applied)
104
- end
105
- end
106
-
107
- describe '.advertised' do
108
- let!(:promotion_not_advertised) { Spree::Promotion.create! name: 'test', advertise: false }
109
- let!(:promotion_advertised) { Spree::Promotion.create! name: 'test1', advertise: true }
110
-
111
- subject { Spree::Promotion.advertised }
112
-
113
- it 'is expected to not include promotion not advertised' do
114
- is_expected.to_not include(promotion_not_advertised)
115
- end
116
-
117
- it 'is expected to include promotion advertised' do
118
- is_expected.to include(promotion_advertised)
119
- end
120
- end
121
- end
122
-
123
- describe "#destroy" do
124
- let(:promotion) { Spree::Promotion.create(name: "delete me") }
125
-
126
- before(:each) do
127
- promotion.actions << Spree::Promotion::Actions::CreateAdjustment.new
128
- promotion.rules << Spree::Promotion::Rules::FirstOrder.new
129
- promotion.save!
130
- promotion.destroy
131
- end
132
-
133
- it "should delete actions" do
134
- expect(Spree::PromotionAction.count).to eq(0)
135
- end
136
-
137
- it "should delete rules" do
138
- expect(Spree::PromotionRule.count).to eq(0)
139
- end
140
- end
141
-
142
- describe "#save" do
143
- let(:promotion) { Spree::Promotion.create(name: "delete me") }
144
-
145
- before(:each) do
146
- promotion.actions << Spree::Promotion::Actions::CreateAdjustment.new
147
- promotion.rules << Spree::Promotion::Rules::FirstOrder.new
148
- promotion.save!
149
- end
150
-
151
- it "should deeply autosave records and preferences" do
152
- promotion.actions[0].calculator.preferred_flat_percent = 10
153
- promotion.save!
154
- expect(Spree::Calculator.first.preferred_flat_percent).to eq(10)
155
- end
156
- end
157
-
158
- describe "#activate" do
159
- before do
160
- @action1 = Spree::Promotion::Actions::CreateAdjustment.create!
161
- @action2 = Spree::Promotion::Actions::CreateAdjustment.create!
162
- allow(@action1).to receive_messages perform: true
163
- allow(@action2).to receive_messages perform: true
164
-
165
- promotion.promotion_actions = [@action1, @action2]
166
- promotion.created_at = 2.days.ago
167
-
168
- @user = stub_model(Spree::LegacyUser, email: "spree@example.com")
169
- @order = Spree::Order.create user: @user
170
- @payload = { order: @order, user: @user }
171
- end
172
-
173
- it "should check path if present" do
174
- promotion.path = 'content/cvv'
175
- @payload[:path] = 'content/cvv'
176
- expect(@action1).to receive(:perform).with(@payload)
177
- expect(@action2).to receive(:perform).with(@payload)
178
- promotion.activate(@payload)
179
- end
180
-
181
- it "does not perform actions against an order in a finalized state" do
182
- expect(@action1).not_to receive(:perform).with(@payload)
183
-
184
- @order.state = 'complete'
185
- promotion.activate(@payload)
186
-
187
- @order.state = 'awaiting_return'
188
- promotion.activate(@payload)
189
-
190
- @order.state = 'returned'
191
- promotion.activate(@payload)
192
- end
193
-
194
- it "does activate if newer then order" do
195
- expect(@action1).to receive(:perform).with(@payload)
196
- promotion.created_at = DateTime.current + 2
197
- expect(promotion.activate(@payload)).to be true
198
- end
199
-
200
- context "keeps track of the orders" do
201
- context "when activated" do
202
- it "assigns the order" do
203
- expect(promotion.orders).to be_empty
204
- expect(promotion.activate(@payload)).to be true
205
- expect(promotion.orders.first).to eql @order
206
- end
207
- end
208
- context "when not activated" do
209
- it "will not assign the order" do
210
- @order.state = 'complete'
211
- expect(promotion.orders).to be_empty
212
- expect(promotion.activate(@payload)).to be_falsey
213
- expect(promotion.orders).to be_empty
214
- end
215
- end
216
-
217
- end
218
-
219
- end
220
-
221
- context "#usage_limit_exceeded" do
222
- let(:promotable) { double('Promotable') }
223
- it "should not have its usage limit exceeded with no usage limit" do
224
- promotion.usage_limit = 0
225
- expect(promotion.usage_limit_exceeded?(promotable)).to be false
226
- end
227
-
228
- it "should have its usage limit exceeded" do
229
- promotion.usage_limit = 2
230
- allow(promotion).to receive_messages(adjusted_credits_count: 2)
231
- expect(promotion.usage_limit_exceeded?(promotable)).to be true
232
-
233
- allow(promotion).to receive_messages(adjusted_credits_count: 3)
234
- expect(promotion.usage_limit_exceeded?(promotable)).to be true
235
- end
236
- end
237
-
238
- context "#expired" do
239
- it "should not be exipired" do
240
- expect(promotion).not_to be_expired
241
- end
242
-
243
- it "should be expired if it hasn't started yet" do
244
- promotion.starts_at = Time.current + 1.day
245
- expect(promotion).to be_expired
246
- end
247
-
248
- it "should be expired if it has already ended" do
249
- promotion.expires_at = Time.current - 1.day
250
- expect(promotion).to be_expired
251
- end
252
-
253
- it "should not be expired if it has started already" do
254
- promotion.starts_at = Time.current - 1.day
255
- expect(promotion).not_to be_expired
256
- end
257
-
258
- it "should not be expired if it has not ended yet" do
259
- promotion.expires_at = Time.current + 1.day
260
- expect(promotion).not_to be_expired
261
- end
262
-
263
- it "should not be expired if current time is within starts_at and expires_at range" do
264
- promotion.starts_at = Time.current - 1.day
265
- promotion.expires_at = Time.current + 1.day
266
- expect(promotion).not_to be_expired
267
- end
268
-
269
- it "should not be expired if usage limit is not exceeded" do
270
- promotion.usage_limit = 2
271
- allow(promotion).to receive_messages(credits_count: 1)
272
- expect(promotion).not_to be_expired
273
- end
274
- end
275
-
276
- context "#credits_count" do
277
- let!(:promotion) do
278
- promotion = Spree::Promotion.new
279
- promotion.name = "Foo"
280
- promotion.code = "XXX"
281
- calculator = Spree::Calculator::FlatRate.new
282
- promotion.tap(&:save)
283
- end
284
-
285
- let!(:action) do
286
- calculator = Spree::Calculator::FlatRate.new
287
- action_params = { promotion: promotion, calculator: calculator }
288
- action = Spree::Promotion::Actions::CreateAdjustment.create(action_params)
289
- promotion.actions << action
290
- action
291
- end
292
-
293
- let!(:adjustment) do
294
- order = create(:order)
295
- Spree::Adjustment.create!(
296
- order: order,
297
- adjustable: order,
298
- source: action,
299
- amount: 10,
300
- label: 'Promotional adjustment'
301
- )
302
- end
303
-
304
- it "counts eligible adjustments" do
305
- adjustment.update_column(:eligible, true)
306
- expect(promotion.credits_count).to eq(1)
307
- end
308
-
309
- # Regression test for #4112
310
- it "does not count ineligible adjustments" do
311
- adjustment.update_column(:eligible, false)
312
- expect(promotion.credits_count).to eq(0)
313
- end
314
- end
315
-
316
- context "#adjusted_credits_count" do
317
- let(:order) { create :order }
318
- let(:line_item) { create :line_item, order: order }
319
- let(:promotion) { Spree::Promotion.create name: "promo", code: "10off" }
320
- let(:order_action) {
321
- action = Spree::Promotion::Actions::CreateAdjustment.create(calculator: Spree::Calculator::FlatPercentItemTotal.new)
322
- promotion.actions << action
323
- action
324
- }
325
- let(:item_action) {
326
- action = Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: Spree::Calculator::FlatPercentItemTotal.new)
327
- promotion.actions << action
328
- action
329
- }
330
- let(:order_adjustment) do
331
- Spree::Adjustment.create!(
332
- source: order_action,
333
- amount: 10,
334
- adjustable: order,
335
- order: order,
336
- label: "Promotional adjustment"
337
- )
338
- end
339
- let(:item_adjustment) do
340
- Spree::Adjustment.create!(
341
- source: item_action,
342
- amount: 10,
343
- adjustable: line_item,
344
- order: order,
345
- label: "Promotional adjustment"
346
- )
347
- end
348
-
349
- it "counts order level adjustments" do
350
- expect(order_adjustment.adjustable).to eq(order)
351
- expect(promotion.credits_count).to eq(1)
352
- expect(promotion.adjusted_credits_count(order)).to eq(0)
353
- end
354
-
355
- it "counts item level adjustments" do
356
- expect(item_adjustment.adjustable).to eq(line_item)
357
- expect(promotion.credits_count).to eq(1)
358
- expect(promotion.adjusted_credits_count(order)).to eq(0)
359
- end
360
- end
361
-
362
- context "#products" do
363
- let(:product) { create(:product) }
364
- let(:promotion) { create(:promotion) }
365
-
366
- context "when it has product rules with products associated" do
367
- let(:promotion_rule) { create(:promotion_rule, promotion: promotion, type: 'Spree::Promotion::Rules::Product') }
368
-
369
- before do
370
- promotion.promotion_rules << promotion_rule
371
- product.product_promotion_rules.create(promotion_rule_id: promotion_rule.id)
372
- end
373
-
374
- it "should have products" do
375
- expect(promotion.reload.products.size).to eq(1)
376
- end
377
- end
378
-
379
- context "when there's no product rule associated" do
380
- it "should not have products but still return an empty array" do
381
- expect(promotion.products).to be_blank
382
- end
383
- end
384
- end
385
-
386
- context "#eligible?" do
387
- let(:promotable) { create :order }
388
- subject { promotion.eligible?(promotable) }
389
- context "when promotion is expired" do
390
- before { promotion.expires_at = Time.current - 10.days }
391
- it { is_expected.to be false }
392
- end
393
- context "when promotable is a Spree::LineItem" do
394
- let(:promotable) { create :line_item }
395
- let(:product) { promotable.product }
396
- before do
397
- product.promotionable = promotionable
398
- end
399
- context "and product is promotionable" do
400
- let(:promotionable) { true }
401
- it { is_expected.to be true }
402
- end
403
- context "and product is not promotionable" do
404
- let(:promotionable) { false }
405
- it { is_expected.to be false }
406
- end
407
- end
408
- context "when promotable is a Spree::Order" do
409
- let(:promotable) { create :order }
410
- context "and it is empty" do
411
- it { is_expected.to be true }
412
- end
413
- context "and it contains items" do
414
- let!(:line_item) { create(:line_item, order: promotable) }
415
- context "and the items are all non-promotionable" do
416
- before do
417
- line_item.product.update_column(:promotionable, false)
418
- end
419
- it { is_expected.to be false }
420
- end
421
- context "and at least one item is promotionable" do
422
- it { is_expected.to be true }
423
- end
424
- end
425
- end
426
- end
427
-
428
- context "#eligible_rules" do
429
- let(:promotable) { double('Promotable') }
430
- it "true if there are no rules" do
431
- expect(promotion.eligible_rules(promotable)).to eq []
432
- end
433
-
434
- it "true if there are no applicable rules" do
435
- promotion.promotion_rules = [stub_model(Spree::PromotionRule, eligible?: true, applicable?: false)]
436
- allow(promotion.promotion_rules).to receive(:for).and_return([])
437
- expect(promotion.eligible_rules(promotable)).to eq []
438
- end
439
-
440
- context "with 'all' match policy" do
441
- let(:promo1) { Spree::PromotionRule.create! }
442
- let(:promo2) { Spree::PromotionRule.create! }
443
-
444
- before { promotion.match_policy = 'all' }
445
-
446
- context "when all rules are eligible" do
447
- before do
448
- allow(promo1).to receive_messages(eligible?: true, applicable?: true)
449
- allow(promo2).to receive_messages(eligible?: true, applicable?: true)
450
-
451
- promotion.promotion_rules = [promo1, promo2]
452
- allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
453
- end
454
- it "returns the eligible rules" do
455
- expect(promotion.eligible_rules(promotable)).to eq [promo1, promo2]
456
- end
457
- it "does set anything to eligiblity errors" do
458
- promotion.eligible_rules(promotable)
459
- expect(promotion.eligibility_errors).to be_nil
460
- end
461
- end
462
-
463
- context "when any of the rules is not eligible" do
464
- let(:errors) { double ActiveModel::Errors, empty?: false }
465
- before do
466
- allow(promo1).to receive_messages(eligible?: true, applicable?: true, eligibility_errors: nil)
467
- allow(promo2).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
468
-
469
- promotion.promotion_rules = [promo1, promo2]
470
- allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
471
- end
472
- it "returns nil" do
473
- expect(promotion.eligible_rules(promotable)).to be_nil
474
- end
475
- it "sets eligibility errors to the first non-nil one" do
476
- promotion.eligible_rules(promotable)
477
- expect(promotion.eligibility_errors).to eq errors
478
- end
479
- end
480
- end
481
-
482
- context "with 'any' match policy" do
483
- let(:promotion) { Spree::Promotion.create(name: "Promo", match_policy: 'any') }
484
- let(:promotable) { double('Promotable') }
485
-
486
- it "should have eligible rules if any of the rules are eligible" do
487
- allow_any_instance_of(Spree::PromotionRule).to receive_messages(applicable?: true)
488
- true_rule = Spree::PromotionRule.create(promotion: promotion)
489
- allow(true_rule).to receive_messages(eligible?: true)
490
- allow(promotion).to receive_messages(rules: [true_rule])
491
- allow(promotion).to receive_message_chain(:rules, :for).and_return([true_rule])
492
- expect(promotion.eligible_rules(promotable)).to eq [true_rule]
493
- end
494
-
495
- context "when none of the rules are eligible" do
496
- let(:promo) { Spree::PromotionRule.create! }
497
- let(:errors) { double ActiveModel::Errors, empty?: false }
498
- before do
499
- allow(promo).to receive_messages(eligible?: false, applicable?: true, eligibility_errors: errors)
500
-
501
- promotion.promotion_rules = [promo]
502
- allow(promotion.promotion_rules).to receive(:for).and_return(promotion.promotion_rules)
503
- end
504
- it "returns nil" do
505
- expect(promotion.eligible_rules(promotable)).to be_nil
506
- end
507
- it "sets eligibility errors to the first non-nil one" do
508
- promotion.eligible_rules(promotable)
509
- expect(promotion.eligibility_errors).to eq errors
510
- end
511
- end
512
- end
513
- end
514
-
515
- describe '#line_item_actionable?' do
516
- let(:order) { double Spree::Order }
517
- let(:line_item) { double Spree::LineItem}
518
- let(:true_rule) { double Spree::PromotionRule, eligible?: true, applicable?: true, actionable?: true }
519
- let(:false_rule) { double Spree::PromotionRule, eligible?: true, applicable?: true, actionable?: false }
520
- let(:rules) { [] }
521
-
522
- before do
523
- allow(promotion).to receive(:rules) { rules }
524
- allow(rules).to receive(:for) { rules }
525
- end
526
-
527
- subject { promotion.line_item_actionable? order, line_item }
528
-
529
- context 'when the order is eligible for promotion' do
530
- context 'when there are no rules' do
531
- it { is_expected.to be }
532
- end
533
-
534
- context 'when there are rules' do
535
- context 'when the match policy is all' do
536
- before { promotion.match_policy = 'all' }
537
-
538
- context 'when all rules allow action on the line item' do
539
- let(:rules) { [true_rule] }
540
- it { is_expected.to be}
541
- end
542
-
543
- context 'when at least one rule does not allow action on the line item' do
544
- let(:rules) { [true_rule, false_rule] }
545
- it { is_expected.not_to be}
546
- end
547
- end
548
-
549
- context 'when the match policy is any' do
550
- before { promotion.match_policy = 'any' }
551
-
552
- context 'when at least one rule allows action on the line item' do
553
- let(:rules) { [true_rule, false_rule] }
554
- it { is_expected.to be }
555
- end
556
-
557
- context 'when no rules allow action on the line item' do
558
- let(:rules) { [false_rule] }
559
- it { is_expected.not_to be}
560
- end
561
- end
562
- end
563
- end
564
-
565
- context 'when the order is not eligible for the promotion' do
566
- before { promotion.starts_at = Time.current + 2.days }
567
- it { is_expected.not_to be }
568
- end
569
- end
570
-
571
- # regression for #4059
572
- # admin form posts the code and path as empty string
573
- describe "normalize blank values for code & path" do
574
- it "will save blank value as nil value instead" do
575
- promotion = Spree::Promotion.create(name: "A promotion", code: "", path: "")
576
- expect(promotion.code).to be_nil
577
- expect(promotion.path).to be_nil
578
- end
579
- end
580
-
581
- # Regression test for #4081
582
- describe "#with_coupon_code" do
583
- context "and code stored in uppercase" do
584
- let!(:promotion) { create(:promotion, :with_order_adjustment, code: "MY-COUPON-123") }
585
- it "finds the code with lowercase" do
586
- expect(Spree::Promotion.with_coupon_code("my-coupon-123")).to eql promotion
587
- end
588
- end
589
-
590
- context "when promotion has no actions" do
591
- let!(:promotion_without_actions) { create(:promotion, code: "MY-COUPON-123").actions.clear }
592
-
593
- it "then returns the one with an action" do
594
- expect(Spree::Promotion.with_coupon_code("MY-COUPON-123")).to be_nil
595
- end
596
- end
597
- end
598
-
599
- describe '#used_by?' do
600
- subject { promotion.used_by? user, [excluded_order] }
601
-
602
- let(:promotion) { create :promotion, :with_order_adjustment }
603
- let(:user) { create :user }
604
- let(:order) { create :order_with_line_items, user: user }
605
- let(:excluded_order) { create :order_with_line_items, user: user }
606
-
607
- before do
608
- order.user_id = user.id
609
- order.save!
610
- end
611
-
612
- context 'when the user has used this promo' do
613
- before do
614
- promotion.activate(order: order)
615
- order.update_with_updater!
616
- order.completed_at = Time.current
617
- order.save!
618
- end
619
-
620
- context 'when the order is complete' do
621
- it { is_expected.to be true }
622
-
623
- context 'when the promotion was not eligible' do
624
- let(:adjustment) { order.adjustments.first }
625
-
626
- before do
627
- adjustment.eligible = false
628
- adjustment.save!
629
- end
630
-
631
- it { is_expected.to be false }
632
- end
633
-
634
- context 'when the only matching order is the excluded order' do
635
- let(:excluded_order) { order }
636
- it { is_expected.to be false }
637
- end
638
- end
639
-
640
- context 'when the order is not complete' do
641
- let(:order) { create :order, user: user }
642
- it { is_expected.to be false }
643
- end
644
- end
645
-
646
- context 'when the user has not used this promo' do
647
- it { is_expected.to be false }
648
- end
649
- end
650
-
651
- describe "adding items to the cart" do
652
- let(:order) { create :order }
653
- let(:line_item) { create :line_item, order: order }
654
- let(:promo) { create :promotion_with_item_adjustment, adjustment_rate: 5, code: 'promo' }
655
- let(:variant) { create :variant }
656
-
657
- it "updates the promotions for new line items" do
658
- expect(line_item.adjustments).to be_empty
659
- expect(order.adjustment_total).to eq 0
660
-
661
- promo.activate order: order
662
- order.update_with_updater!
663
-
664
- expect(line_item.adjustments.size).to eq(1)
665
- expect(order.adjustment_total).to eq -5
666
-
667
- other_line_item = order.contents.add(variant, 1, currency: order.currency)
668
-
669
- expect(other_line_item).not_to eq line_item
670
- expect(other_line_item.adjustments.size).to eq(1)
671
- expect(order.adjustment_total).to eq -10
672
- end
673
- end
674
- end