solidus_frontend 2.9.6 → 2.11.0

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.

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