solidus_frontend 2.9.6 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of solidus_frontend might be problematic. Click here for more details.

Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spree/frontend/checkout/address.js +1 -1
  3. data/app/assets/javascripts/spree/frontend/checkout/coupon-code.js +1 -1
  4. data/app/assets/stylesheets/spree/frontend/screen.css.scss +3 -3
  5. data/app/controllers/spree/checkout_controller.rb +13 -5
  6. data/app/controllers/spree/orders_controller.rb +13 -9
  7. data/app/controllers/spree/products_controller.rb +1 -1
  8. data/app/views/spree/address/_form.html.erb +15 -8
  9. data/app/views/spree/address/_form_hidden.html.erb +6 -2
  10. data/app/views/spree/checkout/payment/_gateway.html.erb +1 -1
  11. data/app/views/spree/orders/_form.html.erb +1 -1
  12. data/app/views/spree/shared/_address.html.erb +1 -1
  13. data/app/views/spree/shared/_image.html.erb +3 -2
  14. data/lib/generators/solidus/views/override_generator.rb +3 -2
  15. data/lib/spree/frontend/config.rb +9 -0
  16. data/lib/spree/frontend/engine.rb +5 -3
  17. data/lib/spree/frontend/middleware/seo_assist.rb +4 -4
  18. data/{app/models → lib}/spree/frontend_configuration.rb +1 -1
  19. data/solidus_frontend.gemspec +6 -5
  20. metadata +28 -56
  21. data/script/rails +0 -10
  22. data/spec/controllers/controller_helpers_spec.rb +0 -29
  23. data/spec/controllers/locale_controller_spec.rb +0 -57
  24. data/spec/controllers/spree/checkout_controller_spec.rb +0 -610
  25. data/spec/controllers/spree/checkout_controller_with_views_spec.rb +0 -37
  26. data/spec/controllers/spree/content_controller_spec.rb +0 -9
  27. data/spec/controllers/spree/current_order_tracking_spec.rb +0 -47
  28. data/spec/controllers/spree/home_controller_spec.rb +0 -29
  29. data/spec/controllers/spree/orders_controller_ability_spec.rb +0 -90
  30. data/spec/controllers/spree/orders_controller_spec.rb +0 -229
  31. data/spec/controllers/spree/orders_controller_transitions_spec.rb +0 -33
  32. data/spec/controllers/spree/products_controller_spec.rb +0 -38
  33. data/spec/controllers/spree/taxons_controller_spec.rb +0 -14
  34. data/spec/features/address_spec.rb +0 -78
  35. data/spec/features/automatic_promotion_adjustments_spec.rb +0 -49
  36. data/spec/features/caching/products_spec.rb +0 -48
  37. data/spec/features/caching/taxons_spec.rb +0 -21
  38. data/spec/features/cart_spec.rb +0 -85
  39. data/spec/features/checkout_confirm_insufficient_stock_spec.rb +0 -71
  40. data/spec/features/checkout_spec.rb +0 -707
  41. data/spec/features/checkout_unshippable_spec.rb +0 -37
  42. data/spec/features/coupon_code_spec.rb +0 -266
  43. data/spec/features/currency_spec.rb +0 -20
  44. data/spec/features/first_order_promotion_spec.rb +0 -59
  45. data/spec/features/free_shipping_promotions_spec.rb +0 -60
  46. data/spec/features/locale_spec.rb +0 -26
  47. data/spec/features/order_spec.rb +0 -73
  48. data/spec/features/products_spec.rb +0 -291
  49. data/spec/features/promotion_code_invalidation_spec.rb +0 -54
  50. data/spec/features/quantity_promotions_spec.rb +0 -130
  51. data/spec/features/taxons_spec.rb +0 -158
  52. data/spec/features/template_rendering_spec.rb +0 -20
  53. data/spec/fixtures/thinking-cat.jpg +0 -0
  54. data/spec/generators/solidus/views/override_generator_spec.rb +0 -50
  55. data/spec/helpers/base_helper_spec.rb +0 -13
  56. data/spec/helpers/order_helper_spec.rb +0 -14
  57. data/spec/helpers/taxon_filters_helper_spec.rb +0 -12
  58. data/spec/spec_helper.rb +0 -106
  59. data/spec/support/shared_contexts/checkout_setup.rb +0 -12
  60. data/spec/support/shared_contexts/custom_products.rb +0 -28
  61. data/spec/support/shared_contexts/locales.rb +0 -16
  62. data/spec/views/spree/checkout/_summary_spec.rb +0 -11
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Spree::ProductsController, type: :controller do
6
- let!(:product) { create(:product, available_on: 1.year.from_now) }
7
-
8
- # Regression test for https://github.com/spree/spree/issues/1390
9
- it "allows admins to view non-active products" do
10
- allow(controller).to receive_messages try_spree_current_user: mock_model(Spree.user_class, has_spree_role?: true, last_incomplete_spree_order: nil, spree_api_key: 'fake')
11
- get :show, params: { id: product.to_param }
12
- expect(response.status).to eq(200)
13
- end
14
-
15
- it "cannot view non-active products" do
16
- expect {
17
- get :show, params: { id: product.to_param }
18
- }.to raise_error(ActiveRecord::RecordNotFound)
19
- end
20
-
21
- it "should provide the current user to the searcher class" do
22
- user = mock_model(Spree.user_class, last_incomplete_spree_order: nil, spree_api_key: 'fake')
23
- allow(controller).to receive_messages try_spree_current_user: user
24
- expect_any_instance_of(Spree::Config.searcher_class).to receive(:current_user=).with(user)
25
- get :index
26
- expect(response.status).to eq(200)
27
- end
28
-
29
- # Regression test for https://github.com/spree/spree/issues/2249
30
- it "doesn't error when given an invalid referer" do
31
- current_user = mock_model(Spree.user_class, has_spree_role?: true, last_incomplete_spree_order: nil, generate_spree_api_key!: nil)
32
- allow(controller).to receive_messages try_spree_current_user: current_user
33
- request.env['HTTP_REFERER'] = "not|a$url"
34
-
35
- # Previously a URI::InvalidURIError exception was being thrown
36
- get :show, params: { id: product.to_param }
37
- end
38
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Spree::TaxonsController, type: :controller do
6
- it "should provide the current user to the searcher class" do
7
- taxon = create(:taxon, permalink: "test")
8
- user = mock_model(Spree.user_class, last_incomplete_spree_order: nil, spree_api_key: 'fake')
9
- allow(controller).to receive_messages try_spree_current_user: user
10
- expect_any_instance_of(Spree::Config.searcher_class).to receive(:current_user=).with(user)
11
- get :show, params: { id: taxon.permalink }
12
- expect(response.status).to eq(200)
13
- end
14
- end
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe "Address", type: :feature, inaccessible: true do
6
- let!(:product) { create(:product, name: "RoR Mug") }
7
- let!(:order) { create(:order_with_totals, state: 'cart') }
8
-
9
- stub_authorization!
10
-
11
- before do
12
- visit spree.root_path
13
-
14
- click_link "RoR Mug"
15
- click_button "add-to-cart-button"
16
-
17
- address = "order_bill_address_attributes"
18
- @country_css = "#{address}_country_id"
19
- @state_select_css = "##{address}_state_id"
20
- @state_name_css = "##{address}_state_name"
21
- end
22
-
23
- context "country requires state", js: true, focus: true do
24
- let!(:canada) { create(:country, name: "Canada", states_required: true, iso: "CA") }
25
- let!(:uk) { create(:country, name: "United Kingdom", states_required: true, iso: "GB") }
26
-
27
- before { stub_spree_preferences(default_country_iso: uk.iso) }
28
-
29
- context "but has no state" do
30
- it "shows the state input field" do
31
- click_button "Checkout"
32
-
33
- select canada.name, from: @country_css
34
- expect(page).to have_no_css(@state_select_css)
35
- expect(page).to have_css("#{@state_name_css}.required")
36
- end
37
- end
38
-
39
- context "and has state" do
40
- before { create(:state, name: "Ontario", country: canada) }
41
-
42
- it "shows the state collection selection" do
43
- click_button "Checkout"
44
-
45
- select canada.name, from: @country_css
46
- expect(page).to have_no_css(@state_name_css)
47
- expect(page).to have_css("#{@state_select_css}.required")
48
- end
49
- end
50
-
51
- context "user changes to country without states required" do
52
- let!(:france) { create(:country, name: "France", states_required: false, iso: "FR") }
53
-
54
- it "clears the state name" do
55
- click_button "Checkout"
56
- select canada.name, from: @country_css
57
- page.find(@state_name_css).set("Toscana")
58
-
59
- select france.name, from: @country_css
60
-
61
- expect(page).to have_no_css(@state_name_css)
62
- expect(page).to have_no_css(@state_select_css)
63
- end
64
- end
65
- end
66
-
67
- context "country does not require state", js: true do
68
- let!(:france) { create(:country, name: "France", states_required: false, iso: "FR") }
69
-
70
- it "shows a disabled state input field" do
71
- click_button "Checkout"
72
-
73
- select france.name, from: @country_css
74
- expect(page).to have_no_css(@state_name_css)
75
- expect(page).to have_css("#{@state_select_css}[disabled]", visible: false)
76
- end
77
- end
78
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe "Automatic promotions", type: :feature, js: true do
6
- let!(:store) { create(:store) }
7
- let!(:country) { create(:country, name: "United States of America", states_required: true) }
8
- let!(:state) { create(:state, name: "Alabama", country: country) }
9
- let!(:zone) { create(:zone) }
10
- let!(:shipping_method) { create(:shipping_method) }
11
- let!(:payment_method) { create(:check_payment_method) }
12
- let!(:product) { create(:product, name: "RoR Mug", price: 20) }
13
-
14
- let!(:promotion) do
15
- promotion = Spree::Promotion.create!(name: "$10 off when you spend more than $100", apply_automatically: true)
16
-
17
- calculator = Spree::Calculator::FlatRate.new
18
- calculator.preferred_amount = 10
19
-
20
- rule = Spree::Promotion::Rules::ItemTotal.create
21
- rule.preferred_amount = 100
22
- rule.save
23
-
24
- promotion.rules << rule
25
-
26
- action = Spree::Promotion::Actions::CreateAdjustment.create
27
- action.calculator = calculator
28
- action.save
29
-
30
- promotion.actions << action
31
- end
32
-
33
- context "on the cart page" do
34
- before do
35
- visit spree.root_path
36
- click_link product.name
37
- click_button "add-to-cart-button"
38
- end
39
-
40
- it "automatically applies the promotion once the order crosses the threshold" do
41
- fill_in "order_line_items_attributes_0_quantity", with: 10
42
- click_button "Update"
43
- expect(page).to have_content("Promotion ($10 off when you spend more than $100) -$10.00", normalize_ws: true)
44
- fill_in "order_line_items_attributes_0_quantity", with: 1
45
- click_button "Update"
46
- expect(page).not_to have_content("Promotion ($10 off when you spend more than $100) -$10.00", normalize_ws: true)
47
- end
48
- end
49
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe 'products', type: :feature, caching: true do
6
- let!(:product) { create(:product) }
7
- let!(:product2) { create(:product) }
8
- let!(:taxonomy) { create(:taxonomy) }
9
- let!(:taxon) { create(:taxon, taxonomy: taxonomy) }
10
-
11
- before do
12
- product2.update_column(:updated_at, 1.day.ago)
13
- # warm up the cache
14
- visit spree.root_path
15
-
16
- clear_cache_events
17
- end
18
-
19
- it "reads from cache upon a second viewing" do
20
- visit spree.root_path
21
- expect(cache_writes.count).to eq(0)
22
- end
23
-
24
- it "busts the cache when a product is updated" do
25
- product.update_column(:updated_at, 1.day.from_now)
26
- visit spree.root_path
27
- expect(cache_writes.count).to eq(2)
28
- end
29
-
30
- it "busts the cache when all products are soft-deleted" do
31
- product.discard
32
- product2.discard
33
- visit spree.root_path
34
- expect(cache_writes.count).to eq(1)
35
- end
36
-
37
- it "busts the cache when the newest product is soft-deleted" do
38
- product.discard
39
- visit spree.root_path
40
- expect(cache_writes.count).to eq(1)
41
- end
42
-
43
- it "busts the cache when an older product is soft-deleted" do
44
- product2.discard
45
- visit spree.root_path
46
- expect(cache_writes.count).to eq(1)
47
- end
48
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe 'taxons', type: :feature, caching: true do
6
- let!(:taxonomy) { create(:taxonomy) }
7
- let!(:taxon) { create(:taxon, taxonomy: taxonomy) }
8
-
9
- before do
10
- # warm up the cache
11
- visit spree.root_path
12
-
13
- clear_cache_events
14
- end
15
-
16
- it "busts the cache when max_level_in_taxons_menu conf changes" do
17
- stub_spree_preferences(max_level_in_taxons_menu: 5)
18
- visit spree.root_path
19
- expect(cache_writes.count).to eq(1)
20
- end
21
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe "Cart", type: :feature, inaccessible: true do
6
- before { create(:store) }
7
-
8
- it "shows cart icon on non-cart pages" do
9
- visit spree.root_path
10
- expect(page).to have_selector("li#link-to-cart a", visible: true)
11
- end
12
-
13
- it "prevents double clicking the remove button on cart", js: true do
14
- @product = create(:product, name: "RoR Mug")
15
-
16
- visit spree.root_path
17
- click_link "RoR Mug"
18
- click_button "add-to-cart-button"
19
-
20
- # prevent form submit to verify button is disabled
21
- page.execute_script("$('#update-cart').submit(function(){return false;})")
22
-
23
- expect(page).not_to have_selector('button#update-button[disabled]')
24
- page.find(:css, '.delete img').click
25
- expect(page).to have_selector('button#update-button[disabled]')
26
- end
27
-
28
- # Regression test for https://github.com/spree/spree/issues/2006
29
- it "does not error out with a 404 when GET'ing to /orders/populate" do
30
- visit '/orders/populate'
31
- within(".error") do
32
- expect(page).to have_content(I18n.t('spree.populate_get_error'))
33
- end
34
- end
35
-
36
- it 'allows you to remove an item from the cart', js: true do
37
- create(:product, name: "RoR Mug")
38
- visit spree.root_path
39
- click_link "RoR Mug"
40
- click_button "add-to-cart-button"
41
- find('.cart-item-delete .delete').click
42
- expect(page).not_to have_content("Line items quantity must be an integer")
43
- expect(page).not_to have_content("RoR Mug")
44
- expect(page).to have_content("Your cart is empty")
45
-
46
- within "#link-to-cart" do
47
- expect(page).to have_content("EMPTY")
48
- end
49
- end
50
-
51
- it 'allows you to empty the cart', js: true do
52
- create(:product, name: "RoR Mug")
53
- visit spree.root_path
54
- click_link "RoR Mug"
55
- click_button "add-to-cart-button"
56
-
57
- expect(page).to have_content("RoR Mug")
58
- click_on "Empty Cart"
59
- expect(page).to have_content("Your cart is empty")
60
-
61
- within "#link-to-cart" do
62
- expect(page).to have_content("EMPTY")
63
- end
64
- end
65
-
66
- # regression for https://github.com/spree/spree/issues/2276
67
- context "product contains variants but no option values" do
68
- let(:variant) { create(:variant) }
69
- let(:product) { variant.product }
70
-
71
- before { variant.option_values.destroy_all }
72
-
73
- it "still adds product to cart", inaccessible: true do
74
- visit spree.product_path(product)
75
- click_button "add-to-cart-button"
76
-
77
- visit spree.cart_path
78
- expect(page).to have_content(product.name)
79
- end
80
- end
81
- it "should have a surrounding element with data-hook='cart_container'" do
82
- visit spree.cart_path
83
- expect(page).to have_selector("div[data-hook='cart_container']")
84
- end
85
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe "Checkout confirm page submission", type: :feature do
6
- include_context 'checkout setup'
7
-
8
- context "when the product from the order is not backorderable but has enough stock quantity" do
9
- let(:user) { create(:user) }
10
-
11
- let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:payment) }
12
- let(:order_product) { order.products.first }
13
- let(:order_stock_item) { order_product.stock_items.first }
14
-
15
- before do
16
- order_stock_item.update! backorderable: false
17
- order_stock_item.set_count_on_hand(1)
18
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
19
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
20
- allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
21
- end
22
-
23
- context 'when there are not other backorderable stock locations' do
24
- context 'when the customer is on the confirm page and the availabilty drops to zero' do
25
- before do
26
- visit spree.checkout_state_path(:confirm)
27
- order_stock_item.set_count_on_hand(0)
28
- end
29
-
30
- it 'redirects to cart page and shows an unavailable product message' do
31
- click_button "Place Order"
32
- expect(page).to have_content "#{order_product.name} became unavailable"
33
- expect(page).to have_current_path spree.cart_path
34
- end
35
- end
36
- end
37
-
38
- context 'when there is another backorderable stock location' do
39
- before do
40
- create :stock_location, backorderable_default: true, default: false
41
- end
42
-
43
- context 'when the customer is on the confirm page and the availabilty drops to zero' do
44
- before do
45
- visit spree.checkout_state_path(:confirm)
46
- order_stock_item.set_count_on_hand(0)
47
- end
48
-
49
- it "redirects to the address checkout page and shows an availability changed message" do
50
- click_button "Place Order"
51
- error_message = "Quantity selected of #{order_product.name} is not available. Still, items may be available from another stock location, please try again."
52
- expect(page).to have_content error_message
53
- expect(page).to have_current_path spree.checkout_state_path(:address)
54
- end
55
-
56
- it "can still complete the order using the backorderable stock location by restarting the checkout" do
57
- click_button "Place Order"
58
- expect(page).to have_current_path spree.checkout_state_path(:address)
59
- click_button "Save and Continue"
60
- expect(page).to have_current_path spree.checkout_state_path(:delivery)
61
- click_button "Save and Continue"
62
- expect(page).to have_current_path spree.checkout_state_path(:payment)
63
- click_button "Save and Continue"
64
- expect(page).to have_current_path spree.checkout_state_path(:confirm)
65
- click_button "Place Order"
66
- expect(page).to have_content 'Your order has been processed successfully'
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,707 +0,0 @@
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
- context "when order has only a void payment" do
215
- let(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:payment) }
216
-
217
- before do
218
- user = create(:user)
219
- order.user = user
220
- order.recalculate
221
-
222
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
223
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
224
- end
225
-
226
- it "does not allow successful order submission" do
227
- visit spree.checkout_path
228
- order.payments.first.update state: :void
229
- click_button 'Place Order'
230
- expect(page).to have_current_path spree.checkout_state_path(:payment)
231
- end
232
- end
233
-
234
- # Regression test for https://github.com/spree/spree/issues/2694 and https://github.com/spree/spree/issues/4117
235
- context "doesn't allow bad credit card numbers" do
236
- let!(:payment_method) { create(:credit_card_payment_method) }
237
- before(:each) do
238
- order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
239
-
240
- user = create(:user)
241
- order.user = user
242
- order.recalculate
243
-
244
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
245
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
246
- end
247
-
248
- it "redirects to payment page", inaccessible: true do
249
- visit spree.checkout_state_path(:delivery)
250
- click_button "Save and Continue"
251
- choose "Credit Card"
252
- fill_in "Card Number", with: '123'
253
- fill_in "card_expiry", with: '04 / 20'
254
- fill_in "Card Code", with: '123'
255
- click_button "Save and Continue"
256
- click_button "Place Order"
257
- expect(page).to have_content("Bogus Gateway: Forced failure")
258
- expect(page.current_url).to include("/checkout/payment")
259
- end
260
- end
261
-
262
- context "and likes to double click buttons" do
263
- let!(:user) { create(:user) }
264
-
265
- let!(:order) do
266
- order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
267
-
268
- order.reload
269
- order.user = user
270
- order.recalculate
271
- order
272
- end
273
-
274
- before(:each) do
275
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
276
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
277
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(skip_state_validation?: true)
278
- end
279
-
280
- it "prevents double clicking the payment button on checkout", js: true do
281
- visit spree.checkout_state_path(:payment)
282
-
283
- # prevent form submit to verify button is disabled
284
- page.execute_script("$('#checkout_form_payment').submit(function(){return false;})")
285
-
286
- expect(page).not_to have_selector('input.button[disabled]')
287
- click_button "Save and Continue"
288
- expect(page).to have_selector('input.button[disabled]')
289
- end
290
-
291
- it "prevents double clicking the confirm button on checkout", js: true do
292
- order.payments << create(:payment)
293
- visit spree.checkout_state_path(:confirm)
294
-
295
- # prevent form submit to verify button is disabled
296
- page.execute_script("$('#checkout_form_confirm').submit(function(){return false;})")
297
-
298
- expect(page).not_to have_selector('input.button[disabled]')
299
- click_button "Place Order"
300
- expect(page).to have_selector('input.button[disabled]')
301
- end
302
- end
303
-
304
- context "when several payment methods are available" do
305
- let(:credit_cart_payment) { create(:credit_card_payment_method) }
306
- let(:check_payment) { create(:check_payment_method) }
307
-
308
- after do
309
- Capybara.ignore_hidden_elements = true
310
- end
311
-
312
- before do
313
- Capybara.ignore_hidden_elements = false
314
- order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
315
- allow(order).to receive_messages(available_payment_methods: [check_payment, credit_cart_payment])
316
- order.user = create(:user)
317
- order.recalculate
318
-
319
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
320
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: order.user)
321
-
322
- visit spree.checkout_state_path(:payment)
323
- end
324
-
325
- it "the first payment method should be selected", js: true do
326
- payment_method_css = "#order_payments_attributes__payment_method_id_"
327
- expect(find("#{payment_method_css}#{check_payment.id}")).to be_checked
328
- expect(find("#{payment_method_css}#{credit_cart_payment.id}")).not_to be_checked
329
- end
330
-
331
- it "the fields for the other payment methods should be hidden", js: true do
332
- payment_method_css = "#payment_method_"
333
- expect(find("#{payment_method_css}#{check_payment.id}")).to be_visible
334
- expect(find("#{payment_method_css}#{credit_cart_payment.id}")).not_to be_visible
335
- end
336
- end
337
-
338
- context "user has payment sources", js: true do
339
- before { Spree::PaymentMethod.all.each(&:really_destroy!) }
340
- let!(:bogus) { create(:credit_card_payment_method) }
341
- let(:user) { create(:user) }
342
-
343
- let!(:credit_card) do
344
- create(:credit_card, user_id: user.id, payment_method: bogus, gateway_customer_profile_id: "BGS-WEFWF")
345
- end
346
-
347
- before do
348
- user.wallet.add(credit_card)
349
- order = Spree::TestingSupport::OrderWalkthrough.up_to(:delivery)
350
-
351
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
352
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
353
- allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
354
-
355
- visit spree.checkout_state_path(:payment)
356
- end
357
-
358
- it "selects first source available and customer moves on" do
359
- expect(find("#use_existing_card_yes")).to be_checked
360
-
361
- click_on "Save and Continue"
362
- click_on "Place Order"
363
- expect(page).to have_current_path(spree.order_path(Spree::Order.last))
364
- expect(page).to have_current_path(spree.order_path(Spree::Order.last))
365
- expect(page).to have_content("Ending in #{credit_card.last_digits}")
366
- end
367
-
368
- it "allows user to enter a new source" do
369
- choose "use_existing_card_no"
370
- fill_in_credit_card
371
-
372
- click_on "Save and Continue"
373
- click_on "Place Order"
374
- expect(page).to have_current_path(spree.order_path(Spree::Order.last))
375
- expect(page).to have_content('Ending in 1111')
376
- end
377
-
378
- it "allows user to save a billing address associated to the credit card" do
379
- choose "use_existing_card_no"
380
- fill_in_credit_card
381
-
382
- click_on "Save and Continue"
383
- expect(Spree::CreditCard.last.address).to be_present
384
- end
385
- end
386
-
387
- # regression for https://github.com/spree/spree/issues/2921
388
- context "goes back from payment to add another item", js: true do
389
- let!(:store) { FactoryBot.create(:store) }
390
- let!(:bag) { create(:product, name: "RoR Bag") }
391
-
392
- it "transit nicely through checkout steps again" do
393
- add_mug_to_cart
394
- click_on "Checkout"
395
- fill_in "order_email", with: "test@example.com"
396
- fill_in_address
397
- click_on "Save and Continue"
398
- click_on "Save and Continue"
399
- expect(page).to have_current_path(spree.checkout_state_path("payment"))
400
-
401
- visit spree.root_path
402
- click_link bag.name
403
- click_button "add-to-cart-button"
404
-
405
- click_on "Checkout"
406
- # edit an address field
407
- fill_in "order_bill_address_attributes_firstname", with: "Ryann"
408
- click_on "Save and Continue"
409
- click_on "Save and Continue"
410
- click_on "Save and Continue"
411
- click_on "Place Order"
412
-
413
- expect(page).to have_current_path(spree.order_path(Spree::Order.last))
414
- end
415
- end
416
-
417
- context "from payment step customer goes back to cart", js: true do
418
- before do
419
- add_mug_to_cart
420
- click_on "Checkout"
421
- fill_in "order_email", with: "test@example.com"
422
- fill_in_address
423
- click_on "Save and Continue"
424
- click_on "Save and Continue"
425
- expect(page).to have_current_path(spree.checkout_state_path("payment"))
426
- end
427
-
428
- context "and updates line item quantity and try to reach payment page" do
429
- before do
430
- visit spree.cart_path
431
- within ".cart-item-quantity" do
432
- fill_in first("input")["name"], with: 3
433
- end
434
-
435
- click_on "Update"
436
- end
437
-
438
- it "redirects user back to address step" do
439
- visit spree.checkout_state_path("payment")
440
- expect(page).to have_current_path(spree.checkout_state_path("address"))
441
- end
442
-
443
- it "updates shipments properly through step address -> delivery transitions" do
444
- visit spree.checkout_state_path("payment")
445
- click_on "Save and Continue"
446
- click_on "Save and Continue"
447
-
448
- expect(Spree::InventoryUnit.count).to eq 3
449
- end
450
- end
451
-
452
- context "and adds new product to cart and try to reach payment page" do
453
- let!(:bag) { create(:product, name: "RoR Bag") }
454
-
455
- before do
456
- visit spree.root_path
457
- click_link bag.name
458
- click_button "add-to-cart-button"
459
- end
460
-
461
- it "redirects user back to address step" do
462
- visit spree.checkout_state_path("payment")
463
- expect(page).to have_current_path(spree.checkout_state_path("address"))
464
- end
465
-
466
- it "updates shipments properly through step address -> delivery transitions" do
467
- visit spree.checkout_state_path("payment")
468
- click_on "Save and Continue"
469
- click_on "Save and Continue"
470
-
471
- expect(Spree::InventoryUnit.count).to eq 2
472
- end
473
- end
474
- end
475
-
476
- context "Coupon promotions", js: true do
477
- let!(:promotion) { create(:promotion, name: "Huhuhu", code: "huhu") }
478
- let!(:calculator) { Spree::Calculator::FlatPercentItemTotal.create(preferred_flat_percent: "10") }
479
- let!(:action) { Spree::Promotion::Actions::CreateItemAdjustments.create(calculator: calculator) }
480
-
481
- before do
482
- promotion.actions << action
483
-
484
- add_mug_to_cart
485
- click_on "Checkout"
486
-
487
- fill_in "order_email", with: "test@example.com"
488
- fill_in_address
489
- click_on "Save and Continue"
490
-
491
- click_on "Save and Continue"
492
- expect(page).to have_current_path(spree.checkout_state_path("payment"))
493
- end
494
-
495
- it "applies them & refreshes the page on user clicking the Apply Code button" do
496
- fill_in "Coupon Code", with: promotion.codes.first.value
497
- click_on "Apply Code"
498
-
499
- expect(page).to have_content(promotion.name)
500
- expect(page).to have_content("-$2.00")
501
- end
502
-
503
- context "with invalid coupon" do
504
- it "doesnt apply the promotion" do
505
- fill_in "Coupon Code", with: 'invalid'
506
- click_on "Apply Code"
507
-
508
- expect(page).to have_content(I18n.t('spree.coupon_code_not_found'))
509
- end
510
- end
511
-
512
- context "doesn't fill in coupon code input" do
513
- it "advances just fine" do
514
- click_on "Save and Continue"
515
- expect(page).to have_current_path(spree.checkout_state_path("confirm"))
516
- end
517
- end
518
- end
519
-
520
- context "order has only payment step", js: true do
521
- before do
522
- create(:credit_card_payment_method)
523
- @old_checkout_flow = Spree::Order.checkout_flow
524
- Spree::Order.class_eval do
525
- checkout_flow do
526
- go_to_state :payment
527
- go_to_state :confirm
528
- end
529
- end
530
-
531
- allow_any_instance_of(Spree::Order).to receive_messages email: "spree@commerce.com"
532
-
533
- add_mug_to_cart
534
- click_on "Checkout"
535
- end
536
-
537
- after do
538
- Spree::Order.checkout_flow(&@old_checkout_flow)
539
- end
540
-
541
- it "goes right payment step and place order just fine" do
542
- expect(page).to have_current_path(spree.checkout_state_path('payment'))
543
-
544
- choose "Credit Card"
545
- fill_in_credit_card
546
- click_button "Save and Continue"
547
-
548
- expect(current_path).to eq spree.checkout_state_path('confirm')
549
- click_button "Place Order"
550
- end
551
- end
552
-
553
- context "save my address" do
554
- before do
555
- stock_location.stock_items.update_all(count_on_hand: 1)
556
- add_mug_to_cart
557
- end
558
-
559
- context 'as a guest' do
560
- before do
561
- Spree::Order.last.update_column(:email, "test@example.com")
562
- click_button "Checkout"
563
- end
564
-
565
- it 'should not be displayed' do
566
- expect(page).to_not have_css("[data-hook=save_user_address]")
567
- end
568
- end
569
-
570
- context 'as a User' do
571
- before do
572
- user = create(:user)
573
- Spree::Order.last.update_column :user_id, user.id
574
- allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
575
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
576
- click_button "Checkout"
577
- end
578
-
579
- it 'should be displayed' do
580
- expect(page).to have_css("[data-hook=save_user_address]")
581
- end
582
- end
583
- end
584
-
585
- context "when order is completed" do
586
- let!(:user) { create(:user) }
587
- let!(:order) { Spree::TestingSupport::OrderWalkthrough.up_to(:delivery) }
588
-
589
- before(:each) do
590
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(current_order: order)
591
- allow_any_instance_of(Spree::CheckoutController).to receive_messages(try_spree_current_user: user)
592
- allow_any_instance_of(Spree::OrdersController).to receive_messages(try_spree_current_user: user)
593
-
594
- visit spree.checkout_state_path(:delivery)
595
- click_button "Save and Continue"
596
- click_button "Save and Continue"
597
- click_button "Place Order"
598
- end
599
-
600
- it "displays a thank you message" do
601
- expect(page).to have_content(I18n.t('spree.thank_you_for_your_order'), normalize_ws: true)
602
- end
603
-
604
- it "does not display a thank you message on that order future visits" do
605
- visit spree.order_path(order)
606
- expect(page).to_not have_content(I18n.t('spree.thank_you_for_your_order'))
607
- end
608
- end
609
-
610
- context "with attempted XSS", js: true do
611
- shared_examples "safe from XSS" do
612
- # We need a country with states required but no states so that we have
613
- # access to the state_name input
614
- let!(:canada) { create(:country, name: 'Canada', iso: "CA", states_required: true) }
615
- before do
616
- canada.states.destroy_all
617
- zone.members.create!(zoneable: canada)
618
- end
619
-
620
- it "displays the entered state name without evaluating" do
621
- add_mug_to_cart
622
- visit spree.checkout_state_path(:address)
623
- fill_in_address
624
-
625
- state_name_css = "order_bill_address_attributes_state_name"
626
-
627
- select "Canada", from: "order_bill_address_attributes_country_id"
628
- fill_in 'Customer E-Mail', with: 'test@example.com'
629
- fill_in state_name_css, with: xss_string
630
- fill_in "Zip", with: "H0H0H0"
631
-
632
- click_on 'Save and Continue'
633
- visit spree.checkout_state_path(:address)
634
-
635
- expect(page).to have_field(state_name_css, with: xss_string)
636
- end
637
- end
638
-
639
- let(:xss_string) { %(<script>throw("XSS")</script>) }
640
- include_examples "safe from XSS"
641
-
642
- context "escaped XSS string" do
643
- let(:xss_string) { '\x27\x3e\x3cscript\x3ethrow(\x27XSS\x27)\x3c/script\x3e' }
644
- include_examples "safe from XSS"
645
- end
646
- end
647
-
648
- context "using credit card" do
649
- let!(:payment_method) { create(:credit_card_payment_method) }
650
-
651
- # Regression test for https://github.com/solidusio/solidus/issues/1421
652
- it "works with card number 1", js: true do
653
- add_mug_to_cart
654
-
655
- click_on "Checkout"
656
- fill_in "order_email", with: "test@example.com"
657
- fill_in_address
658
- click_on "Save and Continue"
659
- click_on "Save and Continue"
660
-
661
- fill_in_credit_card(number: "1")
662
- click_on "Save and Continue"
663
-
664
- expect(page).to have_current_path("/checkout/confirm")
665
- end
666
-
667
- it "works with card number 4111111111111111", js: true do
668
- add_mug_to_cart
669
-
670
- click_on "Checkout"
671
- fill_in "order_email", with: "test@example.com"
672
- fill_in_address
673
- click_on "Save and Continue"
674
- click_on "Save and Continue"
675
-
676
- fill_in_credit_card
677
- click_on "Save and Continue"
678
-
679
- expect(page).to have_current_path("/checkout/confirm")
680
- end
681
- end
682
-
683
- def fill_in_credit_card(number: "4111 1111 1111 1111")
684
- fill_in "Name on card", with: 'Mary Doe'
685
- fill_in_with_force "Card Number", with: number
686
- fill_in_with_force "Expiration", with: "12 / 24"
687
- fill_in "Card Code", with: "123"
688
- end
689
-
690
- def fill_in_address
691
- address = "order_bill_address_attributes"
692
- fill_in "#{address}_firstname", with: "Ryan"
693
- fill_in "#{address}_lastname", with: "Bigg"
694
- fill_in "#{address}_address1", with: "143 Swan Street"
695
- fill_in "#{address}_city", with: "Richmond"
696
- select "United States of America", from: "#{address}_country_id"
697
- select "Alabama", from: "#{address}_state_id"
698
- fill_in "#{address}_zipcode", with: "12345"
699
- fill_in "#{address}_phone", with: "(555) 555-5555"
700
- end
701
-
702
- def add_mug_to_cart
703
- visit spree.root_path
704
- click_link mug.name
705
- click_button "add-to-cart-button"
706
- end
707
- end