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,84 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Spree::Order, :type => :model do
|
|
5
|
+
let(:order) { stub_model(Spree::Order) }
|
|
6
|
+
|
|
7
|
+
context "#tax_zone" do
|
|
8
|
+
let(:bill_address) { create :address }
|
|
9
|
+
let(:ship_address) { create :address }
|
|
10
|
+
let(:order) { Spree::Order.create(:ship_address => ship_address, :bill_address => bill_address) }
|
|
11
|
+
let(:zone) { create :zone }
|
|
12
|
+
|
|
13
|
+
context "when no zones exist" do
|
|
14
|
+
it "should return nil" do
|
|
15
|
+
expect(order.tax_zone).to be_nil
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "when :tax_using_ship_address => true" do
|
|
20
|
+
before { Spree::Config.set(:tax_using_ship_address => true) }
|
|
21
|
+
|
|
22
|
+
it "should calculate using ship_address" do
|
|
23
|
+
expect(Spree::Zone).to receive(:match).at_least(:once).with(ship_address)
|
|
24
|
+
expect(Spree::Zone).not_to receive(:match).with(bill_address)
|
|
25
|
+
order.tax_zone
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "when :tax_using_ship_address => false" do
|
|
30
|
+
before { Spree::Config.set(:tax_using_ship_address => false) }
|
|
31
|
+
|
|
32
|
+
it "should calculate using bill_address" do
|
|
33
|
+
expect(Spree::Zone).to receive(:match).at_least(:once).with(bill_address)
|
|
34
|
+
expect(Spree::Zone).not_to receive(:match).with(ship_address)
|
|
35
|
+
order.tax_zone
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "when there is a default tax zone" do
|
|
40
|
+
before do
|
|
41
|
+
@default_zone = create(:zone, :name => "foo_zone")
|
|
42
|
+
allow(Spree::Zone).to receive_messages :default_tax => @default_zone
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "when there is a matching zone" do
|
|
46
|
+
before { allow(Spree::Zone).to receive_messages(:match => zone) }
|
|
47
|
+
|
|
48
|
+
it "should return the matching zone" do
|
|
49
|
+
expect(order.tax_zone).to eq(zone)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "when there is no matching zone" do
|
|
54
|
+
before { allow(Spree::Zone).to receive_messages(:match => nil) }
|
|
55
|
+
|
|
56
|
+
it "should return the default tax zone" do
|
|
57
|
+
expect(order.tax_zone).to eq(@default_zone)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "when no default tax zone" do
|
|
63
|
+
before { allow(Spree::Zone).to receive_messages :default_tax => nil }
|
|
64
|
+
|
|
65
|
+
context "when there is a matching zone" do
|
|
66
|
+
before { allow(Spree::Zone).to receive_messages(:match => zone) }
|
|
67
|
+
|
|
68
|
+
it "should return the matching zone" do
|
|
69
|
+
expect(order.tax_zone).to eq(zone)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "when there is no matching zone" do
|
|
74
|
+
before { allow(Spree::Zone).to receive_messages(:match => nil) }
|
|
75
|
+
|
|
76
|
+
it "should return nil" do
|
|
77
|
+
expect(order.tax_zone).to be_nil
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Order, :type => :model do
|
|
5
|
+
let(:order) { Order.create }
|
|
6
|
+
let(:shirt) { create(:variant) }
|
|
7
|
+
|
|
8
|
+
context "adds item to cart and activates promo" do
|
|
9
|
+
let(:promotion) { Promotion.create name: 'Huhu' }
|
|
10
|
+
let(:calculator) { Calculator::FlatPercentItemTotal.new(:preferred_flat_percent => 10) }
|
|
11
|
+
let!(:action) { Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
|
|
12
|
+
|
|
13
|
+
before { order.contents.add(shirt, 1) }
|
|
14
|
+
|
|
15
|
+
context "item quantity changes" do
|
|
16
|
+
it "recalculates order adjustments" do
|
|
17
|
+
expect {
|
|
18
|
+
order.contents.add(shirt, 3)
|
|
19
|
+
}.to change { order.adjustments.eligible.pluck(:amount) }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::Order, :type => :model do
|
|
4
|
+
let(:order) { stub_model(Spree::Order) }
|
|
5
|
+
|
|
6
|
+
context "#update!" do
|
|
7
|
+
let(:line_items) { [mock_model(Spree::LineItem, :amount => 5) ]}
|
|
8
|
+
|
|
9
|
+
context "when there are update hooks" do
|
|
10
|
+
before { Spree::Order.register_update_hook :foo }
|
|
11
|
+
after { Spree::Order.update_hooks.clear }
|
|
12
|
+
it "should call each of the update hooks" do
|
|
13
|
+
expect(order).to receive :foo
|
|
14
|
+
order.update!
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Spree::Order, :type => :model do
|
|
5
|
+
context "validations" do
|
|
6
|
+
# Regression test for #2214
|
|
7
|
+
it "does not return two error messages when email is blank" do
|
|
8
|
+
order = Spree::Order.new
|
|
9
|
+
allow(order).to receive_messages(:require_email => true)
|
|
10
|
+
order.valid?
|
|
11
|
+
expect(order.errors[:email]).to eq(["can't be blank"])
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::OrderCancellations do
|
|
4
|
+
describe "#short_ship" do
|
|
5
|
+
subject { Spree::OrderCancellations.new(order).short_ship([inventory_unit]) }
|
|
6
|
+
|
|
7
|
+
let(:order) { create(:order_ready_to_ship, line_items_count: 1) }
|
|
8
|
+
let(:inventory_unit) { order.inventory_units.first }
|
|
9
|
+
let(:shipment) { inventory_unit.shipment }
|
|
10
|
+
|
|
11
|
+
it "creates a UnitCancel record" do
|
|
12
|
+
expect { subject }.to change { Spree::UnitCancel.count }.by(1)
|
|
13
|
+
|
|
14
|
+
unit_cancel = Spree::UnitCancel.last
|
|
15
|
+
expect(unit_cancel.inventory_unit).to eq inventory_unit
|
|
16
|
+
expect(unit_cancel.reason).to eq Spree::UnitCancel::SHORT_SHIP
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "cancels the inventory unit" do
|
|
20
|
+
expect { subject }.to change { inventory_unit.state }.to "canceled"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "updates the shipment.state" do
|
|
24
|
+
expect { subject }.to change { shipment.reload.state }.from('ready').to('shipped')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "updates the order.shipment_state" do
|
|
28
|
+
expect { subject }.to change { order.shipment_state }.from('ready').to('shipped')
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "adjusts the order" do
|
|
32
|
+
expect { subject }.to change { order.total }.by(-10.0)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "sends a cancellation email" do
|
|
36
|
+
mail_double = double
|
|
37
|
+
expect(Spree::OrderMailer).to receive(:inventory_cancellation_email).with(order, [inventory_unit]).and_return(mail_double)
|
|
38
|
+
expect(mail_double).to receive(:deliver_later)
|
|
39
|
+
subject
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context "when send_cancellation_mailer is false" do
|
|
43
|
+
subject { Spree::OrderCancellations.new(order).short_ship([inventory_unit]) }
|
|
44
|
+
|
|
45
|
+
before do
|
|
46
|
+
@original_send_boolean = Spree::OrderCancellations.send_cancellation_mailer
|
|
47
|
+
Spree::OrderCancellations.send_cancellation_mailer = false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
after { Spree::OrderCancellations.send_cancellation_mailer = @original_send_boolean }
|
|
51
|
+
|
|
52
|
+
it "does not send a cancellation email" do
|
|
53
|
+
expect(Spree::OrderMailer).not_to receive(:inventory_cancellation_email)
|
|
54
|
+
subject
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "with a who" do
|
|
59
|
+
subject { order.cancellations.short_ship([inventory_unit], whodunnit: 'some automated system') }
|
|
60
|
+
|
|
61
|
+
let(:user) { order.user }
|
|
62
|
+
|
|
63
|
+
it "sets the user on the UnitCancel" do
|
|
64
|
+
expect { subject }.to change { Spree::UnitCancel.count }.by(1)
|
|
65
|
+
expect(Spree::UnitCancel.last.created_by).to eq("some automated system")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "when rounding is required" do
|
|
70
|
+
let(:order) { create(:order_ready_to_ship, line_items_count: 1, line_items_price: 0.83) }
|
|
71
|
+
let(:line_item) { order.line_items.first }
|
|
72
|
+
let(:inventory_unit_1) { line_item.inventory_units[0] }
|
|
73
|
+
let(:inventory_unit_2) { line_item.inventory_units[1] }
|
|
74
|
+
|
|
75
|
+
before do
|
|
76
|
+
order.contents.add(line_item.variant)
|
|
77
|
+
line_item.reload
|
|
78
|
+
|
|
79
|
+
# make the total $1.67 so it divides unevenly
|
|
80
|
+
Spree::Adjustment.tax.create!(
|
|
81
|
+
order: order,
|
|
82
|
+
adjustable: line_item,
|
|
83
|
+
amount: 0.01,
|
|
84
|
+
label: 'some fake tax',
|
|
85
|
+
state: 'closed',
|
|
86
|
+
)
|
|
87
|
+
order.update!
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "generates the correct total amount" do
|
|
91
|
+
order.cancellations.short_ship([inventory_unit_1])
|
|
92
|
+
order.cancellations.short_ship([inventory_unit_2])
|
|
93
|
+
expect(line_item.adjustments.non_tax.sum(:amount)).to eq -1.67
|
|
94
|
+
expect(line_item.total).to eq 0
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe 'short_ship_tax_notifier' do
|
|
99
|
+
context 'when present' do
|
|
100
|
+
let(:short_ship_tax_notifier) { double }
|
|
101
|
+
|
|
102
|
+
before do
|
|
103
|
+
@old_notifier = Spree::OrderCancellations.short_ship_tax_notifier
|
|
104
|
+
Spree::OrderCancellations.short_ship_tax_notifier = short_ship_tax_notifier
|
|
105
|
+
end
|
|
106
|
+
after do
|
|
107
|
+
Spree::OrderCancellations.short_ship_tax_notifier = @old_notifier
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'calls the short_ship_tax_notifier' do
|
|
111
|
+
expect(short_ship_tax_notifier).to receive(:call) do |unit_cancels|
|
|
112
|
+
expect(unit_cancels.map(&:inventory_unit)).to match_array([inventory_unit])
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
order.cancellations.short_ship([inventory_unit])
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::OrderCapturing do
|
|
4
|
+
describe '#capture_payments' do
|
|
5
|
+
subject { Spree::OrderCapturing.new(order, payment_methods).capture_payments }
|
|
6
|
+
|
|
7
|
+
context "payment methods specified" do
|
|
8
|
+
let!(:order) { create(:order, ship_address: create(:address)) }
|
|
9
|
+
|
|
10
|
+
let!(:product) { create(:product, price: 10.00) }
|
|
11
|
+
let!(:variant) do
|
|
12
|
+
create(:variant, price: 10, product: product, track_inventory: false, tax_category: tax_rate.tax_category)
|
|
13
|
+
end
|
|
14
|
+
let!(:shipping_method) { create(:free_shipping_method) }
|
|
15
|
+
let(:tax_rate) { create(:tax_rate, amount: 0.1, zone: create(:global_zone, name: "Some Tax Zone")) }
|
|
16
|
+
let(:secondary_total) { 10.0 }
|
|
17
|
+
let(:bogus_total) { order.total }
|
|
18
|
+
|
|
19
|
+
before do
|
|
20
|
+
order.contents.add(variant, 3)
|
|
21
|
+
order.update!
|
|
22
|
+
@secondary_bogus_payment = create(:payment, order: order, amount: secondary_total, payment_method: secondary_payment_method.create!(name: 'So bogus', environment: 'test'))
|
|
23
|
+
@bogus_payment = create(:payment, order: order, amount: bogus_total)
|
|
24
|
+
order.contents.advance
|
|
25
|
+
order.complete!
|
|
26
|
+
order.reload
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "payment method ordering" do
|
|
30
|
+
let(:secondary_payment_method) { SecondaryBogusPaymentMethod }
|
|
31
|
+
|
|
32
|
+
class SecondaryBogusPaymentMethod < Spree::Gateway::Bogus; end
|
|
33
|
+
|
|
34
|
+
context "SecondaryBogusPaymentMethod payments are prioritized" do
|
|
35
|
+
let(:payment_methods) { [SecondaryBogusPaymentMethod, Spree::Gateway::Bogus] }
|
|
36
|
+
|
|
37
|
+
it "captures SecondaryBogusPaymentMethod payments first" do
|
|
38
|
+
subject
|
|
39
|
+
expect(@secondary_bogus_payment.reload.capture_events.sum(:amount)).to eq(10.0)
|
|
40
|
+
expect(@bogus_payment.reload.capture_events.sum(:amount)).to eq(order.total - 10.0)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "Bogus payments are prioritized" do
|
|
45
|
+
let(:payment_methods) { [Spree::Gateway::Bogus, SecondaryBogusPaymentMethod] }
|
|
46
|
+
|
|
47
|
+
it "captures Bogus payments first" do
|
|
48
|
+
subject
|
|
49
|
+
expect(@secondary_bogus_payment.reload.capture_events.sum(:amount)).to eq(0.0)
|
|
50
|
+
expect(@bogus_payment.reload.capture_events.sum(:amount)).to eq(order.total)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "when the payment method ordering is configured" do
|
|
55
|
+
subject { Spree::OrderCapturing.new(order, payment_methods).capture_payments }
|
|
56
|
+
|
|
57
|
+
let(:payment_methods) { nil }
|
|
58
|
+
|
|
59
|
+
before do
|
|
60
|
+
allow(Spree::OrderCapturing).to receive(:sorted_payment_method_classes).and_return(
|
|
61
|
+
[SecondaryBogusPaymentMethod, Spree::Gateway::Bogus]
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "captures in the order specified" do
|
|
66
|
+
subject
|
|
67
|
+
expect(@secondary_bogus_payment.reload.capture_events.sum(:amount)).to eq(10.0)
|
|
68
|
+
expect(@bogus_payment.reload.capture_events.sum(:amount)).to eq(order.total - 10.0)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context "when a payment is not needed to capture the entire order" do
|
|
74
|
+
let(:bogus_total) { order.total }
|
|
75
|
+
let(:secondary_payment_method) { SecondaryBogusPaymentMethod }
|
|
76
|
+
let(:payment_methods) { [Spree::Gateway::Bogus, SecondaryBogusPaymentMethod] }
|
|
77
|
+
|
|
78
|
+
context "when void_unused_payments is true" do
|
|
79
|
+
before { allow(Spree::OrderCapturing).to receive(:void_unused_payments).and_return(true) }
|
|
80
|
+
|
|
81
|
+
it "captures for the order and voids the unused payment" do
|
|
82
|
+
subject
|
|
83
|
+
expect(order.reload.payment_state).to eq 'paid'
|
|
84
|
+
expect(@secondary_bogus_payment.reload.state).to eq 'void'
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "when void_unused_payments is false" do
|
|
89
|
+
it "captures for the order and leaves the unused payment in a pending state" do
|
|
90
|
+
subject
|
|
91
|
+
expect(order.reload.payment_state).to eq 'paid'
|
|
92
|
+
expect(@secondary_bogus_payment.reload.state).to eq 'pending'
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context "when there is an error processing a payment" do
|
|
98
|
+
let(:secondary_payment_method) { ExceptionallyBogusPaymentMethod }
|
|
99
|
+
let(:bogus_total) { order.total - 1 }
|
|
100
|
+
let(:secondary_total) { 1 }
|
|
101
|
+
let(:payment_methods) { [Spree::Gateway::Bogus, ExceptionallyBogusPaymentMethod] }
|
|
102
|
+
|
|
103
|
+
class ExceptionallyBogusPaymentMethod < Spree::Gateway::Bogus
|
|
104
|
+
def capture(*args)
|
|
105
|
+
raise ActiveMerchant::ConnectionError.new("foo", nil)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "raises an error and leaves the order in a reasonable state" do
|
|
110
|
+
expect { subject }.to raise_error(Spree::Core::GatewayError)
|
|
111
|
+
expect(order.payments.to_a.sum(&:uncaptured_amount)).to eq 1.0
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::OrderContents, :type => :model do
|
|
4
|
+
let(:order) { Spree::Order.create }
|
|
5
|
+
let(:variant) { create(:variant) }
|
|
6
|
+
let!(:stock_location) { variant.stock_locations.first }
|
|
7
|
+
let(:stock_location_2) { create(:stock_location) }
|
|
8
|
+
|
|
9
|
+
subject { described_class.new(order) }
|
|
10
|
+
|
|
11
|
+
context "#add" do
|
|
12
|
+
context 'given quantity is not explicitly provided' do
|
|
13
|
+
it 'should add one line item' do
|
|
14
|
+
line_item = subject.add(variant)
|
|
15
|
+
expect(line_item.quantity).to eq(1)
|
|
16
|
+
expect(order.line_items.size).to eq(1)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'given a shipment' do
|
|
21
|
+
it "ensure shipment calls update_amounts instead of order calling ensure_updated_shipments" do
|
|
22
|
+
shipment = create(:shipment)
|
|
23
|
+
expect(subject.order).to_not receive(:ensure_updated_shipments)
|
|
24
|
+
expect(shipment).to receive(:update_amounts)
|
|
25
|
+
subject.add(variant, 1, shipment: shipment)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'not given a shipment' do
|
|
30
|
+
it "ensures updated shipments" do
|
|
31
|
+
expect(subject.order).to receive(:ensure_updated_shipments)
|
|
32
|
+
subject.add(variant)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should add line item if one does not exist' do
|
|
37
|
+
line_item = subject.add(variant, 1)
|
|
38
|
+
expect(line_item.quantity).to eq(1)
|
|
39
|
+
expect(order.line_items.size).to eq(1)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'should update line item if one exists' do
|
|
43
|
+
subject.add(variant, 1)
|
|
44
|
+
line_item = subject.add(variant, 1)
|
|
45
|
+
expect(line_item.quantity).to eq(2)
|
|
46
|
+
expect(order.line_items.size).to eq(1)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should update order totals" do
|
|
50
|
+
expect(order.item_total.to_f).to eq(0.00)
|
|
51
|
+
expect(order.total.to_f).to eq(0.00)
|
|
52
|
+
|
|
53
|
+
subject.add(variant, 1)
|
|
54
|
+
|
|
55
|
+
expect(order.item_total.to_f).to eq(19.99)
|
|
56
|
+
expect(order.total.to_f).to eq(19.99)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should create stock location associations if provided" do
|
|
60
|
+
line_item = subject.add(variant, 3, stock_location_quantities: {stock_location.id => 1, stock_location_2.id => 2})
|
|
61
|
+
order_stock_locations = line_item.order.order_stock_locations
|
|
62
|
+
expect(order_stock_locations.count).to eq(2)
|
|
63
|
+
expect(order_stock_locations.map(&:quantity)).to eq([1, 2])
|
|
64
|
+
expect(order_stock_locations.map(&:stock_location_id)).to eq([stock_location.id, stock_location_2.id])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "running promotions" do
|
|
68
|
+
let(:promotion) { create(:promotion) }
|
|
69
|
+
let(:calculator) { Spree::Calculator::FlatRate.new(:preferred_amount => 10) }
|
|
70
|
+
|
|
71
|
+
shared_context "discount changes order total" do
|
|
72
|
+
before { subject.add(variant, 1) }
|
|
73
|
+
it { expect(subject.order.total).not_to eq variant.price }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "one active order promotion" do
|
|
77
|
+
let!(:action) { Spree::Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
|
|
78
|
+
|
|
79
|
+
it "creates valid discount on order" do
|
|
80
|
+
subject.add(variant, 1)
|
|
81
|
+
expect(subject.order.adjustments.to_a.sum(&:amount)).not_to eq 0
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
include_context "discount changes order total"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "one active line item promotion" do
|
|
88
|
+
let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
|
|
89
|
+
|
|
90
|
+
it "creates valid discount on order" do
|
|
91
|
+
subject.add(variant, 1)
|
|
92
|
+
expect(subject.order.line_item_adjustments.to_a.sum(&:amount)).not_to eq 0
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
include_context "discount changes order total"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context "#remove" do
|
|
101
|
+
context "given an invalid variant" do
|
|
102
|
+
it "raises an exception" do
|
|
103
|
+
expect {
|
|
104
|
+
subject.remove(variant, 1)
|
|
105
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context 'given quantity is not explicitly provided' do
|
|
110
|
+
it 'should remove one line item' do
|
|
111
|
+
line_item = subject.add(variant, 3)
|
|
112
|
+
subject.remove(variant)
|
|
113
|
+
|
|
114
|
+
expect(line_item.reload.quantity).to eq(2)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
context 'given a shipment' do
|
|
119
|
+
it "ensure shipment calls update_amounts instead of order calling ensure_updated_shipments" do
|
|
120
|
+
line_item = subject.add(variant, 1)
|
|
121
|
+
shipment = create(:shipment)
|
|
122
|
+
expect(subject.order).to_not receive(:ensure_updated_shipments)
|
|
123
|
+
expect(shipment).to receive(:update_amounts)
|
|
124
|
+
subject.remove(variant, 1, shipment: shipment)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context 'not given a shipment' do
|
|
129
|
+
it "ensures updated shipments" do
|
|
130
|
+
line_item = subject.add(variant, 1)
|
|
131
|
+
expect(subject.order).to receive(:ensure_updated_shipments)
|
|
132
|
+
subject.remove(variant)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
it 'should reduce line_item quantity if quantity is less the line_item quantity' do
|
|
137
|
+
line_item = subject.add(variant, 3)
|
|
138
|
+
subject.remove(variant, 1)
|
|
139
|
+
|
|
140
|
+
expect(line_item.reload.quantity).to eq(2)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'should remove line_item if quantity matches line_item quantity' do
|
|
144
|
+
subject.add(variant, 1)
|
|
145
|
+
subject.remove(variant, 1)
|
|
146
|
+
|
|
147
|
+
expect(order.reload.find_line_item_by_variant(variant)).to be_nil
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "should update order totals" do
|
|
151
|
+
expect(order.item_total.to_f).to eq(0.00)
|
|
152
|
+
expect(order.total.to_f).to eq(0.00)
|
|
153
|
+
|
|
154
|
+
subject.add(variant,2)
|
|
155
|
+
|
|
156
|
+
expect(order.item_total.to_f).to eq(39.98)
|
|
157
|
+
expect(order.total.to_f).to eq(39.98)
|
|
158
|
+
|
|
159
|
+
subject.remove(variant,1)
|
|
160
|
+
expect(order.item_total.to_f).to eq(19.99)
|
|
161
|
+
expect(order.total.to_f).to eq(19.99)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
context "update cart" do
|
|
166
|
+
let!(:shirt) { subject.add variant, 1 }
|
|
167
|
+
|
|
168
|
+
let(:params) do
|
|
169
|
+
{ line_items_attributes: {
|
|
170
|
+
"0" => { id: shirt.id, quantity: 3 }
|
|
171
|
+
} }
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it "changes item quantity" do
|
|
175
|
+
subject.update_cart params
|
|
176
|
+
expect(shirt.reload.quantity).to eq 3
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "updates order totals" do
|
|
180
|
+
expect {
|
|
181
|
+
subject.update_cart params
|
|
182
|
+
}.to change { subject.order.total }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context "submits item quantity 0" do
|
|
186
|
+
let(:params) do
|
|
187
|
+
{ line_items_attributes: {
|
|
188
|
+
"0" => { id: shirt.id, quantity: 0 },
|
|
189
|
+
} }
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "removes item from order" do
|
|
193
|
+
expect {
|
|
194
|
+
subject.update_cart params
|
|
195
|
+
}.to change { subject.order.line_items.count }
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "ensures updated shipments" do
|
|
200
|
+
expect(subject.order).to receive(:ensure_updated_shipments)
|
|
201
|
+
subject.update_cart params
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "completed order" do
|
|
206
|
+
let(:order) { Spree::Order.create! state: 'complete', completed_at: Time.now }
|
|
207
|
+
|
|
208
|
+
before { order.shipments.create! stock_location_id: variant.stock_location_ids.first }
|
|
209
|
+
|
|
210
|
+
it "updates order payment state" do
|
|
211
|
+
expect {
|
|
212
|
+
subject.add variant
|
|
213
|
+
}.to change { order.payment_state }
|
|
214
|
+
|
|
215
|
+
expect {
|
|
216
|
+
subject.remove variant
|
|
217
|
+
}.to change { order.payment_state }
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
describe "#approve" do
|
|
222
|
+
context 'when a name is supplied' do
|
|
223
|
+
it 'approves the order' do
|
|
224
|
+
order.contents.approve(name: 'Jordan')
|
|
225
|
+
expect(order.approver).to be_nil
|
|
226
|
+
expect(order.approver_name).to eq('Jordan')
|
|
227
|
+
expect(order.approved_at).to be_present
|
|
228
|
+
expect(order.approved?).to be_truthy
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
context 'when a user is supplied' do
|
|
233
|
+
let(:user) { create(:user) }
|
|
234
|
+
|
|
235
|
+
it 'approves the order' do
|
|
236
|
+
order.contents.approve(user: user)
|
|
237
|
+
expect(order.approver).to eq(user)
|
|
238
|
+
expect(order.approver_name).to be_nil
|
|
239
|
+
expect(order.approved_at).to be_present
|
|
240
|
+
expect(order.approved?).to be_truthy
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
context 'when a user and a name are supplied' do
|
|
245
|
+
let(:user) { create(:user) }
|
|
246
|
+
|
|
247
|
+
it 'approves the order' do
|
|
248
|
+
order.contents.approve(user: user, name: 'Jordan')
|
|
249
|
+
expect(order.approver).to eq(user)
|
|
250
|
+
expect(order.approver_name).to eq('Jordan')
|
|
251
|
+
expect(order.approved_at).to be_present
|
|
252
|
+
expect(order.approved?).to be_truthy
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
context 'when neither a user nor a name are supplied' do
|
|
257
|
+
it 'raises' do
|
|
258
|
+
expect {
|
|
259
|
+
order.contents.approve
|
|
260
|
+
}.to raise_error(ArgumentError, 'user or name must be specified')
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
end
|