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,138 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::RoleConfiguration do
|
|
4
|
+
class DummyPermissionSet < Spree::PermissionSets::Base
|
|
5
|
+
def activate!
|
|
6
|
+
can :manage, :things
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
class OtherDummyPermissionSet < Spree::PermissionSets::Base; end
|
|
10
|
+
|
|
11
|
+
let(:instance) { described_class.instance }
|
|
12
|
+
let!(:default_roles) do
|
|
13
|
+
Hash.new do |h, name|
|
|
14
|
+
h[name] = described_class::Role.new(name, Set.new)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe ".configure" do
|
|
19
|
+
it "yields with the instance" do
|
|
20
|
+
expect { |b| described_class.configure &b }.to yield_with_args(described_class.instance)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "only yields once" do
|
|
24
|
+
expect { |b| described_class.configure &b }.to yield_control.once
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#assign_permissions" do
|
|
29
|
+
let(:name) { "thing" }
|
|
30
|
+
subject { instance.assign_permissions name, [DummyPermissionSet]}
|
|
31
|
+
|
|
32
|
+
after do
|
|
33
|
+
instance.roles = default_roles
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "when a role for the name exists" do
|
|
37
|
+
before do
|
|
38
|
+
instance.roles.merge!({ name => described_class::Role.new(name, Set.new(existing_roles)) })
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "when adding duplicate permission sets" do
|
|
42
|
+
let(:existing_roles) { [DummyPermissionSet] }
|
|
43
|
+
|
|
44
|
+
it "does not add another role" do
|
|
45
|
+
expect{subject}.to_not change{instance.roles.count}
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "does not add duplicate permission sets" do
|
|
49
|
+
subject
|
|
50
|
+
role = instance.roles.values.detect { |r| r.name == name }
|
|
51
|
+
expect(role.permission_sets).to match_array([DummyPermissionSet])
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context "when adding new permission sets to an existing role" do
|
|
56
|
+
let(:existing_roles) { [OtherDummyPermissionSet] }
|
|
57
|
+
|
|
58
|
+
it "does not add another role" do
|
|
59
|
+
expect{subject}.to_not change{instance.roles.count}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "appends the permission set to the existing role" do
|
|
63
|
+
subject
|
|
64
|
+
role = instance.roles.values.detect { |r| r.name == name }
|
|
65
|
+
expect(role.permission_sets).to match_array([OtherDummyPermissionSet, DummyPermissionSet])
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context "when a role for the name does not yet exist" do
|
|
71
|
+
it "creates a new role" do
|
|
72
|
+
expect{subject}.to change{instance.roles.count}.from(0).to(1)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "sets the roles name accordingly" do
|
|
76
|
+
subject
|
|
77
|
+
expect(instance.roles.values.first.name).to eql(name)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "sets the permission sets accordingly" do
|
|
81
|
+
subject
|
|
82
|
+
expect(instance.roles.values.first.permission_sets).to match_array([DummyPermissionSet])
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "#activate_permissions!" do
|
|
88
|
+
let(:user) { build :user }
|
|
89
|
+
let(:roles_double) { double pluck: user_roles, any?: true }
|
|
90
|
+
let(:role_name) { "testrole" }
|
|
91
|
+
let(:ability) { DummyAbility.new }
|
|
92
|
+
|
|
93
|
+
before do
|
|
94
|
+
allow(user).to receive(:spree_roles).and_return(roles_double)
|
|
95
|
+
allow(user).to receive(:has_spree_role?).with("admin").and_return(false)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
after do
|
|
99
|
+
instance.roles = default_roles
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
subject { described_class.instance.activate_permissions! ability, user }
|
|
103
|
+
|
|
104
|
+
context "when the configuration has roles" do
|
|
105
|
+
before do
|
|
106
|
+
instance.roles.merge!({ role_name => described_class::Role.new(role_name, [DummyPermissionSet])})
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context "when the configuration has applicable roles" do
|
|
110
|
+
let(:user_roles) {[role_name, "someotherrandomrole"]}
|
|
111
|
+
|
|
112
|
+
it "activates the applicable permissions on the ability" do
|
|
113
|
+
expect{subject}.to change{ability.can? :manage, :things}.
|
|
114
|
+
from(false).
|
|
115
|
+
to(true)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "when the configuration does not have applicable roles" do
|
|
120
|
+
let(:user_roles) {["somerandomrole"]}
|
|
121
|
+
|
|
122
|
+
it "doesn't activate non matching roles" do
|
|
123
|
+
subject
|
|
124
|
+
expect(ability.can? :manage, :things).to be false
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context "when the configuration does not have roles" do
|
|
130
|
+
let(:user_roles) {["somerandomrole"]}
|
|
131
|
+
|
|
132
|
+
it "doesnt activate any new permissions" do
|
|
133
|
+
subject
|
|
134
|
+
expect(ability.can? :manage, :things).to be false
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe EmailValidator do
|
|
4
|
+
|
|
5
|
+
class Tester
|
|
6
|
+
include ActiveModel::Validations
|
|
7
|
+
attr_accessor :email_address
|
|
8
|
+
validates :email_address, email: true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:valid_emails) {[
|
|
12
|
+
'valid@email.com',
|
|
13
|
+
'valid@email.com.uk',
|
|
14
|
+
'e@email.com',
|
|
15
|
+
'valid+email@email.com',
|
|
16
|
+
'valid-email@email.com',
|
|
17
|
+
'valid_email@email.com',
|
|
18
|
+
'valid.email@email.com'
|
|
19
|
+
]}
|
|
20
|
+
let(:invalid_emails) {[
|
|
21
|
+
'invalid email@email.com',
|
|
22
|
+
'.invalid.email@email.com',
|
|
23
|
+
'invalid.email.@email.com',
|
|
24
|
+
'@email.com',
|
|
25
|
+
'.@email.com',
|
|
26
|
+
'invalidemailemail.com',
|
|
27
|
+
'@invalid.email@email.com',
|
|
28
|
+
'invalid@email@email.com',
|
|
29
|
+
'invalid.email@@email.com'
|
|
30
|
+
]}
|
|
31
|
+
|
|
32
|
+
it 'validates valid email addresses' do
|
|
33
|
+
tester = Tester.new
|
|
34
|
+
valid_emails.each do |email|
|
|
35
|
+
tester.email_address = email
|
|
36
|
+
expect(tester.valid?).to be true
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'validates invalid email addresses' do
|
|
41
|
+
tester = Tester.new
|
|
42
|
+
invalid_emails.each do |email|
|
|
43
|
+
tester.email_address = email
|
|
44
|
+
expect(tester.valid?).to be false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::LocalizedNumber do
|
|
4
|
+
|
|
5
|
+
context ".parse" do
|
|
6
|
+
before do
|
|
7
|
+
I18n.enforce_available_locales = false
|
|
8
|
+
I18n.locale = I18n.default_locale
|
|
9
|
+
I18n.backend.store_translations(:de, { :number => { :currency => { :format => { :delimiter => '.', :separator => ',' } } } })
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after do
|
|
13
|
+
I18n.locale = I18n.default_locale
|
|
14
|
+
I18n.enforce_available_locales = true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context "with decimal point" do
|
|
18
|
+
it "captures the proper amount for a formatted price" do
|
|
19
|
+
expect(subject.class.parse('1,599.99')).to eql 1599.99
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "with decimal comma" do
|
|
24
|
+
it "captures the proper amount for a formatted price" do
|
|
25
|
+
I18n.locale = :de
|
|
26
|
+
expect(subject.class.parse('1.599,99')).to eql 1599.99
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "with a numeric price" do
|
|
31
|
+
it "uses the price as is" do
|
|
32
|
+
I18n.locale = :de
|
|
33
|
+
expect(subject.class.parse(1599.99)).to eql 1599.99
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe Migrations do
|
|
5
|
+
let(:app_migrations) { [".", "34_add_title.rb", "52_add_text.rb"] }
|
|
6
|
+
let(:engine_migrations) { [".", "334_create_orders.spree.rb", "777_create_products.spree.rb"] }
|
|
7
|
+
|
|
8
|
+
let(:config) { double("Config", root: "dir") }
|
|
9
|
+
|
|
10
|
+
let(:engine_dir) { "dir/db/migrate" }
|
|
11
|
+
let(:app_dir) { "#{Rails.root}/db/migrate" }
|
|
12
|
+
|
|
13
|
+
subject { described_class.new(config, "spree") }
|
|
14
|
+
|
|
15
|
+
before do
|
|
16
|
+
expect(File).to receive(:directory?).with(app_dir).and_return true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "warns about missing migrations" do
|
|
20
|
+
expect(Dir).to receive(:entries).with(app_dir).and_return app_migrations
|
|
21
|
+
expect(Dir).to receive(:entries).with(engine_dir).and_return engine_migrations
|
|
22
|
+
|
|
23
|
+
silence_stream(STDOUT) {
|
|
24
|
+
expect(subject.check).to eq true
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "no missing migrations" do
|
|
29
|
+
it "says nothing" do
|
|
30
|
+
expect(Dir).to receive(:entries).with(engine_dir).and_return engine_migrations
|
|
31
|
+
expect(Dir).to receive(:entries).with(app_dir).and_return (app_migrations + engine_migrations)
|
|
32
|
+
expect(subject.check).to eq nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe Spree::Money do
|
|
5
|
+
before do
|
|
6
|
+
configure_spree_preferences do |config|
|
|
7
|
+
config.currency = "USD"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "formats correctly" do
|
|
12
|
+
money = Spree::Money.new(10)
|
|
13
|
+
expect(money.to_s).to eq("$10.00")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "can get cents" do
|
|
17
|
+
money = Spree::Money.new(10)
|
|
18
|
+
expect(money.cents).to eq(1000)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
context "with currency" do
|
|
22
|
+
it "passed in option" do
|
|
23
|
+
money = Spree::Money.new(10, :with_currency => true, :html => false)
|
|
24
|
+
expect(money.to_s).to eq("$10.00 USD")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "hide cents" do
|
|
29
|
+
it "hides cents suffix" do
|
|
30
|
+
money = Spree::Money.new(10, no_cents: true)
|
|
31
|
+
expect(money.to_s).to eq("$10")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "shows cents suffix" do
|
|
35
|
+
money = Spree::Money.new(10)
|
|
36
|
+
expect(money.to_s).to eq("$10.00")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "currency parameter" do
|
|
41
|
+
context "when currency is specified in Canadian Dollars" do
|
|
42
|
+
it "uses the currency param over the global configuration" do
|
|
43
|
+
money = Spree::Money.new(10, :currency => 'CAD', :with_currency => true, :html => false)
|
|
44
|
+
expect(money.to_s).to eq("$10.00 CAD")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "when currency is specified in Japanese Yen" do
|
|
49
|
+
it "uses the currency param over the global configuration" do
|
|
50
|
+
money = Spree::Money.new(100, :currency => 'JPY', :html => false)
|
|
51
|
+
expect(money.to_s).to eq("¥100")
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "symbol positioning" do
|
|
57
|
+
it "passed in option" do
|
|
58
|
+
money = Spree::Money.new(10, :symbol_position => :after, :html => false)
|
|
59
|
+
expect(money.to_s).to eq("10.00 $")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "config option" do
|
|
63
|
+
money = Spree::Money.new(10, symbol_position: :after, html: false)
|
|
64
|
+
expect(money.to_s).to eq("10.00 $")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "sign before symbol" do
|
|
69
|
+
it "defaults to -$10.00" do
|
|
70
|
+
money = Spree::Money.new(-10)
|
|
71
|
+
expect(money.to_s).to eq("-$10.00")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "passed in option" do
|
|
75
|
+
money = Spree::Money.new(-10, :sign_before_symbol => false)
|
|
76
|
+
expect(money.to_s).to eq("$-10.00")
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context "JPY" do
|
|
81
|
+
before do
|
|
82
|
+
configure_spree_preferences do |config|
|
|
83
|
+
config.currency = "JPY"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "formats correctly" do
|
|
88
|
+
money = Spree::Money.new(1000, :html => false)
|
|
89
|
+
expect(money.to_s).to eq("¥1,000")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context "EUR" do
|
|
94
|
+
before do
|
|
95
|
+
configure_spree_preferences do |config|
|
|
96
|
+
config.currency = "EUR"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Regression test for #2634
|
|
101
|
+
it "formats as plain by default" do
|
|
102
|
+
money = Spree::Money.new(10, symbol_position: :after)
|
|
103
|
+
expect(money.to_s).to eq("10.00 €")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "formats as HTML if asked (nicely) to" do
|
|
107
|
+
money = Spree::Money.new(10, symbol_position: :after)
|
|
108
|
+
# The HTML'ified version of "10.00 €"
|
|
109
|
+
expect(money.to_html).to eq("10.00 €")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "formats as HTML with currency" do
|
|
113
|
+
money = Spree::Money.new(10, symbol_position: :after, with_currency: true)
|
|
114
|
+
# The HTML'ified version of "10.00 €"
|
|
115
|
+
expect(money.to_html).to eq("10.00 € <span class=\"currency\">EUR</span>")
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
describe "#as_json" do
|
|
120
|
+
let(:options) { double('options') }
|
|
121
|
+
|
|
122
|
+
it "returns the expected string" do
|
|
123
|
+
money = Spree::Money.new(10)
|
|
124
|
+
expect(money.as_json(options)).to eq("$10.00")
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "exchanges:charge_unreturned_items" do
|
|
4
|
+
let(:task) do
|
|
5
|
+
Rake::Task['exchanges:charge_unreturned_items']
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
before do
|
|
9
|
+
Rails.application.load_tasks
|
|
10
|
+
task.reenable
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
subject { task }
|
|
14
|
+
|
|
15
|
+
describe '#prerequisites' do
|
|
16
|
+
it { expect(subject.prerequisites).to include("environment") }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
before do
|
|
20
|
+
@original_expedited_exchanges_pref = Spree::Config[:expedited_exchanges]
|
|
21
|
+
Spree::Config[:expedited_exchanges] = true
|
|
22
|
+
Spree::StockItem.update_all(count_on_hand: 10)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after { Spree::Config[:expedited_exchanges] = @original_expedited_exchanges_pref }
|
|
26
|
+
|
|
27
|
+
context "there are no unreturned items" do
|
|
28
|
+
it { expect { subject.invoke }.not_to change { Spree::Order.count } }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "there are return items in an intermediate return status" do
|
|
32
|
+
let!(:order) { create(:shipped_order, line_items_count: 2) }
|
|
33
|
+
let(:return_item_1) { build(:exchange_return_item, inventory_unit: order.inventory_units.first) }
|
|
34
|
+
let(:return_item_2) { build(:exchange_return_item, inventory_unit: order.inventory_units.last) }
|
|
35
|
+
let!(:rma) { create(:return_authorization, order: order, return_items: [return_item_1, return_item_2]) }
|
|
36
|
+
let!(:tax_rate) { create(:tax_rate, zone: order.tax_zone, tax_category: return_item_2.exchange_variant.tax_category) }
|
|
37
|
+
before do
|
|
38
|
+
rma.save!
|
|
39
|
+
Spree::Shipment.last.ship!
|
|
40
|
+
return_item_1.lost!
|
|
41
|
+
return_item_2.give!
|
|
42
|
+
Timecop.travel (Spree::Config[:expedited_exchanges_days_window] + 1).days
|
|
43
|
+
end
|
|
44
|
+
after { Timecop.return }
|
|
45
|
+
it { expect { subject.invoke }.not_to change { Spree::Order.count } }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "there are unreturned items" do
|
|
49
|
+
let!(:order) { create(:shipped_order, line_items_count: 2) }
|
|
50
|
+
let(:return_item_1) { build(:exchange_return_item, inventory_unit: order.inventory_units.first) }
|
|
51
|
+
let(:return_item_2) { build(:exchange_return_item, inventory_unit: order.inventory_units.last) }
|
|
52
|
+
let!(:rma) { create(:return_authorization, order: order, return_items: [return_item_1, return_item_2]) }
|
|
53
|
+
let!(:tax_rate) { create(:tax_rate, zone: order.tax_zone, tax_category: return_item_2.exchange_variant.tax_category) }
|
|
54
|
+
|
|
55
|
+
before do
|
|
56
|
+
rma.save!
|
|
57
|
+
Spree::Shipment.last.ship!
|
|
58
|
+
return_item_1.receive!
|
|
59
|
+
Timecop.travel travel_time
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
after { Timecop.return }
|
|
63
|
+
|
|
64
|
+
context "fewer than the config allowed days have passed" do
|
|
65
|
+
let(:travel_time) { (Spree::Config[:expedited_exchanges_days_window] - 1).days }
|
|
66
|
+
|
|
67
|
+
it "does not create a new order" do
|
|
68
|
+
expect { subject.invoke }.not_to change { Spree::Order.count }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "more than the config allowed days have passed" do
|
|
73
|
+
|
|
74
|
+
let(:travel_time) { (Spree::Config[:expedited_exchanges_days_window] + 1).days }
|
|
75
|
+
|
|
76
|
+
it "creates a new completed order" do
|
|
77
|
+
expect { subject.invoke }.to change { Spree::Order.count }
|
|
78
|
+
expect(Spree::Order.last).to be_completed
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "sets frontend_viewable to false" do
|
|
82
|
+
subject.invoke
|
|
83
|
+
expect(Spree::Order.last).not_to be_frontend_viewable
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "moves the shipment for the unreturned items to the new order" do
|
|
87
|
+
subject.invoke
|
|
88
|
+
new_order = Spree::Order.last
|
|
89
|
+
expect(new_order.shipments.count).to eq 1
|
|
90
|
+
expect(return_item_2.reload.exchange_shipment.order).to eq Spree::Order.last
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "creates line items on the order for the unreturned items" do
|
|
94
|
+
subject.invoke
|
|
95
|
+
expect(Spree::Order.last.line_items.map(&:variant)).to eq [return_item_2.exchange_variant]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "associates the exchanges inventory units with the new line items" do
|
|
99
|
+
subject.invoke
|
|
100
|
+
expect(return_item_2.reload.exchange_inventory_unit.try(:line_item).try(:order)).to eq Spree::Order.last
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "uses the credit card from the previous order" do
|
|
104
|
+
subject.invoke
|
|
105
|
+
new_order = Spree::Order.last
|
|
106
|
+
expect(new_order.credit_cards).to be_present
|
|
107
|
+
expect(new_order.credit_cards.first).to eq order.valid_credit_cards.first
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "payments" do
|
|
111
|
+
it "authorizes the order for the full amount of the unreturned items including taxes" do
|
|
112
|
+
expect { subject.invoke }.to change { Spree::Payment.count }.by(1)
|
|
113
|
+
new_order = Spree::Order.last
|
|
114
|
+
expected_amount = return_item_2.reload.exchange_variant.price + new_order.additional_tax_total + new_order.included_tax_total + new_order.shipment_total
|
|
115
|
+
expect(new_order.total).to eq expected_amount
|
|
116
|
+
payment = new_order.payments.first
|
|
117
|
+
expect(payment.amount).to eq expected_amount
|
|
118
|
+
expect(new_order.item_total).to eq return_item_2.reload.exchange_variant.price
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "auto_capture_exchanges is true" do
|
|
122
|
+
before do
|
|
123
|
+
@original_auto_capture_exchanges = Spree::Config[:auto_capture_exchanges]
|
|
124
|
+
Spree::Config[:auto_capture_exchanges] = true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
after { Spree::Config[:auto_capture_exchanges] = @original_auto_capture_exchanges }
|
|
128
|
+
|
|
129
|
+
it 'creates a pending payment' do
|
|
130
|
+
expect { subject.invoke }.to change { Spree::Payment.count }.by(1)
|
|
131
|
+
payment = Spree::Payment.last
|
|
132
|
+
expect(payment).to be_completed
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "auto_capture_exchanges is false" do
|
|
137
|
+
before do
|
|
138
|
+
@original_auto_capture_exchanges = Spree::Config[:auto_capture_exchanges]
|
|
139
|
+
Spree::Config[:auto_capture_exchanges] = false
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
after { Spree::Config[:auto_capture_exchanges] = @original_auto_capture_exchanges }
|
|
143
|
+
|
|
144
|
+
it 'captures payment' do
|
|
145
|
+
expect { subject.invoke }.to change { Spree::Payment.count }.by(1)
|
|
146
|
+
payment = Spree::Payment.last
|
|
147
|
+
expect(payment).to be_pending
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "does not attempt to create a new order for the item more than once" do
|
|
153
|
+
subject.invoke
|
|
154
|
+
subject.reenable
|
|
155
|
+
expect { subject.invoke }.not_to change { Spree::Order.count }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "associates the store of the original order with the exchange order" do
|
|
159
|
+
store = order.store
|
|
160
|
+
expect(Spree::Order).to receive(:create!).once.with(hash_including({store_id: store.id})).and_call_original
|
|
161
|
+
subject.invoke
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'approves the order' do
|
|
165
|
+
subject.invoke
|
|
166
|
+
new_order = Spree::Order.last
|
|
167
|
+
expect(new_order).to be_approved
|
|
168
|
+
expect(new_order.is_risky?).to eq false
|
|
169
|
+
expect(new_order.approver_name).to eq "Spree::UnreturnedItemCharger"
|
|
170
|
+
expect(new_order.approver).to be nil
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
context "there is no card from the previous order" do
|
|
174
|
+
let!(:credit_card) { create(:credit_card, user: order.user, default: true, gateway_customer_profile_id: "BGS-123") }
|
|
175
|
+
before { allow_any_instance_of(Spree::Order).to receive(:valid_credit_cards) { [] } }
|
|
176
|
+
|
|
177
|
+
it "attempts to use the user's default card" do
|
|
178
|
+
expect { subject.invoke }.to change { Spree::Payment.count }.by(1)
|
|
179
|
+
new_order = Spree::Order.last
|
|
180
|
+
expect(new_order.credit_cards).to be_present
|
|
181
|
+
expect(new_order.credit_cards.first).to eq credit_card
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context "it is unable to authorize the credit card" do
|
|
186
|
+
before { allow_any_instance_of(Spree::Payment).to receive(:authorize!).and_raise(RuntimeError) }
|
|
187
|
+
|
|
188
|
+
it "raises an error with the order" do
|
|
189
|
+
expect { subject.invoke }.to raise_error(Spree::ChargeUnreturnedItemsFailures)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context "the exchange inventory unit is not shipped" do
|
|
194
|
+
before { return_item_2.reload.exchange_inventory_unit.update_columns(state: "on hand") }
|
|
195
|
+
it "does not create a new order" do
|
|
196
|
+
expect { subject.invoke }.not_to change { Spree::Order.count }
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
context "the exchange inventory unit has been returned" do
|
|
201
|
+
before { return_item_2.reload.exchange_inventory_unit.update_columns(state: "returned") }
|
|
202
|
+
it "does not create a new order" do
|
|
203
|
+
expect { subject.invoke }.not_to change { Spree::Order.count }
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
context 'rma for unreturned exchanges' do
|
|
208
|
+
context 'config to not create' do
|
|
209
|
+
before { Spree::Config[:create_rma_for_unreturned_exchange] = false }
|
|
210
|
+
|
|
211
|
+
it 'does not create rma' do
|
|
212
|
+
expect { subject.invoke }.not_to change { Spree::ReturnAuthorization.count }
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context 'config to create' do
|
|
217
|
+
before do
|
|
218
|
+
Spree::Config[:create_rma_for_unreturned_exchange] = true
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
it 'creates with return items' do
|
|
222
|
+
expect { subject.invoke }.to change { Spree::ReturnAuthorization.count }
|
|
223
|
+
rma = Spree::ReturnAuthorization.last
|
|
224
|
+
|
|
225
|
+
expect(rma.return_items.all?(&:awaiting?)).to be true
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|