solidus_frontend_devise_token_auth 2.8.0.alpha.2

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 (163) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +42 -0
  4. data/Rakefile +17 -0
  5. data/app/assets/config/solidus_frontend_manifest.js +4 -0
  6. data/app/assets/images/credit_cards/amex_cid.gif +0 -0
  7. data/app/assets/images/credit_cards/credit_card.gif +0 -0
  8. data/app/assets/images/credit_cards/discover_cid.gif +0 -0
  9. data/app/assets/images/credit_cards/icons/american_express.png +0 -0
  10. data/app/assets/images/credit_cards/icons/cirrus.png +0 -0
  11. data/app/assets/images/credit_cards/icons/delta.png +0 -0
  12. data/app/assets/images/credit_cards/icons/diners_club.png +0 -0
  13. data/app/assets/images/credit_cards/icons/directdebit.png +0 -0
  14. data/app/assets/images/credit_cards/icons/discover.png +0 -0
  15. data/app/assets/images/credit_cards/icons/egold.png +0 -0
  16. data/app/assets/images/credit_cards/icons/maestro.png +0 -0
  17. data/app/assets/images/credit_cards/icons/master.png +0 -0
  18. data/app/assets/images/credit_cards/icons/paypal.png +0 -0
  19. data/app/assets/images/credit_cards/icons/solo.png +0 -0
  20. data/app/assets/images/credit_cards/icons/switch.png +0 -0
  21. data/app/assets/images/credit_cards/icons/visa.png +0 -0
  22. data/app/assets/images/credit_cards/icons/visaelectron.png +0 -0
  23. data/app/assets/images/credit_cards/icons/westernunion.png +0 -0
  24. data/app/assets/images/credit_cards/icons/wirecard.png +0 -0
  25. data/app/assets/images/credit_cards/icons/worldpay.png +0 -0
  26. data/app/assets/images/credit_cards/master_cid.jpg +0 -0
  27. data/app/assets/images/credit_cards/visa_cid.gif +0 -0
  28. data/app/assets/images/favicon.ico +0 -0
  29. data/app/assets/images/icons/add-to-cart.png +0 -0
  30. data/app/assets/images/icons/checkout.png +0 -0
  31. data/app/assets/images/icons/delete.png +0 -0
  32. data/app/assets/images/icons/update.png +0 -0
  33. data/app/assets/images/spinner.gif +0 -0
  34. data/app/assets/images/spree/frontend/cart.png +0 -0
  35. data/app/assets/javascripts/spree/frontend/cart.js +30 -0
  36. data/app/assets/javascripts/spree/frontend/checkout/address.js +127 -0
  37. data/app/assets/javascripts/spree/frontend/checkout/coupon-code.js +41 -0
  38. data/app/assets/javascripts/spree/frontend/checkout/payment.js +55 -0
  39. data/app/assets/javascripts/spree/frontend/checkout.js +24 -0
  40. data/app/assets/javascripts/spree/frontend/locale_selector.js +5 -0
  41. data/app/assets/javascripts/spree/frontend/product.js +81 -0
  42. data/app/assets/javascripts/spree/frontend.js +5 -0
  43. data/app/assets/stylesheets/spree/frontend/_skeleton.scss +242 -0
  44. data/app/assets/stylesheets/spree/frontend/_variables.scss +65 -0
  45. data/app/assets/stylesheets/spree/frontend/screen.css.scss +1387 -0
  46. data/app/assets/stylesheets/spree/frontend.css +5 -0
  47. data/app/controllers/spree/checkout_controller.rb +236 -0
  48. data/app/controllers/spree/content_controller.rb +11 -0
  49. data/app/controllers/spree/home_controller.rb +14 -0
  50. data/app/controllers/spree/locale_controller.rb +20 -0
  51. data/app/controllers/spree/orders_controller.rb +138 -0
  52. data/app/controllers/spree/products_controller.rb +52 -0
  53. data/app/controllers/spree/store_controller.rb +30 -0
  54. data/app/controllers/spree/taxons_controller.rb +31 -0
  55. data/app/helpers/spree/orders_helper.rb +18 -0
  56. data/app/helpers/spree/taxon_filters_helper.rb +13 -0
  57. data/app/models/spree/frontend_configuration.rb +10 -0
  58. data/app/views/spree/address/_form.html.erb +96 -0
  59. data/app/views/spree/address/_form_hidden.html.erb +12 -0
  60. data/app/views/spree/checkout/_address.html.erb +33 -0
  61. data/app/views/spree/checkout/_confirm.html.erb +25 -0
  62. data/app/views/spree/checkout/_coupon_code.html.erb +12 -0
  63. data/app/views/spree/checkout/_delivery.html.erb +108 -0
  64. data/app/views/spree/checkout/_payment.html.erb +67 -0
  65. data/app/views/spree/checkout/_summary.html.erb +76 -0
  66. data/app/views/spree/checkout/_terms_and_conditions.en.html.erb +1 -0
  67. data/app/views/spree/checkout/edit.html.erb +32 -0
  68. data/app/views/spree/checkout/existing_payment/_gateway.html.erb +9 -0
  69. data/app/views/spree/checkout/payment/_check.html.erb +0 -0
  70. data/app/views/spree/checkout/payment/_gateway.html.erb +36 -0
  71. data/app/views/spree/content/cvv.html.erb +13 -0
  72. data/app/views/spree/home/index.html.erb +12 -0
  73. data/app/views/spree/layouts/spree_application.html.erb +36 -0
  74. data/app/views/spree/orders/_adjustment_row.html.erb +8 -0
  75. data/app/views/spree/orders/_adjustments.html.erb +24 -0
  76. data/app/views/spree/orders/_form.html.erb +29 -0
  77. data/app/views/spree/orders/_line_item.html.erb +34 -0
  78. data/app/views/spree/orders/edit.html.erb +47 -0
  79. data/app/views/spree/orders/show.html.erb +22 -0
  80. data/app/views/spree/payments/_payment.html.erb +18 -0
  81. data/app/views/spree/products/_cart_form.html.erb +65 -0
  82. data/app/views/spree/products/_image.html.erb +8 -0
  83. data/app/views/spree/products/_promotions.html.erb +19 -0
  84. data/app/views/spree/products/_properties.html.erb +15 -0
  85. data/app/views/spree/products/_taxons.html.erb +14 -0
  86. data/app/views/spree/products/_thumbnails.html.erb +21 -0
  87. data/app/views/spree/products/index.html.erb +27 -0
  88. data/app/views/spree/products/show.html.erb +51 -0
  89. data/app/views/spree/shared/_address.html.erb +38 -0
  90. data/app/views/spree/shared/_filters.html.erb +27 -0
  91. data/app/views/spree/shared/_footer.html.erb +6 -0
  92. data/app/views/spree/shared/_head.html.erb +14 -0
  93. data/app/views/spree/shared/_header.html.erb +5 -0
  94. data/app/views/spree/shared/_image.html.erb +12 -0
  95. data/app/views/spree/shared/_link_to_cart.html.erb +1 -0
  96. data/app/views/spree/shared/_locale_selector.html.erb +25 -0
  97. data/app/views/spree/shared/_login_bar_items.html.erb +1 -0
  98. data/app/views/spree/shared/_main_nav_bar.html.erb +12 -0
  99. data/app/views/spree/shared/_nav_bar.html.erb +9 -0
  100. data/app/views/spree/shared/_order_details.html.erb +146 -0
  101. data/app/views/spree/shared/_products.html.erb +51 -0
  102. data/app/views/spree/shared/_search.html.erb +11 -0
  103. data/app/views/spree/shared/_shipment_tracking.html.erb +9 -0
  104. data/app/views/spree/shared/_sidebar.html.erb +3 -0
  105. data/app/views/spree/shared/_taxonomies.html.erb +9 -0
  106. data/app/views/spree/shared/unauthorized.html.erb +0 -0
  107. data/app/views/spree/store/cart_link.html.erb +1 -0
  108. data/app/views/spree/taxons/_taxon.html.erb +4 -0
  109. data/app/views/spree/taxons/show.html.erb +20 -0
  110. data/config/initializers/assets.rb +3 -0
  111. data/config/initializers/canonical_rails.rb +16 -0
  112. data/config/routes.rb +33 -0
  113. data/lib/generators/solidus/views/override_generator.rb +49 -0
  114. data/lib/solidus_frontend.rb +3 -0
  115. data/lib/spree/frontend/engine.rb +13 -0
  116. data/lib/spree/frontend/middleware/seo_assist.rb +52 -0
  117. data/lib/spree/frontend.rb +15 -0
  118. data/lib/spree_frontend.rb +3 -0
  119. data/lib/tasks/rake_util.rb +18 -0
  120. data/lib/tasks/taxon.rake +16 -0
  121. data/script/rails +10 -0
  122. data/solidus_frontend.gemspec +35 -0
  123. data/spec/controllers/controller_helpers_spec.rb +30 -0
  124. data/spec/controllers/locale_controller_spec.rb +57 -0
  125. data/spec/controllers/spree/checkout_controller_spec.rb +539 -0
  126. data/spec/controllers/spree/checkout_controller_with_views_spec.rb +37 -0
  127. data/spec/controllers/spree/content_controller_spec.rb +9 -0
  128. data/spec/controllers/spree/current_order_tracking_spec.rb +47 -0
  129. data/spec/controllers/spree/home_controller_spec.rb +29 -0
  130. data/spec/controllers/spree/orders_controller_ability_spec.rb +93 -0
  131. data/spec/controllers/spree/orders_controller_spec.rb +225 -0
  132. data/spec/controllers/spree/orders_controller_transitions_spec.rb +33 -0
  133. data/spec/controllers/spree/products_controller_spec.rb +38 -0
  134. data/spec/controllers/spree/taxons_controller_spec.rb +14 -0
  135. data/spec/features/address_spec.rb +78 -0
  136. data/spec/features/automatic_promotion_adjustments_spec.rb +49 -0
  137. data/spec/features/caching/products_spec.rb +48 -0
  138. data/spec/features/caching/taxons_spec.rb +21 -0
  139. data/spec/features/cart_spec.rb +85 -0
  140. data/spec/features/checkout_spec.rb +690 -0
  141. data/spec/features/checkout_unshippable_spec.rb +37 -0
  142. data/spec/features/coupon_code_spec.rb +266 -0
  143. data/spec/features/currency_spec.rb +20 -0
  144. data/spec/features/free_shipping_promotions_spec.rb +60 -0
  145. data/spec/features/locale_spec.rb +27 -0
  146. data/spec/features/order_spec.rb +73 -0
  147. data/spec/features/products_spec.rb +291 -0
  148. data/spec/features/promotion_code_invalidation_spec.rb +54 -0
  149. data/spec/features/quantity_promotions_spec.rb +130 -0
  150. data/spec/features/taxons_spec.rb +158 -0
  151. data/spec/features/template_rendering_spec.rb +20 -0
  152. data/spec/fixtures/thinking-cat.jpg +0 -0
  153. data/spec/generators/solidus/views/override_generator_spec.rb +50 -0
  154. data/spec/helpers/base_helper_spec.rb +13 -0
  155. data/spec/helpers/order_helper_spec.rb +14 -0
  156. data/spec/helpers/taxon_filters_helper_spec.rb +12 -0
  157. data/spec/spec_helper.rb +106 -0
  158. data/spec/support/features/fill_in_with_force.rb +12 -0
  159. data/spec/support/shared_contexts/checkout_setup.rb +12 -0
  160. data/spec/support/shared_contexts/custom_products.rb +28 -0
  161. data/spec/support/shared_contexts/locales.rb +16 -0
  162. data/spec/views/spree/checkout/_summary_spec.rb +11 -0
  163. metadata +337 -0
@@ -0,0 +1,690 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe "Checkout", type: :feature, inaccessible: true do
6
+ include_context 'checkout setup'
7
+
8
+ context "visitor makes checkout as guest without registration" do
9
+ before(:each) do
10
+ stock_location.stock_items.update_all(count_on_hand: 1)
11
+ end
12
+
13
+ context "defaults to use billing address" do
14
+ before do
15
+ add_mug_to_cart
16
+ Spree::Order.last.update_column(:email, "test@example.com")
17
+ click_button "Checkout"
18
+ end
19
+
20
+ it "should default checkbox to checked", inaccessible: true do
21
+ expect(find('input#order_use_billing')).to be_checked
22
+ end
23
+
24
+ it "should remain checked when used and visitor steps back to address step", js: true do
25
+ fill_in_address
26
+ expect(find('input#order_use_billing')).to be_checked
27
+ end
28
+ end
29
+
30
+ # Regression test for https://github.com/spree/spree/issues/4079
31
+ context "persists state when on address page" do
32
+ before do
33
+ add_mug_to_cart
34
+ click_button "Checkout"
35
+ end
36
+
37
+ specify do
38
+ expect(Spree::Order.count).to eq(1)
39
+ expect(Spree::Order.last.state).to eq("address")
40
+ end
41
+ end
42
+
43
+ # Regression test for https://github.com/spree/spree/issues/1596
44
+ context "full checkout" do
45
+ before do
46
+ shipping_method.calculator.update!(preferred_amount: 10)
47
+ mug.shipping_category = shipping_method.shipping_categories.first
48
+ mug.save!
49
+ end
50
+
51
+ it "does not break the per-item shipping method calculator", js: true do
52
+ add_mug_to_cart
53
+ click_button "Checkout"
54
+
55
+ fill_in "order_email", with: "test@example.com"
56
+ fill_in_address
57
+
58
+ click_button "Save and Continue"
59
+ expect(page).not_to have_content("undefined method `promotion'")
60
+ click_button "Save and Continue"
61
+ expect(page).to have_content("Shipping total: $10.00")
62
+ end
63
+ end
64
+
65
+ # Regression test for https://github.com/spree/spree/issues/4306
66
+ context "free shipping" do
67
+ before do
68
+ add_mug_to_cart
69
+ click_button "Checkout"
70
+ end
71
+
72
+ it "should not show 'Free Shipping' when there are no shipments" do
73
+ within("#checkout-summary") do
74
+ expect(page).to_not have_content('Free Shipping')
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ context "displays default user addresses on address step" do
81
+ before do
82
+ stock_location.stock_items.update_all(count_on_hand: 1)
83
+ end
84
+
85
+ context "when user is logged in" do
86
+ let!(:user) do
87
+ create(:user, bill_address: saved_bill_address, ship_address: saved_ship_address)
88
+ end
89
+
90
+ let!(:order) do
91
+ order = Spree::Order.create!(
92
+ email: "spree@example.com",
93
+ store: Spree::Store.first || FactoryBot.create(:store)
94
+ )
95
+
96
+ order.reload
97
+ order.user = user
98
+ order.recalculate
99
+ order
100
+ end
101
+
102
+ before do
103
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
104
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
105
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
106
+
107
+ add_mug_to_cart
108
+ click_button "Checkout"
109
+ # We need an order reload here to get newly associated addresses.
110
+ # Then we go back to address where we are supposed to be redirected.
111
+ order.reload
112
+ visit spree.checkout_state_path(:address)
113
+ end
114
+
115
+ context "when user has default addresses saved" do
116
+ let(:saved_bill_address) { create(:address, firstname: 'Bill') }
117
+ let(:saved_ship_address) { create(:address, firstname: 'Steve') }
118
+
119
+ it "shows the saved addresses" do
120
+ within("#billing") do
121
+ expect(find_field('First Name').value).to eq 'Bill'
122
+ end
123
+
124
+ within("#shipping") do
125
+ expect(find_field('First Name').value).to eq 'Steve'
126
+ end
127
+ end
128
+ end
129
+
130
+ context "when user does not have default addresses saved" do
131
+ let(:saved_bill_address) { nil }
132
+ let(:saved_ship_address) { nil }
133
+
134
+ it 'shows an empty address' do
135
+ within("#billing") do
136
+ expect(find_field('First Name').value).to be_nil
137
+ end
138
+
139
+ within("#shipping") do
140
+ expect(find_field('First Name').value).to be_nil
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ context "when user is not logged in" do
147
+ context "and proceeds with guest checkout" do
148
+ it 'shows empty addresses' do
149
+ add_mug_to_cart
150
+ click_button "Checkout"
151
+
152
+ within("#billing") do
153
+ expect(find_field('First Name').value).to be_nil
154
+ end
155
+
156
+ within("#shipping") do
157
+ expect(find_field('First Name').value).to be_nil
158
+ end
159
+ end
160
+ end
161
+
162
+ context "and proceeds logging in" do
163
+ let!(:user) do
164
+ create(:user, bill_address: saved_bill_address, ship_address: saved_ship_address)
165
+ end
166
+
167
+ before do
168
+ add_mug_to_cart
169
+ click_button "Checkout"
170
+
171
+ # Simulate user login
172
+ Spree::Order.last.associate_user!(user)
173
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
174
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
175
+
176
+ # Simulate redirect back to address after login
177
+ visit spree.checkout_state_path(:address)
178
+ end
179
+
180
+ context "when does not have saved addresses" do
181
+ let(:saved_bill_address) { nil }
182
+ let(:saved_ship_address) { nil }
183
+
184
+ it 'shows empty addresses' do
185
+ within("#billing") do
186
+ expect(find_field('First Name').value).to be_nil
187
+ end
188
+
189
+ within("#shipping") do
190
+ expect(find_field('First Name').value).to be_nil
191
+ end
192
+ end
193
+ end
194
+
195
+ # Regression test for https://github.com/solidusio/solidus/issues/1811
196
+ context "when does have saved addresses" do
197
+ let(:saved_bill_address) { create(:address, firstname: 'Bill') }
198
+ let(:saved_ship_address) { create(:address, firstname: 'Steve') }
199
+
200
+ it 'shows empty addresses' do
201
+ within("#billing") do
202
+ expect(find_field('First Name').value).to eq 'Bill'
203
+ end
204
+
205
+ within("#shipping") do
206
+ expect(find_field('First Name').value).to eq 'Steve'
207
+ end
208
+ end
209
+ end
210
+ end
211
+ end
212
+ end
213
+
214
+ # Regression test for https://github.com/spree/spree/issues/2694 and https://github.com/spree/spree/issues/4117
215
+ context "doesn't allow bad credit card numbers" do
216
+ let!(:payment_method) { create(:credit_card_payment_method) }
217
+ before(:each) do
218
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
219
+
220
+ user = create(:user)
221
+ order.user = user
222
+ order.recalculate
223
+
224
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
225
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
226
+ end
227
+
228
+ it "redirects to payment page", inaccessible: true do
229
+ visit spree.checkout_state_path(:delivery)
230
+ click_button "Save and Continue"
231
+ choose "Credit Card"
232
+ fill_in "Card Number", with: '123'
233
+ fill_in "card_expiry", with: '04 / 20'
234
+ fill_in "Card Code", with: '123'
235
+ click_button "Save and Continue"
236
+ click_button "Place Order"
237
+ expect(page).to have_content("Bogus Gateway: Forced failure")
238
+ expect(page.current_url).to include("/checkout/payment")
239
+ end
240
+ end
241
+
242
+ context "and likes to double click buttons" do
243
+ let!(:user) { create(:user) }
244
+
245
+ let!(:order) do
246
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
247
+
248
+ order.reload
249
+ order.user = user
250
+ order.recalculate
251
+ order
252
+ end
253
+
254
+ before(:each) do
255
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
256
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
257
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(skip_state_validation?: true)
258
+ end
259
+
260
+ it "prevents double clicking the payment button on checkout", js: true do
261
+ visit spree.checkout_state_path(:payment)
262
+
263
+ # prevent form submit to verify button is disabled
264
+ page.execute_script("$('#checkout_form_payment').submit(function(){return false;})")
265
+
266
+ expect(page).not_to have_selector('input.button[disabled]')
267
+ click_button "Save and Continue"
268
+ expect(page).to have_selector('input.button[disabled]')
269
+ end
270
+
271
+ it "prevents double clicking the confirm button on checkout", js: true do
272
+ order.payments << create(:payment)
273
+ visit spree.checkout_state_path(:confirm)
274
+
275
+ # prevent form submit to verify button is disabled
276
+ page.execute_script("$('#checkout_form_confirm').submit(function(){return false;})")
277
+
278
+ expect(page).not_to have_selector('input.button[disabled]')
279
+ click_button "Place Order"
280
+ expect(page).to have_selector('input.button[disabled]')
281
+ end
282
+ end
283
+
284
+ context "when several payment methods are available" do
285
+ let(:credit_cart_payment) { create(:credit_card_payment_method) }
286
+ let(:check_payment) { create(:check_payment_method) }
287
+
288
+ after do
289
+ Capybara.ignore_hidden_elements = true
290
+ end
291
+
292
+ before do
293
+ Capybara.ignore_hidden_elements = false
294
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
295
+ allow(order).to receive_messages(available_payment_methods: [check_payment, credit_cart_payment])
296
+ order.user = create(:user)
297
+ order.recalculate
298
+
299
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
300
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: order.user)
301
+
302
+ visit spree.checkout_state_path(:payment)
303
+ end
304
+
305
+ it "the first payment method should be selected", js: true do
306
+ payment_method_css = "#order_payments_attributes__payment_method_id_"
307
+ expect(find("#{payment_method_css}#{check_payment.id}")).to be_checked
308
+ expect(find("#{payment_method_css}#{credit_cart_payment.id}")).not_to be_checked
309
+ end
310
+
311
+ it "the fields for the other payment methods should be hidden", js: true do
312
+ payment_method_css = "#payment_method_"
313
+ expect(find("#{payment_method_css}#{check_payment.id}")).to be_visible
314
+ expect(find("#{payment_method_css}#{credit_cart_payment.id}")).not_to be_visible
315
+ end
316
+ end
317
+
318
+ context "user has payment sources", js: true do
319
+ before { Spree::PaymentMethod.all.each(&:really_destroy!) }
320
+ let!(:bogus) { create(:credit_card_payment_method) }
321
+ let(:user) { create(:user) }
322
+
323
+ let!(:credit_card) do
324
+ create(:credit_card, user_id: user.id, payment_method: bogus, gateway_customer_profile_id: "BGS-WEFWF")
325
+ end
326
+
327
+ before do
328
+ user.wallet.add(credit_card)
329
+ order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
330
+
331
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
332
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
333
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
334
+
335
+ visit spree.checkout_state_path(:payment)
336
+ end
337
+
338
+ it "selects first source available and customer moves on" do
339
+ expect(find("#use_existing_card_yes")).to be_checked
340
+
341
+ expect {
342
+ click_on "Save and Continue"
343
+ }.not_to change { Spree::CreditCard.count }
344
+
345
+ click_on "Place Order"
346
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
347
+ end
348
+
349
+ it "allows user to enter a new source" do
350
+ choose "use_existing_card_no"
351
+
352
+ fill_in "Name on card", with: 'Spree Commerce'
353
+ fill_in_with_force "Card Number", with: '4111 1111 1111 1111'
354
+ fill_in "card_expiry", with: '04 / 20'
355
+ fill_in "Card Code", with: '123'
356
+
357
+ expect {
358
+ click_on "Save and Continue"
359
+ }.to change { Spree::CreditCard.count }.by 1
360
+
361
+ expect(Spree::CreditCard.last.address).to be_present
362
+
363
+ click_on "Place Order"
364
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
365
+ end
366
+ end
367
+
368
+ # regression for https://github.com/spree/spree/issues/2921
369
+ context "goes back from payment to add another item", js: true do
370
+ let!(:store) { FactoryBot.create(:store) }
371
+ let!(:bag) { create(:product, name: "RoR Bag") }
372
+
373
+ it "transit nicely through checkout steps again" do
374
+ add_mug_to_cart
375
+ click_on "Checkout"
376
+ fill_in "order_email", with: "test@example.com"
377
+ fill_in_address
378
+ click_on "Save and Continue"
379
+ click_on "Save and Continue"
380
+ expect(page).to have_current_path(spree.checkout_state_path("payment"))
381
+
382
+ visit spree.root_path
383
+ click_link bag.name
384
+ click_button "add-to-cart-button"
385
+
386
+ click_on "Checkout"
387
+ # edit an address field
388
+ fill_in "order_bill_address_attributes_firstname", with: "Ryann"
389
+ click_on "Save and Continue"
390
+ click_on "Save and Continue"
391
+ click_on "Save and Continue"
392
+ click_on "Place Order"
393
+
394
+ expect(page).to have_current_path(spree.order_path(Spree::Order.last))
395
+ end
396
+ end
397
+
398
+ context "from payment step customer goes back to cart", js: true do
399
+ before do
400
+ add_mug_to_cart
401
+ click_on "Checkout"
402
+ fill_in "order_email", with: "test@example.com"
403
+ fill_in_address
404
+ click_on "Save and Continue"
405
+ click_on "Save and Continue"
406
+ expect(page).to have_current_path(spree.checkout_state_path("payment"))
407
+ end
408
+
409
+ context "and updates line item quantity and try to reach payment page" do
410
+ before do
411
+ visit spree.cart_path
412
+ within ".cart-item-quantity" do
413
+ fill_in first("input")["name"], with: 3
414
+ end
415
+
416
+ click_on "Update"
417
+ end
418
+
419
+ it "redirects user back to address step" do
420
+ visit spree.checkout_state_path("payment")
421
+ expect(page).to have_current_path(spree.checkout_state_path("address"))
422
+ end
423
+
424
+ it "updates shipments properly through step address -> delivery transitions" do
425
+ visit spree.checkout_state_path("payment")
426
+ click_on "Save and Continue"
427
+ click_on "Save and Continue"
428
+
429
+ expect(Spree::InventoryUnit.count).to eq 3
430
+ end
431
+ end
432
+
433
+ context "and adds new product to cart and try to reach payment page" do
434
+ let!(:bag) { create(:product, name: "RoR Bag") }
435
+
436
+ before do
437
+ visit spree.root_path
438
+ click_link bag.name
439
+ click_button "add-to-cart-button"
440
+ end
441
+
442
+ it "redirects user back to address step" do
443
+ visit spree.checkout_state_path("payment")
444
+ expect(page).to have_current_path(spree.checkout_state_path("address"))
445
+ end
446
+
447
+ it "updates shipments properly through step address -> delivery transitions" do
448
+ visit spree.checkout_state_path("payment")
449
+ click_on "Save and Continue"
450
+ click_on "Save and Continue"
451
+
452
+ expect(Spree::InventoryUnit.count).to eq 2
453
+ end
454
+ end
455
+ end
456
+
457
+ context "Coupon promotions", js: true do
458
+ let!(:promotion) { create(:promotion, name: "Huhuhu", code: "huhu") }
459
+ let!(:calculator) { Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10") }
460
+ let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator) }
461
+
462
+ before do
463
+ promotion.actions << action
464
+
465
+ add_mug_to_cart
466
+ click_on "Checkout"
467
+
468
+ fill_in "order_email", with: "test@example.com"
469
+ fill_in_address
470
+ click_on "Save and Continue"
471
+
472
+ click_on "Save and Continue"
473
+ expect(page).to have_current_path(spree.checkout_state_path("payment"))
474
+ end
475
+
476
+ it "applies them & refreshes the page on user clicking the Apply Code button" do
477
+ fill_in "Coupon Code", with: promotion.codes.first.value
478
+ click_on "Apply Code"
479
+
480
+ expect(page).to have_content(promotion.name)
481
+ expect(page).to have_content("-$2.00")
482
+ end
483
+
484
+ context "with invalid coupon" do
485
+ it "doesnt apply the promotion" do
486
+ fill_in "Coupon Code", with: 'invalid'
487
+ click_on "Apply Code"
488
+
489
+ expect(page).to have_content(I18n.t('spree.coupon_code_not_found'))
490
+ end
491
+ end
492
+
493
+ context "doesn't fill in coupon code input" do
494
+ it "advances just fine" do
495
+ click_on "Save and Continue"
496
+ expect(page).to have_current_path(spree.checkout_state_path("confirm"))
497
+ end
498
+ end
499
+ end
500
+
501
+ context "order has only payment step" do
502
+ before do
503
+ create(:credit_card_payment_method)
504
+ @old_checkout_flow = Spree::Order.checkout_flow
505
+ Spree::Order.class_eval do
506
+ checkout_flow do
507
+ go_to_state :payment
508
+ go_to_state :confirm
509
+ end
510
+ end
511
+
512
+ allow_any_instance_of(Spree::Order).to receive_messages email: "spree@commerce.com"
513
+
514
+ add_mug_to_cart
515
+ click_on "Checkout"
516
+ end
517
+
518
+ after do
519
+ Spree::Order.checkout_flow(&@old_checkout_flow)
520
+ end
521
+
522
+ it "goes right payment step and place order just fine" do
523
+ expect(page).to have_current_path(spree.checkout_state_path('payment'))
524
+
525
+ choose "Credit Card"
526
+ fill_in "Name on card", with: 'Spree Commerce'
527
+ fill_in "Card Number", with: '4111 1111 1111 1111'
528
+ fill_in "card_expiry", with: '04 / 20'
529
+ fill_in "Card Code", with: '123'
530
+ click_button "Save and Continue"
531
+
532
+ expect(current_path).to eq spree.checkout_state_path('confirm')
533
+ click_button "Place Order"
534
+ end
535
+ end
536
+
537
+ context "save my address" do
538
+ before do
539
+ stock_location.stock_items.update_all(count_on_hand: 1)
540
+ add_mug_to_cart
541
+ end
542
+
543
+ context 'as a guest' do
544
+ before do
545
+ Spree::Order.last.update_column(:email, "test@example.com")
546
+ click_button "Checkout"
547
+ end
548
+
549
+ it 'should not be displayed' do
550
+ expect(page).to_not have_css("[data-hook=save_user_address]")
551
+ end
552
+ end
553
+
554
+ context 'as a User' do
555
+ before do
556
+ user = create(:user)
557
+ Spree::Order.last.update_column :user_id, user.id
558
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
559
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
560
+ click_button "Checkout"
561
+ end
562
+
563
+ it 'should be displayed' do
564
+ expect(page).to have_css("[data-hook=save_user_address]")
565
+ end
566
+ end
567
+ end
568
+
569
+ context "when order is completed" do
570
+ let!(:user) { create(:user) }
571
+ let!(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:delivery) }
572
+
573
+ before(:each) do
574
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
575
+ allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
576
+ allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
577
+
578
+ visit spree.checkout_state_path(:delivery)
579
+ click_button "Save and Continue"
580
+ click_button "Save and Continue"
581
+ click_button "Place Order"
582
+ end
583
+
584
+ it "displays a thank you message" do
585
+ expect(page).to have_content(I18n.t('spree.thank_you_for_your_order'))
586
+ end
587
+
588
+ it "does not display a thank you message on that order future visits" do
589
+ visit spree.order_path(order)
590
+ expect(page).to_not have_content(I18n.t('spree.thank_you_for_your_order'))
591
+ end
592
+ end
593
+
594
+ context "with attempted XSS", js: true do
595
+ shared_examples "safe from XSS" do
596
+ # We need a country with states required but no states so that we have
597
+ # access to the state_name input
598
+ let!(:canada) { create(:country, name: 'Canada', iso: "CA", states_required: true) }
599
+ before do
600
+ canada.states.destroy_all
601
+ zone.members.create!(zoneable: canada)
602
+ end
603
+
604
+ it "displays the entered state name without evaluating" do
605
+ add_mug_to_cart
606
+ visit spree.checkout_state_path(:address)
607
+ fill_in_address
608
+
609
+ state_name_css = "order_bill_address_attributes_state_name"
610
+
611
+ select "Canada", from: "order_bill_address_attributes_country_id"
612
+ fill_in 'Customer E-Mail', with: 'test@example.com'
613
+ fill_in state_name_css, with: xss_string
614
+ fill_in "Zip", with: "H0H0H0"
615
+
616
+ click_on 'Save and Continue'
617
+ visit spree.checkout_state_path(:address)
618
+
619
+ expect(page).to have_field(state_name_css, with: xss_string)
620
+ end
621
+ end
622
+
623
+ let(:xss_string) { %(<script>throw("XSS")</script>) }
624
+ include_examples "safe from XSS"
625
+
626
+ context "escaped XSS string" do
627
+ let(:xss_string) { '\x27\x3e\x3cscript\x3ethrow(\x27XSS\x27)\x3c/script\x3e' }
628
+ include_examples "safe from XSS"
629
+ end
630
+ end
631
+
632
+ context "using credit card" do
633
+ let!(:payment_method) { create(:credit_card_payment_method) }
634
+
635
+ # Regression test for https://github.com/solidusio/solidus/issues/1421
636
+ it "works with card number 1", js: true do
637
+ add_mug_to_cart
638
+
639
+ click_on "Checkout"
640
+ fill_in "order_email", with: "test@example.com"
641
+ fill_in_address
642
+ click_on "Save and Continue"
643
+ click_on "Save and Continue"
644
+
645
+ fill_in_credit_card(number: "1")
646
+ click_on "Save and Continue"
647
+
648
+ expect(page).to have_current_path("/checkout/confirm")
649
+ end
650
+
651
+ it "works with card number 4111111111111111", js: true do
652
+ add_mug_to_cart
653
+
654
+ click_on "Checkout"
655
+ fill_in "order_email", with: "test@example.com"
656
+ fill_in_address
657
+ click_on "Save and Continue"
658
+ click_on "Save and Continue"
659
+
660
+ fill_in_credit_card(number: "4111 1111 1111 1111")
661
+ click_on "Save and Continue"
662
+
663
+ expect(page).to have_current_path("/checkout/confirm")
664
+ end
665
+ end
666
+
667
+ def fill_in_credit_card(number:)
668
+ fill_in "Card Number", with: number
669
+ fill_in "Expiration", with: "12 / 24"
670
+ fill_in "Card Code", with: "123"
671
+ end
672
+
673
+ def fill_in_address
674
+ address = "order_bill_address_attributes"
675
+ fill_in "#{address}_firstname", with: "Ryan"
676
+ fill_in "#{address}_lastname", with: "Bigg"
677
+ fill_in "#{address}_address1", with: "143 Swan Street"
678
+ fill_in "#{address}_city", with: "Richmond"
679
+ select "United States of America", from: "#{address}_country_id"
680
+ select "Alabama", from: "#{address}_state_id"
681
+ fill_in "#{address}_zipcode", with: "12345"
682
+ fill_in "#{address}_phone", with: "(555) 555-5555"
683
+ end
684
+
685
+ def add_mug_to_cart
686
+ visit spree.root_path
687
+ click_link mug.name
688
+ click_button "add-to-cart-button"
689
+ end
690
+ end