solidus_core 1.1.0 → 1.1.1
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/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 +208 -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 +106 -0
- data/spec/lib/search/base_spec.rb +86 -0
- data/spec/lib/search/variant_spec.rb +112 -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/payment_parameters_spec.rb +80 -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 +24 -0
- data/spec/lib/spree/core/importer/order_spec.rb +431 -0
- data/spec/lib/spree/core/role_configuration_spec.rb +156 -0
- data/spec/lib/spree/core/unreturned_item_charger_spec.rb +130 -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 +55 -0
- data/spec/mailers/order_mailer_spec.rb +135 -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 +376 -0
- data/spec/models/spree/adjustment_reason_spec.rb +13 -0
- data/spec/models/spree/adjustment_spec.rb +169 -0
- data/spec/models/spree/app_configuration_spec.rb +24 -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 +60 -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 +93 -0
- data/spec/models/spree/concerns/display_money_spec.rb +43 -0
- data/spec/models/spree/concerns/ordered_property_value_list_spec.rb +25 -0
- data/spec/models/spree/concerns/user_address_book_spec.rb +332 -0
- data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
- data/spec/models/spree/credit_card_spec.rb +341 -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 +104 -0
- data/spec/models/spree/inventory_unit_spec.rb +307 -0
- data/spec/models/spree/item_adjustments_spec.rb +275 -0
- data/spec/models/spree/line_item_spec.rb +199 -0
- data/spec/models/spree/option_type_spec.rb +14 -0
- data/spec/models/spree/option_value_spec.rb +45 -0
- data/spec/models/spree/order/address_spec.rb +50 -0
- data/spec/models/spree/order/adjustments_spec.rb +27 -0
- data/spec/models/spree/order/callbacks_spec.rb +42 -0
- data/spec/models/spree/order/checkout_spec.rb +884 -0
- data/spec/models/spree/order/currency_updater_spec.rb +32 -0
- data/spec/models/spree/order/finalizing_spec.rb +110 -0
- data/spec/models/spree/order/payment_spec.rb +243 -0
- data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
- data/spec/models/spree/order/state_machine_spec.rb +209 -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 +150 -0
- data/spec/models/spree/order_contents_spec.rb +307 -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 +241 -0
- data/spec/models/spree/order_spec.rb +1482 -0
- data/spec/models/spree/order_stock_location_spec.rb +18 -0
- data/spec/models/spree/order_updater_spec.rb +283 -0
- data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
- data/spec/models/spree/payment_method_spec.rb +147 -0
- data/spec/models/spree/payment_spec.rb +1087 -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 +55 -0
- data/spec/models/spree/permission_sets/order_management_spec.rb +42 -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 +40 -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_stock_display_spec.rb +41 -0
- data/spec/models/spree/permission_sets/restricted_stock_management_spec.rb +41 -0
- data/spec/models/spree/permission_sets/restricted_stock_transfer_display_spec.rb +50 -0
- data/spec/models/spree/permission_sets/restricted_stock_transfer_management_spec.rb +160 -0
- data/spec/models/spree/permission_sets/stock_display_spec.rb +24 -0
- data/spec/models/spree/permission_sets/stock_management_spec.rb +22 -0
- data/spec/models/spree/permission_sets/stock_transfer_display_spec.rb +24 -0
- data/spec/models/spree/permission_sets/stock_transfer_management_spec.rb +25 -0
- data/spec/models/spree/permission_sets/user_display_spec.rb +38 -0
- data/spec/models/spree/permission_sets/user_management_spec.rb +48 -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 +60 -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 +116 -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 +18 -0
- data/spec/models/spree/product_spec.rb +504 -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/first_repeat_purchase_since_spec.rb +69 -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 +130 -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 +776 -0
- data/spec/models/spree/refund_spec.rb +192 -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 +776 -0
- data/spec/models/spree/returns_calculator_spec.rb +14 -0
- data/spec/models/spree/shipment_spec.rb +753 -0
- data/spec/models/spree/shipping_calculator_spec.rb +45 -0
- data/spec/models/spree/shipping_manifest_spec.rb +94 -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 +444 -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 +149 -0
- data/spec/models/spree/user_spec.rb +246 -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_property_rule_condition_spec.rb +15 -0
- data/spec/models/spree/variant_property_rule_spec.rb +83 -0
- data/spec/models/spree/variant_property_rule_value_spec.rb +18 -0
- data/spec/models/spree/variant_spec.rb +601 -0
- data/spec/models/spree/zone_spec.rb +305 -0
- data/spec/spec_helper.rb +80 -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 +242 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::OrderedPropertyValueList do
|
|
4
|
+
#
|
|
5
|
+
# Using ProductProperty as a subject
|
|
6
|
+
# since it includes OrderedPropertyValueList
|
|
7
|
+
#
|
|
8
|
+
let(:product_property) { create(:product_property) }
|
|
9
|
+
|
|
10
|
+
context "validations" do
|
|
11
|
+
# Only MySQL stores or stores that were migrated prior to the Rails 4.2
|
|
12
|
+
# upgrade have length limitations on "value":
|
|
13
|
+
# > The PostgreSQL and SQLite adapters no longer add a default limit of 255
|
|
14
|
+
# > characters on string columns.
|
|
15
|
+
# http://guides.rubyonrails.org/4_2_release_notes.html#active-record-notable-changes
|
|
16
|
+
# https://github.com/rails/rails/pull/14579
|
|
17
|
+
if Spree::ProductProperty.columns_hash['value'].limit
|
|
18
|
+
it "should validate length of value" do
|
|
19
|
+
overflow_length = Spree::ProductProperty.columns_hash['value'].limit + 1
|
|
20
|
+
product_property.value = "x" * overflow_length
|
|
21
|
+
expect(product_property).not_to be_valid
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Spree
|
|
4
|
+
describe UserAddressBook do
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Using LegacyUser as a subject
|
|
8
|
+
# since it uses the UserAddressBookExtension
|
|
9
|
+
#
|
|
10
|
+
let!(:user) { create(:user) }
|
|
11
|
+
|
|
12
|
+
describe "#save_in_address_book" do
|
|
13
|
+
context "saving a default address" do
|
|
14
|
+
let(:user_address) { user.user_addresses.find_first_by_address_values(address.attributes) }
|
|
15
|
+
|
|
16
|
+
subject { user.save_in_address_book(address.attributes, true) }
|
|
17
|
+
|
|
18
|
+
context "the address is a new record" do
|
|
19
|
+
let(:address) { build(:address) }
|
|
20
|
+
|
|
21
|
+
it "creates a new Address" do
|
|
22
|
+
expect { subject }.to change { Spree::Address.count }.by(1)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "creates a UserAddress" do
|
|
26
|
+
expect { subject }.to change { Spree::UserAddress.count }.by(1)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "sets the UserAddress default flag to true" do
|
|
30
|
+
subject
|
|
31
|
+
expect(user_address.default).to eq true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "adds the address to the user's the associated addresses" do
|
|
35
|
+
expect { subject }.to change { user.reload.addresses.count }.by(1)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "user already has a default address" do
|
|
40
|
+
let(:address) { create(:address) }
|
|
41
|
+
let(:original_default_address) { create(:ship_address) }
|
|
42
|
+
let(:original_user_address) { user.user_addresses.find_first_by_address_values(original_default_address.attributes) }
|
|
43
|
+
|
|
44
|
+
before do
|
|
45
|
+
user.user_addresses.create(address: original_default_address, default: true)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "makes all the other associated addresses not be the default" do
|
|
49
|
+
expect { subject }.to change { original_user_address.reload.default }.from(true).to(false)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "an odd flip-flop corner case discovered running backfill rake task" do
|
|
53
|
+
|
|
54
|
+
before do
|
|
55
|
+
user.save_in_address_book(original_default_address.attributes, true)
|
|
56
|
+
user.save_in_address_book(address.attributes, true)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "handles setting 2 addresses as default without a reload of user" do
|
|
60
|
+
user.save_in_address_book(original_default_address.attributes, true)
|
|
61
|
+
user.save_in_address_book(address.attributes, true)
|
|
62
|
+
expect(user.addresses.count).to eq 2
|
|
63
|
+
expect(user.default_address.address1).to eq address.address1
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "changing existing address to default" do
|
|
69
|
+
let(:address) { create(:address) }
|
|
70
|
+
|
|
71
|
+
before do
|
|
72
|
+
user.user_addresses.create(address: address, default: false)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "properly sets the default flag" do
|
|
76
|
+
expect(subject).to eq user.default_address
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context "and changing another address field at the same time" do
|
|
80
|
+
let(:updated_address_attributes) { address.attributes.tap {|a| a[:first_name] = "Newbie"} }
|
|
81
|
+
|
|
82
|
+
subject { user.save_in_address_book(updated_address_attributes, true) }
|
|
83
|
+
|
|
84
|
+
it "changes first name" do
|
|
85
|
+
expect(subject.first_name).to eq updated_address_attributes[:first_name]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "preserves last name" do
|
|
89
|
+
expect(subject.last_name).to eq address.last_name
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "is a new immutable address instance" do
|
|
93
|
+
expect(subject.id).to_not eq address.id
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "is the new default" do
|
|
97
|
+
expect(subject).to eq user.default_address
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "updating an address and making default at once" do
|
|
104
|
+
let(:address1) { create(:address) }
|
|
105
|
+
let(:address2) { create(:address, firstname: "Different") }
|
|
106
|
+
let(:updated_attrs) do
|
|
107
|
+
address2.attributes.tap {|a| a[:firstname] = "Johnny" }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
before do
|
|
111
|
+
user.save_in_address_book(address1.attributes, true)
|
|
112
|
+
user.save_in_address_book(address2.attributes, false)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "returns the edit as the first address" do
|
|
116
|
+
user.save_in_address_book(updated_attrs, true)
|
|
117
|
+
expect(user.user_addresses.first.address.firstname).to eq "Johnny"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context "saving a non-default address" do
|
|
122
|
+
let(:user_address) { user.user_addresses.find_first_by_address_values(address.attributes) }
|
|
123
|
+
|
|
124
|
+
subject { user.save_in_address_book(address.attributes) }
|
|
125
|
+
|
|
126
|
+
context "the address is a new record" do
|
|
127
|
+
let(:address) { build(:address) }
|
|
128
|
+
|
|
129
|
+
it "creates a new Address" do
|
|
130
|
+
expect { subject }.to change { Spree::Address.count }.by(1)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "creates a UserAddress" do
|
|
134
|
+
expect { subject }.to change { Spree::UserAddress.count }.by(1)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
context "it is not the first address" do
|
|
138
|
+
before { user.user_addresses.create!(address: create(:address)) }
|
|
139
|
+
it "sets the UserAddress default flag to false" do
|
|
140
|
+
expect { subject }.to change { Spree::UserAddress.count }.by(1)
|
|
141
|
+
expect(user_address.default).to eq false
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context "it is the first address" do
|
|
146
|
+
it "sets the UserAddress default flag to true" do
|
|
147
|
+
subject
|
|
148
|
+
expect(user_address.default).to eq true
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "adds the address to the user's the associated addresses" do
|
|
153
|
+
expect { subject }.to change { user.reload.addresses.count }.by(1)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context "resurrecting a previously saved (but now archived) address" do
|
|
159
|
+
let(:address) { create(:address) }
|
|
160
|
+
before do
|
|
161
|
+
user.save_in_address_book(address.attributes, true)
|
|
162
|
+
user.remove_from_address_book(address.id)
|
|
163
|
+
end
|
|
164
|
+
subject { user.save_in_address_book(address.attributes, true) }
|
|
165
|
+
|
|
166
|
+
it "returns the address" do
|
|
167
|
+
expect(subject).to eq address
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "sets it as default" do
|
|
171
|
+
subject
|
|
172
|
+
expect(user.default_address).to eq address
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
context "via an edit to another address" do
|
|
176
|
+
let(:address2) { create(:address, firstname: "Different") }
|
|
177
|
+
let(:edited_attributes) do
|
|
178
|
+
# conceptually edit address2 to match the values of address
|
|
179
|
+
edited_attributes = address.attributes
|
|
180
|
+
edited_attributes[:id] = address2.id
|
|
181
|
+
edited_attributes
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
before { user.save_in_address_book(address2.attributes, true) }
|
|
185
|
+
|
|
186
|
+
subject { user.save_in_address_book(edited_attributes) }
|
|
187
|
+
|
|
188
|
+
it "returns the address" do
|
|
189
|
+
expect(subject).to eq address
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "archives address2" do
|
|
193
|
+
subject
|
|
194
|
+
user_address2 = user.user_addresses.all_historical.find_by(address_id: address2.id)
|
|
195
|
+
expect(user_address2.archived).to be true
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
context "via a new address that matches an archived one" do
|
|
199
|
+
let(:added_attributes) do
|
|
200
|
+
added_attributes = address.attributes
|
|
201
|
+
added_attributes.delete(:id)
|
|
202
|
+
added_attributes
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
subject { user.save_in_address_book(added_attributes) }
|
|
206
|
+
|
|
207
|
+
it "returns the address" do
|
|
208
|
+
expect(subject).to eq address
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "no longer has archived user_addresses" do
|
|
212
|
+
subject
|
|
213
|
+
expect(user.user_addresses.all_historical).to eq user.user_addresses
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
context "#remove_from_address_book" do
|
|
221
|
+
let(:address1) { create(:address) }
|
|
222
|
+
let(:address2) { create(:address, firstname: "Different") }
|
|
223
|
+
let(:remove_id) { address1.id}
|
|
224
|
+
subject { user.remove_from_address_book(remove_id) }
|
|
225
|
+
|
|
226
|
+
before do
|
|
227
|
+
user.save_in_address_book(address1.attributes)
|
|
228
|
+
user.save_in_address_book(address2.attributes)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "removes the address from user_addresses" do
|
|
232
|
+
subject
|
|
233
|
+
expect(user.user_addresses.find_first_by_address_values(address1.attributes)).to be_nil
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "leaves user_address record in an archived state" do
|
|
237
|
+
subject
|
|
238
|
+
archived_user_address = user.user_addresses.all_historical.find_first_by_address_values(address1.attributes)
|
|
239
|
+
expect(archived_user_address).to be_archived
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "returns false if the addresses is not there" do
|
|
243
|
+
expect(user.remove_from_address_book(42)).to be false
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
context "#persist_order_address" do
|
|
248
|
+
context "when automatic_default_address preference is at a default of true" do
|
|
249
|
+
before do
|
|
250
|
+
Spree::Config.automatic_default_address = true
|
|
251
|
+
expect(user).to receive(:save_in_address_book).with(kind_of(Hash), true)
|
|
252
|
+
expect(user).to receive(:save_in_address_book).with(kind_of(Hash), false)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
it "does set the default: true flag" do
|
|
256
|
+
order = build(:order)
|
|
257
|
+
user.persist_order_address(order)
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
context "when automatic_default_address preference is false" do
|
|
262
|
+
before do
|
|
263
|
+
Spree::Config.automatic_default_address = false
|
|
264
|
+
expect(user).to receive(:save_in_address_book).with(kind_of(Hash),false).twice
|
|
265
|
+
#and not the optional 2nd argument
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it "does not set the default: true flag" do
|
|
269
|
+
order = build(:order)
|
|
270
|
+
user.persist_order_address(order)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
context "when address is nil" do
|
|
275
|
+
context "when automatic_default_address preference is at a default of true" do
|
|
276
|
+
before do
|
|
277
|
+
Spree::Config.automatic_default_address = true
|
|
278
|
+
expect(user).to receive(:save_in_address_book).with(kind_of(Hash), true).once
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it "does not call save_in_address_book on ship address" do
|
|
282
|
+
order = build(:order)
|
|
283
|
+
order.ship_address = nil
|
|
284
|
+
|
|
285
|
+
user.persist_order_address(order)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
it "does not call save_in_address_book on bill address" do
|
|
289
|
+
order = build(:order)
|
|
290
|
+
order.bill_address = nil
|
|
291
|
+
|
|
292
|
+
user.persist_order_address(order)
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
context "when automatic_default_address preference is false" do
|
|
298
|
+
before do
|
|
299
|
+
Spree::Config.automatic_default_address = false
|
|
300
|
+
expect(user).to receive(:save_in_address_book).with(kind_of(Hash), false).once
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "does not call save_in_address_book on ship address" do
|
|
304
|
+
order = build(:order)
|
|
305
|
+
order.ship_address = nil
|
|
306
|
+
|
|
307
|
+
user.persist_order_address(order)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
it "does not call save_in_address_book on bill address" do
|
|
311
|
+
order = build(:order)
|
|
312
|
+
order.bill_address = nil
|
|
313
|
+
|
|
314
|
+
user.persist_order_address(order)
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
context "generating a new user with a ship_address at once" do
|
|
321
|
+
let(:ship_address) { build(:ship_address) }
|
|
322
|
+
subject { create(:user, ship_address: ship_address) }
|
|
323
|
+
|
|
324
|
+
it "stores the ship_address" do
|
|
325
|
+
expect(subject.ship_address).to eq ship_address
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
it "is also available as default_address" do
|
|
329
|
+
expect(subject.default_address).to eq ship_address
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::UserMethods do
|
|
4
|
+
let(:test_user) { create :user }
|
|
5
|
+
|
|
6
|
+
describe '#has_spree_role?' do
|
|
7
|
+
subject { test_user.has_spree_role? name }
|
|
8
|
+
|
|
9
|
+
let(:role) { Spree::Role.create(name: name) }
|
|
10
|
+
let(:name) { 'test' }
|
|
11
|
+
|
|
12
|
+
context 'with a role' do
|
|
13
|
+
before { test_user.spree_roles << role }
|
|
14
|
+
it { is_expected.to be_truthy }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
context 'without a role' do
|
|
18
|
+
it { is_expected.to be_falsy }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '#last_incomplete_spree_order' do
|
|
23
|
+
subject { test_user.last_incomplete_spree_order }
|
|
24
|
+
|
|
25
|
+
context 'with an incomplete order' do
|
|
26
|
+
let(:last_incomplete_order) { create :order, user: test_user }
|
|
27
|
+
|
|
28
|
+
before do
|
|
29
|
+
create(:order, user: test_user, created_at: 1.day.ago)
|
|
30
|
+
create(:order, user: create(:user))
|
|
31
|
+
last_incomplete_order
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it { is_expected.to eq last_incomplete_order }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
context 'without an incomplete order' do
|
|
38
|
+
it { is_expected.to be_nil }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Spree::CreditCard, type: :model do
|
|
4
|
+
let(:valid_credit_card_attributes) do
|
|
5
|
+
{
|
|
6
|
+
number: '4111111111111111',
|
|
7
|
+
verification_value: '123',
|
|
8
|
+
expiry: "12 / #{(Time.now.year + 1).to_s.last(2)}",
|
|
9
|
+
name: 'Spree Commerce'
|
|
10
|
+
}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.payment_states
|
|
14
|
+
Spree::Payment.state_machine.states.keys
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
let(:credit_card) { Spree::CreditCard.new }
|
|
18
|
+
|
|
19
|
+
before(:each) do
|
|
20
|
+
|
|
21
|
+
@order = create(:order)
|
|
22
|
+
@payment = Spree::Payment.create(:amount => 100, :order => @order)
|
|
23
|
+
|
|
24
|
+
@success_response = double('gateway_response', success?: true, authorization: '123', avs_result: { 'code' => 'avs-code' })
|
|
25
|
+
@fail_response = double('gateway_response', success?: false)
|
|
26
|
+
|
|
27
|
+
@payment_gateway = mock_model(Spree::PaymentMethod,
|
|
28
|
+
payment_profiles_supported?: true,
|
|
29
|
+
authorize: @success_response,
|
|
30
|
+
purchase: @success_response,
|
|
31
|
+
capture: @success_response,
|
|
32
|
+
void: @success_response,
|
|
33
|
+
credit: @success_response,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
allow(@payment).to receive_messages payment_method: @payment_gateway
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "#can_capture?" do
|
|
40
|
+
it "should be true if payment is pending" do
|
|
41
|
+
payment = mock_model(Spree::Payment, pending?: true, created_at: Time.now)
|
|
42
|
+
expect(credit_card.can_capture?(payment)).to be true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should be true if payment is checkout" do
|
|
46
|
+
payment = mock_model(Spree::Payment, pending?: false, checkout?: true, created_at: Time.now)
|
|
47
|
+
expect(credit_card.can_capture?(payment)).to be true
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context "#can_void?" do
|
|
52
|
+
it "should be true if payment is not void" do
|
|
53
|
+
payment = mock_model(Spree::Payment, failed?: false, void?: false)
|
|
54
|
+
expect(credit_card.can_void?(payment)).to be true
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "#can_credit?" do
|
|
59
|
+
it "should be false if payment is not completed" do
|
|
60
|
+
payment = mock_model(Spree::Payment, completed?: false)
|
|
61
|
+
expect(credit_card.can_credit?(payment)).to be false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should be false when credit_allowed is zero" do
|
|
65
|
+
payment = mock_model(Spree::Payment, completed?: true, credit_allowed: 0, order: mock_model(Spree::Order, payment_state: 'credit_owed'))
|
|
66
|
+
expect(credit_card.can_credit?(payment)).to be false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context "#valid?" do
|
|
71
|
+
it "should validate presence of number" do
|
|
72
|
+
credit_card.attributes = valid_credit_card_attributes.except(:number)
|
|
73
|
+
expect(credit_card).not_to be_valid
|
|
74
|
+
expect(credit_card.errors[:number]).to eq(["can't be blank"])
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should validate presence of security code" do
|
|
78
|
+
credit_card.attributes = valid_credit_card_attributes.except(:verification_value)
|
|
79
|
+
expect(credit_card).not_to be_valid
|
|
80
|
+
expect(credit_card.errors[:verification_value]).to eq(["can't be blank"])
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it "validates name presence" do
|
|
84
|
+
credit_card.valid?
|
|
85
|
+
expect(credit_card.error_on(:name).size).to eq(1)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should only validate on create" do
|
|
89
|
+
credit_card.attributes = valid_credit_card_attributes
|
|
90
|
+
credit_card.save
|
|
91
|
+
expect(credit_card).to be_valid
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
context "encrypted data is present" do
|
|
95
|
+
it "does not validate presence of number or cvv" do
|
|
96
|
+
credit_card.encrypted_data = "$fdgsfgdgfgfdg&gfdgfdgsf-"
|
|
97
|
+
credit_card.valid?
|
|
98
|
+
expect(credit_card.errors[:number]).to be_empty
|
|
99
|
+
expect(credit_card.errors[:verification_value]).to be_empty
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "imported is true" do
|
|
104
|
+
it "does not validate presence of number or cvv" do
|
|
105
|
+
credit_card.imported = true
|
|
106
|
+
credit_card.valid?
|
|
107
|
+
expect(credit_card.errors[:number]).to be_empty
|
|
108
|
+
expect(credit_card.errors[:verification_value]).to be_empty
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "#save" do
|
|
114
|
+
before do
|
|
115
|
+
credit_card.attributes = valid_credit_card_attributes
|
|
116
|
+
credit_card.save!
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
let!(:persisted_card) { Spree::CreditCard.find(credit_card.id) }
|
|
120
|
+
let (:valid_address_attributes) { {firstname: "Hugo", lastname: "Furst",
|
|
121
|
+
address1: "123 Main", city: "Somewhere",
|
|
122
|
+
country_id: 1, zipcode: 55555,
|
|
123
|
+
phone: "1234567890"} }
|
|
124
|
+
|
|
125
|
+
it "should not actually store the number" do
|
|
126
|
+
expect(persisted_card.number).to be_blank
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "should not actually store the security code" do
|
|
130
|
+
expect(persisted_card.verification_value).to be_blank
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should save and update addresses through nested attributes" do
|
|
134
|
+
persisted_card.update_attributes({address_attributes: valid_address_attributes})
|
|
135
|
+
persisted_card.save!
|
|
136
|
+
updated_attributes = {id: persisted_card.address.id, address1: "123 Main St."}
|
|
137
|
+
persisted_card.update_attributes({address_attributes: updated_attributes})
|
|
138
|
+
expect(persisted_card.address.address1).to eq "123 Main St."
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
context "#number=" do
|
|
143
|
+
it "should strip non-numeric characters from card input" do
|
|
144
|
+
credit_card.number = "6011000990139424"
|
|
145
|
+
expect(credit_card.number).to eq("6011000990139424")
|
|
146
|
+
|
|
147
|
+
credit_card.number = " 6011-0009-9013-9424 "
|
|
148
|
+
expect(credit_card.number).to eq("6011000990139424")
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "should not raise an exception on non-string input" do
|
|
152
|
+
credit_card.number = Hash.new
|
|
153
|
+
expect(credit_card.number).to be_nil
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Regression test for #3847 & #3896
|
|
158
|
+
context "#expiry=" do
|
|
159
|
+
it "can set with a 2-digit month and year" do
|
|
160
|
+
credit_card.expiry = '04 / 15'
|
|
161
|
+
expect(credit_card.month).to eq('4')
|
|
162
|
+
expect(credit_card.year).to eq('2015')
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "can set with a 2-digit month and 4-digit year" do
|
|
166
|
+
credit_card.expiry = '04 / 2015'
|
|
167
|
+
expect(credit_card.month).to eq('4')
|
|
168
|
+
expect(credit_card.year).to eq('2015')
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "can set with a 2-digit month and 4-digit year without whitespace" do
|
|
172
|
+
credit_card.expiry = '04/15'
|
|
173
|
+
expect(credit_card.month).to eq('4')
|
|
174
|
+
expect(credit_card.year).to eq('2015')
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "can set with a 2-digit month and 4-digit year without whitespace" do
|
|
178
|
+
credit_card.expiry = '04/2015'
|
|
179
|
+
expect(credit_card.month).to eq('4')
|
|
180
|
+
expect(credit_card.year).to eq('2015')
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "can set with a 2-digit month and 4-digit year without whitespace and slash" do
|
|
184
|
+
credit_card.expiry = '042015'
|
|
185
|
+
expect(credit_card.month).to eq('4')
|
|
186
|
+
expect(credit_card.year).to eq('2015')
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "can set with a 2-digit month and 2-digit year without whitespace and slash" do
|
|
190
|
+
credit_card.expiry = '0415'
|
|
191
|
+
expect(credit_card.month).to eq('4')
|
|
192
|
+
expect(credit_card.year).to eq('2015')
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "does not blow up when passed an empty string" do
|
|
196
|
+
expect { credit_card.expiry = '' }.not_to raise_error
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Regression test for #4725
|
|
200
|
+
it "does not blow up when passed one number" do
|
|
201
|
+
expect { credit_card.expiry = '12' }.not_to raise_error
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
context "#cc_type=" do
|
|
207
|
+
it "converts between the different types" do
|
|
208
|
+
credit_card.cc_type = 'mastercard'
|
|
209
|
+
expect(credit_card.cc_type).to eq('master')
|
|
210
|
+
|
|
211
|
+
credit_card.cc_type = 'maestro'
|
|
212
|
+
expect(credit_card.cc_type).to eq('master')
|
|
213
|
+
|
|
214
|
+
credit_card.cc_type = 'amex'
|
|
215
|
+
expect(credit_card.cc_type).to eq('american_express')
|
|
216
|
+
|
|
217
|
+
credit_card.cc_type = 'dinersclub'
|
|
218
|
+
expect(credit_card.cc_type).to eq('diners_club')
|
|
219
|
+
|
|
220
|
+
credit_card.cc_type = 'some_outlandish_cc_type'
|
|
221
|
+
expect(credit_card.cc_type).to eq('some_outlandish_cc_type')
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "assigns the type based on card number in the event of js failure" do
|
|
225
|
+
credit_card.number = '4242424242424242'
|
|
226
|
+
credit_card.cc_type = ''
|
|
227
|
+
expect(credit_card.cc_type).to eq('visa')
|
|
228
|
+
|
|
229
|
+
credit_card.number = '5555555555554444'
|
|
230
|
+
credit_card.cc_type = ''
|
|
231
|
+
expect(credit_card.cc_type).to eq('master')
|
|
232
|
+
|
|
233
|
+
credit_card.number = '378282246310005'
|
|
234
|
+
credit_card.cc_type = ''
|
|
235
|
+
expect(credit_card.cc_type).to eq('american_express')
|
|
236
|
+
|
|
237
|
+
credit_card.number = '30569309025904'
|
|
238
|
+
credit_card.cc_type = ''
|
|
239
|
+
expect(credit_card.cc_type).to eq('diners_club')
|
|
240
|
+
|
|
241
|
+
credit_card.number = '3530111333300000'
|
|
242
|
+
credit_card.cc_type = ''
|
|
243
|
+
expect(credit_card.cc_type).to eq('jcb')
|
|
244
|
+
|
|
245
|
+
credit_card.number = ''
|
|
246
|
+
credit_card.cc_type = ''
|
|
247
|
+
expect(credit_card.cc_type).to eq('')
|
|
248
|
+
|
|
249
|
+
credit_card.number = nil
|
|
250
|
+
credit_card.cc_type = ''
|
|
251
|
+
expect(credit_card.cc_type).to eq('')
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
context "#associations" do
|
|
256
|
+
it "should be able to access its payments" do
|
|
257
|
+
expect { credit_card.payments.to_a }.not_to raise_error
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
context "#first_name" do
|
|
262
|
+
before do
|
|
263
|
+
credit_card.name = "Ludwig van Beethoven"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it "extracts the first name" do
|
|
267
|
+
expect(credit_card.first_name).to eq "Ludwig"
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
context "#last_name" do
|
|
272
|
+
before do
|
|
273
|
+
credit_card.name = "Ludwig van Beethoven"
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "extracts the last name" do
|
|
277
|
+
expect(credit_card.last_name).to eq "van Beethoven"
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
context "#to_active_merchant" do
|
|
282
|
+
before do
|
|
283
|
+
credit_card.number = "4111111111111111"
|
|
284
|
+
credit_card.year = Time.now.year
|
|
285
|
+
credit_card.month = Time.now.month
|
|
286
|
+
credit_card.name = "Ludwig van Beethoven"
|
|
287
|
+
credit_card.verification_value = 123
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
it "converts to an ActiveMerchant::Billing::CreditCard object" do
|
|
291
|
+
am_card = credit_card.to_active_merchant
|
|
292
|
+
expect(am_card.number).to eq("4111111111111111")
|
|
293
|
+
expect(am_card.year).to eq(Time.now.year)
|
|
294
|
+
expect(am_card.month).to eq(Time.now.month)
|
|
295
|
+
expect(am_card.first_name).to eq("Ludwig")
|
|
296
|
+
expect(am_card.last_name).to eq("van Beethoven")
|
|
297
|
+
expect(am_card.verification_value).to eq(123)
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it 'ensures only one credit card per user is default at a time' do
|
|
302
|
+
user = FactoryGirl.create(:user)
|
|
303
|
+
first = FactoryGirl.create(:credit_card, user: user, default: true)
|
|
304
|
+
second = FactoryGirl.create(:credit_card, user: user, default: true)
|
|
305
|
+
|
|
306
|
+
expect(first.reload.default).to eq false
|
|
307
|
+
expect(second.reload.default).to eq true
|
|
308
|
+
|
|
309
|
+
first.default = true
|
|
310
|
+
first.save!
|
|
311
|
+
|
|
312
|
+
expect(first.reload.default).to eq true
|
|
313
|
+
expect(second.reload.default).to eq false
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
it 'allows default credit cards for different users' do
|
|
317
|
+
first = FactoryGirl.create(:credit_card, user: FactoryGirl.create(:user), default: true)
|
|
318
|
+
second = FactoryGirl.create(:credit_card, user: FactoryGirl.create(:user), default: true)
|
|
319
|
+
|
|
320
|
+
expect(first.reload.default).to eq true
|
|
321
|
+
expect(second.reload.default).to eq true
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it 'allows this card to save even if the previously default card has expired' do
|
|
325
|
+
user = FactoryGirl.create(:user)
|
|
326
|
+
first = FactoryGirl.create(:credit_card, user: user, default: true)
|
|
327
|
+
second = FactoryGirl.create(:credit_card, user: user, default: false)
|
|
328
|
+
first.update_columns(year: DateTime.now.year, month: 1.month.ago.month)
|
|
329
|
+
|
|
330
|
+
expect { second.update_attributes!(default: true) }.not_to raise_error
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it 'allows this card to save even if the previously default card has expired' do
|
|
334
|
+
user = FactoryGirl.create(:user)
|
|
335
|
+
first = FactoryGirl.create(:credit_card, user: user, default: true)
|
|
336
|
+
second = FactoryGirl.create(:credit_card, user: user, default: false)
|
|
337
|
+
first.update_columns(year: DateTime.now.year, month: 1.month.ago.month)
|
|
338
|
+
|
|
339
|
+
expect { second.update_attributes!(default: true) }.not_to raise_error
|
|
340
|
+
end
|
|
341
|
+
end
|