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,376 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Address, :type => :model do
4
+
5
+ subject { Spree::Address }
6
+
7
+ context "aliased attributes" do
8
+ let(:address) { Spree::Address.new firstname: 'Ryan', lastname: 'Bigg'}
9
+
10
+ it " first_name" do
11
+ expect(address.first_name).to eq("Ryan")
12
+ end
13
+
14
+ it "last_name" do
15
+ expect(address.last_name).to eq("Bigg")
16
+ end
17
+ end
18
+
19
+ context "validation" do
20
+
21
+ let(:country) { mock_model(Spree::Country, :states => [state], :states_required => true) }
22
+ let(:state) { stub_model(Spree::State, :name => 'maryland', :abbr => 'md') }
23
+ let(:address) { build(:address, :country => country) }
24
+
25
+ before do
26
+ allow(country.states).to receive_messages :find_all_by_name_or_abbr => [state]
27
+ end
28
+
29
+ context 'address does not require state' do
30
+ before do
31
+ Spree::Config.address_requires_state = false
32
+ end
33
+ it "address_requires_state preference is false" do
34
+ address.state = nil
35
+ address.state_name = nil
36
+ expect(address).to be_valid
37
+ end
38
+ end
39
+
40
+ context 'address requires state' do
41
+ before do
42
+ Spree::Config.address_requires_state = true
43
+ end
44
+
45
+ it "state_name is not nil and country does not have any states" do
46
+ address.state = nil
47
+ address.state_name = 'alabama'
48
+ expect(address).to be_valid
49
+ end
50
+
51
+ it "errors when state_name is nil" do
52
+ address.state_name = nil
53
+ address.state = nil
54
+ expect(address).not_to be_valid
55
+ end
56
+
57
+ it "full state name is in state_name and country does contain that state" do
58
+ address.state_name = 'alabama'
59
+ # called by state_validate to set up state_id.
60
+ # Perhaps this should be a before_validation instead?
61
+ expect(address).to be_valid
62
+ expect(address.state).not_to be_nil
63
+ expect(address.state_name).to be_nil
64
+ end
65
+
66
+ it "state abbr is in state_name and country does contain that state" do
67
+ address.state_name = state.abbr
68
+ expect(address).to be_valid
69
+ expect(address.state_id).not_to be_nil
70
+ expect(address.state_name).to be_nil
71
+ end
72
+
73
+ it "state is entered but country does not contain that state" do
74
+ address.state = state
75
+ address.country = stub_model(Spree::Country, :states_required => true)
76
+ address.valid?
77
+ expect(address.errors["state"]).to eq(['is invalid'])
78
+ end
79
+
80
+ it "both state and state_name are entered but country does not contain the state" do
81
+ address.state = state
82
+ address.state_name = 'maryland'
83
+ address.country = stub_model(Spree::Country, :states_required => true)
84
+ expect(address).to be_valid
85
+ expect(address.state_id).to be_nil
86
+ end
87
+
88
+ it "both state and state_name are entered and country does contain the state" do
89
+ address.state = state
90
+ address.state_name = 'maryland'
91
+ expect(address).to be_valid
92
+ expect(address.state_name).to be_nil
93
+ end
94
+ end
95
+
96
+ it "requires phone" do
97
+ address.phone = ""
98
+ address.valid?
99
+ expect(address.errors["phone"]).to eq(["can't be blank"])
100
+ end
101
+
102
+ it "requires zipcode" do
103
+ address.zipcode = ""
104
+ address.valid?
105
+ expect(address.errors['zipcode']).to include("can't be blank")
106
+ end
107
+
108
+ context "zipcode validation" do
109
+ it "validates the zipcode" do
110
+ allow(address.country).to receive(:iso).and_return('US')
111
+ address.zipcode = 'abc'
112
+ address.valid?
113
+ expect(address.errors['zipcode']).to include('is invalid')
114
+ end
115
+
116
+ context 'does not validate' do
117
+ it 'does not have a country' do
118
+ address.country = nil
119
+ address.valid?
120
+ expect(address.errors['zipcode']).not_to include('is invalid')
121
+ end
122
+
123
+ it 'does not have an iso' do
124
+ allow(address.country).to receive(:iso).and_return(nil)
125
+ address.valid?
126
+ expect(address.errors['zipcode']).not_to include('is invalid')
127
+ end
128
+
129
+ it 'does not have a zipcode' do
130
+ address.zipcode = ""
131
+ address.valid?
132
+ expect(address.errors['zipcode']).not_to include('is invalid')
133
+ end
134
+
135
+ it 'does not have a supported country iso' do
136
+ allow(address.country).to receive(:iso).and_return('BO')
137
+ address.valid?
138
+ expect(address.errors['zipcode']).not_to include('is invalid')
139
+ end
140
+ end
141
+ end
142
+
143
+ context "phone not required" do
144
+ before { allow(address).to receive_messages require_phone?: false }
145
+
146
+ it "shows no errors when phone is blank" do
147
+ address.phone = ""
148
+ address.valid?
149
+ expect(address.errors[:phone].size).to eq 0
150
+ end
151
+ end
152
+
153
+ context "zipcode not required" do
154
+ before { allow(address).to receive_messages require_zipcode?: false }
155
+
156
+ it "shows no errors when phone is blank" do
157
+ address.zipcode = ""
158
+ address.valid?
159
+ expect(address.errors[:zipcode].size).to eq 0
160
+ end
161
+ end
162
+ end
163
+
164
+ context ".build_default" do
165
+ context "no user given" do
166
+ let!(:default_country) { create(:country) }
167
+
168
+ context 'has a default country' do
169
+ before do
170
+ Spree::Config[:default_country_id] = default_country.id
171
+ end
172
+
173
+ it "sets up a new record with Spree::Config[:default_country_id]" do
174
+ expect(Spree::Address.build_default.country).to eq default_country
175
+ end
176
+ end
177
+
178
+ # Regression test for #1142
179
+ it "uses the first available country if :default_country_id is set to an invalid value" do
180
+ Spree::Config[:default_country_id] = "0"
181
+ expect(Spree::Address.build_default.country).to eq default_country
182
+ end
183
+ end
184
+ end
185
+
186
+
187
+ context '.factory' do
188
+ context 'with attributes that use setters defined in Address' do
189
+ let(:address_attributes) { attributes_for(:address, country_id: nil, country_iso: country.iso) }
190
+ let(:country) { create(:country, iso: 'ZZ') }
191
+
192
+ it 'uses the setters' do
193
+ expect(subject.factory(address_attributes).country_id).to eq(country.id)
194
+ end
195
+ end
196
+ end
197
+
198
+ context ".immutable_merge" do
199
+ RSpec::Matchers.define :be_address_equivalent_attributes do |expected|
200
+ fields_of_interest = [:firstname, :lastname, :company, :address1, :address2, :city, :zipcode, :phone, :alternative_phone]
201
+ match do |actual|
202
+ expected_attrs = expected.symbolize_keys.slice(*fields_of_interest)
203
+ actual_attrs = actual.symbolize_keys.slice(*fields_of_interest)
204
+ expected_attrs == actual_attrs
205
+ end
206
+ end
207
+
208
+ let(:new_address_attributes) { attributes_for(:address) }
209
+ subject { Spree::Address.immutable_merge(existing_address, new_address_attributes) }
210
+
211
+ context "no existing address supplied" do
212
+ let(:existing_address) { nil }
213
+
214
+ context 'and there is not a matching address in the database' do
215
+ it "returns new Address matching attributes given" do
216
+ expect(subject.attributes).to be_address_equivalent_attributes(new_address_attributes)
217
+ end
218
+ end
219
+
220
+ context 'and there is a matching address in the database' do
221
+ let(:new_address_attributes) { Spree::Address.value_attributes(matching_address.attributes) }
222
+ let!(:matching_address) { create(:address, firstname: 'Jordan') }
223
+
224
+ it "returns the matching address" do
225
+ expect(subject.attributes).to be_address_equivalent_attributes(new_address_attributes)
226
+ expect(subject.id).to eq(matching_address.id)
227
+ end
228
+ end
229
+ end
230
+
231
+ context "with existing address" do
232
+ let(:existing_address) { create(:address) }
233
+
234
+ it "returns a new Address of merged data" do
235
+ merged_attributes = subject.attributes.merge(new_address_attributes.symbolize_keys)
236
+ expect(subject.attributes).to be_address_equivalent_attributes merged_attributes
237
+ expect(subject.id).not_to eq existing_address.id
238
+ end
239
+
240
+ context "and no changes to attributes" do
241
+ let(:new_address_attributes) { existing_address.attributes }
242
+
243
+ it "returns existing address" do
244
+ expect(subject).to eq existing_address
245
+ expect(subject.id).to eq existing_address.id
246
+ end
247
+ end
248
+
249
+ context 'and changed address matches an existing address' do
250
+ let(:new_address_attributes) { Spree::Address.value_attributes(matching_address.attributes) }
251
+ let!(:matching_address) { create(:address, firstname: 'Jordan') }
252
+
253
+ it 'returns the matching address' do
254
+ expect(subject.attributes).to be_address_equivalent_attributes(new_address_attributes)
255
+ expect(subject.id).to eq(matching_address.id)
256
+ end
257
+ end
258
+ end
259
+ end
260
+
261
+
262
+ describe '.value_attributes' do
263
+ subject do
264
+ Spree::Address.value_attributes(base_attributes, merge_attributes)
265
+ end
266
+
267
+ context 'with symbols and strings' do
268
+ let(:base_attributes) { {'address1' => '1234 way', 'address2' => 'apt 2'} }
269
+ let(:merge_attributes) { {:address1 => '5678 way'} }
270
+
271
+ it 'stringifies and merges the keys' do
272
+ expect(subject).to eq('address1' => '5678 way', 'address2' => 'apt 2')
273
+ end
274
+ end
275
+
276
+ context 'with database-only attributes' do
277
+ let(:base_attributes) do
278
+ {
279
+ 'id' => 1,
280
+ 'created_at' => Time.now,
281
+ 'updated_at' => Time.now,
282
+ 'address1' => '1234 way',
283
+ }
284
+ end
285
+ let(:merge_attributes) do
286
+ {
287
+ 'updated_at' => Time.now,
288
+ 'address2' => 'apt 2',
289
+ }
290
+ end
291
+
292
+ it 'removes the database-only addresses' do
293
+ expect(subject).to eq('address1' => '1234 way', 'address2' => 'apt 2')
294
+ end
295
+ end
296
+
297
+ context 'with aliased attributes' do
298
+ let(:base_attributes) { {'first_name' => 'Jordan'} }
299
+ let(:merge_attributes) { {'last_name' => 'Brough'} }
300
+
301
+ it 'renames them to the normalized value' do
302
+ expect(subject).to eq('firstname' => 'Jordan', 'lastname' => 'Brough')
303
+ end
304
+
305
+ it 'does not modify the original hashes' do
306
+ subject
307
+ expect(base_attributes).to eq('first_name' => 'Jordan')
308
+ expect(merge_attributes).to eq('last_name' => 'Brough')
309
+ end
310
+ end
311
+ end
312
+
313
+ context '#country_iso=' do
314
+ let(:address) { build(:address, :country_id => nil) }
315
+ let(:country) { create(:country, iso: 'ZZ') }
316
+
317
+ it 'sets the country to the country with the matching iso code' do
318
+ address.country_iso = country.iso
319
+ expect(address.country_id).to eq(country.id)
320
+ end
321
+
322
+ it 'raises an exception if the iso is not found' do
323
+ expect {
324
+ address.country_iso = "NOCOUNTRY"
325
+ }.to raise_error(::ActiveRecord::RecordNotFound, "Couldn't find Spree::Country")
326
+ end
327
+ end
328
+
329
+ context '#full_name' do
330
+ context 'both first and last names are present' do
331
+ let(:address) { stub_model(Spree::Address, :firstname => 'Michael', :lastname => 'Jackson') }
332
+ specify { expect(address.full_name).to eq('Michael Jackson') }
333
+ end
334
+
335
+ context 'first name is blank' do
336
+ let(:address) { stub_model(Spree::Address, :firstname => nil, :lastname => 'Jackson') }
337
+ specify { expect(address.full_name).to eq('Jackson') }
338
+ end
339
+
340
+ context 'last name is blank' do
341
+ let(:address) { stub_model(Spree::Address, :firstname => 'Michael', :lastname => nil) }
342
+ specify { expect(address.full_name).to eq('Michael') }
343
+ end
344
+
345
+ context 'both first and last names are blank' do
346
+ let(:address) { stub_model(Spree::Address, :firstname => nil, :lastname => nil) }
347
+ specify { expect(address.full_name).to eq('') }
348
+ end
349
+
350
+ end
351
+
352
+ context '#state_text' do
353
+ context 'state is blank' do
354
+ let(:address) { stub_model(Spree::Address, :state => nil, :state_name => 'virginia') }
355
+ specify { expect(address.state_text).to eq('virginia') }
356
+ end
357
+
358
+ context 'both name and abbr is present' do
359
+ let(:state) { stub_model(Spree::State, :name => 'virginia', :abbr => 'va') }
360
+ let(:address) { stub_model(Spree::Address, :state => state) }
361
+ specify { expect(address.state_text).to eq('va') }
362
+ end
363
+
364
+ context 'only name is present' do
365
+ let(:state) { stub_model(Spree::State, :name => 'virginia', :abbr => nil) }
366
+ let(:address) { stub_model(Spree::Address, :state => state) }
367
+ specify { expect(address.state_text).to eq('virginia') }
368
+ end
369
+ end
370
+
371
+ context '#requires_phone' do
372
+ subject { described_class.new }
373
+
374
+ it { is_expected.to be_require_phone }
375
+ end
376
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::AdjustmentReason do
4
+
5
+ describe 'creation' do
6
+ it 'is successful' do
7
+ expect {
8
+ create(:adjustment_reason)
9
+ }.to_not raise_error
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,169 @@
1
+ # encoding: utf-8
2
+ #
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Spree::Adjustment, :type => :model do
7
+
8
+ let(:order) { Spree::Order.new }
9
+ let(:line_item) { create :line_item, order: order }
10
+
11
+ let(:adjustment) { Spree::Adjustment.create!(label: 'Adjustment', adjustable: order, order: order, amount: 5) }
12
+
13
+ context '#create & #destroy' do
14
+ let(:adjustment) { Spree::Adjustment.new(label: "Adjustment", amount: 5, order: order, adjustable: line_item) }
15
+
16
+ it 'calls #update_adjustable_adjustment_total' do
17
+ expect(adjustment).to receive(:update_adjustable_adjustment_total).twice
18
+ adjustment.save
19
+ adjustment.destroy
20
+ end
21
+ end
22
+
23
+ context '#save' do
24
+ let(:adjustment) { Spree::Adjustment.create(label: "Adjustment", amount: 5, order: order, adjustable: line_item) }
25
+
26
+ it 'touches the adjustable' do
27
+ expect { adjustment.save }.to change { line_item.updated_at }
28
+ end
29
+ end
30
+
31
+ describe 'non_tax scope' do
32
+ subject do
33
+ Spree::Adjustment.non_tax.to_a
34
+ end
35
+
36
+ let!(:tax_adjustment) do
37
+ create(:adjustment, adjustable: order, order: order, source: create(:tax_rate))
38
+ end
39
+
40
+ let!(:non_tax_adjustment_with_source) do
41
+ create(:adjustment, adjustable: order, order: order, source_type: 'Spree::Order', source_id: nil)
42
+ end
43
+
44
+ let!(:non_tax_adjustment_without_source) do
45
+ create(:adjustment, adjustable: order, order: order, source: nil)
46
+ end
47
+
48
+ it 'select non-tax adjustments' do
49
+ expect(subject).to_not include tax_adjustment
50
+ expect(subject).to include non_tax_adjustment_with_source
51
+ expect(subject).to include non_tax_adjustment_without_source
52
+ end
53
+ end
54
+
55
+ context '#currency' do
56
+ let(:order) { Spree::Order.new currency: 'JPY' }
57
+
58
+ it 'returns the adjustables currency' do
59
+ expect(adjustment.currency).to eq 'JPY'
60
+ end
61
+
62
+ context 'adjustable is nil' do
63
+ before do
64
+ adjustment.adjustable = nil
65
+ end
66
+ it 'uses the global currency of USD' do
67
+ expect(adjustment.currency).to eq 'USD'
68
+ end
69
+ end
70
+ end
71
+
72
+ context "#display_amount" do
73
+ before { adjustment.amount = 10.55 }
74
+
75
+ it "shows the amount" do
76
+ expect(adjustment.display_amount.to_s).to eq "$10.55"
77
+ end
78
+
79
+ context "with currency set to JPY" do
80
+ let(:order) { Spree::Order.new currency: 'JPY' }
81
+
82
+ context "when adjustable is set to an order" do
83
+ it "displays in JPY" do
84
+ expect(adjustment.display_amount.to_s).to eq "¥11"
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ context '#update!' do
91
+ let(:adjustment) { Spree::Adjustment.create!(label: 'Adjustment', order: order, adjustable: order, amount: 5, finalized: finalized, source: source) }
92
+ let(:source) { mock_model(Spree::TaxRate, compute_amount: 10) }
93
+
94
+ subject { adjustment.update! }
95
+
96
+ context "when adjustment is closed" do
97
+ let(:finalized) { true }
98
+
99
+ it "does not update the adjustment" do
100
+ expect(adjustment).to_not receive(:update_column)
101
+ subject
102
+ end
103
+ end
104
+
105
+ context "when adjustment isn't finalized" do
106
+ let(:finalized) { false }
107
+
108
+ it "updates the amount" do
109
+ expect { subject }.to change { adjustment.amount }.to(10)
110
+ end
111
+
112
+ context "it is a promotion adjustment" do
113
+ let(:promotion) { create(:promotion, :with_order_adjustment, starts_at: promo_start_date) }
114
+ let(:promo_start_date) { nil }
115
+ let(:promotion_code) { promotion.codes.first }
116
+ let(:order) { create(:order_with_line_items, line_items_count: 1) }
117
+
118
+ let!(:adjustment) do
119
+ promotion.activate(order: order, promotion_code: promotion_code)
120
+ order.adjustments.first
121
+ end
122
+
123
+ context "the promotion is eligible" do
124
+ it "sets the adjustment elgiible to true" do
125
+ subject
126
+ expect(adjustment.eligible).to eq true
127
+ end
128
+ end
129
+
130
+ context "the promotion is not eligible" do
131
+ let(:promo_start_date) { Date.tomorrow }
132
+
133
+ it "sets the adjustment elgiible to false" do
134
+ subject
135
+ expect(adjustment.eligible).to eq false
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "promotion code presence error" do
143
+ subject do
144
+ adjustment.valid?
145
+ adjustment.errors[:promotion_code]
146
+ end
147
+
148
+ context "when the adjustment is not a promotion adjustment" do
149
+ let(:adjustment) { build(:adjustment) }
150
+
151
+ it { is_expected.to be_blank }
152
+ end
153
+
154
+ context "when the adjustment is a promotion adjustment" do
155
+ let(:adjustment) { build(:adjustment, source: promotion.actions.first) }
156
+ let(:promotion) { create(:promotion, :with_order_adjustment) }
157
+
158
+ context "when the promotion does not have a code" do
159
+ it { is_expected.to be_blank }
160
+ end
161
+
162
+ context "when the promotion has a code" do
163
+ let!(:promotion_code) { create(:promotion_code, promotion: promotion) }
164
+
165
+ it { is_expected.to include("can't be blank") }
166
+ end
167
+ end
168
+ end
169
+ end