spree_core 3.0.5 → 3.0.6

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 (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