spree_core 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/Gemfile +3 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/spree.js.coffee.erb +1 -1
  6. data/app/models/spree/ability.rb +1 -1
  7. data/app/models/spree/base.rb +3 -1
  8. data/app/models/spree/order_updater.rb +2 -1
  9. data/app/models/spree/price.rb +7 -12
  10. data/app/models/spree/product.rb +3 -2
  11. data/app/models/spree/reimbursement.rb +1 -1
  12. data/app/models/spree/state.rb +2 -0
  13. data/app/models/spree/zone.rb +1 -1
  14. data/lib/spree/core/version.rb +1 -1
  15. data/lib/spree/testing_support/shoulda_matcher_configuration.rb +6 -0
  16. data/script/rails +9 -0
  17. data/spec/fixtures/thinking-cat.jpg +0 -0
  18. data/spec/helpers/base_helper_spec.rb +137 -0
  19. data/spec/helpers/products_helper_spec.rb +224 -0
  20. data/spec/lib/calculated_adjustments_spec.rb +7 -0
  21. data/spec/lib/i18n_spec.rb +123 -0
  22. data/spec/lib/search/base_spec.rb +86 -0
  23. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +101 -0
  24. data/spec/lib/spree/core/controller_helpers/order_spec.rb +95 -0
  25. data/spec/lib/spree/core/controller_helpers/search_spec.rb +17 -0
  26. data/spec/lib/spree/core/controller_helpers/store_spec.rb +16 -0
  27. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +39 -0
  28. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +22 -0
  29. data/spec/lib/spree/core/importer/order_spec.rb +502 -0
  30. data/spec/lib/spree/core/validators/email_spec.rb +53 -0
  31. data/spec/lib/spree/localized_number_spec.rb +38 -0
  32. data/spec/lib/spree/migrations_spec.rb +34 -0
  33. data/spec/lib/spree/money_spec.rb +122 -0
  34. data/spec/lib/tasks/exchanges_spec.rb +136 -0
  35. data/spec/mailers/order_mailer_spec.rb +124 -0
  36. data/spec/mailers/reimbursement_mailer_spec.rb +47 -0
  37. data/spec/mailers/shipment_mailer_spec.rb +63 -0
  38. data/spec/mailers/test_mailer_spec.rb +24 -0
  39. data/spec/models/spree/ability_spec.rb +246 -0
  40. data/spec/models/spree/address_spec.rb +291 -0
  41. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +286 -0
  42. data/spec/models/spree/adjustment_spec.rb +163 -0
  43. data/spec/models/spree/app_configuration_spec.rb +23 -0
  44. data/spec/models/spree/asset_spec.rb +25 -0
  45. data/spec/models/spree/calculator/default_tax_spec.rb +127 -0
  46. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +25 -0
  47. data/spec/models/spree/calculator/flat_rate_spec.rb +47 -0
  48. data/spec/models/spree/calculator/flexi_rate_spec.rb +41 -0
  49. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +15 -0
  50. data/spec/models/spree/calculator/price_sack_spec.rb +30 -0
  51. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +51 -0
  52. data/spec/models/spree/calculator/shipping.rb +8 -0
  53. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +23 -0
  54. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +13 -0
  55. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +52 -0
  56. data/spec/models/spree/calculator/shipping/per_item_spec.rb +20 -0
  57. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +29 -0
  58. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +40 -0
  59. data/spec/models/spree/calculator/tiered_percent_spec.rb +51 -0
  60. data/spec/models/spree/calculator_spec.rb +69 -0
  61. data/spec/models/spree/classification_spec.rb +93 -0
  62. data/spec/models/spree/concerns/display_money_spec.rb +43 -0
  63. data/spec/models/spree/country_spec.rb +18 -0
  64. data/spec/models/spree/credit_card_spec.rb +324 -0
  65. data/spec/models/spree/customer_return_spec.rb +262 -0
  66. data/spec/models/spree/exchange_spec.rb +75 -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 +54 -0
  70. data/spec/models/spree/image_spec.rb +5 -0
  71. data/spec/models/spree/inventory_unit_spec.rb +242 -0
  72. data/spec/models/spree/line_item_spec.rb +267 -0
  73. data/spec/models/spree/option_type_spec.rb +14 -0
  74. data/spec/models/spree/option_value_spec.rb +13 -0
  75. data/spec/models/spree/order/address_spec.rb +50 -0
  76. data/spec/models/spree/order/adjustments_spec.rb +29 -0
  77. data/spec/models/spree/order/callbacks_spec.rb +42 -0
  78. data/spec/models/spree/order/checkout_spec.rb +764 -0
  79. data/spec/models/spree/order/currency_updater_spec.rb +32 -0
  80. data/spec/models/spree/order/finalizing_spec.rb +117 -0
  81. data/spec/models/spree/order/helpers_spec.rb +5 -0
  82. data/spec/models/spree/order/payment_spec.rb +214 -0
  83. data/spec/models/spree/order/risk_assessment_spec.rb +84 -0
  84. data/spec/models/spree/order/shipments_spec.rb +43 -0
  85. data/spec/models/spree/order/state_machine_spec.rb +216 -0
  86. data/spec/models/spree/order/tax_spec.rb +84 -0
  87. data/spec/models/spree/order/totals_spec.rb +24 -0
  88. data/spec/models/spree/order/updating_spec.rb +18 -0
  89. data/spec/models/spree/order/validations_spec.rb +15 -0
  90. data/spec/models/spree/order_contents_spec.rb +256 -0
  91. data/spec/models/spree/order_inventory_spec.rb +228 -0
  92. data/spec/models/spree/order_merger_spec.rb +133 -0
  93. data/spec/models/spree/order_spec.rb +954 -0
  94. data/spec/models/spree/order_updater_spec.rb +283 -0
  95. data/spec/models/spree/payment/gateway_options_spec.rb +119 -0
  96. data/spec/models/spree/payment_method_spec.rb +95 -0
  97. data/spec/models/spree/payment_spec.rb +926 -0
  98. data/spec/models/spree/preference_spec.rb +80 -0
  99. data/spec/models/spree/preferences/configuration_spec.rb +30 -0
  100. data/spec/models/spree/preferences/preferable_spec.rb +348 -0
  101. data/spec/models/spree/preferences/scoped_store_spec.rb +58 -0
  102. data/spec/models/spree/preferences/store_spec.rb +46 -0
  103. data/spec/models/spree/price_spec.rb +42 -0
  104. data/spec/models/spree/product/scopes_spec.rb +148 -0
  105. data/spec/models/spree/product_duplicator_spec.rb +103 -0
  106. data/spec/models/spree/product_filter_spec.rb +26 -0
  107. data/spec/models/spree/product_option_type_spec.rb +5 -0
  108. data/spec/models/spree/product_property_spec.rb +11 -0
  109. data/spec/models/spree/product_spec.rb +474 -0
  110. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +50 -0
  111. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +148 -0
  112. data/spec/models/spree/promotion/actions/create_line_items_spec.rb +86 -0
  113. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +36 -0
  114. data/spec/models/spree/promotion/rules/first_order_spec.rb +75 -0
  115. data/spec/models/spree/promotion/rules/item_total_spec.rb +282 -0
  116. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +42 -0
  117. data/spec/models/spree/promotion/rules/option_value_spec.rb +90 -0
  118. data/spec/models/spree/promotion/rules/product_spec.rb +143 -0
  119. data/spec/models/spree/promotion/rules/taxon_spec.rb +102 -0
  120. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +27 -0
  121. data/spec/models/spree/promotion/rules/user_spec.rb +37 -0
  122. data/spec/models/spree/promotion_action_spec.rb +10 -0
  123. data/spec/models/spree/promotion_category_spec.rb +17 -0
  124. data/spec/models/spree/promotion_handler/cart_spec.rb +102 -0
  125. data/spec/models/spree/promotion_handler/coupon_spec.rb +323 -0
  126. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +48 -0
  127. data/spec/models/spree/promotion_handler/page_spec.rb +44 -0
  128. data/spec/models/spree/promotion_rule_spec.rb +29 -0
  129. data/spec/models/spree/promotion_spec.rb +603 -0
  130. data/spec/models/spree/property_spec.rb +5 -0
  131. data/spec/models/spree/prototype_spec.rb +5 -0
  132. data/spec/models/spree/refund_spec.rb +195 -0
  133. data/spec/models/spree/reimbursement/credit_spec.rb +36 -0
  134. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +140 -0
  135. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +83 -0
  136. data/spec/models/spree/reimbursement_performer_spec.rb +30 -0
  137. data/spec/models/spree/reimbursement_spec.rb +215 -0
  138. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +51 -0
  139. data/spec/models/spree/reimbursement_type/credit_spec.rb +53 -0
  140. data/spec/models/spree/reimbursement_type/exchange_spec.rb +46 -0
  141. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +55 -0
  142. data/spec/models/spree/return_authorization_spec.rb +250 -0
  143. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +77 -0
  144. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +58 -0
  145. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +61 -0
  146. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +32 -0
  147. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +29 -0
  148. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +35 -0
  149. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +65 -0
  150. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +43 -0
  151. data/spec/models/spree/return_item_spec.rb +682 -0
  152. data/spec/models/spree/returns_calculator_spec.rb +14 -0
  153. data/spec/models/spree/shipment_spec.rb +740 -0
  154. data/spec/models/spree/shipping_calculator_spec.rb +45 -0
  155. data/spec/models/spree/shipping_category_spec.rb +5 -0
  156. data/spec/models/spree/shipping_method_spec.rb +88 -0
  157. data/spec/models/spree/shipping_rate_spec.rb +141 -0
  158. data/spec/models/spree/state_spec.rb +18 -0
  159. data/spec/models/spree/stock/availability_validator_spec.rb +36 -0
  160. data/spec/models/spree/stock/content_item_spec.rb +22 -0
  161. data/spec/models/spree/stock/coordinator_spec.rb +51 -0
  162. data/spec/models/spree/stock/differentiator_spec.rb +39 -0
  163. data/spec/models/spree/stock/estimator_spec.rb +154 -0
  164. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +38 -0
  165. data/spec/models/spree/stock/package_spec.rb +194 -0
  166. data/spec/models/spree/stock/packer_spec.rb +70 -0
  167. data/spec/models/spree/stock/prioritizer_spec.rb +125 -0
  168. data/spec/models/spree/stock/quantifier_spec.rb +97 -0
  169. data/spec/models/spree/stock/splitter/backordered_spec.rb +29 -0
  170. data/spec/models/spree/stock/splitter/base_spec.rb +21 -0
  171. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +47 -0
  172. data/spec/models/spree/stock/splitter/weight_spec.rb +32 -0
  173. data/spec/models/spree/stock_item_spec.rb +410 -0
  174. data/spec/models/spree/stock_location_spec.rb +243 -0
  175. data/spec/models/spree/stock_movement_spec.rb +56 -0
  176. data/spec/models/spree/stock_transfer_spec.rb +50 -0
  177. data/spec/models/spree/store_spec.rb +50 -0
  178. data/spec/models/spree/tax_category_spec.rb +27 -0
  179. data/spec/models/spree/tax_rate_spec.rb +382 -0
  180. data/spec/models/spree/taxon_spec.rb +74 -0
  181. data/spec/models/spree/taxonomy_spec.rb +18 -0
  182. data/spec/models/spree/tracker_spec.rb +21 -0
  183. data/spec/models/spree/user_spec.rb +130 -0
  184. data/spec/models/spree/validations/db_maximum_length_validator_spec.rb +24 -0
  185. data/spec/models/spree/variant_spec.rb +523 -0
  186. data/spec/models/spree/zone_spec.rb +444 -0
  187. data/spec/spec_helper.rb +74 -0
  188. data/spec/support/big_decimal.rb +5 -0
  189. data/spec/support/concerns/adjustment_source_spec.rb +23 -0
  190. data/spec/support/concerns/default_price_spec.rb +28 -0
  191. data/spec/support/rake.rb +13 -0
  192. data/spec/support/test_gateway.rb +2 -0
  193. data/spree_core.gemspec +48 -0
  194. metadata +185 -4
@@ -0,0 +1,43 @@
1
+ describe Spree::Order, type: :model do
2
+ let(:order) { create(:order_with_totals) }
3
+
4
+ context "ensure shipments will be updated" do
5
+ before { Spree::Shipment.create!(order: order, stock_location: create(:stock_location)) }
6
+
7
+ it "destroys current shipments" do
8
+ order.ensure_updated_shipments
9
+ expect(order.shipments).to be_empty
10
+ end
11
+
12
+ it "puts order back in address state" do
13
+ order.ensure_updated_shipments
14
+ expect(order.state).to eq 'address'
15
+ end
16
+
17
+ it "resets shipment_total" do
18
+ order.update_column(:shipment_total, 5)
19
+ order.ensure_updated_shipments
20
+ expect(order.shipment_total).to eq(0)
21
+ end
22
+
23
+ context "except when order is completed, that's OrderInventory job" do
24
+ it "doesn't touch anything" do
25
+ allow(order).to receive_messages completed?: true
26
+ order.update_column(:shipment_total, 5)
27
+ order.shipments.create!(stock_location: create(:stock_location))
28
+
29
+ expect {
30
+ order.ensure_updated_shipments
31
+ }.not_to change { order.shipment_total }
32
+
33
+ expect {
34
+ order.ensure_updated_shipments
35
+ }.not_to change { order.shipments }
36
+
37
+ expect {
38
+ order.ensure_updated_shipments
39
+ }.not_to change { order.state }
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,216 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, type: :model do
4
+ let(:order) { Spree::Order.new }
5
+ before do
6
+ # Ensure state machine has been re-defined correctly
7
+ Spree::Order.define_state_machine!
8
+ # We don't care about this validation here
9
+ allow(order).to receive(:require_email)
10
+ end
11
+
12
+ context "#next!" do
13
+ context "when current state is confirm" do
14
+ before do
15
+ order.state = "confirm"
16
+ order.run_callbacks(:create)
17
+ allow(order).to receive_messages payment_required?: true
18
+ allow(order).to receive_messages process_payments!: true
19
+ allow(order).to receive :has_available_shipment
20
+ end
21
+
22
+ context "when payment processing succeeds" do
23
+ before do
24
+ order.payments << FactoryGirl.create(:payment, state: 'checkout', order: order)
25
+ allow(order).to receive_messages process_payments: true
26
+ end
27
+
28
+ it "should finalize order when transitioning to complete state" do
29
+ expect(order).to receive(:finalize!)
30
+ order.next!
31
+ end
32
+
33
+ context "when credit card processing fails" do
34
+ before { allow(order).to receive_messages process_payments!: false }
35
+
36
+ it "should not complete the order" do
37
+ order.next
38
+ expect(order.state).to eq("confirm")
39
+ end
40
+ end
41
+ end
42
+
43
+ context "when payment processing fails" do
44
+ before { allow(order).to receive_messages process_payments!: false }
45
+
46
+ it "cannot transition to complete" do
47
+ order.next
48
+ expect(order.state).to eq("confirm")
49
+ end
50
+ end
51
+ end
52
+
53
+ context "when current state is delivery" do
54
+ before do
55
+ allow(order).to receive_messages payment_required?: true
56
+ allow(order).to receive :apply_free_shipping_promotions
57
+ order.state = "delivery"
58
+ end
59
+
60
+ it "adjusts tax rates when transitioning to delivery" do
61
+ # Once for the line items
62
+ expect(Spree::TaxRate).to receive(:adjust).once
63
+ allow(order).to receive :set_shipments_cost
64
+ order.next!
65
+ end
66
+
67
+ it "adjusts tax rates twice if there are any shipments" do
68
+ # Once for the line items, once for the shipments
69
+ order.shipments.build stock_location: create(:stock_location)
70
+ expect(Spree::TaxRate).to receive(:adjust).twice
71
+ allow(order).to receive :set_shipments_cost
72
+ order.next!
73
+ end
74
+ end
75
+ end
76
+
77
+ context "#can_cancel?" do
78
+ %w(pending backorder ready).each do |shipment_state|
79
+ it "should be true if shipment_state is #{shipment_state}" do
80
+ allow(order).to receive_messages completed?: true
81
+ order.shipment_state = shipment_state
82
+ expect(order.can_cancel?).to be true
83
+ end
84
+ end
85
+
86
+ (Spree::Shipment.state_machine.states.keys - [:pending, :backorder, :ready]).each do |shipment_state|
87
+ it "should be false if shipment_state is #{shipment_state}" do
88
+ allow(order).to receive_messages completed?: true
89
+ order.shipment_state = shipment_state
90
+ expect(order.can_cancel?).to be false
91
+ end
92
+ end
93
+ end
94
+
95
+ context "#cancel" do
96
+ let!(:variant) { stub_model(Spree::Variant) }
97
+ let!(:inventory_units) { [stub_model(Spree::InventoryUnit, variant: variant),
98
+ stub_model(Spree::InventoryUnit, variant: variant)] }
99
+ let!(:shipment) do
100
+ shipment = stub_model(Spree::Shipment)
101
+ allow(shipment).to receive_messages inventory_units: inventory_units, order: order
102
+ allow(order).to receive_messages shipments: [shipment]
103
+ shipment
104
+ end
105
+
106
+ before do
107
+ 2.times do
108
+ create(:line_item, order: order, price: 10)
109
+ end
110
+
111
+ allow(order.line_items).to receive_messages find_by_variant_id: order.line_items.first
112
+
113
+ allow(order).to receive_messages completed?: true
114
+ allow(order).to receive_messages allow_cancel?: true
115
+
116
+ shipments = [shipment]
117
+ allow(order).to receive_messages shipments: shipments
118
+ allow(shipments).to receive_messages states: []
119
+ allow(shipments).to receive_messages ready: []
120
+ allow(shipments).to receive_messages pending: []
121
+ allow(shipments).to receive_messages shipped: []
122
+
123
+ allow_any_instance_of(Spree::OrderUpdater).to receive(:update_adjustment_total) { 10 }
124
+ end
125
+
126
+ it "should send a cancel email" do
127
+ # Stub methods that cause side-effects in this test
128
+ allow(shipment).to receive(:cancel!)
129
+ allow(order).to receive :has_available_shipment
130
+ allow(order).to receive :restock_items!
131
+ mail_message = double "Mail::Message"
132
+ order_id = nil
133
+ expect(Spree::OrderMailer).to receive(:cancel_email) { |*args|
134
+ order_id = args[0]
135
+ mail_message
136
+ }
137
+ expect(mail_message).to receive :deliver_later
138
+ order.cancel!
139
+ expect(order_id).to eq(order.id)
140
+ end
141
+
142
+ context "restocking inventory" do
143
+ before do
144
+ allow(shipment).to receive(:ensure_correct_adjustment)
145
+ allow(shipment).to receive(:update_order)
146
+ allow(Spree::OrderMailer).to receive(:cancel_email).and_return(mail_message = double)
147
+ allow(mail_message).to receive :deliver
148
+
149
+ allow(order).to receive :has_available_shipment
150
+ end
151
+ end
152
+
153
+ context "resets payment state" do
154
+ let(:payment) { create(:payment, amount: order.total) }
155
+
156
+ before do
157
+ # TODO: This is ugly :(
158
+ # Stubs methods that cause unwanted side effects in this test
159
+ allow(Spree::OrderMailer).to receive(:cancel_email).and_return(mail_message = double)
160
+ allow(mail_message).to receive :deliver_later
161
+ allow(order).to receive :has_available_shipment
162
+ allow(order).to receive :restock_items!
163
+ allow(shipment).to receive(:cancel!)
164
+ allow(payment).to receive(:cancel!)
165
+ allow(order).to receive_message_chain(:payments, :valid, :size).and_return(1)
166
+ allow(order).to receive_message_chain(:payments, :completed).and_return([payment])
167
+ allow(order).to receive_message_chain(:payments, :completed, :includes).and_return([payment])
168
+ allow(order).to receive_message_chain(:payments, :last).and_return(payment)
169
+ end
170
+
171
+ context "without shipped items" do
172
+ it "should set payment state to 'void'" do
173
+ expect { order.cancel! }.to change{ order.reload.payment_state }.to("void")
174
+ end
175
+ end
176
+
177
+ context "with shipped items" do
178
+ before do
179
+ allow(order).to receive_messages shipment_state: 'partial'
180
+ allow(order).to receive_messages outstanding_balance?: false
181
+ allow(order).to receive_messages payment_state: "paid"
182
+ end
183
+
184
+ it "should not alter the payment state" do
185
+ order.cancel!
186
+ expect(order.payment_state).to eql "paid"
187
+ end
188
+ end
189
+
190
+ context "with payments" do
191
+ let(:payment) { create(:payment) }
192
+
193
+ it "should automatically refund all payments" do
194
+ allow(order).to receive_message_chain(:payments, :valid, :size).and_return(1)
195
+ allow(order).to receive_message_chain(:payments, :completed).and_return([payment])
196
+ allow(order).to receive_message_chain(:payments, :completed, :includes).and_return([payment])
197
+ allow(order).to receive_message_chain(:payments, :last).and_return(payment)
198
+ expect(payment).to receive(:cancel!)
199
+ order.cancel!
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ # Another regression test for #729
206
+ context "#resume" do
207
+ before do
208
+ allow(order).to receive_messages email: "user@spreecommerce.com"
209
+ allow(order).to receive_messages state: "canceled"
210
+ allow(order).to receive_messages allow_resume?: true
211
+
212
+ # Stubs method that cause unwanted side effects in this test
213
+ allow(order).to receive :has_available_shipment
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Spree::Order, :type => :model do
5
+ let(:order) { stub_model(Spree::Order) }
6
+
7
+ context "#tax_zone" do
8
+ let(:bill_address) { create :address }
9
+ let(:ship_address) { create :address }
10
+ let(:order) { Spree::Order.create(:ship_address => ship_address, :bill_address => bill_address) }
11
+ let(:zone) { create :zone }
12
+
13
+ context "when no zones exist" do
14
+ it "should return nil" do
15
+ expect(order.tax_zone).to be_nil
16
+ end
17
+ end
18
+
19
+ context "when :tax_using_ship_address => true" do
20
+ before { Spree::Config.set(:tax_using_ship_address => true) }
21
+
22
+ it "should calculate using ship_address" do
23
+ expect(Spree::Zone).to receive(:match).at_least(:once).with(ship_address)
24
+ expect(Spree::Zone).not_to receive(:match).with(bill_address)
25
+ order.tax_zone
26
+ end
27
+ end
28
+
29
+ context "when :tax_using_ship_address => false" do
30
+ before { Spree::Config.set(:tax_using_ship_address => false) }
31
+
32
+ it "should calculate using bill_address" do
33
+ expect(Spree::Zone).to receive(:match).at_least(:once).with(bill_address)
34
+ expect(Spree::Zone).not_to receive(:match).with(ship_address)
35
+ order.tax_zone
36
+ end
37
+ end
38
+
39
+ context "when there is a default tax zone" do
40
+ before do
41
+ @default_zone = create(:zone, :name => "foo_zone")
42
+ allow(Spree::Zone).to receive_messages :default_tax => @default_zone
43
+ end
44
+
45
+ context "when there is a matching zone" do
46
+ before { allow(Spree::Zone).to receive_messages(:match => zone) }
47
+
48
+ it "should return the matching zone" do
49
+ expect(order.tax_zone).to eq(zone)
50
+ end
51
+ end
52
+
53
+ context "when there is no matching zone" do
54
+ before { allow(Spree::Zone).to receive_messages(:match => nil) }
55
+
56
+ it "should return the default tax zone" do
57
+ expect(order.tax_zone).to eq(@default_zone)
58
+ end
59
+ end
60
+ end
61
+
62
+ context "when no default tax zone" do
63
+ before { allow(Spree::Zone).to receive_messages :default_tax => nil }
64
+
65
+ context "when there is a matching zone" do
66
+ before { allow(Spree::Zone).to receive_messages(:match => zone) }
67
+
68
+ it "should return the matching zone" do
69
+ expect(order.tax_zone).to eq(zone)
70
+ end
71
+ end
72
+
73
+ context "when there is no matching zone" do
74
+ before { allow(Spree::Zone).to receive_messages(:match => nil) }
75
+
76
+ it "should return nil" do
77
+ expect(order.tax_zone).to be_nil
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Order, :type => :model do
5
+ let(:order) { Order.create }
6
+ let(:shirt) { create(:variant) }
7
+
8
+ context "adds item to cart and activates promo" do
9
+ let(:promotion) { Promotion.create name: 'Huhu' }
10
+ let(:calculator) { Calculator::FlatPercentItemTotal.new(:preferred_flat_percent => 10) }
11
+ let!(:action) { Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
12
+
13
+ before { order.contents.add(shirt, 1) }
14
+
15
+ context "item quantity changes" do
16
+ it "recalculates order adjustments" do
17
+ expect {
18
+ order.contents.add(shirt, 3)
19
+ }.to change { order.adjustments.eligible.pluck(:amount) }
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::Order, :type => :model do
4
+ let(:order) { create(:order) }
5
+
6
+ context "#update!" do
7
+ let(:line_items) { [mock_model(Spree::LineItem, :amount => 5) ]}
8
+
9
+ context "when there are update hooks" do
10
+ before { Spree::Order.register_update_hook :foo }
11
+ after { Spree::Order.update_hooks.clear }
12
+ it "should call each of the update hooks" do
13
+ expect(order).to receive :foo
14
+ order.update!
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ module Spree
4
+ describe Spree::Order, :type => :model do
5
+ context "validations" do
6
+ # Regression test for #2214
7
+ it "does not return two error messages when email is blank" do
8
+ order = Spree::Order.new
9
+ allow(order).to receive_messages(:require_email => true)
10
+ order.valid?
11
+ expect(order.errors[:email]).to eq(["can't be blank"])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,256 @@
1
+ require 'spec_helper'
2
+
3
+ describe Spree::OrderContents, :type => :model do
4
+ let(:order) { Spree::Order.create }
5
+ let(:variant) { create(:variant) }
6
+
7
+ subject { described_class.new(order) }
8
+
9
+ context "#add" do
10
+ context 'given quantity is not explicitly provided' do
11
+ it 'should add one line item' do
12
+ line_item = subject.add(variant)
13
+ expect(line_item.quantity).to eq(1)
14
+ expect(order.line_items.size).to eq(1)
15
+ end
16
+ end
17
+
18
+ context 'given a shipment' do
19
+ it "ensure shipment calls update_amounts instead of order calling ensure_updated_shipments" do
20
+ shipment = create(:shipment)
21
+ expect(subject.order).to_not receive(:ensure_updated_shipments)
22
+ expect(shipment).to receive(:update_amounts)
23
+ subject.add(variant, 1, shipment: shipment)
24
+ end
25
+ end
26
+
27
+ context 'not given a shipment' do
28
+ it "ensures updated shipments" do
29
+ expect(subject.order).to receive(:ensure_updated_shipments)
30
+ subject.add(variant)
31
+ end
32
+ end
33
+
34
+ it 'should add line item if one does not exist' do
35
+ line_item = subject.add(variant, 1)
36
+ expect(line_item.quantity).to eq(1)
37
+ expect(order.line_items.size).to eq(1)
38
+ end
39
+
40
+ it 'should update line item if one exists' do
41
+ subject.add(variant, 1)
42
+ line_item = subject.add(variant, 1)
43
+ expect(line_item.quantity).to eq(2)
44
+ expect(order.line_items.size).to eq(1)
45
+ end
46
+
47
+ it "should update order totals" do
48
+ expect(order.item_total.to_f).to eq(0.00)
49
+ expect(order.total.to_f).to eq(0.00)
50
+
51
+ subject.add(variant, 1)
52
+
53
+ expect(order.item_total.to_f).to eq(19.99)
54
+ expect(order.total.to_f).to eq(19.99)
55
+ end
56
+
57
+ context "running promotions" do
58
+ let(:promotion) { create(:promotion) }
59
+ let(:calculator) { Spree::Calculator::FlatRate.new(:preferred_amount => 10) }
60
+
61
+ shared_context "discount changes order total" do
62
+ before { subject.add(variant, 1) }
63
+ it { expect(subject.order.total).not_to eq variant.price }
64
+ end
65
+
66
+ context "one active order promotion" do
67
+ let!(:action) { Spree::Promotion::Actions::CreateAdjustment.create(promotion: promotion, calculator: calculator) }
68
+
69
+ it "creates valid discount on order" do
70
+ subject.add(variant, 1)
71
+ expect(subject.order.adjustments.to_a.sum(&:amount)).not_to eq 0
72
+ end
73
+
74
+ include_context "discount changes order total"
75
+ end
76
+
77
+ context "one active line item promotion" do
78
+ let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
79
+
80
+ it "creates valid discount on order" do
81
+ subject.add(variant, 1)
82
+ expect(subject.order.line_item_adjustments.to_a.sum(&:amount)).not_to eq 0
83
+ end
84
+
85
+ include_context "discount changes order total"
86
+ end
87
+
88
+ context "VAT for variant with percent promotion" do
89
+ let!(:category) { Spree::TaxCategory.create name: "Taxable Foo" }
90
+ let!(:rate) do
91
+ Spree::TaxRate.create(
92
+ amount: 0.25,
93
+ included_in_price: true,
94
+ calculator: Spree::Calculator::DefaultTax.create,
95
+ tax_category: category,
96
+ zone: create(:zone_with_country, default_tax: true)
97
+ )
98
+ end
99
+ let(:variant) { create(:variant, price: 1000) }
100
+ let(:calculator) { Spree::Calculator::PercentOnLineItem.new(:preferred_percent => 50) }
101
+ let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(promotion: promotion, calculator: calculator) }
102
+
103
+ it "should update included_tax_total" do
104
+ expect(order.included_tax_total.to_f).to eq(0.00)
105
+ subject.add(variant, 1)
106
+ expect(order.included_tax_total.to_f).to eq(100)
107
+ end
108
+
109
+ it "should update included_tax_total after adding two line items" do
110
+ subject.add(variant, 1)
111
+ expect(order.included_tax_total.to_f).to eq(100)
112
+ subject.add(variant, 1)
113
+ expect(order.included_tax_total.to_f).to eq(200)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ context "#remove" do
120
+ context "given an invalid variant" do
121
+ it "raises an exception" do
122
+ expect {
123
+ subject.remove(variant, 1)
124
+ }.to raise_error(ActiveRecord::RecordNotFound)
125
+ end
126
+ end
127
+
128
+ context 'given quantity is not explicitly provided' do
129
+ it 'should remove one line item' do
130
+ line_item = subject.add(variant, 3)
131
+ subject.remove(variant)
132
+
133
+ expect(line_item.quantity).to eq(2)
134
+ end
135
+ end
136
+
137
+ context 'given a shipment' do
138
+ it "ensure shipment calls update_amounts instead of order calling ensure_updated_shipments" do
139
+ line_item = subject.add(variant, 1)
140
+ shipment = create(:shipment)
141
+ expect(subject.order).to_not receive(:ensure_updated_shipments)
142
+ expect(shipment).to receive(:update_amounts)
143
+ subject.remove(variant, 1, shipment: shipment)
144
+ end
145
+ end
146
+
147
+ context 'not given a shipment' do
148
+ it "ensures updated shipments" do
149
+ line_item = subject.add(variant, 1)
150
+ expect(subject.order).to receive(:ensure_updated_shipments)
151
+ subject.remove(variant)
152
+ end
153
+ end
154
+
155
+ it 'should reduce line_item quantity if quantity is less the line_item quantity' do
156
+ line_item = subject.add(variant, 3)
157
+ subject.remove(variant, 1)
158
+
159
+ expect(line_item.quantity).to eq(2)
160
+ end
161
+
162
+ it 'should remove line_item if quantity matches line_item quantity' do
163
+ subject.add(variant, 1)
164
+ removed_line_item = subject.remove(variant, 1)
165
+
166
+ # Should reflect the change already in Order#line_item
167
+ expect(order.line_items).to_not include(removed_line_item)
168
+ end
169
+
170
+ it "should update order totals" do
171
+ expect(order.item_total.to_f).to eq(0.00)
172
+ expect(order.total.to_f).to eq(0.00)
173
+
174
+ subject.add(variant,2)
175
+
176
+ expect(order.item_total.to_f).to eq(39.98)
177
+ expect(order.total.to_f).to eq(39.98)
178
+
179
+ subject.remove(variant,1)
180
+ expect(order.item_total.to_f).to eq(19.99)
181
+ expect(order.total.to_f).to eq(19.99)
182
+ end
183
+ end
184
+
185
+ context "update cart" do
186
+ let!(:shirt) { subject.add variant, 1 }
187
+
188
+ let(:params) do
189
+ { line_items_attributes: {
190
+ "0" => { id: shirt.id, quantity: 3 }
191
+ } }
192
+ end
193
+
194
+ it "changes item quantity" do
195
+ subject.update_cart params
196
+ expect(shirt.quantity).to eq 3
197
+ end
198
+
199
+ it "updates order totals" do
200
+ expect {
201
+ subject.update_cart params
202
+ }.to change { subject.order.total }
203
+ end
204
+
205
+ context "submits item quantity 0" do
206
+ let(:params) do
207
+ { line_items_attributes: {
208
+ "0" => { id: shirt.id, quantity: 0 },
209
+ "1" => { id: "666", quantity: 0}
210
+ } }
211
+ end
212
+
213
+ it "removes item from order" do
214
+ expect {
215
+ subject.update_cart params
216
+ }.to change { subject.order.line_items.count }
217
+ end
218
+
219
+ it "doesnt try to update unexistent items" do
220
+ filtered_params = { line_items_attributes: {
221
+ "0" => { id: shirt.id, quantity: 0 },
222
+ } }
223
+ expect(subject.order).to receive(:update_attributes).with(filtered_params)
224
+ subject.update_cart params
225
+ end
226
+
227
+ it "should not filter if there is only one line item" do
228
+ single_line_item_params = { line_items_attributes: { id: shirt.id, quantity: 0 } }
229
+ expect(subject.order).to receive(:update_attributes).with(single_line_item_params)
230
+ subject.update_cart single_line_item_params
231
+ end
232
+
233
+ end
234
+
235
+ it "ensures updated shipments" do
236
+ expect(subject.order).to receive(:ensure_updated_shipments)
237
+ subject.update_cart params
238
+ end
239
+ end
240
+
241
+ context "completed order" do
242
+ let(:order) { create(:order, state: 'complete', completed_at: Time.now) }
243
+
244
+ before { order.shipments.create! stock_location_id: variant.stock_location_ids.first }
245
+
246
+ it "updates order payment state" do
247
+ expect {
248
+ subject.add variant
249
+ }.to change { order.payment_state }
250
+
251
+ expect {
252
+ subject.remove variant
253
+ }.to change { order.payment_state }
254
+ end
255
+ end
256
+ end