spree_core 3.0.5 → 3.0.6

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 (194) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +3 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/spree.js.coffee.erb +1 -1
  6. data/app/models/spree/ability.rb +1 -1
  7. data/app/models/spree/base.rb +3 -1
  8. data/app/models/spree/order_updater.rb +2 -1
  9. data/app/models/spree/price.rb +7 -12
  10. data/app/models/spree/product.rb +3 -2
  11. data/app/models/spree/reimbursement.rb +1 -1
  12. data/app/models/spree/state.rb +2 -0
  13. data/app/models/spree/zone.rb +1 -1
  14. data/lib/spree/core/version.rb +1 -1
  15. data/lib/spree/testing_support/shoulda_matcher_configuration.rb +6 -0
  16. data/script/rails +9 -0
  17. data/spec/fixtures/thinking-cat.jpg +0 -0
  18. data/spec/helpers/base_helper_spec.rb +137 -0
  19. data/spec/helpers/products_helper_spec.rb +224 -0
  20. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  21. data/spec/lib/i18n_spec.rb +123 -0
  22. data/spec/lib/search/base_spec.rb +86 -0
  23. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +101 -0
  24. data/spec/lib/spree/core/controller_helpers/order_spec.rb +95 -0
  25. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  26. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  27. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  28. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
  29. data/spec/lib/spree/core/importer/order_spec.rb +502 -0
  30. data/spec/lib/spree/core/validators/email_spec.rb +53 -0
  31. data/spec/lib/spree/localized_number_spec.rb +38 -0
  32. data/spec/lib/spree/migrations_spec.rb +34 -0
  33. data/spec/lib/spree/money_spec.rb +122 -0
  34. data/spec/lib/tasks/exchanges_spec.rb +136 -0
  35. data/spec/mailers/order_mailer_spec.rb +124 -0
  36. data/spec/mailers/reimbursement_mailer_spec.rb +47 -0
  37. data/spec/mailers/shipment_mailer_spec.rb +63 -0
  38. data/spec/mailers/test_mailer_spec.rb +24 -0
  39. data/spec/models/spree/ability_spec.rb +246 -0
  40. data/spec/models/spree/address_spec.rb +291 -0
  41. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +286 -0
  42. data/spec/models/spree/adjustment_spec.rb +163 -0
  43. data/spec/models/spree/app_configuration_spec.rb +23 -0
  44. data/spec/models/spree/asset_spec.rb +25 -0
  45. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  46. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  47. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  48. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  49. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  50. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  51. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
  52. data/spec/models/spree/calculator/shipping.rb +8 -0
  53. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  54. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  55. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  56. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  57. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +29 -0
  58. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +40 -0
  59. data/spec/models/spree/calculator/tiered_percent_spec.rb +51 -0
  60. data/spec/models/spree/calculator_spec.rb +69 -0
  61. data/spec/models/spree/classification_spec.rb +93 -0
  62. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  63. data/spec/models/spree/country_spec.rb +18 -0
  64. data/spec/models/spree/credit_card_spec.rb +324 -0
  65. data/spec/models/spree/customer_return_spec.rb +262 -0
  66. data/spec/models/spree/exchange_spec.rb +75 -0
  67. data/spec/models/spree/gateway/bogus_simple.rb +20 -0
  68. data/spec/models/spree/gateway/bogus_spec.rb +13 -0
  69. data/spec/models/spree/gateway_spec.rb +54 -0
  70. data/spec/models/spree/image_spec.rb +5 -0
  71. data/spec/models/spree/inventory_unit_spec.rb +242 -0
  72. data/spec/models/spree/line_item_spec.rb +267 -0
  73. data/spec/models/spree/option_type_spec.rb +14 -0
  74. data/spec/models/spree/option_value_spec.rb +13 -0
  75. data/spec/models/spree/order/address_spec.rb +50 -0
  76. data/spec/models/spree/order/adjustments_spec.rb +29 -0
  77. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  78. data/spec/models/spree/order/checkout_spec.rb +764 -0
  79. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  80. data/spec/models/spree/order/finalizing_spec.rb +117 -0
  81. data/spec/models/spree/order/helpers_spec.rb +5 -0
  82. data/spec/models/spree/order/payment_spec.rb +214 -0
  83. data/spec/models/spree/order/risk_assessment_spec.rb +84 -0
  84. data/spec/models/spree/order/shipments_spec.rb +43 -0
  85. data/spec/models/spree/order/state_machine_spec.rb +216 -0
  86. data/spec/models/spree/order/tax_spec.rb +84 -0
  87. data/spec/models/spree/order/totals_spec.rb +24 -0
  88. data/spec/models/spree/order/updating_spec.rb +18 -0
  89. data/spec/models/spree/order/validations_spec.rb +15 -0
  90. data/spec/models/spree/order_contents_spec.rb +256 -0
  91. data/spec/models/spree/order_inventory_spec.rb +228 -0
  92. data/spec/models/spree/order_merger_spec.rb +133 -0
  93. data/spec/models/spree/order_spec.rb +954 -0
  94. data/spec/models/spree/order_updater_spec.rb +283 -0
  95. data/spec/models/spree/payment/gateway_options_spec.rb +119 -0
  96. data/spec/models/spree/payment_method_spec.rb +95 -0
  97. data/spec/models/spree/payment_spec.rb +926 -0
  98. data/spec/models/spree/preference_spec.rb +80 -0
  99. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  100. data/spec/models/spree/preferences/preferable_spec.rb +348 -0
  101. data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
  102. data/spec/models/spree/preferences/store_spec.rb +46 -0
  103. data/spec/models/spree/price_spec.rb +42 -0
  104. data/spec/models/spree/product/scopes_spec.rb +148 -0
  105. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  106. data/spec/models/spree/product_filter_spec.rb +26 -0
  107. data/spec/models/spree/product_option_type_spec.rb +5 -0
  108. data/spec/models/spree/product_property_spec.rb +11 -0
  109. data/spec/models/spree/product_spec.rb +474 -0
  110. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +50 -0
  111. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +148 -0
  112. data/spec/models/spree/promotion/actions/create_line_items_spec.rb +86 -0
  113. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +36 -0
  114. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  115. data/spec/models/spree/promotion/rules/item_total_spec.rb +282 -0
  116. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  117. data/spec/models/spree/promotion/rules/option_value_spec.rb +90 -0
  118. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  119. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  120. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  121. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  122. data/spec/models/spree/promotion_action_spec.rb +10 -0
  123. data/spec/models/spree/promotion_category_spec.rb +17 -0
  124. data/spec/models/spree/promotion_handler/cart_spec.rb +102 -0
  125. data/spec/models/spree/promotion_handler/coupon_spec.rb +323 -0
  126. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +48 -0
  127. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  128. data/spec/models/spree/promotion_rule_spec.rb +29 -0
  129. data/spec/models/spree/promotion_spec.rb +603 -0
  130. data/spec/models/spree/property_spec.rb +5 -0
  131. data/spec/models/spree/prototype_spec.rb +5 -0
  132. data/spec/models/spree/refund_spec.rb +195 -0
  133. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  134. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  135. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  136. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  137. data/spec/models/spree/reimbursement_spec.rb +215 -0
  138. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  139. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  140. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  141. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +55 -0
  142. data/spec/models/spree/return_authorization_spec.rb +250 -0
  143. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  144. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  145. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +61 -0
  146. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  147. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  148. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  149. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  150. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  151. data/spec/models/spree/return_item_spec.rb +682 -0
  152. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  153. data/spec/models/spree/shipment_spec.rb +740 -0
  154. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  155. data/spec/models/spree/shipping_category_spec.rb +5 -0
  156. data/spec/models/spree/shipping_method_spec.rb +88 -0
  157. data/spec/models/spree/shipping_rate_spec.rb +141 -0
  158. data/spec/models/spree/state_spec.rb +18 -0
  159. data/spec/models/spree/stock/availability_validator_spec.rb +36 -0
  160. data/spec/models/spree/stock/content_item_spec.rb +22 -0
  161. data/spec/models/spree/stock/coordinator_spec.rb +51 -0
  162. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  163. data/spec/models/spree/stock/estimator_spec.rb +154 -0
  164. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  165. data/spec/models/spree/stock/package_spec.rb +194 -0
  166. data/spec/models/spree/stock/packer_spec.rb +70 -0
  167. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  168. data/spec/models/spree/stock/quantifier_spec.rb +97 -0
  169. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  170. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  171. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +47 -0
  172. data/spec/models/spree/stock/splitter/weight_spec.rb +32 -0
  173. data/spec/models/spree/stock_item_spec.rb +410 -0
  174. data/spec/models/spree/stock_location_spec.rb +243 -0
  175. data/spec/models/spree/stock_movement_spec.rb +56 -0
  176. data/spec/models/spree/stock_transfer_spec.rb +50 -0
  177. data/spec/models/spree/store_spec.rb +50 -0
  178. data/spec/models/spree/tax_category_spec.rb +27 -0
  179. data/spec/models/spree/tax_rate_spec.rb +382 -0
  180. data/spec/models/spree/taxon_spec.rb +74 -0
  181. data/spec/models/spree/taxonomy_spec.rb +18 -0
  182. data/spec/models/spree/tracker_spec.rb +21 -0
  183. data/spec/models/spree/user_spec.rb +130 -0
  184. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +24 -0
  185. data/spec/models/spree/variant_spec.rb +523 -0
  186. data/spec/models/spree/zone_spec.rb +444 -0
  187. data/spec/spec_helper.rb +74 -0
  188. data/spec/support/big_decimal.rb +5 -0
  189. data/spec/support/concerns/adjustment_source_spec.rb +23 -0
  190. data/spec/support/concerns/default_price_spec.rb +28 -0
  191. data/spec/support/rake.rb +13 -0
  192. data/spec/support/test_gateway.rb +2 -0
  193. data/spree_core.gemspec +48 -0
  194. metadata +185 -4
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Calculator::Shipping
5
+ describe PerItem, :type => :model do
6
+ let(:variant1) { build(:variant) }
7
+ let(:variant2) { build(:variant) }
8
+
9
+ let(:package) do
10
+ build(:stock_package, variants_contents: { variant1 => 5, variant2 => 3 })
11
+ end
12
+
13
+ subject { PerItem.new(:preferred_amount => 10) }
14
+
15
+ it "correctly calculates per item shipping" do
16
+ expect(subject.compute(package).to_f).to eq(80) # 5 x 10 + 3 x 10
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ module Calculator::Shipping
5
+ describe PriceSack do
6
+ let(:variant) { build(:variant, price: 2) }
7
+ subject(:calculator) do
8
+ calculator = PriceSack.new
9
+ calculator.preferred_minimal_amount = 5
10
+ calculator.preferred_normal_amount = 10
11
+ calculator.preferred_discount_amount = 1
12
+ calculator
13
+ end
14
+
15
+ let(:normal_package) do
16
+ build(:stock_package, variants_contents: { variant => 2 })
17
+ end
18
+
19
+ let(:discount_package) do
20
+ build(:stock_package, variants_contents: { variant => 4 })
21
+ end
22
+
23
+ it 'computes the correct amount' do
24
+ expect(calculator.compute(normal_package)).to eq(calculator.preferred_normal_amount)
25
+ expect(calculator.compute(discount_package)).to eq(calculator.preferred_discount_amount)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Calculator::TieredFlatRate, :type => :model do
4
+ let(:calculator) { Spree::Calculator::TieredFlatRate.new }
5
+
6
+ describe "#valid?" do
7
+ subject { calculator.valid? }
8
+ context "when tiers is not a hash" do
9
+ before { calculator.preferred_tiers = ["nope", 0] }
10
+ it { is_expected.to be false }
11
+ end
12
+ context "when tiers is a hash" do
13
+ context "and one of the keys is not a positive number" do
14
+ before { calculator.preferred_tiers = { "nope" => 20 } }
15
+ it { is_expected.to be false }
16
+ end
17
+ end
18
+ end
19
+
20
+ describe "#compute" do
21
+ let(:line_item) { mock_model Spree::LineItem, amount: amount }
22
+ before do
23
+ calculator.preferred_base_amount = 10
24
+ calculator.preferred_tiers = {
25
+ 100 => 15,
26
+ 200 => 20
27
+ }
28
+ end
29
+ subject { calculator.compute(line_item) }
30
+ context "when amount falls within the first tier" do
31
+ let(:amount) { 50 }
32
+ it { is_expected.to eq 10 }
33
+ end
34
+ context "when amount falls within the second tier" do
35
+ let(:amount) { 150 }
36
+ it { is_expected.to eq 15 }
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Calculator::TieredPercent, :type => :model do
4
+ let(:calculator) { Spree::Calculator::TieredPercent.new }
5
+
6
+ describe "#valid?" do
7
+ subject { calculator.valid? }
8
+ context "when base percent is less than zero" do
9
+ before { calculator.preferred_base_percent = -1 }
10
+ it { is_expected.to be false }
11
+ end
12
+ context "when base percent is greater than 100" do
13
+ before { calculator.preferred_base_percent = 110 }
14
+ it { is_expected.to be false }
15
+ end
16
+ context "when tiers is not a hash" do
17
+ before { calculator.preferred_tiers = ["nope", 0] }
18
+ it { is_expected.to be false }
19
+ end
20
+ context "when tiers is a hash" do
21
+ context "and one of the keys is not a positive number" do
22
+ before { calculator.preferred_tiers = { "nope" => 20 } }
23
+ it { is_expected.to be false }
24
+ end
25
+ context "and one of the values is not a percent" do
26
+ before { calculator.preferred_tiers = { 10 => 110 } }
27
+ it { is_expected.to be false }
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#compute" do
33
+ let(:line_item) { mock_model Spree::LineItem, amount: amount }
34
+ before do
35
+ calculator.preferred_base_percent = 10
36
+ calculator.preferred_tiers = {
37
+ 100 => 15,
38
+ 200 => 20
39
+ }
40
+ end
41
+ subject { calculator.compute(line_item) }
42
+ context "when amount falls within the first tier" do
43
+ let(:amount) { 50 }
44
+ it { is_expected.to eq 5 }
45
+ end
46
+ context "when amount falls within the second tier" do
47
+ let(:amount) { 150 }
48
+ it { is_expected.to eq 22 }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Calculator, :type => :model do
4
+
5
+ let(:order) { create(:order) }
6
+ let!(:line_item) { create(:line_item, :order => order) }
7
+ let(:shipment) { create(:shipment, :order => order, :stock_location => create(:stock_location_with_items)) }
8
+
9
+ context "with computable" do
10
+ context "and compute methods stubbed out" do
11
+ context "with a Spree::LineItem" do
12
+ it "calls compute_line_item" do
13
+ expect(subject).to receive(:compute_line_item).with(line_item)
14
+ subject.compute(line_item)
15
+ end
16
+ end
17
+
18
+ context "with a Spree::Order" do
19
+ it "calls compute_order" do
20
+ expect(subject).to receive(:compute_order).with(order)
21
+ subject.compute(order)
22
+ end
23
+ end
24
+
25
+ context "with a Spree::Shipment" do
26
+ it "calls compute_shipment" do
27
+ expect(subject).to receive(:compute_shipment).with(shipment)
28
+ subject.compute(shipment)
29
+ end
30
+ end
31
+
32
+ context "with a arbitray object" do
33
+ it "calls the correct compute" do
34
+ s = "Calculator can all"
35
+ expect(subject).to receive(:compute_string).with(s)
36
+ subject.compute(s)
37
+ end
38
+ end
39
+ end
40
+
41
+ context "with no stubbing" do
42
+ context "with a Spree::LineItem" do
43
+ it "raises NotImplementedError" do
44
+ expect{subject.compute(line_item)}.to raise_error NotImplementedError, /Please implement \'compute_line_item\(line_item\)\' in your calculator/
45
+ end
46
+ end
47
+
48
+ context "with a Spree::Order" do
49
+ it "raises NotImplementedError" do
50
+ expect{subject.compute(order)}.to raise_error NotImplementedError, /Please implement \'compute_order\(order\)\' in your calculator/
51
+ end
52
+ end
53
+
54
+ context "with a Spree::Shipment" do
55
+ it "raises NotImplementedError" do
56
+ expect{subject.compute(shipment)}.to raise_error NotImplementedError, /Please implement \'compute_shipment\(shipment\)\' in your calculator/
57
+ end
58
+ end
59
+
60
+ context "with a arbitray object" do
61
+ it "raises NotImplementedError" do
62
+ s = "Calculator can all"
63
+ expect{subject.compute(s)}.to raise_error NotImplementedError, /Please implement \'compute_string\(string\)\' in your calculator/
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Classification, :type => :model do
5
+ # Regression test for #3494
6
+ it "cannot link the same taxon to the same product more than once" do
7
+ product = create(:product)
8
+ taxon = create(:taxon)
9
+ add_taxon = lambda { product.taxons << taxon }
10
+ expect(add_taxon).not_to raise_error
11
+ expect(add_taxon).to raise_error(ActiveRecord::RecordInvalid)
12
+ end
13
+
14
+ let(:taxon_with_5_products) do
15
+ products = []
16
+ 5.times do
17
+ products << create(:base_product)
18
+ end
19
+
20
+ create(:taxon, products: products)
21
+ end
22
+
23
+ def positions_to_be_valid(taxon)
24
+ positions = taxon.reload.classifications.map(&:position)
25
+ expect(positions).to eq((1..taxon.classifications.count).to_a)
26
+ end
27
+
28
+ it "has a valid fixtures" do
29
+ expect positions_to_be_valid(taxon_with_5_products)
30
+ expect(Spree::Classification.count).to eq 5
31
+ end
32
+
33
+ context "removing product from taxon" do
34
+ before :each do
35
+ p = taxon_with_5_products.products[1]
36
+ expect(p.classifications.first.position).to eq(2)
37
+ taxon_with_5_products.products.destroy(p)
38
+ end
39
+
40
+ it "resets positions" do
41
+ expect positions_to_be_valid(taxon_with_5_products)
42
+ end
43
+ end
44
+
45
+ context "replacing taxon's products" do
46
+ before :each do
47
+ products = taxon_with_5_products.products.to_a
48
+ products.pop(1)
49
+ taxon_with_5_products.products = products
50
+ taxon_with_5_products.save!
51
+ end
52
+
53
+ it "resets positions" do
54
+ expect positions_to_be_valid(taxon_with_5_products)
55
+ end
56
+ end
57
+
58
+ context "removing taxon from product" do
59
+ before :each do
60
+ p = taxon_with_5_products.products[1]
61
+ p.taxons.destroy(taxon_with_5_products)
62
+ p.save!
63
+ end
64
+
65
+ it "resets positions" do
66
+ expect positions_to_be_valid(taxon_with_5_products)
67
+ end
68
+ end
69
+
70
+ context "replacing product's taxons" do
71
+ before :each do
72
+ p = taxon_with_5_products.products[1]
73
+ p.taxons = []
74
+ p.save!
75
+ end
76
+
77
+ it "resets positions" do
78
+ expect positions_to_be_valid(taxon_with_5_products)
79
+ end
80
+ end
81
+
82
+ context "destroying classification" do
83
+ before :each do
84
+ classification = taxon_with_5_products.classifications[1]
85
+ classification.destroy
86
+ end
87
+
88
+ it "resets positions" do
89
+ expect positions_to_be_valid(taxon_with_5_products)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+
5
+ describe DisplayMoney do
6
+ let(:test_class) do
7
+ Class.new do
8
+ extend DisplayMoney
9
+ def total; 10.0; end
10
+ end
11
+ end
12
+
13
+ describe ".money_methods" do
14
+ before { test_class.money_methods :total }
15
+
16
+ context "currency is not defined" do
17
+ it "generates a display_method that builds a Spree::Money without options" do
18
+ expect(test_class.new.display_total).to eq Spree::Money.new(10.0)
19
+ end
20
+ end
21
+
22
+ context "currency is defined" do
23
+ before { test_class.class_eval { def currency; "USD"; end } }
24
+
25
+ it "generates a display_* method that builds a Spree::Money with currency" do
26
+ expect(test_class.new.display_total).to eq Spree::Money.new(10.0, currency: "USD")
27
+ end
28
+ end
29
+
30
+ context "with multiple + options" do
31
+ before do
32
+ test_class.class_eval { def amount; 20.0; end }
33
+ test_class.money_methods :total, amount: { no_cents: true }
34
+ end
35
+
36
+ it "generates a display_* method that builds a Spree::Money with the specified options" do
37
+ expect(test_class.new.display_total).to eq Spree::Money.new(10.0)
38
+ expect(test_class.new.display_amount).to eq Spree::Money.new(20.0, no_cents: true)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Country, type: :model do
4
+ describe '.default' do
5
+ let(:america) { create :country }
6
+ let(:canada) { create :country, name: 'Canada' }
7
+
8
+ it 'will return the country from the config' do
9
+ Spree::Config[:default_country_id] = canada.id
10
+ expect(described_class.default.id).to eql canada.id
11
+ end
12
+
13
+ it 'will return the US if config is not set' do
14
+ america.touch
15
+ expect(described_class.default.id).to eql america.id
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,324 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::CreditCard, type: :model do
4
+ let(:valid_credit_card_attributes) do
5
+ {
6
+ number: '4111111111111111',
7
+ verification_value: '123',
8
+ expiry: "12 / #{(Time.now.year + 1).to_s.last(2)}",
9
+ name: 'Spree Commerce'
10
+ }
11
+ end
12
+
13
+ def self.payment_states
14
+ Spree::Payment.state_machine.states.keys
15
+ end
16
+
17
+ let(:credit_card) { Spree::CreditCard.new }
18
+
19
+ before(:each) do
20
+
21
+ @order = create(:order)
22
+ @payment = Spree::Payment.create(:amount => 100, :order => @order)
23
+
24
+ @success_response = double('gateway_response', success?: true, authorization: '123', avs_result: { 'code' => 'avs-code' })
25
+ @fail_response = double('gateway_response', success?: false)
26
+
27
+ @payment_gateway = mock_model(Spree::PaymentMethod,
28
+ payment_profiles_supported?: true,
29
+ authorize: @success_response,
30
+ purchase: @success_response,
31
+ capture: @success_response,
32
+ void: @success_response,
33
+ credit: @success_response,
34
+ )
35
+
36
+ allow(@payment).to receive_messages payment_method: @payment_gateway
37
+ end
38
+
39
+ it 'should respond to track_data' do
40
+ expect(credit_card.respond_to?(:track_data)).to be true
41
+ end
42
+
43
+ context "#can_capture?" do
44
+ it "should be true if payment is pending" do
45
+ payment = mock_model(Spree::Payment, pending?: true, created_at: Time.now)
46
+ expect(credit_card.can_capture?(payment)).to be true
47
+ end
48
+
49
+ it "should be true if payment is checkout" do
50
+ payment = mock_model(Spree::Payment, pending?: false, checkout?: true, created_at: Time.now)
51
+ expect(credit_card.can_capture?(payment)).to be true
52
+ end
53
+ end
54
+
55
+ context "#can_void?" do
56
+ it "should be true if payment is not void" do
57
+ payment = mock_model(Spree::Payment, failed?: false, void?: false)
58
+ expect(credit_card.can_void?(payment)).to be true
59
+ end
60
+ end
61
+
62
+ context "#can_credit?" do
63
+ it "should be false if payment is not completed" do
64
+ payment = mock_model(Spree::Payment, completed?: false)
65
+ expect(credit_card.can_credit?(payment)).to be false
66
+ end
67
+
68
+ it "should be false when credit_allowed is zero" do
69
+ payment = mock_model(Spree::Payment, completed?: true, credit_allowed: 0, order: mock_model(Spree::Order, payment_state: 'credit_owed'))
70
+ expect(credit_card.can_credit?(payment)).to be false
71
+ end
72
+ end
73
+
74
+ context "#valid?" do
75
+ it "should validate presence of number" do
76
+ credit_card.attributes = valid_credit_card_attributes.except(:number)
77
+ expect(credit_card).not_to be_valid
78
+ expect(credit_card.errors[:number]).to eq(["can't be blank"])
79
+ end
80
+
81
+ it "should validate presence of security code" do
82
+ credit_card.attributes = valid_credit_card_attributes.except(:verification_value)
83
+ expect(credit_card).not_to be_valid
84
+ expect(credit_card.errors[:verification_value]).to eq(["can't be blank"])
85
+ end
86
+
87
+ it "validates name presence" do
88
+ credit_card.valid?
89
+ expect(credit_card.error_on(:name).size).to eq(1)
90
+ end
91
+
92
+ it "should only validate on create" do
93
+ credit_card.attributes = valid_credit_card_attributes
94
+ credit_card.save
95
+ expect(credit_card).to be_valid
96
+ end
97
+
98
+ context "encrypted data is present" do
99
+ it "does not validate presence of number or cvv" do
100
+ credit_card.encrypted_data = "$fdgsfgdgfgfdg&gfdgfdgsf-"
101
+ credit_card.valid?
102
+ expect(credit_card.errors[:number]).to be_empty
103
+ expect(credit_card.errors[:verification_value]).to be_empty
104
+ end
105
+ end
106
+
107
+ context "imported is true" do
108
+ it "does not validate presence of number or cvv" do
109
+ credit_card.imported = true
110
+ credit_card.valid?
111
+ expect(credit_card.errors[:number]).to be_empty
112
+ expect(credit_card.errors[:verification_value]).to be_empty
113
+ end
114
+ end
115
+ end
116
+
117
+ context "#save" do
118
+ before do
119
+ credit_card.attributes = valid_credit_card_attributes
120
+ credit_card.save!
121
+ end
122
+
123
+ let!(:persisted_card) { Spree::CreditCard.find(credit_card.id) }
124
+
125
+ it "should not actually store the number" do
126
+ expect(persisted_card.number).to be_blank
127
+ end
128
+
129
+ it "should not actually store the security code" do
130
+ expect(persisted_card.verification_value).to be_blank
131
+ end
132
+ end
133
+
134
+ context "#number=" do
135
+ it "should strip non-numeric characters from card input" do
136
+ credit_card.number = "6011000990139424"
137
+ expect(credit_card.number).to eq("6011000990139424")
138
+
139
+ credit_card.number = " 6011-0009-9013-9424 "
140
+ expect(credit_card.number).to eq("6011000990139424")
141
+ end
142
+
143
+ it "should not raise an exception on non-string input" do
144
+ credit_card.number = Hash.new
145
+ expect(credit_card.number).to be_nil
146
+ end
147
+ end
148
+
149
+ # Regression test for #3847 & #3896
150
+ context "#expiry=" do
151
+ it "can set with a 2-digit month and year" do
152
+ credit_card.expiry = '04 / 14'
153
+ expect(credit_card.month).to eq(4)
154
+ expect(credit_card.year).to eq(2014)
155
+ end
156
+
157
+ it "can set with a 2-digit month and 4-digit year" do
158
+ credit_card.expiry = '04 / 2014'
159
+ expect(credit_card.month).to eq(4)
160
+ expect(credit_card.year).to eq(2014)
161
+ end
162
+
163
+ it "can set with a 2-digit month and 4-digit year without whitespace" do
164
+ credit_card.expiry = '04/14'
165
+ expect(credit_card.month).to eq(4)
166
+ expect(credit_card.year).to eq(2014)
167
+ end
168
+
169
+ it "can set with a 2-digit month and 4-digit year without whitespace" do
170
+ credit_card.expiry = '04/2014'
171
+ expect(credit_card.month).to eq(4)
172
+ expect(credit_card.year).to eq(2014)
173
+ end
174
+
175
+ it "can set with a 2-digit month and 4-digit year without whitespace and slash" do
176
+ credit_card.expiry = '042014'
177
+ expect(credit_card.month).to eq(4)
178
+ expect(credit_card.year).to eq(2014)
179
+ end
180
+
181
+ it "can set with a 2-digit month and 2-digit year without whitespace and slash" do
182
+ credit_card.expiry = '0414'
183
+ expect(credit_card.month).to eq(4)
184
+ expect(credit_card.year).to eq(2014)
185
+ end
186
+
187
+ it "does not blow up when passed an empty string" do
188
+ expect { credit_card.expiry = '' }.not_to raise_error
189
+ end
190
+
191
+ # Regression test for #4725
192
+ it "does not blow up when passed one number" do
193
+ expect { credit_card.expiry = '12' }.not_to raise_error
194
+ end
195
+
196
+ end
197
+
198
+ context "#cc_type=" do
199
+ it "converts between the different types" do
200
+ credit_card.cc_type = 'mastercard'
201
+ expect(credit_card.cc_type).to eq('master')
202
+
203
+ credit_card.cc_type = 'maestro'
204
+ expect(credit_card.cc_type).to eq('master')
205
+
206
+ credit_card.cc_type = 'amex'
207
+ expect(credit_card.cc_type).to eq('american_express')
208
+
209
+ credit_card.cc_type = 'dinersclub'
210
+ expect(credit_card.cc_type).to eq('diners_club')
211
+
212
+ credit_card.cc_type = 'some_outlandish_cc_type'
213
+ expect(credit_card.cc_type).to eq('some_outlandish_cc_type')
214
+ end
215
+
216
+ it "assigns the type based on card number in the event of js failure" do
217
+ credit_card.number = '4242424242424242'
218
+ credit_card.cc_type = ''
219
+ expect(credit_card.cc_type).to eq('visa')
220
+
221
+ credit_card.number = '5555555555554444'
222
+ credit_card.cc_type = ''
223
+ expect(credit_card.cc_type).to eq('master')
224
+
225
+ credit_card.number = '378282246310005'
226
+ credit_card.cc_type = ''
227
+ expect(credit_card.cc_type).to eq('american_express')
228
+
229
+ credit_card.number = '30569309025904'
230
+ credit_card.cc_type = ''
231
+ expect(credit_card.cc_type).to eq('diners_club')
232
+
233
+ credit_card.number = '3530111333300000'
234
+ credit_card.cc_type = ''
235
+ expect(credit_card.cc_type).to eq('jcb')
236
+
237
+ credit_card.number = ''
238
+ credit_card.cc_type = ''
239
+ expect(credit_card.cc_type).to eq('')
240
+
241
+ credit_card.number = nil
242
+ credit_card.cc_type = ''
243
+ expect(credit_card.cc_type).to eq('')
244
+ end
245
+ end
246
+
247
+ context "#associations" do
248
+ it "should be able to access its payments" do
249
+ expect { credit_card.payments.to_a }.not_to raise_error
250
+ end
251
+ end
252
+
253
+ context "#first_name" do
254
+ before do
255
+ credit_card.name = "Ludwig van Beethoven"
256
+ end
257
+
258
+ it "extracts the first name" do
259
+ expect(credit_card.first_name).to eq "Ludwig"
260
+ end
261
+ end
262
+
263
+ context "#last_name" do
264
+ before do
265
+ credit_card.name = "Ludwig van Beethoven"
266
+ end
267
+
268
+ it "extracts the last name" do
269
+ expect(credit_card.last_name).to eq "van Beethoven"
270
+ end
271
+ end
272
+
273
+ context "#to_active_merchant" do
274
+ before do
275
+ credit_card.number = "4111111111111111"
276
+ credit_card.year = Time.now.year
277
+ credit_card.month = Time.now.month
278
+ credit_card.name = "Ludwig van Beethoven"
279
+ credit_card.verification_value = 123
280
+ end
281
+
282
+ it "converts to an ActiveMerchant::Billing::CreditCard object" do
283
+ am_card = credit_card.to_active_merchant
284
+ expect(am_card.number).to eq("4111111111111111")
285
+ expect(am_card.year).to eq(Time.now.year)
286
+ expect(am_card.month).to eq(Time.now.month)
287
+ expect(am_card.first_name).to eq("Ludwig")
288
+ expect(am_card.last_name).to eq("van Beethoven")
289
+ expect(am_card.verification_value).to eq(123)
290
+ end
291
+ end
292
+
293
+ it 'ensures only one credit card per user is default at a time' do
294
+ user = FactoryGirl.create(:user)
295
+ first = FactoryGirl.create(:credit_card, user: user, default: true)
296
+ second = FactoryGirl.create(:credit_card, user: user, default: true)
297
+
298
+ expect(first.reload.default).to eq false
299
+ expect(second.reload.default).to eq true
300
+
301
+ first.default = true
302
+ first.save!
303
+
304
+ expect(first.reload.default).to eq true
305
+ expect(second.reload.default).to eq false
306
+ end
307
+
308
+ it 'allows default credit cards for different users' do
309
+ first = FactoryGirl.create(:credit_card, user: FactoryGirl.create(:user), default: true)
310
+ second = FactoryGirl.create(:credit_card, user: FactoryGirl.create(:user), default: true)
311
+
312
+ expect(first.reload.default).to eq true
313
+ expect(second.reload.default).to eq true
314
+ end
315
+
316
+ it 'allows this card to save even if the previously default card has expired' do
317
+ user = FactoryGirl.create(:user)
318
+ first = FactoryGirl.create(:credit_card, user: user, default: true)
319
+ second = FactoryGirl.create(:credit_card, user: user, default: false)
320
+ first.update_columns(year: DateTime.now.year, month: 1.month.ago.month)
321
+
322
+ expect { second.update_attributes!(default: true) }.not_to raise_error
323
+ end
324
+ end