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.
Files changed (228) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Rakefile +16 -0
  4. data/script/rails +9 -0
  5. data/solidus_core.gemspec +48 -0
  6. data/spec/fixtures/thinking-cat.jpg +0 -0
  7. data/spec/helpers/base_helper_spec.rb +173 -0
  8. data/spec/helpers/order_helper_spec.rb +12 -0
  9. data/spec/helpers/products_helper_spec.rb +208 -0
  10. data/spec/helpers/taxons_helper_spec.rb +17 -0
  11. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  12. data/spec/lib/i18n_spec.rb +106 -0
  13. data/spec/lib/search/base_spec.rb +86 -0
  14. data/spec/lib/search/variant_spec.rb +112 -0
  15. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +66 -0
  16. data/spec/lib/spree/core/controller_helpers/order_spec.rb +92 -0
  17. data/spec/lib/spree/core/controller_helpers/payment_parameters_spec.rb +80 -0
  18. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  19. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  20. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  21. data/spec/lib/spree/core/current_store_spec.rb +36 -0
  22. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +24 -0
  23. data/spec/lib/spree/core/importer/order_spec.rb +431 -0
  24. data/spec/lib/spree/core/role_configuration_spec.rb +156 -0
  25. data/spec/lib/spree/core/unreturned_item_charger_spec.rb +130 -0
  26. data/spec/lib/spree/core/validators/email_spec.rb +48 -0
  27. data/spec/lib/spree/localized_number_spec.rb +38 -0
  28. data/spec/lib/spree/migrations_spec.rb +36 -0
  29. data/spec/lib/spree/money_spec.rb +127 -0
  30. data/spec/lib/tasks/exchanges_spec.rb +231 -0
  31. data/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +115 -0
  32. data/spec/lib/tasks/order_capturing_spec.rb +56 -0
  33. data/spec/mailers/carton_mailer_spec.rb +55 -0
  34. data/spec/mailers/order_mailer_spec.rb +135 -0
  35. data/spec/mailers/reimbursement_mailer_spec.rb +40 -0
  36. data/spec/mailers/test_mailer_spec.rb +15 -0
  37. data/spec/models/spree/ability_spec.rb +276 -0
  38. data/spec/models/spree/address_spec.rb +376 -0
  39. data/spec/models/spree/adjustment_reason_spec.rb +13 -0
  40. data/spec/models/spree/adjustment_spec.rb +169 -0
  41. data/spec/models/spree/app_configuration_spec.rb +24 -0
  42. data/spec/models/spree/asset_spec.rb +24 -0
  43. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  44. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  45. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  46. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  47. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  48. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  49. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +60 -0
  50. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  51. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  52. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  53. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  54. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +30 -0
  55. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +36 -0
  56. data/spec/models/spree/calculator/tiered_percent_spec.rb +47 -0
  57. data/spec/models/spree/calculator_spec.rb +36 -0
  58. data/spec/models/spree/carton_spec.rb +133 -0
  59. data/spec/models/spree/classification_spec.rb +93 -0
  60. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  61. data/spec/models/spree/concerns/ordered_property_value_list_spec.rb +25 -0
  62. data/spec/models/spree/concerns/user_address_book_spec.rb +332 -0
  63. data/spec/models/spree/concerns/user_methods_spec.rb +41 -0
  64. data/spec/models/spree/credit_card_spec.rb +341 -0
  65. data/spec/models/spree/customer_return_spec.rb +276 -0
  66. data/spec/models/spree/exchange_spec.rb +79 -0
  67. data/spec/models/spree/gateway/bogus_simple.rb +20 -0
  68. data/spec/models/spree/gateway/bogus_spec.rb +13 -0
  69. data/spec/models/spree/gateway_spec.rb +104 -0
  70. data/spec/models/spree/inventory_unit_spec.rb +307 -0
  71. data/spec/models/spree/item_adjustments_spec.rb +275 -0
  72. data/spec/models/spree/line_item_spec.rb +199 -0
  73. data/spec/models/spree/option_type_spec.rb +14 -0
  74. data/spec/models/spree/option_value_spec.rb +45 -0
  75. data/spec/models/spree/order/address_spec.rb +50 -0
  76. data/spec/models/spree/order/adjustments_spec.rb +27 -0
  77. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  78. data/spec/models/spree/order/checkout_spec.rb +884 -0
  79. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  80. data/spec/models/spree/order/finalizing_spec.rb +110 -0
  81. data/spec/models/spree/order/payment_spec.rb +243 -0
  82. data/spec/models/spree/order/risk_assessment_spec.rb +68 -0
  83. data/spec/models/spree/order/state_machine_spec.rb +209 -0
  84. data/spec/models/spree/order/tax_spec.rb +84 -0
  85. data/spec/models/spree/order/totals_spec.rb +24 -0
  86. data/spec/models/spree/order/updating_spec.rb +18 -0
  87. data/spec/models/spree/order/validations_spec.rb +15 -0
  88. data/spec/models/spree/order_cancellations_spec.rb +120 -0
  89. data/spec/models/spree/order_capturing_spec.rb +150 -0
  90. data/spec/models/spree/order_contents_spec.rb +307 -0
  91. data/spec/models/spree/order_inventory_spec.rb +228 -0
  92. data/spec/models/spree/order_mutex_spec.rb +85 -0
  93. data/spec/models/spree/order_promotion_spec.rb +31 -0
  94. data/spec/models/spree/order_shipping_spec.rb +241 -0
  95. data/spec/models/spree/order_spec.rb +1482 -0
  96. data/spec/models/spree/order_stock_location_spec.rb +18 -0
  97. data/spec/models/spree/order_updater_spec.rb +283 -0
  98. data/spec/models/spree/payment_method/store_credit_spec.rb +294 -0
  99. data/spec/models/spree/payment_method_spec.rb +147 -0
  100. data/spec/models/spree/payment_spec.rb +1087 -0
  101. data/spec/models/spree/permission_sets/base_spec.rb +12 -0
  102. data/spec/models/spree/permission_sets/configuration_display.rb +82 -0
  103. data/spec/models/spree/permission_sets/configuration_management_spec.rb +50 -0
  104. data/spec/models/spree/permission_sets/dashboard_display_spec.rb +22 -0
  105. data/spec/models/spree/permission_sets/order_display_spec.rb +55 -0
  106. data/spec/models/spree/permission_sets/order_management_spec.rb +42 -0
  107. data/spec/models/spree/permission_sets/product_display_spec.rb +60 -0
  108. data/spec/models/spree/permission_sets/product_management_spec.rb +40 -0
  109. data/spec/models/spree/permission_sets/promotion_display_spec.rb +40 -0
  110. data/spec/models/spree/permission_sets/promotion_management_spec.rb +26 -0
  111. data/spec/models/spree/permission_sets/report_display_spec.rb +24 -0
  112. data/spec/models/spree/permission_sets/restricted_stock_display_spec.rb +41 -0
  113. data/spec/models/spree/permission_sets/restricted_stock_management_spec.rb +41 -0
  114. data/spec/models/spree/permission_sets/restricted_stock_transfer_display_spec.rb +50 -0
  115. data/spec/models/spree/permission_sets/restricted_stock_transfer_management_spec.rb +160 -0
  116. data/spec/models/spree/permission_sets/stock_display_spec.rb +24 -0
  117. data/spec/models/spree/permission_sets/stock_management_spec.rb +22 -0
  118. data/spec/models/spree/permission_sets/stock_transfer_display_spec.rb +24 -0
  119. data/spec/models/spree/permission_sets/stock_transfer_management_spec.rb +25 -0
  120. data/spec/models/spree/permission_sets/user_display_spec.rb +38 -0
  121. data/spec/models/spree/permission_sets/user_management_spec.rb +48 -0
  122. data/spec/models/spree/preference_spec.rb +80 -0
  123. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  124. data/spec/models/spree/preferences/preferable_spec.rb +294 -0
  125. data/spec/models/spree/preferences/scoped_store_spec.rb +60 -0
  126. data/spec/models/spree/preferences/static_model_preferences_spec.rb +78 -0
  127. data/spec/models/spree/preferences/statically_configurable_spec.rb +60 -0
  128. data/spec/models/spree/preferences/store_spec.rb +39 -0
  129. data/spec/models/spree/price_spec.rb +42 -0
  130. data/spec/models/spree/product/scopes_spec.rb +116 -0
  131. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  132. data/spec/models/spree/product_filter_spec.rb +26 -0
  133. data/spec/models/spree/product_property_spec.rb +18 -0
  134. data/spec/models/spree/product_spec.rb +504 -0
  135. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +96 -0
  136. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +165 -0
  137. data/spec/models/spree/promotion/actions/create_quantity_adjustments_spec.rb +115 -0
  138. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +40 -0
  139. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  140. data/spec/models/spree/promotion/rules/first_repeat_purchase_since_spec.rb +69 -0
  141. data/spec/models/spree/promotion/rules/item_total_spec.rb +67 -0
  142. data/spec/models/spree/promotion/rules/nth_order_spec.rb +70 -0
  143. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  144. data/spec/models/spree/promotion/rules/option_value_spec.rb +94 -0
  145. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  146. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  147. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  148. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  149. data/spec/models/spree/promotion_builder_spec.rb +118 -0
  150. data/spec/models/spree/promotion_category_spec.rb +17 -0
  151. data/spec/models/spree/promotion_code/code_builder_spec.rb +79 -0
  152. data/spec/models/spree/promotion_code_spec.rb +187 -0
  153. data/spec/models/spree/promotion_handler/cart_spec.rb +130 -0
  154. data/spec/models/spree/promotion_handler/coupon_spec.rb +335 -0
  155. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +47 -0
  156. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  157. data/spec/models/spree/promotion_rule_spec.rb +28 -0
  158. data/spec/models/spree/promotion_spec.rb +776 -0
  159. data/spec/models/spree/refund_spec.rb +192 -0
  160. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  161. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  162. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  163. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  164. data/spec/models/spree/reimbursement_spec.rb +231 -0
  165. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  166. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  167. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  168. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +107 -0
  169. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +97 -0
  170. data/spec/models/spree/return_authorization_spec.rb +290 -0
  171. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  172. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  173. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +85 -0
  174. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  175. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  176. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  177. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  178. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  179. data/spec/models/spree/return_item_spec.rb +776 -0
  180. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  181. data/spec/models/spree/shipment_spec.rb +753 -0
  182. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  183. data/spec/models/spree/shipping_manifest_spec.rb +94 -0
  184. data/spec/models/spree/shipping_method_spec.rb +88 -0
  185. data/spec/models/spree/shipping_rate_spec.rb +142 -0
  186. data/spec/models/spree/state_spec.rb +14 -0
  187. data/spec/models/spree/stock/availability_validator_spec.rb +83 -0
  188. data/spec/models/spree/stock/coordinator_spec.rb +116 -0
  189. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  190. data/spec/models/spree/stock/estimator_spec.rb +146 -0
  191. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  192. data/spec/models/spree/stock/package_spec.rb +163 -0
  193. data/spec/models/spree/stock/packer_spec.rb +91 -0
  194. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  195. data/spec/models/spree/stock/quantifier_spec.rb +115 -0
  196. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  197. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  198. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +50 -0
  199. data/spec/models/spree/stock/splitter/weight_spec.rb +29 -0
  200. data/spec/models/spree/stock_item_spec.rb +444 -0
  201. data/spec/models/spree/stock_location_spec.rb +279 -0
  202. data/spec/models/spree/stock_movement_spec.rb +56 -0
  203. data/spec/models/spree/stock_transfer_spec.rb +290 -0
  204. data/spec/models/spree/store_credit_category_spec.rb +17 -0
  205. data/spec/models/spree/store_credit_event_spec.rb +314 -0
  206. data/spec/models/spree/store_credit_spec.rb +876 -0
  207. data/spec/models/spree/store_spec.rb +55 -0
  208. data/spec/models/spree/tax_category_spec.rb +27 -0
  209. data/spec/models/spree/tax_rate_spec.rb +378 -0
  210. data/spec/models/spree/taxon_spec.rb +74 -0
  211. data/spec/models/spree/taxonomy_spec.rb +18 -0
  212. data/spec/models/spree/tracker_spec.rb +21 -0
  213. data/spec/models/spree/transfer_item_spec.rb +264 -0
  214. data/spec/models/spree/unit_cancel_spec.rb +149 -0
  215. data/spec/models/spree/user_spec.rb +246 -0
  216. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +23 -0
  217. data/spec/models/spree/variant/scopes_spec.rb +55 -0
  218. data/spec/models/spree/variant_property_rule_condition_spec.rb +15 -0
  219. data/spec/models/spree/variant_property_rule_spec.rb +83 -0
  220. data/spec/models/spree/variant_property_rule_value_spec.rb +18 -0
  221. data/spec/models/spree/variant_spec.rb +601 -0
  222. data/spec/models/spree/zone_spec.rb +305 -0
  223. data/spec/spec_helper.rb +80 -0
  224. data/spec/support/big_decimal.rb +5 -0
  225. data/spec/support/concerns/default_price.rb +34 -0
  226. data/spec/support/dummy_ability.rb +4 -0
  227. data/spec/support/test_gateway.rb +2 -0
  228. 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