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,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::ItemTotal, :type => :model do
4
+ let(:rule) { Spree::Promotion::Rules::ItemTotal.new }
5
+ let(:order) { double(:order) }
6
+
7
+ before { rule.preferred_amount = 50 }
8
+
9
+ context "preferred operator set to gt" do
10
+ before { rule.preferred_operator = 'gt' }
11
+
12
+ it "should be eligible when item total is greater than preferred amount" do
13
+ allow(order).to receive_messages :item_total => 51
14
+ expect(rule).to be_eligible(order)
15
+ end
16
+
17
+ context "when item total is equal to preferred amount" do
18
+ before { allow(order).to receive_messages item_total: 50 }
19
+ it "is not eligible" do
20
+ expect(rule).not_to be_eligible(order)
21
+ end
22
+ it "set an error message" do
23
+ rule.eligible?(order)
24
+ expect(rule.eligibility_errors.full_messages.first).
25
+ to eq "This coupon code can't be applied to orders less than or equal to $50.00."
26
+ end
27
+ end
28
+
29
+ context "when item total is lower than preferred amount" do
30
+ before { allow(order).to receive_messages item_total: 49 }
31
+ it "is not eligible" do
32
+ expect(rule).not_to be_eligible(order)
33
+ end
34
+ it "set an error message" do
35
+ rule.eligible?(order)
36
+ expect(rule.eligibility_errors.full_messages.first).
37
+ to eq "This coupon code can't be applied to orders less than or equal to $50.00."
38
+ end
39
+ end
40
+ end
41
+
42
+ context "preferred operator set to gte" do
43
+ before { rule.preferred_operator = 'gte' }
44
+
45
+ it "should be eligible when item total is greater than preferred amount" do
46
+ allow(order).to receive_messages :item_total => 51
47
+ expect(rule).to be_eligible(order)
48
+ end
49
+
50
+ it "should be eligible when item total is equal to preferred amount" do
51
+ allow(order).to receive_messages :item_total => 50
52
+ expect(rule).to be_eligible(order)
53
+ end
54
+
55
+ context "when item total is lower than preferred amount" do
56
+ before { allow(order).to receive_messages item_total: 49 }
57
+ it "is not eligible" do
58
+ expect(rule).not_to be_eligible(order)
59
+ end
60
+ it "set an error message" do
61
+ rule.eligible?(order)
62
+ expect(rule.eligibility_errors.full_messages.first).
63
+ to eq "This coupon code can't be applied to orders less than $50.00."
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::NthOrder do
4
+ describe "#applicable?" do
5
+ subject { described_class.new.applicable?(promotable) }
6
+
7
+ context "when the promotable is an order" do
8
+ let(:promotable) { Spree::Order.new }
9
+
10
+ it { is_expected.to be true }
11
+ end
12
+
13
+ context "when the promotable is not a order" do
14
+ let(:promotable) { "not an order" }
15
+
16
+ it { is_expected.to be false }
17
+ end
18
+ end
19
+
20
+ describe "eligible?" do
21
+ let(:instance) { described_class.new }
22
+ subject { instance.eligible?(order) }
23
+
24
+ before do
25
+ instance.preferred_nth_order = 2
26
+ end
27
+
28
+ context "when the order does not have a user" do
29
+ let(:order) { Spree::Order.new }
30
+
31
+ it { is_expected.to be false }
32
+ end
33
+
34
+ context "when the order has a user" do
35
+ let(:order) { create :order }
36
+ let(:user) { order.user }
37
+
38
+ context "when the user has completed orders" do
39
+ before do
40
+ old_order = create :completed_order_with_totals, user: user
41
+ old_order.update_attributes(completed_at: 1.day.ago)
42
+ end
43
+
44
+ context "when this order will be the 'nth' order" do
45
+ it { is_expected.to be true }
46
+ end
47
+
48
+ context "when this order is completed and is still the 'nth' order" do
49
+ before do
50
+ order.update_attributes(completed_at: Time.now)
51
+ end
52
+
53
+ it { is_expected.to be true }
54
+ end
55
+
56
+ context "when this order will not be the 'nth' order" do
57
+ before do
58
+ instance.preferred_nth_order = 100
59
+ end
60
+
61
+ it { is_expected.to be false }
62
+ end
63
+ end
64
+
65
+ context "when the user has no completed orders " do
66
+ it { is_expected.to be false }
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::OneUsePerUser, :type => :model do
4
+ let(:rule) { described_class.new }
5
+
6
+ describe '#eligible?(order)' do
7
+ subject { rule.eligible?(order) }
8
+ let(:order) { double Spree::Order, user: user }
9
+ let(:user) { double Spree::LegacyUser }
10
+ let(:promotion) { stub_model Spree::Promotion, used_by?: used_by }
11
+ let(:used_by) { false }
12
+
13
+ before { rule.promotion = promotion }
14
+
15
+ context 'when the order is assigned to a user' do
16
+ context 'when the user has used this promotion before' do
17
+ let(:used_by) { true }
18
+
19
+ it { is_expected.to be false }
20
+ it "sets an error message" do
21
+ subject
22
+ expect(rule.eligibility_errors.full_messages.first).
23
+ to eq "This coupon code can only be used once per user."
24
+ end
25
+ end
26
+
27
+ context 'when the user has not used this promotion before' do
28
+ it { is_expected.to be true }
29
+ end
30
+ end
31
+
32
+ context 'when the order is not assigned to a user' do
33
+ let(:user) { nil }
34
+ it { is_expected.to be false }
35
+ it "sets an error message" do
36
+ subject
37
+ expect(rule.eligibility_errors.full_messages.first).
38
+ to eq "You need to login before applying this coupon code."
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::OptionValue do
4
+ let(:rule) { Spree::Promotion::Rules::OptionValue.new }
5
+
6
+ describe "#preferred_eligible_values" do
7
+ subject { rule.preferred_eligible_values }
8
+ it "assigns a nicely formatted hash" do
9
+ rule.preferred_eligible_values = Hash["5" => "1,2", "6" => "1"]
10
+ expect(subject).to eq Hash[5 => [1, 2], 6 => [1]]
11
+ end
12
+ end
13
+
14
+ describe "#applicable?" do
15
+ subject { rule.applicable?(promotable) }
16
+ context "when promotable is an order" do
17
+ let(:promotable) { Spree::Order.new }
18
+ it { is_expected.to be true }
19
+ end
20
+ context "when promotable is not an order" do
21
+ let(:promotable) { Spree::LineItem.new }
22
+ it { is_expected.to be false }
23
+ end
24
+ end
25
+
26
+ describe "#eligible?" do
27
+ let(:variant) { create :variant }
28
+ let(:line_item) { create :line_item, variant: variant }
29
+ let(:promotable) { line_item.order }
30
+ subject { rule.eligible?(promotable) }
31
+ context "when there are any applicable line items" do
32
+ before do
33
+ rule.preferred_eligible_values = Hash[line_item.product.id => [
34
+ line_item.variant.option_values.pluck(:id).first
35
+ ]]
36
+ end
37
+ it { is_expected.to be true }
38
+ end
39
+ context "when there are no applicable line items" do
40
+ before do
41
+ rule.preferred_eligible_values = Hash[99 => [99]]
42
+ end
43
+ it { is_expected.to be false }
44
+ end
45
+ end
46
+
47
+ describe "#actionable?" do
48
+ let(:line_item) { create :line_item }
49
+ let(:option_value_blue) do
50
+ create(
51
+ :option_value,
52
+ name: 'Blue',
53
+ presentation: 'Blue',
54
+ option_type: create(
55
+ :option_type,
56
+ name: 'foo-colour',
57
+ presentation: 'Colour'
58
+ )
59
+ )
60
+ end
61
+ let(:option_value_medium) do
62
+ create(
63
+ :option_value,
64
+ name: 'Medium',
65
+ presentation: 'M'
66
+ )
67
+ end
68
+ before do
69
+ line_item.variant.option_values << option_value_blue
70
+ rule.preferred_eligible_values = Hash[product_id => option_value_ids]
71
+ end
72
+ subject { rule.actionable?(line_item) }
73
+ context "when the line item has the correct product" do
74
+ let(:product_id) { line_item.product.id }
75
+ context "when all of the option values match" do
76
+ let(:option_value_ids) { [option_value_blue.id] }
77
+ it { is_expected.to be true }
78
+ end
79
+ context "when any of the option values match" do
80
+ let(:option_value_ids) { [option_value_blue.id, option_value_medium.id] }
81
+ it { is_expected.to be true }
82
+ end
83
+ context "when none of the option values match" do
84
+ let(:option_value_ids) { [option_value_medium.id] }
85
+ it { is_expected.to be false }
86
+ end
87
+ end
88
+ context "when the line item's product doesn't match" do
89
+ let(:product_id) { 99 }
90
+ let(:option_value_ids) { [99] }
91
+ it { is_expected.to be false }
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,143 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::Product, :type => :model do
4
+ let(:rule) { Spree::Promotion::Rules::Product.new(rule_options) }
5
+ let(:rule_options) { {} }
6
+
7
+ context "#eligible?(order)" do
8
+ let(:order) { Spree::Order.new }
9
+
10
+ it "should be eligible if there are no products" do
11
+ allow(rule).to receive_messages(:eligible_products => [])
12
+ expect(rule).to be_eligible(order)
13
+ end
14
+
15
+ before do
16
+ 3.times { |i| instance_variable_set("@product#{i}", mock_model(Spree::Product)) }
17
+ end
18
+
19
+ context "with 'any' match policy" do
20
+ let(:rule_options) { super().merge(preferred_match_policy: 'any') }
21
+
22
+ it "should be eligible if any of the products is in eligible products" do
23
+ allow(order).to receive_messages(:products => [@product1, @product2])
24
+ allow(rule).to receive_messages(:eligible_products => [@product2, @product3])
25
+ expect(rule).to be_eligible(order)
26
+ end
27
+
28
+ context "when none of the products are eligible products" do
29
+ before do
30
+ allow(order).to receive_messages(products: [@product1])
31
+ allow(rule).to receive_messages(eligible_products: [@product2, @product3])
32
+ end
33
+ it { expect(rule).not_to be_eligible(order) }
34
+ it "sets an error message" do
35
+ rule.eligible?(order)
36
+ expect(rule.eligibility_errors.full_messages.first).
37
+ to eq "You need to add an applicable product before applying this coupon code."
38
+ end
39
+ end
40
+ end
41
+
42
+ context "with 'all' match policy" do
43
+ let(:rule_options) { super().merge(preferred_match_policy: 'all') }
44
+
45
+ it "should be eligible if all of the eligible products are ordered" do
46
+ allow(order).to receive_messages(:products => [@product3, @product2, @product1])
47
+ allow(rule).to receive_messages(:eligible_products => [@product2, @product3])
48
+ expect(rule).to be_eligible(order)
49
+ end
50
+
51
+ context "when any of the eligible products is not ordered" do
52
+ before do
53
+ allow(order).to receive_messages(products: [@product1, @product2])
54
+ allow(rule).to receive_messages(eligible_products: [@product1, @product2, @product3])
55
+ end
56
+ it { expect(rule).not_to be_eligible(order) }
57
+ it "sets an error message" do
58
+ rule.eligible?(order)
59
+ expect(rule.eligibility_errors.full_messages.first).
60
+ to eq "This coupon code can't be applied because you don't have all of the necessary products in your cart."
61
+ end
62
+ end
63
+ end
64
+
65
+ context "with 'none' match policy" do
66
+ let(:rule_options) { super().merge(preferred_match_policy: 'none') }
67
+
68
+ it "should be eligible if none of the order's products are in eligible products" do
69
+ allow(order).to receive_messages(:products => [@product1])
70
+ allow(rule).to receive_messages(:eligible_products => [@product2, @product3])
71
+ expect(rule).to be_eligible(order)
72
+ end
73
+
74
+ context "when any of the order's products are in eligible products" do
75
+ before do
76
+ allow(order).to receive_messages(products: [@product1, @product2])
77
+ allow(rule).to receive_messages(eligible_products: [@product2, @product3])
78
+ end
79
+ it { expect(rule).not_to be_eligible(order) }
80
+ it "sets an error message" do
81
+ rule.eligible?(order)
82
+ expect(rule.eligibility_errors.full_messages.first).
83
+ to eq "Your cart contains a product that prevents this coupon code from being applied."
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '#actionable?' do
90
+ subject do
91
+ rule.actionable?(line_item)
92
+ end
93
+
94
+ let(:rule_line_item) { Spree::LineItem.new(product: rule_product) }
95
+ let(:other_line_item) { Spree::LineItem.new(product: other_product) }
96
+
97
+ let(:rule_options) { super().merge(products: [rule_product]) }
98
+ let(:rule_product) { mock_model(Spree::Product) }
99
+ let(:other_product) { mock_model(Spree::Product) }
100
+
101
+ context "with 'any' match policy" do
102
+ let(:rule_options) { super().merge(preferred_match_policy: 'any') }
103
+
104
+ context 'for product in rule' do
105
+ let(:line_item) { rule_line_item }
106
+ it { is_expected.to be_truthy }
107
+ end
108
+
109
+ context 'for product not in rule' do
110
+ let(:line_item) { other_line_item }
111
+ it { is_expected.to be_falsey }
112
+ end
113
+ end
114
+
115
+ context "with 'all' match policy" do
116
+ let(:rule_options) { super().merge(preferred_match_policy: 'all') }
117
+
118
+ context 'for product in rule' do
119
+ let(:line_item) { rule_line_item }
120
+ it { is_expected.to be_truthy }
121
+ end
122
+
123
+ context 'for product not in rule' do
124
+ let(:line_item) { other_line_item }
125
+ it { is_expected.to be_falsey }
126
+ end
127
+ end
128
+
129
+ context "with 'none' match policy" do
130
+ let(:rule_options) { super().merge(preferred_match_policy: 'none') }
131
+
132
+ context 'for product in rule' do
133
+ let(:line_item) { rule_line_item }
134
+ it { is_expected.to be_falsey }
135
+ end
136
+
137
+ context 'for product not in rule' do
138
+ let(:line_item) { other_line_item }
139
+ it { is_expected.to be_truthy }
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Promotion::Rules::Taxon, :type => :model do
4
+ let(:rule) { Spree::Promotion::Rules::Taxon.create!(promotion: create(:promotion)) }
5
+
6
+ context '#elegible?(order)' do
7
+ let(:taxon){ create :taxon, name: 'first' }
8
+ let(:taxon2){ create :taxon, name: 'second'}
9
+ let(:order){ create :order_with_line_items }
10
+
11
+ before do
12
+ rule.save
13
+ end
14
+
15
+ context 'with any match policy' do
16
+ before do
17
+ rule.preferred_match_policy = 'any'
18
+ end
19
+
20
+ it 'is eligible if order does have any prefered taxon' do
21
+ order.products.first.taxons << taxon
22
+ rule.taxons << taxon
23
+ expect(rule).to be_eligible(order)
24
+ end
25
+
26
+ context 'when order contains items from different taxons' do
27
+ before do
28
+ order.products.first.taxons << taxon
29
+ rule.taxons << taxon
30
+ end
31
+
32
+ it 'should act on a product within the eligible taxon' do
33
+ expect(rule).to be_actionable(order.line_items.last)
34
+ end
35
+
36
+ it 'should not act on a product in another taxon' do
37
+ order.line_items << create(:line_item, product: create(:product, taxons: [taxon2]))
38
+ expect(rule).not_to be_actionable(order.line_items.last)
39
+ end
40
+ end
41
+
42
+ context "when order does not have any prefered taxon" do
43
+ before { rule.taxons << taxon2 }
44
+ it { expect(rule).not_to be_eligible(order) }
45
+ it "sets an error message" do
46
+ rule.eligible?(order)
47
+ expect(rule.eligibility_errors.full_messages.first).
48
+ to eq "You need to add a product from an applicable category before applying this coupon code."
49
+ end
50
+ end
51
+
52
+ context 'when a product has a taxon child of a taxon rule' do
53
+ before do
54
+ taxon.children << taxon2
55
+ order.products.first.taxons << taxon2
56
+ rule.taxons << taxon2
57
+ end
58
+
59
+ it{ expect(rule).to be_eligible(order) }
60
+ end
61
+ end
62
+
63
+ context 'with all match policy' do
64
+ before do
65
+ rule.preferred_match_policy = 'all'
66
+ end
67
+
68
+ it 'is eligible order has all prefered taxons' do
69
+ order.products.first.taxons << taxon2
70
+ order.products.last.taxons << taxon
71
+
72
+ rule.taxons = [taxon, taxon2]
73
+
74
+ expect(rule).to be_eligible(order)
75
+ end
76
+
77
+ context "when order does not have all prefered taxons" do
78
+ before { rule.taxons << taxon }
79
+ it { expect(rule).not_to be_eligible(order) }
80
+ it "sets an error message" do
81
+ rule.eligible?(order)
82
+ expect(rule.eligibility_errors.full_messages.first).
83
+ to eq "You need to add a product from all applicable categories before applying this coupon code."
84
+ end
85
+ end
86
+
87
+ context 'when a product has a taxon child of a taxon rule' do
88
+ let(:taxon3){ create :taxon }
89
+
90
+ before do
91
+ taxon.children << taxon2
92
+ order.products.first.taxons << taxon2
93
+ order.products.last.taxons << taxon3
94
+ rule.taxons << taxon2
95
+ rule.taxons << taxon3
96
+ end
97
+
98
+ it{ expect(rule).to be_eligible(order) }
99
+ end
100
+ end
101
+ end
102
+ end