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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -0
- data/Rakefile +30 -0
- data/app/assets/javascripts/spree.js.coffee.erb +1 -1
- data/app/models/spree/ability.rb +1 -1
- data/app/models/spree/base.rb +3 -1
- data/app/models/spree/order_updater.rb +2 -1
- data/app/models/spree/price.rb +7 -12
- data/app/models/spree/product.rb +3 -2
- data/app/models/spree/reimbursement.rb +1 -1
- data/app/models/spree/state.rb +2 -0
- data/app/models/spree/zone.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/testing_support/shoulda_matcher_configuration.rb +6 -0
- data/script/rails +9 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/helpers/base_helper_spec.rb +137 -0
- data/spec/helpers/products_helper_spec.rb +224 -0
- data/spec/lib/calculated_adjustments_spec.rb +7 -0
- data/spec/lib/i18n_spec.rb +123 -0
- data/spec/lib/search/base_spec.rb +86 -0
- data/spec/lib/spree/core/controller_helpers/auth_spec.rb +101 -0
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +95 -0
- data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
- data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
- data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
- data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
- data/spec/lib/spree/core/importer/order_spec.rb +502 -0
- data/spec/lib/spree/core/validators/email_spec.rb +53 -0
- data/spec/lib/spree/localized_number_spec.rb +38 -0
- data/spec/lib/spree/migrations_spec.rb +34 -0
- data/spec/lib/spree/money_spec.rb +122 -0
- data/spec/lib/tasks/exchanges_spec.rb +136 -0
- data/spec/mailers/order_mailer_spec.rb +124 -0
- data/spec/mailers/reimbursement_mailer_spec.rb +47 -0
- data/spec/mailers/shipment_mailer_spec.rb +63 -0
- data/spec/mailers/test_mailer_spec.rb +24 -0
- data/spec/models/spree/ability_spec.rb +246 -0
- data/spec/models/spree/address_spec.rb +291 -0
- data/spec/models/spree/adjustable/adjustments_updater_spec.rb +286 -0
- data/spec/models/spree/adjustment_spec.rb +163 -0
- data/spec/models/spree/app_configuration_spec.rb +23 -0
- data/spec/models/spree/asset_spec.rb +25 -0
- data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
- data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
- data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
- data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
- data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
- data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
- data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
- data/spec/models/spree/calculator/shipping.rb +8 -0
- data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
- data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
- data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
- data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
- data/spec/models/spree/calculator/shipping/price_sack_spec.rb +29 -0
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +40 -0
- data/spec/models/spree/calculator/tiered_percent_spec.rb +51 -0
- data/spec/models/spree/calculator_spec.rb +69 -0
- data/spec/models/spree/classification_spec.rb +93 -0
- data/spec/models/spree/concerns/display_money_spec.rb +43 -0
- data/spec/models/spree/country_spec.rb +18 -0
- data/spec/models/spree/credit_card_spec.rb +324 -0
- data/spec/models/spree/customer_return_spec.rb +262 -0
- data/spec/models/spree/exchange_spec.rb +75 -0
- data/spec/models/spree/gateway/bogus_simple.rb +20 -0
- data/spec/models/spree/gateway/bogus_spec.rb +13 -0
- data/spec/models/spree/gateway_spec.rb +54 -0
- data/spec/models/spree/image_spec.rb +5 -0
- data/spec/models/spree/inventory_unit_spec.rb +242 -0
- data/spec/models/spree/line_item_spec.rb +267 -0
- data/spec/models/spree/option_type_spec.rb +14 -0
- data/spec/models/spree/option_value_spec.rb +13 -0
- data/spec/models/spree/order/address_spec.rb +50 -0
- data/spec/models/spree/order/adjustments_spec.rb +29 -0
- data/spec/models/spree/order/callbacks_spec.rb +42 -0
- data/spec/models/spree/order/checkout_spec.rb +764 -0
- data/spec/models/spree/order/currency_updater_spec.rb +32 -0
- data/spec/models/spree/order/finalizing_spec.rb +117 -0
- data/spec/models/spree/order/helpers_spec.rb +5 -0
- data/spec/models/spree/order/payment_spec.rb +214 -0
- data/spec/models/spree/order/risk_assessment_spec.rb +84 -0
- data/spec/models/spree/order/shipments_spec.rb +43 -0
- data/spec/models/spree/order/state_machine_spec.rb +216 -0
- data/spec/models/spree/order/tax_spec.rb +84 -0
- data/spec/models/spree/order/totals_spec.rb +24 -0
- data/spec/models/spree/order/updating_spec.rb +18 -0
- data/spec/models/spree/order/validations_spec.rb +15 -0
- data/spec/models/spree/order_contents_spec.rb +256 -0
- data/spec/models/spree/order_inventory_spec.rb +228 -0
- data/spec/models/spree/order_merger_spec.rb +133 -0
- data/spec/models/spree/order_spec.rb +954 -0
- data/spec/models/spree/order_updater_spec.rb +283 -0
- data/spec/models/spree/payment/gateway_options_spec.rb +119 -0
- data/spec/models/spree/payment_method_spec.rb +95 -0
- data/spec/models/spree/payment_spec.rb +926 -0
- data/spec/models/spree/preference_spec.rb +80 -0
- data/spec/models/spree/preferences/configuration_spec.rb +30 -0
- data/spec/models/spree/preferences/preferable_spec.rb +348 -0
- data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
- data/spec/models/spree/preferences/store_spec.rb +46 -0
- data/spec/models/spree/price_spec.rb +42 -0
- data/spec/models/spree/product/scopes_spec.rb +148 -0
- data/spec/models/spree/product_duplicator_spec.rb +103 -0
- data/spec/models/spree/product_filter_spec.rb +26 -0
- data/spec/models/spree/product_option_type_spec.rb +5 -0
- data/spec/models/spree/product_property_spec.rb +11 -0
- data/spec/models/spree/product_spec.rb +474 -0
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +50 -0
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +148 -0
- data/spec/models/spree/promotion/actions/create_line_items_spec.rb +86 -0
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +36 -0
- data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
- data/spec/models/spree/promotion/rules/item_total_spec.rb +282 -0
- data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
- data/spec/models/spree/promotion/rules/option_value_spec.rb +90 -0
- data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
- data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
- data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
- data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
- data/spec/models/spree/promotion_action_spec.rb +10 -0
- data/spec/models/spree/promotion_category_spec.rb +17 -0
- data/spec/models/spree/promotion_handler/cart_spec.rb +102 -0
- data/spec/models/spree/promotion_handler/coupon_spec.rb +323 -0
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +48 -0
- data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
- data/spec/models/spree/promotion_rule_spec.rb +29 -0
- data/spec/models/spree/promotion_spec.rb +603 -0
- data/spec/models/spree/property_spec.rb +5 -0
- data/spec/models/spree/prototype_spec.rb +5 -0
- data/spec/models/spree/refund_spec.rb +195 -0
- data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
- data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
- data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
- data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
- data/spec/models/spree/reimbursement_spec.rb +215 -0
- data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
- data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
- data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
- data/spec/models/spree/reimbursement_type/original_payment_spec.rb +55 -0
- data/spec/models/spree/return_authorization_spec.rb +250 -0
- data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
- data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
- data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +61 -0
- data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
- data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
- data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
- data/spec/models/spree/return_item_spec.rb +682 -0
- data/spec/models/spree/returns_calculator_spec.rb +14 -0
- data/spec/models/spree/shipment_spec.rb +740 -0
- data/spec/models/spree/shipping_calculator_spec.rb +45 -0
- data/spec/models/spree/shipping_category_spec.rb +5 -0
- data/spec/models/spree/shipping_method_spec.rb +88 -0
- data/spec/models/spree/shipping_rate_spec.rb +141 -0
- data/spec/models/spree/state_spec.rb +18 -0
- data/spec/models/spree/stock/availability_validator_spec.rb +36 -0
- data/spec/models/spree/stock/content_item_spec.rb +22 -0
- data/spec/models/spree/stock/coordinator_spec.rb +51 -0
- data/spec/models/spree/stock/differentiator_spec.rb +39 -0
- data/spec/models/spree/stock/estimator_spec.rb +154 -0
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
- data/spec/models/spree/stock/package_spec.rb +194 -0
- data/spec/models/spree/stock/packer_spec.rb +70 -0
- data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
- data/spec/models/spree/stock/quantifier_spec.rb +97 -0
- data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
- data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
- data/spec/models/spree/stock/splitter/shipping_category_spec.rb +47 -0
- data/spec/models/spree/stock/splitter/weight_spec.rb +32 -0
- data/spec/models/spree/stock_item_spec.rb +410 -0
- data/spec/models/spree/stock_location_spec.rb +243 -0
- data/spec/models/spree/stock_movement_spec.rb +56 -0
- data/spec/models/spree/stock_transfer_spec.rb +50 -0
- data/spec/models/spree/store_spec.rb +50 -0
- data/spec/models/spree/tax_category_spec.rb +27 -0
- data/spec/models/spree/tax_rate_spec.rb +382 -0
- data/spec/models/spree/taxon_spec.rb +74 -0
- data/spec/models/spree/taxonomy_spec.rb +18 -0
- data/spec/models/spree/tracker_spec.rb +21 -0
- data/spec/models/spree/user_spec.rb +130 -0
- data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +24 -0
- data/spec/models/spree/variant_spec.rb +523 -0
- data/spec/models/spree/zone_spec.rb +444 -0
- data/spec/spec_helper.rb +74 -0
- data/spec/support/big_decimal.rb +5 -0
- data/spec/support/concerns/adjustment_source_spec.rb +23 -0
- data/spec/support/concerns/default_price_spec.rb +28 -0
- data/spec/support/rake.rb +13 -0
- data/spec/support/test_gateway.rb +2 -0
- data/spree_core.gemspec +48 -0
- metadata +185 -4
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# coding: UTF-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Spree::Taxon, :type => :model do
|
|
6
|
+
let(:taxon) { FactoryGirl.build(:taxon, :name => "Ruby on Rails") }
|
|
7
|
+
|
|
8
|
+
describe '#to_param' do
|
|
9
|
+
subject { super().to_param }
|
|
10
|
+
it { is_expected.to eql taxon.permalink }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context "set_permalink" do
|
|
14
|
+
|
|
15
|
+
it "should set permalink correctly when no parent present" do
|
|
16
|
+
taxon.set_permalink
|
|
17
|
+
expect(taxon.permalink).to eql "ruby-on-rails"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should support Chinese characters" do
|
|
21
|
+
taxon.name = "你好"
|
|
22
|
+
taxon.set_permalink
|
|
23
|
+
expect(taxon.permalink).to eql 'ni-hao'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
context "with parent taxon" do
|
|
27
|
+
let(:parent) { FactoryGirl.build(:taxon, :permalink => "brands") }
|
|
28
|
+
before { allow(taxon).to receive_messages parent: parent }
|
|
29
|
+
|
|
30
|
+
it "should set permalink correctly when taxon has parent" do
|
|
31
|
+
taxon.set_permalink
|
|
32
|
+
expect(taxon.permalink).to eql "brands/ruby-on-rails"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should set permalink correctly with existing permalink present" do
|
|
36
|
+
taxon.permalink = "b/rubyonrails"
|
|
37
|
+
taxon.set_permalink
|
|
38
|
+
expect(taxon.permalink).to eql "brands/rubyonrails"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should support Chinese characters" do
|
|
42
|
+
taxon.name = "我"
|
|
43
|
+
taxon.set_permalink
|
|
44
|
+
expect(taxon.permalink).to eql "brands/wo"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Regression test for #3390
|
|
48
|
+
context "setting a new node sibling position via :child_index=" do
|
|
49
|
+
let(:idx) { rand(0..100) }
|
|
50
|
+
before { allow(parent).to receive(:move_to_child_with_index) }
|
|
51
|
+
|
|
52
|
+
context "taxon is not new" do
|
|
53
|
+
before { allow(taxon).to receive(:new_record?).and_return(false) }
|
|
54
|
+
|
|
55
|
+
it "passes the desired index move_to_child_with_index of :parent " do
|
|
56
|
+
expect(taxon).to receive(:move_to_child_with_index).with(parent, idx)
|
|
57
|
+
|
|
58
|
+
taxon.child_index = idx
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Regression test for #2620
|
|
67
|
+
context "creating a child node using first_or_create" do
|
|
68
|
+
let(:taxonomy) { create(:taxonomy) }
|
|
69
|
+
|
|
70
|
+
it "does not error out" do
|
|
71
|
+
expect { taxonomy.root.children.unscoped.where(:name => "Some name").first_or_create }.not_to raise_error
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Taxonomy, :type => :model do
|
|
4
|
+
context "#destroy" do
|
|
5
|
+
before do
|
|
6
|
+
@taxonomy = create(:taxonomy)
|
|
7
|
+
@root_taxon = @taxonomy.root
|
|
8
|
+
@child_taxon = create(:taxon, :taxonomy_id => @taxonomy.id, :parent => @root_taxon)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should destroy all associated taxons" do
|
|
12
|
+
@taxonomy.destroy
|
|
13
|
+
expect{ Spree::Taxon.find(@root_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
|
14
|
+
expect{ Spree::Taxon.find(@child_taxon.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Tracker, :type => :model do
|
|
4
|
+
describe "current" do
|
|
5
|
+
before(:each) { @tracker = create(:tracker) }
|
|
6
|
+
|
|
7
|
+
it "returns the first active tracker" do
|
|
8
|
+
expect(Spree::Tracker.current).to eq(@tracker)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "does not return a tracker with a blank analytics_id" do
|
|
12
|
+
@tracker.update_attribute(:analytics_id, '')
|
|
13
|
+
expect(Spree::Tracker.current).to be_nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "does not return an inactive tracker" do
|
|
17
|
+
@tracker.update_attribute(:active, false)
|
|
18
|
+
expect(Spree::Tracker.current).to be_nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::LegacyUser, :type => :model do
|
|
4
|
+
# Regression test for #2844 + #3346
|
|
5
|
+
context "#last_incomplete_order" do
|
|
6
|
+
let!(:user) { create(:user) }
|
|
7
|
+
let!(:order) { create(:order, bill_address: create(:address), ship_address: create(:address)) }
|
|
8
|
+
|
|
9
|
+
let!(:order_1) { create(:order, :created_at => 1.day.ago, :user => user, :created_by => user) }
|
|
10
|
+
let!(:order_2) { create(:order, :user => user, :created_by => user) }
|
|
11
|
+
let!(:order_3) { create(:order, :user => user, :created_by => create(:user)) }
|
|
12
|
+
|
|
13
|
+
it "returns correct order" do
|
|
14
|
+
expect(user.last_incomplete_spree_order).to eq order_3
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context "persists order address" do
|
|
18
|
+
it "copies over order addresses" do
|
|
19
|
+
expect {
|
|
20
|
+
user.persist_order_address(order)
|
|
21
|
+
}.to change { Spree::Address.count }.by(2)
|
|
22
|
+
|
|
23
|
+
expect(user.bill_address).to eq order.bill_address
|
|
24
|
+
expect(user.ship_address).to eq order.ship_address
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "doesnt create new addresses if user has already" do
|
|
28
|
+
user.update_column(:bill_address_id, create(:address))
|
|
29
|
+
user.update_column(:ship_address_id, create(:address))
|
|
30
|
+
user.reload
|
|
31
|
+
|
|
32
|
+
expect {
|
|
33
|
+
user.persist_order_address(order)
|
|
34
|
+
}.not_to change { Spree::Address.count }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "set both bill and ship address id on subject" do
|
|
38
|
+
user.persist_order_address(order)
|
|
39
|
+
|
|
40
|
+
expect(user.bill_address_id).not_to be_blank
|
|
41
|
+
expect(user.ship_address_id).not_to be_blank
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "payment source" do
|
|
46
|
+
let(:payment_method) { create(:credit_card_payment_method) }
|
|
47
|
+
let!(:cc) do
|
|
48
|
+
create(:credit_card, user_id: user.id, payment_method: payment_method, gateway_customer_profile_id: "2342343")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "has payment sources" do
|
|
52
|
+
expect(user.payment_sources.first.gateway_customer_profile_id).not_to be_empty
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "drops payment source" do
|
|
56
|
+
user.drop_payment_source cc
|
|
57
|
+
expect(cc.gateway_customer_profile_id).to be_nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe Spree.user_class, :type => :model do
|
|
64
|
+
context "reporting" do
|
|
65
|
+
let(:order_value) { BigDecimal.new("80.94") }
|
|
66
|
+
let(:order_count) { 4 }
|
|
67
|
+
let(:orders) { Array.new(order_count, double(total: order_value)) }
|
|
68
|
+
|
|
69
|
+
before do
|
|
70
|
+
allow(orders).to receive(:pluck).with(:total).and_return(orders.map(&:total))
|
|
71
|
+
allow(orders).to receive(:count).and_return(orders.length)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def load_orders
|
|
75
|
+
allow(subject).to receive(:orders).and_return(double(complete: orders))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe "#lifetime_value" do
|
|
79
|
+
context "with orders" do
|
|
80
|
+
before { load_orders }
|
|
81
|
+
it "returns the total of completed orders for the user" do
|
|
82
|
+
expect(subject.lifetime_value).to eq (order_count * order_value)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
context "without orders" do
|
|
86
|
+
it "returns 0.00" do
|
|
87
|
+
expect(subject.lifetime_value).to eq BigDecimal("0.00")
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe "#display_lifetime_value" do
|
|
93
|
+
it "returns a Spree::Money version of lifetime_value" do
|
|
94
|
+
value = BigDecimal("500.05")
|
|
95
|
+
allow(subject).to receive(:lifetime_value).and_return(value)
|
|
96
|
+
expect(subject.display_lifetime_value).to eq Spree::Money.new(value)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "#order_count" do
|
|
101
|
+
before { load_orders }
|
|
102
|
+
it "returns the count of completed orders for the user" do
|
|
103
|
+
expect(subject.order_count).to eq BigDecimal(order_count)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "#average_order_value" do
|
|
108
|
+
context "with orders" do
|
|
109
|
+
before { load_orders }
|
|
110
|
+
it "returns the average completed order price for the user" do
|
|
111
|
+
expect(subject.average_order_value).to eq order_value
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
context "without orders" do
|
|
115
|
+
it "returns 0.00" do
|
|
116
|
+
expect(subject.average_order_value).to eq BigDecimal("0.00")
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe "#display_average_order_value" do
|
|
122
|
+
before { load_orders }
|
|
123
|
+
it "returns a Spree::Money version of average_order_value" do
|
|
124
|
+
value = BigDecimal("500.05")
|
|
125
|
+
allow(subject).to receive(:average_order_value).and_return(value)
|
|
126
|
+
expect(subject.display_average_order_value).to eq Spree::Money.new(value)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Validations::DbMaximumLengthValidator, :type => :model do
|
|
4
|
+
context 'when Spree::Product' do
|
|
5
|
+
Spree::Product.class_eval do
|
|
6
|
+
attribute :slug, ActiveRecord::Type::String.new(limit: 255)
|
|
7
|
+
# Slug currently has no validation for maximum length
|
|
8
|
+
validates_with Spree::Validations::DbMaximumLengthValidator, field: :slug
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:limit) { 255 }
|
|
12
|
+
let(:product) { Spree::Product.new }
|
|
13
|
+
let(:slug) { "x" * (limit + 1)}
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
product.slug = slug
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should maximum validate slug' do
|
|
20
|
+
product.valid?
|
|
21
|
+
expect(product.errors[:slug]).to include(I18n.t("errors.messages.too_long", count: limit))
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Spree::Variant, :type => :model do
|
|
6
|
+
let!(:variant) { create(:variant) }
|
|
7
|
+
|
|
8
|
+
it_behaves_like 'default_price'
|
|
9
|
+
|
|
10
|
+
context 'sorting' do
|
|
11
|
+
it 'responds to set_list_position' do
|
|
12
|
+
expect(variant.respond_to?(:set_list_position)).to eq(true)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context "validations" do
|
|
17
|
+
it "should validate price is greater than 0" do
|
|
18
|
+
variant.price = -1
|
|
19
|
+
expect(variant).to be_invalid
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should validate price is 0" do
|
|
23
|
+
variant.price = 0
|
|
24
|
+
expect(variant).to be_valid
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "after create" do
|
|
29
|
+
let!(:product) { create(:product) }
|
|
30
|
+
|
|
31
|
+
it "propagate to stock items" do
|
|
32
|
+
expect_any_instance_of(Spree::StockLocation).to receive(:propagate_variant)
|
|
33
|
+
product.variants.create(:name => "Foobar")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "stock location has disable propagate all variants" do
|
|
37
|
+
before { Spree::StockLocation.update_all propagate_all_variants: false }
|
|
38
|
+
|
|
39
|
+
it "propagate to stock items" do
|
|
40
|
+
expect_any_instance_of(Spree::StockLocation).not_to receive(:propagate_variant)
|
|
41
|
+
product.variants.create(:name => "Foobar")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe 'mark_master_out_of_stock' do
|
|
46
|
+
before do
|
|
47
|
+
product.master.stock_items.first.set_count_on_hand(5)
|
|
48
|
+
end
|
|
49
|
+
context 'when product is created without variants but with stock' do
|
|
50
|
+
it { expect(product.master).to be_in_stock }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'when a variant is created' do
|
|
54
|
+
before(:each) do
|
|
55
|
+
product.variants.create!(:name => 'any-name')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it { expect(product.master).to_not be_in_stock }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "product has other variants" do
|
|
64
|
+
describe "option value accessors" do
|
|
65
|
+
before {
|
|
66
|
+
@multi_variant = FactoryGirl.create :variant, :product => variant.product
|
|
67
|
+
variant.product.reload
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let(:multi_variant) { @multi_variant }
|
|
71
|
+
|
|
72
|
+
it "should set option value" do
|
|
73
|
+
expect(multi_variant.option_value('media_type')).to be_nil
|
|
74
|
+
|
|
75
|
+
multi_variant.set_option_value('media_type', 'DVD')
|
|
76
|
+
expect(multi_variant.option_value('media_type')).to eql 'DVD'
|
|
77
|
+
|
|
78
|
+
multi_variant.set_option_value('media_type', 'CD')
|
|
79
|
+
expect(multi_variant.option_value('media_type')).to eql 'CD'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should not duplicate associated option values when set multiple times" do
|
|
83
|
+
multi_variant.set_option_value('media_type', 'CD')
|
|
84
|
+
|
|
85
|
+
expect {
|
|
86
|
+
multi_variant.set_option_value('media_type', 'DVD')
|
|
87
|
+
}.to_not change(multi_variant.option_values, :count)
|
|
88
|
+
|
|
89
|
+
expect {
|
|
90
|
+
multi_variant.set_option_value('coolness_type', 'awesome')
|
|
91
|
+
}.to change(multi_variant.option_values, :count).by(1)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "product has other variants" do
|
|
96
|
+
describe "option value accessors" do
|
|
97
|
+
before {
|
|
98
|
+
@multi_variant = create(:variant, :product => variant.product)
|
|
99
|
+
variant.product.reload
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let(:multi_variant) { @multi_variant }
|
|
103
|
+
|
|
104
|
+
it "should set option value" do
|
|
105
|
+
expect(multi_variant.option_value('media_type')).to be_nil
|
|
106
|
+
|
|
107
|
+
multi_variant.set_option_value('media_type', 'DVD')
|
|
108
|
+
expect(multi_variant.option_value('media_type')).to eql 'DVD'
|
|
109
|
+
|
|
110
|
+
multi_variant.set_option_value('media_type', 'CD')
|
|
111
|
+
expect(multi_variant.option_value('media_type')).to eql 'CD'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should not duplicate associated option values when set multiple times" do
|
|
115
|
+
multi_variant.set_option_value('media_type', 'CD')
|
|
116
|
+
|
|
117
|
+
expect {
|
|
118
|
+
multi_variant.set_option_value('media_type', 'DVD')
|
|
119
|
+
}.to_not change(multi_variant.option_values, :count)
|
|
120
|
+
|
|
121
|
+
expect {
|
|
122
|
+
multi_variant.set_option_value('coolness_type', 'awesome')
|
|
123
|
+
}.to change(multi_variant.option_values, :count).by(1)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context "#cost_price=" do
|
|
130
|
+
it "should use LocalizedNumber.parse" do
|
|
131
|
+
expect(Spree::LocalizedNumber).to receive(:parse).with('1,599.99')
|
|
132
|
+
subject.cost_price = '1,599.99'
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "#price=" do
|
|
137
|
+
it "should use LocalizedNumber.parse" do
|
|
138
|
+
expect(Spree::LocalizedNumber).to receive(:parse).with('1,599.99')
|
|
139
|
+
subject.price = '1,599.99'
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
context "#weight=" do
|
|
144
|
+
it "should use LocalizedNumber.parse" do
|
|
145
|
+
expect(Spree::LocalizedNumber).to receive(:parse).with('1,599.99')
|
|
146
|
+
subject.weight = '1,599.99'
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
context "#currency" do
|
|
151
|
+
it "returns the globally configured currency" do
|
|
152
|
+
expect(variant.currency).to eql "USD"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context "#display_amount" do
|
|
157
|
+
it "returns a Spree::Money" do
|
|
158
|
+
variant.price = 21.22
|
|
159
|
+
expect(variant.display_amount.to_s).to eql "$21.22"
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context "#cost_currency" do
|
|
164
|
+
context "when cost currency is nil" do
|
|
165
|
+
before { variant.cost_currency = nil }
|
|
166
|
+
it "populates cost currency with the default value on save" do
|
|
167
|
+
variant.save!
|
|
168
|
+
expect(variant.cost_currency).to eql "USD"
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
describe '.price_in' do
|
|
174
|
+
before do
|
|
175
|
+
variant.prices << create(:price, :variant => variant, :currency => "EUR", :amount => 33.33)
|
|
176
|
+
end
|
|
177
|
+
subject { variant.price_in(currency).display_amount }
|
|
178
|
+
|
|
179
|
+
context "when currency is not specified" do
|
|
180
|
+
let(:currency) { nil }
|
|
181
|
+
|
|
182
|
+
it "returns 0" do
|
|
183
|
+
expect(subject.to_s).to eql "$0.00"
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context "when currency is EUR" do
|
|
188
|
+
let(:currency) { 'EUR' }
|
|
189
|
+
|
|
190
|
+
it "returns the value in the EUR" do
|
|
191
|
+
expect(subject.to_s).to eql "€33.33"
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context "when currency is USD" do
|
|
196
|
+
let(:currency) { 'USD' }
|
|
197
|
+
|
|
198
|
+
it "returns the value in the USD" do
|
|
199
|
+
expect(subject.to_s).to eql "$19.99"
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe '.amount_in' do
|
|
205
|
+
before do
|
|
206
|
+
variant.prices << create(:price, :variant => variant, :currency => "EUR", :amount => 33.33)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
subject { variant.amount_in(currency) }
|
|
210
|
+
|
|
211
|
+
context "when currency is not specified" do
|
|
212
|
+
let(:currency) { nil }
|
|
213
|
+
|
|
214
|
+
it "returns nil" do
|
|
215
|
+
expect(subject).to be_nil
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
context "when currency is EUR" do
|
|
220
|
+
let(:currency) { 'EUR' }
|
|
221
|
+
|
|
222
|
+
it "returns the value in the EUR" do
|
|
223
|
+
expect(subject).to eql 33.33
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
context "when currency is USD" do
|
|
228
|
+
let(:currency) { 'USD' }
|
|
229
|
+
|
|
230
|
+
it "returns the value in the USD" do
|
|
231
|
+
expect(subject).to eql 19.99
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Regression test for #2432
|
|
237
|
+
describe 'options_text' do
|
|
238
|
+
let!(:variant) { create(:variant, option_values: []) }
|
|
239
|
+
let!(:master) { create(:master_variant) }
|
|
240
|
+
|
|
241
|
+
before do
|
|
242
|
+
# Order bar than foo
|
|
243
|
+
variant.option_values << create(:option_value, {name: 'Foo', presentation: 'Foo', option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')})
|
|
244
|
+
variant.option_values << create(:option_value, {name: 'Bar', presentation: 'Bar', option_type: create(:option_type, position: 1, name: 'Bar Type', presentation: 'Bar Type')})
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it 'should order by bar than foo' do
|
|
248
|
+
expect(variant.options_text).to eql 'Bar Type: Bar, Foo Type: Foo'
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe 'exchange_name' do
|
|
254
|
+
let!(:variant) { create(:variant, option_values: []) }
|
|
255
|
+
let!(:master) { create(:master_variant) }
|
|
256
|
+
|
|
257
|
+
before do
|
|
258
|
+
variant.option_values << create(:option_value, {
|
|
259
|
+
name: 'Foo',
|
|
260
|
+
presentation: 'Foo',
|
|
261
|
+
option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')
|
|
262
|
+
})
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
context 'master variant' do
|
|
266
|
+
it 'should return name' do
|
|
267
|
+
expect(master.exchange_name).to eql master.name
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
context 'variant' do
|
|
272
|
+
it 'should return options text' do
|
|
273
|
+
expect(variant.exchange_name).to eql 'Foo Type: Foo'
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
describe 'exchange_name' do
|
|
280
|
+
let!(:variant) { create(:variant, option_values: []) }
|
|
281
|
+
let!(:master) { create(:master_variant) }
|
|
282
|
+
|
|
283
|
+
before do
|
|
284
|
+
variant.option_values << create(:option_value, {
|
|
285
|
+
name: 'Foo',
|
|
286
|
+
presentation: 'Foo',
|
|
287
|
+
option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')
|
|
288
|
+
})
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
context 'master variant' do
|
|
292
|
+
it 'should return name' do
|
|
293
|
+
expect(master.exchange_name).to eql master.name
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
context 'variant' do
|
|
298
|
+
it 'should return options text' do
|
|
299
|
+
expect(variant.exchange_name).to eql 'Foo Type: Foo'
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
describe 'descriptive_name' do
|
|
306
|
+
let!(:variant) { create(:variant, option_values: []) }
|
|
307
|
+
let!(:master) { create(:master_variant) }
|
|
308
|
+
|
|
309
|
+
before do
|
|
310
|
+
variant.option_values << create(:option_value, {
|
|
311
|
+
name: 'Foo',
|
|
312
|
+
presentation: 'Foo',
|
|
313
|
+
option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')
|
|
314
|
+
})
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
context 'master variant' do
|
|
318
|
+
it 'should return name with Master identifier' do
|
|
319
|
+
expect(master.descriptive_name).to eql master.name + ' - Master'
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
context 'variant' do
|
|
324
|
+
it 'should return options text with name' do
|
|
325
|
+
expect(variant.descriptive_name).to eql variant.name + ' - Foo Type: Foo'
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# Regression test for #2744
|
|
332
|
+
describe "set_position" do
|
|
333
|
+
it "sets variant position after creation" do
|
|
334
|
+
variant = create(:variant)
|
|
335
|
+
expect(variant.position).to_not be_nil
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
describe '#in_stock?' do
|
|
340
|
+
before do
|
|
341
|
+
Spree::Config.track_inventory_levels = true
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
context 'when stock_items are not backorderable' do
|
|
345
|
+
before do
|
|
346
|
+
allow_any_instance_of(Spree::StockItem).to receive_messages(backorderable: false)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
context 'when stock_items in stock' do
|
|
350
|
+
before do
|
|
351
|
+
variant.stock_items.first.update_column(:count_on_hand, 10)
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
it 'returns true if stock_items in stock' do
|
|
355
|
+
expect(variant.in_stock?).to be true
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
context 'when stock_items out of stock' do
|
|
360
|
+
before do
|
|
361
|
+
allow_any_instance_of(Spree::StockItem).to receive_messages(backorderable: false)
|
|
362
|
+
allow_any_instance_of(Spree::StockItem).to receive_messages(count_on_hand: 0)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
it 'return false if stock_items out of stock' do
|
|
366
|
+
expect(variant.in_stock?).to be false
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
describe "#can_supply?" do
|
|
372
|
+
it "calls out to quantifier" do
|
|
373
|
+
expect(Spree::Stock::Quantifier).to receive(:new).and_return(quantifier = double)
|
|
374
|
+
expect(quantifier).to receive(:can_supply?).with(10)
|
|
375
|
+
variant.can_supply?(10)
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
context 'when stock_items are backorderable' do
|
|
380
|
+
before do
|
|
381
|
+
allow_any_instance_of(Spree::StockItem).to receive_messages(backorderable: true)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
context 'when stock_items out of stock' do
|
|
385
|
+
before do
|
|
386
|
+
allow_any_instance_of(Spree::StockItem).to receive_messages(count_on_hand: 0)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it 'in_stock? returns false' do
|
|
390
|
+
expect(variant.in_stock?).to be false
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
it 'can_supply? return true' do
|
|
394
|
+
expect(variant.can_supply?).to be true
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
describe '#is_backorderable' do
|
|
401
|
+
let(:variant) { build(:variant) }
|
|
402
|
+
subject { variant.is_backorderable? }
|
|
403
|
+
|
|
404
|
+
it 'should invoke Spree::Stock::Quantifier' do
|
|
405
|
+
expect_any_instance_of(Spree::Stock::Quantifier).to receive(:backorderable?) { true }
|
|
406
|
+
subject
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
describe '#total_on_hand' do
|
|
411
|
+
it 'should be infinite if track_inventory_levels is false' do
|
|
412
|
+
Spree::Config[:track_inventory_levels] = false
|
|
413
|
+
expect(build(:variant).total_on_hand).to eql(Float::INFINITY)
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
it 'should match quantifier total_on_hand' do
|
|
417
|
+
variant = build(:variant)
|
|
418
|
+
expect(variant.total_on_hand).to eq(Spree::Stock::Quantifier.new(variant).total_on_hand)
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
describe '#tax_category' do
|
|
423
|
+
context 'when tax_category is nil' do
|
|
424
|
+
let(:product) { build(:product) }
|
|
425
|
+
let(:variant) { build(:variant, product: product, tax_category_id: nil) }
|
|
426
|
+
it 'returns the parent products tax_category' do
|
|
427
|
+
expect(variant.tax_category).to eq(product.tax_category)
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
context 'when tax_category is set' do
|
|
432
|
+
let(:tax_category) { create(:tax_category) }
|
|
433
|
+
let(:variant) { build(:variant, tax_category: tax_category) }
|
|
434
|
+
it 'returns the tax_category set on itself' do
|
|
435
|
+
expect(variant.tax_category).to eq(tax_category)
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
describe "touching" do
|
|
441
|
+
it "updates a product" do
|
|
442
|
+
variant.product.update_column(:updated_at, 1.day.ago)
|
|
443
|
+
variant.touch
|
|
444
|
+
expect(variant.product.reload.updated_at).to be_within(3.seconds).of(Time.now)
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
it "clears the in_stock cache key" do
|
|
448
|
+
expect(Rails.cache).to receive(:delete).with(variant.send(:in_stock_cache_key))
|
|
449
|
+
variant.touch
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
describe "#should_track_inventory?" do
|
|
454
|
+
|
|
455
|
+
it 'should not track inventory when global setting is off' do
|
|
456
|
+
Spree::Config[:track_inventory_levels] = false
|
|
457
|
+
|
|
458
|
+
expect(build(:variant).should_track_inventory?).to eq(false)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it 'should not track inventory when variant is turned off' do
|
|
462
|
+
Spree::Config[:track_inventory_levels] = true
|
|
463
|
+
|
|
464
|
+
expect(build(:on_demand_variant).should_track_inventory?).to eq(false)
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it 'should track inventory when global and variant are on' do
|
|
468
|
+
Spree::Config[:track_inventory_levels] = true
|
|
469
|
+
|
|
470
|
+
expect(build(:variant).should_track_inventory?).to eq(true)
|
|
471
|
+
end
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
describe "deleted_at scope" do
|
|
475
|
+
before { variant.destroy && variant.reload }
|
|
476
|
+
it "should have a price if deleted" do
|
|
477
|
+
variant.price = 10
|
|
478
|
+
expect(variant.price).to eq(10)
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
describe "stock movements" do
|
|
483
|
+
let!(:movement) { create(:stock_movement, stock_item: variant.stock_items.first) }
|
|
484
|
+
|
|
485
|
+
it "builds out collection just fine through stock items" do
|
|
486
|
+
expect(variant.stock_movements.to_a).not_to be_empty
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
describe "in_stock scope" do
|
|
491
|
+
it "returns all in stock variants" do
|
|
492
|
+
in_stock_variant = create(:variant)
|
|
493
|
+
out_of_stock_variant = create(:variant)
|
|
494
|
+
|
|
495
|
+
in_stock_variant.stock_items.first.update_column(:count_on_hand, 10)
|
|
496
|
+
|
|
497
|
+
expect(Spree::Variant.in_stock).to eq [in_stock_variant]
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
context "#volume" do
|
|
502
|
+
let(:variant_zero_width) { create(:variant, width: 0) }
|
|
503
|
+
let(:variant) { create(:variant) }
|
|
504
|
+
|
|
505
|
+
it "it is zero if any dimension parameter is zero" do
|
|
506
|
+
expect(variant_zero_width.volume).to eq 0
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
it "return the volume if the dimension parameters are different of zero" do
|
|
510
|
+
volume_expected = variant.width * variant.depth * variant.height
|
|
511
|
+
expect(variant.volume).to eq (volume_expected)
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
context "#dimension" do
|
|
516
|
+
let(:variant) { create(:variant) }
|
|
517
|
+
|
|
518
|
+
it "return the dimension if the dimension parameters are different of zero" do
|
|
519
|
+
dimension_expected = variant.width + variant.depth + variant.height
|
|
520
|
+
expect(variant.dimension).to eq (dimension_expected)
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
end
|