solidus_core 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/Gemfile +3 -0
- data/Rakefile +16 -0
- data/script/rails +9 -0
- data/solidus_core.gemspec +48 -0
- data/spec/fixtures/thinking-cat.jpg +0 -0
- data/spec/helpers/base_helper_spec.rb +173 -0
- data/spec/helpers/order_helper_spec.rb +12 -0
- data/spec/helpers/products_helper_spec.rb +220 -0
- data/spec/helpers/taxons_helper_spec.rb +17 -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/search/variant_spec.rb +92 -0
- data/spec/lib/spree/core/controller_helpers/auth_spec.rb +66 -0
- data/spec/lib/spree/core/controller_helpers/order_spec.rb +92 -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/current_store_spec.rb +36 -0
- data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
- data/spec/lib/spree/core/importer/order_spec.rb +431 -0
- data/spec/lib/spree/core/role_configuration_spec.rb +138 -0
- data/spec/lib/spree/core/validators/email_spec.rb +48 -0
- data/spec/lib/spree/localized_number_spec.rb +38 -0
- data/spec/lib/spree/migrations_spec.rb +36 -0
- data/spec/lib/spree/money_spec.rb +127 -0
- data/spec/lib/tasks/exchanges_spec.rb +231 -0
- data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +115 -0
- data/spec/lib/tasks/order_capturing_spec.rb +56 -0
- data/spec/mailers/carton_mailer_spec.rb +43 -0
- data/spec/mailers/order_mailer_spec.rb +122 -0
- data/spec/mailers/reimbursement_mailer_spec.rb +40 -0
- data/spec/mailers/test_mailer_spec.rb +15 -0
- data/spec/models/spree/ability_spec.rb +276 -0
- data/spec/models/spree/address_spec.rb +250 -0
- data/spec/models/spree/adjustment_reason_spec.rb +13 -0
- data/spec/models/spree/adjustment_spec.rb +177 -0
- data/spec/models/spree/app_configuration_spec.rb +20 -0
- data/spec/models/spree/asset_spec.rb +24 -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/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 +30 -0
- data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +36 -0
- data/spec/models/spree/calculator/tiered_percent_spec.rb +47 -0
- data/spec/models/spree/calculator_spec.rb +36 -0
- data/spec/models/spree/carton_spec.rb +133 -0
- data/spec/models/spree/classification_spec.rb +15 -0
- data/spec/models/spree/concerns/display_money_spec.rb +43 -0
- data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
- data/spec/models/spree/credit_card_spec.rb +334 -0
- data/spec/models/spree/customer_return_spec.rb +276 -0
- data/spec/models/spree/exchange_spec.rb +79 -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 +82 -0
- data/spec/models/spree/inventory_unit_spec.rb +307 -0
- data/spec/models/spree/item_adjustments_spec.rb +256 -0
- data/spec/models/spree/line_item_spec.rb +191 -0
- data/spec/models/spree/option_type_spec.rb +14 -0
- data/spec/models/spree/option_value_spec.rb +22 -0
- data/spec/models/spree/order/address_spec.rb +50 -0
- data/spec/models/spree/order/adjustments_spec.rb +39 -0
- data/spec/models/spree/order/callbacks_spec.rb +42 -0
- data/spec/models/spree/order/checkout_spec.rb +902 -0
- data/spec/models/spree/order/currency_updater_spec.rb +32 -0
- data/spec/models/spree/order/finalizing_spec.rb +111 -0
- data/spec/models/spree/order/payment_spec.rb +210 -0
- data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
- data/spec/models/spree/order/state_machine_spec.rb +221 -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_cancellations_spec.rb +120 -0
- data/spec/models/spree/order_capturing_spec.rb +116 -0
- data/spec/models/spree/order_contents_spec.rb +265 -0
- data/spec/models/spree/order_inventory_spec.rb +228 -0
- data/spec/models/spree/order_mutex_spec.rb +85 -0
- data/spec/models/spree/order_promotion_spec.rb +31 -0
- data/spec/models/spree/order_shipping_spec.rb +247 -0
- data/spec/models/spree/order_spec.rb +1412 -0
- data/spec/models/spree/order_stock_location_spec.rb +18 -0
- data/spec/models/spree/order_updater_spec.rb +299 -0
- data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
- data/spec/models/spree/payment_method_spec.rb +96 -0
- data/spec/models/spree/payment_spec.rb +1044 -0
- data/spec/models/spree/permission_sets/base_spec.rb +12 -0
- data/spec/models/spree/permission_sets/configuration_display.rb +82 -0
- data/spec/models/spree/permission_sets/configuration_management_spec.rb +50 -0
- data/spec/models/spree/permission_sets/dashboard_display_spec.rb +22 -0
- data/spec/models/spree/permission_sets/order_display_spec.rb +49 -0
- data/spec/models/spree/permission_sets/order_management_spec.rb +36 -0
- data/spec/models/spree/permission_sets/product_display_spec.rb +60 -0
- data/spec/models/spree/permission_sets/product_management_spec.rb +40 -0
- data/spec/models/spree/permission_sets/promotion_display_spec.rb +34 -0
- data/spec/models/spree/permission_sets/promotion_management_spec.rb +26 -0
- data/spec/models/spree/permission_sets/report_display_spec.rb +24 -0
- data/spec/models/spree/permission_sets/restricted_transfer_management_spec.rb +132 -0
- data/spec/models/spree/permission_sets/stock_display_spec.rb +26 -0
- data/spec/models/spree/permission_sets/stock_management_spec.rb +24 -0
- data/spec/models/spree/permission_sets/user_display_spec.rb +36 -0
- data/spec/models/spree/permission_sets/user_management_spec.rb +28 -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 +294 -0
- data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
- data/spec/models/spree/preferences/static_model_preferences_spec.rb +78 -0
- data/spec/models/spree/preferences/statically_configurable_spec.rb +60 -0
- data/spec/models/spree/preferences/store_spec.rb +39 -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_property_spec.rb +20 -0
- data/spec/models/spree/product_spec.rb +437 -0
- data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +96 -0
- data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +165 -0
- data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +115 -0
- data/spec/models/spree/promotion/actions/free_shipping_spec.rb +40 -0
- data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
- data/spec/models/spree/promotion/rules/item_total_spec.rb +67 -0
- data/spec/models/spree/promotion/rules/nth_order_spec.rb +70 -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 +94 -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_builder_spec.rb +118 -0
- data/spec/models/spree/promotion_category_spec.rb +17 -0
- data/spec/models/spree/promotion_code/code_builder_spec.rb +79 -0
- data/spec/models/spree/promotion_code_spec.rb +187 -0
- data/spec/models/spree/promotion_handler/cart_spec.rb +114 -0
- data/spec/models/spree/promotion_handler/coupon_spec.rb +335 -0
- data/spec/models/spree/promotion_handler/free_shipping_spec.rb +47 -0
- data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
- data/spec/models/spree/promotion_rule_spec.rb +28 -0
- data/spec/models/spree/promotion_spec.rb +767 -0
- data/spec/models/spree/refund_spec.rb +204 -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 +231 -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 +107 -0
- data/spec/models/spree/reimbursement_type/store_credit_spec.rb +97 -0
- data/spec/models/spree/return_authorization_spec.rb +290 -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 +85 -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 +775 -0
- data/spec/models/spree/returns_calculator_spec.rb +14 -0
- data/spec/models/spree/shipment_spec.rb +709 -0
- data/spec/models/spree/shipping_calculator_spec.rb +45 -0
- data/spec/models/spree/shipping_method_spec.rb +88 -0
- data/spec/models/spree/shipping_rate_spec.rb +142 -0
- data/spec/models/spree/state_spec.rb +14 -0
- data/spec/models/spree/stock/availability_validator_spec.rb +83 -0
- data/spec/models/spree/stock/coordinator_spec.rb +116 -0
- data/spec/models/spree/stock/differentiator_spec.rb +39 -0
- data/spec/models/spree/stock/estimator_spec.rb +146 -0
- data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
- data/spec/models/spree/stock/package_spec.rb +163 -0
- data/spec/models/spree/stock/packer_spec.rb +91 -0
- data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
- data/spec/models/spree/stock/quantifier_spec.rb +115 -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 +50 -0
- data/spec/models/spree/stock/splitter/weight_spec.rb +29 -0
- data/spec/models/spree/stock_item_spec.rb +426 -0
- data/spec/models/spree/stock_location_spec.rb +279 -0
- data/spec/models/spree/stock_movement_spec.rb +56 -0
- data/spec/models/spree/stock_transfer_spec.rb +290 -0
- data/spec/models/spree/store_credit_category_spec.rb +17 -0
- data/spec/models/spree/store_credit_event_spec.rb +314 -0
- data/spec/models/spree/store_credit_spec.rb +876 -0
- data/spec/models/spree/store_spec.rb +55 -0
- data/spec/models/spree/tax_category_spec.rb +27 -0
- data/spec/models/spree/tax_rate_spec.rb +378 -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/transfer_item_spec.rb +264 -0
- data/spec/models/spree/unit_cancel_spec.rb +148 -0
- data/spec/models/spree/user_spec.rb +223 -0
- data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +23 -0
- data/spec/models/spree/variant/scopes_spec.rb +55 -0
- data/spec/models/spree/variant_spec.rb +546 -0
- data/spec/models/spree/zone_spec.rb +305 -0
- data/spec/spec_helper.rb +78 -0
- data/spec/support/big_decimal.rb +5 -0
- data/spec/support/concerns/default_price.rb +34 -0
- data/spec/support/dummy_ability.rb +4 -0
- data/spec/support/test_gateway.rb +2 -0
- metadata +229 -3
- data/lib/spree/testing_support/rspec-activemodel-mocks_patch.rb +0 -8
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe ReturnsCalculator, :type => :model do
|
|
5
|
+
let(:return_item) { build(:return_item) }
|
|
6
|
+
subject { ReturnsCalculator.new }
|
|
7
|
+
|
|
8
|
+
it 'compute_shipment must be overridden' do
|
|
9
|
+
expect {
|
|
10
|
+
subject.compute(return_item)
|
|
11
|
+
}.to raise_error NotImplementedError
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'benchmark'
|
|
3
|
+
|
|
4
|
+
describe Spree::Shipment, :type => :model do
|
|
5
|
+
let(:stock_location) { create(:stock_location) }
|
|
6
|
+
let(:order) { create(:order_ready_to_ship, line_items_count: 1) }
|
|
7
|
+
let(:shipping_method) { create(:shipping_method, name: "UPS") }
|
|
8
|
+
let(:stock_location) { create(:stock_location) }
|
|
9
|
+
let(:shipment) do
|
|
10
|
+
order.shipments.create!(
|
|
11
|
+
state: 'pending',
|
|
12
|
+
cost: 1,
|
|
13
|
+
address: order.ship_address,
|
|
14
|
+
inventory_units: order.inventory_units,
|
|
15
|
+
shipping_rates: [
|
|
16
|
+
Spree::ShippingRate.new(
|
|
17
|
+
shipping_method: shipping_method,
|
|
18
|
+
selected: true,
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
stock_location: stock_location,
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
let(:variant) { mock_model(Spree::Variant) }
|
|
26
|
+
let(:line_item) { mock_model(Spree::LineItem, variant: variant) }
|
|
27
|
+
|
|
28
|
+
# Regression test for #4063
|
|
29
|
+
context "number generation" do
|
|
30
|
+
before do
|
|
31
|
+
allow(order).to receive :update!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "generates a number containing a letter + 11 numbers" do
|
|
35
|
+
shipment.save
|
|
36
|
+
expect(shipment.number[0]).to eq("H")
|
|
37
|
+
expect(/\d{11}/.match(shipment.number)).not_to be_nil
|
|
38
|
+
expect(shipment.number.length).to eq(12)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'is backordered if one if its inventory_units is backordered' do
|
|
43
|
+
shipment.inventory_units = [
|
|
44
|
+
build(:inventory_unit, state: 'backordered', shipment: nil),
|
|
45
|
+
build(:inventory_unit, state: 'shipped', shipment: nil),
|
|
46
|
+
]
|
|
47
|
+
expect(shipment).to be_backordered
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context '#determine_state' do
|
|
51
|
+
it 'returns canceled if order is canceled?' do
|
|
52
|
+
allow(order).to receive_messages canceled?: true
|
|
53
|
+
expect(shipment.determine_state(order)).to eq 'canceled'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'returns pending unless order.can_ship?' do
|
|
57
|
+
allow(order).to receive_messages can_ship?: false
|
|
58
|
+
expect(shipment.determine_state(order)).to eq 'pending'
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'returns pending if backordered' do
|
|
62
|
+
allow(shipment).to receive_messages inventory_units: [mock_model(Spree::InventoryUnit, backordered?: true)]
|
|
63
|
+
expect(shipment.determine_state(order)).to eq 'pending'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'returns shipped when already shipped' do
|
|
67
|
+
allow(shipment).to receive_messages state: 'shipped'
|
|
68
|
+
expect(shipment.determine_state(order)).to eq 'shipped'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it 'returns pending when unpaid' do
|
|
72
|
+
allow(order).to receive_messages paid?: false
|
|
73
|
+
expect(shipment.determine_state(order)).to eq 'pending'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'returns ready when paid' do
|
|
77
|
+
allow(order).to receive_messages paid?: true
|
|
78
|
+
expect(shipment.determine_state(order)).to eq 'ready'
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context "display_amount" do
|
|
83
|
+
it "retuns a Spree::Money" do
|
|
84
|
+
shipment.cost = 21.22
|
|
85
|
+
expect(shipment.display_amount).to eq(Spree::Money.new(21.22))
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "display_final_price" do
|
|
90
|
+
it "retuns a Spree::Money" do
|
|
91
|
+
allow(shipment).to receive(:final_price) { 21.22 }
|
|
92
|
+
expect(shipment.display_final_price).to eq(Spree::Money.new(21.22))
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "display_item_cost" do
|
|
97
|
+
it "retuns a Spree::Money" do
|
|
98
|
+
allow(shipment).to receive(:item_cost) { 21.22 }
|
|
99
|
+
expect(shipment.display_item_cost).to eq(Spree::Money.new(21.22))
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "#item_cost" do
|
|
104
|
+
it 'should equal line items final amount with tax' do
|
|
105
|
+
shipment = create(:shipment, order: create(:order_with_totals))
|
|
106
|
+
create :tax_adjustment, adjustable: shipment.order.line_items.first, order: shipment.order
|
|
107
|
+
expect(shipment.item_cost).to eql(11.0)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "#discounted_cost" do
|
|
112
|
+
shipment = create(:shipment)
|
|
113
|
+
shipment.cost = 10
|
|
114
|
+
shipment.promo_total = -1
|
|
115
|
+
expect(shipment.discounted_cost).to eq(9)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "#tax_total with included taxes" do
|
|
119
|
+
shipment = Spree::Shipment.new
|
|
120
|
+
expect(shipment.tax_total).to eq(0)
|
|
121
|
+
shipment.included_tax_total = 10
|
|
122
|
+
expect(shipment.tax_total).to eq(10)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "#tax_total with additional taxes" do
|
|
126
|
+
shipment = Spree::Shipment.new
|
|
127
|
+
expect(shipment.tax_total).to eq(0)
|
|
128
|
+
shipment.additional_tax_total = 10
|
|
129
|
+
expect(shipment.tax_total).to eq(10)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "#final_price" do
|
|
133
|
+
shipment = Spree::Shipment.new
|
|
134
|
+
shipment.cost = 10
|
|
135
|
+
shipment.adjustment_total = -2
|
|
136
|
+
shipment.included_tax_total = 1
|
|
137
|
+
expect(shipment.final_price).to eq(8)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
context "manifest" do
|
|
141
|
+
let(:order) { Spree::Order.create }
|
|
142
|
+
let(:variant) { create(:variant) }
|
|
143
|
+
let!(:line_item) { order.contents.add variant }
|
|
144
|
+
let!(:shipment) { order.create_proposed_shipments.first }
|
|
145
|
+
|
|
146
|
+
it "returns variant expected" do
|
|
147
|
+
expect(shipment.manifest.first.variant).to eq variant
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
context "variant was removed" do
|
|
151
|
+
before { variant.destroy }
|
|
152
|
+
|
|
153
|
+
it "still returns variant expected" do
|
|
154
|
+
expect(shipment.manifest.first.variant).to eq variant
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context 'shipping_rates' do
|
|
160
|
+
let(:shipment) { create(:shipment) }
|
|
161
|
+
let(:shipping_method1) { create(:shipping_method) }
|
|
162
|
+
let(:shipping_method2) { create(:shipping_method) }
|
|
163
|
+
let(:shipping_rates) { [
|
|
164
|
+
Spree::ShippingRate.new(shipping_method: shipping_method1, cost: 10.00, selected: true),
|
|
165
|
+
Spree::ShippingRate.new(shipping_method: shipping_method2, cost: 20.00)
|
|
166
|
+
] }
|
|
167
|
+
|
|
168
|
+
it 'returns shipping_method from selected shipping_rate' do
|
|
169
|
+
shipment.shipping_rates.delete_all
|
|
170
|
+
shipment.shipping_rates.create shipping_method: shipping_method1, cost: 10.00, selected: true
|
|
171
|
+
expect(shipment.shipping_method).to eq shipping_method1
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
context 'refresh_rates' do
|
|
175
|
+
let(:mock_estimator) { double('estimator', shipping_rates: shipping_rates) }
|
|
176
|
+
before { allow(shipment).to receive(:can_get_rates?){ true } }
|
|
177
|
+
|
|
178
|
+
it 'should request new rates, and maintain shipping_method selection' do
|
|
179
|
+
expect(Spree::Stock::Estimator).to receive(:new).with(shipment.order).and_return(mock_estimator)
|
|
180
|
+
allow(shipment).to receive_messages(shipping_method: shipping_method2)
|
|
181
|
+
|
|
182
|
+
expect(shipment.refresh_rates).to eq(shipping_rates)
|
|
183
|
+
expect(shipment.reload.selected_shipping_rate.shipping_method_id).to eq(shipping_method2.id)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
it 'should handle no shipping_method selection' do
|
|
187
|
+
expect(Spree::Stock::Estimator).to receive(:new).with(shipment.order).and_return(mock_estimator)
|
|
188
|
+
allow(shipment).to receive_messages(shipping_method: nil)
|
|
189
|
+
expect(shipment.refresh_rates).to eq(shipping_rates)
|
|
190
|
+
expect(shipment.reload.selected_shipping_rate).not_to be_nil
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it 'should not refresh if shipment is shipped' do
|
|
194
|
+
expect(Spree::Stock::Estimator).not_to receive(:new)
|
|
195
|
+
shipment.shipping_rates.delete_all
|
|
196
|
+
allow(shipment).to receive_messages(shipped?: true)
|
|
197
|
+
expect(shipment.refresh_rates).to eq([])
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "can't get rates without a shipping address" do
|
|
201
|
+
shipment.order(ship_address: nil)
|
|
202
|
+
expect(shipment.refresh_rates).to eq([])
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context 'to_package' do
|
|
206
|
+
let(:inventory_units) do
|
|
207
|
+
[build(:inventory_unit, line_item: line_item, variant: variant, state: 'on_hand'),
|
|
208
|
+
build(:inventory_unit, line_item: line_item, variant: variant, state: 'backordered')]
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
before do
|
|
212
|
+
allow(shipment).to receive(:inventory_units) { inventory_units }
|
|
213
|
+
allow(inventory_units).to receive_message_chain(:includes, :joins).and_return inventory_units
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
it 'should use symbols for states when adding contents to package' do
|
|
217
|
+
package = shipment.to_package
|
|
218
|
+
expect(package.on_hand.count).to eq 1
|
|
219
|
+
expect(package.backordered.count).to eq 1
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context "#update!" do
|
|
226
|
+
shared_examples_for "immutable once shipped" do
|
|
227
|
+
it "should remain in shipped state once shipped" do
|
|
228
|
+
shipment.state = 'shipped'
|
|
229
|
+
expect(shipment).to receive(:update_columns).with(state: 'shipped', updated_at: kind_of(Time))
|
|
230
|
+
shipment.update!(order)
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
shared_examples_for "pending if backordered" do
|
|
235
|
+
it "should have a state of pending if backordered" do
|
|
236
|
+
allow(shipment).to receive_messages(inventory_units: [mock_model(Spree::InventoryUnit, backordered?: true)])
|
|
237
|
+
expect(shipment).to receive(:update_columns).with(state: 'pending', updated_at: kind_of(Time))
|
|
238
|
+
shipment.update!(order)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
context "when order cannot ship" do
|
|
243
|
+
before { allow(order).to receive_messages can_ship?: false }
|
|
244
|
+
it "should result in a 'pending' state" do
|
|
245
|
+
expect(shipment).to receive(:update_columns).with(state: 'pending', updated_at: kind_of(Time))
|
|
246
|
+
shipment.update!(order)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
context "when order is paid" do
|
|
251
|
+
before { allow(order).to receive_messages paid?: true }
|
|
252
|
+
it "should result in a 'ready' state" do
|
|
253
|
+
expect(shipment).to receive(:update_columns).with(state: 'ready', updated_at: kind_of(Time))
|
|
254
|
+
shipment.update!(order)
|
|
255
|
+
end
|
|
256
|
+
it_should_behave_like 'immutable once shipped'
|
|
257
|
+
it_should_behave_like 'pending if backordered'
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
context "when payment is not required" do
|
|
261
|
+
before do
|
|
262
|
+
@original_require_payment = Spree::Config[:require_payment_to_ship]
|
|
263
|
+
Spree::Config[:require_payment_to_ship] = false
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
after do
|
|
267
|
+
Spree::Config[:require_payment_to_ship] = @original_require_payment
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
it "should result in a 'ready' state" do
|
|
271
|
+
expect(shipment).to receive(:update_columns).with(state: 'ready', updated_at: kind_of(Time))
|
|
272
|
+
shipment.update!(order)
|
|
273
|
+
end
|
|
274
|
+
it_should_behave_like 'immutable once shipped'
|
|
275
|
+
it_should_behave_like 'pending if backordered'
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
context "when order has balance due" do
|
|
279
|
+
before { allow(order).to receive_messages paid?: false }
|
|
280
|
+
it "should result in a 'pending' state" do
|
|
281
|
+
shipment.state = 'ready'
|
|
282
|
+
expect(shipment).to receive(:update_columns).with(state: 'pending', updated_at: kind_of(Time))
|
|
283
|
+
shipment.update!(order)
|
|
284
|
+
end
|
|
285
|
+
it_should_behave_like 'immutable once shipped'
|
|
286
|
+
it_should_behave_like 'pending if backordered'
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
context "when order has a credit owed" do
|
|
290
|
+
before { allow(order).to receive_messages payment_state: 'credit_owed', paid?: true }
|
|
291
|
+
it "should result in a 'ready' state" do
|
|
292
|
+
shipment.state = 'pending'
|
|
293
|
+
expect(shipment).to receive(:update_columns).with(state: 'ready', updated_at: kind_of(Time))
|
|
294
|
+
shipment.update!(order)
|
|
295
|
+
end
|
|
296
|
+
it_should_behave_like 'immutable once shipped'
|
|
297
|
+
it_should_behave_like 'pending if backordered'
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
context "when shipment state changes to shipped" do
|
|
301
|
+
it "should call after_ship" do
|
|
302
|
+
shipment.state = 'pending'
|
|
303
|
+
expect(shipment).to receive :after_ship
|
|
304
|
+
allow(shipment).to receive_messages determine_state: 'shipped'
|
|
305
|
+
expect(shipment).to receive(:update_columns).with(state: 'shipped', updated_at: kind_of(Time))
|
|
306
|
+
shipment.update!(order)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Regression test for #4347
|
|
310
|
+
context "with adjustments" do
|
|
311
|
+
before do
|
|
312
|
+
shipment.adjustments << Spree::Adjustment.create(order: order, label: "Label", amount: 5)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it "transitions to shipped" do
|
|
316
|
+
shipment.update_column(:state, "ready")
|
|
317
|
+
expect { shipment.ship! }.not_to raise_error
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
context "when order is completed" do
|
|
324
|
+
after { Spree::Config.set track_inventory_levels: true }
|
|
325
|
+
|
|
326
|
+
before do
|
|
327
|
+
allow(order).to receive_messages completed?: true
|
|
328
|
+
allow(order).to receive_messages canceled?: false
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
context "with inventory tracking" do
|
|
332
|
+
before { Spree::Config.set track_inventory_levels: true }
|
|
333
|
+
|
|
334
|
+
it "should validate with inventory" do
|
|
335
|
+
shipment.inventory_units = [create(:inventory_unit)]
|
|
336
|
+
expect(shipment.valid?).to be true
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
context "without inventory tracking" do
|
|
341
|
+
before { Spree::Config.set track_inventory_levels: false }
|
|
342
|
+
|
|
343
|
+
it "should validate with no inventory" do
|
|
344
|
+
expect(shipment.valid?).to be true
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
context "#cancel" do
|
|
350
|
+
it 'cancels the shipment' do
|
|
351
|
+
allow(shipment.order).to receive(:update!)
|
|
352
|
+
|
|
353
|
+
shipment.state = 'pending'
|
|
354
|
+
expect(shipment).to receive(:after_cancel)
|
|
355
|
+
shipment.cancel!
|
|
356
|
+
expect(shipment.state).to eq 'canceled'
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it 'restocks the items' do
|
|
360
|
+
variant = shipment.inventory_units.first.variant
|
|
361
|
+
shipment.stock_location = mock_model(Spree::StockLocation)
|
|
362
|
+
expect(shipment.stock_location).to receive(:restock).with(variant, 1, shipment)
|
|
363
|
+
shipment.after_cancel
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
context "with backordered inventory units" do
|
|
367
|
+
let(:order) { create(:order) }
|
|
368
|
+
let(:variant) { create(:variant) }
|
|
369
|
+
let(:other_order) { create(:order) }
|
|
370
|
+
|
|
371
|
+
before do
|
|
372
|
+
order.contents.add variant
|
|
373
|
+
order.create_proposed_shipments
|
|
374
|
+
|
|
375
|
+
other_order.contents.add variant
|
|
376
|
+
other_order.create_proposed_shipments
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
it "doesn't fill backorders when restocking inventory units" do
|
|
380
|
+
shipment = order.shipments.first
|
|
381
|
+
expect(shipment.inventory_units.count).to eq 1
|
|
382
|
+
expect(shipment.inventory_units.first).to be_backordered
|
|
383
|
+
|
|
384
|
+
other_shipment = other_order.shipments.first
|
|
385
|
+
expect(other_shipment.inventory_units.count).to eq 1
|
|
386
|
+
expect(other_shipment.inventory_units.first).to be_backordered
|
|
387
|
+
|
|
388
|
+
expect {
|
|
389
|
+
shipment.cancel!
|
|
390
|
+
}.not_to change { other_shipment.inventory_units.first.state }
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
context "#resume" do
|
|
396
|
+
let(:inventory_unit) { create(:inventory_unit) }
|
|
397
|
+
|
|
398
|
+
before { shipment.state = 'canceled' }
|
|
399
|
+
|
|
400
|
+
context "when order cannot ship" do
|
|
401
|
+
before { allow(order).to receive_messages(can_ship?: false) }
|
|
402
|
+
it "should result in a 'pending' state" do
|
|
403
|
+
shipment.resume!
|
|
404
|
+
expect(shipment.state).to eq 'pending'
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
context "when order is not paid" do
|
|
409
|
+
before { allow(order).to receive_messages(paid?: false) }
|
|
410
|
+
it "should result in a 'ready' state" do
|
|
411
|
+
shipment.resume!
|
|
412
|
+
expect(shipment.state).to eq 'pending'
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
context "when any inventory is backordered" do
|
|
417
|
+
before { allow_any_instance_of(Spree::InventoryUnit).to receive(:backordered?).and_return(true) }
|
|
418
|
+
it "should result in a 'ready' state" do
|
|
419
|
+
shipment.resume!
|
|
420
|
+
expect(shipment.state).to eq 'pending'
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
context "when the order is paid, shippable, and not backordered" do
|
|
425
|
+
before do
|
|
426
|
+
allow(order).to receive_messages(can_ship?: true)
|
|
427
|
+
allow(order).to receive_messages(paid?: true)
|
|
428
|
+
allow_any_instance_of(Spree::InventoryUnit).to receive(:backordered?).and_return(false)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it "should result in a 'ready' state" do
|
|
432
|
+
shipment.resume!
|
|
433
|
+
expect(shipment.state).to eq 'ready'
|
|
434
|
+
end
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it 'unstocks them items' do
|
|
438
|
+
variant = shipment.inventory_units.first.variant
|
|
439
|
+
shipment.stock_location = mock_model(Spree::StockLocation)
|
|
440
|
+
expect(shipment.stock_location).to receive(:unstock).with(variant, 1, shipment)
|
|
441
|
+
shipment.after_resume
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
context "#ship" do
|
|
446
|
+
context "when the shipment is canceled" do
|
|
447
|
+
let(:address){ create(:address) }
|
|
448
|
+
let(:order){ create(:order_with_line_items, ship_address: address) }
|
|
449
|
+
let(:shipment_with_inventory_units) { create(:shipment, order: order, address: address, state: 'canceled') }
|
|
450
|
+
let(:subject) { shipment_with_inventory_units.ship! }
|
|
451
|
+
before do
|
|
452
|
+
allow(order).to receive(:update!)
|
|
453
|
+
allow(shipment_with_inventory_units).to receive_messages(require_inventory: false, update_order: true)
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
it 'unstocks them items' do
|
|
457
|
+
expect(shipment_with_inventory_units.stock_location).to receive(:unstock).with(an_instance_of(Spree::Variant), 1, shipment_with_inventory_units)
|
|
458
|
+
subject
|
|
459
|
+
end
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
['ready', 'canceled'].each do |state|
|
|
463
|
+
context "from #{state}" do
|
|
464
|
+
before do
|
|
465
|
+
allow(order).to receive(:update!)
|
|
466
|
+
allow(shipment).to receive_messages(require_inventory: false, update_order: true, state: state)
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it "should call fulfill_order_with_stock_location" do
|
|
470
|
+
expect(Spree::OrderStockLocation).to(
|
|
471
|
+
receive(:fulfill_for_order_with_stock_location).
|
|
472
|
+
with(order, stock_location)
|
|
473
|
+
)
|
|
474
|
+
shipment.ship!
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
it "finalizes adjustments" do
|
|
478
|
+
shipment.adjustments.each do |adjustment|
|
|
479
|
+
expect(adjustment).to receive(:finalize!)
|
|
480
|
+
end
|
|
481
|
+
shipment.ship!
|
|
482
|
+
end
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
context "#ready" do
|
|
488
|
+
# Regression test for #2040
|
|
489
|
+
it "cannot ready a shipment for an order if the order is unpaid" do
|
|
490
|
+
expect(order).to receive_messages(paid?: false)
|
|
491
|
+
expect(shipment).not_to be_can_ready
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
context "updates cost when selected shipping rate is present" do
|
|
496
|
+
let(:shipment) { create(:shipment) }
|
|
497
|
+
|
|
498
|
+
before { allow(shipment).to receive_message_chain :selected_shipping_rate, cost: 5 }
|
|
499
|
+
|
|
500
|
+
it "updates shipment totals" do
|
|
501
|
+
shipment.update_amounts
|
|
502
|
+
expect(shipment.reload.cost).to eq(5)
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it "factors in additional adjustments to adjustment total" do
|
|
506
|
+
shipment.adjustments.create!(
|
|
507
|
+
order: order,
|
|
508
|
+
label: "Additional",
|
|
509
|
+
amount: 5,
|
|
510
|
+
included: false,
|
|
511
|
+
state: "closed"
|
|
512
|
+
)
|
|
513
|
+
shipment.update_amounts
|
|
514
|
+
expect(shipment.reload.adjustment_total).to eq(5)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
it "does not factor in included adjustments to adjustment total" do
|
|
518
|
+
shipment.adjustments.create!(
|
|
519
|
+
order: order,
|
|
520
|
+
label: "Included",
|
|
521
|
+
amount: 5,
|
|
522
|
+
included: true,
|
|
523
|
+
state: "closed"
|
|
524
|
+
)
|
|
525
|
+
shipment.update_amounts
|
|
526
|
+
expect(shipment.reload.adjustment_total).to eq(0)
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
context "changes shipping rate via general update" do
|
|
531
|
+
let(:order) do
|
|
532
|
+
Spree::Order.create(
|
|
533
|
+
payment_total: 100, payment_state: 'paid', total: 100, item_total: 100
|
|
534
|
+
)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
let(:shipment) { Spree::Shipment.create order_id: order.id }
|
|
538
|
+
|
|
539
|
+
let(:shipping_rate) do
|
|
540
|
+
Spree::ShippingRate.create shipment_id: shipment.id, cost: 10
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
before do
|
|
544
|
+
shipment.update_attributes_and_order selected_shipping_rate_id: shipping_rate.id
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
it "updates everything around order shipment total and state" do
|
|
548
|
+
expect(shipment.cost.to_f).to eq 10
|
|
549
|
+
expect(shipment.state).to eq 'pending'
|
|
550
|
+
expect(shipment.order.total.to_f).to eq 110
|
|
551
|
+
expect(shipment.order.payment_state).to eq 'balance_due'
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
context "after_save" do
|
|
556
|
+
context "line item changes" do
|
|
557
|
+
before do
|
|
558
|
+
shipment.cost = shipment.cost + 10
|
|
559
|
+
end
|
|
560
|
+
|
|
561
|
+
it "triggers adjustment total recalculation" do
|
|
562
|
+
expect(shipment).to receive(:recalculate_adjustments)
|
|
563
|
+
shipment.save
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
it "does not trigger adjustment recalculation if shipment has shipped" do
|
|
567
|
+
shipment.state = 'shipped'
|
|
568
|
+
expect(shipment).not_to receive(:recalculate_adjustments)
|
|
569
|
+
shipment.save
|
|
570
|
+
end
|
|
571
|
+
end
|
|
572
|
+
|
|
573
|
+
context "line item does not change" do
|
|
574
|
+
it "does not trigger adjustment total recalculation" do
|
|
575
|
+
expect(shipment).not_to receive(:recalculate_adjustments)
|
|
576
|
+
shipment.save
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
end
|
|
580
|
+
|
|
581
|
+
context "currency" do
|
|
582
|
+
it "returns the order currency" do
|
|
583
|
+
expect(shipment.currency).to eq(order.currency)
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
context "nil costs" do
|
|
588
|
+
it "sets cost to 0" do
|
|
589
|
+
shipment = Spree::Shipment.new
|
|
590
|
+
shipment.valid?
|
|
591
|
+
expect(shipment.cost).to eq 0
|
|
592
|
+
end
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
context "#tracking_url" do
|
|
596
|
+
subject do
|
|
597
|
+
shipment.tracking_url
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
before do
|
|
601
|
+
shipping_method.update!(tracking_url: "https://example.com/:tracking")
|
|
602
|
+
shipment.tracking = '1Z12345'
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
it "uses shipping method to determine url" do
|
|
606
|
+
is_expected.to eq("https://example.com/1Z12345")
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
context "set up new inventory units" do
|
|
611
|
+
# let(:line_item) { double(
|
|
612
|
+
let(:variant) { double("Variant", id: 9) }
|
|
613
|
+
|
|
614
|
+
let(:inventory_units) { double }
|
|
615
|
+
|
|
616
|
+
let(:params) do
|
|
617
|
+
{ variant_id: variant.id, state: 'on_hand', order_id: order.id, line_item_id: line_item.id }
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
before { allow(shipment).to receive_messages inventory_units: inventory_units }
|
|
621
|
+
|
|
622
|
+
it "associates variant and order" do
|
|
623
|
+
expect(inventory_units).to receive(:create).with(params)
|
|
624
|
+
unit = shipment.set_up_inventory('on_hand', variant, order, line_item)
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
# Regression test for #3349
|
|
629
|
+
context "#destroy" do
|
|
630
|
+
it "destroys linked shipping_rates" do
|
|
631
|
+
reflection = Spree::Shipment.reflect_on_association(:shipping_rates)
|
|
632
|
+
expect(reflection.options[:dependent]).to be(:delete_all)
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
# Regression test for #4072 (kinda)
|
|
637
|
+
# The need for this was discovered in the research for #4702
|
|
638
|
+
context "state changes" do
|
|
639
|
+
before do
|
|
640
|
+
# Must be stubbed so transition can succeed
|
|
641
|
+
allow(order).to receive_messages :paid? => true
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
it "are logged to the database" do
|
|
645
|
+
expect(shipment.state_changes).to be_empty
|
|
646
|
+
expect(shipment.ready!).to be true
|
|
647
|
+
expect(shipment.state_changes.count).to eq(1)
|
|
648
|
+
state_change = shipment.state_changes.first
|
|
649
|
+
expect(state_change.previous_state).to eq('pending')
|
|
650
|
+
expect(state_change.next_state).to eq('ready')
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
context "don't require shipment" do
|
|
655
|
+
let(:stock_location) { create(:stock_location, fulfillable: false)}
|
|
656
|
+
let(:unshippable_shipment) do
|
|
657
|
+
create(
|
|
658
|
+
:shipment,
|
|
659
|
+
address: create(:address),
|
|
660
|
+
stock_location: stock_location,
|
|
661
|
+
inventory_units: [build(:inventory_unit)],
|
|
662
|
+
)
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
before { allow(order).to receive_messages paid?: true }
|
|
666
|
+
|
|
667
|
+
it 'proceeds automatically to shipped state' do
|
|
668
|
+
unshippable_shipment.ready!
|
|
669
|
+
expect(unshippable_shipment.state).to eq('shipped')
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
it 'does not send a confirmation email' do
|
|
673
|
+
expect(unshippable_shipment).to_not receive(:send_shipment_email)
|
|
674
|
+
unshippable_shipment.ready!
|
|
675
|
+
unshippable_shipment.inventory_units(true).each do |unit|
|
|
676
|
+
expect(unit.state).to eq('shipped')
|
|
677
|
+
end
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
context "destroy prevention" do
|
|
682
|
+
it "can be destroyed when pending" do
|
|
683
|
+
shipment = create(:shipment, state: "pending")
|
|
684
|
+
expect(shipment.destroy).to be_truthy
|
|
685
|
+
expect { shipment.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
it "cannot be destroyed when ready" do
|
|
689
|
+
shipment = create(:shipment, state: "ready")
|
|
690
|
+
expect(shipment.destroy).to eq false
|
|
691
|
+
expect(shipment.errors.full_messages.join).to match /Cannot destroy/
|
|
692
|
+
expect { shipment.reload }.not_to raise_error
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
it "cannot be destroyed when shipped" do
|
|
696
|
+
shipment = create(:shipment, state: "shipped")
|
|
697
|
+
expect(shipment.destroy).to eq false
|
|
698
|
+
expect(shipment.errors.full_messages.join).to match /Cannot destroy/
|
|
699
|
+
expect { shipment.reload }.not_to raise_error
|
|
700
|
+
end
|
|
701
|
+
|
|
702
|
+
it "cannot be destroyed when canceled" do
|
|
703
|
+
shipment = create(:shipment, state: "canceled")
|
|
704
|
+
expect(shipment.destroy).to eq false
|
|
705
|
+
expect(shipment.errors.full_messages.join).to match /Cannot destroy/
|
|
706
|
+
expect { shipment.reload }.not_to raise_error
|
|
707
|
+
end
|
|
708
|
+
end
|
|
709
|
+
end
|