spree_core 3.2.1 → 3.2.2
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/lib/spree/core/version.rb +1 -1
- data/spree_core.gemspec +1 -1
- metadata +3 -206
- data/spec/fixtures/microdata.html +0 -22
- data/spec/fixtures/microdata_itemref.html +0 -15
- data/spec/fixtures/microdata_no_itemscope.html +0 -20
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/helpers/base_helper_spec.rb +0 -200
- data/spec/helpers/products_helper_spec.rb +0 -289
- data/spec/lib/calculated_adjustments_spec.rb +0 -7
- data/spec/lib/i18n_spec.rb +0 -123
- data/spec/lib/search/base_spec.rb +0 -86
- data/spec/lib/spree/core/controller_helpers/auth_spec.rb +0 -103
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +0 -110
- data/spec/lib/spree/core/controller_helpers/search_spec.rb +0 -17
- data/spec/lib/spree/core/controller_helpers/store_spec.rb +0 -72
- data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +0 -39
- data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -22
- data/spec/lib/spree/core/importer/order_spec.rb +0 -605
- data/spec/lib/spree/core/number_generator_spec.rb +0 -175
- data/spec/lib/spree/core/token_generator_spec.rb +0 -24
- data/spec/lib/spree/core/validators/email_spec.rb +0 -53
- data/spec/lib/spree/core_spec.rb +0 -23
- data/spec/lib/spree/localized_number_spec.rb +0 -48
- data/spec/lib/spree/migrations_spec.rb +0 -36
- data/spec/lib/spree/money_spec.rb +0 -122
- data/spec/lib/tasks/exchanges_spec.rb +0 -136
- data/spec/mailers/order_mailer_spec.rb +0 -122
- data/spec/mailers/reimbursement_mailer_spec.rb +0 -47
- data/spec/mailers/shipment_mailer_spec.rb +0 -81
- data/spec/mailers/test_mailer_spec.rb +0 -38
- data/spec/models/option_type_prototype_spec.rb +0 -9
- data/spec/models/spree/ability_spec.rb +0 -251
- data/spec/models/spree/address_spec.rb +0 -402
- data/spec/models/spree/adjustable/adjuster/base_spec.rb +0 -10
- data/spec/models/spree/adjustable/adjuster/promotion_spec.rb +0 -211
- data/spec/models/spree/adjustable/adjuster/tax_spec.rb +0 -86
- data/spec/models/spree/adjustable/adjustments_updater_spec.rb +0 -26
- data/spec/models/spree/adjustment_spec.rb +0 -189
- data/spec/models/spree/app_configuration_spec.rb +0 -26
- data/spec/models/spree/asset_spec.rb +0 -28
- data/spec/models/spree/calculator/default_tax_spec.rb +0 -152
- data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +0 -25
- data/spec/models/spree/calculator/flat_rate_spec.rb +0 -47
- data/spec/models/spree/calculator/flexi_rate_spec.rb +0 -41
- data/spec/models/spree/calculator/percent_on_line_item_spec.rb +0 -15
- data/spec/models/spree/calculator/price_sack_spec.rb +0 -30
- data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +0 -47
- data/spec/models/spree/calculator/shipping.rb +0 -8
- data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +0 -23
- data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +0 -13
- data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +0 -52
- data/spec/models/spree/calculator/shipping/per_item_spec.rb +0 -20
- data/spec/models/spree/calculator/shipping/price_sack_spec.rb +0 -29
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +0 -40
- data/spec/models/spree/calculator/tiered_percent_spec.rb +0 -51
- data/spec/models/spree/calculator_spec.rb +0 -69
- data/spec/models/spree/classification_spec.rb +0 -93
- data/spec/models/spree/concerns/display_money_spec.rb +0 -43
- data/spec/models/spree/concerns/user_methods_spec.rb +0 -82
- data/spec/models/spree/concerns/vat_price_calculation_spec.rb +0 -66
- data/spec/models/spree/country_spec.rb +0 -55
- data/spec/models/spree/credit_card_spec.rb +0 -328
- data/spec/models/spree/customer_return_spec.rb +0 -240
- data/spec/models/spree/exchange_spec.rb +0 -75
- data/spec/models/spree/gateway/bogus_simple.rb +0 -20
- data/spec/models/spree/gateway/bogus_spec.rb +0 -13
- data/spec/models/spree/gateway_spec.rb +0 -61
- data/spec/models/spree/image_spec.rb +0 -8
- data/spec/models/spree/inventory_unit_spec.rb +0 -256
- data/spec/models/spree/line_item_spec.rb +0 -346
- data/spec/models/spree/option_type_spec.rb +0 -14
- data/spec/models/spree/option_value_spec.rb +0 -18
- data/spec/models/spree/order/address_spec.rb +0 -50
- data/spec/models/spree/order/adjustments_spec.rb +0 -29
- data/spec/models/spree/order/callbacks_spec.rb +0 -42
- data/spec/models/spree/order/checkout_spec.rb +0 -770
- data/spec/models/spree/order/currency_updater_spec.rb +0 -32
- data/spec/models/spree/order/finalizing_spec.rb +0 -114
- data/spec/models/spree/order/helpers_spec.rb +0 -5
- data/spec/models/spree/order/payment_spec.rb +0 -214
- data/spec/models/spree/order/risk_assessment_spec.rb +0 -84
- data/spec/models/spree/order/shipments_spec.rb +0 -43
- data/spec/models/spree/order/state_machine_spec.rb +0 -212
- data/spec/models/spree/order/store_credit_spec.rb +0 -426
- data/spec/models/spree/order/tax_spec.rb +0 -84
- data/spec/models/spree/order/totals_spec.rb +0 -24
- data/spec/models/spree/order/updating_spec.rb +0 -18
- data/spec/models/spree/order/validations_spec.rb +0 -15
- data/spec/models/spree/order_contents_spec.rb +0 -297
- data/spec/models/spree/order_inventory_spec.rb +0 -239
- data/spec/models/spree/order_merger_spec.rb +0 -135
- data/spec/models/spree/order_spec.rb +0 -1046
- data/spec/models/spree/order_updater_spec.rb +0 -305
- data/spec/models/spree/payment/gateway_options_spec.rb +0 -127
- data/spec/models/spree/payment/store_credit_spec.rb +0 -60
- data/spec/models/spree/payment_method/store_credit_spec.rb +0 -291
- data/spec/models/spree/payment_method_spec.rb +0 -103
- data/spec/models/spree/payment_spec.rb +0 -919
- data/spec/models/spree/preference_spec.rb +0 -80
- data/spec/models/spree/preferences/configuration_spec.rb +0 -30
- data/spec/models/spree/preferences/preferable_spec.rb +0 -344
- data/spec/models/spree/preferences/scoped_store_spec.rb +0 -58
- data/spec/models/spree/preferences/store_spec.rb +0 -46
- data/spec/models/spree/price_spec.rb +0 -128
- data/spec/models/spree/product/scopes_spec.rb +0 -183
- data/spec/models/spree/product_duplicator_spec.rb +0 -103
- data/spec/models/spree/product_filter_spec.rb +0 -26
- data/spec/models/spree/product_option_type_spec.rb +0 -9
- data/spec/models/spree/product_promotion_rule_spec.rb +0 -9
- data/spec/models/spree/product_property_spec.rb +0 -26
- data/spec/models/spree/product_spec.rb +0 -629
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +0 -113
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +0 -148
- data/spec/models/spree/promotion/actions/create_line_items_spec.rb +0 -86
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +0 -36
- data/spec/models/spree/promotion/rules/country_spec.rb +0 -36
- data/spec/models/spree/promotion/rules/first_order_spec.rb +0 -75
- data/spec/models/spree/promotion/rules/item_total_spec.rb +0 -282
- data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +0 -42
- data/spec/models/spree/promotion/rules/option_value_spec.rb +0 -90
- data/spec/models/spree/promotion/rules/product_spec.rb +0 -143
- data/spec/models/spree/promotion/rules/taxon_spec.rb +0 -102
- data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +0 -27
- data/spec/models/spree/promotion/rules/user_spec.rb +0 -45
- data/spec/models/spree/promotion_action_spec.rb +0 -10
- data/spec/models/spree/promotion_category_spec.rb +0 -17
- data/spec/models/spree/promotion_handler/cart_spec.rb +0 -102
- data/spec/models/spree/promotion_handler/coupon_spec.rb +0 -323
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +0 -48
- data/spec/models/spree/promotion_handler/page_spec.rb +0 -44
- data/spec/models/spree/promotion_rule_spec.rb +0 -29
- data/spec/models/spree/promotion_rule_taxon_spec.rb +0 -9
- data/spec/models/spree/promotion_rule_user_spec.rb +0 -9
- data/spec/models/spree/promotion_spec.rb +0 -679
- data/spec/models/spree/property_prototype_spec.rb +0 -9
- data/spec/models/spree/property_spec.rb +0 -5
- data/spec/models/spree/prototype_spec.rb +0 -5
- data/spec/models/spree/prototype_taxon_spec.rb +0 -9
- data/spec/models/spree/refund_reason_spec.rb +0 -20
- data/spec/models/spree/refund_spec.rb +0 -195
- data/spec/models/spree/reimbursement/credit_spec.rb +0 -36
- data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +0 -140
- data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +0 -83
- data/spec/models/spree/reimbursement_performer_spec.rb +0 -30
- data/spec/models/spree/reimbursement_spec.rb +0 -188
- data/spec/models/spree/reimbursement_tax_calculator_spec.rb +0 -63
- data/spec/models/spree/reimbursement_type/credit_spec.rb +0 -53
- data/spec/models/spree/reimbursement_type/exchange_spec.rb +0 -46
- data/spec/models/spree/reimbursement_type/original_payment_spec.rb +0 -55
- data/spec/models/spree/reimbursement_type/store_credit_spec.rb +0 -101
- data/spec/models/spree/return_authorization_reason_spec.rb +0 -7
- data/spec/models/spree/return_authorization_spec.rb +0 -230
- data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +0 -77
- data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +0 -58
- data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +0 -61
- data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +0 -32
- data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +0 -29
- data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +0 -35
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +0 -65
- data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +0 -43
- data/spec/models/spree/return_item_spec.rb +0 -731
- data/spec/models/spree/returns_calculator_spec.rb +0 -14
- data/spec/models/spree/role_spec.rb +0 -7
- data/spec/models/spree/shipment_spec.rb +0 -742
- data/spec/models/spree/shipping_calculator_spec.rb +0 -45
- data/spec/models/spree/shipping_category_spec.rb +0 -19
- data/spec/models/spree/shipping_method_spec.rb +0 -95
- data/spec/models/spree/shipping_rate_spec.rb +0 -140
- data/spec/models/spree/state_spec.rb +0 -29
- data/spec/models/spree/stock/availability_validator_spec.rb +0 -36
- data/spec/models/spree/stock/content_item_spec.rb +0 -31
- data/spec/models/spree/stock/coordinator_spec.rb +0 -61
- data/spec/models/spree/stock/differentiator_spec.rb +0 -39
- data/spec/models/spree/stock/estimator_spec.rb +0 -202
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +0 -38
- data/spec/models/spree/stock/package_spec.rb +0 -182
- data/spec/models/spree/stock/packer_spec.rb +0 -70
- data/spec/models/spree/stock/prioritizer_spec.rb +0 -125
- data/spec/models/spree/stock/quantifier_spec.rb +0 -126
- data/spec/models/spree/stock/splitter/backordered_spec.rb +0 -29
- data/spec/models/spree/stock/splitter/base_spec.rb +0 -21
- data/spec/models/spree/stock/splitter/shipping_category_spec.rb +0 -47
- data/spec/models/spree/stock/splitter/weight_spec.rb +0 -32
- data/spec/models/spree/stock_item_spec.rb +0 -432
- data/spec/models/spree/stock_location_spec.rb +0 -243
- data/spec/models/spree/stock_movement_spec.rb +0 -120
- data/spec/models/spree/stock_transfer_spec.rb +0 -50
- data/spec/models/spree/store_credit_event_spec.rb +0 -101
- data/spec/models/spree/store_credit_spec.rb +0 -786
- data/spec/models/spree/store_spec.rb +0 -78
- data/spec/models/spree/tax_category_spec.rb +0 -32
- data/spec/models/spree/tax_rate_spec.rb +0 -561
- data/spec/models/spree/taxon_spec.rb +0 -85
- data/spec/models/spree/taxonomy_spec.rb +0 -18
- data/spec/models/spree/tracker_spec.rb +0 -21
- data/spec/models/spree/user_spec.rb +0 -203
- data/spec/models/spree/variant_spec.rb +0 -818
- data/spec/models/spree/zone_member_spec.rb +0 -38
- data/spec/models/spree/zone_spec.rb +0 -472
- data/spec/spec_helper.rb +0 -79
- data/spec/support/big_decimal.rb +0 -5
- data/spec/support/concerns/adjustment_source.rb +0 -23
- data/spec/support/concerns/default_price.rb +0 -37
- data/spec/support/rake.rb +0 -13
- data/spec/support/test_gateway.rb +0 -2
|
@@ -1,85 +0,0 @@
|
|
|
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
|
-
it "stores old slugs in FriendlyIds history" do
|
|
27
|
-
# Stub out unrelated methods that cannot handle a save without an id
|
|
28
|
-
allow(subject).to receive(:set_depth!)
|
|
29
|
-
# create_slug is a private method, included by FriendlyId::History
|
|
30
|
-
# it's effect is rather complex and dependent on state and config.
|
|
31
|
-
# However, when a new slug is set, it should call slugs.create!
|
|
32
|
-
expect(subject.slugs).to receive(:create!)
|
|
33
|
-
subject.permalink = "custom-slug"
|
|
34
|
-
subject.run_callbacks :save
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context "with parent taxon" do
|
|
38
|
-
let(:parent) { FactoryGirl.build(:taxon, permalink: "brands") }
|
|
39
|
-
before { allow(taxon).to receive_messages parent: parent }
|
|
40
|
-
|
|
41
|
-
it "should set permalink correctly when taxon has parent" do
|
|
42
|
-
taxon.set_permalink
|
|
43
|
-
expect(taxon.permalink).to eql "brands/ruby-on-rails"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "should set permalink correctly with existing permalink present" do
|
|
47
|
-
taxon.permalink = "b/rubyonrails"
|
|
48
|
-
taxon.set_permalink
|
|
49
|
-
expect(taxon.permalink).to eql "brands/rubyonrails"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "should support Chinese characters" do
|
|
53
|
-
taxon.name = "我"
|
|
54
|
-
taxon.set_permalink
|
|
55
|
-
expect(taxon.permalink).to eql "brands/wo"
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Regression test for #3390
|
|
59
|
-
context "setting a new node sibling position via :child_index=" do
|
|
60
|
-
let(:idx) { rand(0..100) }
|
|
61
|
-
before { allow(parent).to receive(:move_to_child_with_index) }
|
|
62
|
-
|
|
63
|
-
context "taxon is not new" do
|
|
64
|
-
before { allow(taxon).to receive(:new_record?).and_return(false) }
|
|
65
|
-
|
|
66
|
-
it "passes the desired index move_to_child_with_index of :parent " do
|
|
67
|
-
expect(taxon).to receive(:move_to_child_with_index).with(parent, idx)
|
|
68
|
-
|
|
69
|
-
taxon.child_index = idx
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Regression test for #2620
|
|
78
|
-
context "creating a child node using first_or_create" do
|
|
79
|
-
let(:taxonomy) { create(:taxonomy) }
|
|
80
|
-
|
|
81
|
-
it "does not error out" do
|
|
82
|
-
expect { taxonomy.root.children.unscoped.where(name: "Some name").first_or_create }.not_to raise_error
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
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
|
-
|
|
@@ -1,21 +0,0 @@
|
|
|
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
|
|
@@ -1,203 +0,0 @@
|
|
|
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
|
-
Timecop.scale(3600) do
|
|
15
|
-
order_1
|
|
16
|
-
order_2
|
|
17
|
-
order_3
|
|
18
|
-
|
|
19
|
-
expect(user.last_incomplete_spree_order).to eq order_3
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context 'persists order address' do
|
|
24
|
-
it 'copies over order addresses' do
|
|
25
|
-
expect do
|
|
26
|
-
user.persist_order_address(order)
|
|
27
|
-
end.to change { Spree::Address.count }.by(2)
|
|
28
|
-
|
|
29
|
-
expect(user.bill_address).to eq order.bill_address
|
|
30
|
-
expect(user.ship_address).to eq order.ship_address
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it 'doesnt create new addresses if user has already' do
|
|
34
|
-
user.update_column(:bill_address_id, create(:address).id)
|
|
35
|
-
user.update_column(:ship_address_id, create(:address).id)
|
|
36
|
-
user.reload
|
|
37
|
-
|
|
38
|
-
expect do
|
|
39
|
-
user.persist_order_address(order)
|
|
40
|
-
end.not_to change { Spree::Address.count }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
it 'set both bill and ship address id on subject' do
|
|
44
|
-
user.persist_order_address(order)
|
|
45
|
-
|
|
46
|
-
expect(user.bill_address_id).not_to be_blank
|
|
47
|
-
expect(user.ship_address_id).not_to be_blank
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
context 'payment source' do
|
|
52
|
-
let(:payment_method) { create(:credit_card_payment_method) }
|
|
53
|
-
let!(:cc) do
|
|
54
|
-
create(:credit_card, user_id: user.id, payment_method: payment_method, gateway_customer_profile_id: "2342343")
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it 'has payment sources' do
|
|
58
|
-
expect(user.payment_sources.first.gateway_customer_profile_id).not_to be_empty
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it 'drops payment source' do
|
|
62
|
-
user.drop_payment_source cc
|
|
63
|
-
expect(cc.gateway_customer_profile_id).to be_nil
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
describe Spree.user_class, type: :model do
|
|
70
|
-
context 'reporting' do
|
|
71
|
-
let(:order_value) { BigDecimal.new('80.94') }
|
|
72
|
-
let(:order_count) { 4 }
|
|
73
|
-
let(:orders) { Array.new(order_count, double(total: order_value)) }
|
|
74
|
-
|
|
75
|
-
before do
|
|
76
|
-
allow(orders).to receive(:sum).with(:total).and_return(orders.sum(&:total))
|
|
77
|
-
allow(orders).to receive(:count).and_return(orders.length)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def load_orders
|
|
81
|
-
allow(subject).to receive(:orders).and_return(double(complete: orders))
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
describe '#lifetime_value' do
|
|
85
|
-
context 'with orders' do
|
|
86
|
-
before { load_orders }
|
|
87
|
-
it "returns the total of completed orders for the user" do
|
|
88
|
-
expect(subject.lifetime_value).to eq (order_count * order_value)
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
context 'without orders' do
|
|
92
|
-
it 'returns 0.00' do
|
|
93
|
-
expect(subject.lifetime_value).to eq BigDecimal("0.00")
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
describe '#display_lifetime_value' do
|
|
99
|
-
it 'returns a Spree::Money version of lifetime_value' do
|
|
100
|
-
value = BigDecimal('500.05')
|
|
101
|
-
allow(subject).to receive(:lifetime_value).and_return(value)
|
|
102
|
-
expect(subject.display_lifetime_value).to eq Spree::Money.new(value)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
describe '#order_count' do
|
|
107
|
-
before { load_orders }
|
|
108
|
-
it 'returns the count of completed orders for the user' do
|
|
109
|
-
expect(subject.order_count).to eq BigDecimal(order_count)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
describe '#average_order_value' do
|
|
114
|
-
context 'with orders' do
|
|
115
|
-
before { load_orders }
|
|
116
|
-
it 'returns the average completed order price for the user' do
|
|
117
|
-
expect(subject.average_order_value).to eq order_value
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
context 'without orders' do
|
|
121
|
-
it 'returns 0.00' do
|
|
122
|
-
expect(subject.average_order_value).to eq BigDecimal('0.00')
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
describe "#display_average_order_value" do
|
|
128
|
-
before { load_orders }
|
|
129
|
-
it 'returns a Spree::Money version of average_order_value' do
|
|
130
|
-
value = BigDecimal('500.05')
|
|
131
|
-
allow(subject).to receive(:average_order_value).and_return(value)
|
|
132
|
-
expect(subject.display_average_order_value).to eq Spree::Money.new(value)
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
describe '#total_available_store_credit' do
|
|
138
|
-
context 'user does not have any associated store credits' do
|
|
139
|
-
subject { create(:user) }
|
|
140
|
-
|
|
141
|
-
it 'returns 0' do
|
|
142
|
-
expect(subject.total_available_store_credit).to be_zero
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
context 'user has several associated store credits' do
|
|
147
|
-
let(:user) { create(:user) }
|
|
148
|
-
let(:amount) { 120.25 }
|
|
149
|
-
let(:additional_amount) { 55.75 }
|
|
150
|
-
let(:store_credit) { create(:store_credit, user: user, amount: amount, amount_used: 0.0) }
|
|
151
|
-
let!(:additional_store_credit) { create(:store_credit, user: user, amount: additional_amount, amount_used: 0.0) }
|
|
152
|
-
|
|
153
|
-
subject { store_credit.user }
|
|
154
|
-
|
|
155
|
-
context 'part of the store credit has been used' do
|
|
156
|
-
let(:amount_used) { 35.00 }
|
|
157
|
-
|
|
158
|
-
before { store_credit.update_attributes(amount_used: amount_used) }
|
|
159
|
-
|
|
160
|
-
context 'part of the store credit has been authorized' do
|
|
161
|
-
let(:authorized_amount) { 10 }
|
|
162
|
-
|
|
163
|
-
before { additional_store_credit.update_attributes(amount_authorized: authorized_amount) }
|
|
164
|
-
|
|
165
|
-
it 'returns sum of amounts minus used amount and authorized amount' do
|
|
166
|
-
available_store_credit = amount + additional_amount - amount_used - authorized_amount
|
|
167
|
-
expect(subject.total_available_store_credit.to_f).to eq available_store_credit
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
context 'there are no authorized amounts on any of the store credits' do
|
|
172
|
-
it 'returns sum of amounts minus used amount' do
|
|
173
|
-
expect(subject.total_available_store_credit.to_f).to eq (amount + additional_amount - amount_used)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
context 'store credits have never been used' do
|
|
179
|
-
context 'part of the store credit has been authorized' do
|
|
180
|
-
let(:authorized_amount) { 10 }
|
|
181
|
-
|
|
182
|
-
before { additional_store_credit.update_attributes(amount_authorized: authorized_amount) }
|
|
183
|
-
|
|
184
|
-
it 'returns sum of amounts minus authorized amount' do
|
|
185
|
-
expect(subject.total_available_store_credit.to_f).to eq (amount + additional_amount - authorized_amount)
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
context 'there are no authorized amounts on any of the store credits' do
|
|
190
|
-
it 'returns sum of amounts' do
|
|
191
|
-
expect(subject.total_available_store_credit.to_f).to eq (amount + additional_amount)
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
context 'all store credits have never been used or authorized' do
|
|
197
|
-
it 'returns sum of amounts' do
|
|
198
|
-
expect(subject.total_available_store_credit.to_f).to eq (amount + additional_amount)
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
end
|
|
@@ -1,818 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
describe Spree::Variant, type: :model do
|
|
6
|
-
let!(:variant) { create(:variant) }
|
|
7
|
-
let(:master_variant) { create(:master_variant) }
|
|
8
|
-
|
|
9
|
-
it_behaves_like 'default_price'
|
|
10
|
-
|
|
11
|
-
describe 'validations' do
|
|
12
|
-
it { expect(master_variant).to_not validate_presence_of(:option_values) }
|
|
13
|
-
it { expect(variant).to validate_presence_of(:option_values) }
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context 'sorting' do
|
|
17
|
-
it 'responds to set_list_position' do
|
|
18
|
-
expect(variant.respond_to?(:set_list_position)).to eq(true)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context "validations" do
|
|
23
|
-
it "should validate price is greater than 0" do
|
|
24
|
-
variant.price = -1
|
|
25
|
-
expect(variant).to be_invalid
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "should validate price is 0" do
|
|
29
|
-
variant.price = 0
|
|
30
|
-
expect(variant).to be_valid
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
context "after create" do
|
|
35
|
-
let!(:product) { create(:product) }
|
|
36
|
-
|
|
37
|
-
it "propagate to stock items" do
|
|
38
|
-
expect_any_instance_of(Spree::StockLocation).to receive(:propagate_variant)
|
|
39
|
-
create(:variant, product: product)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
context "stock location has disable propagate all variants" do
|
|
43
|
-
before { Spree::StockLocation.update_all propagate_all_variants: false }
|
|
44
|
-
|
|
45
|
-
it "propagate to stock items" do
|
|
46
|
-
expect_any_instance_of(Spree::StockLocation).not_to receive(:propagate_variant)
|
|
47
|
-
product.variants.create(name: "Foobar")
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
describe 'mark_master_out_of_stock' do
|
|
52
|
-
before do
|
|
53
|
-
product.master.stock_items.first.set_count_on_hand(5)
|
|
54
|
-
end
|
|
55
|
-
context 'when product is created without variants but with stock' do
|
|
56
|
-
it { expect(product.master).to be_in_stock }
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
context 'when a variant is created' do
|
|
60
|
-
let!(:new_variant) { create(:variant, product: product) }
|
|
61
|
-
|
|
62
|
-
it { expect(product.master).to_not be_in_stock }
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
describe 'scope' do
|
|
68
|
-
describe '.not_discontinued' do
|
|
69
|
-
context 'when discontinued' do
|
|
70
|
-
let!(:discontinued_variant) { create(:variant, discontinue_on: Time.current - 1.day) }
|
|
71
|
-
|
|
72
|
-
it { expect(Spree::Variant.not_discontinued).not_to include(discontinued_variant) }
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
context 'when not discontinued' do
|
|
76
|
-
let!(:variant_2) { create(:variant, discontinue_on: Time.current + 1.day) }
|
|
77
|
-
|
|
78
|
-
it { expect(Spree::Variant.not_discontinued).to include(variant_2) }
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
context 'when discontinue_on not present' do
|
|
82
|
-
let!(:variant_2) { create(:variant, discontinue_on: nil) }
|
|
83
|
-
|
|
84
|
-
it { expect(Spree::Variant.not_discontinued).to include(variant_2) }
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
describe '.not_deleted' do
|
|
89
|
-
context 'when deleted' do
|
|
90
|
-
let!(:deleted_variant) { create(:variant, deleted_at: Time.current) }
|
|
91
|
-
|
|
92
|
-
it { expect(Spree::Variant.not_deleted).not_to include(deleted_variant) }
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
context 'when not deleted' do
|
|
96
|
-
let!(:variant_2) { create(:variant, deleted_at: nil) }
|
|
97
|
-
|
|
98
|
-
it { expect(Spree::Variant.not_deleted).to include(variant_2) }
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
describe '.for_currency_and_available_price_amount' do
|
|
103
|
-
let(:currency) { 'EUR' }
|
|
104
|
-
|
|
105
|
-
context 'when price with currency present' do
|
|
106
|
-
context 'when price has amount' do
|
|
107
|
-
let!(:price_1) { create(:price, currency: currency, variant: variant, amount: 10) }
|
|
108
|
-
|
|
109
|
-
it { expect(Spree::Variant.for_currency_and_available_price_amount(currency)).to include(variant) }
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
context 'when price do not have amount' do
|
|
113
|
-
let!(:price_1) { create(:price, currency: currency, variant: variant, amount: nil) }
|
|
114
|
-
|
|
115
|
-
it { expect(Spree::Variant.for_currency_and_available_price_amount(currency)).not_to include(variant) }
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
context 'when price with currency not present' do
|
|
120
|
-
let!(:unavailable_currency) { 'INR' }
|
|
121
|
-
context 'when price has amount' do
|
|
122
|
-
let!(:price_1) { create(:price, currency: unavailable_currency, variant: variant, amount: 10) }
|
|
123
|
-
|
|
124
|
-
it { expect(Spree::Variant.for_currency_and_available_price_amount(currency)).not_to include(variant) }
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
context 'when price do not have amount' do
|
|
128
|
-
let!(:price_1) { create(:price, currency: unavailable_currency, variant: variant, amount: nil) }
|
|
129
|
-
|
|
130
|
-
it { expect(Spree::Variant.for_currency_and_available_price_amount(currency)).not_to include(variant) }
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
context 'when multiple prices for same currency present' do
|
|
135
|
-
let!(:price_1) { create(:price, currency: currency, variant: variant) }
|
|
136
|
-
let!(:price_2) { create(:price, currency: currency, variant: variant) }
|
|
137
|
-
|
|
138
|
-
it 'should not duplicate variant' do
|
|
139
|
-
expect(Spree::Variant.for_currency_and_available_price_amount(currency)).to eq([variant])
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
describe '.active' do
|
|
145
|
-
let!(:variants) { [variant] }
|
|
146
|
-
let!(:currency) { 'EUR' }
|
|
147
|
-
|
|
148
|
-
before(:each) do
|
|
149
|
-
allow(Spree::Variant).to receive(:not_discontinued).and_return(variants)
|
|
150
|
-
allow(variants).to receive(:not_deleted).and_return(variants)
|
|
151
|
-
allow(variants).to receive(:for_currency_and_available_price_amount).with(currency).and_return(variants)
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
it 'should find not_discontinued variants' do
|
|
155
|
-
expect(Spree::Variant).to receive(:not_discontinued).and_return(variants)
|
|
156
|
-
Spree::Variant.active(currency)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it 'should find not_deleted variants' do
|
|
160
|
-
expect(variants).to receive(:not_deleted).and_return(variants)
|
|
161
|
-
Spree::Variant.active(currency)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
it 'should find variants for_currency_and_available_price_amount' do
|
|
165
|
-
expect(variants).to receive(:for_currency_and_available_price_amount).with(currency).and_return(variants)
|
|
166
|
-
Spree::Variant.active(currency)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
it { expect(Spree::Variant.active(currency)).to eq(variants) }
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
context "product has other variants" do
|
|
174
|
-
describe "option value accessors" do
|
|
175
|
-
before {
|
|
176
|
-
@multi_variant = FactoryGirl.create :variant, product: variant.product
|
|
177
|
-
variant.product.reload
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
let(:multi_variant) { @multi_variant }
|
|
181
|
-
|
|
182
|
-
it "should set option value" do
|
|
183
|
-
expect(multi_variant.option_value('media_type')).to be_nil
|
|
184
|
-
|
|
185
|
-
multi_variant.set_option_value('media_type', 'DVD')
|
|
186
|
-
expect(multi_variant.option_value('media_type')).to eql 'DVD'
|
|
187
|
-
|
|
188
|
-
multi_variant.set_option_value('media_type', 'CD')
|
|
189
|
-
expect(multi_variant.option_value('media_type')).to eql 'CD'
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
it "should not duplicate associated option values when set multiple times" do
|
|
193
|
-
multi_variant.set_option_value('media_type', 'CD')
|
|
194
|
-
|
|
195
|
-
expect {
|
|
196
|
-
multi_variant.set_option_value('media_type', 'DVD')
|
|
197
|
-
}.to_not change(multi_variant.option_values, :count)
|
|
198
|
-
|
|
199
|
-
expect {
|
|
200
|
-
multi_variant.set_option_value('coolness_type', 'awesome')
|
|
201
|
-
}.to change(multi_variant.option_values, :count).by(1)
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
context "product has other variants" do
|
|
206
|
-
describe "option value accessors" do
|
|
207
|
-
before {
|
|
208
|
-
@multi_variant = create(:variant, product: variant.product)
|
|
209
|
-
variant.product.reload
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
let(:multi_variant) { @multi_variant }
|
|
213
|
-
|
|
214
|
-
it "should set option value" do
|
|
215
|
-
expect(multi_variant.option_value('media_type')).to be_nil
|
|
216
|
-
|
|
217
|
-
multi_variant.set_option_value('media_type', 'DVD')
|
|
218
|
-
expect(multi_variant.option_value('media_type')).to eql 'DVD'
|
|
219
|
-
|
|
220
|
-
multi_variant.set_option_value('media_type', 'CD')
|
|
221
|
-
expect(multi_variant.option_value('media_type')).to eql 'CD'
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
it "should not duplicate associated option values when set multiple times" do
|
|
225
|
-
multi_variant.set_option_value('media_type', 'CD')
|
|
226
|
-
|
|
227
|
-
expect {
|
|
228
|
-
multi_variant.set_option_value('media_type', 'DVD')
|
|
229
|
-
}.to_not change(multi_variant.option_values, :count)
|
|
230
|
-
|
|
231
|
-
expect {
|
|
232
|
-
multi_variant.set_option_value('coolness_type', 'awesome')
|
|
233
|
-
}.to change(multi_variant.option_values, :count).by(1)
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
context "#cost_price=" do
|
|
240
|
-
it "should use LocalizedNumber.parse" do
|
|
241
|
-
expect(Spree::LocalizedNumber).to receive(:parse).with('1,599.99')
|
|
242
|
-
subject.cost_price = '1,599.99'
|
|
243
|
-
end
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
context "#price=" do
|
|
247
|
-
it "should use LocalizedNumber.parse" do
|
|
248
|
-
expect(Spree::LocalizedNumber).to receive(:parse).with('1,599.99')
|
|
249
|
-
subject.price = '1,599.99'
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
context "#weight=" do
|
|
254
|
-
it "should use LocalizedNumber.parse" do
|
|
255
|
-
expect(Spree::LocalizedNumber).to receive(:parse).with('1,599.99')
|
|
256
|
-
subject.weight = '1,599.99'
|
|
257
|
-
end
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
context "#currency" do
|
|
261
|
-
it "returns the globally configured currency" do
|
|
262
|
-
expect(variant.currency).to eql "USD"
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
context "#display_amount" do
|
|
267
|
-
it "returns a Spree::Money" do
|
|
268
|
-
variant.price = 21.22
|
|
269
|
-
expect(variant.display_amount.to_s).to eql "$21.22"
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
context "#cost_currency" do
|
|
274
|
-
context "when cost currency is nil" do
|
|
275
|
-
before { variant.cost_currency = nil }
|
|
276
|
-
it "populates cost currency with the default value on save" do
|
|
277
|
-
variant.save!
|
|
278
|
-
expect(variant.cost_currency).to eql "USD"
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
describe '.price_in' do
|
|
284
|
-
before do
|
|
285
|
-
variant.prices << create(:price, variant: variant, currency: "EUR", amount: 33.33)
|
|
286
|
-
end
|
|
287
|
-
subject { variant.price_in(currency).display_amount }
|
|
288
|
-
|
|
289
|
-
context "when currency is not specified" do
|
|
290
|
-
let(:currency) { nil }
|
|
291
|
-
|
|
292
|
-
it "returns 0" do
|
|
293
|
-
expect(subject.to_s).to eql "$0.00"
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
context "when currency is EUR" do
|
|
298
|
-
let(:currency) { 'EUR' }
|
|
299
|
-
|
|
300
|
-
it "returns the value in the EUR" do
|
|
301
|
-
expect(subject.to_s).to eql "€33.33"
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
context "when currency is USD" do
|
|
306
|
-
let(:currency) { 'USD' }
|
|
307
|
-
|
|
308
|
-
it "returns the value in the USD" do
|
|
309
|
-
expect(subject.to_s).to eql "$19.99"
|
|
310
|
-
end
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
describe '.amount_in' do
|
|
315
|
-
before do
|
|
316
|
-
variant.prices << create(:price, variant: variant, currency: "EUR", amount: 33.33)
|
|
317
|
-
end
|
|
318
|
-
|
|
319
|
-
subject { variant.amount_in(currency) }
|
|
320
|
-
|
|
321
|
-
context "when currency is not specified" do
|
|
322
|
-
let(:currency) { nil }
|
|
323
|
-
|
|
324
|
-
it "returns nil" do
|
|
325
|
-
expect(subject).to be_nil
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
context "when currency is EUR" do
|
|
330
|
-
let(:currency) { 'EUR' }
|
|
331
|
-
|
|
332
|
-
it "returns the value in the EUR" do
|
|
333
|
-
expect(subject).to eql 33.33
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
context "when currency is USD" do
|
|
338
|
-
let(:currency) { 'USD' }
|
|
339
|
-
|
|
340
|
-
it "returns the value in the USD" do
|
|
341
|
-
expect(subject).to eql 19.99
|
|
342
|
-
end
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
# Regression test for #2432
|
|
347
|
-
describe 'options_text' do
|
|
348
|
-
let!(:variant) { build(:variant, option_values: []) }
|
|
349
|
-
let!(:master) { create(:master_variant) }
|
|
350
|
-
|
|
351
|
-
before do
|
|
352
|
-
# Order bar than foo
|
|
353
|
-
variant.option_values << create(:option_value, {name: 'Foo', presentation: 'Foo', option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')})
|
|
354
|
-
variant.option_values << create(:option_value, {name: 'Bar', presentation: 'Bar', option_type: create(:option_type, position: 1, name: 'Bar Type', presentation: 'Bar Type')})
|
|
355
|
-
variant.save
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
it 'should order by bar than foo' do
|
|
359
|
-
expect(variant.options_text).to eql 'Bar Type: Bar, Foo Type: Foo'
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
describe 'exchange_name' do
|
|
365
|
-
let!(:variant) { build(:variant, option_values: []) }
|
|
366
|
-
let!(:master) { create(:master_variant) }
|
|
367
|
-
|
|
368
|
-
before do
|
|
369
|
-
variant.option_values << create(:option_value, {
|
|
370
|
-
name: 'Foo',
|
|
371
|
-
presentation: 'Foo',
|
|
372
|
-
option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')
|
|
373
|
-
})
|
|
374
|
-
variant.save
|
|
375
|
-
end
|
|
376
|
-
|
|
377
|
-
context 'master variant' do
|
|
378
|
-
it 'should return name' do
|
|
379
|
-
expect(master.exchange_name).to eql master.name
|
|
380
|
-
end
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
context 'variant' do
|
|
384
|
-
it 'should return options text' do
|
|
385
|
-
expect(variant.exchange_name).to eql 'Foo Type: Foo'
|
|
386
|
-
end
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
describe 'exchange_name' do
|
|
392
|
-
let!(:variant) { build(:variant, option_values: []) }
|
|
393
|
-
let!(:master) { create(:master_variant) }
|
|
394
|
-
|
|
395
|
-
before do
|
|
396
|
-
variant.option_values << create(:option_value, {
|
|
397
|
-
name: 'Foo',
|
|
398
|
-
presentation: 'Foo',
|
|
399
|
-
option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')
|
|
400
|
-
})
|
|
401
|
-
variant.save
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
context 'master variant' do
|
|
405
|
-
it 'should return name' do
|
|
406
|
-
expect(master.exchange_name).to eql master.name
|
|
407
|
-
end
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
context 'variant' do
|
|
411
|
-
it 'should return options text' do
|
|
412
|
-
expect(variant.exchange_name).to eql 'Foo Type: Foo'
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
end
|
|
417
|
-
|
|
418
|
-
describe 'descriptive_name' do
|
|
419
|
-
let!(:variant) { build(:variant, option_values: []) }
|
|
420
|
-
let!(:master) { create(:master_variant) }
|
|
421
|
-
|
|
422
|
-
before do
|
|
423
|
-
variant.option_values << create(:option_value, {
|
|
424
|
-
name: 'Foo',
|
|
425
|
-
presentation: 'Foo',
|
|
426
|
-
option_type: create(:option_type, position: 2, name: 'Foo Type', presentation: 'Foo Type')
|
|
427
|
-
})
|
|
428
|
-
variant.save
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
context 'master variant' do
|
|
432
|
-
it 'should return name with Master identifier' do
|
|
433
|
-
expect(master.descriptive_name).to eql master.name + ' - Master'
|
|
434
|
-
end
|
|
435
|
-
end
|
|
436
|
-
|
|
437
|
-
context 'variant' do
|
|
438
|
-
it 'should return options text with name' do
|
|
439
|
-
expect(variant.descriptive_name).to eql variant.name + ' - Foo Type: Foo'
|
|
440
|
-
end
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
end
|
|
444
|
-
|
|
445
|
-
# Regression test for #2744
|
|
446
|
-
describe "set_position" do
|
|
447
|
-
it "sets variant position after creation" do
|
|
448
|
-
variant = create(:variant)
|
|
449
|
-
expect(variant.position).to_not be_nil
|
|
450
|
-
end
|
|
451
|
-
end
|
|
452
|
-
|
|
453
|
-
describe '#in_stock?' do
|
|
454
|
-
before do
|
|
455
|
-
Spree::Config.track_inventory_levels = true
|
|
456
|
-
end
|
|
457
|
-
|
|
458
|
-
context 'when stock_items are not backorderable' do
|
|
459
|
-
before do
|
|
460
|
-
allow_any_instance_of(Spree::StockItem).to receive_messages(backorderable: false)
|
|
461
|
-
end
|
|
462
|
-
|
|
463
|
-
context 'when stock_items in stock' do
|
|
464
|
-
before do
|
|
465
|
-
variant.stock_items.first.update_column(:count_on_hand, 10)
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
it 'returns true if stock_items in stock' do
|
|
469
|
-
expect(variant.in_stock?).to be true
|
|
470
|
-
end
|
|
471
|
-
end
|
|
472
|
-
|
|
473
|
-
context 'when stock_items out of stock' do
|
|
474
|
-
before do
|
|
475
|
-
allow_any_instance_of(Spree::StockItem).to receive_messages(backorderable: false)
|
|
476
|
-
allow_any_instance_of(Spree::StockItem).to receive_messages(count_on_hand: 0)
|
|
477
|
-
end
|
|
478
|
-
|
|
479
|
-
it 'return false if stock_items out of stock' do
|
|
480
|
-
expect(variant.in_stock?).to be false
|
|
481
|
-
end
|
|
482
|
-
end
|
|
483
|
-
end
|
|
484
|
-
|
|
485
|
-
describe "#can_supply?" do
|
|
486
|
-
it "calls out to quantifier" do
|
|
487
|
-
expect(Spree::Stock::Quantifier).to receive(:new).and_return(quantifier = double)
|
|
488
|
-
expect(quantifier).to receive(:can_supply?).with(10)
|
|
489
|
-
variant.can_supply?(10)
|
|
490
|
-
end
|
|
491
|
-
end
|
|
492
|
-
|
|
493
|
-
context 'when stock_items are backorderable' do
|
|
494
|
-
before do
|
|
495
|
-
allow_any_instance_of(Spree::StockItem).to receive_messages(backorderable: true)
|
|
496
|
-
end
|
|
497
|
-
|
|
498
|
-
context 'when stock_items out of stock' do
|
|
499
|
-
before do
|
|
500
|
-
allow_any_instance_of(Spree::StockItem).to receive_messages(count_on_hand: 0)
|
|
501
|
-
end
|
|
502
|
-
|
|
503
|
-
it 'in_stock? returns false' do
|
|
504
|
-
expect(variant.in_stock?).to be false
|
|
505
|
-
end
|
|
506
|
-
|
|
507
|
-
it 'can_supply? return true' do
|
|
508
|
-
expect(variant.can_supply?).to be true
|
|
509
|
-
end
|
|
510
|
-
end
|
|
511
|
-
end
|
|
512
|
-
end
|
|
513
|
-
|
|
514
|
-
describe '#is_backorderable' do
|
|
515
|
-
let(:variant) { build(:variant) }
|
|
516
|
-
subject { variant.is_backorderable? }
|
|
517
|
-
|
|
518
|
-
it 'should invoke Spree::Stock::Quantifier' do
|
|
519
|
-
expect_any_instance_of(Spree::Stock::Quantifier).to receive(:backorderable?) { true }
|
|
520
|
-
subject
|
|
521
|
-
end
|
|
522
|
-
end
|
|
523
|
-
|
|
524
|
-
describe '#total_on_hand' do
|
|
525
|
-
it 'should be infinite if track_inventory_levels is false' do
|
|
526
|
-
Spree::Config[:track_inventory_levels] = false
|
|
527
|
-
expect(build(:variant).total_on_hand).to eql(Float::INFINITY)
|
|
528
|
-
end
|
|
529
|
-
|
|
530
|
-
it 'should match quantifier total_on_hand' do
|
|
531
|
-
variant = build(:variant)
|
|
532
|
-
expect(variant.total_on_hand).to eq(Spree::Stock::Quantifier.new(variant).total_on_hand)
|
|
533
|
-
end
|
|
534
|
-
end
|
|
535
|
-
|
|
536
|
-
describe '#tax_category' do
|
|
537
|
-
context 'when tax_category is nil' do
|
|
538
|
-
let(:product) { build(:product) }
|
|
539
|
-
let(:variant) { build(:variant, product: product, tax_category_id: nil) }
|
|
540
|
-
it 'returns the parent products tax_category' do
|
|
541
|
-
expect(variant.tax_category).to eq(product.tax_category)
|
|
542
|
-
end
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
context 'when tax_category is set' do
|
|
546
|
-
let(:tax_category) { create(:tax_category) }
|
|
547
|
-
let(:variant) { build(:variant, tax_category: tax_category) }
|
|
548
|
-
it 'returns the tax_category set on itself' do
|
|
549
|
-
expect(variant.tax_category).to eq(tax_category)
|
|
550
|
-
end
|
|
551
|
-
end
|
|
552
|
-
end
|
|
553
|
-
|
|
554
|
-
describe "touching" do
|
|
555
|
-
it "updates a product" do
|
|
556
|
-
variant.product.update_column(:updated_at, 1.day.ago)
|
|
557
|
-
variant.touch
|
|
558
|
-
expect(variant.product.reload.updated_at).to be_within(3.seconds).of(Time.current)
|
|
559
|
-
end
|
|
560
|
-
|
|
561
|
-
it "clears the in_stock cache key" do
|
|
562
|
-
expect(Rails.cache).to receive(:delete).with(variant.send(:in_stock_cache_key))
|
|
563
|
-
variant.touch
|
|
564
|
-
end
|
|
565
|
-
end
|
|
566
|
-
|
|
567
|
-
describe "#should_track_inventory?" do
|
|
568
|
-
|
|
569
|
-
it 'should not track inventory when global setting is off' do
|
|
570
|
-
Spree::Config[:track_inventory_levels] = false
|
|
571
|
-
|
|
572
|
-
expect(build(:variant).should_track_inventory?).to eq(false)
|
|
573
|
-
end
|
|
574
|
-
|
|
575
|
-
it 'should not track inventory when variant is turned off' do
|
|
576
|
-
Spree::Config[:track_inventory_levels] = true
|
|
577
|
-
|
|
578
|
-
expect(build(:on_demand_variant).should_track_inventory?).to eq(false)
|
|
579
|
-
end
|
|
580
|
-
|
|
581
|
-
it 'should track inventory when global and variant are on' do
|
|
582
|
-
Spree::Config[:track_inventory_levels] = true
|
|
583
|
-
|
|
584
|
-
expect(build(:variant).should_track_inventory?).to eq(true)
|
|
585
|
-
end
|
|
586
|
-
end
|
|
587
|
-
|
|
588
|
-
describe "deleted_at scope" do
|
|
589
|
-
before { variant.destroy && variant.reload }
|
|
590
|
-
it "should have a price if deleted" do
|
|
591
|
-
variant.price = 10
|
|
592
|
-
expect(variant.price).to eq(10)
|
|
593
|
-
end
|
|
594
|
-
end
|
|
595
|
-
|
|
596
|
-
describe "stock movements" do
|
|
597
|
-
let!(:movement) { create(:stock_movement, stock_item: variant.stock_items.first) }
|
|
598
|
-
|
|
599
|
-
it "builds out collection just fine through stock items" do
|
|
600
|
-
expect(variant.stock_movements.to_a).not_to be_empty
|
|
601
|
-
end
|
|
602
|
-
end
|
|
603
|
-
|
|
604
|
-
describe "in_stock scope" do
|
|
605
|
-
it "returns all in stock variants" do
|
|
606
|
-
in_stock_variant = create(:variant)
|
|
607
|
-
out_of_stock_variant = create(:variant)
|
|
608
|
-
|
|
609
|
-
in_stock_variant.stock_items.first.update_column(:count_on_hand, 10)
|
|
610
|
-
|
|
611
|
-
expect(Spree::Variant.in_stock).to eq [in_stock_variant]
|
|
612
|
-
end
|
|
613
|
-
end
|
|
614
|
-
|
|
615
|
-
context "#volume" do
|
|
616
|
-
let(:variant_zero_width) { create(:variant, width: 0) }
|
|
617
|
-
let(:variant) { create(:variant) }
|
|
618
|
-
|
|
619
|
-
it "it is zero if any dimension parameter is zero" do
|
|
620
|
-
expect(variant_zero_width.volume).to eq 0
|
|
621
|
-
end
|
|
622
|
-
|
|
623
|
-
it "return the volume if the dimension parameters are different of zero" do
|
|
624
|
-
volume_expected = variant.width * variant.depth * variant.height
|
|
625
|
-
expect(variant.volume).to eq (volume_expected)
|
|
626
|
-
end
|
|
627
|
-
end
|
|
628
|
-
|
|
629
|
-
context "#dimension" do
|
|
630
|
-
let(:variant) { create(:variant) }
|
|
631
|
-
|
|
632
|
-
it "return the dimension if the dimension parameters are different of zero" do
|
|
633
|
-
dimension_expected = variant.width + variant.depth + variant.height
|
|
634
|
-
expect(variant.dimension).to eq (dimension_expected)
|
|
635
|
-
end
|
|
636
|
-
end
|
|
637
|
-
|
|
638
|
-
context "#discontinue!" do
|
|
639
|
-
let(:variant) { create(:variant) }
|
|
640
|
-
|
|
641
|
-
it "sets the discontinued" do
|
|
642
|
-
variant.discontinue!
|
|
643
|
-
variant.reload
|
|
644
|
-
expect(variant.discontinued?).to be(true)
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
it "changes updated_at" do
|
|
648
|
-
Timecop.scale(1000) do
|
|
649
|
-
expect { variant.discontinue! }.to change { variant.updated_at }
|
|
650
|
-
end
|
|
651
|
-
end
|
|
652
|
-
end
|
|
653
|
-
|
|
654
|
-
context "#discontinued?" do
|
|
655
|
-
let(:variant_live) { build(:variant) }
|
|
656
|
-
it "should be false" do
|
|
657
|
-
expect(variant_live.discontinued?).to be(false)
|
|
658
|
-
end
|
|
659
|
-
|
|
660
|
-
let(:variant_discontinued) { build(:variant, discontinue_on: Time.now - 1.day) }
|
|
661
|
-
it "should be true" do
|
|
662
|
-
expect(variant_discontinued.discontinued?).to be(true)
|
|
663
|
-
end
|
|
664
|
-
end
|
|
665
|
-
|
|
666
|
-
describe "#available?" do
|
|
667
|
-
let(:variant) { create(:variant) }
|
|
668
|
-
context 'when discontinued' do
|
|
669
|
-
before(:each) do
|
|
670
|
-
variant.discontinue_on = Time.current - 1.day
|
|
671
|
-
end
|
|
672
|
-
|
|
673
|
-
context 'when product is available' do
|
|
674
|
-
before(:each) do
|
|
675
|
-
allow(variant.product).to receive(:available?) { true }
|
|
676
|
-
end
|
|
677
|
-
|
|
678
|
-
it { expect(variant.available?).to be(false) }
|
|
679
|
-
end
|
|
680
|
-
|
|
681
|
-
context 'when product is not available' do
|
|
682
|
-
before(:each) do
|
|
683
|
-
allow(variant.product).to receive(:available?) { false }
|
|
684
|
-
end
|
|
685
|
-
|
|
686
|
-
it { expect(variant.available?).to be(false) }
|
|
687
|
-
end
|
|
688
|
-
end
|
|
689
|
-
|
|
690
|
-
context 'when not discontinued' do
|
|
691
|
-
before(:each) do
|
|
692
|
-
variant.discontinue_on = Time.current + 1.day
|
|
693
|
-
end
|
|
694
|
-
|
|
695
|
-
context 'when product is available' do
|
|
696
|
-
before(:each) do
|
|
697
|
-
allow(variant.product).to receive(:available?) { true }
|
|
698
|
-
end
|
|
699
|
-
|
|
700
|
-
it { expect(variant.available?).to be(true) }
|
|
701
|
-
end
|
|
702
|
-
|
|
703
|
-
context 'when product is not available' do
|
|
704
|
-
before(:each) do
|
|
705
|
-
allow(variant.product).to receive(:available?) { false }
|
|
706
|
-
end
|
|
707
|
-
|
|
708
|
-
it { expect(variant.available?).to be(false) }
|
|
709
|
-
end
|
|
710
|
-
end
|
|
711
|
-
end
|
|
712
|
-
|
|
713
|
-
describe "#check_price" do
|
|
714
|
-
let(:variant) { create(:variant) }
|
|
715
|
-
let(:variant2) { create(:variant) }
|
|
716
|
-
|
|
717
|
-
context 'require_master_price set false' do
|
|
718
|
-
before { Spree::Config.set(require_master_price: false) }
|
|
719
|
-
|
|
720
|
-
context 'price present and currency present' do
|
|
721
|
-
it { expect(variant.send(:check_price)).to be(nil) }
|
|
722
|
-
end
|
|
723
|
-
|
|
724
|
-
context 'price present and currency nil' do
|
|
725
|
-
before { variant.currency = nil }
|
|
726
|
-
|
|
727
|
-
it { expect(variant.send(:check_price)).to be(Spree::Config[:currency]) }
|
|
728
|
-
end
|
|
729
|
-
|
|
730
|
-
context 'price nil and currency present' do
|
|
731
|
-
before { variant.price = nil }
|
|
732
|
-
|
|
733
|
-
it { expect(variant.send(:check_price)).to be(nil) }
|
|
734
|
-
end
|
|
735
|
-
|
|
736
|
-
context 'price nil and currency nil' do
|
|
737
|
-
before { variant.price = nil }
|
|
738
|
-
|
|
739
|
-
it { expect(variant.send(:check_price)).to be(nil) }
|
|
740
|
-
end
|
|
741
|
-
end
|
|
742
|
-
|
|
743
|
-
context 'require_master_price set true' do
|
|
744
|
-
before { Spree::Config.set(require_master_price: true) }
|
|
745
|
-
|
|
746
|
-
context 'price present and currency present' do
|
|
747
|
-
it { expect(variant.send(:check_price)).to be(nil) }
|
|
748
|
-
end
|
|
749
|
-
|
|
750
|
-
context 'price present and currency nil' do
|
|
751
|
-
before { variant.currency = nil }
|
|
752
|
-
|
|
753
|
-
it { expect(variant.send(:check_price)).to be(Spree::Config[:currency]) }
|
|
754
|
-
end
|
|
755
|
-
|
|
756
|
-
context 'product and master_variant present and equal' do
|
|
757
|
-
context 'price nil and currency present' do
|
|
758
|
-
before { variant.price = nil }
|
|
759
|
-
it { expect(variant.send(:check_price)).to be(nil) }
|
|
760
|
-
|
|
761
|
-
context 'check variant price' do
|
|
762
|
-
before { variant.send(:check_price) }
|
|
763
|
-
it { expect(variant.price).to eq(variant.product.master.price) }
|
|
764
|
-
end
|
|
765
|
-
end
|
|
766
|
-
|
|
767
|
-
context 'price nil and currency nil' do
|
|
768
|
-
before do
|
|
769
|
-
variant.price = nil
|
|
770
|
-
variant.send(:check_price)
|
|
771
|
-
end
|
|
772
|
-
|
|
773
|
-
it { expect(variant.price).to eq(variant.product.master.price) }
|
|
774
|
-
it { expect(variant.currency).to eq(Spree::Config[:currency]) }
|
|
775
|
-
end
|
|
776
|
-
end
|
|
777
|
-
|
|
778
|
-
context 'product not present' do
|
|
779
|
-
context 'product not present' do
|
|
780
|
-
before { variant.product = nil }
|
|
781
|
-
|
|
782
|
-
context 'price nil and currency present' do
|
|
783
|
-
before { variant.price = nil }
|
|
784
|
-
|
|
785
|
-
it { expect { variant.send(:check_price) }.to raise_error(RuntimeError, 'No master variant found to infer price') }
|
|
786
|
-
end
|
|
787
|
-
|
|
788
|
-
context 'price nil and currency nil' do
|
|
789
|
-
before { variant.price = nil }
|
|
790
|
-
|
|
791
|
-
it { expect { variant.send(:check_price) }.to raise_error(RuntimeError, 'No master variant found to infer price') }
|
|
792
|
-
end
|
|
793
|
-
end
|
|
794
|
-
end
|
|
795
|
-
end
|
|
796
|
-
end
|
|
797
|
-
|
|
798
|
-
describe '#created_at' do
|
|
799
|
-
it 'creates variant with created_at timestamp' do
|
|
800
|
-
expect(variant.created_at).to_not be_nil
|
|
801
|
-
end
|
|
802
|
-
end
|
|
803
|
-
|
|
804
|
-
describe '#updated_at' do
|
|
805
|
-
it 'creates variant with updated_at timestamp' do
|
|
806
|
-
expect(variant.updated_at).to_not be_nil
|
|
807
|
-
end
|
|
808
|
-
end
|
|
809
|
-
|
|
810
|
-
describe '#ensure_no_line_items' do
|
|
811
|
-
let!(:line_item) { create(:line_item, variant: variant) }
|
|
812
|
-
|
|
813
|
-
it 'should add error on product destroy' do
|
|
814
|
-
expect(variant.destroy).to eq false
|
|
815
|
-
expect(variant.errors[:base]).to include Spree.t(:cannot_destroy_if_attached_to_line_items)
|
|
816
|
-
end
|
|
817
|
-
end
|
|
818
|
-
end
|